diff --git a/frontend/cypress.config.ts b/frontend/cypress.config.ts index c4419731fb..47f5248cf0 100644 --- a/frontend/cypress.config.ts +++ b/frontend/cypress.config.ts @@ -1,14 +1,14 @@ -import { defineConfig } from "cypress"; +import { defineConfig } from 'cypress'; export default defineConfig({ e2e: { - baseUrl: "http://pitc.okr.localhost:4200", + baseUrl: 'http://pitc.okr.localhost:4200', experimentalMemoryManagement: true, testIsolation: true, viewportWidth: 1920, viewportHeight: 1080 }, env: { - login_url: "http://localhost:8544" + login_url: 'http://localhost:8544' } }); diff --git a/frontend/cypress/e2e/check-in.cy.ts b/frontend/cypress/e2e/check-in.cy.ts index 932bd4c12c..bc30992a16 100644 --- a/frontend/cypress/e2e/check-in.cy.ts +++ b/frontend/cypress/e2e/check-in.cy.ts @@ -1,14 +1,14 @@ -import * as users from "../fixtures/users.json"; -import { uniqueSuffix } from "../support/helper/utils"; -import CyOverviewPage from "../support/helper/dom-helper/pages/overviewPage"; -import { Unit } from "../../src/app/shared/types/enums/Unit"; -import KeyResultDetailPage from "../support/helper/dom-helper/pages/keyResultDetailPage"; -import CheckInDialog from "../support/helper/dom-helper/dialogs/checkInDialog"; -import CheckInHistoryDialog from "../support/helper/dom-helper/dialogs/checkInHistoryDialog"; -import ConfirmDialog from "../support/helper/dom-helper/dialogs/confirmDialog"; +import * as users from '../fixtures/users.json'; +import { uniqueSuffix } from '../support/helper/utils'; +import CyOverviewPage from '../support/helper/dom-helper/pages/overviewPage'; +import { Unit } from '../../src/app/shared/types/enums/Unit'; +import KeyResultDetailPage from '../support/helper/dom-helper/pages/keyResultDetailPage'; +import CheckInDialog from '../support/helper/dom-helper/dialogs/checkInDialog'; +import CheckInHistoryDialog from '../support/helper/dom-helper/dialogs/checkInHistoryDialog'; +import ConfirmDialog from '../support/helper/dom-helper/dialogs/confirmDialog'; -describe("OKR Check-in e2e tests", () => { - describe("tests via click", () => { +describe('OKR Check-in e2e tests', () => { + describe('tests via click', () => { let overviewPage = new CyOverviewPage(); let keyresultDetailPage = new KeyResultDetailPage(); @@ -18,288 +18,288 @@ describe("OKR Check-in e2e tests", () => { cy.loginAsUser(users.gl); }); - it("Create checkin metric", () => { + it('Create checkin metric', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("Very important keyresult") - .withMetricValues(Unit.PERCENT, "21", "51") - .fillKeyResultDescription("This is my description") + .fillKeyResultTitle('Very important keyresult') + .withMetricValues(Unit.PERCENT, '21', '51') + .fillKeyResultDescription('This is my description') .submit(); keyresultDetailPage - .visit("Very important keyresult") + .visit('Very important keyresult') .createCheckIn() .checkForDialogTextMetric() - .fillMetricCheckInValue("30") + .fillMetricCheckInValue('30') .setCheckInConfidence(6) - .fillCheckInCommentary("We bought a new house") - .fillCheckInInitiatives("We have to buy more PCs") + .fillCheckInCommentary('We bought a new house') + .fillCheckInInitiatives('We have to buy more PCs') .submit(); - cy.contains("30%"); - cy.contains("6/10"); - cy.contains("Letztes Check-in (" + getCurrentDate() + ")"); - cy.contains("We bought a new house"); + cy.contains('30%'); + cy.contains('6/10'); + cy.contains('Letztes Check-in (' + getCurrentDate() + ')'); + cy.contains('We bought a new house'); }); - it("Create checkin metric with confidence 0", () => { + it('Create checkin metric with confidence 0', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("Very important keyresult") - .withMetricValues(Unit.PERCENT, "21", "51") - .fillKeyResultDescription("This is my description") + .fillKeyResultTitle('Very important keyresult') + .withMetricValues(Unit.PERCENT, '21', '51') + .fillKeyResultDescription('This is my description') .submit(); keyresultDetailPage - .visit("Very important keyresult") + .visit('Very important keyresult') .createCheckIn() - .fillMetricCheckInValue("30") + .fillMetricCheckInValue('30') .setCheckInConfidence(0) - .fillCheckInCommentary("We bought a new house") - .fillCheckInInitiatives("We have to buy more PCs") + .fillCheckInCommentary('We bought a new house') + .fillCheckInInitiatives('We have to buy more PCs') .submit(); - cy.contains("30%"); - cy.contains("6/10"); - cy.contains("Letztes Check-in (" + getCurrentDate() + ")"); - cy.contains("We bought a new house"); + cy.contains('30%'); + cy.contains('6/10'); + cy.contains('Letztes Check-in (' + getCurrentDate() + ')'); + cy.contains('We bought a new house'); }); - it("Create checkin metric with value below baseline", () => { + it('Create checkin metric with value below baseline', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("This will not be good") - .withMetricValues(Unit.PERCENT, "21", "52") - .fillKeyResultDescription("This is my description") + .fillKeyResultTitle('This will not be good') + .withMetricValues(Unit.PERCENT, '21', '52') + .fillKeyResultDescription('This is my description') .submit(); keyresultDetailPage - .visit("This will not be good") + .visit('This will not be good') .createCheckIn() - .fillMetricCheckInValue("5") + .fillMetricCheckInValue('5') .setCheckInConfidence(5) .submit(); - cy.contains("5%"); - cy.contains("!"); - cy.contains("5/10"); - cy.contains("Letztes Check-in (" + getCurrentDate() + ")"); + cy.contains('5%'); + cy.contains('!'); + cy.contains('5/10'); + cy.contains('Letztes Check-in (' + getCurrentDate() + ')'); }); - it("Create checkin ordinal", () => { + it('Create checkin ordinal', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("A new ordinal keyresult for our company") - .withOrdinalValues("New house", "New car", "New pool") - .fillKeyResultDescription("This is my description") + .fillKeyResultTitle('A new ordinal keyresult for our company') + .withOrdinalValues('New house', 'New car', 'New pool') + .fillKeyResultDescription('This is my description') .submit(); keyresultDetailPage - .visit("A new ordinal keyresult for our company") + .visit('A new ordinal keyresult for our company') .createCheckIn() .checkForDialogTextOrdinal() - .selectOrdinalCheckInZone("commit") + .selectOrdinalCheckInZone('commit') .setCheckInConfidence(6) - .fillCheckInCommentary("There is a new car") - .fillCheckInInitiatives("Buy a new pool") + .fillCheckInCommentary('There is a new car') + .fillCheckInInitiatives('Buy a new pool') .submit(); - cy.contains("6/10"); - cy.contains("There is a new car"); - cy.contains("Letztes Check-in (" + getCurrentDate() + ")"); + cy.contains('6/10'); + cy.contains('There is a new car'); + cy.contains('Letztes Check-in (' + getCurrentDate() + ')'); }); - it("Should generate checkin list", () => { + it('Should generate checkin list', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("This will give a checkin list") - .withMetricValues(Unit.PERCENT, "21", "52") - .fillKeyResultDescription("This is my description") + .fillKeyResultTitle('This will give a checkin list') + .withMetricValues(Unit.PERCENT, '21', '52') + .fillKeyResultDescription('This is my description') .submit(); keyresultDetailPage - .visit("This will give a checkin list") + .visit('This will give a checkin list') .createCheckIn() - .fillMetricCheckInValue("30") + .fillMetricCheckInValue('30') .setCheckInConfidence(5) - .fillCheckInCommentary("We bought a new house") - .fillCheckInInitiatives("We have to buy more PCs") + .fillCheckInCommentary('We bought a new house') + .fillCheckInInitiatives('We have to buy more PCs') .submit(); keyresultDetailPage .createCheckIn() - .fillMetricCheckInValue("50") + .fillMetricCheckInValue('50') .setCheckInConfidence(6) - .fillCheckInCommentary("This was a good idea") - .fillCheckInInitiatives("Will be difficult") + .fillCheckInCommentary('This was a good idea') + .fillCheckInInitiatives('Will be difficult') .submit(); keyresultDetailPage .showAllCheckins() - .checkForAttribute("Confidence:", "5 / 10") - .checkForAttribute("Confidence:", "6 / 10") - .checkForAttribute("Veränderungen:", "We bought a new house") - .checkForAttribute("Veränderungen:", "This was a good idea") - .checkForAttribute("Massnahmen:", "We have to buy more PCs") - .checkForAttribute("Massnahmen:", "Will be difficult"); + .checkForAttribute('Confidence:', '5 / 10') + .checkForAttribute('Confidence:', '6 / 10') + .checkForAttribute('Veränderungen:', 'We bought a new house') + .checkForAttribute('Veränderungen:', 'This was a good idea') + .checkForAttribute('Massnahmen:', 'We have to buy more PCs') + .checkForAttribute('Massnahmen:', 'Will be difficult'); - cy.contains("Check-in History"); + cy.contains('Check-in History'); cy.contains(getCurrentDate()); - cy.contains("Wert: 30%"); - cy.contains("Wert: 50%"); + cy.contains('Wert: 30%'); + cy.contains('Wert: 50%'); }); - it("Edit metric checkin", () => { + it('Edit metric checkin', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("Here we edit a metric checkin") - .withMetricValues(Unit.CHF, "10", "300") - .fillKeyResultDescription("This is my description") + .fillKeyResultTitle('Here we edit a metric checkin') + .withMetricValues(Unit.CHF, '10', '300') + .fillKeyResultDescription('This is my description') .submit(); keyresultDetailPage - .visit("Here we edit a metric checkin") + .visit('Here we edit a metric checkin') .createCheckIn() - .fillMetricCheckInValue("30") + .fillMetricCheckInValue('30') .setCheckInConfidence(5) - .fillCheckInCommentary("Here we are") - .fillCheckInInitiatives("A cat would be great") + .fillCheckInCommentary('Here we are') + .fillCheckInInitiatives('A cat would be great') .submit(); - cy.contains("Aktuell: 30 CHF"); + cy.contains('Aktuell: 30 CHF'); keyresultDetailPage.showAllCheckins(); - cy.contains("Check-in History"); - cy.contains("Wert: 30 CHF"); + cy.contains('Check-in History'); + cy.contains('Wert: 30 CHF'); CheckInHistoryDialog.do() .editLatestCheckIn(); - cy.contains("Here we edit a metric checkin"); - cy.contains("30 CHF"); - cy.contains("Confidence um Target Zone (213 CHF) zu erreichen"); - cy.contains("5/10"); - cy.contains("Here we are"); - cy.contains("A cat would be great"); + cy.contains('Here we edit a metric checkin'); + cy.contains('30 CHF'); + cy.contains('Confidence um Target Zone (213 CHF) zu erreichen'); + cy.contains('5/10'); + cy.contains('Here we are'); + cy.contains('A cat would be great'); CheckInDialog.do() - .fillMetricCheckInValue("200") - .fillCheckInCommentary("We bought a new sheep") + .fillMetricCheckInValue('200') + .fillCheckInCommentary('We bought a new sheep') .submit(); - cy.contains("200 CHF"); - cy.contains("We bought a new sheep"); + cy.contains('200 CHF'); + cy.contains('We bought a new sheep'); }); - it("Should generate right labels in checkin history list", () => { + it('Should generate right labels in checkin history list', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("A new KeyResult for checking checkin list") - .withMetricValues(Unit.EUR, "10", "300") - .fillKeyResultDescription("This is my description") + .fillKeyResultTitle('A new KeyResult for checking checkin list') + .withMetricValues(Unit.EUR, '10', '300') + .fillKeyResultDescription('This is my description') .submit(); keyresultDetailPage - .visit("A new KeyResult for checking checkin list") + .visit('A new KeyResult for checking checkin list') .createCheckIn() - .fillMetricCheckInValue("30") + .fillMetricCheckInValue('30') .setCheckInConfidence(5) - .fillCheckInCommentary("Here we are") - .fillCheckInInitiatives("A cat would be great") + .fillCheckInCommentary('Here we are') + .fillCheckInInitiatives('A cat would be great') .submit(); - cy.contains("Aktuell: 30 EUR"); + cy.contains('Aktuell: 30 EUR'); keyresultDetailPage.showAllCheckins(); - cy.contains("Check-in History"); - cy.contains("Wert: 30 EUR"); + cy.contains('Check-in History'); + cy.contains('Wert: 30 EUR'); CheckInHistoryDialog.do() .close(); keyresultDetailPage.close(); overviewPage .addKeyResult() - .fillKeyResultTitle("There is another kr with fte") - .withMetricValues(Unit.FTE, "10", "300") - .fillKeyResultDescription("This is my description") + .fillKeyResultTitle('There is another kr with fte') + .withMetricValues(Unit.FTE, '10', '300') + .fillKeyResultDescription('This is my description') .submit(); keyresultDetailPage - .visit("There is another kr with fte") + .visit('There is another kr with fte') .createCheckIn() - .fillMetricCheckInValue("30") + .fillMetricCheckInValue('30') .setCheckInConfidence(5) - .fillCheckInCommentary("Here we are") - .fillCheckInInitiatives("A cat would be great") + .fillCheckInCommentary('Here we are') + .fillCheckInInitiatives('A cat would be great') .submit(); - cy.contains("Aktuell: 30 FTE"); + cy.contains('Aktuell: 30 FTE'); keyresultDetailPage.showAllCheckins(); - cy.contains("Check-in History"); - cy.contains("Wert: 30 FTE"); + cy.contains('Check-in History'); + cy.contains('Wert: 30 FTE'); }); - it("Edit ordinal checkin", () => { + it('Edit ordinal checkin', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("For editing ordinal checkin") - .withOrdinalValues("New house", "New car", "New pool") - .fillKeyResultDescription("This is my description") + .fillKeyResultTitle('For editing ordinal checkin') + .withOrdinalValues('New house', 'New car', 'New pool') + .fillKeyResultDescription('This is my description') .submit(); keyresultDetailPage - .visit("For editing ordinal checkin") + .visit('For editing ordinal checkin') .createCheckIn() - .selectOrdinalCheckInZone("fail") + .selectOrdinalCheckInZone('fail') .setCheckInConfidence(6) - .fillCheckInCommentary("There is a new car") - .fillCheckInInitiatives("Buy now a new pool") + .fillCheckInCommentary('There is a new car') + .fillCheckInInitiatives('Buy now a new pool') .submit(); keyresultDetailPage.showAllCheckins() .editLatestCheckIn(); - cy.contains("For editing ordinal checkin"); - cy.contains("Confidence um Target Zone zu erreichen"); - cy.contains("6/10"); - cy.contains("There is a new car"); - cy.contains("Buy now a new pool"); + cy.contains('For editing ordinal checkin'); + cy.contains('Confidence um Target Zone zu erreichen'); + cy.contains('6/10'); + cy.contains('There is a new car'); + cy.contains('Buy now a new pool'); CheckInDialog.do() - .selectOrdinalCheckInZone("stretch") - .fillCheckInCommentary("We bought a new dog") + .selectOrdinalCheckInZone('stretch') + .fillCheckInCommentary('We bought a new dog') .submit(); - cy.contains("We bought a new dog"); - cy.contains("Buy now a new pool"); - cy.contains("STRETCH"); + cy.contains('We bought a new dog'); + cy.contains('Buy now a new pool'); + cy.contains('STRETCH'); }); - it("Should display confirm dialog when creating checkin on draft objective", () => { + it('Should display confirm dialog when creating checkin on draft objective', () => { overviewPage.addObjective() - .fillObjectiveTitle("draft objective title") - .selectQuarter("3") + .fillObjectiveTitle('draft objective title') + .selectQuarter('3') .submitDraftObjective(); overviewPage.visitNextQuarter(); overviewPage - .addKeyResult(undefined, "draft objective title") - .fillKeyResultTitle("I am a metric keyresult for testing") - .withMetricValues(Unit.PERCENT, "21", "52") - .fillKeyResultDescription("This is my description") + .addKeyResult(undefined, 'draft objective title') + .fillKeyResultTitle('I am a metric keyresult for testing') + .withMetricValues(Unit.PERCENT, '21', '52') + .fillKeyResultDescription('This is my description') .submit(); - keyresultDetailPage.visit("I am a metric keyresult for testing"); + keyresultDetailPage.visit('I am a metric keyresult for testing'); keyresultDetailPage.elements.addCheckin() .click(); ConfirmDialog.do() - .checkTitle("Check-in im Draft-Status"); + .checkTitle('Check-in im Draft-Status'); ConfirmDialog.do() - .checkDescription("Dein Objective befindet sich noch im DRAFT Status. Möchtest du das Check-in trotzdem erfassen?"); + .checkDescription('Dein Objective befindet sich noch im DRAFT Status. Möchtest du das Check-in trotzdem erfassen?'); }); - it("Should only display last value div if last checkin is present", () => { - const objectiveName = uniqueSuffix("new objective"); + it('Should only display last value div if last checkin is present', () => { + const objectiveName = uniqueSuffix('new objective'); overviewPage.addObjective() .fillObjectiveTitle(objectiveName) - .selectQuarter("3") + .selectQuarter('3') .submit(); overviewPage.visitNextQuarter(); overviewPage .addKeyResult(undefined, objectiveName) - .fillKeyResultTitle("I am a keyresult metric") - .withMetricValues(Unit.PERCENT, "45", "60") - .fillKeyResultDescription("Description") + .fillKeyResultTitle('I am a keyresult metric') + .withMetricValues(Unit.PERCENT, '45', '60') + .fillKeyResultDescription('Description') .submit(); - keyresultDetailPage.visit("I am a keyresult metric") + keyresultDetailPage.visit('I am a keyresult metric') .createCheckIn(); - cy.getByTestId("old-checkin-value") - .should("not.exist"); + cy.getByTestId('old-checkin-value') + .should('not.exist'); CheckInDialog.do() - .fillMetricCheckInValue("10") + .fillMetricCheckInValue('10') .setCheckInConfidence(0) - .fillCheckInCommentary("changeinfo") - .fillCheckInInitiatives("initiatives") + .fillCheckInCommentary('changeinfo') + .fillCheckInInitiatives('initiatives') .submit(); cy.contains(`Letztes Check-in (${getCurrentDate()})`); keyresultDetailPage.createCheckIn(); - cy.contains("Letzter Wert") - .siblings("div") - .contains("10%"); + cy.contains('Letzter Wert') + .siblings('div') + .contains('10%'); }); }); }); @@ -310,10 +310,10 @@ function getCurrentDate() { const mm = today.getMonth() + 1; // Months start at 0! const dd = today.getDate(); - let dd_str = "" + dd; - let mm_str = "" + mm; - if (dd < 10) dd_str = "0" + dd_str; - if (mm < 10) mm_str = "0" + mm_str; + let dd_str = '' + dd; + let mm_str = '' + mm; + if (dd < 10) dd_str = '0' + dd_str; + if (mm < 10) mm_str = '0' + mm_str; - return dd_str + "." + mm_str + "." + yyyy; + return dd_str + '.' + mm_str + '.' + yyyy; } diff --git a/frontend/cypress/e2e/duplicate-objective.cy.ts b/frontend/cypress/e2e/duplicate-objective.cy.ts index c612428c00..896c841339 100644 --- a/frontend/cypress/e2e/duplicate-objective.cy.ts +++ b/frontend/cypress/e2e/duplicate-objective.cy.ts @@ -1,7 +1,7 @@ -import * as users from "../fixtures/users.json"; -import CyOverviewPage from "../support/helper/dom-helper/pages/overviewPage"; -import KeyResultDetailPage from "../support/helper/dom-helper/pages/keyResultDetailPage"; -import ObjectiveDialog from "../support/helper/dom-helper/dialogs/objectiveDialog"; +import * as users from '../fixtures/users.json'; +import CyOverviewPage from '../support/helper/dom-helper/pages/overviewPage'; +import KeyResultDetailPage from '../support/helper/dom-helper/pages/keyResultDetailPage'; +import ObjectiveDialog from '../support/helper/dom-helper/dialogs/objectiveDialog'; let overviewPage = new CyOverviewPage(); @@ -10,33 +10,33 @@ beforeEach(() => { cy.loginAsUser(users.gl); }); -describe("Functionality of duplicating objectives and their belonging keyResults", () => { - const firstKeyResultName = "New structure that rewards funny guys and innovation before the end of Q1."; - const secondKeyResultName = "Monthly town halls between our people and leadership teams over the next four months."; - const thirdKeyResultName = "High employee satisfaction scores (80%+) throughout the year."; +describe('Functionality of duplicating objectives and their belonging keyResults', () => { + const firstKeyResultName = 'New structure that rewards funny guys and innovation before the end of Q1.'; + const secondKeyResultName = 'Monthly town halls between our people and leadership teams over the next four months.'; + const thirdKeyResultName = 'High employee satisfaction scores (80%+) throughout the year.'; - it("Should be able to duplicate a objective into this quarter, including all keyResults", () => { - const duplicatedTitle = "This is a duplicated objective with all keyResults"; + it('Should be able to duplicate a objective into this quarter, including all keyResults', () => { + const duplicatedTitle = 'This is a duplicated objective with all keyResults'; overviewPage - .duplicateObjective("Build a company culture that kills the competition.") + .duplicateObjective('Build a company culture that kills the competition.') .fillObjectiveTitle(duplicatedTitle) .submit(); cy.contains(duplicatedTitle); overviewPage.getKeyResultOfObjective(duplicatedTitle, firstKeyResultName) - .should("exist"); + .should('exist'); overviewPage.getKeyResultOfObjective(duplicatedTitle, secondKeyResultName) - .should("exist"); + .should('exist'); overviewPage.getKeyResultOfObjective(duplicatedTitle, thirdKeyResultName) - .should("exist"); + .should('exist'); }); - it("Should be able to duplicate a objective into this quarter, only including one keyResult", () => { - const duplicatedTitle = "This is a duplicated objective with one keyResult"; + it('Should be able to duplicate a objective into this quarter, only including one keyResult', () => { + const duplicatedTitle = 'This is a duplicated objective with one keyResult'; overviewPage - .duplicateObjective("Build a company culture that kills the competition.") + .duplicateObjective('Build a company culture that kills the competition.') .fillObjectiveTitle(duplicatedTitle) .excludeKeyResults([secondKeyResultName, thirdKeyResultName]) @@ -46,105 +46,105 @@ describe("Functionality of duplicating objectives and their belonging keyResults overviewPage .getAllKeyResultsOfObjective(duplicatedTitle) - .should("not.contain", secondKeyResultName) - .should("not.contain", thirdKeyResultName); + .should('not.contain', secondKeyResultName) + .should('not.contain', thirdKeyResultName); }); - it("Should not show option to select keyResults when objective with no keyResults is being duplicated", () => { - const duplicatedTitle = "This is a duplicated objective without any keyResults"; + it('Should not show option to select keyResults when objective with no keyResults is being duplicated', () => { + const duplicatedTitle = 'This is a duplicated objective without any keyResults'; - overviewPage.duplicateObjective("should not appear on staging, no sea takimata sanctus est Lorem ipsum dolor sit amet."); - cy.contains("Key Results:") - .should("not.exist"); + overviewPage.duplicateObjective('should not appear on staging, no sea takimata sanctus est Lorem ipsum dolor sit amet.'); + cy.contains('Key Results:') + .should('not.exist'); ObjectiveDialog.do() .fillObjectiveTitle(duplicatedTitle) .submit(); overviewPage.getObjectiveByName(duplicatedTitle) - .should("exist"); + .should('exist'); }); - it("Should be able to duplicate a objective into the next quarter, including all keyResults", () => { - const duplicatedTitle = "This is a default objective with all keyResults in quarter 3!"; + it('Should be able to duplicate a objective into the next quarter, including all keyResults', () => { + const duplicatedTitle = 'This is a default objective with all keyResults in quarter 3!'; overviewPage - .duplicateObjective("Build a company culture that kills the competition.") + .duplicateObjective('Build a company culture that kills the competition.') .fillObjectiveTitle(duplicatedTitle) - .selectQuarter("3") + .selectQuarter('3') .submit(); overviewPage.visitNextQuarter(); cy.contains(duplicatedTitle); overviewPage.getKeyResultOfObjective(duplicatedTitle, firstKeyResultName) - .should("exist"); + .should('exist'); overviewPage.getKeyResultOfObjective(duplicatedTitle, secondKeyResultName) - .should("exist"); + .should('exist'); overviewPage.getKeyResultOfObjective(duplicatedTitle, thirdKeyResultName) - .should("exist"); + .should('exist'); }); - it("Should not duplicate objective when cancel button is clicked", () => { - const duplicatedTitle = "This is a never existing objective"; + it('Should not duplicate objective when cancel button is clicked', () => { + const duplicatedTitle = 'This is a never existing objective'; overviewPage - .duplicateObjective("Build a company culture that kills the competition.") + .duplicateObjective('Build a company culture that kills the competition.') .fillObjectiveTitle(duplicatedTitle) - .fillObjectiveDescription("Wow this is a very nice description!") + .fillObjectiveDescription('Wow this is a very nice description!') .cancel(); cy.contains(duplicatedTitle) - .should("not.exist"); + .should('not.exist'); }); }); -describe("Verify functionality of scoring adjustment on duplicated objectives", () => { +describe('Verify functionality of scoring adjustment on duplicated objectives', () => { const keyresultDetailPage = new KeyResultDetailPage(); - it("Duplicate ordinal checkin and validate value of scoring component", () => { + it('Duplicate ordinal checkin and validate value of scoring component', () => { overviewPage - .addKeyResult("Puzzle ITC", "Wir wollen die Kundenzufriedenheit steigern") - .fillKeyResultTitle("stretch keyresult for testing") - .withOrdinalValues("Ex. val", "Ex. val", "Ex. val") + .addKeyResult('Puzzle ITC', 'Wir wollen die Kundenzufriedenheit steigern') + .fillKeyResultTitle('stretch keyresult for testing') + .withOrdinalValues('Ex. val', 'Ex. val', 'Ex. val') .submit(); - cy.contains("stretch keyresult for testing"); + cy.contains('stretch keyresult for testing'); keyresultDetailPage - .visit("stretch keyresult for testing") + .visit('stretch keyresult for testing') .createCheckIn() - .selectOrdinalCheckInZone("stretch") + .selectOrdinalCheckInZone('stretch') .setCheckInConfidence(8) - .fillCheckInCommentary("Testveränderungen") - .fillCheckInInitiatives("Testmassnahmen") + .fillCheckInCommentary('Testveränderungen') + .fillCheckInInitiatives('Testmassnahmen') .submit(); - cy.intercept("GET", "**/overview?*") - .as("indexPage"); + cy.intercept('GET', '**/overview?*') + .as('indexPage'); keyresultDetailPage.close(); - cy.wait("@indexPage"); + cy.wait('@indexPage'); overviewPage - .duplicateObjective("Wir wollen die Kundenzufriedenheit steigern") - .fillObjectiveTitle("A duplicated Objective for this tool") - .selectQuarter("3") + .duplicateObjective('Wir wollen die Kundenzufriedenheit steigern') + .fillObjectiveTitle('A duplicated Objective for this tool') + .selectQuarter('3') .submit(); - overviewPage.checkForToaster("Das Objective wurde erfolgreich erstellt.", "success"); + overviewPage.checkForToaster('Das Objective wurde erfolgreich erstellt.', 'success'); overviewPage.visitNextQuarter(); overviewPage - .getKeyResultByName("stretch keyresult for testing") - .findByTestId("scoring-component") - .findByTestId("fail") - .as("fail-area"); + .getKeyResultByName('stretch keyresult for testing') + .findByTestId('scoring-component') + .findByTestId('fail') + .as('fail-area'); - cy.get("@fail-area") + cy.get('@fail-area') .should(($fail) => { - expect($fail).not.to.have.css("score-red"); - expect($fail).not.to.have.css("score-yellow"); - expect($fail).not.to.have.css("score-green"); - expect($fail).not.to.have.css("score-stretch"); + expect($fail).not.to.have.css('score-red'); + expect($fail).not.to.have.css('score-yellow'); + expect($fail).not.to.have.css('score-green'); + expect($fail).not.to.have.css('score-stretch'); }); }); }); diff --git a/frontend/cypress/e2e/key-result.cy.ts b/frontend/cypress/e2e/key-result.cy.ts index 7f4a7ba647..45d45af130 100644 --- a/frontend/cypress/e2e/key-result.cy.ts +++ b/frontend/cypress/e2e/key-result.cy.ts @@ -1,10 +1,10 @@ -import * as users from "../fixtures/users.json"; -import CyOverviewPage from "../support/helper/dom-helper/pages/overviewPage"; -import KeyResultDetailPage from "../support/helper/dom-helper/pages/keyResultDetailPage"; -import { Unit } from "../../src/app/shared/types/enums/Unit"; -import KeyResultDialog from "../support/helper/dom-helper/dialogs/keyResultDialog"; +import * as users from '../fixtures/users.json'; +import CyOverviewPage from '../support/helper/dom-helper/pages/overviewPage'; +import KeyResultDetailPage from '../support/helper/dom-helper/pages/keyResultDetailPage'; +import { Unit } from '../../src/app/shared/types/enums/Unit'; +import KeyResultDialog from '../support/helper/dom-helper/dialogs/keyResultDialog'; -describe("OKR Overview", () => { +describe('OKR Overview', () => { let overviewPage = new CyOverviewPage(); let keyResultDetailPage = new KeyResultDetailPage(); @@ -14,346 +14,346 @@ describe("OKR Overview", () => { cy.loginAsUser(users.gl); }); - it("Create new metric KeyResult", () => { + it('Create new metric KeyResult', () => { overviewPage .addKeyResult() .checkForDialogTextMetric() - .fillKeyResultTitle("I am a metric keyresult") - .withMetricValues(Unit.PERCENT, "21", "52") - .fillOwner("Bob Baumeister") - .fillKeyResultDescription("This is my description") + .fillKeyResultTitle('I am a metric keyresult') + .withMetricValues(Unit.PERCENT, '21', '52') + .fillOwner('Bob Baumeister') + .fillKeyResultDescription('This is my description') .submit(); - keyResultDetailPage.visit("I am a metric keyresult"); - - cy.contains("I am a metric keyresult"); - cy.contains("Metrisch"); - cy.contains("Bob Baumeister"); - cy.contains("21%"); - cy.contains("52%"); - cy.contains("Stretch"); - cy.contains("Confidence"); - cy.contains("Beschrieb"); - cy.contains("This is my description"); - cy.contains("Check-in erfassen"); - cy.contains("Key Result bearbeiten"); + keyResultDetailPage.visit('I am a metric keyresult'); + + cy.contains('I am a metric keyresult'); + cy.contains('Metrisch'); + cy.contains('Bob Baumeister'); + cy.contains('21%'); + cy.contains('52%'); + cy.contains('Stretch'); + cy.contains('Confidence'); + cy.contains('Beschrieb'); + cy.contains('This is my description'); + cy.contains('Check-in erfassen'); + cy.contains('Key Result bearbeiten'); }); - it("Create new ordinal KeyResult", () => { + it('Create new ordinal KeyResult', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("I am a ordinal keyresult") - .withOrdinalValues("My commit zone", "My target zone", "My stretch goal") + .fillKeyResultTitle('I am a ordinal keyresult') + .withOrdinalValues('My commit zone', 'My target zone', 'My stretch goal') .checkForDialogTextOrdinal() - .fillOwner("Bob Baumeister") - .fillKeyResultDescription("This is my description") + .fillOwner('Bob Baumeister') + .fillKeyResultDescription('This is my description') .submit(); - keyResultDetailPage.visit("I am a ordinal keyresult"); - - cy.contains("I am a ordinal keyresult"); - cy.contains("Ordinal"); - cy.contains("Bob Baumeister"); - cy.contains("Fail"); - cy.contains("Commit"); - cy.contains("Target"); - cy.contains("My commit zone"); - cy.contains("My target zone"); - cy.contains("My stretch goal"); - cy.contains("Stretch"); - cy.contains("Confidence"); - cy.contains("Beschrieb"); - cy.contains("This is my description"); - cy.contains("Check-in erfassen"); - cy.contains("Key Result bearbeiten"); + keyResultDetailPage.visit('I am a ordinal keyresult'); + + cy.contains('I am a ordinal keyresult'); + cy.contains('Ordinal'); + cy.contains('Bob Baumeister'); + cy.contains('Fail'); + cy.contains('Commit'); + cy.contains('Target'); + cy.contains('My commit zone'); + cy.contains('My target zone'); + cy.contains('My stretch goal'); + cy.contains('Stretch'); + cy.contains('Confidence'); + cy.contains('Beschrieb'); + cy.contains('This is my description'); + cy.contains('Check-in erfassen'); + cy.contains('Key Result bearbeiten'); }); - it("Create new KeyResult and Save and New", () => { + it('Create new KeyResult and Save and New', () => { overviewPage .addKeyResult() .checkForDialogTextMetric() - .fillKeyResultTitle("I am a metric keyresult with a new one") - .withMetricValues(Unit.PERCENT, "21", "52") - .fillOwner("Bob Baumeister") - .fillKeyResultDescription("This is my description when creating and then open a new") + .fillKeyResultTitle('I am a metric keyresult with a new one') + .withMetricValues(Unit.PERCENT, '21', '52') + .fillOwner('Bob Baumeister') + .fillKeyResultDescription('This is my description when creating and then open a new') .saveAndNew(); - cy.contains("Jaya Norris"); + cy.contains('Jaya Norris'); KeyResultDialog.do() .checkForDialogTextMetric(); }); - it("Create and edit KeyResult with Action Plan", () => { + it('Create and edit KeyResult with Action Plan', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("This is a keyresult with an action plan") - .withOrdinalValues("My commit zone", "My target zone", "My stretch goal") - .fillOwner("Bob Baumeister") - .fillKeyResultDescription("This is my description") - .addActionPlanElement("A new car") - .addActionPlanElement("A new house") - .addActionPlanElement("A new company") + .fillKeyResultTitle('This is a keyresult with an action plan') + .withOrdinalValues('My commit zone', 'My target zone', 'My stretch goal') + .fillOwner('Bob Baumeister') + .fillKeyResultDescription('This is my description') + .addActionPlanElement('A new car') + .addActionPlanElement('A new house') + .addActionPlanElement('A new company') .submit(); - keyResultDetailPage.visit("This is a keyresult with an action plan"); + keyResultDetailPage.visit('This is a keyresult with an action plan'); - cy.contains("This is a keyresult with an action plan"); - cy.contains("Ordinal"); - cy.contains("My commit zone"); - cy.contains("My target zone"); - cy.contains("My stretch goal"); - cy.contains("A new car"); - cy.contains("A new house"); - cy.contains("A new company"); + cy.contains('This is a keyresult with an action plan'); + cy.contains('Ordinal'); + cy.contains('My commit zone'); + cy.contains('My target zone'); + cy.contains('My stretch goal'); + cy.contains('A new car'); + cy.contains('A new house'); + cy.contains('A new company'); keyResultDetailPage.editKeyResult(); - cy.getByTestId("actionInput") - .should("have.length", 3); + cy.getByTestId('actionInput') + .should('have.length', 3); }); - it("Edit a KeyResult without type change", () => { + it('Edit a KeyResult without type change', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("We want not to change keyresult title") - .withOrdinalValues("My commit zone", "My target zone", "My stretch goal") + .fillKeyResultTitle('We want not to change keyresult title') + .withOrdinalValues('My commit zone', 'My target zone', 'My stretch goal') .checkForDialogTextOrdinal() - .fillKeyResultDescription("This is my description") + .fillKeyResultDescription('This is my description') .submit(); - keyResultDetailPage.visit("We want not to change keyresult title") + keyResultDetailPage.visit('We want not to change keyresult title') .editKeyResult(); - cy.getByTestId("submit") - .should("not.be.disabled"); - cy.contains("Key Result bearbeiten"); - cy.getByTestId("titleInput") - .should("have.value", "We want not to change keyresult title"); - cy.getByTestId("commitZone") - .should("have.value", "My commit zone"); - cy.getByTestId("targetZone") - .should("have.value", "My target zone"); - cy.getByTestId("stretchZone") - .should("have.value", "My stretch goal"); - cy.getByTestId("ownerInput") - .should("have.value", "Jaya Norris"); - cy.getByTestId("descriptionInput") - .should("have.value", "This is my description"); + cy.getByTestId('submit') + .should('not.be.disabled'); + cy.contains('Key Result bearbeiten'); + cy.getByTestId('titleInput') + .should('have.value', 'We want not to change keyresult title'); + cy.getByTestId('commitZone') + .should('have.value', 'My commit zone'); + cy.getByTestId('targetZone') + .should('have.value', 'My target zone'); + cy.getByTestId('stretchZone') + .should('have.value', 'My stretch goal'); + cy.getByTestId('ownerInput') + .should('have.value', 'Jaya Norris'); + cy.getByTestId('descriptionInput') + .should('have.value', 'This is my description'); KeyResultDialog.do() - .fillKeyResultTitle("This is the new title") - .withOrdinalValues("New commit", "New target", "New stretch") - .fillKeyResultDescription("This is my new description") + .fillKeyResultTitle('This is the new title') + .withOrdinalValues('New commit', 'New target', 'New stretch') + .fillKeyResultDescription('This is my new description') .submit(); - cy.contains("This is the new title"); - cy.contains("New commit"); - cy.contains("New target"); - cy.contains("New stretch"); - cy.contains("Jaya Norris"); - cy.contains("This is my new description"); + cy.contains('This is the new title'); + cy.contains('New commit'); + cy.contains('New target'); + cy.contains('New stretch'); + cy.contains('Jaya Norris'); + cy.contains('This is my new description'); }); - it("Edit a KeyResult with type change", () => { + it('Edit a KeyResult with type change', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("Here we want to change keyresult title") - .withOrdinalValues("My commit zone", "My target zone", "My stretch goal") + .fillKeyResultTitle('Here we want to change keyresult title') + .withOrdinalValues('My commit zone', 'My target zone', 'My stretch goal') .checkForDialogTextOrdinal() - .fillKeyResultDescription("This is my description") - .addActionPlanElement("Action 1") - .addActionPlanElement("Action 2") + .fillKeyResultDescription('This is my description') + .addActionPlanElement('Action 1') + .addActionPlanElement('Action 2') .submit(); - keyResultDetailPage.visit("Here we want to change keyresult title") + keyResultDetailPage.visit('Here we want to change keyresult title') .editKeyResult(); - cy.getByTestId("submit") - .should("not.be.disabled"); - cy.contains("Key Result bearbeiten"); - cy.getByTestId("titleInput") - .should("have.value", "Here we want to change keyresult title"); - cy.getByTestId("commitZone") - .should("have.value", "My commit zone"); - cy.getByTestId("targetZone") - .should("have.value", "My target zone"); - cy.getByTestId("stretchZone") - .should("have.value", "My stretch goal"); - cy.getByTestId("ownerInput") - .should("have.value", "Jaya Norris"); - cy.getByTestId("descriptionInput") - .should("have.value", "This is my description"); + cy.getByTestId('submit') + .should('not.be.disabled'); + cy.contains('Key Result bearbeiten'); + cy.getByTestId('titleInput') + .should('have.value', 'Here we want to change keyresult title'); + cy.getByTestId('commitZone') + .should('have.value', 'My commit zone'); + cy.getByTestId('targetZone') + .should('have.value', 'My target zone'); + cy.getByTestId('stretchZone') + .should('have.value', 'My stretch goal'); + cy.getByTestId('ownerInput') + .should('have.value', 'Jaya Norris'); + cy.getByTestId('descriptionInput') + .should('have.value', 'This is my description'); KeyResultDialog.do() - .fillKeyResultTitle("This is my new title for the new metric keyresult") - .withMetricValues(Unit.PERCENT, "21", "56") - .fillKeyResultDescription("This is my new description") + .fillKeyResultTitle('This is my new title for the new metric keyresult') + .withMetricValues(Unit.PERCENT, '21', '56') + .fillKeyResultDescription('This is my new description') .submit(); - cy.contains("This is my new title for the new metric keyresult"); - cy.contains("21%"); - cy.contains("56%"); - cy.contains("Metrisch"); - cy.contains("Jaya Norris"); - cy.contains("This is my new description"); - cy.contains("Action 1"); - cy.contains("Action 2"); + cy.contains('This is my new title for the new metric keyresult'); + cy.contains('21%'); + cy.contains('56%'); + cy.contains('Metrisch'); + cy.contains('Jaya Norris'); + cy.contains('This is my new description'); + cy.contains('Action 1'); + cy.contains('Action 2'); }); - it("A KeyResult should not be able to change type after a checkin", () => { + it('A KeyResult should not be able to change type after a checkin', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("Here we want to create a checkin") - .withOrdinalValues("My commit zone", "My target zone", "My stretch goal") + .fillKeyResultTitle('Here we want to create a checkin') + .withOrdinalValues('My commit zone', 'My target zone', 'My stretch goal') .checkForDialogTextOrdinal() - .fillKeyResultDescription("This is my description") - .addActionPlanElement("Action 1") - .addActionPlanElement("Action 2") + .fillKeyResultDescription('This is my description') + .addActionPlanElement('Action 1') + .addActionPlanElement('Action 2') .submit(); keyResultDetailPage - .visit("Here we want to create a checkin") + .visit('Here we want to create a checkin') .createCheckIn() - .selectOrdinalCheckInZone("commit") + .selectOrdinalCheckInZone('commit') .setCheckInConfidence(6) .submit(); keyResultDetailPage.close(); - keyResultDetailPage.visit("Here we want to create a checkin") + keyResultDetailPage.visit('Here we want to create a checkin') .editKeyResult(); - cy.getByTestId("metricTab") - .should("have.class", "non-active"); + cy.getByTestId('metricTab') + .should('have.class', 'non-active'); }); - it("Check validation in keyresult dialog", () => { + it('Check validation in keyresult dialog', () => { overviewPage.addKeyResult() .checkForDialogTextMetric(); - cy.getByTestId("submit") - .should("be.disabled"); + cy.getByTestId('submit') + .should('be.disabled'); KeyResultDialog.do() - .fillKeyResultTitle("I am a metric keyresult") - .withMetricValues(Unit.PERCENT, "21", "52") - .fillKeyResultDescription("This is my description"); + .fillKeyResultTitle('I am a metric keyresult') + .withMetricValues(Unit.PERCENT, '21', '52') + .fillKeyResultDescription('This is my description'); - cy.getByTestId("submit") - .should("not.be.disabled"); + cy.getByTestId('submit') + .should('not.be.disabled'); - cy.getByTestId("titleInput") + cy.getByTestId('titleInput') .clear(); - cy.getByTestId("submit") - .should("be.disabled"); - cy.contains("Titel muss folgende Länge haben: 2-250 Zeichen"); + cy.getByTestId('submit') + .should('be.disabled'); + cy.contains('Titel muss folgende Länge haben: 2-250 Zeichen'); KeyResultDialog.do() - .fillKeyResultTitle("My title"); - cy.getByTestId("submit") - .should("not.be.disabled"); - cy.getByTestId("baseline") + .fillKeyResultTitle('My title'); + cy.getByTestId('submit') + .should('not.be.disabled'); + cy.getByTestId('baseline') .clear(); - cy.getByTestId("submit") - .should("be.disabled"); - cy.contains("Baseline muss eine Zahl sein"); + cy.getByTestId('submit') + .should('be.disabled'); + cy.contains('Baseline muss eine Zahl sein'); KeyResultDialog.do() - .withMetricValues(Unit.PERCENT, "abc", "52"); - cy.getByTestId("submit") - .should("be.disabled"); - cy.contains("Baseline muss eine Zahl sein"); + .withMetricValues(Unit.PERCENT, 'abc', '52'); + cy.getByTestId('submit') + .should('be.disabled'); + cy.contains('Baseline muss eine Zahl sein'); KeyResultDialog.do() - .withMetricValues(Unit.PERCENT, "45", "52"); - cy.getByTestId("submit") - .should("not.be.disabled"); - cy.getByTestId("stretchGoal") + .withMetricValues(Unit.PERCENT, '45', '52'); + cy.getByTestId('submit') + .should('not.be.disabled'); + cy.getByTestId('stretchGoal') .clear(); - cy.getByTestId("submit") - .should("be.disabled"); - cy.contains("Stretch Goal muss eine Zahl sein"); + cy.getByTestId('submit') + .should('be.disabled'); + cy.contains('Stretch Goal muss eine Zahl sein'); KeyResultDialog.do() - .withMetricValues(Unit.PERCENT, "45", "abc"); - cy.getByTestId("submit") - .should("be.disabled"); - cy.contains("Stretch Goal muss eine Zahl sein"); + .withMetricValues(Unit.PERCENT, '45', 'abc'); + cy.getByTestId('submit') + .should('be.disabled'); + cy.contains('Stretch Goal muss eine Zahl sein'); KeyResultDialog.do() - .withMetricValues(Unit.PERCENT, "45", "83"); - cy.getByTestId("submit") - .should("not.be.disabled"); - cy.getByTestId("ownerInput") + .withMetricValues(Unit.PERCENT, '45', '83'); + cy.getByTestId('submit') + .should('not.be.disabled'); + cy.getByTestId('ownerInput') .clear(); - cy.getByTestId("submit") - .should("be.disabled"); + cy.getByTestId('submit') + .should('be.disabled'); - cy.getByTestId("ownerInput") - .type("abc"); - cy.getByTestId("titleInput") - .type("Hello"); - cy.getByTestId("submit") - .should("be.disabled"); - cy.contains("Owner muss ausgewählt sein"); + cy.getByTestId('ownerInput') + .type('abc'); + cy.getByTestId('titleInput') + .type('Hello'); + cy.getByTestId('submit') + .should('be.disabled'); + cy.contains('Owner muss ausgewählt sein'); KeyResultDialog.do() - .fillOwner("Bob Baumeister"); - cy.getByTestId("submit") - .should("not.be.disabled"); + .fillOwner('Bob Baumeister'); + cy.getByTestId('submit') + .should('not.be.disabled'); - cy.getByTestId("ordinalTab") + cy.getByTestId('ordinalTab') .click(); - cy.getByTestId("submit") - .should("be.disabled"); + cy.getByTestId('submit') + .should('be.disabled'); KeyResultDialog.do() - .withOrdinalValues("Commit", "Target", "Stretch"); - cy.getByTestId("submit") - .should("not.be.disabled"); + .withOrdinalValues('Commit', 'Target', 'Stretch'); + cy.getByTestId('submit') + .should('not.be.disabled'); - cy.getByTestId("commitZone") + cy.getByTestId('commitZone') .clear(); - cy.getByTestId("submit") - .should("be.disabled"); - cy.contains("Commit Zone muss folgende Länge haben: 1-400 Zeichen"); + cy.getByTestId('submit') + .should('be.disabled'); + cy.contains('Commit Zone muss folgende Länge haben: 1-400 Zeichen'); KeyResultDialog.do() - .withOrdinalValues("Commit", "Target", "Stretch"); - cy.getByTestId("submit") - .should("not.be.disabled"); - cy.getByTestId("targetZone") + .withOrdinalValues('Commit', 'Target', 'Stretch'); + cy.getByTestId('submit') + .should('not.be.disabled'); + cy.getByTestId('targetZone') .clear(); - cy.getByTestId("submit") - .should("be.disabled"); - cy.contains("Target Zone muss folgende Länge haben: 1-400 Zeichen"); + cy.getByTestId('submit') + .should('be.disabled'); + cy.contains('Target Zone muss folgende Länge haben: 1-400 Zeichen'); KeyResultDialog.do() - .withOrdinalValues("Commit", "Target", "Stretch"); - cy.getByTestId("submit") - .should("not.be.disabled"); - cy.getByTestId("stretchZone") + .withOrdinalValues('Commit', 'Target', 'Stretch'); + cy.getByTestId('submit') + .should('not.be.disabled'); + cy.getByTestId('stretchZone') .clear(); - cy.getByTestId("submit") - .should("be.disabled"); - cy.contains("Stretch Zone muss folgende Länge haben: 1-400 Zeichen"); + cy.getByTestId('submit') + .should('be.disabled'); + cy.contains('Stretch Zone muss folgende Länge haben: 1-400 Zeichen'); KeyResultDialog.do() - .withOrdinalValues("Commit", "Target", "Stretch"); - cy.getByTestId("submit") - .should("not.be.disabled"); + .withOrdinalValues('Commit', 'Target', 'Stretch'); + cy.getByTestId('submit') + .should('not.be.disabled'); }); - it("Delete existing keyresult", () => { + it('Delete existing keyresult', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("A keyresult to delete") - .withOrdinalValues("My commit zone", "My target zone", "My stretch goal") + .fillKeyResultTitle('A keyresult to delete') + .withOrdinalValues('My commit zone', 'My target zone', 'My stretch goal') .checkForDialogTextOrdinal() - .fillKeyResultDescription("This is my description") + .fillKeyResultDescription('This is my description') .submit(); keyResultDetailPage - .visit("A keyresult to delete") + .visit('A keyresult to delete') .editKeyResult() .deleteKeyResult() - .checkTitle("Key Result löschen") - .checkDescription("Möchtest du dieses Key Result wirklich löschen? Zugehörige Check-ins werden dadurch ebenfalls gelöscht!") + .checkTitle('Key Result löschen') + .checkDescription('Möchtest du dieses Key Result wirklich löschen? Zugehörige Check-ins werden dadurch ebenfalls gelöscht!') .submit(); - cy.contains("Puzzle ITC"); - cy.get("A keyresult to delete") - .should("not.exist"); + cy.contains('Puzzle ITC'); + cy.get('A keyresult to delete') + .should('not.exist'); }); }); diff --git a/frontend/cypress/e2e/login.cy.ts b/frontend/cypress/e2e/login.cy.ts index dfe84ec8d3..2ab584f05c 100644 --- a/frontend/cypress/e2e/login.cy.ts +++ b/frontend/cypress/e2e/login.cy.ts @@ -1,42 +1,42 @@ -import * as users from "../fixtures/users.json"; +import * as users from '../fixtures/users.json'; -describe("OKR Login", () => { +describe('OKR Login', () => { beforeEach(() => { cy.loginAsUser(users.gl); }); - it("Login and check correct name is displayed", () => { + it('Login and check correct name is displayed', () => { cy.title() - .should("equal", "Puzzle OKR"); - cy.getByTestId("user-name") + .should('equal', 'Puzzle OKR'); + cy.getByTestId('user-name') .contains(users.gl.name); }); - it("Login and logout", () => { + it('Login and logout', () => { cy.title() - .should("equal", "Puzzle OKR"); - cy.getByTestId("user-options") + .should('equal', 'Puzzle OKR'); + cy.getByTestId('user-options') .click(); - cy.getByTestId("logout") + cy.getByTestId('logout') .click(); - cy.origin(Cypress.env("login_url"), () => { + cy.origin(Cypress.env('login_url'), () => { cy.url() - .should("include", Cypress.env("login_url")); - cy.get("#kc-page-title") - .contains("Sign in to your account"); + .should('include', Cypress.env('login_url')); + cy.get('#kc-page-title') + .contains('Sign in to your account'); }); }); - it("Click on the Hilfe button should open a new tab with the correct URL", () => { + it('Click on the Hilfe button should open a new tab with the correct URL', () => { cy.window() .then((win) => { - cy.stub(win, "open") - .as("openWindow"); + cy.stub(win, 'open') + .as('openWindow'); }); - cy.get("#hilfeButton") + cy.get('#hilfeButton') .click(); - cy.get("@openWindow") - .should("be.calledWith", "https://wiki.puzzle.ch/Puzzle/OKRs"); + cy.get('@openWindow') + .should('be.calledWith', 'https://wiki.puzzle.ch/Puzzle/OKRs'); }); }); diff --git a/frontend/cypress/e2e/objective-backlog.cy.ts b/frontend/cypress/e2e/objective-backlog.cy.ts index cf9e3a315e..8772db6b35 100644 --- a/frontend/cypress/e2e/objective-backlog.cy.ts +++ b/frontend/cypress/e2e/objective-backlog.cy.ts @@ -1,8 +1,8 @@ -import * as users from "../fixtures/users.json"; -import CyOverviewPage from "../support/helper/dom-helper/pages/overviewPage"; -import ObjectiveDialog from "../support/helper/dom-helper/dialogs/objectiveDialog"; +import * as users from '../fixtures/users.json'; +import CyOverviewPage from '../support/helper/dom-helper/pages/overviewPage'; +import ObjectiveDialog from '../support/helper/dom-helper/dialogs/objectiveDialog'; -describe("OKR Objective Backlog e2e tests", () => { +describe('OKR Objective Backlog e2e tests', () => { let overviewPage = new CyOverviewPage(); beforeEach(() => { @@ -10,201 +10,201 @@ describe("OKR Objective Backlog e2e tests", () => { cy.loginAsUser(users.gl); }); - it("Create Objective in backlog quarter should not have save button", () => { + it('Create Objective in backlog quarter should not have save button', () => { overviewPage .addObjective() - .fillObjectiveTitle("Objective in quarter backlog") - .selectQuarter("Backlog") - .run(cy.contains("Speichern") - .should("not.exist")) - .run(cy.contains("Als Draft speichern")) + .fillObjectiveTitle('Objective in quarter backlog') + .selectQuarter('Backlog') + .run(cy.contains('Speichern') + .should('not.exist')) + .run(cy.contains('Als Draft speichern')) .submitDraftObjective(); - cy.contains("Objective in quarter backlog") - .should("not.exist"); + cy.contains('Objective in quarter backlog') + .should('not.exist'); overviewPage.visitBacklogQuarter(); - cy.contains("Objective in quarter backlog"); + cy.contains('Objective in quarter backlog'); }); - it("Edit Objective and move to backlog", () => { + it('Edit Objective and move to backlog', () => { overviewPage.addObjective() - .fillObjectiveTitle("Move to another quarter on edit") + .fillObjectiveTitle('Move to another quarter on edit') .submitDraftObjective(); overviewPage - .getObjectiveByNameAndState("Move to another quarter on edit", "draft") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('Move to another quarter on edit', 'draft') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective bearbeiten"); + overviewPage.selectFromThreeDotMenu('Objective bearbeiten'); ObjectiveDialog.do() - .fillObjectiveTitle("This goes now to backlog") - .selectQuarter("Backlog") + .fillObjectiveTitle('This goes now to backlog') + .selectQuarter('Backlog') .submit(); - cy.contains("This goes now to backlog") - .should("not.exist"); + cy.contains('This goes now to backlog') + .should('not.exist'); overviewPage.visitBacklogQuarter(); - cy.contains("This goes now to backlog"); + cy.contains('This goes now to backlog'); }); - it("Edit ongoing Objective can not choose backlog in quarter select", () => { + it('Edit ongoing Objective can not choose backlog in quarter select', () => { overviewPage.addObjective() - .fillObjectiveTitle("We can not move this to backlog") + .fillObjectiveTitle('We can not move this to backlog') .submit(); overviewPage - .getObjectiveByNameAndState("We can not move this to backlog", "ongoing") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('We can not move this to backlog', 'ongoing') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective bearbeiten"); + overviewPage.selectFromThreeDotMenu('Objective bearbeiten'); - cy.get("select#quarter") - .should("contain", "GJ ForTests"); - cy.get("select#quarter") - .should("not.contain", "Backlog"); + cy.get('select#quarter') + .should('contain', 'GJ ForTests'); + cy.get('select#quarter') + .should('not.contain', 'Backlog'); }); - it("Can release Objective to another quarter from backlog", () => { + it('Can release Objective to another quarter from backlog', () => { overviewPage.visitBacklogQuarter(); overviewPage.addObjective() - .fillObjectiveTitle("We can not release this") + .fillObjectiveTitle('We can not release this') .submitDraftObjective(); - overviewPage.getObjectiveByNameAndState("We can not release this", "draft") - .findByTestId("three-dot-menu") + overviewPage.getObjectiveByNameAndState('We can not release this', 'draft') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective veröffentlichen"); + overviewPage.selectFromThreeDotMenu('Objective veröffentlichen'); - cy.contains("Objective veröffentlichen"); - cy.getByTestId("title") + cy.contains('Objective veröffentlichen'); + cy.getByTestId('title') .first() - .as("title"); - cy.get("@title") + .as('title'); + cy.get('@title') .clear(); - cy.get("@title") - .type("This is our first released objective"); - - cy.get("select#quarter") - .should("not.contain", "Backlog"); - cy.get("select#quarter") - .select("GJ ForTests"); - - cy.contains("Als Draft speichern") - .should("not.exist"); - cy.contains("Speichern"); - cy.getByTestId("save") + cy.get('@title') + .type('This is our first released objective'); + + cy.get('select#quarter') + .should('not.contain', 'Backlog'); + cy.get('select#quarter') + .select('GJ ForTests'); + + cy.contains('Als Draft speichern') + .should('not.exist'); + cy.contains('Speichern'); + cy.getByTestId('save') .click(); - cy.contains("This is our first released objective") - .should("not.exist"); + cy.contains('This is our first released objective') + .should('not.exist'); overviewPage.visitGJForTests(); - cy.contains("This is our first released objective"); + cy.contains('This is our first released objective'); }); - it("Can edit Objective title in backlog", () => { + it('Can edit Objective title in backlog', () => { overviewPage.visitBacklogQuarter(); overviewPage.addObjective() - .fillObjectiveTitle("This is possible for edit") + .fillObjectiveTitle('This is possible for edit') .submitDraftObjective(); overviewPage - .getObjectiveByNameAndState("This is possible for edit", "draft") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('This is possible for edit', 'draft') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective bearbeiten"); + overviewPage.selectFromThreeDotMenu('Objective bearbeiten'); ObjectiveDialog.do() - .fillObjectiveTitle("My new title") + .fillObjectiveTitle('My new title') .submit(); - overviewPage.getObjectiveByNameAndState("My new title", "draft"); + overviewPage.getObjectiveByNameAndState('My new title', 'draft'); }); - it("Can edit Objective in backlog and change quarter", () => { + it('Can edit Objective in backlog and change quarter', () => { overviewPage.visitBacklogQuarter(); overviewPage.addObjective() - .fillObjectiveTitle("This goes to other quarter later") + .fillObjectiveTitle('This goes to other quarter later') .submitDraftObjective(); overviewPage - .getObjectiveByNameAndState("This goes to other quarter later", "draft") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('This goes to other quarter later', 'draft') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective bearbeiten"); + overviewPage.selectFromThreeDotMenu('Objective bearbeiten'); ObjectiveDialog.do() - .selectQuarter("GJ ForTests") + .selectQuarter('GJ ForTests') .submit(); overviewPage.visitGJForTests(); - overviewPage.getObjectiveByNameAndState("This goes to other quarter later", "draft"); + overviewPage.getObjectiveByNameAndState('This goes to other quarter later', 'draft'); }); - it("Can duplicate in backlog", () => { + it('Can duplicate in backlog', () => { overviewPage.visitBacklogQuarter(); overviewPage.addObjective() - .fillObjectiveTitle("Ready for duplicate in backlog") + .fillObjectiveTitle('Ready for duplicate in backlog') .submitDraftObjective(); overviewPage - .getObjectiveByNameAndState("Ready for duplicate in backlog", "draft") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('Ready for duplicate in backlog', 'draft') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective duplizieren"); + overviewPage.selectFromThreeDotMenu('Objective duplizieren'); ObjectiveDialog.do() - .fillObjectiveTitle("This is a new duplication in backlog") + .fillObjectiveTitle('This is a new duplication in backlog') .submit(); - overviewPage.getObjectiveByNameAndState("Ready for duplicate in backlog", "draft"); - overviewPage.getObjectiveByNameAndState("This is a new duplication in backlog", "draft"); + overviewPage.getObjectiveByNameAndState('Ready for duplicate in backlog', 'draft'); + overviewPage.getObjectiveByNameAndState('This is a new duplication in backlog', 'draft'); }); - it("should duplicate from backlog", () => { + it('should duplicate from backlog', () => { overviewPage.visitBacklogQuarter(); overviewPage.addObjective() - .fillObjectiveTitle("Ready for duplicate to another quarter") + .fillObjectiveTitle('Ready for duplicate to another quarter') .submitDraftObjective(); overviewPage - .getObjectiveByNameAndState("Ready for duplicate to another quarter", "draft") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('Ready for duplicate to another quarter', 'draft') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective duplizieren"); + overviewPage.selectFromThreeDotMenu('Objective duplizieren'); ObjectiveDialog.do() - .fillObjectiveTitle("New duplication from backlog") - .selectQuarter("GJ ForTests") + .fillObjectiveTitle('New duplication from backlog') + .selectQuarter('GJ ForTests') .submit(); - overviewPage.getObjectiveByNameAndState("Ready for duplicate to another quarter", "draft") - .should("exist"); - cy.contains("New duplication from backlog") - .should("not.exist"); + overviewPage.getObjectiveByNameAndState('Ready for duplicate to another quarter', 'draft') + .should('exist'); + cy.contains('New duplication from backlog') + .should('not.exist'); overviewPage.visitGJForTests(); - overviewPage.getObjectiveByNameAndState("New duplication from backlog", "draft") - .should("exist"); + overviewPage.getObjectiveByNameAndState('New duplication from backlog', 'draft') + .should('exist'); }); - it("Can duplicate ongoing Objective to backlog", () => { + it('Can duplicate ongoing Objective to backlog', () => { overviewPage.addObjective() - .fillObjectiveTitle("Possible to duplicate into backlog") + .fillObjectiveTitle('Possible to duplicate into backlog') .submit(); overviewPage - .getObjectiveByNameAndState("Possible to duplicate into backlog", "ongoing") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('Possible to duplicate into backlog', 'ongoing') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective duplizieren"); + overviewPage.selectFromThreeDotMenu('Objective duplizieren'); ObjectiveDialog.do() - .selectQuarter("Backlog") + .selectQuarter('Backlog') .submit(); overviewPage.visitBacklogQuarter(); - cy.contains("Possible to duplicate into backlog"); + cy.contains('Possible to duplicate into backlog'); }); }); diff --git a/frontend/cypress/e2e/objective-crud.cy.ts b/frontend/cypress/e2e/objective-crud.cy.ts index 632a558fd1..236a8b90f7 100644 --- a/frontend/cypress/e2e/objective-crud.cy.ts +++ b/frontend/cypress/e2e/objective-crud.cy.ts @@ -1,8 +1,8 @@ -import * as users from "../fixtures/users.json"; -import CyOverviewPage from "../support/helper/dom-helper/pages/overviewPage"; -import ObjectiveDialog from "../support/helper/dom-helper/dialogs/objectiveDialog"; +import * as users from '../fixtures/users.json'; +import CyOverviewPage from '../support/helper/dom-helper/pages/overviewPage'; +import ObjectiveDialog from '../support/helper/dom-helper/dialogs/objectiveDialog'; -describe("CRUD operations", () => { +describe('CRUD operations', () => { let overviewPage = new CyOverviewPage(); beforeEach(() => { @@ -10,96 +10,96 @@ describe("CRUD operations", () => { cy.loginAsUser(users.gl); }); - [["ongoing objective title", - "save", - "ongoing-icon.svg"], - ["draft objective title", - "save-draft", - "draft-icon.svg"]].forEach(([objectiveTitle, + [['ongoing objective title', + 'save', + 'ongoing-icon.svg'], + ['draft objective title', + 'save-draft', + 'draft-icon.svg']].forEach(([objectiveTitle, buttonTestId, icon]) => { - it("Create objective, no keyresults", () => { + it('Create objective, no keyresults', () => { overviewPage.addObjective() .fillObjectiveTitle(objectiveTitle) - .selectQuarter("3"); + .selectQuarter('3'); cy.getByTestId(buttonTestId) .click(); overviewPage.visitNextQuarter(); overviewPage .getObjectiveByName(objectiveTitle) - .findByTestId("objective-state") - .should("have.attr", "src", `assets/icons/${icon}`); + .findByTestId('objective-state') + .should('have.attr', 'src', `assets/icons/${icon}`); }); }); - it("Create objective, should display error message", () => { + it('Create objective, should display error message', () => { overviewPage.addObjective(); - cy.getByTestId("title") + cy.getByTestId('title') .first() - .type("title") + .type('title') .clear(); - cy.contains("Titel muss folgende Länge haben: 2-250 Zeichen"); - cy.getByTestId("save") - .should("be.disabled"); - cy.getByTestId("save-draft") - .should("be.disabled"); - cy.getByTestId("cancel") - .should("not.be.disabled"); + cy.contains('Titel muss folgende Länge haben: 2-250 Zeichen'); + cy.getByTestId('save') + .should('be.disabled'); + cy.getByTestId('save-draft') + .should('be.disabled'); + cy.getByTestId('cancel') + .should('not.be.disabled'); }); - it("Create objective, cancel", () => { - const objectiveTitle = "this is a canceled objective"; + it('Create objective, cancel', () => { + const objectiveTitle = 'this is a canceled objective'; overviewPage.addObjective() - .selectQuarter("3") + .selectQuarter('3') .cancel(); overviewPage.visitNextQuarter(); cy.contains(objectiveTitle) - .should("not.exist"); + .should('not.exist'); }); - it("Delete existing objective", () => { + it('Delete existing objective', () => { overviewPage.getFirstObjective() - .findByTestId("three-dot-menu") + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective bearbeiten"); + overviewPage.selectFromThreeDotMenu('Objective bearbeiten'); ObjectiveDialog.do() .deleteObjective() - .checkTitle("Objective löschen") - .checkDescription("Möchtest du dieses Objective wirklich löschen? Zugehörige Key Results werden dadurch ebenfalls gelöscht!") + .checkTitle('Objective löschen') + .checkDescription('Möchtest du dieses Objective wirklich löschen? Zugehörige Key Results werden dadurch ebenfalls gelöscht!') .submit(); }); - it("Open objective aside via click", () => { + it('Open objective aside via click', () => { overviewPage.getFirstObjective() - .find(".title") + .find('.title') .click(); cy.url() - .should("include", "objective"); + .should('include', 'objective'); }); - it("update objective", () => { - const updatedTitle = "This is an updated title"; + it('update objective', () => { + const updatedTitle = 'This is an updated title'; overviewPage.getFirstObjective() - .findByTestId("three-dot-menu") + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective bearbeiten"); + overviewPage.selectFromThreeDotMenu('Objective bearbeiten'); ObjectiveDialog.do() .fillObjectiveTitle(updatedTitle) .submit(); cy.contains(updatedTitle) - .should("exist"); + .should('exist'); }); - it("Duplicate objective", () => { - const duplicatedTitle = "This is a duplicated objective"; + it('Duplicate objective', () => { + const duplicatedTitle = 'This is a duplicated objective'; overviewPage.getFirstObjective() - .findByTestId("three-dot-menu") + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective duplizieren"); + overviewPage.selectFromThreeDotMenu('Objective duplizieren'); ObjectiveDialog.do() .fillObjectiveTitle(duplicatedTitle) .submit(); cy.contains(duplicatedTitle) - .should("exist"); + .should('exist'); }); }); diff --git a/frontend/cypress/e2e/objective.cy.ts b/frontend/cypress/e2e/objective.cy.ts index 28da14fa94..1ac6b70e5d 100644 --- a/frontend/cypress/e2e/objective.cy.ts +++ b/frontend/cypress/e2e/objective.cy.ts @@ -1,310 +1,310 @@ -import * as users from "../fixtures/users.json"; -import CyOverviewPage from "../support/helper/dom-helper/pages/overviewPage"; -import ObjectiveDialog from "../support/helper/dom-helper/dialogs/objectiveDialog"; -import ConfirmDialog from "../support/helper/dom-helper/dialogs/confirmDialog"; +import * as users from '../fixtures/users.json'; +import CyOverviewPage from '../support/helper/dom-helper/pages/overviewPage'; +import ObjectiveDialog from '../support/helper/dom-helper/dialogs/objectiveDialog'; +import ConfirmDialog from '../support/helper/dom-helper/dialogs/confirmDialog'; -describe("OKR Objective e2e tests", () => { +describe('OKR Objective e2e tests', () => { let overviewPage = new CyOverviewPage(); beforeEach(() => { overviewPage = new CyOverviewPage(); cy.loginAsUser(users.gl); }); - describe("tests via click", () => { - it("Release Objective from Draft to Ongoing", () => { + describe('tests via click', () => { + it('Release Objective from Draft to Ongoing', () => { overviewPage.addObjective() - .fillObjectiveTitle("A objective in state draft") + .fillObjectiveTitle('A objective in state draft') .submitDraftObjective(); overviewPage - .getObjectiveByNameAndState("A objective in state draft", "draft") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('A objective in state draft', 'draft') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective veröffentlichen"); + overviewPage.selectFromThreeDotMenu('Objective veröffentlichen'); ConfirmDialog.do() - .checkTitle("Objective veröffentlichen") - .checkDescription("Soll dieses Objective veröffentlicht werden?") + .checkTitle('Objective veröffentlichen') + .checkDescription('Soll dieses Objective veröffentlicht werden?') .submit(); - overviewPage.getObjectiveByNameAndState("A objective in state draft", "ongoing") - .should("exist"); + overviewPage.getObjectiveByNameAndState('A objective in state draft', 'ongoing') + .should('exist'); }); - it("Complete Objective with Successful", () => { + it('Complete Objective with Successful', () => { overviewPage.addObjective() - .fillObjectiveTitle("We want to complete this successful") + .fillObjectiveTitle('We want to complete this successful') .submit(); overviewPage - .getObjectiveByNameAndState("We want to complete this successful", "ongoing") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('We want to complete this successful', 'ongoing') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective abschliessen"); + overviewPage.selectFromThreeDotMenu('Objective abschliessen'); - cy.contains("Bewertung"); - cy.contains("Objective erreicht"); - cy.contains("Objective nicht erreicht"); - cy.contains("Kommentar (optional)"); - cy.contains("Objective abschliessen"); - cy.contains("Abbrechen"); + cy.contains('Bewertung'); + cy.contains('Objective erreicht'); + cy.contains('Objective nicht erreicht'); + cy.contains('Kommentar (optional)'); + cy.contains('Objective abschliessen'); + cy.contains('Abbrechen'); - cy.getByTestId("successful") + cy.getByTestId('successful') .click(); - cy.getByTestId("submit") + cy.getByTestId('submit') .click(); - overviewPage.getObjectiveByNameAndState("We want to complete this successful", "successful"); + overviewPage.getObjectiveByNameAndState('We want to complete this successful', 'successful'); }); - it("Complete Objective with Not-Successful", () => { + it('Complete Objective with Not-Successful', () => { overviewPage.addObjective() - .fillObjectiveTitle("A not successful objective") + .fillObjectiveTitle('A not successful objective') .submit(); overviewPage - .getObjectiveByNameAndState("A not successful objective", "ongoing") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('A not successful objective', 'ongoing') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective abschliessen"); + overviewPage.selectFromThreeDotMenu('Objective abschliessen'); - cy.contains("Bewertung"); - cy.contains("Objective erreicht"); - cy.contains("Objective nicht erreicht"); - cy.contains("Kommentar (optional)"); - cy.contains("Objective abschliessen"); - cy.contains("Abbrechen"); + cy.contains('Bewertung'); + cy.contains('Objective erreicht'); + cy.contains('Objective nicht erreicht'); + cy.contains('Kommentar (optional)'); + cy.contains('Objective abschliessen'); + cy.contains('Abbrechen'); - cy.getByTestId("not-successful") + cy.getByTestId('not-successful') .click(); - cy.getByTestId("submit") + cy.getByTestId('submit') .click(); - overviewPage.getObjectiveByNameAndState("A not successful objective", "not-successful"); + overviewPage.getObjectiveByNameAndState('A not successful objective', 'not-successful'); }); - it("Reopen Successful Objective", () => { + it('Reopen Successful Objective', () => { overviewPage.addObjective() - .fillObjectiveTitle("This objective will be reopened after") + .fillObjectiveTitle('This objective will be reopened after') .submit(); overviewPage - .getObjectiveByNameAndState("This objective will be reopened after", "ongoing") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('This objective will be reopened after', 'ongoing') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective abschliessen"); + overviewPage.selectFromThreeDotMenu('Objective abschliessen'); - cy.getByTestId("successful") + cy.getByTestId('successful') .click(); - cy.getByTestId("submit") + cy.getByTestId('submit') .click(); cy.wait(500); overviewPage - .getObjectiveByNameAndState("This objective will be reopened after", "successful") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('This objective will be reopened after', 'successful') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective wiedereröffnen"); + overviewPage.selectFromThreeDotMenu('Objective wiedereröffnen'); ConfirmDialog.do() - .checkTitle("Objective wiedereröffnen") - .checkDescription("Soll dieses Objective wiedereröffnet werden?") + .checkTitle('Objective wiedereröffnen') + .checkDescription('Soll dieses Objective wiedereröffnet werden?') .submit(); - overviewPage.getObjectiveByNameAndState("This objective will be reopened after", "ongoing") - .should("exist"); + overviewPage.getObjectiveByNameAndState('This objective will be reopened after', 'ongoing') + .should('exist'); }); - it("Cancel Reopen Successful Objective", () => { + it('Cancel Reopen Successful Objective', () => { overviewPage.addObjective() - .fillObjectiveTitle("The reopening of this objective will be canceled") + .fillObjectiveTitle('The reopening of this objective will be canceled') .submit(); overviewPage - .getObjectiveByNameAndState("The reopening of this objective will be canceled", "ongoing") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('The reopening of this objective will be canceled', 'ongoing') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective abschliessen"); + overviewPage.selectFromThreeDotMenu('Objective abschliessen'); - cy.getByTestId("successful") + cy.getByTestId('successful') .click(); - cy.getByTestId("submit") + cy.getByTestId('submit') .click(); cy.wait(500); overviewPage - .getObjectiveByNameAndState("he reopening of this objective will be canceled", "successful") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('he reopening of this objective will be canceled', 'successful') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective wiedereröffnen"); + overviewPage.selectFromThreeDotMenu('Objective wiedereröffnen'); ConfirmDialog.do() - .checkTitle("Objective wiedereröffnen") - .checkDescription("Soll dieses Objective wiedereröffnet werden?") + .checkTitle('Objective wiedereröffnen') + .checkDescription('Soll dieses Objective wiedereröffnet werden?') .cancel(); overviewPage - .getObjectiveByNameAndState("The reopening of this objective will be canceled", "successful") - .should("exist"); + .getObjectiveByNameAndState('The reopening of this objective will be canceled', 'successful') + .should('exist'); }); - it("Cancel Ongoing objective back to draft state", () => { + it('Cancel Ongoing objective back to draft state', () => { overviewPage.addObjective() - .fillObjectiveTitle("This objective will be returned to draft state") + .fillObjectiveTitle('This objective will be returned to draft state') .submit(); overviewPage - .getObjectiveByNameAndState("This objective will be returned to draft state", "ongoing") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('This objective will be returned to draft state', 'ongoing') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective als Draft speichern"); + overviewPage.selectFromThreeDotMenu('Objective als Draft speichern'); ConfirmDialog.do() - .checkTitle("Objective als Draft speichern") - .checkDescription("Soll dieses Objective als Draft gespeichert werden?") + .checkTitle('Objective als Draft speichern') + .checkDescription('Soll dieses Objective als Draft gespeichert werden?') .submit(); overviewPage - .getObjectiveByNameAndState("This objective will be returned to draft state", "draft") - .should("exist"); + .getObjectiveByNameAndState('This objective will be returned to draft state', 'draft') + .should('exist'); }); - it("Ongoing objective back to draft state", () => { + it('Ongoing objective back to draft state', () => { overviewPage .addObjective() - .fillObjectiveTitle("Putting this objective back to draft state will be canceled") + .fillObjectiveTitle('Putting this objective back to draft state will be canceled') .submit(); overviewPage - .getObjectiveByNameAndState("Putting this objective back to draft state will be canceled", "ongoing") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('Putting this objective back to draft state will be canceled', 'ongoing') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective als Draft speichern"); + overviewPage.selectFromThreeDotMenu('Objective als Draft speichern'); ConfirmDialog.do() - .checkTitle("Objective als Draft speichern") - .checkDescription("Soll dieses Objective als Draft gespeichert werden?") + .checkTitle('Objective als Draft speichern') + .checkDescription('Soll dieses Objective als Draft gespeichert werden?') .cancel(); overviewPage - .getObjectiveByNameAndState("Putting this objective back to draft state will be canceled", "ongoing") - .should("exist"); + .getObjectiveByNameAndState('Putting this objective back to draft state will be canceled', 'ongoing') + .should('exist'); }); - it("Search for Objective", () => { + it('Search for Objective', () => { overviewPage.addObjective() - .fillObjectiveTitle("Search after this objective") + .fillObjectiveTitle('Search after this objective') .submit(); overviewPage.addObjective() - .fillObjectiveTitle("We dont want to search for this") + .fillObjectiveTitle('We dont want to search for this') .submit(); - cy.contains("Search after this objective"); - cy.contains("We dont want to search for this"); + cy.contains('Search after this objective'); + cy.contains('We dont want to search for this'); cy.scrollTo(0, 0); cy.wait(500); - cy.getByTestId("objectiveSearch") + cy.getByTestId('objectiveSearch') .first() .click(); - cy.getByTestId("objectiveSearch") + cy.getByTestId('objectiveSearch') .first() - .type("Search after") + .type('Search after') .wait(350); - cy.contains("Search after this objective"); - cy.contains("We dont want to search for this") - .should("not.exist"); + cy.contains('Search after this objective'); + cy.contains('We dont want to search for this') + .should('not.exist'); - cy.getByTestId("objectiveSearch") + cy.getByTestId('objectiveSearch') .first() - .as("objective-search") + .as('objective-search') .clear(); - cy.get("@objective-search") - .type("this") + cy.get('@objective-search') + .type('this') .wait(350); - cy.contains("Search after this objective"); - cy.contains("We dont want to search for this"); + cy.contains('Search after this objective'); + cy.contains('We dont want to search for this'); - cy.get("@objective-search") + cy.get('@objective-search') .clear(); - cy.get("@objective-search") - .type("dont want to") + cy.get('@objective-search') + .type('dont want to') .wait(350); - cy.contains("We dont want to search for this"); - cy.contains("Search after this objective") - .should("not.exist"); + cy.contains('We dont want to search for this'); + cy.contains('Search after this objective') + .should('not.exist'); - cy.get("@objective-search") + cy.get('@objective-search') .clear(); - cy.get("@objective-search") - .type("there is no objective") + cy.get('@objective-search') + .type('there is no objective') .wait(350); - cy.contains("We dont want to search for this") - .should("not.exist"); - cy.contains("Search after this objective") - .should("not.exist"); + cy.contains('We dont want to search for this') + .should('not.exist'); + cy.contains('Search after this objective') + .should('not.exist'); }); - it("Create Objective in other quarter", () => { + it('Create Objective in other quarter', () => { overviewPage.addObjective() - .fillObjectiveTitle("Objective in quarter 3") - .selectQuarter("3") + .fillObjectiveTitle('Objective in quarter 3') + .selectQuarter('3') .submit(); - cy.contains("Objective in quarter 3") - .should("not.exist"); + cy.contains('Objective in quarter 3') + .should('not.exist'); overviewPage.visitNextQuarter(); - cy.contains("Objective in quarter 3"); + cy.contains('Objective in quarter 3'); }); - it("Edit Objective and move to other quarter", () => { + it('Edit Objective and move to other quarter', () => { overviewPage.addObjective() - .fillObjectiveTitle("Move to another quarter on edit") + .fillObjectiveTitle('Move to another quarter on edit') .submit(); overviewPage - .getObjectiveByNameAndState("Move to another quarter on edit", "ongoing") - .findByTestId("three-dot-menu") + .getObjectiveByNameAndState('Move to another quarter on edit', 'ongoing') + .findByTestId('three-dot-menu') .click(); - overviewPage.selectFromThreeDotMenu("Objective bearbeiten"); + overviewPage.selectFromThreeDotMenu('Objective bearbeiten'); ObjectiveDialog.do() - .selectQuarter("3") + .selectQuarter('3') .submit(); - cy.contains("Move to another quarter on edit") - .should("not.exist"); + cy.contains('Move to another quarter on edit') + .should('not.exist'); overviewPage.visitNextQuarter(); - cy.contains("Move to another quarter on edit"); + cy.contains('Move to another quarter on edit'); }); }); - describe("tests via keyboard", () => { - it("Open objective aside via enter", () => { - cy.getByTestId("objective") + describe('tests via keyboard', () => { + it('Open objective aside via enter', () => { + cy.getByTestId('objective') .first() - .find("[tabindex]") + .find('[tabindex]') .first() .focus(); - cy.realPress("Enter"); + cy.realPress('Enter'); cy.url() - .should("include", "objective"); + .should('include', 'objective'); }); }); }); diff --git a/frontend/cypress/e2e/overview.cy.ts b/frontend/cypress/e2e/overview.cy.ts index bd390d73cd..770428a26e 100644 --- a/frontend/cypress/e2e/overview.cy.ts +++ b/frontend/cypress/e2e/overview.cy.ts @@ -1,28 +1,28 @@ -import * as users from "../fixtures/users.json"; -import FilterHelper from "../support/helper/dom-helper/filterHelper"; +import * as users from '../fixtures/users.json'; +import FilterHelper from '../support/helper/dom-helper/filterHelper'; -describe("OKR Overview", () => { +describe('OKR Overview', () => { beforeEach(() => { cy.loginAsUser(users.gl); }); - it("should have the current quarter with label Aktuell", () => { - cy.getByTestId("quarterFilter") - .contains("Aktuell"); + it('should have the current quarter with label Aktuell', () => { + cy.getByTestId('quarterFilter') + .contains('Aktuell'); }); - it("Check order of teams", () => { + it('Check order of teams', () => { FilterHelper.do() - .optionShouldNotBeSelected("Alle") - .toggleOption("Alle"); + .optionShouldNotBeSelected('Alle') + .toggleOption('Alle'); const textsExpectedOrder = [ - "LoremIpsum", - "Puzzle ITC", - "/BBT", - "we are cube.³" + 'LoremIpsum', + 'Puzzle ITC', + '/BBT', + 'we are cube.³' ]; - cy.get(".team-title:contains(\"we are cube.³\")"); - cy.get(".team-title") + cy.get('.team-title:contains("we are cube.³")'); + cy.get('.team-title') .then((elements) => { const texts: string[] = elements.map((_, el) => Cypress.$(el) .text()) @@ -31,14 +31,14 @@ describe("OKR Overview", () => { }); }); - it("Check font ", () => { - cy.get(".team-title") + it('Check font ', () => { + cy.get('.team-title') .first() - .invoke("css", "font-family") - .should("eq", "Roboto, \"sans-serif\""); - cy.get(".team-title") + .invoke('css', 'font-family') + .should('eq', 'Roboto, "sans-serif"'); + cy.get('.team-title') .first() - .invoke("css", "font-variation-settings") - .should("eq", "\"wght\" 600"); + .invoke('css', 'font-variation-settings') + .should('eq', '"wght" 600'); }); }); diff --git a/frontend/cypress/e2e/routing.cy.ts b/frontend/cypress/e2e/routing.cy.ts index 41196d2372..e08fb94367 100644 --- a/frontend/cypress/e2e/routing.cy.ts +++ b/frontend/cypress/e2e/routing.cy.ts @@ -1,38 +1,38 @@ -import * as users from "../fixtures/users.json"; -import CyOverviewPage from "../support/helper/dom-helper/pages/overviewPage"; -import TeammanagementPage from "../support/helper/dom-helper/pages/teammanagementPage"; +import * as users from '../fixtures/users.json'; +import CyOverviewPage from '../support/helper/dom-helper/pages/overviewPage'; +import TeammanagementPage from '../support/helper/dom-helper/pages/teammanagementPage'; -describe("Routing", () => { +describe('Routing', () => { beforeEach(() => { cy.loginAsUser(users.gl); }); - describe("Route via url", () => { - it("should route to overview", () => { + describe('Route via url', () => { + it('should route to overview', () => { // Visit autocalls the validatePage method CyOverviewPage.do() .visitViaURL(); }); - it("should route to teammanagement", () => { + it('should route to teammanagement', () => { // Visit autocalls the validatePage method TeammanagementPage.do() .visitViaURL(); }); - it("should route from overview to team management ", () => { + it('should route from overview to team management ', () => { CyOverviewPage.do() .visitViaURL() .visitTeammanagement(); }); - it("should route from team management to Overview via back button", () => { + it('should route from team management to Overview via back button', () => { TeammanagementPage.do() .visitViaURL() .backToOverview(); }); - it("should route from team management to Overview via logo", () => { + it('should route from team management to Overview via logo', () => { TeammanagementPage.do() .visitViaURL() .visitOverview(); diff --git a/frontend/cypress/e2e/scoring.cy.ts b/frontend/cypress/e2e/scoring.cy.ts index a5f197fe74..4c7e421b78 100644 --- a/frontend/cypress/e2e/scoring.cy.ts +++ b/frontend/cypress/e2e/scoring.cy.ts @@ -1,10 +1,10 @@ -import * as users from "../fixtures/users.json"; -import { getPercentageMetric, getPercentageOrdinal } from "cypress/support/helper/scoringSupport"; -import CyOverviewPage from "../support/helper/dom-helper/pages/overviewPage"; -import { Unit } from "../../src/app/shared/types/enums/Unit"; -import KeyResultDetailPage from "../support/helper/dom-helper/pages/keyResultDetailPage"; +import * as users from '../fixtures/users.json'; +import { getPercentageMetric, getPercentageOrdinal } from 'cypress/support/helper/scoringSupport'; +import CyOverviewPage from '../support/helper/dom-helper/pages/overviewPage'; +import { Unit } from '../../src/app/shared/types/enums/Unit'; +import KeyResultDetailPage from '../support/helper/dom-helper/pages/keyResultDetailPage'; -describe("Scoring component e2e tests", () => { +describe('Scoring component e2e tests', () => { let overviewPage = new CyOverviewPage(); let keyresultDetailPage = new KeyResultDetailPage(); @@ -30,25 +30,25 @@ describe("Scoring component e2e tests", () => { ].forEach(([baseline, stretchgoal, value]) => { - it("Create metric checkin and validate value of scoring component", () => { + it('Create metric checkin and validate value of scoring component', () => { setupMetricKR( `Metric kr with check-in value ${value}`, baseline, stretchgoal, value ); const percentage = getPercentageMetric(baseline, stretchgoal, value); cy.validateScoring(false, percentage); - cy.get(".keyResult-detail-attribute-show") - .contains("Aktuell") + cy.get('.keyResult-detail-attribute-show') + .contains('Aktuell') .parent() - .not(":contains(!)") - .should("have.css", "border-color") - .and("not.equal", "rgb(186, 56, 56)"); + .not(':contains(!)') + .should('have.css', 'border-color') + .and('not.equal', 'rgb(186, 56, 56)'); keyresultDetailPage.close(); cy.validateScoring(true, percentage); overviewPage .getKeyResultByName(`Metric kr with check-in value ${value}`) - .not(":contains(*[class=\"scoring-error-badge\"])"); + .not(':contains(*[class="scoring-error-badge"])'); }); }); @@ -60,48 +60,48 @@ describe("Scoring component e2e tests", () => { 250]].forEach(([baseline, stretchgoal, value]) => { - it("show indicator that value is negative", () => { + it('show indicator that value is negative', () => { setupMetricKR( `Check indicator with value ${value}`, baseline, stretchgoal, value ); cy.validateScoring(false, 0); - cy.get(".keyResult-detail-attribute-show") - .contains("Aktuell") + cy.get('.keyResult-detail-attribute-show') + .contains('Aktuell') .parent() - .contains("!") - .should("have.css", "border-color") - .and("equal", "rgb(186, 56, 56)"); + .contains('!') + .should('have.css', 'border-color') + .and('equal', 'rgb(186, 56, 56)'); keyresultDetailPage.close(); cy.validateScoring(true, 0); overviewPage.getKeyResultByName(`Check indicator with value ${value}`) - .get(".scoring-error-badge"); + .get('.scoring-error-badge'); }); }); [ - ["fail"], - ["commit"], - ["target"], - ["stretch"] + ['fail'], + ['commit'], + ['target'], + ['stretch'] ].forEach(([zoneName]) => { - it("Create ordinal checkin and validate value of scoring component", () => { + it('Create ordinal checkin and validate value of scoring component', () => { overviewPage .addKeyResult() - .fillKeyResultTitle("Ordinal scoring keyresult") - .withOrdinalValues("My commit zone", "My target zone", "My stretch goal") + .fillKeyResultTitle('Ordinal scoring keyresult') + .withOrdinalValues('My commit zone', 'My target zone', 'My stretch goal') .checkForDialogTextOrdinal() - .fillKeyResultDescription("This is my description") + .fillKeyResultDescription('This is my description') .submit(); keyresultDetailPage - .visit("Ordinal scoring keyresult") + .visit('Ordinal scoring keyresult') .createCheckIn() - .selectOrdinalCheckInZone(zoneName as "fail" | "commit" | "target" | "stretch") + .selectOrdinalCheckInZone(zoneName as 'fail' | 'commit' | 'target' | 'stretch') .setCheckInConfidence(8) - .fillCheckInCommentary("Testveränderungen") - .fillCheckInInitiatives("Testmassnahmen") + .fillCheckInCommentary('Testveränderungen') + .fillCheckInInitiatives('Testmassnahmen') .submit(); const percentage = getPercentageOrdinal(zoneName); cy.validateScoring(false, percentage); @@ -123,8 +123,8 @@ function setupMetricKR( .visit(name) .createCheckIn() .fillMetricCheckInValue(value.toString()) - .fillCheckInCommentary("Testveränderungen") - .fillCheckInInitiatives("Testmassnahmen") + .fillCheckInCommentary('Testveränderungen') + .fillCheckInInitiatives('Testmassnahmen') .setCheckInConfidence(8) .submit(); } diff --git a/frontend/cypress/e2e/tab.cy.ts b/frontend/cypress/e2e/tab.cy.ts index ef096fbeae..ad08374842 100644 --- a/frontend/cypress/e2e/tab.cy.ts +++ b/frontend/cypress/e2e/tab.cy.ts @@ -1,9 +1,9 @@ -import * as users from "../fixtures/users.json"; -import CyOverviewPage from "../support/helper/dom-helper/pages/overviewPage"; -import { Unit } from "../../src/app/shared/types/enums/Unit"; -import KeyResultDetailPage from "../support/helper/dom-helper/pages/keyResultDetailPage"; +import * as users from '../fixtures/users.json'; +import CyOverviewPage from '../support/helper/dom-helper/pages/overviewPage'; +import { Unit } from '../../src/app/shared/types/enums/Unit'; +import KeyResultDetailPage from '../support/helper/dom-helper/pages/keyResultDetailPage'; -describe("Tab workflow tests", () => { +describe('Tab workflow tests', () => { let overviewPage = new CyOverviewPage(); beforeEach(() => { cy.loginAsUser(users.gl); @@ -15,7 +15,7 @@ describe("Tab workflow tests", () => { function focusedShouldHaveTestId(testId: string) { cy.focused() - .should("have.attr", "data-testId", testId); + .should('have.attr', 'data-testId', testId); } function tabAndCheck(testId: string, text?: string) { @@ -27,344 +27,344 @@ describe("Tab workflow tests", () => { } } - it("should be able to tab to header items", () => { - tabAndCheck("team-management", "Teamverwaltung"); - tabAndCheck("help-button", "Hilfe"); - tabAndCheck("user-options", "Jaya Norris"); - cy.realPress("Enter"); - cy.pressUntilContains("Logout", "ArrowDown"); - focusedShouldHaveTestId("logout"); - cy.realPress("Escape"); - tabAndCheck("quarterFilter", "GJ"); - tabAndCheck("objectiveSearch"); + it('should be able to tab to header items', () => { + tabAndCheck('team-management', 'Teamverwaltung'); + tabAndCheck('help-button', 'Hilfe'); + tabAndCheck('user-options', 'Jaya Norris'); + cy.realPress('Enter'); + cy.pressUntilContains('Logout', 'ArrowDown'); + focusedShouldHaveTestId('logout'); + cy.realPress('Escape'); + tabAndCheck('quarterFilter', 'GJ'); + tabAndCheck('objectiveSearch'); cy.tabForward(); cy.focused() - .children("img") + .children('img') .first() - .should("have.attr", "src") - .and("match", /search-icon.svg/); + .should('have.attr', 'src') + .and('match', /search-icon.svg/); cy.tabForward(); cy.focused() - .contains("Alle"); + .contains('Alle'); }); - it("should be able to tab to overview items", () => { - tabAndCheck("team-management", "Teamverwaltung"); - tabAndCheck("add-objective", "Objective hinzufügen"); - tabAndCheck("objective"); - tabAndCheck("three-dot-menu"); - tabAndCheck("key-result"); - tabAndCheck("add-keyResult", "Key Result hinzufügen"); + it('should be able to tab to overview items', () => { + tabAndCheck('team-management', 'Teamverwaltung'); + tabAndCheck('add-objective', 'Objective hinzufügen'); + tabAndCheck('objective'); + tabAndCheck('three-dot-menu'); + tabAndCheck('key-result'); + tabAndCheck('add-keyResult', 'Key Result hinzufügen'); }); - describe("Objective", () => { - it("should be able to tab objective dialog", () => { - tabAndCheck("add-objective", "Objective hinzufügen"); - cy.realPress("Enter"); - cy.contains("h2", "Objective für"); - tabAndCheck("title"); - cy.realType("title"); - tabAndCheck("description"); - cy.realType("description"); - tabAndCheck("quarterSelect"); - tabAndCheck("save-draft"); - tabAndCheck("save"); - tabAndCheck("cancel"); + describe('Objective', () => { + it('should be able to tab objective dialog', () => { + tabAndCheck('add-objective', 'Objective hinzufügen'); + cy.realPress('Enter'); + cy.contains('h2', 'Objective für'); + tabAndCheck('title'); + cy.realType('title'); + tabAndCheck('description'); + cy.realType('description'); + tabAndCheck('quarterSelect'); + tabAndCheck('save-draft'); + tabAndCheck('save'); + tabAndCheck('cancel'); }); - it("should focus three dot menu after edit objective", () => { - overviewPage.getObjectiveByState("ongoing") + it('should focus three dot menu after edit objective', () => { + overviewPage.getObjectiveByState('ongoing') .focus(); - tabAndCheck("three-dot-menu"); - cy.realPress("Enter"); - tabToThreeDotMenuOption("Objective bearbeiten"); - cy.contains("h2", "Objective von"); - tabAndCheck("title"); - cy.realType("title"); - tabAndCheck("description"); - cy.realType("description"); - tabAndCheck("quarterSelect"); - tabAndCheck("cancel", "Abbrechen"); - tabAndCheck("save", "Speichern"); - cy.realPress("Enter"); - focusedShouldHaveTestId("three-dot-menu"); + tabAndCheck('three-dot-menu'); + cy.realPress('Enter'); + tabToThreeDotMenuOption('Objective bearbeiten'); + cy.contains('h2', 'Objective von'); + tabAndCheck('title'); + cy.realType('title'); + tabAndCheck('description'); + cy.realType('description'); + tabAndCheck('quarterSelect'); + tabAndCheck('cancel', 'Abbrechen'); + tabAndCheck('save', 'Speichern'); + cy.realPress('Enter'); + focusedShouldHaveTestId('three-dot-menu'); }); - it("should be able to complete and reopen objective", () => { - overviewPage.getObjectiveByState("ongoing") + it('should be able to complete and reopen objective', () => { + overviewPage.getObjectiveByState('ongoing') .focus(); - tabAndCheck("three-dot-menu"); - cy.realPress("Enter"); - tabToThreeDotMenuOption("Objective abschliessen"); - cy.contains("h2", "Objective abschliessen "); - focusedShouldHaveTestId("close-dialog"); + tabAndCheck('three-dot-menu'); + cy.realPress('Enter'); + tabToThreeDotMenuOption('Objective abschliessen'); + cy.contains('h2', 'Objective abschliessen '); + focusedShouldHaveTestId('close-dialog'); cy.tabForward(); cy.focused() - .contains("Objective erreicht"); - cy.realPress("Enter"); + .contains('Objective erreicht'); + cy.realPress('Enter'); cy.tabForward(); cy.focused() - .contains("Objective nicht erreicht"); - tabAndCheck("completeComment"); - tabAndCheck("cancel", "Abbrechen"); - tabAndCheck("submit", "Objective abschliessen"); - cy.realPress("Enter"); + .contains('Objective nicht erreicht'); + tabAndCheck('completeComment'); + tabAndCheck('cancel', 'Abbrechen'); + tabAndCheck('submit', 'Objective abschliessen'); + cy.realPress('Enter'); - focusedShouldHaveTestId("three-dot-menu"); - cy.realPress("Enter"); + focusedShouldHaveTestId('three-dot-menu'); + cy.realPress('Enter'); - tabToThreeDotMenuOption("Objective wiedereröffnen"); - cy.contains("h2", "Objective wiedereröffnen"); - focusedShouldHaveTestId("close-dialog"); - cy.contains("Soll dieses Objective wiedereröffnet werden?"); - tabAndCheck("confirm-no", "Nein"); - tabAndCheck("confirm-yes", "Ja"); - cy.realPress("Enter"); - focusedShouldHaveTestId("three-dot-menu"); + tabToThreeDotMenuOption('Objective wiedereröffnen'); + cy.contains('h2', 'Objective wiedereröffnen'); + focusedShouldHaveTestId('close-dialog'); + cy.contains('Soll dieses Objective wiedereröffnet werden?'); + tabAndCheck('confirm-no', 'Nein'); + tabAndCheck('confirm-yes', 'Ja'); + cy.realPress('Enter'); + focusedShouldHaveTestId('three-dot-menu'); }); - it("should be able to set objective to draft and publish it", () => { - overviewPage.getObjectiveByState("ongoing") + it('should be able to set objective to draft and publish it', () => { + overviewPage.getObjectiveByState('ongoing') .focus(); - tabAndCheck("three-dot-menu"); - cy.realPress("Enter"); - tabToThreeDotMenuOption("Objective als Draft speichern"); - cy.contains("h2", "Objective als Draft speichern"); - focusedShouldHaveTestId("close-dialog"); - cy.contains("Soll dieses Objective als Draft gespeichert werden?"); - tabAndCheck("confirm-no", "Nein"); - tabAndCheck("confirm-yes", "Ja"); - cy.realPress("Enter"); + tabAndCheck('three-dot-menu'); + cy.realPress('Enter'); + tabToThreeDotMenuOption('Objective als Draft speichern'); + cy.contains('h2', 'Objective als Draft speichern'); + focusedShouldHaveTestId('close-dialog'); + cy.contains('Soll dieses Objective als Draft gespeichert werden?'); + tabAndCheck('confirm-no', 'Nein'); + tabAndCheck('confirm-yes', 'Ja'); + cy.realPress('Enter'); - focusedShouldHaveTestId("three-dot-menu"); - cy.realPress("Enter"); + focusedShouldHaveTestId('three-dot-menu'); + cy.realPress('Enter'); - tabToThreeDotMenuOption("Objective veröffentlichen"); - cy.contains("h2", "Objective veröffentlichen"); - focusedShouldHaveTestId("close-dialog"); - cy.contains("Soll dieses Objective veröffentlicht werden?"); - tabAndCheck("confirm-no", "Nein"); - tabAndCheck("confirm-yes", "Ja"); - cy.realPress("Enter"); - focusedShouldHaveTestId("three-dot-menu"); + tabToThreeDotMenuOption('Objective veröffentlichen'); + cy.contains('h2', 'Objective veröffentlichen'); + focusedShouldHaveTestId('close-dialog'); + cy.contains('Soll dieses Objective veröffentlicht werden?'); + tabAndCheck('confirm-no', 'Nein'); + tabAndCheck('confirm-yes', 'Ja'); + cy.realPress('Enter'); + focusedShouldHaveTestId('three-dot-menu'); }); - it("should be able to open objective detail view", () => { - overviewPage.getObjectiveByState("ongoing") + it('should be able to open objective detail view', () => { + overviewPage.getObjectiveByState('ongoing') .focus(); - cy.realPress("Enter") + cy.realPress('Enter') .tabForward(); - focusedShouldHaveTestId("closeDrawer"); - tabAndCheck("add-keyResult-objective-detail", "Key Result hinzufügen"); - tabAndCheck("edit-objective", "Objective bearbeiten"); + focusedShouldHaveTestId('closeDrawer'); + tabAndCheck('add-keyResult-objective-detail', 'Key Result hinzufügen'); + tabAndCheck('edit-objective', 'Objective bearbeiten'); }); }); - describe("Keyresult & Check-In", () => { - it("Should be able to tab Keyresult dialog", () => { - tabAndCheck("add-keyResult", "Key Result hinzufügen"); - cy.realPress("Enter"); - focusedShouldHaveTestId("close-dialog"); - tabAndCheck("titleInput"); + describe('Keyresult & Check-In', () => { + it('Should be able to tab Keyresult dialog', () => { + tabAndCheck('add-keyResult', 'Key Result hinzufügen'); + cy.realPress('Enter'); + focusedShouldHaveTestId('close-dialog'); + tabAndCheck('titleInput'); cy.focused() - .type("Title"); - tabAndCheck("unit"); - tabAndCheck("baseline"); - tabAndCheck("stretchGoal"); - tabAndCheck("ownerInput"); - tabAndCheck("descriptionInput"); - tabAndCheck("actionInput"); - tabAndCheck("add-action-plan-line", "Weitere Action hinzufügen"); - tabAndCheck("ordinalTab", "Ordinal"); - cy.realPress("Enter"); - tabAndCheck("commitZone"); + .type('Title'); + tabAndCheck('unit'); + tabAndCheck('baseline'); + tabAndCheck('stretchGoal'); + tabAndCheck('ownerInput'); + tabAndCheck('descriptionInput'); + tabAndCheck('actionInput'); + tabAndCheck('add-action-plan-line', 'Weitere Action hinzufügen'); + tabAndCheck('ordinalTab', 'Ordinal'); + cy.realPress('Enter'); + tabAndCheck('commitZone'); cy.focused() - .type("Commit"); - tabAndCheck("targetZone"); + .type('Commit'); + tabAndCheck('targetZone'); cy.focused() - .type("Target"); - tabAndCheck("stretchZone"); + .type('Target'); + tabAndCheck('stretchZone'); cy.focused() - .type("Stretch"); - tabAndCheck("submit", "Speichern"); - tabAndCheck("saveAndNew", "Speichern & Neu"); - tabAndCheck("cancel", "Abbrechen"); + .type('Stretch'); + tabAndCheck('submit', 'Speichern'); + tabAndCheck('saveAndNew', 'Speichern & Neu'); + tabAndCheck('cancel', 'Abbrechen'); }); - it("Should tab keyresult detail view", () => { - overviewPage.getObjectiveByState("ongoing") - .findByTestId("key-result") + it('Should tab keyresult detail view', () => { + overviewPage.getObjectiveByState('ongoing') + .findByTestId('key-result') .first() .focus(); - cy.realPress("Enter") + cy.realPress('Enter') .tabForward(); - focusedShouldHaveTestId("close-drawer"); - tabAndCheck("show-all-checkins", "Alle Check-ins anzeigen"); - cy.realPress("Enter"); - cy.contains("Check-in History"); - focusedShouldHaveTestId("close-dialog"); - tabAndCheck("edit-check-in"); - tabAndCheck("closeButton", "Schliessen"); - cy.realPress("Enter"); - tabAndCheck("add-check-in", "Check-in erfassen"); - tabAndCheck("edit-keyResult", "Key Result bearbeiten"); + focusedShouldHaveTestId('close-drawer'); + tabAndCheck('show-all-checkins', 'Alle Check-ins anzeigen'); + cy.realPress('Enter'); + cy.contains('Check-in History'); + focusedShouldHaveTestId('close-dialog'); + tabAndCheck('edit-check-in'); + tabAndCheck('closeButton', 'Schliessen'); + cy.realPress('Enter'); + tabAndCheck('add-check-in', 'Check-in erfassen'); + tabAndCheck('edit-keyResult', 'Key Result bearbeiten'); }); - it("Should tab create-check-in metric", () => { + it('Should tab create-check-in metric', () => { overviewPage .addOngoingKeyResult() - .fillKeyResultTitle("A metric Keyresult for tabbing tests") - .withMetricValues(Unit.CHF, "10", "100") + .fillKeyResultTitle('A metric Keyresult for tabbing tests') + .withMetricValues(Unit.CHF, '10', '100') .submit(); KeyResultDetailPage.do() - .visit("A metric Keyresult for tabbing tests"); - tabAndCheck("add-check-in", "Check-in erfassen"); - cy.realPress("Enter"); - cy.contains("Check-in erfassen"); - focusedShouldHaveTestId("close-dialog"); - tabAndCheck("changeInfo"); - tabAndCheck("check-in-metric-value"); + .visit('A metric Keyresult for tabbing tests'); + tabAndCheck('add-check-in', 'Check-in erfassen'); + cy.realPress('Enter'); + cy.contains('Check-in erfassen'); + focusedShouldHaveTestId('close-dialog'); + tabAndCheck('changeInfo'); + tabAndCheck('check-in-metric-value'); cy.focused() - .type("20"); - tabAndCheck("initiatives"); - cy.contains("5/10"); + .type('20'); + tabAndCheck('initiatives'); + cy.contains('5/10'); cy.tabForward(); - cy.realPress("ArrowLeft"); - cy.contains("4/10"); - tabAndCheck("submit-check-in", "Check-in speichern"); - tabAndCheck("cancel", "Abbrechen"); + cy.realPress('ArrowLeft'); + cy.contains('4/10'); + tabAndCheck('submit-check-in', 'Check-in speichern'); + tabAndCheck('cancel', 'Abbrechen'); }); - it("Should tab create-check-in ordinal", () => { + it('Should tab create-check-in ordinal', () => { overviewPage .addOngoingKeyResult() - .fillKeyResultTitle("A ordinal Keyresult for tabbing tests") - .withOrdinalValues("Commit", "Target", "Stretch") + .fillKeyResultTitle('A ordinal Keyresult for tabbing tests') + .withOrdinalValues('Commit', 'Target', 'Stretch') .submit(); KeyResultDetailPage.do() - .visit("A ordinal Keyresult for tabbing tests"); - tabAndCheck("add-check-in", "Check-in erfassen"); - cy.realPress("Enter"); - cy.contains("Check-in erfassen"); - focusedShouldHaveTestId("close-dialog"); - tabAndCheck("changeInfo"); + .visit('A ordinal Keyresult for tabbing tests'); + tabAndCheck('add-check-in', 'Check-in erfassen'); + cy.realPress('Enter'); + cy.contains('Check-in erfassen'); + focusedShouldHaveTestId('close-dialog'); + tabAndCheck('changeInfo'); cy.tabForward(); cy.focused() - .closest("mat-radio-button") - .should("have.attr", "data-testId", "fail-radio"); - cy.realPress("ArrowDown"); + .closest('mat-radio-button') + .should('have.attr', 'data-testId', 'fail-radio'); + cy.realPress('ArrowDown'); cy.focused() - .closest("mat-radio-button") - .should("have.attr", "data-testId", "commit-radio"); - cy.realPress("ArrowDown"); + .closest('mat-radio-button') + .should('have.attr', 'data-testId', 'commit-radio'); + cy.realPress('ArrowDown'); cy.focused() - .closest("mat-radio-button") - .should("have.attr", "data-testId", "target-radio"); - cy.realPress("ArrowDown"); + .closest('mat-radio-button') + .should('have.attr', 'data-testId', 'target-radio'); + cy.realPress('ArrowDown'); cy.focused() - .closest("mat-radio-button") - .should("have.attr", "data-testId", "stretch-radio"); - tabAndCheck("initiatives"); - cy.contains("5/10"); + .closest('mat-radio-button') + .should('have.attr', 'data-testId', 'stretch-radio'); + tabAndCheck('initiatives'); + cy.contains('5/10'); cy.tabForward(); - cy.realPress("ArrowLeft"); - cy.contains("4/10"); - tabAndCheck("submit-check-in", "Check-in speichern"); - tabAndCheck("cancel", "Abbrechen"); + cy.realPress('ArrowLeft'); + cy.contains('4/10'); + tabAndCheck('submit-check-in', 'Check-in speichern'); + tabAndCheck('cancel', 'Abbrechen'); }); }); - describe("Team management", () => { - it("Should tab team management", () => { - tabAndCheck("team-management", "Teamverwaltung"); - cy.realPress("Enter"); - tabAndCheck("routerLink-to-overview", "Zurück zur OKR Übersicht"); - tabAndCheck("teamManagementSearch"); - tabAndCheck("add-team", "Team erfassen"); - tabAndCheck("all-teams-selector", "Alle Teams (4)"); - tabAndCheck("invite-member", "Member registrieren"); + describe('Team management', () => { + it('Should tab team management', () => { + tabAndCheck('team-management', 'Teamverwaltung'); + cy.realPress('Enter'); + tabAndCheck('routerLink-to-overview', 'Zurück zur OKR Übersicht'); + tabAndCheck('teamManagementSearch'); + tabAndCheck('add-team', 'Team erfassen'); + tabAndCheck('all-teams-selector', 'Alle Teams (4)'); + tabAndCheck('invite-member', 'Member registrieren'); }); - it("Should tab create team", () => { - cy.getByTestId("team-management") + it('Should tab create team', () => { + cy.getByTestId('team-management') .click(); - tabAndCheck("add-team"); - cy.realPress("Enter"); - cy.contains("Team erfassen"); - focusedShouldHaveTestId("close-dialog"); - tabAndCheck("add-team-name"); + tabAndCheck('add-team'); + cy.realPress('Enter'); + cy.contains('Team erfassen'); + focusedShouldHaveTestId('close-dialog'); + tabAndCheck('add-team-name'); cy.focused() - .type("Name of new team"); - tabAndCheck("save", "Speichern"); - tabAndCheck("cancel", "Abbrechen"); + .type('Name of new team'); + tabAndCheck('save', 'Speichern'); + tabAndCheck('cancel', 'Abbrechen'); }); - it("Should tab register member", () => { - cy.getByTestId("team-management") + it('Should tab register member', () => { + cy.getByTestId('team-management') .click(); - tabAndCheck("invite-member"); - cy.realPress("Enter"); - cy.contains("Member registrieren"); - focusedShouldHaveTestId("close-dialog"); - tabAndCheck("new-member-first-name"); - tabAndCheck("new-member-last-name"); - tabAndCheck("email-col_0"); + tabAndCheck('invite-member'); + cy.realPress('Enter'); + cy.contains('Member registrieren'); + focusedShouldHaveTestId('close-dialog'); + tabAndCheck('new-member-first-name'); + tabAndCheck('new-member-last-name'); + tabAndCheck('email-col_0'); cy.tabForward(); cy.focused() - .closest("app-puzzle-icon-button") - .should("have.attr", "icon", "delete-icon.svg"); - tabAndCheck("new-member-add-row", "Weiterer Member hinzufügen"); - tabAndCheck("invite", "Einladen"); - tabAndCheck("new-member-cancel", "Abbrechen"); + .closest('app-puzzle-icon-button') + .should('have.attr', 'icon', 'delete-icon.svg'); + tabAndCheck('new-member-add-row', 'Weiterer Member hinzufügen'); + tabAndCheck('invite', 'Einladen'); + tabAndCheck('new-member-cancel', 'Abbrechen'); }); - it("Should tab edit member", () => { - cy.getByTestId("team-management") + it('Should tab edit member', () => { + cy.getByTestId('team-management') .click(); - cy.pressUntilContains("Alice Wunderland", "Tab"); + cy.pressUntilContains('Alice Wunderland', 'Tab'); cy.tabForward(); - cy.realPress("Enter"); + cy.realPress('Enter'); cy.tabForward(); - focusedShouldHaveTestId("close-drawer"); + focusedShouldHaveTestId('close-drawer'); // Field to toggle if user is OKR-Champion cy.tabForward(); cy.focused() - .closest("app-puzzle-icon-button") - .should("have.attr", "icon", "edit.svg"); - cy.realPress("Enter"); + .closest('app-puzzle-icon-button') + .should('have.attr', 'icon', 'edit.svg'); + cy.realPress('Enter'); cy.tabForward(); - tabAndCheck("close-drawer"); + tabAndCheck('close-drawer'); cy.tabForward(); cy.focused() - .closest("mat-checkbox") - .should("have.attr", "data-testId", "edit-okr-champion-checkbox"); + .closest('mat-checkbox') + .should('have.attr', 'data-testId', 'edit-okr-champion-checkbox'); // Field to edit role of assigned team cy.tabForward(); cy.focused() - .closest("app-puzzle-icon-button") - .should("have.attr", "icon", "edit.svg"); - cy.realPress("Enter"); + .closest('app-puzzle-icon-button') + .should('have.attr', 'icon', 'edit.svg'); + cy.realPress('Enter'); cy.tabForward(); - tabAndCheck("select-team-role", "Team-Member"); + tabAndCheck('select-team-role', 'Team-Member'); // Button to delete assigned team cy.tabForward(); cy.focused() - .closest("app-puzzle-icon-button") - .should("have.attr", "icon", "delete-icon.svg"); + .closest('app-puzzle-icon-button') + .should('have.attr', 'icon', 'delete-icon.svg'); // Button to add user to another team - tabAndCheck("add-user"); - cy.realPress("Enter"); + tabAndCheck('add-user'); + cy.realPress('Enter'); cy.tabForward(); - tabAndCheck("select-team-dropdown", "Puzzle ITC"); - tabAndCheck("select-team-role", "Team-Member"); - tabAndCheck("add-user-to-team-save", "Hinzufügen"); - tabAndCheck("add-user-to-team-cancel", "Abbrechen"); + tabAndCheck('select-team-dropdown', 'Puzzle ITC'); + tabAndCheck('select-team-role', 'Team-Member'); + tabAndCheck('add-user-to-team-save', 'Hinzufügen'); + tabAndCheck('add-user-to-team-cancel', 'Abbrechen'); }); }); }); function tabToThreeDotMenuOption(name: string) { - cy.pressUntilContains(name, "ArrowDown"); - cy.realPress("Enter"); + cy.pressUntilContains(name, 'ArrowDown'); + cy.realPress('Enter'); } diff --git a/frontend/cypress/e2e/team.cy.ts b/frontend/cypress/e2e/team.cy.ts index f4dc510ce0..50a88bc4a0 100644 --- a/frontend/cypress/e2e/team.cy.ts +++ b/frontend/cypress/e2e/team.cy.ts @@ -1,147 +1,147 @@ -import * as users from "../fixtures/users.json"; -import FilterHelper from "../support/helper/dom-helper/filterHelper"; -import CyOverviewPage from "../support/helper/dom-helper/pages/overviewPage"; -import TeammanagementPage from "../support/helper/dom-helper/pages/teammanagementPage"; +import * as users from '../fixtures/users.json'; +import FilterHelper from '../support/helper/dom-helper/filterHelper'; +import CyOverviewPage from '../support/helper/dom-helper/pages/overviewPage'; +import TeammanagementPage from '../support/helper/dom-helper/pages/teammanagementPage'; -describe("OKR team e2e tests", () => { - describe("tests via click", () => { +describe('OKR team e2e tests', () => { + describe('tests via click', () => { beforeEach(() => { cy.loginAsUser(users.gl); CyOverviewPage.do() .visitCurrentQuarter(); }); - it("Should select teams from teamfilter", () => { + it('Should select teams from teamfilter', () => { const filterHelper = FilterHelper.do() - .optionShouldBeSelected("Puzzle ITC") - .optionShouldBeSelected("LoremIpsum") - .optionShouldNotBeSelected("Alle") - .optionShouldNotBeSelected("/BBT") - .optionShouldNotBeSelected("we are cube"); + .optionShouldBeSelected('Puzzle ITC') + .optionShouldBeSelected('LoremIpsum') + .optionShouldNotBeSelected('Alle') + .optionShouldNotBeSelected('/BBT') + .optionShouldNotBeSelected('we are cube'); filterHelper - .toggleOption("Alle") - .optionShouldBeSelected("Alle", false) - .optionShouldBeSelected("/BBT") - .optionShouldBeSelected("Puzzle ITC") - .optionShouldBeSelected("LoremIpsum") - .optionShouldBeSelected("we are cube"); + .toggleOption('Alle') + .optionShouldBeSelected('Alle', false) + .optionShouldBeSelected('/BBT') + .optionShouldBeSelected('Puzzle ITC') + .optionShouldBeSelected('LoremIpsum') + .optionShouldBeSelected('we are cube'); filterHelper - .toggleOption("/BBT") - .optionShouldBeSelected("/BBT") - .optionShouldNotBeSelected("Alle") - .optionShouldNotBeSelected("Puzzle ITC") - .optionShouldNotBeSelected("LoremIpsum") - .optionShouldNotBeSelected("we are cube"); + .toggleOption('/BBT') + .optionShouldBeSelected('/BBT') + .optionShouldNotBeSelected('Alle') + .optionShouldNotBeSelected('Puzzle ITC') + .optionShouldNotBeSelected('LoremIpsum') + .optionShouldNotBeSelected('we are cube'); filterHelper - .toggleOption("Puzzle ITC") - .optionShouldBeSelected("/BBT") - .optionShouldNotBeSelected("Alle") - .optionShouldBeSelected("Puzzle ITC") - .optionShouldNotBeSelected("LoremIpsum") - .optionShouldNotBeSelected("we are cube"); + .toggleOption('Puzzle ITC') + .optionShouldBeSelected('/BBT') + .optionShouldNotBeSelected('Alle') + .optionShouldBeSelected('Puzzle ITC') + .optionShouldNotBeSelected('LoremIpsum') + .optionShouldNotBeSelected('we are cube'); }); - it("Deselect all teams from filter will display text on overview", () => { + it('Deselect all teams from filter will display text on overview', () => { const filterHelper = FilterHelper.do() - .optionShouldBeSelected("Puzzle ITC") - .optionShouldBeSelected("LoremIpsum") - .optionShouldNotBeSelected("Alle") - .optionShouldNotBeSelected("/BBT") - .optionShouldNotBeSelected("we are cube"); + .optionShouldBeSelected('Puzzle ITC') + .optionShouldBeSelected('LoremIpsum') + .optionShouldNotBeSelected('Alle') + .optionShouldNotBeSelected('/BBT') + .optionShouldNotBeSelected('we are cube'); - filterHelper.toggleOption("Puzzle ITC") - .toggleOption("LoremIpsum"); + filterHelper.toggleOption('Puzzle ITC') + .toggleOption('LoremIpsum'); - cy.contains("Kein Team ausgewählt"); + cy.contains('Kein Team ausgewählt'); }); - it("URL changes to the selected teams", () => { + it('URL changes to the selected teams', () => { const filterHelper = FilterHelper.do() - .optionShouldBeSelected("Puzzle ITC") - .optionShouldBeSelected("LoremIpsum") - .optionShouldNotBeSelected("Alle") - .optionShouldNotBeSelected("/BBT") - .optionShouldNotBeSelected("we are cube"); - - filterHelper.validateUrlParameter("teams", ["5", - "6"]); - - filterHelper.toggleOption("/BBT") - .validateUrlParameter("teams", ["4", - "5", - "6"]); - filterHelper.toggleOption("Puzzle ITC") - .toggleOption("LoremIpsum") - .toggleOption("/BBT"); + .optionShouldBeSelected('Puzzle ITC') + .optionShouldBeSelected('LoremIpsum') + .optionShouldNotBeSelected('Alle') + .optionShouldNotBeSelected('/BBT') + .optionShouldNotBeSelected('we are cube'); + + filterHelper.validateUrlParameter('teams', ['5', + '6']); + + filterHelper.toggleOption('/BBT') + .validateUrlParameter('teams', ['4', + '5', + '6']); + filterHelper.toggleOption('Puzzle ITC') + .toggleOption('LoremIpsum') + .toggleOption('/BBT'); cy.url() - .should("not.include", "teams="); + .should('not.include', 'teams='); }); - it("Select teams by url", () => { + it('Select teams by url', () => { cy.url() - .should("not.include", "teams"); + .should('not.include', 'teams'); - cy.visit("/?quarter=2&teams=4,5,8"); + cy.visit('/?quarter=2&teams=4,5,8'); FilterHelper.do() - .optionShouldNotBeSelected("Alle") - .optionShouldBeSelected("/BBT") - .optionShouldBeSelected("Puzzle ITC") - .optionShouldBeSelected("we are cube") - .optionShouldNotBeSelected("LoremIpsum"); + .optionShouldNotBeSelected('Alle') + .optionShouldBeSelected('/BBT') + .optionShouldBeSelected('Puzzle ITC') + .optionShouldBeSelected('we are cube') + .optionShouldNotBeSelected('LoremIpsum'); }); - it("should display less button on mobile header", () => { + it('should display less button on mobile header', () => { const teammanagementPage = TeammanagementPage.do() .visitViaURL(); - cy.intercept("POST", "**/teams") - .as("addTeam"); + cy.intercept('POST', '**/teams') + .as('addTeam'); teammanagementPage.addTeam() - .fillName("X-Team") + .fillName('X-Team') .submit(); - cy.wait("@addTeam"); - cy.contains("X-Team"); + cy.wait('@addTeam'); + cy.contains('X-Team'); teammanagementPage.addTeam() - .fillName("Y-Team") + .fillName('Y-Team') .submit(); - cy.wait("@addTeam"); - cy.contains("Y-Team"); + cy.wait('@addTeam'); + cy.contains('Y-Team'); teammanagementPage.addTeam() - .fillName("Z-Team") + .fillName('Z-Team') .submit(); - cy.wait("@addTeam"); - cy.contains("Z-Team"); + cy.wait('@addTeam'); + cy.contains('Z-Team'); teammanagementPage.visitOverview(); // set viewport to < 768 to trigger mobile header cy.viewport(767, 1200); - cy.getByTestId("expansion-panel-header") + cy.getByTestId('expansion-panel-header') .click(); - cy.contains("Weniger"); + cy.contains('Weniger'); // reset viewport - cy.viewport(Cypress.config("viewportWidth"), Cypress.config("viewportHeight")); + cy.viewport(Cypress.config('viewportWidth'), Cypress.config('viewportHeight')); cy.visit(`${teammanagementPage.getURL()}`); - cy.intercept("DELETE", "**/teams/*") - .as("deleteTeam"); + cy.intercept('DELETE', '**/teams/*') + .as('deleteTeam'); - teammanagementPage.deleteTeam("X-Team") + teammanagementPage.deleteTeam('X-Team') .submit(); - cy.wait("@deleteTeam"); + cy.wait('@deleteTeam'); - teammanagementPage.deleteTeam("Y-Team") + teammanagementPage.deleteTeam('Y-Team') .submit(); - cy.wait("@deleteTeam"); + cy.wait('@deleteTeam'); - teammanagementPage.deleteTeam("Z-Team") + teammanagementPage.deleteTeam('Z-Team') .submit(); - cy.wait("@deleteTeam"); + cy.wait('@deleteTeam'); }); }); }); diff --git a/frontend/cypress/e2e/teammanagement.cy.ts b/frontend/cypress/e2e/teammanagement.cy.ts index a5ff09e6e8..f9ca5bfbef 100644 --- a/frontend/cypress/e2e/teammanagement.cy.ts +++ b/frontend/cypress/e2e/teammanagement.cy.ts @@ -1,26 +1,26 @@ -import * as users from "../fixtures/users.json"; -import { uniqueSuffix } from "../support/helper/utils"; -import ConfirmDialog from "../support/helper/dom-helper/dialogs/confirmDialog"; -import TeammanagementPage from "../support/helper/dom-helper/pages/teammanagementPage"; -import CyOverviewPage from "../support/helper/dom-helper/pages/overviewPage"; -import InviteMembersDialog from "../support/helper/dom-helper/dialogs/inviteMembersDialog"; -import FilterHelper from "../support/helper/dom-helper/filterHelper"; - -describe("Team management tests", () => { - const teamName = uniqueSuffix("New Team"); +import * as users from '../fixtures/users.json'; +import { uniqueSuffix } from '../support/helper/utils'; +import ConfirmDialog from '../support/helper/dom-helper/dialogs/confirmDialog'; +import TeammanagementPage from '../support/helper/dom-helper/pages/teammanagementPage'; +import CyOverviewPage from '../support/helper/dom-helper/pages/overviewPage'; +import InviteMembersDialog from '../support/helper/dom-helper/dialogs/inviteMembersDialog'; +import FilterHelper from '../support/helper/dom-helper/filterHelper'; + +describe('Team management tests', () => { + const teamName = uniqueSuffix('New Team'); const nameEsha = users.bl.name; - describe("Routing to overview", () => { + describe('Routing to overview', () => { beforeEach(() => { cy.loginAsUser(users.gl); }); - it("should preserve team filter", () => { + it('should preserve team filter', () => { CyOverviewPage.do() .visitViaURL(); FilterHelper.do() - .toggleOption("/BBT") - .toggleOption("Puzzle ITC"); + .toggleOption('/BBT') + .toggleOption('Puzzle ITC'); checkTeamsSelected(); CyOverviewPage.do() .visitTeammanagement(); @@ -37,19 +37,19 @@ describe("Team management tests", () => { function checkTeamsSelected() { FilterHelper.do() - .optionShouldBeSelected("LoremIpsum") - .optionShouldBeSelected("/BBT"); + .optionShouldBeSelected('LoremIpsum') + .optionShouldBeSelected('/BBT'); } }); - describe("As GL", () => { + describe('As GL', () => { let teammanagementPage: TeammanagementPage; before(() => { // login as bl to ensure this user exists in database cy.loginAsUser(users.bl); - cy.getByTestId("user-name") + cy.getByTestId('user-name') .click(); - cy.getByTestId("logout") + cy.getByTestId('logout') .click(); }); @@ -59,91 +59,91 @@ describe("Team management tests", () => { .visitViaURL(); }); - it("Create team", () => { - cy.intercept("POST", "**/teams") - .as("addTeam"); + it('Create team', () => { + cy.intercept('POST', '**/teams') + .as('addTeam'); teammanagementPage.addTeam() .fillName(teamName) .submit(); - cy.wait("@addTeam"); + cy.wait('@addTeam'); cy.contains(teamName); }); - it("Try to remove last admin of team should not work", () => { - cy.intercept("PUT", "**/removeuser") - .as("removeUser"); + it('Try to remove last admin of team should not work', () => { + cy.intercept('PUT', '**/removeuser') + .as('removeUser'); - cy.get("app-team-list .mat-mdc-list-item") + cy.get('app-team-list .mat-mdc-list-item') .contains(teamName) .click(); - cy.getByTestId("member-list-more") + cy.getByTestId('member-list-more') .click(); - cy.getByTestId("remove-from-member-list") + cy.getByTestId('remove-from-member-list') .click(); ConfirmDialog.do() - .checkTitle("Mitglied entfernen") + .checkTitle('Mitglied entfernen') .checkDescription(`Möchtest du Jaya Norris wirklich aus dem Team '${teamName}' entfernen?`) .submit(); - cy.wait("@removeUser"); + cy.wait('@removeUser'); - cy.contains("Der letzte Administrator eines Teams kann nicht entfernt werden") - .should("exist"); + cy.contains('Der letzte Administrator eines Teams kann nicht entfernt werden') + .should('exist'); }); - it("clicking cancel in dialog when removing user should not remove user", () => { - cy.intercept("PUT", "**/removeuser") - .as("removeUser"); + it('clicking cancel in dialog when removing user should not remove user', () => { + cy.intercept('PUT', '**/removeuser') + .as('removeUser'); - cy.get("app-team-list .mat-mdc-list-item") + cy.get('app-team-list .mat-mdc-list-item') .contains(teamName) .click(); - cy.getByTestId("member-list-more") + cy.getByTestId('member-list-more') .click(); - cy.getByTestId("remove-from-member-list") + cy.getByTestId('remove-from-member-list') .click(); // cancel dialog ConfirmDialog.do() - .checkTitle("Mitglied entfernen") + .checkTitle('Mitglied entfernen') .checkDescription(`Möchtest du Jaya Norris wirklich aus dem Team '${teamName}' entfernen?`) .cancel(); - cy.get("@removeUser.all") + cy.get('@removeUser.all') .then((interceptions) => { expect(interceptions).to.have.length(0); }); }); - it("Edit team", () => { - cy.intercept("GET", "**/users") - .as("getUsers"); - cy.intercept("GET", "**/teams") - .as("getTeams"); + it('Edit team', () => { + cy.intercept('GET', '**/users') + .as('getUsers'); + cy.intercept('GET', '**/teams') + .as('getTeams'); - cy.get("app-team-list .mat-mdc-list-item") - .contains("LoremIpsum") + cy.get('app-team-list .mat-mdc-list-item') + .contains('LoremIpsum') .click(); - editTeamNameAndTest("IpsumLorem"); - cy.visit("team-management"); + editTeamNameAndTest('IpsumLorem'); + cy.visit('team-management'); - cy.wait(["@getUsers", - "@getTeams"]); + cy.wait(['@getUsers', + '@getTeams']); - cy.contains("LoremIpsum") - .should("not.exist"); - cy.contains("IpsumLorem") - .should("exist"); + cy.contains('LoremIpsum') + .should('not.exist'); + cy.contains('IpsumLorem') + .should('exist'); // set old team name again - cy.get("app-team-list .mat-mdc-list-item") - .contains("IpsumLorem") + cy.get('app-team-list .mat-mdc-list-item') + .contains('IpsumLorem') .click(); - editTeamNameAndTest("LoremIpsum"); + editTeamNameAndTest('LoremIpsum'); }); - it("Delete team", () => { + it('Delete team', () => { // Click delete button and cancel teammanagementPage.deleteTeam(teamName) .cancel(); @@ -153,152 +153,152 @@ describe("Team management tests", () => { .submit(); }); - describe("Search", () => { - it("Search user", () => { + describe('Search', () => { + it('Search user', () => { teammanagementPage.elements .teamSearch() - .fill("pa") - .shouldHaveOption("Paco Eggimann (peggimann@puzzle.ch)") - .shouldHaveOption("Paco Egiman (egiman@puzzle.ch)") - .selectOption("Robin Papierer (papierer@puzzle.ch)"); + .fill('pa') + .shouldHaveOption('Paco Eggimann (peggimann@puzzle.ch)') + .shouldHaveOption('Paco Egiman (egiman@puzzle.ch)') + .selectOption('Robin Papierer (papierer@puzzle.ch)'); - cy.contains("app-member-detail h2", "Robin Papierer"); + cy.contains('app-member-detail h2', 'Robin Papierer'); }); - it("Search team", () => { + it('Search team', () => { teammanagementPage.elements.teamSearch() - .fill("we are") - .selectOption("we are cube.³"); + .fill('we are') + .selectOption('we are cube.³'); - cy.contains("app-member-list h2", "we are cube.³"); + cy.contains('app-member-list h2', 'we are cube.³'); }); - it("Search mixed", () => { + it('Search mixed', () => { teammanagementPage.elements .teamSearch() - .fill("puz") - .shouldHaveLabel("Members") - .shouldHaveLabel("Teams") - .shouldHaveOption("Paco Eggimann (peggimann@puzzle.ch)") - .shouldHaveOption("Paco Egiman (egiman@puzzle.ch)") - .shouldHaveOption("Robin Papierer (papierer@puzzle.ch)") - .shouldHaveOption("Puzzle ITC"); + .fill('puz') + .shouldHaveLabel('Members') + .shouldHaveLabel('Teams') + .shouldHaveOption('Paco Eggimann (peggimann@puzzle.ch)') + .shouldHaveOption('Paco Egiman (egiman@puzzle.ch)') + .shouldHaveOption('Robin Papierer (papierer@puzzle.ch)') + .shouldHaveOption('Puzzle ITC'); }); }); - describe("invite members", () => { - it("invite two members", () => { + describe('invite members', () => { + it('invite two members', () => { teammanagementPage.elements.registerMember() .click(); const firstNames = InviteMembersDialog.do() - .enterUser("Claudia", "Meier", "claudia.meier@test.ch") + .enterUser('Claudia', 'Meier', 'claudia.meier@test.ch') .addAnotherUser() - .enterUser("Stefan", "Schmidt", "stefan.schmidt@test.ch") + .enterUser('Stefan', 'Schmidt', 'stefan.schmidt@test.ch') .addAnotherUser() .getFirstNames(); // test error messages - fillOutNewUser("Robin", "", "papierer"); - cy.getByTestId("invite") + fillOutNewUser('Robin', '', 'papierer'); + cy.getByTestId('invite') .click(); - cy.contains("Angabe benötigt"); - cy.contains("E-Mail ungültig"); - cy.getByTestId("email-col_2") + cy.contains('Angabe benötigt'); + cy.contains('E-Mail ungültig'); + cy.getByTestId('email-col_2') .focus(); - cy.realType("@puzzle.ch"); - cy.contains("E-Mail ungültig") - .should("not.exist"); - cy.contains("E-Mail existiert bereits"); + cy.realType('@puzzle.ch'); + cy.contains('E-Mail ungültig') + .should('not.exist'); + cy.contains('E-Mail existiert bereits'); cy.tabBackward(); - cy.realType("Papirer"); - cy.contains("Angabe benötigt") - .should("not.exist"); + cy.realType('Papirer'); + cy.contains('Angabe benötigt') + .should('not.exist'); // delete last entry cy.tabForward(); cy.tabForward(); - cy.realPress("Enter"); - cy.contains("papiererr@puzzle.ch") - .should("not.exist"); + cy.realPress('Enter'); + cy.contains('papiererr@puzzle.ch') + .should('not.exist'); // save - cy.getByTestId("invite") + cy.getByTestId('invite') .click(); - cy.contains("Die Members wurden erfolgreich registriert"); + cy.contains('Die Members wurden erfolgreich registriert'); firstNames.forEach((email) => cy.contains(email)); }); }); - it("Navigate to Bobs profile and add him to BBT and LoremIpsum", () => { - cy.intercept("PUT", "**/updateaddteammembership/*") - .as("updateEsha"); + it('Navigate to Bobs profile and add him to BBT and LoremIpsum', () => { + cy.intercept('PUT', '**/updateaddteammembership/*') + .as('updateEsha'); navigateToUser(nameEsha); // add to team bbt as admin - cy.get("app-member-detail") - .findByTestId("add-user") + cy.get('app-member-detail') + .findByTestId('add-user') .click(); - cy.get("app-member-detail") - .findByTestId("select-team-dropdown") + cy.get('app-member-detail') + .findByTestId('select-team-dropdown') .click(); - cy.getByTestId("select-team-dropdown-option") - .contains("/BBT") + cy.getByTestId('select-team-dropdown-option') + .contains('/BBT') .click(); - cy.get("app-member-detail") - .findByTestId("select-team-role") + cy.get('app-member-detail') + .findByTestId('select-team-role') .click(); - cy.getByTestId("select-team-role-admin") + cy.getByTestId('select-team-role-admin') .click(); - cy.get("app-member-detail") - .findByTestId("add-user-to-team-save") + cy.get('app-member-detail') + .findByTestId('add-user-to-team-save') .click(); - cy.wait("@updateEsha"); + cy.wait('@updateEsha'); // add to team loremipsum as member - cy.get("app-member-detail") - .findByTestId("add-user") + cy.get('app-member-detail') + .findByTestId('add-user') .click(); - cy.get("app-member-detail") - .findByTestId("select-team-dropdown") + cy.get('app-member-detail') + .findByTestId('select-team-dropdown') .click(); // team BBT should not be in list anymore - cy.getByTestId("select-team-dropdown-option") - .should("not.contain", "/BBT"); + cy.getByTestId('select-team-dropdown-option') + .should('not.contain', '/BBT'); - cy.getByTestId("select-team-dropdown-option") - .contains("LoremIpsum") + cy.getByTestId('select-team-dropdown-option') + .contains('LoremIpsum') .click(); - cy.get("app-member-detail") - .findByTestId("select-team-role") + cy.get('app-member-detail') + .findByTestId('select-team-role') .click(); - cy.getByTestId("select-team-role-member") + cy.getByTestId('select-team-role-member') .click(); - cy.get("app-member-detail") - .findByTestId("add-user-to-team-save") + cy.get('app-member-detail') + .findByTestId('add-user-to-team-save') .click(); - cy.wait("@updateEsha"); + cy.wait('@updateEsha'); // check table checkRolesForEsha(); closeOverlay(); let foundEsha = false; - cy.get("app-member-list tbody tr") + cy.get('app-member-list tbody tr') .each(($row) => { - const usernameCell = $row.find("td:nth-child(2)"); + const usernameCell = $row.find('td:nth-child(2)'); if (usernameCell.text() .trim() === nameEsha) { foundEsha = true; - const roleCell = $row.find("td:nth-child(3)"); - const teamsCell = $row.find("td:nth-child(4)"); + const roleCell = $row.find('td:nth-child(3)'); + const teamsCell = $row.find('td:nth-child(4)'); expect(roleCell.text() - .trim()).to.equal("Team-Admin, Team-Member"); + .trim()).to.equal('Team-Admin, Team-Member'); expect(teamsCell.text() - .trim()).to.equal("/BBT, LoremIpsum"); + .trim()).to.equal('/BBT, LoremIpsum'); return false; } return true; @@ -308,282 +308,282 @@ describe("Team management tests", () => { }); }); - it("Navigate to user Esha and set as okr champion", () => { + it('Navigate to user Esha and set as okr champion', () => { navigateToUser(nameEsha); - cy.getByTestId("edit-okr-champion-readonly") - .contains("OKR Champion:"); - cy.getByTestId("edit-okr-champion-readonly") - .contains("Nein"); - cy.getByTestId("edit-okr-champion-edit") - .click(); - cy.getByTestId("edit-okr-champion-readonly") - .should("not.exist"); - cy.getByTestId("edit-okr-champion-checkbox") - .click(); - cy.getByTestId("edit-okr-champion-readonly") - .contains("OKR Champion:"); - cy.getByTestId("edit-okr-champion-readonly") - .contains("Ja"); - cy.contains("Der Member wurde erfolgreich aktualisiert."); + cy.getByTestId('edit-okr-champion-readonly') + .contains('OKR Champion:'); + cy.getByTestId('edit-okr-champion-readonly') + .contains('Nein'); + cy.getByTestId('edit-okr-champion-edit') + .click(); + cy.getByTestId('edit-okr-champion-readonly') + .should('not.exist'); + cy.getByTestId('edit-okr-champion-checkbox') + .click(); + cy.getByTestId('edit-okr-champion-readonly') + .contains('OKR Champion:'); + cy.getByTestId('edit-okr-champion-readonly') + .contains('Ja'); + cy.contains('Der Member wurde erfolgreich aktualisiert.'); // reset okr champion to false - cy.getByTestId("edit-okr-champion-edit") + cy.getByTestId('edit-okr-champion-edit') .click(); - cy.getByTestId("edit-okr-champion-checkbox") + cy.getByTestId('edit-okr-champion-checkbox') .click(); - cy.getByTestId("edit-okr-champion-readonly") - .contains("OKR Champion:"); - cy.getByTestId("edit-okr-champion-readonly") - .contains("Nein"); + cy.getByTestId('edit-okr-champion-readonly') + .contains('OKR Champion:'); + cy.getByTestId('edit-okr-champion-readonly') + .contains('Nein'); // test click outside of element - cy.getByTestId("edit-okr-champion-edit") + cy.getByTestId('edit-okr-champion-edit') .click(); - cy.get("app-member-detail") - .find("h2") + cy.get('app-member-detail') + .find('h2') .click(); // checkbox should hide again - cy.getByTestId("edit-okr-champion-readonly") - .contains("OKR Champion:"); - cy.getByTestId("edit-okr-champion-readonly") - .contains("Nein"); + cy.getByTestId('edit-okr-champion-readonly') + .contains('OKR Champion:'); + cy.getByTestId('edit-okr-champion-readonly') + .contains('Nein'); }); }); - describe("As BL", () => { + describe('As BL', () => { beforeEach(() => { cy.loginAsUser(users.bl); - cy.getByTestId("team-management") + cy.getByTestId('team-management') .click(); - cy.intercept("GET", "**/users/*") - .as("getEsha"); + cy.intercept('GET', '**/users/*') + .as('getEsha'); }); - it("should check if correct roles for BL are set", () => { - cy.get("td") + it('should check if correct roles for BL are set', () => { + cy.get('td') .contains(nameEsha) .click(); - cy.wait("@getEsha"); + cy.wait('@getEsha'); checkRolesForEsha(); closeOverlay(); }); - it("should check if team loremIpsum cannot be edited", () => { - cy.get("app-team-management") - .contains("LoremIpsum") - .click(); - cy.getByTestId("teamMoreButton") - .should("not.exist"); - cy.getByTestId("editTeamButton") - .should("not.exist"); - cy.getByTestId("member-list-more") - .should("not.exist"); - cy.getByTestId("edit-role") - .should("not.exist"); + it('should check if team loremIpsum cannot be edited', () => { + cy.get('app-team-management') + .contains('LoremIpsum') + .click(); + cy.getByTestId('teamMoreButton') + .should('not.exist'); + cy.getByTestId('editTeamButton') + .should('not.exist'); + cy.getByTestId('member-list-more') + .should('not.exist'); + cy.getByTestId('edit-role') + .should('not.exist'); }); - it("should check if team /BBT can be edited and edit name", () => { - cy.get("app-team-management") - .contains("/BBT") + it('should check if team /BBT can be edited and edit name', () => { + cy.get('app-team-management') + .contains('/BBT') .click(); - cy.getByTestId("teamMoreButton") - .should("exist"); - editTeamNameAndTest("/BBT_edit"); + cy.getByTestId('teamMoreButton') + .should('exist'); + editTeamNameAndTest('/BBT_edit'); // restore old name - editTeamNameAndTest("/BBT"); + editTeamNameAndTest('/BBT'); }); - it("should add members to team /BBT", () => { - cy.get("app-team-management") - .contains("/BBT") + it('should add members to team /BBT', () => { + cy.get('app-team-management') + .contains('/BBT') .click(); - cy.getByTestId("add-team-member") + cy.getByTestId('add-team-member') .click(); - cy.getByTestId("search-member-to-add") + cy.getByTestId('search-member-to-add') .click(); // esha should not exist (is already member of team) - const matOption = ".cdk-overlay-container mat-option"; + const matOption = '.cdk-overlay-container mat-option'; cy.get(matOption) .contains(nameEsha) - .should("not.exist"); + .should('not.exist'); // add findus peterson - cy.getByTestId("search-member-to-add") - .as("member-search") + cy.getByTestId('search-member-to-add') + .as('member-search') .click(); - cy.get("@member-search") - .type("Find"); - cy.contains(matOption, "Findus Peterson") + cy.get('@member-search') + .type('Find'); + cy.contains(matOption, 'Findus Peterson') .click(); // add robin papierer - cy.getByTestId("search-member-to-add") + cy.getByTestId('search-member-to-add') .click(); cy.get(matOption) - .contains("Findus Peterson") - .should("not.exist"); + .contains('Findus Peterson') + .should('not.exist'); cy.get(matOption) - .contains("Robin Papierer") + .contains('Robin Papierer') .click(); // check if Findus and Robin exists in table - const allMemberTableTr = "#all-member-table tbody tr"; + const allMemberTableTr = '#all-member-table tbody tr'; cy.get(allMemberTableTr) .eq(0) - .should("contain", "Findus Peterson"); + .should('contain', 'Findus Peterson'); cy.get(allMemberTableTr) .eq(1) - .should("contain", "Robin Papierer"); + .should('contain', 'Robin Papierer'); // remove robin papierer from list - cy.get(allMemberTableTr + " button") + cy.get(allMemberTableTr + ' button') .eq(1) .click(); cy.get(allMemberTableTr) .eq(1) - .should("not.exist"); + .should('not.exist'); - cy.getByTestId("save") + cy.getByTestId('save') .click(); }); - it("should change role of Findus Peterson to Team Admin", () => { - cy.get("app-team-management") - .contains("/BBT") + it('should change role of Findus Peterson to Team Admin', () => { + cy.get('app-team-management') + .contains('/BBT') .click(); - cy.get("app-member-list tbody tr") + cy.get('app-member-list tbody tr') .each(($row) => { - const usernameCell = $row.find("td:nth-child(2)"); + const usernameCell = $row.find('td:nth-child(2)'); if (usernameCell.text() - .trim() !== "Findus Peterson") { + .trim() !== 'Findus Peterson') { return; } - $row.find("[data-testId='edit-role']") + $row.find('[data-testId=\'edit-role\']') .click(); cy.wait(500); // wait for dialog to open }) .then(() => { - cy.getByTestId("select-team-role") + cy.getByTestId('select-team-role') .click(); - cy.getByTestId("select-team-role-admin") + cy.getByTestId('select-team-role-admin') .click(); - cy.getByTestId("select-team-role") - .should("not.exist"); - cy.contains("Das Team wurde erfolgreich aktualisiert."); + cy.getByTestId('select-team-role') + .should('not.exist'); + cy.contains('Das Team wurde erfolgreich aktualisiert.'); }); }); - it("should test that Findus Peterson cannot be added to further teams", () => { - navigateToUser("Findus Peterson"); + it('should test that Findus Peterson cannot be added to further teams', () => { + navigateToUser('Findus Peterson'); /* * current user BL (Esha Harris) is only admin in /BBT team. * That's why 'add-team-member' should be disabled */ - cy.get("app-member-detail") - .getByTestId("add-user") - .should("be.disabled"); + cy.get('app-member-detail') + .getByTestId('add-user') + .should('be.disabled'); }); - it("should remove BBT membership of findus", () => { - navigateToUser("Findus Peterson"); - cy.getByTestId("delete-team-member") + it('should remove BBT membership of findus', () => { + navigateToUser('Findus Peterson'); + cy.getByTestId('delete-team-member') .click(); ConfirmDialog.do() - .checkTitle("Mitglied entfernen") - .checkDescription("Möchtest du Findus Peterson wirklich aus dem Team '/BBT' entfernen?") + .checkTitle('Mitglied entfernen') + .checkDescription('Möchtest du Findus Peterson wirklich aus dem Team \'/BBT\' entfernen?') .submit(); - cy.get("app-member-detail") - .contains("/BBT") - .should("not.exist"); + cy.get('app-member-detail') + .contains('/BBT') + .should('not.exist'); }); - it("should remove added memberships from esha", () => { - cy.intercept("PUT", "**/removeuser") - .as("removeUser"); + it('should remove added memberships from esha', () => { + cy.intercept('PUT', '**/removeuser') + .as('removeUser'); navigateToUser(nameEsha); - cy.getByTestId("delete-team-member") + cy.getByTestId('delete-team-member') .eq(0) .click(); ConfirmDialog.do() - .checkTitle("Mitglied entfernen") + .checkTitle('Mitglied entfernen') .checkDescription(`Möchtest du ${nameEsha} wirklich aus dem Team '/BBT' entfernen?`) .submit(); - cy.wait("@removeUser"); + cy.wait('@removeUser'); - cy.getByTestId("delete-team-member") + cy.getByTestId('delete-team-member') .eq(0) .click(); ConfirmDialog.do() - .checkTitle("Mitglied entfernen") + .checkTitle('Mitglied entfernen') .checkDescription(`Möchtest du ${nameEsha} wirklich aus dem Team 'LoremIpsum' entfernen?`) .submit(); - cy.get("app-member-detail") - .should("not.contain", "/BBT") - .and("not.contain", "LoremIpsum"); + cy.get('app-member-detail') + .should('not.contain', '/BBT') + .and('not.contain', 'LoremIpsum'); }); - it("Navigate to user Esha and check if okr champion is not editable", () => { + it('Navigate to user Esha and check if okr champion is not editable', () => { navigateToUser(nameEsha); - cy.getByTestId("edit-okr-champion-readonly") - .should("exist"); - cy.getByTestId("edit-okr-champion-edit") - .should("not.exist"); + cy.getByTestId('edit-okr-champion-readonly') + .should('exist'); + cy.getByTestId('edit-okr-champion-edit') + .should('not.exist'); }); }); }); function closeOverlay() { - cy.get(".cdk-overlay-backdrop") + cy.get('.cdk-overlay-backdrop') .click(-50, -50, { force: true }); } function checkRolesForEsha() { - cy.get("app-member-detail tbody tr") + cy.get('app-member-detail tbody tr') .eq(0) - .should("contain", "/BBT") - .and("contain", "Team-Admin"); - cy.get("app-member-detail tbody tr") + .should('contain', '/BBT') + .and('contain', 'Team-Admin'); + cy.get('app-member-detail tbody tr') .eq(1) - .should("contain", "LoremIpsum") - .and("contain", "Team-Member"); + .should('contain', 'LoremIpsum') + .and('contain', 'Team-Member'); } function editTeamNameAndTest(teamName: string) { - cy.intercept("PUT", "**/teams/*") - .as("saveTeam"); - cy.getByTestId("editTeamButton") + cy.intercept('PUT', '**/teams/*') + .as('saveTeam'); + cy.getByTestId('editTeamButton') .click(); - cy.getByTestId("add-team-name") - .as("team-name") + cy.getByTestId('add-team-name') + .as('team-name') .click(); - cy.get("@team-name") + cy.get('@team-name') .clear(); - cy.get("@team-name") + cy.get('@team-name') .type(teamName); - cy.getByTestId("save") + cy.getByTestId('save') .click(); - cy.wait("@saveTeam"); + cy.wait('@saveTeam'); cy.contains(teamName); } function navigateToUser(userName: string) { - cy.intercept("GET", "**/users/*") - .as("getUser"); - cy.get("td") + cy.intercept('GET', '**/users/*') + .as('getUser'); + cy.get('td') .contains(userName) .click(); - cy.wait("@getUser"); + cy.wait('@getUser'); } function fillOutNewUser(firstname: string, lastname: string, email: string) { diff --git a/frontend/cypress/support/commands.ts b/frontend/cypress/support/commands.ts index 654de3a5b6..e5fa2511a5 100644 --- a/frontend/cypress/support/commands.ts +++ b/frontend/cypress/support/commands.ts @@ -1,14 +1,14 @@ -import { validateScoring } from "./helper/scoringSupport"; -import { keyCodeDefinitions } from "cypress-real-events/keyCodeDefinitions"; -import { doUntilSelector, pressUntilContains } from "./helper/utils"; +import { validateScoring } from './helper/scoringSupport'; +import { keyCodeDefinitions } from 'cypress-real-events/keyCodeDefinitions'; +import { doUntilSelector, pressUntilContains } from './helper/utils'; import Chainable = Cypress.Chainable; -Cypress.Commands.add("loginAsUser", (user: any) => { +Cypress.Commands.add('loginAsUser', (user: any) => { loginWithCredentials(user.username, user.password); overviewIsLoaded(); }); -Cypress.Commands.add("getByTestId", (testId: string, text?: string): Chainable => { +Cypress.Commands.add('getByTestId', (testId: string, text?: string): Chainable => { const selector = `[data-testId=${testId}]`; if (text) { @@ -19,7 +19,7 @@ Cypress.Commands.add("getByTestId", (testId: string, text?: string): Chainable = } }); -Cypress.Commands.add("findByTestId", { prevSubject: true }, (subject: JQuery, testId: string, text?: string): Chainable => { +Cypress.Commands.add('findByTestId', { prevSubject: true }, (subject: JQuery, testId: string, text?: string): Chainable => { const selector = `[data-testId=${testId}]`; if (text) { return cy.wrap(subject) @@ -31,64 +31,64 @@ Cypress.Commands.add("findByTestId", { prevSubject: true }, (subject: JQuery { +Cypress.Commands.add('pressUntilContains', (text: string, key: keyof typeof keyCodeDefinitions) => { pressUntilContains(text, key); }); -Cypress.Commands.add("tabForward", () => { - cy.realPress("Tab"); +Cypress.Commands.add('tabForward', () => { + cy.realPress('Tab'); }); -Cypress.Commands.add("tabBackward", () => { - cy.realPress(["Shift", - "Tab"]); +Cypress.Commands.add('tabBackward', () => { + cy.realPress(['Shift', + 'Tab']); }); -Cypress.Commands.add("tabForwardUntil", (selector: string, limit?: number) => { +Cypress.Commands.add('tabForwardUntil', (selector: string, limit?: number) => { doUntilSelector(selector, cy.tabForward, limit); }); -Cypress.Commands.add("tabBackwardUntil", (selector: string, limit?: number) => { +Cypress.Commands.add('tabBackwardUntil', (selector: string, limit?: number) => { doUntilSelector(selector, cy.tabBackward, limit); }); -Cypress.Commands.add("getZone", (zone: string, onOverview: boolean) => { - return (onOverview ? cy.focused() : cy.getByTestId("side-panel")).findByTestId(zone); +Cypress.Commands.add('getZone', (zone: string, onOverview: boolean) => { + return (onOverview ? cy.focused() : cy.getByTestId('side-panel')).findByTestId(zone); }); -Cypress.Commands.add("validateScoring", (isOverview: boolean, percentage: number) => { +Cypress.Commands.add('validateScoring', (isOverview: boolean, percentage: number) => { validateScoring(isOverview, percentage); }); function loginWithCredentials(username: string, password: string) { - cy.visit("/"); - cy.intercept("GET", "**/users/current") - .as("getCurrentUser"); - cy.origin(Cypress.env("login_url"), { + cy.visit('/'); + cy.intercept('GET', '**/users/current') + .as('getCurrentUser'); + cy.origin(Cypress.env('login_url'), { args: { username, password } }, ({ username, password }) => { - cy.get("input[name=\"username\"]") + cy.get('input[name="username"]') .type(username); - cy.get("input[name=\"password\"]") + cy.get('input[name="password"]') .type(password); - cy.get("button[type=\"submit\"]") + cy.get('button[type="submit"]') .click(); - cy.wait("@getCurrentUser", { responseTimeout: 10000 }); + cy.wait('@getCurrentUser', { responseTimeout: 10000 }); }); cy.url() .then((url) => { const currentUrl = new URL(url); - const baseURL = new URL(Cypress.config().baseUrl ?? ""); + const baseURL = new URL(Cypress.config().baseUrl ?? ''); expect(currentUrl.pathname) .equal(baseURL.pathname); }); } -const overviewIsLoaded = () => cy.get("mat-chip") - .should("have.length.at.least", 2); +const overviewIsLoaded = () => cy.get('mat-chip') + .should('have.length.at.least', 2); /* * -- This is a parent command -- diff --git a/frontend/cypress/support/component.ts b/frontend/cypress/support/component.ts index 2aff61fd87..3d45dba0b0 100644 --- a/frontend/cypress/support/component.ts +++ b/frontend/cypress/support/component.ts @@ -1,5 +1,5 @@ -import "./commands"; -import { keyCodeDefinitions } from "cypress-real-events/keyCodeDefinitions"; +import './commands'; +import { keyCodeDefinitions } from 'cypress-real-events/keyCodeDefinitions'; declare global { export namespace Cypress { diff --git a/frontend/cypress/support/e2e.ts b/frontend/cypress/support/e2e.ts index bd855f71aa..3628b50adf 100644 --- a/frontend/cypress/support/e2e.ts +++ b/frontend/cypress/support/e2e.ts @@ -15,14 +15,14 @@ * *********************************************************** */ -import "./commands"; -import "cypress-real-events"; -import { onlyOn } from "@cypress/skip-test"; +import './commands'; +import 'cypress-real-events'; +import { onlyOn } from '@cypress/skip-test'; Cypress.Keyboard.defaults({ keystrokeDelay: 0 }); beforeEach(() => { - onlyOn("chrome"); + onlyOn('chrome'); }); diff --git a/frontend/cypress/support/helper/dom-helper/angularSearchBox.ts b/frontend/cypress/support/helper/dom-helper/angularSearchBox.ts index 360f9a516f..706f73cfb9 100644 --- a/frontend/cypress/support/helper/dom-helper/angularSearchBox.ts +++ b/frontend/cypress/support/helper/dom-helper/angularSearchBox.ts @@ -1,4 +1,4 @@ -import { PageObjectMapperBase } from "./pageObjectMapperBase"; +import { PageObjectMapperBase } from './pageObjectMapperBase'; export default class AngularSearchBox extends PageObjectMapperBase { selector: string; @@ -10,7 +10,7 @@ export default class AngularSearchBox extends PageObjectMapperBase { } fill(value: string) { - const input = cy.get("input") + const input = cy.get('input') .first(); input.clear(); input.type(value); @@ -18,17 +18,17 @@ export default class AngularSearchBox extends PageObjectMapperBase { } shouldHaveOption(option: string) { - cy.contains(".mat-mdc-autocomplete-panel mat-option", option); + cy.contains('.mat-mdc-autocomplete-panel mat-option', option); return this; } shouldHaveLabel(label: string) { - cy.contains(".mat-mdc-autocomplete-panel .mat-mdc-optgroup-label", label); + cy.contains('.mat-mdc-autocomplete-panel .mat-mdc-optgroup-label', label); return this; } selectOption(option: string) { - cy.contains(".mat-mdc-autocomplete-panel mat-option", option) + cy.contains('.mat-mdc-autocomplete-panel mat-option', option) .click(); } @@ -42,6 +42,6 @@ export default class AngularSearchBox extends PageObjectMapperBase { validatePage(): void { this.getPage() - .should("exist"); + .should('exist'); } } diff --git a/frontend/cypress/support/helper/dom-helper/dialogs/checkInDialog.ts b/frontend/cypress/support/helper/dom-helper/dialogs/checkInDialog.ts index e5a927286f..576539fc8d 100644 --- a/frontend/cypress/support/helper/dom-helper/dialogs/checkInDialog.ts +++ b/frontend/cypress/support/helper/dom-helper/dialogs/checkInDialog.ts @@ -1,33 +1,33 @@ -import Dialog from "./dialog"; +import Dialog from './dialog'; import Chainable = Cypress.Chainable; export default class CheckInDialog extends Dialog { fillCheckInCommentary(commentary: string) { - this.fillInputByTestId("changeInfo", commentary); + this.fillInputByTestId('changeInfo', commentary); return this; } fillMetricCheckInValue(value: string) { - this.fillInputByTestId("check-in-metric-value", value); + this.fillInputByTestId('check-in-metric-value', value); return this; } - selectOrdinalCheckInZone(zone: "fail" | "commit" | "target" | "stretch") { + selectOrdinalCheckInZone(zone: 'fail' | 'commit' | 'target' | 'stretch') { switch (zone) { - case "fail": - cy.getByTestId("fail-radio") + case 'fail': + cy.getByTestId('fail-radio') .click(); break; - case "commit": - cy.getByTestId("commit-radio") + case 'commit': + cy.getByTestId('commit-radio') .click(); break; - case "target": - cy.getByTestId("target-radio") + case 'target': + cy.getByTestId('target-radio') .click(); break; - case "stretch": - cy.getByTestId("stretch-radio") + case 'stretch': + cy.getByTestId('stretch-radio') .click(); break; } @@ -35,56 +35,56 @@ export default class CheckInDialog extends Dialog { } fillCheckInInitiatives(value: string) { - this.fillInputByTestId("initiatives", value); + this.fillInputByTestId('initiatives', value); return this; } setCheckInConfidence(confidence: number) { - cy.getByTestId("confidence-slider") - .find("input") + cy.getByTestId('confidence-slider') + .find('input') .focus(); for (let i = 0; i < 10; i++) { - cy.realPress("ArrowLeft"); + cy.realPress('ArrowLeft'); } for (let i = 0; i < confidence; i++) { - cy.realPress("ArrowRight"); + cy.realPress('ArrowRight'); } return this; } checkForDialogTextMetric() { - cy.contains("Very important keyresult"); - cy.contains("Check-in erfassen"); - cy.contains("Key Result"); - cy.contains("Neuer Wert"); - cy.contains("Confidence um Target Zone (42%) zu erreichen"); - cy.contains("Abbrechen"); + cy.contains('Very important keyresult'); + cy.contains('Check-in erfassen'); + cy.contains('Key Result'); + cy.contains('Neuer Wert'); + cy.contains('Confidence um Target Zone (42%) zu erreichen'); + cy.contains('Abbrechen'); return this; } checkForDialogTextOrdinal() { - cy.contains("A new ordinal keyresult for our company"); - cy.contains("Check-in erfassen"); - cy.contains("Key Result"); - cy.contains("Fail:"); - cy.contains("Commit / Target / Stretch noch nicht erreicht"); - cy.contains("Commit:"); - cy.contains("Target:"); - cy.contains("Stretch:"); - cy.contains("New car"); - cy.contains("New house"); - cy.contains("New pool"); - cy.contains("Confidence um Target Zone zu erreichen"); - cy.contains("Abbrechen"); + cy.contains('A new ordinal keyresult for our company'); + cy.contains('Check-in erfassen'); + cy.contains('Key Result'); + cy.contains('Fail:'); + cy.contains('Commit / Target / Stretch noch nicht erreicht'); + cy.contains('Commit:'); + cy.contains('Target:'); + cy.contains('Stretch:'); + cy.contains('New car'); + cy.contains('New house'); + cy.contains('New pool'); + cy.contains('Confidence um Target Zone zu erreichen'); + cy.contains('Abbrechen'); return this; } override submit() { - cy.getByTestId("submit-check-in") + cy.getByTestId('submit-check-in') .click(); } getPage(): Chainable { - return cy.get("app-check-in-form"); + return cy.get('app-check-in-form'); } } diff --git a/frontend/cypress/support/helper/dom-helper/dialogs/checkInHistoryDialog.ts b/frontend/cypress/support/helper/dom-helper/dialogs/checkInHistoryDialog.ts index 984b1ba520..4fc5053e8c 100644 --- a/frontend/cypress/support/helper/dom-helper/dialogs/checkInHistoryDialog.ts +++ b/frontend/cypress/support/helper/dom-helper/dialogs/checkInHistoryDialog.ts @@ -1,33 +1,33 @@ -import Dialog from "./dialog"; -import CheckInDialog from "./checkInDialog"; +import Dialog from './dialog'; +import CheckInDialog from './checkInDialog'; import Chainable = Cypress.Chainable; export default class CheckInHistoryDialog extends Dialog { override submit() { - throw new Error("This dialog doesnt have a submit button"); + throw new Error('This dialog doesnt have a submit button'); } override cancel() { - cy.getByTestId("closeButton") + cy.getByTestId('closeButton') .click(); } editLatestCheckIn() { - cy.getByTestId("edit-check-in") + cy.getByTestId('edit-check-in') .first() .click(); return new CheckInDialog(); } getPage(): Chainable { - return cy.get("app-check-in-history-dialog"); + return cy.get('app-check-in-history-dialog'); } checkForAttribute(title: string, value: string) { - cy.get("mat-dialog-container") + cy.get('mat-dialog-container') .contains(value) .parent() - .should("contain", title); + .should('contain', title); return this; } } diff --git a/frontend/cypress/support/helper/dom-helper/dialogs/confirmDialog.ts b/frontend/cypress/support/helper/dom-helper/dialogs/confirmDialog.ts index 7f37a8e372..677ab5127d 100644 --- a/frontend/cypress/support/helper/dom-helper/dialogs/confirmDialog.ts +++ b/frontend/cypress/support/helper/dom-helper/dialogs/confirmDialog.ts @@ -1,32 +1,32 @@ -import Dialog from "./dialog"; +import Dialog from './dialog'; import Chainable = Cypress.Chainable; export default class ConfirmDialog extends Dialog { checkTitle(title: string) { this.getPage() .contains(title) - .should("exist"); + .should('exist'); return this; } checkDescription(title: string) { this.getPage() .contains(title) - .should("exist"); + .should('exist'); return this; } override submit() { - cy.getByTestId("confirm-yes") + cy.getByTestId('confirm-yes') .click(); } override cancel() { - cy.getByTestId("confirm-no") + cy.getByTestId('confirm-no') .click(); } getPage(): Chainable { - return cy.get("app-confirm-dialog"); + return cy.get('app-confirm-dialog'); } } diff --git a/frontend/cypress/support/helper/dom-helper/dialogs/dialog.ts b/frontend/cypress/support/helper/dom-helper/dialogs/dialog.ts index 4de43ac229..fd23784bb0 100644 --- a/frontend/cypress/support/helper/dom-helper/dialogs/dialog.ts +++ b/frontend/cypress/support/helper/dom-helper/dialogs/dialog.ts @@ -1,4 +1,4 @@ -import { PageObjectMapperBase } from "../pageObjectMapperBase"; +import { PageObjectMapperBase } from '../pageObjectMapperBase'; import Chainable = Cypress.Chainable; export default abstract class Dialog extends PageObjectMapperBase { @@ -9,21 +9,21 @@ export default abstract class Dialog extends PageObjectMapperBase { override validatePage() { this.getPage() - .should("exist"); + .should('exist'); } submit() { - cy.getByTestId("save") + cy.getByTestId('save') .click(); } cancel() { - cy.getByTestId("cancel") + cy.getByTestId('cancel') .click(); } close() { - cy.getByTestId("close-dialog") + cy.getByTestId('close-dialog') .click(); } diff --git a/frontend/cypress/support/helper/dom-helper/dialogs/inviteMembersDialog.ts b/frontend/cypress/support/helper/dom-helper/dialogs/inviteMembersDialog.ts index 3a56fca910..01379e7966 100644 --- a/frontend/cypress/support/helper/dom-helper/dialogs/inviteMembersDialog.ts +++ b/frontend/cypress/support/helper/dom-helper/dialogs/inviteMembersDialog.ts @@ -1,5 +1,5 @@ -import Dialog from "./dialog"; -import { uniqueSuffix } from "../../utils"; +import Dialog from './dialog'; +import { uniqueSuffix } from '../../utils'; import Chainable = Cypress.Chainable; export default class InviteMembersDialog extends Dialog { @@ -8,19 +8,19 @@ export default class InviteMembersDialog extends Dialog { override validatePage() { super.validatePage(); this.getPage() - .contains("Members registrieren") - .should("exist"); + .contains('Members registrieren') + .should('exist'); } enterUser(firstName: string, lastName: string, email: string) { firstName = uniqueSuffix(firstName); email = uniqueSuffix(email); this.firstnames.push(firstName); - const firstNameInput = cy.get("[formcontrolname=\"firstname\"]") + const firstNameInput = cy.get('[formcontrolname="firstname"]') .last(); - const lastNameInput = cy.get("[formcontrolname=\"lastname\"]") + const lastNameInput = cy.get('[formcontrolname="lastname"]') .last(); - const emailInput = cy.get("[formcontrolname=\"email\"]") + const emailInput = cy.get('[formcontrolname="email"]') .last(); this.fillInput(firstNameInput, firstName); this.fillInput(lastNameInput, lastName); @@ -29,7 +29,7 @@ export default class InviteMembersDialog extends Dialog { } addAnotherUser() { - cy.contains("Weiterer Member hinzufügen") + cy.contains('Weiterer Member hinzufügen') .click(); return this; } @@ -39,12 +39,12 @@ export default class InviteMembersDialog extends Dialog { } override submit() { - cy.getByTestId("invite") + cy.getByTestId('invite') .click(); return this.firstnames; } getPage(): Chainable { - return cy.get("app-invite-user-dialog"); + return cy.get('app-invite-user-dialog'); } } diff --git a/frontend/cypress/support/helper/dom-helper/dialogs/keyResultDialog.ts b/frontend/cypress/support/helper/dom-helper/dialogs/keyResultDialog.ts index 050a2c27dd..b724f5131a 100644 --- a/frontend/cypress/support/helper/dom-helper/dialogs/keyResultDialog.ts +++ b/frontend/cypress/support/helper/dom-helper/dialogs/keyResultDialog.ts @@ -1,51 +1,51 @@ -import Dialog from "./dialog"; -import { Unit } from "../../../../../src/app/shared/types/enums/Unit"; -import ConfirmDialog from "./confirmDialog"; +import Dialog from './dialog'; +import { Unit } from '../../../../../src/app/shared/types/enums/Unit'; +import ConfirmDialog from './confirmDialog'; import Chainable = Cypress.Chainable; export default class KeyResultDialog extends Dialog { fillKeyResultTitle(title: string) { - this.fillInputByTestId("titleInput", title); + this.fillInputByTestId('titleInput', title); return this; } fillKeyResultDescription(description: string) { - this.fillInputByTestId("descriptionInput", description); + this.fillInputByTestId('descriptionInput', description); return this; } withMetricValues(unit: Unit, baseline: string, stretchGoal: string) { - cy.getByTestId("metricTab") + cy.getByTestId('metricTab') .click(); - cy.getByTestId("unit") + cy.getByTestId('unit') .select(unit); - this.fillInputByTestId("baseline", baseline); - this.fillInputByTestId("stretchGoal", stretchGoal); + this.fillInputByTestId('baseline', baseline); + this.fillInputByTestId('stretchGoal', stretchGoal); return this; } withOrdinalValues(commitZone: string, targetZone: string, stretchGoal: string) { - cy.getByTestId("ordinalTab") + cy.getByTestId('ordinalTab') .click(); - this.fillInputByTestId("commitZone", commitZone); - this.fillInputByTestId("targetZone", targetZone); - this.fillInputByTestId("stretchZone", stretchGoal); + this.fillInputByTestId('commitZone', commitZone); + this.fillInputByTestId('targetZone', targetZone); + this.fillInputByTestId('stretchZone', stretchGoal); return this; } fillOwner(owner: string) { - this.fillInputByTestId("ownerInput", owner); - cy.realPress("ArrowDown") - .realPress("Enter"); + this.fillInputByTestId('ownerInput', owner); + cy.realPress('ArrowDown') + .realPress('Enter'); return this; } addActionPlanElement(action: string) { - cy.getByTestId("add-action-plan-line") + cy.getByTestId('add-action-plan-line') .click(); - cy.getByTestId("actionInput") + cy.getByTestId('actionInput') .filter((k, el) => { - return (el as HTMLInputElement).value.trim() === ""; + return (el as HTMLInputElement).value.trim() === ''; }) .first() .type(action); @@ -53,52 +53,52 @@ export default class KeyResultDialog extends Dialog { } deleteKeyResult() { - cy.getByTestId("delete-keyResult") + cy.getByTestId('delete-keyResult') .click(); return new ConfirmDialog(); } checkForDialogTextMetric() { - cy.contains("Einheit"); - cy.contains("Baseline"); - cy.contains("Stretch Goal"); + cy.contains('Einheit'); + cy.contains('Baseline'); + cy.contains('Stretch Goal'); this.checkForDialogText(); return this; } checkForDialogTextOrdinal() { - cy.contains("Commit Zone"); - cy.contains("Target Zone"); - cy.contains("Stretch Goal"); + cy.contains('Commit Zone'); + cy.contains('Target Zone'); + cy.contains('Stretch Goal'); this.checkForDialogText(); return this; } private checkForDialogText() { - cy.contains("Key Result erfassen"); - cy.contains("Titel"); - cy.contains("Metrisch"); - cy.contains("Ordinal"); - cy.contains("Owner"); - cy.contains("Beschreibung (optional)"); - cy.contains("Action Plan (optional)"); - cy.contains("Weitere Action hinzufügen"); - cy.contains("Speichern"); - cy.contains("Speichern & Neu"); - cy.contains("Abbrechen"); + cy.contains('Key Result erfassen'); + cy.contains('Titel'); + cy.contains('Metrisch'); + cy.contains('Ordinal'); + cy.contains('Owner'); + cy.contains('Beschreibung (optional)'); + cy.contains('Action Plan (optional)'); + cy.contains('Weitere Action hinzufügen'); + cy.contains('Speichern'); + cy.contains('Speichern & Neu'); + cy.contains('Abbrechen'); } override submit() { - cy.getByTestId("submit") + cy.getByTestId('submit') .click(); } saveAndNew() { - cy.getByTestId("saveAndNew") + cy.getByTestId('saveAndNew') .click(); } getPage(): Chainable { - return cy.get("app-key-result-form"); + return cy.get('app-key-result-form'); } } diff --git a/frontend/cypress/support/helper/dom-helper/dialogs/objectiveDialog.ts b/frontend/cypress/support/helper/dom-helper/dialogs/objectiveDialog.ts index cd11058837..6252040b00 100644 --- a/frontend/cypress/support/helper/dom-helper/dialogs/objectiveDialog.ts +++ b/frontend/cypress/support/helper/dom-helper/dialogs/objectiveDialog.ts @@ -1,45 +1,45 @@ -import Dialog from "./dialog"; -import ConfirmDialog from "./confirmDialog"; +import Dialog from './dialog'; +import ConfirmDialog from './confirmDialog'; import Chainable = Cypress.Chainable; export default class ObjectiveDialog extends Dialog { fillObjectiveTitle(title: string) { - this.fillInputByTestId("title", title); + this.fillInputByTestId('title', title); return this; } fillObjectiveDescription(description: string) { - this.fillInputByTestId("description", description); + this.fillInputByTestId('description', description); return this; } selectQuarter(quarter: string) { - cy.get("select#quarter") + cy.get('select#quarter') .select(quarter); return this; } toggleCreateKeyResults() { - cy.getByTestId("keyResult-checkbox") - .find("[type='checkbox']") + cy.getByTestId('keyResult-checkbox') + .find('[type=\'checkbox\']') .check(); return this; } deleteObjective() { - cy.getByTestId("delete") + cy.getByTestId('delete') .click(); return new ConfirmDialog(); } submitDraftObjective() { - cy.getByTestId("save-draft") + cy.getByTestId('save-draft') .click(); } excludeKeyResults(keyResults: string[]) { keyResults.forEach((keyResult) => { - cy.get("label") + cy.get('label') .contains(keyResult.slice(0, 30)) .click(); }); @@ -47,7 +47,7 @@ export default class ObjectiveDialog extends Dialog { } getPage(): Chainable { - return cy.get("app-objective-form") - .should("exist"); + return cy.get('app-objective-form') + .should('exist'); } } diff --git a/frontend/cypress/support/helper/dom-helper/dialogs/teamDialog.ts b/frontend/cypress/support/helper/dom-helper/dialogs/teamDialog.ts index 977e9326cb..8b64e8243c 100644 --- a/frontend/cypress/support/helper/dom-helper/dialogs/teamDialog.ts +++ b/frontend/cypress/support/helper/dom-helper/dialogs/teamDialog.ts @@ -1,24 +1,24 @@ -import Dialog from "./dialog"; +import Dialog from './dialog'; import Chainable = Cypress.Chainable; export default class TeamDialog extends Dialog { override validatePage() { super.validatePage(); this.getPage() - .contains("Team erfassen"); + .contains('Team erfassen'); } fillName(name: string) { - this.fillInputByTestId("add-team-name", name); + this.fillInputByTestId('add-team-name', name); return this; } override submit() { - cy.getByTestId("save") + cy.getByTestId('save') .click(); } getPage(): Chainable { - return cy.get("app-add-edit-team-dialog"); + return cy.get('app-add-edit-team-dialog'); } } diff --git a/frontend/cypress/support/helper/dom-helper/filterHelper.ts b/frontend/cypress/support/helper/dom-helper/filterHelper.ts index 1149ac5717..de8532bcdf 100644 --- a/frontend/cypress/support/helper/dom-helper/filterHelper.ts +++ b/frontend/cypress/support/helper/dom-helper/filterHelper.ts @@ -1,4 +1,4 @@ -import { PageObjectMapperBase } from "./pageObjectMapperBase"; +import { PageObjectMapperBase } from './pageObjectMapperBase'; export default class FilterHelper extends PageObjectMapperBase { validatePage(): void { @@ -7,23 +7,23 @@ export default class FilterHelper extends PageObjectMapperBase { optionShouldBeSelected(text: string, onOverview = true): this { if (onOverview) { - cy.contains("h1:visible", text) - .should("have.length", 1); + cy.contains('h1:visible', text) + .should('have.length', 1); } this.getOption(text) - .should("have.length", 1) - .should("have.css", "background-color") - .and("eq", "rgb(30, 90, 150)"); + .should('have.length', 1) + .should('have.css', 'background-color') + .and('eq', 'rgb(30, 90, 150)'); return this; } optionShouldNotBeSelected(text: string): this { - cy.contains("h1:visible", text) - .should("not.exist"); + cy.contains('h1:visible', text) + .should('not.exist'); this.getOption(text) - .should("have.length", 1) - .should("have.css", "background-color") - .and("eq", "rgb(255, 255, 255)"); + .should('have.length', 1) + .should('have.css', 'background-color') + .and('eq', 'rgb(255, 255, 255)'); return this; } @@ -34,6 +34,6 @@ export default class FilterHelper extends PageObjectMapperBase { } private getOption(text: string): Cypress.Chainable> { - return cy.contains("mat-chip:visible", text); + return cy.contains('mat-chip:visible', text); } } diff --git a/frontend/cypress/support/helper/dom-helper/pageObjectMapperBase.ts b/frontend/cypress/support/helper/dom-helper/pageObjectMapperBase.ts index db800ad3cf..ac4a103a8e 100644 --- a/frontend/cypress/support/helper/dom-helper/pageObjectMapperBase.ts +++ b/frontend/cypress/support/helper/dom-helper/pageObjectMapperBase.ts @@ -9,11 +9,11 @@ export abstract class PageObjectMapperBase { return this; } - checkForToaster(content: any, type: "success" | "error") { - cy.get("#toast-container") + checkForToaster(content: any, type: 'success' | 'error') { + cy.get('#toast-container') .find(`.toast-${type}`) .contains(content) - .should("exist"); + .should('exist'); return this; } @@ -22,7 +22,7 @@ export abstract class PageObjectMapperBase { .then((url) => { const params = new URL(url).searchParams; const queryParamValues = params.get(key) - ?.split(","); + ?.split(','); expect(queryParamValues).to.have.length(value.length); value.forEach((v) => expect(queryParamValues).to.include(v)); }); diff --git a/frontend/cypress/support/helper/dom-helper/pages/keyResultDetailPage.ts b/frontend/cypress/support/helper/dom-helper/pages/keyResultDetailPage.ts index f777e1045a..93328177d2 100644 --- a/frontend/cypress/support/helper/dom-helper/pages/keyResultDetailPage.ts +++ b/frontend/cypress/support/helper/dom-helper/pages/keyResultDetailPage.ts @@ -1,23 +1,23 @@ -import { Page } from "./page"; -import CyOverviewPage from "./overviewPage"; -import CheckInDialog from "../dialogs/checkInDialog"; -import KeyResultDialog from "../dialogs/keyResultDialog"; -import CheckInHistoryDialog from "../dialogs/checkInHistoryDialog"; +import { Page } from './page'; +import CyOverviewPage from './overviewPage'; +import CheckInDialog from '../dialogs/checkInDialog'; +import KeyResultDialog from '../dialogs/keyResultDialog'; +import CheckInHistoryDialog from '../dialogs/checkInHistoryDialog'; export default class KeyResultDetailPage extends Page { elements = { - logo: () => cy.getByTestId("logo"), - closeDrawer: () => cy.getByTestId("close-drawer"), - addCheckin: () => cy.getByTestId("add-check-in"), - showAllCheckins: () => cy.getByTestId("show-all-checkins"), - editKeyResult: () => cy.getByTestId("edit-keyResult") + logo: () => cy.getByTestId('logo'), + closeDrawer: () => cy.getByTestId('close-drawer'), + addCheckin: () => cy.getByTestId('add-check-in'), + showAllCheckins: () => cy.getByTestId('show-all-checkins'), + editKeyResult: () => cy.getByTestId('edit-keyResult') }; override validatePage() { this.elements.addCheckin() - .contains("Check-in erfassen"); + .contains('Check-in erfassen'); this.elements.editKeyResult() - .contains("Key Result bearbeiten"); + .contains('Key Result bearbeiten'); } override visit(keyResultName: string): this { @@ -61,6 +61,6 @@ export default class KeyResultDetailPage extends Page { } getURL(): string { - return "/details/keyresult"; + return '/details/keyresult'; } } diff --git a/frontend/cypress/support/helper/dom-helper/pages/overviewPage.ts b/frontend/cypress/support/helper/dom-helper/pages/overviewPage.ts index 924b7417ff..6b0960a204 100644 --- a/frontend/cypress/support/helper/dom-helper/pages/overviewPage.ts +++ b/frontend/cypress/support/helper/dom-helper/pages/overviewPage.ts @@ -1,13 +1,13 @@ -import { filterByObjectiveName, filterByObjectiveState, getObjectiveColumns } from "../../objectiveHelper"; -import ObjectiveDialog from "../dialogs/objectiveDialog"; -import { Page } from "./page"; -import KeyResultDialog from "../dialogs/keyResultDialog"; -import { filterByKeyResultName, getKeyResults } from "../../keyResultHelper"; +import { filterByObjectiveName, filterByObjectiveState, getObjectiveColumns } from '../../objectiveHelper'; +import ObjectiveDialog from '../dialogs/objectiveDialog'; +import { Page } from './page'; +import KeyResultDialog from '../dialogs/keyResultDialog'; +import { filterByKeyResultName, getKeyResults } from '../../keyResultHelper'; export default class CyOverviewPage extends Page { elements = { - logo: () => cy.getByTestId("logo"), - teammanagement: () => cy.getByTestId("team-management") + logo: () => cy.getByTestId('logo'), + teammanagement: () => cy.getByTestId('team-management') }; visitGJForTests() { @@ -33,12 +33,12 @@ export default class CyOverviewPage extends Page { addObjective(teamName?: string) { if (teamName) { this.getTeamByName(teamName) - .find(".add-objective") + .find('.add-objective') .first() .click(); return new ObjectiveDialog(); } - cy.getByTestId("add-objective") + cy.getByTestId('add-objective') .first() .click(); return new ObjectiveDialog(); @@ -47,21 +47,21 @@ export default class CyOverviewPage extends Page { addKeyResult(teamName?: string, objectiveName?: string) { if (teamName && objectiveName) { this.getObjectiveByTeamAndName(teamName, objectiveName) - .findByTestId("add-keyResult") + .findByTestId('add-keyResult') .first() .click(); } else if (teamName) { this.getTeamByName(teamName) - .findByTestId("add-keyResult") + .findByTestId('add-keyResult') .first() .click(); } else if (objectiveName) { this.getObjectiveByName(objectiveName) - .findByTestId("add-keyResult") + .findByTestId('add-keyResult') .first() .click(); } else { - cy.getByTestId("add-keyResult") + cy.getByTestId('add-keyResult') .first() .click(); } @@ -70,8 +70,8 @@ export default class CyOverviewPage extends Page { } addOngoingKeyResult() { - this.getObjectiveByState("ongoing") - .findByTestId("add-keyResult") + this.getObjectiveByState('ongoing') + .findByTestId('add-keyResult') .first() .click(); @@ -79,22 +79,22 @@ export default class CyOverviewPage extends Page { } getTeamByName(teamName: string) { - return cy.contains(".team-title", teamName) - .parentsUntil("#overview") + return cy.contains('.team-title', teamName) + .parentsUntil('#overview') .last(); } getFirstObjective() { - return cy.get(".objective") + return cy.get('.objective') .first(); } getObjectiveByNameAndState(objectiveName: string, state: string) { this.getObjectivesByNameAndState(objectiveName, state) .last() - .as("objective") + .as('objective') .scrollIntoView(); - return cy.get("@objective"); + return cy.get('@objective'); } getObjectivesByNameAndState(objectiveName: string, state: string) { @@ -106,20 +106,20 @@ export default class CyOverviewPage extends Page { getObjectiveByName(objectiveName: string) { this.getObjectivesByName(objectiveName) .last() - .as("objective") + .as('objective') .scrollIntoView(); - return cy.get("@objective"); + return cy.get('@objective'); } getObjectiveByTeamAndName(teamName: string, objectiveName: string) { this.getTeamByName(teamName) - .find(".objective") + .find('.objective') .filter(filterByObjectiveName(objectiveName)) .last() - .as("team") + .as('team') .scrollIntoView(); - return cy.get("@team"); + return cy.get('@team'); } getKeyResultOfObjective(objectiveName: string, keyResultName: string) { @@ -129,7 +129,7 @@ export default class CyOverviewPage extends Page { getAllKeyResultsOfObjective(objectiveName: string) { return this.getObjectiveByName(objectiveName) - .find(".key-result"); + .find('.key-result'); } getObjectivesByName(objectiveName: string) { @@ -140,9 +140,9 @@ export default class CyOverviewPage extends Page { getObjectiveByState(state: string) { this.getObjectivesByState(state) .first() - .as("objective") + .as('objective') .scrollIntoView(); - return cy.get("@objective"); + return cy.get('@objective'); } getObjectivesByState(state: string) { @@ -153,9 +153,9 @@ export default class CyOverviewPage extends Page { getKeyResultByName(keyResultName: string) { this.getKeyResultsByName(keyResultName) .last() - .as("keyResult") + .as('keyResult') .scrollIntoView(); - return cy.get("@keyResult"); + return cy.get('@keyResult'); } getKeyResultsByName(keyresultName: string) { @@ -165,25 +165,25 @@ export default class CyOverviewPage extends Page { selectFromThreeDotMenu(optionName: string) { cy.contains(optionName) - .should("exist"); - cy.get(".objective-three-dot-menu") + .should('exist'); + cy.get('.objective-three-dot-menu') .contains(optionName) - .as("option") + .as('option') .scrollIntoView(); - cy.get("@option") - .should("have.class", "objective-menu-option") + cy.get('@option') + .should('have.class', 'objective-menu-option') .click(); } duplicateObjective(objectiveName: string) { - cy.intercept("GET", "**/objectives/*/keyResults") - .as("keyResults"); + cy.intercept('GET', '**/objectives/*/keyResults') + .as('keyResults'); this.getObjectiveByName(objectiveName) - .findByTestId("three-dot-menu") + .findByTestId('three-dot-menu') .click(); - this.selectFromThreeDotMenu("Objective duplizieren"); - cy.wait("@keyResults"); + this.selectFromThreeDotMenu('Objective duplizieren'); + cy.wait('@keyResults'); return new ObjectiveDialog(); } @@ -193,7 +193,7 @@ export default class CyOverviewPage extends Page { } getURL(): string { - return ""; + return ''; } validatePage(): void { diff --git a/frontend/cypress/support/helper/dom-helper/pages/page.ts b/frontend/cypress/support/helper/dom-helper/pages/page.ts index 627e952746..9ac04fbddd 100644 --- a/frontend/cypress/support/helper/dom-helper/pages/page.ts +++ b/frontend/cypress/support/helper/dom-helper/pages/page.ts @@ -1,4 +1,4 @@ -import { PageObjectMapperBase } from "../pageObjectMapperBase"; +import { PageObjectMapperBase } from '../pageObjectMapperBase'; export abstract class Page extends PageObjectMapperBase { visit(arg?: any): this { @@ -15,7 +15,7 @@ export abstract class Page extends PageObjectMapperBase { afterVisit(): this { cy.url() - .should("include", this.getURL()); + .should('include', this.getURL()); this.validatePage(); return this; } diff --git a/frontend/cypress/support/helper/dom-helper/pages/teammanagementPage.ts b/frontend/cypress/support/helper/dom-helper/pages/teammanagementPage.ts index e2adf1ea50..44af69d882 100644 --- a/frontend/cypress/support/helper/dom-helper/pages/teammanagementPage.ts +++ b/frontend/cypress/support/helper/dom-helper/pages/teammanagementPage.ts @@ -1,35 +1,35 @@ -import { Page } from "./page"; -import TeamDialog from "../dialogs/teamDialog"; -import AngularSearchBox from "../angularSearchBox"; -import ConfirmDialog from "../dialogs/confirmDialog"; +import { Page } from './page'; +import TeamDialog from '../dialogs/teamDialog'; +import AngularSearchBox from '../angularSearchBox'; +import ConfirmDialog from '../dialogs/confirmDialog'; export default class TeammanagementPage extends Page { elements = { - logo: () => cy.getByTestId("logo"), - teammanagement: () => cy.getByTestId("team-management"), - backToOverview: () => cy.getByTestId("routerLink-to-overview"), - teamMenu: () => cy.get("app-team-list"), - memberHeader: () => cy.get("#member-header"), - registerMember: () => cy.getByTestId("invite-member"), - addTeam: () => cy.getByTestId("add-team"), - teamSearch: () => AngularSearchBox.from("app-team-management-banner [data-testId=\"teamManagementSearch\"]") + logo: () => cy.getByTestId('logo'), + teammanagement: () => cy.getByTestId('team-management'), + backToOverview: () => cy.getByTestId('routerLink-to-overview'), + teamMenu: () => cy.get('app-team-list'), + memberHeader: () => cy.get('#member-header'), + registerMember: () => cy.getByTestId('invite-member'), + addTeam: () => cy.getByTestId('add-team'), + teamSearch: () => AngularSearchBox.from('app-team-management-banner [data-testId="teamManagementSearch"]') }; override validatePage() { this.elements.teammanagement() - .contains("Teamverwaltung"); + .contains('Teamverwaltung'); this.elements.backToOverview() - .contains("Zurück zur OKR Übersicht"); + .contains('Zurück zur OKR Übersicht'); this.elements.addTeam() - .contains("Team erfassen"); + .contains('Team erfassen'); this.elements.teamMenu() - .contains("Alle Teams"); + .contains('Alle Teams'); this.elements.memberHeader() - .contains("Alle Teams"); + .contains('Alle Teams'); this.elements.memberHeader() - .contains("Members:"); + .contains('Members:'); this.elements.registerMember() - .contains("Member registrieren"); + .contains('Member registrieren'); } protected doVisit(): this { @@ -55,20 +55,20 @@ export default class TeammanagementPage extends Page { } deleteTeam(teamName: string) { - cy.get("app-team-list .mat-mdc-list-item") + cy.get('app-team-list .mat-mdc-list-item') .contains(teamName) .click(); - cy.getByTestId("teamMoreButton") + cy.getByTestId('teamMoreButton') .click(); - cy.getByTestId("teamDeleteButton") + cy.getByTestId('teamDeleteButton') .click(); return ConfirmDialog.do() - .checkTitle("Team löschen") + .checkTitle('Team löschen') .checkDescription(`Möchtest du das Team '${teamName}' wirklich löschen? Zugehörige Objectives werden dadurch in allen Quartalen ebenfalls gelöscht!`); } getURL(): string { - return "team-management"; + return 'team-management'; } } diff --git a/frontend/cypress/support/helper/keyResultHelper.ts b/frontend/cypress/support/helper/keyResultHelper.ts index 3877ec5e93..0edaa2d253 100644 --- a/frontend/cypress/support/helper/keyResultHelper.ts +++ b/frontend/cypress/support/helper/keyResultHelper.ts @@ -8,5 +8,5 @@ const isKeyResultName = (element: HTMLElement, keyResultName: string) => { }; export function getKeyResults() { - return cy.get(".key-result"); + return cy.get('.key-result'); } diff --git a/frontend/cypress/support/helper/objectiveHelper.ts b/frontend/cypress/support/helper/objectiveHelper.ts index b4b421cd9e..b0bf9edae2 100644 --- a/frontend/cypress/support/helper/objectiveHelper.ts +++ b/frontend/cypress/support/helper/objectiveHelper.ts @@ -17,5 +17,5 @@ const isObjectiveName = (element: HTMLElement, objectiveName: string) => { }; export function getObjectiveColumns() { - return cy.get(".objective"); + return cy.get('.objective'); } diff --git a/frontend/cypress/support/helper/scoringSupport.ts b/frontend/cypress/support/helper/scoringSupport.ts index 8a073e3e69..a0f2446911 100644 --- a/frontend/cypress/support/helper/scoringSupport.ts +++ b/frontend/cypress/support/helper/scoringSupport.ts @@ -1,4 +1,4 @@ -import { isLastCheckInNegative } from "../../../src/app/shared/common"; +import { isLastCheckInNegative } from '../../../src/app/shared/common'; interface ScoringValue { failPercent: number; @@ -11,19 +11,19 @@ export function validateScoring(isOverview: boolean, percentage: number) { const scoringValue = scoringValueFromPercentage(percentage); if (percentage >= 100) { - cy.getZone("stretch", isOverview) - .should("have.attr", "src") - .should("include", "star-filled-icon.svg"); + cy.getZone('stretch', isOverview) + .should('have.attr', 'src') + .should('include', 'star-filled-icon.svg'); } - validateScoringWidth("fail", scoringValue.failPercent, isOverview); - validateScoringWidth("commit", scoringValue.commitPercent, isOverview); - validateScoringWidth("target", scoringValue.targetPercent, isOverview); + validateScoringWidth('fail', scoringValue.failPercent, isOverview); + validateScoringWidth('commit', scoringValue.commitPercent, isOverview); + validateScoringWidth('target', scoringValue.targetPercent, isOverview); if (percentage == 0) return; - validateScoringColor("fail", rgbCode, isOverview); - validateScoringColor("commit", rgbCode, isOverview); - validateScoringColor("target", rgbCode, isOverview); + validateScoringColor('fail', rgbCode, isOverview); + validateScoringColor('commit', rgbCode, isOverview); + validateScoringColor('target', rgbCode, isOverview); } export function getPercentageMetric(baseline: number, stretchGoal: number, value: number) { @@ -34,55 +34,55 @@ export function getPercentageMetric(baseline: number, stretchGoal: number, value } export function getPercentageOrdinal(zone: string) { - if (zone == "stretch") return 101; - if (zone == "target") return 99.99; - if (zone == "commit") return 70; - if (zone == "fail") return 30; + if (zone == 'stretch') return 101; + if (zone == 'target') return 99.99; + if (zone == 'commit') return 70; + if (zone == 'fail') return 30; return 0; } function validateScoringWidth(zone: string, percent: number, isOverview: boolean) { cy.getZone(zone, isOverview) .parent() - .invoke("width") + .invoke('width') .then((parentWidth) => { expect(parentWidth).not.to.equal(undefined); if (parentWidth) { cy.getZone(zone, isOverview) - .invoke("width") - .should("be.within", parentWidth * (percent / 100) - 3, parentWidth * (percent / 100) + 3); + .invoke('width') + .should('be.within', parentWidth * (percent / 100) - 3, parentWidth * (percent / 100) + 3); } }); } function validateScoringColor(zone: string, rgbCode: string, isOverview: boolean) { cy.getZone(zone, isOverview) - .invoke("css", "background-color") - .should("equal", rgbCode); - if (rgbCode == "rgba(0, 0, 0, 0)") { - cy.getByTestId("star-scoring") - .invoke("css", "background-image") - .should("contain", "scoring-stars"); - checkVisibilityOfScoringComponent(isOverview, "block", "star-scoring"); - checkVisibilityOfScoringComponent(isOverview, "none", "normal-scoring"); + .invoke('css', 'background-color') + .should('equal', rgbCode); + if (rgbCode == 'rgba(0, 0, 0, 0)') { + cy.getByTestId('star-scoring') + .invoke('css', 'background-image') + .should('contain', 'scoring-stars'); + checkVisibilityOfScoringComponent(isOverview, 'block', 'star-scoring'); + checkVisibilityOfScoringComponent(isOverview, 'none', 'normal-scoring'); } else { - checkVisibilityOfScoringComponent(isOverview, "none", "star-scoring"); - checkVisibilityOfScoringComponent(isOverview, "flex", "normal-scoring"); + checkVisibilityOfScoringComponent(isOverview, 'none', 'star-scoring'); + checkVisibilityOfScoringComponent(isOverview, 'flex', 'normal-scoring'); } } function checkVisibilityOfScoringComponent(isOverview: boolean, displayProperty: string, componentTestId: string) { - (isOverview ? cy.focused() : cy.getByTestId("side-panel")) + (isOverview ? cy.focused() : cy.getByTestId('side-panel')) .findByTestId(componentTestId) - .invoke("css", "display") - .should("equal", displayProperty); + .invoke('css', 'display') + .should('equal', displayProperty); } function colorFromPercentage(percentage: number) { - if (percentage >= 100) return "rgba(0, 0, 0, 0)"; - if (percentage > 70) return "rgb(30, 138, 41)"; - if (percentage > 30) return "rgb(255, 214, 0)"; - return "rgb(186, 56, 56)"; + if (percentage >= 100) return 'rgba(0, 0, 0, 0)'; + if (percentage > 70) return 'rgb(30, 138, 41)'; + if (percentage > 30) return 'rgb(255, 214, 0)'; + return 'rgb(186, 56, 56)'; } function scoringValueFromPercentage(percentage: number): ScoringValue { diff --git a/frontend/cypress/support/helper/utils.ts b/frontend/cypress/support/helper/utils.ts index fdd228d407..454ba2433c 100644 --- a/frontend/cypress/support/helper/utils.ts +++ b/frontend/cypress/support/helper/utils.ts @@ -1,5 +1,5 @@ -import { v4 as uuidv4 } from "uuid"; -import { keyCodeDefinitions } from "cypress-real-events/keyCodeDefinitions"; +import { v4 as uuidv4 } from 'uuid'; +import { keyCodeDefinitions } from 'cypress-real-events/keyCodeDefinitions'; export const uniqueSuffix = (value: string): string => { return `${value}-${uuidv4()}`; diff --git a/frontend/eslint.config.mjs b/frontend/eslint.config.mjs index f9f569ab57..37bebc8244 100644 --- a/frontend/eslint.config.mjs +++ b/frontend/eslint.config.mjs @@ -7,6 +7,9 @@ import angular from 'angular-eslint' import htmlParser from '@html-eslint/parser' export default tsEslint.config( + { + ignores: ['cypress/downloads/**/*'], + }, { files: ['**/*.ts'], extends: [ @@ -89,7 +92,7 @@ export default tsEslint.config( //Stylistic eslint rules '@stylistic/no-extra-parens': 'error', '@stylistic/function-call-argument-newline': ['error', 'never'], - '@stylistic/quotes': ['error', 'double'], + '@stylistic/quotes': ['error', 'single'], '@stylistic/padded-blocks': ['error', 'never'], '@stylistic/dot-location': ['error', 'property'], '@stylistic/newline-per-chained-call': ['error', { ignoreChainWithDepth: 1 }], diff --git a/frontend/setup-jest.ts b/frontend/setup-jest.ts index a702c63396..1100b3e8a6 100644 --- a/frontend/setup-jest.ts +++ b/frontend/setup-jest.ts @@ -1 +1 @@ -import "jest-preset-angular/setup-jest"; +import 'jest-preset-angular/setup-jest'; diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index f0a47f2b03..d73c397344 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -1,14 +1,14 @@ -import { inject, NgModule } from "@angular/core"; -import { ResolveFn, RouterModule, Routes } from "@angular/router"; -import { OverviewComponent } from "./components/overview/overview.component"; -import { of } from "rxjs"; -import { SidepanelComponent } from "./shared/sidepanel/sidepanel.component"; -import { authGuard } from "./guards/auth.guard"; -import { UserService } from "./services/user.service"; -import { User } from "./shared/types/model/User"; -import { OAuthService } from "angular-oauth2-oidc"; -import { ObjectiveDetailComponent } from "./components/objective-detail/objective-detail.component"; -import { KeyresultDetailComponent } from "./components/keyresult-detail/keyresult-detail.component"; +import { inject, NgModule } from '@angular/core'; +import { ResolveFn, RouterModule, Routes } from '@angular/router'; +import { OverviewComponent } from './components/overview/overview.component'; +import { of } from 'rxjs'; +import { SidepanelComponent } from './shared/sidepanel/sidepanel.component'; +import { authGuard } from './guards/auth.guard'; +import { UserService } from './services/user.service'; +import { User } from './shared/types/model/User'; +import { OAuthService } from 'angular-oauth2-oidc'; +import { ObjectiveDetailComponent } from './components/objective-detail/objective-detail.component'; +import { KeyresultDetailComponent } from './components/keyresult-detail/keyresult-detail.component'; const currentUserResolver: ResolveFn = () => { const oauthService = inject(OAuthService); @@ -21,38 +21,38 @@ const currentUserResolver: ResolveFn = () => { const routes: Routes = [ { - path: "", + path: '', component: OverviewComponent, resolve: { user: currentUserResolver }, children: [{ - path: "details", + path: 'details', component: SidepanelComponent, children: [{ - path: "objective/:id", + path: 'objective/:id', component: ObjectiveDetailComponent }, { - path: "keyresult/:id", + path: 'keyresult/:id', component: KeyresultDetailComponent }] }], canActivate: [authGuard] }, { - path: "team-management", - loadChildren: () => import("./team-management/team-management.module").then((m) => m.TeamManagementModule), + path: 'team-management', + loadChildren: () => import('./team-management/team-management.module').then((m) => m.TeamManagementModule), canActivate: [authGuard], resolve: { user: currentUserResolver } }, - { path: "objective", - redirectTo: "details/objective" }, - { path: "keyresult", - redirectTo: "details/keyresult" }, - { path: "**", - redirectTo: "", - pathMatch: "full" } + { path: 'objective', + redirectTo: 'details/objective' }, + { path: 'keyresult', + redirectTo: 'details/keyresult' }, + { path: '**', + redirectTo: '', + pathMatch: 'full' } ]; @NgModule({ diff --git a/frontend/src/app/app.component.spec.ts b/frontend/src/app/app.component.spec.ts index 2a0ceca5ac..1560f812d3 100644 --- a/frontend/src/app/app.component.spec.ts +++ b/frontend/src/app/app.component.spec.ts @@ -1,32 +1,32 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { RouterTestingModule } from "@angular/router/testing"; -import { AppComponent } from "./app.component"; -import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; -import { TranslateTestingModule } from "ngx-translate-testing"; -import { OAuthModule, OAuthService } from "angular-oauth2-oidc"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AppComponent } from './app.component'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { TranslateTestingModule } from 'ngx-translate-testing'; +import { OAuthModule, OAuthService } from 'angular-oauth2-oidc'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; // @ts-ignore -import * as de from "../assets/i18n/de.json"; -import { MatSidenavModule } from "@angular/material/sidenav"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { Routes } from "@angular/router"; -import { OverviewComponent } from "./components/overview/overview.component"; -import { ObjectiveDetailComponent } from "./components/objective-detail/objective-detail.component"; -import { CommonModule } from "@angular/common"; +import * as de from '../assets/i18n/de.json'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { Routes } from '@angular/router'; +import { OverviewComponent } from './components/overview/overview.component'; +import { ObjectiveDetailComponent } from './components/objective-detail/objective-detail.component'; +import { CommonModule } from '@angular/common'; const oauthServiceMock = {}; const routes: Routes = [{ - path: "", + path: '', component: OverviewComponent, children: [{ - path: "objective/:id", + path: 'objective/:id', component: ObjectiveDetailComponent, - pathMatch: "full" + pathMatch: 'full' }] }]; -describe("AppComponent", () => { +describe('AppComponent', () => { let component: AppComponent; let fixture: ComponentFixture; @@ -61,7 +61,7 @@ describe("AppComponent", () => { }); }); - test("should create the app", () => { + test('should create the app', () => { expect(component) .toBeTruthy(); }); diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts index c09e988daa..33a11643d9 100644 --- a/frontend/src/app/app.component.ts +++ b/frontend/src/app/app.component.ts @@ -1,19 +1,19 @@ -import { ChangeDetectionStrategy, Component } from "@angular/core"; -import { MatIconRegistry } from "@angular/material/icon"; -import { DomSanitizer } from "@angular/platform-browser"; +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { MatIconRegistry } from '@angular/material/icon'; +import { DomSanitizer } from '@angular/platform-browser'; @Component({ - selector: "app-root", - templateUrl: "./app.component.html", - styleUrls: ["./app.component.scss"], + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class AppComponent { - readonly PATH_PREFIX = "../assets/icons/"; + readonly PATH_PREFIX = '../assets/icons/'; constructor(private matIconRegistry: MatIconRegistry, private domSanitizer: DomSanitizer) { - this.matIconRegistry.addSvgIcon("pz-search", this.domSanitizer.bypassSecurityTrustResourceUrl(this.PATH_PREFIX + "search-icon.svg")); - this.matIconRegistry.addSvgIcon("pz-menu-icon", this.domSanitizer.bypassSecurityTrustResourceUrl(this.PATH_PREFIX + "three-dot-menu-icon.svg")); + this.matIconRegistry.addSvgIcon('pz-search', this.domSanitizer.bypassSecurityTrustResourceUrl(this.PATH_PREFIX + 'search-icon.svg')); + this.matIconRegistry.addSvgIcon('pz-menu-icon', this.domSanitizer.bypassSecurityTrustResourceUrl(this.PATH_PREFIX + 'three-dot-menu-icon.svg')); } } diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index fa922621e8..053e984698 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -1,74 +1,74 @@ -import { APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, Injector, NgModule } from "@angular/core"; -import { BrowserModule } from "@angular/platform-browser"; -import { AppRoutingModule } from "./app-routing.module"; -import { AppComponent } from "./app.component"; +import { APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, Injector, NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; import { HTTP_INTERCEPTORS, HttpBackend, HttpClient, provideHttpClient, withInterceptorsFromDi -} from "@angular/common/http"; -import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { MatSelectModule } from "@angular/material/select"; -import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { MatIconModule } from "@angular/material/icon"; -import { MatMenuModule } from "@angular/material/menu"; -import { MatButtonModule } from "@angular/material/button"; -import { MatProgressBarModule } from "@angular/material/progress-bar"; -import { MatExpansionModule } from "@angular/material/expansion"; -import { MatInputModule } from "@angular/material/input"; -import { MatDialogModule } from "@angular/material/dialog"; -import { ToastrModule } from "ngx-toastr"; -import { MatProgressSpinnerModule } from "@angular/material/progress-spinner"; -import { TranslateLoader, TranslateModule, TranslateService } from "@ngx-translate/core"; -import { TranslateHttpLoader } from "@ngx-translate/http-loader"; -import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from "@angular/material/core"; -import { MomentDateAdapter } from "@angular/material-moment-adapter"; -import { OAuthModule, OAuthService, OAuthStorage } from "angular-oauth2-oidc"; -import { MatTooltipModule } from "@angular/material/tooltip"; -import { MatAutocompleteModule } from "@angular/material/autocomplete"; -import { MatRadioModule } from "@angular/material/radio"; -import { ConfigService } from "./services/config.service"; -import { firstValueFrom } from "rxjs"; -import { environment } from "../environments/environment"; -import { TeamComponent } from "./components/team/team.component"; -import { OverviewComponent } from "./components/overview/overview.component"; -import { ObjectiveComponent } from "./components/objective/objective.component"; -import { CommonModule, NgOptimizedImage } from "@angular/common"; -import { KeyresultComponent } from "./components/keyresult/keyresult.component"; -import { KeyresultDetailComponent } from "./components/keyresult-detail/keyresult-detail.component"; -import { ObjectiveDetailComponent } from "./components/objective-detail/objective-detail.component"; -import { MatSidenavModule } from "@angular/material/sidenav"; -import { ConfidenceComponent } from "./components/confidence/confidence.component"; -import { MatSliderModule } from "@angular/material/slider"; -import { MatDividerModule } from "@angular/material/divider"; -import { ApplicationBannerComponent } from "./components/application-banner/application-banner.component"; -import { MatCheckboxModule } from "@angular/material/checkbox"; -import { OverlayModule } from "@angular/cdk/overlay"; -import { QuarterFilterComponent } from "./components/quarter-filter/quarter-filter.component"; -import { TeamFilterComponent } from "./components/team-filter/team-filter.component"; -import { MatChipsModule } from "@angular/material/chips"; -import { Router } from "@angular/router"; -import { KeyresultTypeComponent } from "./components/keyresult-type/keyresult-type.component"; -import { ObjectiveFilterComponent } from "./components/objective-filter/objective-filter.component"; -import { ActionPlanComponent } from "./components/action-plan/action-plan.component"; -import { CdkDrag, CdkDragHandle, CdkDropList } from "@angular/cdk/drag-drop"; -import { SharedModule } from "./shared/shared.module"; -import { OauthInterceptor } from "./interceptors/oauth.interceptor"; -import { ErrorInterceptor } from "./interceptors/error-interceptor.service"; -import { CustomRouter } from "./shared/customRouter"; -import { KeyResultFormComponent } from "./components/key-result-form/key-result-form.component"; -import { KeyresultDialogComponent } from "./components/keyresult-dialog/keyresult-dialog.component"; -import { CheckInHistoryDialogComponent } from "./components/check-in-history-dialog/check-in-history-dialog.component"; -import { CheckInFormMetricComponent } from "./components/checkin/check-in-form-metric/check-in-form-metric.component"; -import { CheckInFormOrdinalComponent } from "./components/checkin/check-in-form-ordinal/check-in-form-ordinal.component"; -import { CheckInFormComponent } from "./components/checkin/check-in-form/check-in-form.component"; -import { ApplicationTopBarComponent } from "./components/application-top-bar/application-top-bar.component"; -import { A11yModule } from "@angular/cdk/a11y"; -import { CustomizationService } from "./services/customization.service"; -import { MetricCheckInDirective } from "./components/checkin/check-in-form-metric/metric-check-in-directive"; +} from '@angular/common/http'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatSelectModule } from '@angular/material/select'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatButtonModule } from '@angular/material/button'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatInputModule } from '@angular/material/input'; +import { MatDialogModule } from '@angular/material/dialog'; +import { ToastrModule } from 'ngx-toastr'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core'; +import { TranslateHttpLoader } from '@ngx-translate/http-loader'; +import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core'; +import { MomentDateAdapter } from '@angular/material-moment-adapter'; +import { OAuthModule, OAuthService, OAuthStorage } from 'angular-oauth2-oidc'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatRadioModule } from '@angular/material/radio'; +import { ConfigService } from './services/config.service'; +import { firstValueFrom } from 'rxjs'; +import { environment } from '../environments/environment'; +import { TeamComponent } from './components/team/team.component'; +import { OverviewComponent } from './components/overview/overview.component'; +import { ObjectiveComponent } from './components/objective/objective.component'; +import { CommonModule, NgOptimizedImage } from '@angular/common'; +import { KeyresultComponent } from './components/keyresult/keyresult.component'; +import { KeyresultDetailComponent } from './components/keyresult-detail/keyresult-detail.component'; +import { ObjectiveDetailComponent } from './components/objective-detail/objective-detail.component'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { ConfidenceComponent } from './components/confidence/confidence.component'; +import { MatSliderModule } from '@angular/material/slider'; +import { MatDividerModule } from '@angular/material/divider'; +import { ApplicationBannerComponent } from './components/application-banner/application-banner.component'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { OverlayModule } from '@angular/cdk/overlay'; +import { QuarterFilterComponent } from './components/quarter-filter/quarter-filter.component'; +import { TeamFilterComponent } from './components/team-filter/team-filter.component'; +import { MatChipsModule } from '@angular/material/chips'; +import { Router } from '@angular/router'; +import { KeyresultTypeComponent } from './components/keyresult-type/keyresult-type.component'; +import { ObjectiveFilterComponent } from './components/objective-filter/objective-filter.component'; +import { ActionPlanComponent } from './components/action-plan/action-plan.component'; +import { CdkDrag, CdkDragHandle, CdkDropList } from '@angular/cdk/drag-drop'; +import { SharedModule } from './shared/shared.module'; +import { OauthInterceptor } from './interceptors/oauth.interceptor'; +import { ErrorInterceptor } from './interceptors/error-interceptor.service'; +import { CustomRouter } from './shared/customRouter'; +import { KeyResultFormComponent } from './components/key-result-form/key-result-form.component'; +import { KeyresultDialogComponent } from './components/keyresult-dialog/keyresult-dialog.component'; +import { CheckInHistoryDialogComponent } from './components/check-in-history-dialog/check-in-history-dialog.component'; +import { CheckInFormMetricComponent } from './components/checkin/check-in-form-metric/check-in-form-metric.component'; +import { CheckInFormOrdinalComponent } from './components/checkin/check-in-form-ordinal/check-in-form-ordinal.component'; +import { CheckInFormComponent } from './components/checkin/check-in-form/check-in-form.component'; +import { ApplicationTopBarComponent } from './components/application-top-bar/application-top-bar.component'; +import { A11yModule } from '@angular/cdk/a11y'; +import { CustomizationService } from './services/customization.service'; +import { MetricCheckInDirective } from './components/checkin/check-in-form-metric/metric-check-in-directive'; function initOauthFactory(configService: ConfigService, oauthService: OAuthService) { return async() => { @@ -82,7 +82,7 @@ function initOauthFactory(configService: ConfigService, oauthService: OAuthServi } export function createTranslateLoader(http: HttpBackend) { - return new TranslateHttpLoader(new HttpClient(http), "./assets/i18n/", ".json"); + return new TranslateHttpLoader(new HttpClient(http), './assets/i18n/', '.json'); } export function storageFactory(): OAuthStorage { @@ -91,13 +91,13 @@ export function storageFactory(): OAuthStorage { export const MY_FORMATS = { parse: { - dateInput: "LL" + dateInput: 'LL' }, display: { - dateInput: "DD.MM.YYYY", - monthYearLabel: "DD.MM.YYYY", - dateA11yLabel: "DD.MM.YYYY", - monthYearA11yLabel: "DD.MM.YYYY" + dateInput: 'DD.MM.YYYY', + monthYearLabel: 'DD.MM.YYYY', + dateA11yLabel: 'DD.MM.YYYY', + monthYearA11yLabel: 'DD.MM.YYYY' } }; @@ -149,7 +149,7 @@ export const MY_FORMATS = { ToastrModule.forRoot(), MatProgressSpinnerModule, TranslateModule.forRoot({ - defaultLanguage: "de", + defaultLanguage: 'de', loader: { provide: TranslateLoader, useFactory: createTranslateLoader, diff --git a/frontend/src/app/components/action-plan/action-plan.component.spec.ts b/frontend/src/app/components/action-plan/action-plan.component.spec.ts index dacd347490..7d733991ac 100644 --- a/frontend/src/app/components/action-plan/action-plan.component.spec.ts +++ b/frontend/src/app/components/action-plan/action-plan.component.spec.ts @@ -1,22 +1,22 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; - -import { ActionPlanComponent } from "./action-plan.component"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { MatDialogRef } from "@angular/material/dialog"; -import { CdkDrag, CdkDropList } from "@angular/cdk/drag-drop"; -import { ActionService } from "../../services/action.service"; -import { action1, action2, action3, addedAction } from "../../shared/testData"; -import { BehaviorSubject, of } from "rxjs"; -import { Action } from "../../shared/types/model/Action"; -import { TranslateModule, TranslateService } from "@ngx-translate/core"; -import { DialogService } from "../../services/dialog.service"; -import { ConfirmDialogComponent } from "../../shared/dialog/confirm-dialog/confirm-dialog.component"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ActionPlanComponent } from './action-plan.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { MatDialogRef } from '@angular/material/dialog'; +import { CdkDrag, CdkDropList } from '@angular/cdk/drag-drop'; +import { ActionService } from '../../services/action.service'; +import { action1, action2, action3, addedAction } from '../../shared/testData'; +import { BehaviorSubject, of } from 'rxjs'; +import { Action } from '../../shared/types/model/Action'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { DialogService } from '../../services/dialog.service'; +import { ConfirmDialogComponent } from '../../shared/dialog/confirm-dialog/confirm-dialog.component'; const actionServiceMock = { deleteAction: jest.fn() }; -describe("ActionPlanComponent", () => { +describe('ActionPlanComponent', () => { let component: ActionPlanComponent; let fixture: ComponentFixture; let matDialogRef: MatDialogRef; @@ -49,17 +49,17 @@ describe("ActionPlanComponent", () => { actionServiceMock.deleteAction.mockReset(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should remove item from actionplan array", () => { + it('should remove item from actionplan array', () => { component.control = new BehaviorSubject([action1, action2]); actionServiceMock.deleteAction.mockReturnValue(of(null)); jest - .spyOn(component.dialogService, "openConfirmDialog") + .spyOn(component.dialogService, 'openConfirmDialog') .mockReturnValue({ afterClosed: () => of(true) } as MatDialogRef); component.removeAction(0); @@ -74,8 +74,8 @@ describe("ActionPlanComponent", () => { .toBe(0); }); - it("should remove item from actionplan without opening dialog when action has no text and id", () => { - const dialogSpy = jest.spyOn(component.dialogService, "open"); + it('should remove item from actionplan without opening dialog when action has no text and id', () => { + const dialogSpy = jest.spyOn(component.dialogService, 'open'); component.control = new BehaviorSubject([action3]); component.removeAction(0); @@ -87,8 +87,8 @@ describe("ActionPlanComponent", () => { expect(actionServiceMock.deleteAction).not.toHaveBeenCalled(); }); - it("should decrease index of active item when index is the same as the one of the removed item", () => { - jest.spyOn(component.dialogService, "open"); + it('should decrease index of active item when index is the same as the one of the removed item', () => { + jest.spyOn(component.dialogService, 'open'); component.control = new BehaviorSubject([action2, action3, action1]); @@ -99,7 +99,7 @@ describe("ActionPlanComponent", () => { .toBe(1); }); - it("should add new action with empty text into array", () => { + it('should add new action with empty text into array', () => { component.control = new BehaviorSubject([]); component.keyResultId = addedAction.keyResultId; component.addNewAction(); @@ -109,8 +109,8 @@ describe("ActionPlanComponent", () => { .toStrictEqual(addedAction); }); - it("should decrease index of active item", () => { - const keyEvent = new KeyboardEvent("keydown", { key: "ArrowUp" }); + it('should decrease index of active item', () => { + const keyEvent = new KeyboardEvent('keydown', { key: 'ArrowUp' }); component.control.next([action1, action2, action3]); @@ -126,8 +126,8 @@ describe("ActionPlanComponent", () => { expect(component.control.getValue()![2].priority == 2); }); - it("should increase index of active item", () => { - const keyEvent = new KeyboardEvent("keydown", { key: "ArrowDown" }); + it('should increase index of active item', () => { + const keyEvent = new KeyboardEvent('keydown', { key: 'ArrowDown' }); component.control.next([ action1, action2, @@ -150,7 +150,7 @@ describe("ActionPlanComponent", () => { expect(component.control.getValue()![3].priority == 3); }); - it("should increase active item index", () => { + it('should increase active item index', () => { component.activeItem = 0; component.control.next([action1, action2, @@ -160,7 +160,7 @@ describe("ActionPlanComponent", () => { .toBe(1); }); - it("should decrease active item index", () => { + it('should decrease active item index', () => { component.activeItem = 2; component.control.next([action1, action2, diff --git a/frontend/src/app/components/action-plan/action-plan.component.ts b/frontend/src/app/components/action-plan/action-plan.component.ts index 93e4c81258..6afb2affd0 100644 --- a/frontend/src/app/components/action-plan/action-plan.component.ts +++ b/frontend/src/app/components/action-plan/action-plan.component.ts @@ -1,15 +1,15 @@ -import { Component, ElementRef, Input, QueryList, ViewChildren } from "@angular/core"; -import { CdkDragDrop, moveItemInArray, transferArrayItem } from "@angular/cdk/drag-drop"; -import { Action } from "../../shared/types/model/Action"; -import { ActionService } from "../../services/action.service"; -import { BehaviorSubject } from "rxjs"; -import { trackByFn } from "../../shared/common"; -import { DialogService } from "../../services/dialog.service"; +import { Component, ElementRef, Input, QueryList, ViewChildren } from '@angular/core'; +import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop'; +import { Action } from '../../shared/types/model/Action'; +import { ActionService } from '../../services/action.service'; +import { BehaviorSubject } from 'rxjs'; +import { trackByFn } from '../../shared/common'; +import { DialogService } from '../../services/dialog.service'; @Component({ - selector: "app-action-plan", - templateUrl: "./action-plan.component.html", - styleUrls: ["./action-plan.component.scss"] + selector: 'app-action-plan', + templateUrl: './action-plan.component.html', + styleUrls: ['./action-plan.component.scss'] }) export class ActionPlanComponent { @Input() control: BehaviorSubject = new BehaviorSubject([]); @@ -18,7 +18,7 @@ export class ActionPlanComponent { activeItem = 0; - @ViewChildren("listItem") + @ViewChildren('listItem') listItems!: QueryList; constructor(private actionService: ActionService, @@ -27,11 +27,11 @@ export class ActionPlanComponent { handleKeyDown(event: Event, currentIndex: number) { let newIndex = currentIndex; - if ((event as KeyboardEvent).key === "ArrowDown") { + if ((event as KeyboardEvent).key === 'ArrowDown') { if (newIndex + 1 <= (this.control.getValue() ?? []).length - 1) { newIndex += 1; } - } else if ((event as KeyboardEvent).key === "ArrowUp") { + } else if ((event as KeyboardEvent).key === 'ArrowUp') { if (newIndex - 1 >= 0) { newIndex -= 1; } @@ -70,7 +70,7 @@ export class ActionPlanComponent { drop(event: CdkDragDrop) { const value: string = (event.container.element.nativeElement.children[event.previousIndex].children[1] as HTMLInputElement).value; const actions: Action[] = this.control.getValue() ?? []; - if (actions[event.previousIndex].action == "" && value != "") { + if (actions[event.previousIndex].action == '' && value != '') { actions[event.previousIndex] = { ...actions[event.previousIndex], action: value @@ -101,9 +101,9 @@ export class ActionPlanComponent { if (this.activeItem == index && this.activeItem > 0) { this.activeItem--; } - if (actions[index].action !== "" || actions[index].id) { + if (actions[index].action !== '' || actions[index].id) { this.dialogService - .openConfirmDialog("DELETE.ACTION") + .openConfirmDialog('DELETE.ACTION') .afterClosed() .subscribe((result) => { if (result) { @@ -126,7 +126,7 @@ export class ActionPlanComponent { addNewAction() { const actions: Action[] = this.control.getValue() ?? []; actions.push({ - action: "", + action: '', priority: actions.length, keyResultId: this.keyResultId } as Action); diff --git a/frontend/src/app/components/application-banner/application-banner.component.spec.ts b/frontend/src/app/components/application-banner/application-banner.component.spec.ts index bc1d7ff44d..339dbded88 100644 --- a/frontend/src/app/components/application-banner/application-banner.component.spec.ts +++ b/frontend/src/app/components/application-banner/application-banner.component.spec.ts @@ -1,24 +1,24 @@ -import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; - -import { ApplicationBannerComponent } from "./application-banner.component"; -import { By } from "@angular/platform-browser"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { PUZZLE_TOP_BAR_HEIGHT } from "../../shared/constantLibary"; -import { TeamFilterComponent } from "../team-filter/team-filter.component"; -import { QuarterFilterComponent } from "../quarter-filter/quarter-filter.component"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { ActivatedRoute } from "@angular/router"; -import { ObjectiveFilterComponent } from "../objective-filter/objective-filter.component"; -import { of } from "rxjs"; -import { MatExpansionModule } from "@angular/material/expansion"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { MatChipsModule } from "@angular/material/chips"; -import { MatSelectModule } from "@angular/material/select"; -import { MatIconModule } from "@angular/material/icon"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { OkrTangramComponent } from "../../shared/custom/okr-tangram/okr-tangram.component"; -import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { MatInputModule } from "@angular/material/input"; +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; + +import { ApplicationBannerComponent } from './application-banner.component'; +import { By } from '@angular/platform-browser'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { PUZZLE_TOP_BAR_HEIGHT } from '../../shared/constantLibary'; +import { TeamFilterComponent } from '../team-filter/team-filter.component'; +import { QuarterFilterComponent } from '../quarter-filter/quarter-filter.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { ActivatedRoute } from '@angular/router'; +import { ObjectiveFilterComponent } from '../objective-filter/objective-filter.component'; +import { of } from 'rxjs'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatChipsModule } from '@angular/material/chips'; +import { MatSelectModule } from '@angular/material/select'; +import { MatIconModule } from '@angular/material/icon'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { OkrTangramComponent } from '../../shared/custom/okr-tangram/okr-tangram.component'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatInputModule } from '@angular/material/input'; class ResizeObserverMock { observe() {} @@ -39,7 +39,7 @@ const routeMock = { queryParams: of(null) }; -describe("ApplicationBannerComponent", () => { +describe('ApplicationBannerComponent', () => { // @ts-ignore global.ResizeObserver = ResizeObserverMock; let component: ApplicationBannerComponent; @@ -77,12 +77,12 @@ describe("ApplicationBannerComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should should hide banner if scrolled down", fakeAsync(() => { + it('should should hide banner if scrolled down', fakeAsync(() => { // Set bannerHeight to default const bannerHeight = 160; // Scroll more than the height of the banner @@ -97,11 +97,11 @@ describe("ApplicationBannerComponent", () => { // Assert that banner is hidden was changed fixture.detectChanges(); - expect(fixture.debugElement.query(By.css("#okrBanner")).attributes["style"]) - .toContain("top: -" + (PUZZLE_TOP_BAR_HEIGHT + bannerHeight)); + expect(fixture.debugElement.query(By.css('#okrBanner')).attributes['style']) + .toContain('top: -' + (PUZZLE_TOP_BAR_HEIGHT + bannerHeight)); })); - it("should show banner if scrolled up", fakeAsync(() => { + it('should show banner if scrolled up', fakeAsync(() => { // Scroll more than the height of the banner const scrollTop = 180; // Set lastScrollPosition to bigger than scrollTop => user scrolls up @@ -113,12 +113,12 @@ describe("ApplicationBannerComponent", () => { // Assert that banner is visible fixture.detectChanges(); - expect(fixture.debugElement.query(By.css("#okrBanner")).attributes["style"]) - .toContain("top: " + PUZZLE_TOP_BAR_HEIGHT); + expect(fixture.debugElement.query(By.css('#okrBanner')).attributes['style']) + .toContain('top: ' + PUZZLE_TOP_BAR_HEIGHT); })); - it("should call setOKRBannerStyle() when changing header appearance", () => { - jest.spyOn(component, "refreshBanner") + it('should call setOKRBannerStyle() when changing header appearance', () => { + jest.spyOn(component, 'refreshBanner') .mockReturnValue(); // Set bannerHeight to default and execute header appearance change @@ -131,8 +131,8 @@ describe("ApplicationBannerComponent", () => { .toHaveBeenCalled(); }); - it("should call correct method after call scroll()", () => { - jest.spyOn(component, "changeHeaderAppearance"); + it('should call correct method after call scroll()', () => { + jest.spyOn(component, 'changeHeaderAppearance'); component.scroll(); diff --git a/frontend/src/app/components/application-banner/application-banner.component.ts b/frontend/src/app/components/application-banner/application-banner.component.ts index 3ef61cdf82..2e0ef4c781 100644 --- a/frontend/src/app/components/application-banner/application-banner.component.ts +++ b/frontend/src/app/components/application-banner/application-banner.component.ts @@ -6,21 +6,21 @@ import { HostListener, OnDestroy, ViewChild -} from "@angular/core"; -import { BehaviorSubject } from "rxjs"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { DEFAULT_HEADER_HEIGHT_PX, PUZZLE_TOP_BAR_HEIGHT } from "../../shared/constantLibary"; +} from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { DEFAULT_HEADER_HEIGHT_PX, PUZZLE_TOP_BAR_HEIGHT } from '../../shared/constantLibary'; @Component({ - selector: "app-application-banner", - templateUrl: "./application-banner.component.html", - styleUrls: ["./application-banner.component.scss"], + selector: 'app-application-banner', + templateUrl: './application-banner.component.html', + styleUrls: ['./application-banner.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class ApplicationBannerComponent implements AfterViewInit, OnDestroy { - @ViewChild("okrBanner") okrBanner!: ElementRef; + @ViewChild('okrBanner') okrBanner!: ElementRef; - quarterLabel$: BehaviorSubject = new BehaviorSubject(""); + quarterLabel$: BehaviorSubject = new BehaviorSubject(''); panelOpenState = false; @@ -53,7 +53,7 @@ export class ApplicationBannerComponent implements AfterViewInit, OnDestroy { refreshBanner(scrollTop: number) { const newBannerPadding = this.getBannerTopPadding(scrollTop); - this.okrBanner.nativeElement.style.top = newBannerPadding + "px"; + this.okrBanner.nativeElement.style.top = newBannerPadding + 'px'; const overviewPadding = this.getOverviewPadding(newBannerPadding, this.bannerHeight); this.refreshDataService.okrBannerHeightSubject.next(overviewPadding); @@ -69,7 +69,7 @@ export class ApplicationBannerComponent implements AfterViewInit, OnDestroy { return newBannerPadding < 0 ? PUZZLE_TOP_BAR_HEIGHT * 2 : paddingAmount; } - @HostListener("window:scroll") + @HostListener('window:scroll') scroll() { this.changeHeaderAppearance(); } diff --git a/frontend/src/app/components/application-top-bar/application-top-bar.component.spec.ts b/frontend/src/app/components/application-top-bar/application-top-bar.component.spec.ts index 361607a438..f1cf1d3568 100644 --- a/frontend/src/app/components/application-top-bar/application-top-bar.component.spec.ts +++ b/frontend/src/app/components/application-top-bar/application-top-bar.component.spec.ts @@ -1,21 +1,21 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ApplicationTopBarComponent } from "./application-top-bar.component"; -import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; -import { DateTimeProvider, OAuthLogger, OAuthService, UrlHelperService } from "angular-oauth2-oidc"; -import { HttpClient, HttpHandler } from "@angular/common/http"; -import { MatMenuModule } from "@angular/material/menu"; -import { HarnessLoader } from "@angular/cdk/testing"; -import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed"; -import { MatMenuHarness } from "@angular/material/menu/testing"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { MatDialogModule } from "@angular/material/dialog"; -import { NavigationEnd, Router } from "@angular/router"; -import { of } from "rxjs"; -import { testUser } from "../../shared/testData"; -import { UserService } from "../../services/user.service"; -import { ConfigService } from "../../services/config.service"; -import { DialogService } from "../../services/dialog.service"; +import { ApplicationTopBarComponent } from './application-top-bar.component'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { DateTimeProvider, OAuthLogger, OAuthService, UrlHelperService } from 'angular-oauth2-oidc'; +import { HttpClient, HttpHandler } from '@angular/common/http'; +import { MatMenuModule } from '@angular/material/menu'; +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { MatMenuHarness } from '@angular/material/menu/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatDialogModule } from '@angular/material/dialog'; +import { NavigationEnd, Router } from '@angular/router'; +import { of } from 'rxjs'; +import { testUser } from '../../shared/testData'; +import { UserService } from '../../services/user.service'; +import { ConfigService } from '../../services/config.service'; +import { DialogService } from '../../services/dialog.service'; const oAuthMock = { getIdentityClaims: jest.fn(), @@ -28,7 +28,7 @@ const dialogServiceMock = { }; const routerMock = { - events: of(new NavigationEnd(1, "", "")), + events: of(new NavigationEnd(1, '', '')), navigateByUrl: jest.fn() }; @@ -40,7 +40,7 @@ const configServiceMock = { config$: of({}) }; -describe("ApplicationTopBarComponent", () => { +describe('ApplicationTopBarComponent', () => { let component: ApplicationTopBarComponent; let fixture: ComponentFixture; let loader: HarnessLoader; @@ -86,17 +86,17 @@ describe("ApplicationTopBarComponent", () => { component.ngOnInit(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should set full name from user service", () => { + it('should set full name from user service', () => { expect(component.userFullName) - .toBe("Bob Baumeister"); + .toBe('Bob Baumeister'); }); - it("logout function should get called on button click", async() => { + it('logout function should get called on button click', async() => { routerMock.navigateByUrl.mockReturnValue(of() .toPromise()); const harness = await loader.getHarness(MatMenuHarness); diff --git a/frontend/src/app/components/application-top-bar/application-top-bar.component.ts b/frontend/src/app/components/application-top-bar/application-top-bar.component.ts index e64d2cbca9..dca10dac5a 100644 --- a/frontend/src/app/components/application-top-bar/application-top-bar.component.ts +++ b/frontend/src/app/components/application-top-bar/application-top-bar.component.ts @@ -1,25 +1,25 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from "@angular/core"; -import { OAuthService } from "angular-oauth2-oidc"; -import { BehaviorSubject, Subscription } from "rxjs"; -import { ConfigService } from "../../services/config.service"; -import { NavigationEnd, Router } from "@angular/router"; -import { UserService } from "../../services/user.service"; -import { getFullNameFromUser } from "../../shared/types/model/User"; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { OAuthService } from 'angular-oauth2-oidc'; +import { BehaviorSubject, Subscription } from 'rxjs'; +import { ConfigService } from '../../services/config.service'; +import { NavigationEnd, Router } from '@angular/router'; +import { UserService } from '../../services/user.service'; +import { getFullNameFromUser } from '../../shared/types/model/User'; @Component({ - selector: "app-application-top-bar", - templateUrl: "./application-top-bar.component.html", - styleUrls: ["./application-top-bar.component.scss"], + selector: 'app-application-top-bar', + templateUrl: './application-top-bar.component.html', + styleUrls: ['./application-top-bar.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class ApplicationTopBarComponent implements OnInit, OnDestroy { - userFullName = ""; + userFullName = ''; menuIsOpen = false; - logoSrc$ = new BehaviorSubject("assets/images/empty.svg"); + logoSrc$ = new BehaviorSubject('assets/images/empty.svg'); - helpSiteUrl = new BehaviorSubject("https://en.wikipedia.org/wiki/Objectives_and_key_results"); + helpSiteUrl = new BehaviorSubject('https://en.wikipedia.org/wiki/Objectives_and_key_results'); private subscription?: Subscription; diff --git a/frontend/src/app/components/check-in-history-dialog/check-in-history-dialog.component.spec.ts b/frontend/src/app/components/check-in-history-dialog/check-in-history-dialog.component.spec.ts index bb20873ad5..1f01408053 100644 --- a/frontend/src/app/components/check-in-history-dialog/check-in-history-dialog.component.spec.ts +++ b/frontend/src/app/components/check-in-history-dialog/check-in-history-dialog.component.spec.ts @@ -1,25 +1,25 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { CheckInHistoryDialogComponent } from "./check-in-history-dialog.component"; -import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from "@angular/material/dialog"; -import { provideHttpClientTesting } from "@angular/common/http/testing"; -import { checkInMetric, checkInMetricWriteableFalse, keyResult } from "../../shared/testData"; -import { By } from "@angular/platform-browser"; -import { DialogService } from "../../services/dialog.service"; -import { TranslateModule, TranslateService } from "@ngx-translate/core"; -import { MatIconModule } from "@angular/material/icon"; -import { SpinnerComponent } from "../../shared/custom/spinner/spinner.component"; -import { MatProgressSpinner } from "@angular/material/progress-spinner"; -import { provideRouter } from "@angular/router"; -import { provideHttpClient } from "@angular/common/http"; -import { DialogTemplateCoreComponent } from "../../shared/custom/dialog-template-core/dialog-template-core.component"; -import { MatDividerModule } from "@angular/material/divider"; +import { CheckInHistoryDialogComponent } from './check-in-history-dialog.component'; +import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { checkInMetric, checkInMetricWriteableFalse, keyResult } from '../../shared/testData'; +import { By } from '@angular/platform-browser'; +import { DialogService } from '../../services/dialog.service'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { MatIconModule } from '@angular/material/icon'; +import { SpinnerComponent } from '../../shared/custom/spinner/spinner.component'; +import { MatProgressSpinner } from '@angular/material/progress-spinner'; +import { provideRouter } from '@angular/router'; +import { provideHttpClient } from '@angular/common/http'; +import { DialogTemplateCoreComponent } from '../../shared/custom/dialog-template-core/dialog-template-core.component'; +import { MatDividerModule } from '@angular/material/divider'; const checkInService = { getAllCheckInOfKeyResult: jest.fn() }; -describe("CheckInHistoryDialogComponent", () => { +describe('CheckInHistoryDialogComponent', () => { let component: CheckInHistoryDialogComponent; let fixture: ComponentFixture; @@ -49,7 +49,7 @@ describe("CheckInHistoryDialogComponent", () => { ] }); jest - .spyOn(checkInService, "getAllCheckInOfKeyResult") + .spyOn(checkInService, 'getAllCheckInOfKeyResult') .mockReturnValue([checkInMetric, checkInMetricWriteableFalse]); fixture = TestBed.createComponent(CheckInHistoryDialogComponent); @@ -57,13 +57,13 @@ describe("CheckInHistoryDialogComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it.skip("should not display edit check-in button if writeable is false", async() => { - const buttons = fixture.debugElement.queryAll(By.css("button")); + it.skip('should not display edit check-in button if writeable is false', async() => { + const buttons = fixture.debugElement.queryAll(By.css('button')); expect(buttons.length) .toBe(1); }); diff --git a/frontend/src/app/components/check-in-history-dialog/check-in-history-dialog.component.ts b/frontend/src/app/components/check-in-history-dialog/check-in-history-dialog.component.ts index 09208aea04..e562dba5b4 100644 --- a/frontend/src/app/components/check-in-history-dialog/check-in-history-dialog.component.ts +++ b/frontend/src/app/components/check-in-history-dialog/check-in-history-dialog.component.ts @@ -1,21 +1,21 @@ -import { Component, Inject, OnInit } from "@angular/core"; -import { CheckInMin } from "../../shared/types/model/CheckInMin"; -import { CheckInService } from "../../services/check-in.service"; -import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; -import { DATE_FORMAT } from "../../shared/constantLibary"; -import { KeyResult } from "../../shared/types/model/KeyResult"; -import { CheckInFormComponent } from "../checkin/check-in-form/check-in-form.component"; -import { Observable, of } from "rxjs"; -import { KeyResultMetric } from "../../shared/types/model/KeyResultMetric"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { DialogService } from "../../services/dialog.service"; -import { CheckInMetricMin } from "../../shared/types/model/CheckInMetricMin"; -import { CheckInOrdinalMin } from "../../shared/types/model/CheckInOrdinalMin"; +import { Component, Inject, OnInit } from '@angular/core'; +import { CheckInMin } from '../../shared/types/model/CheckInMin'; +import { CheckInService } from '../../services/check-in.service'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { DATE_FORMAT } from '../../shared/constantLibary'; +import { KeyResult } from '../../shared/types/model/KeyResult'; +import { CheckInFormComponent } from '../checkin/check-in-form/check-in-form.component'; +import { Observable, of } from 'rxjs'; +import { KeyResultMetric } from '../../shared/types/model/KeyResultMetric'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { DialogService } from '../../services/dialog.service'; +import { CheckInMetricMin } from '../../shared/types/model/CheckInMetricMin'; +import { CheckInOrdinalMin } from '../../shared/types/model/CheckInOrdinalMin'; @Component({ - selector: "app-check-in-history-dialog", - templateUrl: "./check-in-history-dialog.component.html", - styleUrls: ["./check-in-history-dialog.component.scss"] + selector: 'app-check-in-history-dialog', + templateUrl: './check-in-history-dialog.component.html', + styleUrls: ['./check-in-history-dialog.component.scss'] }) export class CheckInHistoryDialogComponent implements OnInit { keyResult!: KeyResult; diff --git a/frontend/src/app/components/checkin/check-in-form-metric/check-in-form-metric.component.spec.ts b/frontend/src/app/components/checkin/check-in-form-metric/check-in-form-metric.component.spec.ts index cef38a26fe..808addfb4f 100644 --- a/frontend/src/app/components/checkin/check-in-form-metric/check-in-form-metric.component.spec.ts +++ b/frontend/src/app/components/checkin/check-in-form-metric/check-in-form-metric.component.spec.ts @@ -1,18 +1,18 @@ -import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { CheckInFormMetricComponent } from "./check-in-form-metric.component"; -import { checkInMetric, keyResultMetric } from "../../../shared/testData"; -import { FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms"; -import { MatDialogModule } from "@angular/material/dialog"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { MatSelectModule } from "@angular/material/select"; -import { MatInputModule } from "@angular/material/input"; -import { MatRadioModule } from "@angular/material/radio"; -import { Unit } from "../../../shared/types/enums/Unit"; -import { TranslateTestingModule } from "ngx-translate-testing"; -import * as de from "../../../../assets/i18n/de.json"; +import { CheckInFormMetricComponent } from './check-in-form-metric.component'; +import { checkInMetric, keyResultMetric } from '../../../shared/testData'; +import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { MatDialogModule } from '@angular/material/dialog'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatSelectModule } from '@angular/material/select'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { Unit } from '../../../shared/types/enums/Unit'; +import { TranslateTestingModule } from 'ngx-translate-testing'; +import * as de from '../../../../assets/i18n/de.json'; -describe("CheckInFormComponent", () => { +describe('CheckInFormComponent', () => { let component: CheckInFormMetricComponent; let fixture: ComponentFixture; @@ -36,7 +36,7 @@ describe("CheckInFormComponent", () => { component.keyResult = keyResultMetric; component.checkIn = checkInMetric; component.dialogForm = new FormGroup({ - value: new FormControl("", [Validators.required]), + value: new FormControl('', [Validators.required]), confidence: new FormControl(5, [Validators.required, Validators.min(1), Validators.max(10)]) @@ -44,43 +44,43 @@ describe("CheckInFormComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should format percent correctly", waitForAsync(async() => { + it('should format percent correctly', waitForAsync(async() => { component.keyResult = { ...keyResultMetric, unit: Unit.PERCENT }; expect(component.generateUnitLabel()) - .toEqual("%"); + .toEqual('%'); })); - it("should format chf correctly", waitForAsync(async() => { + it('should format chf correctly', waitForAsync(async() => { component.keyResult = { ...keyResultMetric, unit: Unit.CHF }; expect(component.generateUnitLabel()) - .toEqual("CHF"); + .toEqual('CHF'); })); - it("should format eur correctly", waitForAsync(async() => { + it('should format eur correctly', waitForAsync(async() => { component.keyResult = { ...keyResultMetric, unit: Unit.EUR }; expect(component.generateUnitLabel()) - .toEqual("EUR"); + .toEqual('EUR'); })); - it("should format fte correctly", waitForAsync(async() => { + it('should format fte correctly', waitForAsync(async() => { component.keyResult = { ...keyResultMetric, unit: Unit.FTE }; expect(component.generateUnitLabel()) - .toEqual("FTE"); + .toEqual('FTE'); })); - it("should format number correctly", waitForAsync(async() => { + it('should format number correctly', waitForAsync(async() => { component.keyResult = { ...keyResultMetric, unit: Unit.NUMBER }; expect(component.generateUnitLabel()) - .toEqual(""); + .toEqual(''); })); }); diff --git a/frontend/src/app/components/checkin/check-in-form-metric/check-in-form-metric.component.ts b/frontend/src/app/components/checkin/check-in-form-metric/check-in-form-metric.component.ts index 0b2db0d538..ca77d2ef0b 100644 --- a/frontend/src/app/components/checkin/check-in-form-metric/check-in-form-metric.component.ts +++ b/frontend/src/app/components/checkin/check-in-form-metric/check-in-form-metric.component.ts @@ -1,15 +1,15 @@ -import { ChangeDetectionStrategy, Component, Input, OnInit } from "@angular/core"; -import { FormGroup, Validators } from "@angular/forms"; -import { KeyResultMetric } from "../../../shared/types/model/KeyResultMetric"; -import { CheckInMin } from "../../../shared/types/model/CheckInMin"; -import { formInputCheck, hasFormFieldErrors } from "../../../shared/common"; -import { TranslateService } from "@ngx-translate/core"; -import { CheckInMetricMin } from "../../../shared/types/model/CheckInMetricMin"; +import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; +import { FormGroup, Validators } from '@angular/forms'; +import { KeyResultMetric } from '../../../shared/types/model/KeyResultMetric'; +import { CheckInMin } from '../../../shared/types/model/CheckInMin'; +import { formInputCheck, hasFormFieldErrors } from '../../../shared/common'; +import { TranslateService } from '@ngx-translate/core'; +import { CheckInMetricMin } from '../../../shared/types/model/CheckInMetricMin'; @Component({ - selector: "app-check-in-form-metric", - templateUrl: "./check-in-form-metric.component.html", - styleUrls: ["./check-in-form-metric.component.scss"], + selector: 'app-check-in-form-metric', + templateUrl: './check-in-form-metric.component.html', + styleUrls: ['./check-in-form-metric.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class CheckInFormMetricComponent implements OnInit { @@ -29,27 +29,27 @@ export class CheckInFormMetricComponent implements OnInit { constructor(private translate: TranslateService) {} ngOnInit() { - this.dialogForm.controls["value"].setValidators([Validators.required, - Validators.pattern("^-?\\d+\\.?\\d*$")]); + this.dialogForm.controls['value'].setValidators([Validators.required, + Validators.pattern('^-?\\d+\\.?\\d*$')]); } generateUnitLabel(): string { switch (this.keyResult.unit) { - case "PERCENT": - return "%"; - case "CHF": - return "CHF"; - case "EUR": - return "EUR"; - case "FTE": - return "FTE"; + case 'PERCENT': + return '%'; + case 'CHF': + return 'CHF'; + case 'EUR': + return 'EUR'; + case 'FTE': + return 'FTE'; default: - return ""; + return ''; } } getErrorMessage(error: string, field: string): string { - return field + this.translate.instant("DIALOG_ERRORS." + error); + return field + this.translate.instant('DIALOG_ERRORS.' + error); } getCheckInMetric(): CheckInMetricMin { diff --git a/frontend/src/app/components/checkin/check-in-form-metric/metric-check-in-directive.spec.ts b/frontend/src/app/components/checkin/check-in-form-metric/metric-check-in-directive.spec.ts index 2b2e765d83..36b0cb5d76 100644 --- a/frontend/src/app/components/checkin/check-in-form-metric/metric-check-in-directive.spec.ts +++ b/frontend/src/app/components/checkin/check-in-form-metric/metric-check-in-directive.spec.ts @@ -1,26 +1,26 @@ -import { MetricCheckInDirective } from "./metric-check-in-directive"; +import { MetricCheckInDirective } from './metric-check-in-directive'; -describe("MetricCheckInDirective", () => { - it("create an instance", () => { +describe('MetricCheckInDirective', () => { + it('create an instance', () => { const directive = new MetricCheckInDirective(); expect(directive) .toBeTruthy(); }); it.each([ - ["HelloWorld200", + ['HelloWorld200', 200], - ["200HelloWorld", + ['200HelloWorld', 200], - ["200'000", + ['200\'000', 200000], - ["1050&%ç*", + ['1050&%ç*', 1050], - ["-1", + ['-1', -1], - ["-ç13&%", + ['-ç13&%', -13] - ])("should parse value %s correctly to %s", (value: string, expected: number) => { + ])('should parse value %s correctly to %s', (value: string, expected: number) => { const mockOnChange = jest.fn(); const directive = new MetricCheckInDirective(); directive.registerOnChange(mockOnChange); diff --git a/frontend/src/app/components/checkin/check-in-form-metric/metric-check-in-directive.ts b/frontend/src/app/components/checkin/check-in-form-metric/metric-check-in-directive.ts index 57e274cca6..33e2bb2d20 100644 --- a/frontend/src/app/components/checkin/check-in-form-metric/metric-check-in-directive.ts +++ b/frontend/src/app/components/checkin/check-in-form-metric/metric-check-in-directive.ts @@ -1,8 +1,8 @@ -import { Directive, forwardRef, HostListener } from "@angular/core"; -import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms"; +import { Directive, forwardRef, HostListener } from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Directive({ - selector: "[metricCheckIn]", + selector: '[metricCheckIn]', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MetricCheckInDirective), @@ -27,16 +27,16 @@ export class MetricCheckInDirective implements ControlValueAccessor { // does not need to be implemented } - @HostListener("input", ["$event.target.value"]) + @HostListener('input', ['$event.target.value']) handleInput(param: string): void { - const value: string = param || "0"; + const value: string = param || '0'; if (value.toString() - .at(0) == "-") { - this.onChange(+("-" + value.toString() - .replace(this.CHAR_REGEX, ""))); + .at(0) == '-') { + this.onChange(+('-' + value.toString() + .replace(this.CHAR_REGEX, ''))); return; } this.onChange(Number(value.toString() - .replace(this.CHAR_REGEX, ""))); + .replace(this.CHAR_REGEX, ''))); } } diff --git a/frontend/src/app/components/checkin/check-in-form-ordinal/check-in-form-ordinal.component.spec.ts b/frontend/src/app/components/checkin/check-in-form-ordinal/check-in-form-ordinal.component.spec.ts index 3452ecff7a..62dd6f82e8 100644 --- a/frontend/src/app/components/checkin/check-in-form-ordinal/check-in-form-ordinal.component.spec.ts +++ b/frontend/src/app/components/checkin/check-in-form-ordinal/check-in-form-ordinal.component.spec.ts @@ -1,20 +1,20 @@ -import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { CheckInFormOrdinalComponent } from "./check-in-form-ordinal.component"; -import { FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms"; -import { keyResultOrdinalMin } from "../../../shared/testData"; -import { KeyResultOrdinal } from "../../../shared/types/model/KeyResultOrdinal"; -import { MatDialogModule } from "@angular/material/dialog"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { MatSelectModule } from "@angular/material/select"; -import { MatInputModule } from "@angular/material/input"; -import { MatRadioModule } from "@angular/material/radio"; -import { Zone } from "../../../shared/types/enums/Zone"; -import { MatRadioButtonHarness } from "@angular/material/radio/testing"; -import { HarnessLoader } from "@angular/cdk/testing"; -import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed"; +import { CheckInFormOrdinalComponent } from './check-in-form-ordinal.component'; +import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { keyResultOrdinalMin } from '../../../shared/testData'; +import { KeyResultOrdinal } from '../../../shared/types/model/KeyResultOrdinal'; +import { MatDialogModule } from '@angular/material/dialog'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatSelectModule } from '@angular/material/select'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { Zone } from '../../../shared/types/enums/Zone'; +import { MatRadioButtonHarness } from '@angular/material/radio/testing'; +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; -describe("CheckInFormOrdinalComponent", () => { +describe('CheckInFormOrdinalComponent', () => { let component: CheckInFormOrdinalComponent; let fixture: ComponentFixture; let loader: HarnessLoader; @@ -35,7 +35,7 @@ describe("CheckInFormOrdinalComponent", () => { component = fixture.componentInstance; component.keyResult = keyResultOrdinalMin as unknown as KeyResultOrdinal; component.dialogForm = new FormGroup({ - value: new FormControl("", [Validators.required]), + value: new FormControl('', [Validators.required]), confidence: new FormControl(5, [Validators.required, Validators.min(1), Validators.max(10)]) @@ -44,49 +44,49 @@ describe("CheckInFormOrdinalComponent", () => { loader = TestbedHarnessEnvironment.loader(fixture); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should set zone of check-in to fail if value is empty", waitForAsync(async() => { - expect(component.dialogForm.controls["value"].value) - .toBe(""); + it('should set zone of check-in to fail if value is empty', waitForAsync(async() => { + expect(component.dialogForm.controls['value'].value) + .toBe(''); })); - it("should set zone to Fail", waitForAsync(async() => { + it('should set zone to Fail', waitForAsync(async() => { const radioButtons = await loader.getAllHarnesses(MatRadioButtonHarness); await radioButtons[0].check(); - expect(component.dialogForm.controls["value"].value) + expect(component.dialogForm.controls['value'].value) .toBe(Zone.FAIL); })); - it("should set zone to Commit", waitForAsync(async() => { + it('should set zone to Commit', waitForAsync(async() => { const radioButtons = await loader.getAllHarnesses(MatRadioButtonHarness); await radioButtons[1].check(); - expect(component.dialogForm.controls["value"].value) + expect(component.dialogForm.controls['value'].value) .toBe(Zone.COMMIT); })); - it("should set zone to Target", waitForAsync(async() => { + it('should set zone to Target', waitForAsync(async() => { const radioButtons = await loader.getAllHarnesses(MatRadioButtonHarness); await radioButtons[2].check(); - expect(component.dialogForm.controls["value"].value) + expect(component.dialogForm.controls['value'].value) .toBe(Zone.TARGET); })); - it("should set zone to Stretch", waitForAsync(async() => { + it('should set zone to Stretch', waitForAsync(async() => { const radioButtons = await loader.getAllHarnesses(MatRadioButtonHarness); await radioButtons[3].check(); - expect(component.dialogForm.controls["value"].value) + expect(component.dialogForm.controls['value'].value) .toBe(Zone.STRETCH); })); - it("should be able to switch options ", waitForAsync(async() => { + it('should be able to switch options ', waitForAsync(async() => { const radioButtons = await loader.getAllHarnesses(MatRadioButtonHarness); await radioButtons[3].check(); await radioButtons[1].check(); - expect(component.dialogForm.controls["value"].value) + expect(component.dialogForm.controls['value'].value) .toBe(Zone.COMMIT); })); }); diff --git a/frontend/src/app/components/checkin/check-in-form-ordinal/check-in-form-ordinal.component.ts b/frontend/src/app/components/checkin/check-in-form-ordinal/check-in-form-ordinal.component.ts index 6e28fcbfae..ed8354c380 100644 --- a/frontend/src/app/components/checkin/check-in-form-ordinal/check-in-form-ordinal.component.ts +++ b/frontend/src/app/components/checkin/check-in-form-ordinal/check-in-form-ordinal.component.ts @@ -1,13 +1,13 @@ -import { Component, Input } from "@angular/core"; -import { FormGroup } from "@angular/forms"; -import { KeyResultOrdinal } from "../../../shared/types/model/KeyResultOrdinal"; -import { Zone } from "../../../shared/types/enums/Zone"; -import { CheckInMin } from "../../../shared/types/model/CheckInMin"; +import { Component, Input } from '@angular/core'; +import { FormGroup } from '@angular/forms'; +import { KeyResultOrdinal } from '../../../shared/types/model/KeyResultOrdinal'; +import { Zone } from '../../../shared/types/enums/Zone'; +import { CheckInMin } from '../../../shared/types/model/CheckInMin'; @Component({ - selector: "app-check-in-form-ordinal", - templateUrl: "./check-in-form-ordinal.component.html", - styleUrls: ["./check-in-form-ordinal.component.scss"] + selector: 'app-check-in-form-ordinal', + templateUrl: './check-in-form-ordinal.component.html', + styleUrls: ['./check-in-form-ordinal.component.scss'] }) export class CheckInFormOrdinalComponent { @Input() diff --git a/frontend/src/app/components/checkin/check-in-form/check-in-form.component.spec.ts b/frontend/src/app/components/checkin/check-in-form/check-in-form.component.spec.ts index 2f07c5c847..a9988b3081 100644 --- a/frontend/src/app/components/checkin/check-in-form/check-in-form.component.spec.ts +++ b/frontend/src/app/components/checkin/check-in-form/check-in-form.component.spec.ts @@ -1,7 +1,7 @@ -import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { CheckInFormComponent } from "./check-in-form.component"; -import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from "@angular/material/dialog"; +import { CheckInFormComponent } from './check-in-form.component'; +import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { action1, action2, @@ -10,27 +10,27 @@ import { keyResultActions, keyResultMetric, keyResultOrdinal -} from "../../../shared/testData"; -import { MatIconModule } from "@angular/material/icon"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { MatSelectModule } from "@angular/material/select"; -import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { MatInputModule } from "@angular/material/input"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { MatCheckboxModule } from "@angular/material/checkbox"; -import { CheckInService } from "../../../services/check-in.service"; -import { of } from "rxjs"; -import { ActionService } from "../../../services/action.service"; +} from '../../../shared/testData'; +import { MatIconModule } from '@angular/material/icon'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatSelectModule } from '@angular/material/select'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatInputModule } from '@angular/material/input'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { CheckInService } from '../../../services/check-in.service'; +import { of } from 'rxjs'; +import { ActionService } from '../../../services/action.service'; // @ts-ignore -import * as de from "../../../../assets/i18n/de.json"; -import { TranslateTestingModule } from "ngx-translate-testing"; -import { ConfidenceComponent } from "../../confidence/confidence.component"; -import { MatSliderModule } from "@angular/material/slider"; -import { provideRouter } from "@angular/router"; -import { provideHttpClient } from "@angular/common/http"; -import { provideHttpClientTesting } from "@angular/common/http/testing"; -import { DialogTemplateCoreComponent } from "../../../shared/custom/dialog-template-core/dialog-template-core.component"; -import { MatDividerModule } from "@angular/material/divider"; +import * as de from '../../../../assets/i18n/de.json'; +import { TranslateTestingModule } from 'ngx-translate-testing'; +import { ConfidenceComponent } from '../../confidence/confidence.component'; +import { MatSliderModule } from '@angular/material/slider'; +import { provideRouter } from '@angular/router'; +import { provideHttpClient } from '@angular/common/http'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { DialogTemplateCoreComponent } from '../../../shared/custom/dialog-template-core/dialog-template-core.component'; +import { MatDividerModule } from '@angular/material/divider'; const dialogMock = { close: jest.fn() @@ -44,7 +44,7 @@ const actionServiceMock = { updateActions: jest.fn() }; -describe("CheckInFormComponent", () => { +describe('CheckInFormComponent', () => { let component: CheckInFormComponent; let fixture: ComponentFixture; @@ -89,18 +89,18 @@ describe("CheckInFormComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should save check-in correctly if key result is metric", waitForAsync(async() => { + it('should save check-in correctly if key result is metric', waitForAsync(async() => { component.checkIn = checkInMetric; component.keyResult = keyResultMetric; - component.dialogForm.controls["value"].setValue(checkInMetric?.value!.toString()); - component.dialogForm.controls["confidence"].setValue(checkInMetric.confidence); - component.dialogForm.controls["changeInfo"].setValue(checkInMetric.changeInfo); - component.dialogForm.controls["initiatives"].setValue(checkInMetric.initiatives); + component.dialogForm.controls['value'].setValue(checkInMetric?.value!.toString()); + component.dialogForm.controls['confidence'].setValue(checkInMetric.confidence); + component.dialogForm.controls['changeInfo'].setValue(checkInMetric.changeInfo); + component.dialogForm.controls['initiatives'].setValue(checkInMetric.initiatives); checkInServiceMock.saveCheckIn.mockReturnValue(of(checkInMetric)); actionServiceMock.updateActions.mockReturnValue(of(action2)); @@ -120,13 +120,13 @@ describe("CheckInFormComponent", () => { .toHaveBeenCalled(); })); - it("should save check-in correctly if key result is ordinal", waitForAsync(async() => { + it('should save check-in correctly if key result is ordinal', waitForAsync(async() => { component.checkIn = checkInOrdinal; component.keyResult = keyResultOrdinal; - component.dialogForm.controls["value"].setValue(checkInOrdinal?.zone!.toString()); - component.dialogForm.controls["confidence"].setValue(checkInOrdinal.confidence); - component.dialogForm.controls["changeInfo"].setValue(checkInOrdinal.changeInfo); - component.dialogForm.controls["initiatives"].setValue(checkInOrdinal.initiatives); + component.dialogForm.controls['value'].setValue(checkInOrdinal?.zone!.toString()); + component.dialogForm.controls['confidence'].setValue(checkInOrdinal.confidence); + component.dialogForm.controls['changeInfo'].setValue(checkInOrdinal.changeInfo); + component.dialogForm.controls['initiatives'].setValue(checkInOrdinal.initiatives); checkInServiceMock.saveCheckIn.mockReturnValue(of(checkInOrdinal)); actionServiceMock.updateActions.mockReturnValue(of(action2)); @@ -144,7 +144,7 @@ describe("CheckInFormComponent", () => { }); })); - it("should set default values if form check-in input is not null", waitForAsync(async() => { + it('should set default values if form check-in input is not null', waitForAsync(async() => { component.data.checkIn = checkInMetric; component.setDefaultValues(); expect(component.dialogForm.value) @@ -157,36 +157,36 @@ describe("CheckInFormComponent", () => { }); })); - it("should set default values if last check-in of key result is not null", waitForAsync(async() => { + it('should set default values if last check-in of key result is not null', waitForAsync(async() => { component.keyResult = keyResultOrdinal; component.ngOnInit(); component.setDefaultValues(); expect(component.dialogForm.value) .toStrictEqual({ confidence: keyResultOrdinal.lastCheckIn!.confidence, - value: "", - changeInfo: "", - initiatives: "", + value: '', + changeInfo: '', + initiatives: '', actionList: [] }); })); - it("should set default values with actionList on KeyResult", waitForAsync(async() => { + it('should set default values with actionList on KeyResult', waitForAsync(async() => { component.keyResult = keyResultActions; component.ngOnInit(); component.setDefaultValues(); expect(component.dialogForm.value) .toStrictEqual({ confidence: keyResultActions.lastCheckIn!.confidence, - value: "", - changeInfo: "", - initiatives: "", + value: '', + changeInfo: '', + initiatives: '', actionList: [action1, action2] }); })); - it("should call actionService when saving CheckIn", waitForAsync(async() => { + it('should call actionService when saving CheckIn', waitForAsync(async() => { checkInServiceMock.saveCheckIn.mockReturnValue(of(true)); actionServiceMock.updateActions.mockReturnValue(of(true)); diff --git a/frontend/src/app/components/checkin/check-in-form/check-in-form.component.ts b/frontend/src/app/components/checkin/check-in-form/check-in-form.component.ts index fb4f48e783..0d09f2dd10 100644 --- a/frontend/src/app/components/checkin/check-in-form/check-in-form.component.ts +++ b/frontend/src/app/components/checkin/check-in-form/check-in-form.component.ts @@ -1,23 +1,23 @@ -import { ChangeDetectionStrategy, Component, Inject, OnInit } from "@angular/core"; -import { KeyResultMetric } from "../../../shared/types/model/KeyResultMetric"; -import { FormControl, FormGroup, Validators } from "@angular/forms"; -import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; -import { KeyResult } from "../../../shared/types/model/KeyResult"; -import { KeyResultOrdinal } from "../../../shared/types/model/KeyResultOrdinal"; -import { CheckInMin } from "../../../shared/types/model/CheckInMin"; -import { CheckInService } from "../../../services/check-in.service"; -import { Action } from "../../../shared/types/model/Action"; -import { ActionService } from "../../../services/action.service"; -import { formInputCheck, hasFormFieldErrors } from "../../../shared/common"; -import { TranslateService } from "@ngx-translate/core"; -import { CheckIn } from "../../../shared/types/model/CheckIn"; -import { CheckInMetricMin } from "../../../shared/types/model/CheckInMetricMin"; -import { CheckInOrdinalMin } from "../../../shared/types/model/CheckInOrdinalMin"; +import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core'; +import { KeyResultMetric } from '../../../shared/types/model/KeyResultMetric'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { KeyResult } from '../../../shared/types/model/KeyResult'; +import { KeyResultOrdinal } from '../../../shared/types/model/KeyResultOrdinal'; +import { CheckInMin } from '../../../shared/types/model/CheckInMin'; +import { CheckInService } from '../../../services/check-in.service'; +import { Action } from '../../../shared/types/model/Action'; +import { ActionService } from '../../../services/action.service'; +import { formInputCheck, hasFormFieldErrors } from '../../../shared/common'; +import { TranslateService } from '@ngx-translate/core'; +import { CheckIn } from '../../../shared/types/model/CheckIn'; +import { CheckInMetricMin } from '../../../shared/types/model/CheckInMetricMin'; +import { CheckInOrdinalMin } from '../../../shared/types/model/CheckInOrdinalMin'; @Component({ - selector: "app-check-in-form", - templateUrl: "./check-in-form.component.html", - styleUrls: ["./check-in-form.component.scss"], + selector: 'app-check-in-form', + templateUrl: './check-in-form.component.html', + styleUrls: ['./check-in-form.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class CheckInFormComponent implements OnInit { @@ -30,12 +30,12 @@ export class CheckInFormComponent implements OnInit { continued = false; dialogForm = new FormGroup({ - value: new FormControl("", [Validators.required]), + value: new FormControl('', [Validators.required]), confidence: new FormControl(5, [Validators.required, Validators.min(0), Validators.max(10)]), - changeInfo: new FormControl("", [Validators.maxLength(4096)]), - initiatives: new FormControl("", [Validators.maxLength(4096)]), + changeInfo: new FormControl('', [Validators.maxLength(4096)]), + initiatives: new FormControl('', [Validators.maxLength(4096)]), actionList: new FormControl([]) }); @@ -60,7 +60,7 @@ export class CheckInFormComponent implements OnInit { } getErrorMessage(error: string, field: string, maxLength: number): string { - return field + this.translate.instant("DIALOG_ERRORS." + error) + return field + this.translate.instant('DIALOG_ERRORS.' + error) .format(maxLength); } @@ -106,7 +106,7 @@ export class CheckInFormComponent implements OnInit { }; const checkIn: CheckIn = { ...baseCheckIn, - [this.keyResult.keyResultType === "ordinal" ? "zone" : "value"]: this.dialogForm.controls.value.value + [this.keyResult.keyResultType === 'ordinal' ? 'zone' : 'value']: this.dialogForm.controls.value.value }; this.checkInService.saveCheckIn(checkIn) @@ -120,9 +120,9 @@ export class CheckInFormComponent implements OnInit { getCheckInValue(): string { if ((this.checkIn as CheckInMetricMin).value != null) { - return (this.checkIn as CheckInMetricMin).value?.toString() ?? ""; + return (this.checkIn as CheckInMetricMin).value?.toString() ?? ''; } else { - return (this.checkIn as CheckInOrdinalMin).zone ?? ""; + return (this.checkIn as CheckInOrdinalMin).zone ?? ''; } } @@ -135,7 +135,7 @@ export class CheckInFormComponent implements OnInit { } getActions(): Action[] { - return this.dialogForm.controls["actionList"].value || []; + return this.dialogForm.controls['actionList'].value || []; } changeIsChecked(event: any, index: number) { @@ -148,6 +148,6 @@ export class CheckInFormComponent implements OnInit { } getDialogTitle(): string { - return this.checkIn.id ? "Check-in bearbeiten" : "Check-in erfassen"; + return this.checkIn.id ? 'Check-in bearbeiten' : 'Check-in erfassen'; } } diff --git a/frontend/src/app/components/confidence/confidence.component.spec.ts b/frontend/src/app/components/confidence/confidence.component.spec.ts index cbeac5c773..867eddf454 100644 --- a/frontend/src/app/components/confidence/confidence.component.spec.ts +++ b/frontend/src/app/components/confidence/confidence.component.spec.ts @@ -1,14 +1,14 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ConfidenceComponent } from "./confidence.component"; -import { checkInMetric } from "../../shared/testData"; -import { MatSliderModule } from "@angular/material/slider"; -import { CheckInMin } from "../../shared/types/model/CheckInMin"; -import { FormsModule } from "@angular/forms"; -import { SimpleChange } from "@angular/core"; -import { By } from "@angular/platform-browser"; +import { ConfidenceComponent } from './confidence.component'; +import { checkInMetric } from '../../shared/testData'; +import { MatSliderModule } from '@angular/material/slider'; +import { CheckInMin } from '../../shared/types/model/CheckInMin'; +import { FormsModule } from '@angular/forms'; +import { SimpleChange } from '@angular/core'; +import { By } from '@angular/platform-browser'; -describe("ConfidenceComponent", () => { +describe('ConfidenceComponent', () => { let component: ConfidenceComponent; let fixture: ComponentFixture; @@ -26,24 +26,24 @@ describe("ConfidenceComponent", () => { component.edit = true; }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); it.each([[{ confidence: 8 } as CheckInMin, - "8"], + '8'], [null, - "5"]])("should set confidence of component with right value", async(checkIn: CheckInMin | null, expected: string) => { + '5']])('should set confidence of component with right value', async(checkIn: CheckInMin | null, expected: string) => { component.checkIn = checkIn!; component.ngOnChanges({ checkIn: new SimpleChange(null, component.checkIn, true) }); fixture.detectChanges(); await fixture.whenStable(); - const textField = fixture.debugElement.query(By.css("[data-testid='confidence']")); - const expectedLabel = expected + "/" + component.max; - const sliderInputField = fixture.debugElement.query(By.css("mat-slider > input ")); + const textField = fixture.debugElement.query(By.css('[data-testid=\'confidence\']')); + const expectedLabel = expected + '/' + component.max; + const sliderInputField = fixture.debugElement.query(By.css('mat-slider > input ')); expect(await sliderInputField.nativeElement.value) .toBe(expected); @@ -52,10 +52,10 @@ describe("ConfidenceComponent", () => { }); it.each([[true], - [false]])("should show slider on based on input var", async(editable) => { + [false]])('should show slider on based on input var', async(editable) => { component.edit = editable; fixture.detectChanges(); - const slider = fixture.debugElement.query(By.css("mat-slider")); + const slider = fixture.debugElement.query(By.css('mat-slider')); expect(!!slider) .toBe(editable); diff --git a/frontend/src/app/components/confidence/confidence.component.ts b/frontend/src/app/components/confidence/confidence.component.ts index e2ffcf6823..bfe2b48af6 100644 --- a/frontend/src/app/components/confidence/confidence.component.ts +++ b/frontend/src/app/components/confidence/confidence.component.ts @@ -1,10 +1,10 @@ -import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from "@angular/core"; -import { CheckInMin } from "../../shared/types/model/CheckInMin"; +import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core'; +import { CheckInMin } from '../../shared/types/model/CheckInMin'; @Component({ - selector: "app-confidence", - templateUrl: "./confidence.component.html", - styleUrls: ["./confidence.component.scss"], + selector: 'app-confidence', + templateUrl: './confidence.component.html', + styleUrls: ['./confidence.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class ConfidenceComponent implements OnChanges { @@ -19,7 +19,7 @@ export class ConfidenceComponent implements OnChanges { @Input() checkIn!: CheckInMin; ngOnChanges(changes: SimpleChanges) { - if (!changes["checkIn"]?.currentValue) { + if (!changes['checkIn']?.currentValue) { this.checkIn = { confidence: 5 } as CheckInMin; } } diff --git a/frontend/src/app/components/key-result-form/key-result-form.component.spec.ts b/frontend/src/app/components/key-result-form/key-result-form.component.spec.ts index fa647f8c6e..7127efb2e1 100644 --- a/frontend/src/app/components/key-result-form/key-result-form.component.spec.ts +++ b/frontend/src/app/components/key-result-form/key-result-form.component.spec.ts @@ -1,44 +1,44 @@ -import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { KeyresultService } from "../../services/keyresult.service"; -import { MatDialogModule, MatDialogRef } from "@angular/material/dialog"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { MatInputModule } from "@angular/material/input"; -import { FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms"; -import { provideHttpClientTesting } from "@angular/common/http/testing"; -import { MatIconModule } from "@angular/material/icon"; -import { keyResultOrdinal, testUser, users } from "../../shared/testData"; -import { State } from "../../shared/types/enums/State"; -import { Observable, of } from "rxjs"; -import { MatAutocompleteModule } from "@angular/material/autocomplete"; -import { MatSelectModule } from "@angular/material/select"; -import { MatRadioModule } from "@angular/material/radio"; -import { KeyResultObjective } from "../../shared/types/model/KeyResultObjective"; -import { User } from "../../shared/types/model/User"; -import { OAuthService } from "angular-oauth2-oidc"; -import { KeyresultTypeComponent } from "../keyresult-type/keyresult-type.component"; -import { ActionPlanComponent } from "../action-plan/action-plan.component"; -import { TranslateModule, TranslateService } from "@ngx-translate/core"; -import { DragDropModule } from "@angular/cdk/drag-drop"; -import { UserService } from "../../services/user.service"; -import { KeyResultFormComponent } from "./key-result-form.component"; -import { Action } from "../../shared/types/model/Action"; -import { KeyResultMetric } from "../../shared/types/model/KeyResultMetric"; -import { KeyResultOrdinal } from "../../shared/types/model/KeyResultOrdinal"; -import { TranslateTestingModule } from "ngx-translate-testing"; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { KeyresultService } from '../../services/keyresult.service'; +import { MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatInputModule } from '@angular/material/input'; +import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { MatIconModule } from '@angular/material/icon'; +import { keyResultOrdinal, testUser, users } from '../../shared/testData'; +import { State } from '../../shared/types/enums/State'; +import { Observable, of } from 'rxjs'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatSelectModule } from '@angular/material/select'; +import { MatRadioModule } from '@angular/material/radio'; +import { KeyResultObjective } from '../../shared/types/model/KeyResultObjective'; +import { User } from '../../shared/types/model/User'; +import { OAuthService } from 'angular-oauth2-oidc'; +import { KeyresultTypeComponent } from '../keyresult-type/keyresult-type.component'; +import { ActionPlanComponent } from '../action-plan/action-plan.component'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { DragDropModule } from '@angular/cdk/drag-drop'; +import { UserService } from '../../services/user.service'; +import { KeyResultFormComponent } from './key-result-form.component'; +import { Action } from '../../shared/types/model/Action'; +import { KeyResultMetric } from '../../shared/types/model/KeyResultMetric'; +import { KeyResultOrdinal } from '../../shared/types/model/KeyResultOrdinal'; +import { TranslateTestingModule } from 'ngx-translate-testing'; // @ts-ignore -import * as de from "../../../assets/i18n/de.json"; -import { provideRouter } from "@angular/router"; -import { provideHttpClient } from "@angular/common/http"; -import { DialogTemplateCoreComponent } from "../../shared/custom/dialog-template-core/dialog-template-core.component"; -import { Quarter } from "../../shared/types/model/Quarter"; +import * as de from '../../../assets/i18n/de.json'; +import { provideRouter } from '@angular/router'; +import { provideHttpClient } from '@angular/common/http'; +import { DialogTemplateCoreComponent } from '../../shared/custom/dialog-template-core/dialog-template-core.component'; +import { Quarter } from '../../shared/types/model/Quarter'; -describe("KeyResultFormComponent", () => { +describe('KeyResultFormComponent', () => { let component: KeyResultFormComponent; let fixture: ComponentFixture; const oauthMockService = { getIdentityClaims() { - return { name: users[1].firstname + " " + users[1].lastname }; + return { name: users[1].firstname + ' ' + users[1].lastname }; } }; @@ -60,30 +60,30 @@ describe("KeyResultFormComponent", () => { const keyResultForm = { owner: null, actionList: [], - title: "Title", + title: 'Title', baseline: 0, stretchZone: null, targetZone: null, commitZone: null, - unit: "FTE", + unit: 'FTE', description: null, stretchGoal: 0, - keyResultType: "metric" + keyResultType: 'metric' }; const keyResultObjective: KeyResultObjective = { id: 2, state: State.ONGOING, quarter: new Quarter( - 1, "GJ 22/23-Q2", new Date(), new Date() + 1, 'GJ 22/23-Q2', new Date(), new Date() ) }; const keyResultFormGroup = new FormGroup({ - title: new FormControl("", [Validators.required, + title: new FormControl('', [Validators.required, Validators.minLength(2), Validators.maxLength(250)]), - description: new FormControl("", [Validators.maxLength(4096)]), + description: new FormControl('', [Validators.maxLength(4096)]), owner: new FormControl(null, [Validators.required, Validators.nullValidator]), actionList: new FormControl([]), @@ -93,10 +93,10 @@ describe("KeyResultFormComponent", () => { commitZone: new FormControl(null), targetZone: new FormControl(null), stretchZone: new FormControl(null), - keyResultType: new FormControl("metric") + keyResultType: new FormControl('metric') }); - describe("New KeyResult", () => { + describe('New KeyResult', () => { beforeEach(() => { mockUserService.getUsers.mockReturnValue(users); TestBed.configureTestingModule({ @@ -148,38 +148,38 @@ describe("KeyResultFormComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should have logged in user as owner", waitForAsync(async() => { - const userServiceSpy = jest.spyOn(userService, "getUsers"); + it('should have logged in user as owner', waitForAsync(async() => { + const userServiceSpy = jest.spyOn(userService, 'getUsers'); component.keyResultForm.setValue(keyResultForm); component.ngOnInit(); fixture.detectChanges(); const formObject = component.keyResultForm.value; expect(formObject.title) - .toBe("Title"); + .toBe('Title'); expect(formObject.description) .toBe(null); expect(userServiceSpy) .toHaveBeenCalled(); - expect(component.keyResultForm.controls["owner"].value) + expect(component.keyResultForm.controls['owner'].value) .toBe(testUser); expect(component.keyResultForm.invalid) .toBeFalsy(); })); - it("should return right filtered user", () => { - let userObservable: Observable = component.filter("baum"); + it('should return right filtered user', () => { + let userObservable: Observable = component.filter('baum'); userObservable.subscribe((userList) => { expect(userList.length) .toEqual(1); }); - userObservable = component.filter("ob"); + userObservable = component.filter('ob'); userObservable.subscribe((userList) => { expect(userList.length) @@ -187,85 +187,85 @@ describe("KeyResultFormComponent", () => { }); }); - it("should return label from user", () => { + it('should return label from user', () => { const userName: string = component.getUserNameFromUser(testUser); expect(userName) - .toEqual("Bob Baumeister"); + .toEqual('Bob Baumeister'); }); - it("should set metric values", () => { + it('should set metric values', () => { const fullKeyResultMetric: KeyResultMetric = { id: 3, version: 2, - title: "Der Titel ist hier", - description: "Die Beschreibung", + title: 'Der Titel ist hier', + description: 'Die Beschreibung', owner: testUser, objective: keyResultObjective, baseline: 3, - keyResultType: "metric", + keyResultType: 'metric', lastCheckIn: null, actionList: null, stretchGoal: 25, - unit: "CHF", + unit: 'CHF', createdOn: new Date(), modifiedOn: new Date(), writeable: true }; component.setMetricValuesInForm(fullKeyResultMetric); - expect(component.keyResultForm.controls["baseline"].value) + expect(component.keyResultForm.controls['baseline'].value) .toEqual(3); - expect(component.keyResultForm.controls["stretchGoal"].value) + expect(component.keyResultForm.controls['stretchGoal'].value) .toEqual(25); - expect(component.keyResultForm.controls["unit"].value) - .toEqual("CHF"); + expect(component.keyResultForm.controls['unit'].value) + .toEqual('CHF'); }); - it("should set ordinal values", () => { + it('should set ordinal values', () => { const fullKeyResultOrdinal: KeyResultOrdinal = { id: 3, version: 2, - title: "Der Titel ist hier", - description: "Die Beschreibung", + title: 'Der Titel ist hier', + description: 'Die Beschreibung', owner: testUser, objective: keyResultObjective, - commitZone: "Eine Kuh", - keyResultType: "metric", + commitZone: 'Eine Kuh', + keyResultType: 'metric', lastCheckIn: null, actionList: null, - targetZone: "Ein Schaf", - stretchZone: "Eine Ziege", + targetZone: 'Ein Schaf', + stretchZone: 'Eine Ziege', createdOn: new Date(), modifiedOn: new Date(), writeable: true }; component.setOrdinalValuesInForm(fullKeyResultOrdinal); - expect(component.keyResultForm.controls["commitZone"].value) - .toEqual("Eine Kuh"); - expect(component.keyResultForm.controls["targetZone"].value) - .toEqual("Ein Schaf"); - expect(component.keyResultForm.controls["stretchZone"].value) - .toEqual("Eine Ziege"); + expect(component.keyResultForm.controls['commitZone'].value) + .toEqual('Eine Kuh'); + expect(component.keyResultForm.controls['targetZone'].value) + .toEqual('Ein Schaf'); + expect(component.keyResultForm.controls['stretchZone'].value) + .toEqual('Eine Ziege'); }); - it("should get metric value right", () => { + it('should get metric value right', () => { expect(component.isMetricKeyResult()) .toBeTruthy(); - component.keyResultForm.patchValue({ keyResultType: "ordinal" }); + component.keyResultForm.patchValue({ keyResultType: 'ordinal' }); expect(component.isMetricKeyResult()) .toBeFalsy(); }); - it("should get username from user right", () => { + it('should get username from user right', () => { const user = users[0]; expect(component.getUserNameFromUser(user)) - .toEqual("Bob Baumeister"); + .toEqual('Bob Baumeister'); expect(component.getUserNameFromUser(null!)) - .toEqual(""); + .toEqual(''); }); - it("should get keyresult id right", () => { + it('should get keyresult id right', () => { expect(component.getKeyResultId()) .toEqual(null); component.keyResult = keyResultOrdinal; @@ -273,9 +273,9 @@ describe("KeyResultFormComponent", () => { .toEqual(101); }); - it("should get username from oauthService right", () => { + it('should get username from oauthService right', () => { expect(component.getLoggedInUserName()) - .toEqual(testUser.firstname + " " + testUser.lastname); + .toEqual(testUser.firstname + ' ' + testUser.lastname); }); }); }); diff --git a/frontend/src/app/components/key-result-form/key-result-form.component.ts b/frontend/src/app/components/key-result-form/key-result-form.component.ts index fd26a8a0d5..32bbc076f3 100644 --- a/frontend/src/app/components/key-result-form/key-result-form.component.ts +++ b/frontend/src/app/components/key-result-form/key-result-form.component.ts @@ -1,20 +1,20 @@ -import { ChangeDetectionStrategy, Component, Input, OnDestroy, OnInit } from "@angular/core"; -import { FormGroup } from "@angular/forms"; -import { getFullNameFromUser, User } from "../../shared/types/model/User"; -import { KeyResult } from "../../shared/types/model/KeyResult"; -import { KeyResultMetric } from "../../shared/types/model/KeyResultMetric"; -import { KeyResultOrdinal } from "../../shared/types/model/KeyResultOrdinal"; -import { BehaviorSubject, filter, map, Observable, of, startWith, Subject, switchMap, takeUntil } from "rxjs"; -import { UserService } from "../../services/user.service"; -import { Action } from "../../shared/types/model/Action"; -import { formInputCheck, hasFormFieldErrors } from "../../shared/common"; -import { OAuthService } from "angular-oauth2-oidc"; -import { TranslateService } from "@ngx-translate/core"; +import { ChangeDetectionStrategy, Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { FormGroup } from '@angular/forms'; +import { getFullNameFromUser, User } from '../../shared/types/model/User'; +import { KeyResult } from '../../shared/types/model/KeyResult'; +import { KeyResultMetric } from '../../shared/types/model/KeyResultMetric'; +import { KeyResultOrdinal } from '../../shared/types/model/KeyResultOrdinal'; +import { BehaviorSubject, filter, map, Observable, of, startWith, Subject, switchMap, takeUntil } from 'rxjs'; +import { UserService } from '../../services/user.service'; +import { Action } from '../../shared/types/model/Action'; +import { formInputCheck, hasFormFieldErrors } from '../../shared/common'; +import { OAuthService } from 'angular-oauth2-oidc'; +import { TranslateService } from '@ngx-translate/core'; @Component({ - selector: "app-key-result-form", - templateUrl: "./key-result-form.component.html", - styleUrls: ["./key-result-form.component.scss"], + selector: 'app-key-result-form', + templateUrl: './key-result-form.component.html', + styleUrls: ['./key-result-form.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class KeyResultFormComponent implements OnInit, OnDestroy { @@ -43,13 +43,13 @@ export class KeyResultFormComponent implements OnInit, OnDestroy { ngOnInit(): void { this.users$ = this.userService.getUsers(); - this.filteredUsers$ = this.keyResultForm.get("owner")?.valueChanges.pipe(startWith(""), filter((value) => typeof value === "string"), switchMap((value) => this.filter(value as string))); + this.filteredUsers$ = this.keyResultForm.get('owner')?.valueChanges.pipe(startWith(''), filter((value) => typeof value === 'string'), switchMap((value) => this.filter(value as string))); if (this.keyResult) { this.keyResultForm.patchValue({ actionList: this.keyResult.actionList }); - this.keyResultForm.controls["title"].setValue(this.keyResult.title); - this.keyResultForm.controls["description"].setValue(this.keyResult.description); - this.keyResultForm.controls["owner"].setValue(this.keyResult.owner); - this.keyResultForm.controls["keyResultType"].setValue(this.keyResult.keyResultType); + this.keyResultForm.controls['title'].setValue(this.keyResult.title); + this.keyResultForm.controls['description'].setValue(this.keyResult.description); + this.keyResultForm.controls['owner'].setValue(this.keyResult.owner); + this.keyResultForm.controls['keyResultType'].setValue(this.keyResult.keyResultType); this.isMetricKeyResult() ? this.setMetricValuesInForm(this.keyResult as KeyResultMetric) : this.setOrdinalValuesInForm(this.keyResult as KeyResultOrdinal); @@ -60,7 +60,7 @@ export class KeyResultFormComponent implements OnInit, OnDestroy { this.actionList$ = new BehaviorSubject([{ id: null, version: 1, - action: "", + action: '', priority: 0, keyResultId: null, isChecked: false @@ -68,7 +68,7 @@ export class KeyResultFormComponent implements OnInit, OnDestroy { { id: null, version: 1, - action: "", + action: '', priority: 1, keyResultId: null, isChecked: false @@ -76,7 +76,7 @@ export class KeyResultFormComponent implements OnInit, OnDestroy { { id: null, version: 1, - action: "", + action: '', priority: 2, keyResultId: null, isChecked: false @@ -87,7 +87,7 @@ export class KeyResultFormComponent implements OnInit, OnDestroy { const loggedInUser = this.getLoggedInUserName(); users.forEach((user) => { if (getFullNameFromUser(user) === loggedInUser) { - this.keyResultForm.controls["owner"].setValue(user); + this.keyResultForm.controls['owner'].setValue(user); } }); }); @@ -104,19 +104,19 @@ export class KeyResultFormComponent implements OnInit, OnDestroy { } isMetricKeyResult() { - return this.keyResultForm.controls["keyResultType"].value === "metric"; + return this.keyResultForm.controls['keyResultType'].value === 'metric'; } setMetricValuesInForm(keyResultMetric: KeyResultMetric) { - this.keyResultForm.controls["unit"].setValue(keyResultMetric.unit); - this.keyResultForm.controls["baseline"].setValue(keyResultMetric.baseline); - this.keyResultForm.controls["stretchGoal"].setValue(keyResultMetric.stretchGoal); + this.keyResultForm.controls['unit'].setValue(keyResultMetric.unit); + this.keyResultForm.controls['baseline'].setValue(keyResultMetric.baseline); + this.keyResultForm.controls['stretchGoal'].setValue(keyResultMetric.stretchGoal); } setOrdinalValuesInForm(keyResultOrdinal: KeyResultOrdinal) { - this.keyResultForm.controls["commitZone"].setValue(keyResultOrdinal.commitZone); - this.keyResultForm.controls["targetZone"].setValue(keyResultOrdinal.targetZone); - this.keyResultForm.controls["stretchZone"].setValue(keyResultOrdinal.stretchZone); + this.keyResultForm.controls['commitZone'].setValue(keyResultOrdinal.commitZone); + this.keyResultForm.controls['targetZone'].setValue(keyResultOrdinal.targetZone); + this.keyResultForm.controls['stretchZone'].setValue(keyResultOrdinal.stretchZone); } isTouchedOrDirty(name: string) { @@ -126,7 +126,7 @@ export class KeyResultFormComponent implements OnInit, OnDestroy { getErrorMessage( error: string, field: string, firstNumber: number | null, secondNumber: number | null ): string { - return field + this.translate.instant("DIALOG_ERRORS." + error) + return field + this.translate.instant('DIALOG_ERRORS.' + error) .format(firstNumber, secondNumber); } @@ -139,13 +139,13 @@ export class KeyResultFormComponent implements OnInit, OnDestroy { invalidOwner(): boolean { return ( - !!this.isTouchedOrDirty("owner") && - (typeof this.keyResultForm.value.owner === "string" || !this.keyResultForm.value.owner) + !!this.isTouchedOrDirty('owner') && + (typeof this.keyResultForm.value.owner === 'string' || !this.keyResultForm.value.owner) ); } getUserNameFromUser(user: User): string { - return user ? getFullNameFromUser(user) : ""; + return user ? getFullNameFromUser(user) : ''; } getKeyResultId(): number | null { diff --git a/frontend/src/app/components/keyresult-detail/keyresult-detail.component.spec.ts b/frontend/src/app/components/keyresult-detail/keyresult-detail.component.spec.ts index 5ad19126c1..5422ef8cf3 100644 --- a/frontend/src/app/components/keyresult-detail/keyresult-detail.component.spec.ts +++ b/frontend/src/app/components/keyresult-detail/keyresult-detail.component.spec.ts @@ -1,18 +1,18 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; - -import { KeyresultDetailComponent } from "./keyresult-detail.component"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { MatDialogModule } from "@angular/material/dialog"; -import { TranslateModule } from "@ngx-translate/core"; -import { of } from "rxjs"; -import { keyResult, keyResultWriteableFalse } from "../../shared/testData"; -import { By } from "@angular/platform-browser"; -import { KeyresultService } from "../../services/keyresult.service"; -import { MatIconModule } from "@angular/material/icon"; -import { ActivatedRoute } from "@angular/router"; -import { ScoringComponent } from "../../shared/custom/scoring/scoring.component"; -import { ConfidenceComponent } from "../confidence/confidence.component"; -import { RefreshDataService } from "../../services/refresh-data.service"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { KeyresultDetailComponent } from './keyresult-detail.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { MatDialogModule } from '@angular/material/dialog'; +import { TranslateModule } from '@ngx-translate/core'; +import { of } from 'rxjs'; +import { keyResult, keyResultWriteableFalse } from '../../shared/testData'; +import { By } from '@angular/platform-browser'; +import { KeyresultService } from '../../services/keyresult.service'; +import { MatIconModule } from '@angular/material/icon'; +import { ActivatedRoute } from '@angular/router'; +import { ScoringComponent } from '../../shared/custom/scoring/scoring.component'; +import { ConfidenceComponent } from '../confidence/confidence.component'; +import { RefreshDataService } from '../../services/refresh-data.service'; const keyResultServiceMock = { getFullKeyResult: jest.fn() @@ -26,7 +26,7 @@ const activatedRouteMock = { } }; -describe("KeyresultDetailComponent", () => { +describe('KeyresultDetailComponent', () => { let component: KeyresultDetailComponent; let fixture: ComponentFixture; @@ -52,7 +52,7 @@ describe("KeyresultDetailComponent", () => { }) .compileComponents(); - jest.spyOn(keyResultServiceMock, "getFullKeyResult") + jest.spyOn(keyResultServiceMock, 'getFullKeyResult') .mockReturnValue(of(keyResult)); activatedRouteMock.snapshot.paramMap.get.mockReturnValue(of(1)); @@ -61,60 +61,60 @@ describe("KeyresultDetailComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should throw error when id is undefined", () => { + it('should throw error when id is undefined', () => { activatedRouteMock.snapshot.paramMap.get.mockReturnValue(undefined); expect(() => component.ngOnInit()) - .toThrowError("keyresult id is undefined"); + .toThrowError('keyresult id is undefined'); }); - it("should display edit keyresult button if writeable is true", async() => { - const button = fixture.debugElement.query(By.css("[data-testId=\"edit-keyResult\"]")); + it('should display edit keyresult button if writeable is true', async() => { + const button = fixture.debugElement.query(By.css('[data-testId="edit-keyResult"]')); expect(button) .toBeTruthy(); }); - it("should not display edit keyresult button if writeable is false", async() => { - jest.spyOn(keyResultServiceMock, "getFullKeyResult") + it('should not display edit keyresult button if writeable is false', async() => { + jest.spyOn(keyResultServiceMock, 'getFullKeyResult') .mockReturnValue(of(keyResultWriteableFalse)); component.ngOnInit(); fixture.detectChanges(); - const button = fixture.debugElement.query(By.css("[data-testId=\"edit-keyResult\"]")); + const button = fixture.debugElement.query(By.css('[data-testId="edit-keyResult"]')); expect(button) .toBeFalsy(); }); - it("should display add check-in button if writeable is true", async() => { - const button = fixture.debugElement.query(By.css("[data-testId=\"add-check-in\"]")); + it('should display add check-in button if writeable is true', async() => { + const button = fixture.debugElement.query(By.css('[data-testId="add-check-in"]')); expect(button) .toBeTruthy(); }); - it("should not display add check-in button if writeable is false", async() => { - jest.spyOn(keyResultServiceMock, "getFullKeyResult") + it('should not display add check-in button if writeable is false', async() => { + jest.spyOn(keyResultServiceMock, 'getFullKeyResult') .mockReturnValue(of(keyResultWriteableFalse)); component.ngOnInit(); fixture.detectChanges(); - const button = fixture.debugElement.query(By.css("[data-testId=\"add-check-in\"]")); + const button = fixture.debugElement.query(By.css('[data-testId="add-check-in"]')); expect(button) .toBeFalsy(); }); - it("should trigger observable when subject gets next value", () => { - const spy = jest.spyOn(component, "loadKeyResult"); + it('should trigger observable when subject gets next value', () => { + const spy = jest.spyOn(component, 'loadKeyResult'); const refreshDataService = TestBed.inject(RefreshDataService); refreshDataService.reloadKeyResultSubject.next(); expect(spy) .toHaveBeenCalled(); }); - it("should close subscription on destroy", () => { - const spyNext = jest.spyOn(component.ngDestroy$, "next"); - const spyComplete = jest.spyOn(component.ngDestroy$, "complete"); + it('should close subscription on destroy', () => { + const spyNext = jest.spyOn(component.ngDestroy$, 'next'); + const spyComplete = jest.spyOn(component.ngDestroy$, 'complete'); component.ngOnDestroy(); diff --git a/frontend/src/app/components/keyresult-detail/keyresult-detail.component.ts b/frontend/src/app/components/keyresult-detail/keyresult-detail.component.ts index c24d360d1c..69ab2a4f3f 100644 --- a/frontend/src/app/components/keyresult-detail/keyresult-detail.component.ts +++ b/frontend/src/app/components/keyresult-detail/keyresult-detail.component.ts @@ -1,27 +1,27 @@ -import { ChangeDetectionStrategy, Component, Input, OnDestroy, OnInit } from "@angular/core"; -import { KeyResult } from "../../shared/types/model/KeyResult"; -import { KeyresultService } from "../../services/keyresult.service"; -import { KeyResultMetric } from "../../shared/types/model/KeyResultMetric"; -import { KeyResultOrdinal } from "../../shared/types/model/KeyResultOrdinal"; -import { CheckInHistoryDialogComponent } from "../check-in-history-dialog/check-in-history-dialog.component"; -import { BehaviorSubject, catchError, EMPTY, Subject, takeUntil } from "rxjs"; -import { ActivatedRoute, Router } from "@angular/router"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { CloseState } from "../../shared/types/enums/CloseState"; -import { CheckInFormComponent } from "../checkin/check-in-form/check-in-form.component"; -import { State } from "../../shared/types/enums/State"; -import { DATE_FORMAT } from "../../shared/constantLibary"; -import { calculateCurrentPercentage, isLastCheckInNegative } from "../../shared/common"; -import { KeyresultDialogComponent } from "../keyresult-dialog/keyresult-dialog.component"; -import { DialogService } from "../../services/dialog.service"; -import { KeyresultMin } from "../../shared/types/model/KeyresultMin"; -import { KeyResultMetricMin } from "../../shared/types/model/KeyResultMetricMin"; -import { KeyResultOrdinalMin } from "../../shared/types/model/KeyResultOrdinalMin"; +import { ChangeDetectionStrategy, Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { KeyResult } from '../../shared/types/model/KeyResult'; +import { KeyresultService } from '../../services/keyresult.service'; +import { KeyResultMetric } from '../../shared/types/model/KeyResultMetric'; +import { KeyResultOrdinal } from '../../shared/types/model/KeyResultOrdinal'; +import { CheckInHistoryDialogComponent } from '../check-in-history-dialog/check-in-history-dialog.component'; +import { BehaviorSubject, catchError, EMPTY, Subject, takeUntil } from 'rxjs'; +import { ActivatedRoute, Router } from '@angular/router'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { CloseState } from '../../shared/types/enums/CloseState'; +import { CheckInFormComponent } from '../checkin/check-in-form/check-in-form.component'; +import { State } from '../../shared/types/enums/State'; +import { DATE_FORMAT } from '../../shared/constantLibary'; +import { calculateCurrentPercentage, isLastCheckInNegative } from '../../shared/common'; +import { KeyresultDialogComponent } from '../keyresult-dialog/keyresult-dialog.component'; +import { DialogService } from '../../services/dialog.service'; +import { KeyresultMin } from '../../shared/types/model/KeyresultMin'; +import { KeyResultMetricMin } from '../../shared/types/model/KeyResultMetricMin'; +import { KeyResultOrdinalMin } from '../../shared/types/model/KeyResultOrdinalMin'; @Component({ - selector: "app-keyresult-detail", - templateUrl: "./keyresult-detail.component.html", - styleUrls: ["./keyresult-detail.component.scss"], + selector: 'app-keyresult-detail', + templateUrl: './keyresult-detail.component.html', + styleUrls: ['./keyresult-detail.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class KeyresultDetailComponent implements OnInit, OnDestroy { @@ -60,9 +60,9 @@ export class KeyresultDetailComponent implements OnInit, OnDestroy { } private getIdFromParams(): number { - const id = this.route.snapshot.paramMap.get("id"); + const id = this.route.snapshot.paramMap.get('id'); if (!id) { - throw Error("keyresult id is undefined"); + throw Error('keyresult id is undefined'); } return parseInt(id); } @@ -74,7 +74,7 @@ export class KeyresultDetailComponent implements OnInit, OnDestroy { .subscribe((keyResult) => { this.keyResult$.next(keyResult); const state = keyResult.objective.state; - this.isComplete = state === ("SUCCESSFUL" as State) || state === ("NOTSUCCESSFUL" as State); + this.isComplete = state === ('SUCCESSFUL' as State) || state === ('NOTSUCCESSFUL' as State); }); } @@ -113,7 +113,7 @@ export class KeyresultDetailComponent implements OnInit, OnDestroy { this.loadKeyResult(result.id); this.refreshDataService.markDataRefresh(); } else if (result?.closeState === CloseState.DELETED) { - this.router.navigate([""]) + this.router.navigate(['']) .then(() => this.refreshDataService.markDataRefresh()); } else { this.loadKeyResult(this.keyResult$.getValue().id); @@ -122,9 +122,9 @@ export class KeyresultDetailComponent implements OnInit, OnDestroy { } checkForDraftState(keyResult: KeyResult) { - if (keyResult.objective.state.toUpperCase() === "DRAFT") { + if (keyResult.objective.state.toUpperCase() === 'DRAFT') { this.dialogService - .openConfirmDialog("CONFIRMATION.DRAFT_CREATE") + .openConfirmDialog('CONFIRMATION.DRAFT_CREATE') .afterClosed() .subscribe((result) => { if (result) { @@ -150,11 +150,11 @@ export class KeyresultDetailComponent implements OnInit, OnDestroy { } backToOverview() { - this.router.navigate([""]); + this.router.navigate(['']); } getKeyResultWithCorrectType(keyResult: KeyResult): KeyResultOrdinalMin | KeyResultMetricMin { - if (keyResult.keyResultType === "metric") { + if (keyResult.keyResultType === 'metric') { return keyResult as KeyresultMin as KeyResultMetricMin; } else { return keyResult as KeyresultMin as KeyResultOrdinalMin; diff --git a/frontend/src/app/components/keyresult-dialog/keyresult-dialog.component.spec.ts b/frontend/src/app/components/keyresult-dialog/keyresult-dialog.component.spec.ts index c583b85501..397a27b534 100644 --- a/frontend/src/app/components/keyresult-dialog/keyresult-dialog.component.spec.ts +++ b/frontend/src/app/components/keyresult-dialog/keyresult-dialog.component.spec.ts @@ -1,42 +1,42 @@ -import { KeyresultDialogComponent } from "./keyresult-dialog.component"; -import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; -import { KeyresultService } from "../../services/keyresult.service"; -import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from "@angular/material/dialog"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { MatInputModule } from "@angular/material/input"; -import { ReactiveFormsModule } from "@angular/forms"; -import { MatIconModule } from "@angular/material/icon"; -import { By } from "@angular/platform-browser"; -import { testUser, users } from "../../shared/testData"; -import { State } from "../../shared/types/enums/State"; -import { KeyResult } from "../../shared/types/model/KeyResult"; -import { of } from "rxjs"; -import { MatAutocompleteModule } from "@angular/material/autocomplete"; -import { MatSelectModule } from "@angular/material/select"; -import { MatRadioModule } from "@angular/material/radio"; -import { KeyResultObjective } from "../../shared/types/model/KeyResultObjective"; -import { OAuthService } from "angular-oauth2-oidc"; -import { KeyresultTypeComponent } from "../keyresult-type/keyresult-type.component"; -import { ActionPlanComponent } from "../action-plan/action-plan.component"; -import { TranslateModule, TranslateService } from "@ngx-translate/core"; -import { DragDropModule } from "@angular/cdk/drag-drop"; -import { UserService } from "../../services/user.service"; -import { KeyResultFormComponent } from "../key-result-form/key-result-form.component"; -import { provideRouter } from "@angular/router"; -import { provideHttpClient } from "@angular/common/http"; -import { provideHttpClientTesting } from "@angular/common/http/testing"; -import { MatDividerModule } from "@angular/material/divider"; -import { DialogTemplateCoreComponent } from "../../shared/custom/dialog-template-core/dialog-template-core.component"; -import { Quarter } from "../../shared/types/model/Quarter"; - -describe("KeyresultDialogComponent", () => { +import { KeyresultDialogComponent } from './keyresult-dialog.component'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { KeyresultService } from '../../services/keyresult.service'; +import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatInputModule } from '@angular/material/input'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatIconModule } from '@angular/material/icon'; +import { By } from '@angular/platform-browser'; +import { testUser, users } from '../../shared/testData'; +import { State } from '../../shared/types/enums/State'; +import { KeyResult } from '../../shared/types/model/KeyResult'; +import { of } from 'rxjs'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatSelectModule } from '@angular/material/select'; +import { MatRadioModule } from '@angular/material/radio'; +import { KeyResultObjective } from '../../shared/types/model/KeyResultObjective'; +import { OAuthService } from 'angular-oauth2-oidc'; +import { KeyresultTypeComponent } from '../keyresult-type/keyresult-type.component'; +import { ActionPlanComponent } from '../action-plan/action-plan.component'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { DragDropModule } from '@angular/cdk/drag-drop'; +import { UserService } from '../../services/user.service'; +import { KeyResultFormComponent } from '../key-result-form/key-result-form.component'; +import { provideRouter } from '@angular/router'; +import { provideHttpClient } from '@angular/common/http'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { MatDividerModule } from '@angular/material/divider'; +import { DialogTemplateCoreComponent } from '../../shared/custom/dialog-template-core/dialog-template-core.component'; +import { Quarter } from '../../shared/types/model/Quarter'; + +describe('KeyresultDialogComponent', () => { let component: KeyresultDialogComponent; let fixture: ComponentFixture; let keyResultService: KeyresultService; const oauthMockService = { getIdentityClaims() { - return { name: users[1].firstname + " " + users[1].lastname }; + return { name: users[1].firstname + ' ' + users[1].lastname }; } }; @@ -49,20 +49,20 @@ describe("KeyresultDialogComponent", () => { const fullObjective = { id: 1, - title: "Das ist ein Objective", - description: "Das ist die Beschreibung", + title: 'Das ist ein Objective', + description: 'Das ist die Beschreibung', state: State.ONGOING, team: { id: 1, - name: "Das Puzzle Team" }, + name: 'Das Puzzle Team' }, quarter: { id: 1, - label: "GJ 22/23-Q2" } + label: 'GJ 22/23-Q2' } }; const keyResultObjective: KeyResultObjective = { id: 2, state: State.ONGOING, quarter: new Quarter( - 1, "GJ 22/23-Q2", new Date(), new Date() + 1, 'GJ 22/23-Q2', new Date(), new Date() ) }; @@ -71,33 +71,33 @@ describe("KeyresultDialogComponent", () => { version: 2, actionList: [{ id: 1, - action: "Test", + action: 'Test', isChecked: false, keyResultId: 3, priority: 0 }, { id: 2, - action: "Katze", + action: 'Katze', isChecked: false, keyResultId: 3, priority: 1 }, { id: 3, - action: "Hund", + action: 'Hund', isChecked: true, keyResultId: 3, priority: 2 }], - title: "Der Titel ist hier", - description: "Die Beschreibung", + title: 'Der Titel ist hier', + description: 'Die Beschreibung', owner: testUser, objective: keyResultObjective, baseline: 3, - keyResultType: "metric", + keyResultType: 'metric', stretchGoal: 25, - unit: "CHF" + unit: 'CHF' }; const receivedKeyResultMetric = { @@ -105,33 +105,33 @@ describe("KeyresultDialogComponent", () => { version: 2, actionList: [{ id: 1, - action: "Test", + action: 'Test', isChecked: false, keyResultId: 3, priority: 0 }, { id: 2, - action: "Katze", + action: 'Katze', isChecked: false, keyResultId: 3, priority: 1 }, { id: 3, - action: "Hund", + action: 'Hund', isChecked: true, keyResultId: 3, priority: 2 }], - title: "Der Titel ist hier", - description: "Die Beschreibung", + title: 'Der Titel ist hier', + description: 'Die Beschreibung', owner: testUser, objective: keyResultObjective, baseline: 3, - keyResultType: "metric", + keyResultType: 'metric', stretchGoal: 25, - unit: "CHF", + unit: 'CHF', commitZone: null, targetZone: null, stretchZone: null @@ -142,33 +142,33 @@ describe("KeyresultDialogComponent", () => { version: 2, actionList: [{ id: 1, - action: "Test", + action: 'Test', isChecked: false, keyResultId: 3, priority: 0 }, { id: 2, - action: "Katze", + action: 'Katze', isChecked: false, keyResultId: 3, priority: 1 }, { id: 3, - action: "Hund", + action: 'Hund', isChecked: true, keyResultId: 3, priority: 2 }], - title: "Der Titel ist hier", - description: "Die Beschreibung", + title: 'Der Titel ist hier', + description: 'Die Beschreibung', owner: testUser, objective: keyResultObjective, - keyResultType: "ordinal", - commitZone: "Commit zone", - targetZone: "Target zone", - stretchZone: "Stretch goal" + keyResultType: 'ordinal', + commitZone: 'Commit zone', + targetZone: 'Target zone', + stretchZone: 'Stretch goal' }; const receivedKeyResultOrdinal = { @@ -176,33 +176,33 @@ describe("KeyresultDialogComponent", () => { version: 2, actionList: [{ id: 1, - action: "Test", + action: 'Test', isChecked: false, keyResultId: 3, priority: 0 }, { id: 2, - action: "Katze", + action: 'Katze', isChecked: false, keyResultId: 3, priority: 1 }, { id: 3, - action: "Hund", + action: 'Hund', isChecked: true, keyResultId: 3, priority: 2 }], - title: "Der Titel ist hier", - description: "Die Beschreibung", + title: 'Der Titel ist hier', + description: 'Die Beschreibung', owner: testUser, objective: keyResultObjective, - keyResultType: "ordinal", - commitZone: "Commit zone", - targetZone: "Target zone", - stretchZone: "Stretch goal", + keyResultType: 'ordinal', + commitZone: 'Commit zone', + targetZone: 'Target zone', + stretchZone: 'Stretch goal', baseline: null, stretchGoal: null, unit: null @@ -210,14 +210,14 @@ describe("KeyresultDialogComponent", () => { const initKeyResult = { id: undefined, - title: "", - description: "", + title: '', + description: '', owner: testUser, objective: fullObjective, baseline: 3, - keyResultType: "metric", + keyResultType: 'metric', stretchGoal: 25, - unit: "CHF", + unit: 'CHF', commitZone: null, targetZone: null, stretchZone: null, @@ -227,14 +227,14 @@ describe("KeyresultDialogComponent", () => { const savedKeyResult = { id: undefined, version: undefined, - title: "Neuer Titel", - description: "Description", + title: 'Neuer Titel', + description: 'Description', owner: testUser, objective: fullObjective, baseline: 3, - keyResultType: "metric", + keyResultType: 'metric', stretchGoal: 25, - unit: "CHF", + unit: 'CHF', commitZone: null, targetZone: null, stretchZone: null, @@ -249,7 +249,7 @@ describe("KeyresultDialogComponent", () => { getUsers: jest.fn() }; - describe("New KeyResult", () => { + describe('New KeyResult', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [ @@ -306,63 +306,63 @@ describe("KeyresultDialogComponent", () => { keyResultService = TestBed.inject(KeyresultService); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should be able to set title", waitForAsync(async() => { + it('should be able to set title', waitForAsync(async() => { component.keyResultForm.setValue({ owner: null, actionList: [], - title: "Title", + title: 'Title', baseline: 0, stretchZone: null, targetZone: null, commitZone: null, - unit: "FTE", + unit: 'FTE', description: null, stretchGoal: 0, - keyResultType: "metric" + keyResultType: 'metric' }); fixture.detectChanges(); - const submitButton = fixture.debugElement.query(By.css("[data-testId=\"submit\"]")); - expect(await submitButton.nativeElement.getAttribute("disabled")) + const submitButton = fixture.debugElement.query(By.css('[data-testId="submit"]')); + expect(await submitButton.nativeElement.getAttribute('disabled')) .toBeFalsy(); const formObject = component.keyResultForm.value; expect(formObject.title) - .toBe("Title"); + .toBe('Title'); expect(formObject.description) .toBe(null); })); - it("should display error message of too short input", waitForAsync(async() => { + it('should display error message of too short input', waitForAsync(async() => { component.keyResultForm.setValue({ owner: testUser, actionList: [], - title: "T", + title: 'T', baseline: null, stretchZone: null, targetZone: null, commitZone: null, unit: null, - description: "", + description: '', stretchGoal: null, keyResultType: null }); fixture.detectChanges(); - const submitButton = fixture.debugElement.query(By.css("[data-testId=\"submit\"]")); - expect(await submitButton.nativeElement.getAttribute("disabled")) - .toEqual(""); + const submitButton = fixture.debugElement.query(By.css('[data-testId="submit"]')); + expect(await submitButton.nativeElement.getAttribute('disabled')) + .toEqual(''); expect(component.keyResultForm.invalid) .toBeTruthy(); - expect(component.keyResultForm.get("title")!.errors?.["minlength"]) + expect(component.keyResultForm.get('title')!.errors?.['minlength']) .toBeTruthy(); })); - it("should display error message of required", waitForAsync(async() => { + it('should display error message of required', waitForAsync(async() => { component.keyResultForm.setValue({ owner: testUser, actionList: [], @@ -372,41 +372,41 @@ describe("KeyresultDialogComponent", () => { targetZone: null, commitZone: null, unit: null, - description: "", + description: '', stretchGoal: null, keyResultType: null }); fixture.detectChanges(); - const submitButton = fixture.debugElement.query(By.css("[data-testId=\"submit\"]")); - expect(await submitButton.nativeElement.getAttribute("disabled")) - .toEqual(""); + const submitButton = fixture.debugElement.query(By.css('[data-testId="submit"]')); + expect(await submitButton.nativeElement.getAttribute('disabled')) + .toEqual(''); expect(component.keyResultForm.invalid) .toBeTruthy(); - expect(component.keyResultForm.get("title")!.errors?.["required"]) + expect(component.keyResultForm.get('title')!.errors?.['required']) .toBeTruthy(); })); - it("should call service save method", waitForAsync(() => { - const spy = jest.spyOn(keyResultService, "saveKeyResult"); + it('should call service save method', waitForAsync(() => { + const spy = jest.spyOn(keyResultService, 'saveKeyResult'); spy.mockImplementation(() => of({ id: 2 } as KeyResult)); component.keyResultForm.setValue({ owner: testUser, actionList: [], - title: "Neuer Titel", + title: 'Neuer Titel', baseline: 3, stretchZone: null, targetZone: null, commitZone: null, - unit: "CHF", - description: "Description", + unit: 'CHF', + description: 'Description', stretchGoal: 25, - keyResultType: "metric" + keyResultType: 'metric' }); - initKeyResult.title = "Neuer Titel"; - initKeyResult.description = "Description"; + initKeyResult.title = 'Neuer Titel'; + initKeyResult.description = 'Description'; component.saveKeyResult(); @@ -417,7 +417,7 @@ describe("KeyresultDialogComponent", () => { })); }); - describe("Edit KeyResult Metric", () => { + describe('Edit KeyResult Metric', () => { beforeEach(() => { mockUserService.getUsers.mockReturnValue(users); TestBed.configureTestingModule({ @@ -474,60 +474,60 @@ describe("KeyresultDialogComponent", () => { mockUserService.getUsers.mockReset(); }); - it("should use KeyResult value from data input", waitForAsync(() => { + it('should use KeyResult value from data input', waitForAsync(() => { const formObject = fixture.componentInstance.keyResultForm.value; expect(formObject.title) - .toBe("Der Titel ist hier"); + .toBe('Der Titel ist hier'); expect(formObject.description) - .toBe("Die Beschreibung"); + .toBe('Die Beschreibung'); expect(formObject.owner) .toBe(testUser); })); - it("should be able to set title and description", waitForAsync(async() => { + it('should be able to set title and description', waitForAsync(async() => { expect(component.keyResultForm.value.title) - .toEqual("Der Titel ist hier"); + .toEqual('Der Titel ist hier'); expect(component.keyResultForm.value.description) - .toEqual("Die Beschreibung"); + .toEqual('Die Beschreibung'); component.keyResultForm.setValue({ owner: testUser, actionList: [], - title: "Title", + title: 'Title', baseline: 0, - stretchZone: "", - targetZone: "", - commitZone: "", - unit: "FTE", - description: "Description", + stretchZone: '', + targetZone: '', + commitZone: '', + unit: 'FTE', + description: 'Description', stretchGoal: 0, - keyResultType: "metric" + keyResultType: 'metric' }); fixture.detectChanges(); - const submitButton = fixture.debugElement.query(By.css("[data-testId=\"submit\"]")); - expect(await submitButton.nativeElement.getAttribute("disabled")) + const submitButton = fixture.debugElement.query(By.css('[data-testId="submit"]')); + expect(await submitButton.nativeElement.getAttribute('disabled')) .toBeFalsy(); const formObject = fixture.componentInstance.keyResultForm.value; expect(formObject.title) - .toBe("Title"); + .toBe('Title'); expect(formObject.description) - .toBe("Description"); + .toBe('Description'); expect(component.keyResultForm.invalid) .toBeFalsy(); })); - it("should display error message of too short input", waitForAsync(async() => { + it('should display error message of too short input', waitForAsync(async() => { component.keyResultForm.setValue({ owner: testUser, actionList: [], - title: "T", + title: 'T', baseline: null, stretchZone: null, targetZone: null, commitZone: null, unit: null, - description: "", + description: '', stretchGoal: null, keyResultType: null }); @@ -535,11 +535,11 @@ describe("KeyresultDialogComponent", () => { expect(component.keyResultForm.invalid) .toBeTruthy(); - expect(component.keyResultForm.get("title")!.errors?.["minlength"]) + expect(component.keyResultForm.get('title')!.errors?.['minlength']) .toBeTruthy(); })); - it("should display error message of required", waitForAsync(async() => { + it('should display error message of required', waitForAsync(async() => { component.keyResultForm.setValue({ owner: testUser, actionList: [], @@ -549,7 +549,7 @@ describe("KeyresultDialogComponent", () => { targetZone: null, commitZone: null, unit: null, - description: "", + description: '', stretchGoal: null, keyResultType: null }); @@ -557,12 +557,12 @@ describe("KeyresultDialogComponent", () => { expect(component.keyResultForm.invalid) .toBeTruthy(); - expect(component.keyResultForm.get("title")!.errors?.["required"]) + expect(component.keyResultForm.get('title')!.errors?.['required']) .toBeTruthy(); })); - it("should call service save method", waitForAsync(() => { - const spy = jest.spyOn(keyResultService, "saveKeyResult"); + it('should call service save method', waitForAsync(() => { + const spy = jest.spyOn(keyResultService, 'saveKeyResult'); spy.mockImplementation(() => of({ id: 2 } as KeyResult)); component.saveKeyResult(); @@ -573,9 +573,9 @@ describe("KeyresultDialogComponent", () => { .toHaveBeenCalledWith(receivedKeyResultMetric); })); - it("should not display logged in user when editing", waitForAsync(() => { + it('should not display logged in user when editing', waitForAsync(() => { jest.resetAllMocks(); - const userServiceSpy = jest.spyOn(userService, "getUsers"); + const userServiceSpy = jest.spyOn(userService, 'getUsers'); fixture.detectChanges(); expect(userServiceSpy) .toHaveBeenCalledTimes(0); @@ -584,7 +584,7 @@ describe("KeyresultDialogComponent", () => { })); }); - describe("Edit KeyResult Ordinal", () => { + describe('Edit KeyResult Ordinal', () => { beforeEach(() => { mockUserService.getUsers.mockReturnValue(users); TestBed.configureTestingModule({ @@ -638,72 +638,72 @@ describe("KeyresultDialogComponent", () => { mockUserService.getUsers.mockReset(); }); - it("should use KeyResult value from data input", waitForAsync(() => { + it('should use KeyResult value from data input', waitForAsync(() => { const formObject = fixture.componentInstance.keyResultForm.value; expect(formObject.title) - .toBe("Der Titel ist hier"); + .toBe('Der Titel ist hier'); expect(formObject.description) - .toBe("Die Beschreibung"); + .toBe('Die Beschreibung'); expect(formObject.owner) .toBe(testUser); })); - it("should be able to set title and description", waitForAsync(async() => { + it('should be able to set title and description', waitForAsync(async() => { expect(component.keyResultForm.value.title) - .toEqual("Der Titel ist hier"); + .toEqual('Der Titel ist hier'); expect(component.keyResultForm.value.description) - .toEqual("Die Beschreibung"); + .toEqual('Die Beschreibung'); component.keyResultForm.setValue({ owner: testUser, actionList: [], - title: "Title", + title: 'Title', baseline: 0, - stretchZone: "stretchZone", - targetZone: "targetZone", - commitZone: "commitZone", - unit: "FTE", - description: "Description", + stretchZone: 'stretchZone', + targetZone: 'targetZone', + commitZone: 'commitZone', + unit: 'FTE', + description: 'Description', stretchGoal: 0, - keyResultType: "ordinal" + keyResultType: 'ordinal' }); fixture.detectChanges(); - const submitButton = fixture.debugElement.query(By.css("[data-testId=\"submit\"]")); - expect(await submitButton.nativeElement.getAttribute("disabled")) + const submitButton = fixture.debugElement.query(By.css('[data-testId="submit"]')); + expect(await submitButton.nativeElement.getAttribute('disabled')) .toBeFalsy(); const formObject = fixture.componentInstance.keyResultForm.value; expect(formObject.title) - .toBe("Title"); + .toBe('Title'); expect(formObject.description) - .toBe("Description"); + .toBe('Description'); expect(component.keyResultForm.invalid) .toBeFalsy(); })); - it("should display error message of too short input", waitForAsync(async() => { + it('should display error message of too short input', waitForAsync(async() => { component.keyResultForm.setValue({ owner: testUser, actionList: [], - title: "T", + title: 'T', baseline: 0, - stretchZone: "", - targetZone: "", - commitZone: "", - unit: "FTE", - description: "Description", + stretchZone: '', + targetZone: '', + commitZone: '', + unit: 'FTE', + description: 'Description', stretchGoal: 0, - keyResultType: "metric" + keyResultType: 'metric' }); fixture.detectChanges(); expect(component.keyResultForm.invalid) .toBeTruthy(); - expect(component.keyResultForm.get("title")!.errors?.["minlength"]) + expect(component.keyResultForm.get('title')!.errors?.['minlength']) .toBeTruthy(); })); - it("should display error message of required", waitForAsync(async() => { + it('should display error message of required', waitForAsync(async() => { component.keyResultForm.setValue({ owner: testUser, actionList: [], @@ -713,7 +713,7 @@ describe("KeyresultDialogComponent", () => { targetZone: null, commitZone: null, unit: null, - description: "", + description: '', stretchGoal: null, keyResultType: null }); @@ -721,12 +721,12 @@ describe("KeyresultDialogComponent", () => { expect(component.keyResultForm.invalid) .toBeTruthy(); - expect(component.keyResultForm.get("title")!.errors?.["required"]) + expect(component.keyResultForm.get('title')!.errors?.['required']) .toBeTruthy(); })); - it("should call service save method", waitForAsync(() => { - const spy = jest.spyOn(keyResultService, "saveKeyResult"); + it('should call service save method', waitForAsync(() => { + const spy = jest.spyOn(keyResultService, 'saveKeyResult'); spy.mockImplementation(() => of({ id: 2 } as KeyResult)); component.saveKeyResult(); diff --git a/frontend/src/app/components/keyresult-dialog/keyresult-dialog.component.ts b/frontend/src/app/components/keyresult-dialog/keyresult-dialog.component.ts index f649891c26..7ae3e943d0 100644 --- a/frontend/src/app/components/keyresult-dialog/keyresult-dialog.component.ts +++ b/frontend/src/app/components/keyresult-dialog/keyresult-dialog.component.ts @@ -1,27 +1,27 @@ -import { Component, Inject } from "@angular/core"; -import { FormControl, FormGroup, Validators } from "@angular/forms"; -import { User } from "../../shared/types/model/User"; -import { Action } from "../../shared/types/model/Action"; -import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; -import { Objective } from "../../shared/types/model/Objective"; -import { KeyResult } from "../../shared/types/model/KeyResult"; -import { KeyResultMetricDTO } from "../../shared/types/DTOs/KeyResultMetricDTO"; -import { KeyResultOrdinalDTO } from "../../shared/types/DTOs/KeyResultOrdinalDTO"; -import { CloseState } from "../../shared/types/enums/CloseState"; -import { KeyresultService } from "../../services/keyresult.service"; -import { DialogService } from "../../services/dialog.service"; +import { Component, Inject } from '@angular/core'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { User } from '../../shared/types/model/User'; +import { Action } from '../../shared/types/model/Action'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Objective } from '../../shared/types/model/Objective'; +import { KeyResult } from '../../shared/types/model/KeyResult'; +import { KeyResultMetricDTO } from '../../shared/types/DTOs/KeyResultMetricDTO'; +import { KeyResultOrdinalDTO } from '../../shared/types/DTOs/KeyResultOrdinalDTO'; +import { CloseState } from '../../shared/types/enums/CloseState'; +import { KeyresultService } from '../../services/keyresult.service'; +import { DialogService } from '../../services/dialog.service'; @Component({ - selector: "app-keyresult-dialog", - templateUrl: "./keyresult-dialog.component.html", - styleUrls: ["./keyresult-dialog.component.scss"] + selector: 'app-keyresult-dialog', + templateUrl: './keyresult-dialog.component.html', + styleUrls: ['./keyresult-dialog.component.scss'] }) export class KeyresultDialogComponent { keyResultForm = new FormGroup({ - title: new FormControl("", [Validators.required, + title: new FormControl('', [Validators.required, Validators.minLength(2), Validators.maxLength(250)]), - description: new FormControl("", [Validators.maxLength(4096)]), + description: new FormControl('', [Validators.maxLength(4096)]), owner: new FormControl(null, [Validators.required, Validators.nullValidator]), actionList: new FormControl([]), @@ -31,7 +31,7 @@ export class KeyresultDialogComponent { commitZone: new FormControl(null), targetZone: new FormControl(null), stretchZone: new FormControl(null), - keyResultType: new FormControl("metric") + keyResultType: new FormControl('metric') }); constructor( @@ -46,7 +46,7 @@ export class KeyresultDialogComponent { } isMetricKeyResult() { - return this.keyResultForm.controls["keyResultType"].value === "metric"; + return this.keyResultForm.controls['keyResultType'].value === 'metric'; } saveKeyResult(openNewDialog = false) { @@ -63,7 +63,7 @@ export class KeyresultDialogComponent { } as KeyResultOrdinalDTO); keyResult.id = this.data.keyResult?.id; keyResult.version = this.data.keyResult?.version; - keyResult.actionList = (keyResult.actionList ?? []).filter((action: Action) => action.action !== ""); + keyResult.actionList = (keyResult.actionList ?? []).filter((action: Action) => action.action !== ''); this.keyResultService.saveKeyResult(keyResult) .subscribe((returnValue) => { this.dialogRef.close({ @@ -77,7 +77,7 @@ export class KeyresultDialogComponent { deleteKeyResult() { this.dialogService - .openConfirmDialog("CONFIRMATION.DELETE.KEYRESULT") + .openConfirmDialog('CONFIRMATION.DELETE.KEYRESULT') .afterClosed() .subscribe((result) => { if (result) { @@ -98,12 +98,12 @@ export class KeyresultDialogComponent { invalidOwner(): boolean { return ( - !!this.isTouchedOrDirty("owner") && - (typeof this.keyResultForm.value.owner === "string" || !this.keyResultForm.value.owner) + !!this.isTouchedOrDirty('owner') && + (typeof this.keyResultForm.value.owner === 'string' || !this.keyResultForm.value.owner) ); } getDialogTitle(): string { - return this.data.keyResult ? "Key Result bearbeiten" : "Key Result erfassen"; + return this.data.keyResult ? 'Key Result bearbeiten' : 'Key Result erfassen'; } } diff --git a/frontend/src/app/components/keyresult-type/keyresult-type.component.spec.ts b/frontend/src/app/components/keyresult-type/keyresult-type.component.spec.ts index 3bcb6575a2..e42bef5c18 100644 --- a/frontend/src/app/components/keyresult-type/keyresult-type.component.spec.ts +++ b/frontend/src/app/components/keyresult-type/keyresult-type.component.spec.ts @@ -1,15 +1,15 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import * as de from "../../../assets/i18n/de.json"; - -import { KeyresultTypeComponent } from "./keyresult-type.component"; -import { KeyResult } from "../../shared/types/model/KeyResult"; -import { keyResultMetric, keyResultOrdinal, testUser } from "../../shared/testData"; -import { TranslateTestingModule } from "ngx-translate-testing"; -import { By } from "@angular/platform-browser"; -import { FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms"; -import { User } from "../../shared/types/model/User"; - -describe("KeyresultTypeComponent", () => { +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import * as de from '../../../assets/i18n/de.json'; + +import { KeyresultTypeComponent } from './keyresult-type.component'; +import { KeyResult } from '../../shared/types/model/KeyResult'; +import { keyResultMetric, keyResultOrdinal, testUser } from '../../shared/testData'; +import { TranslateTestingModule } from 'ngx-translate-testing'; +import { By } from '@angular/platform-browser'; +import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { User } from '../../shared/types/model/User'; + +describe('KeyresultTypeComponent', () => { let component: KeyresultTypeComponent; let fixture: ComponentFixture; @@ -17,42 +17,42 @@ describe("KeyresultTypeComponent", () => { const ordinalKeyResult: KeyResult = keyResultOrdinal; const metricKeyResultForm = new FormGroup({ - title: new FormControl("100% aller Schweizer Kunden betreuen", [Validators.required, + title: new FormControl('100% aller Schweizer Kunden betreuen', [Validators.required, Validators.minLength(2), Validators.maxLength(250)]), - description: new FormControl("Puzzle ITC erledigt die IT-Aufträge für 100% aller Unternehmen.", [Validators.maxLength(4096)]), + description: new FormControl('Puzzle ITC erledigt die IT-Aufträge für 100% aller Unternehmen.', [Validators.maxLength(4096)]), owner: new FormControl(testUser, [Validators.required, Validators.nullValidator]), - unit: new FormControl("PERCENT"), + unit: new FormControl('PERCENT'), baseline: new FormControl(30), stretchGoal: new FormControl(100), commitZone: new FormControl(null), targetZone: new FormControl(null), stretchZone: new FormControl(null), - keyResultType: new FormControl("metric") + keyResultType: new FormControl('metric') }); const ordinalKeyResultForm = new FormGroup({ - title: new FormControl("100% aller Schweizer Kunden betreuen", [Validators.required, + title: new FormControl('100% aller Schweizer Kunden betreuen', [Validators.required, Validators.minLength(2), Validators.maxLength(250)]), - description: new FormControl("Puzzle ITC erledigt die IT-Aufträge für 100% aller Unternehmen.", [Validators.maxLength(4096)]), + description: new FormControl('Puzzle ITC erledigt die IT-Aufträge für 100% aller Unternehmen.', [Validators.maxLength(4096)]), owner: new FormControl(testUser, [Validators.required, Validators.nullValidator]), unit: new FormControl(null), baseline: new FormControl(null), stretchGoal: new FormControl(null), - commitZone: new FormControl("Commit"), - targetZone: new FormControl("Target"), - stretchZone: new FormControl("Stretch"), - keyResultType: new FormControl("metric") + commitZone: new FormControl('Commit'), + targetZone: new FormControl('Target'), + stretchZone: new FormControl('Stretch'), + keyResultType: new FormControl('metric') }); const emptyKeyResultForm = new FormGroup({ - title: new FormControl("100% aller Schweizer Kunden betreuen", [Validators.required, + title: new FormControl('100% aller Schweizer Kunden betreuen', [Validators.required, Validators.minLength(2), Validators.maxLength(250)]), - description: new FormControl("Puzzle ITC erledigt die IT-Aufträge für 100% aller Unternehmen.", [Validators.maxLength(4096)]), + description: new FormControl('Puzzle ITC erledigt die IT-Aufträge für 100% aller Unternehmen.', [Validators.maxLength(4096)]), owner: new FormControl(testUser, [Validators.required, Validators.nullValidator]), unit: new FormControl(null), @@ -61,10 +61,10 @@ describe("KeyresultTypeComponent", () => { commitZone: new FormControl(null), targetZone: new FormControl(null), stretchZone: new FormControl(null), - keyResultType: new FormControl("metric") + keyResultType: new FormControl('metric') }); - describe("Edit Metric", () => { + describe('Edit Metric', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [KeyresultTypeComponent], @@ -81,18 +81,18 @@ describe("KeyresultTypeComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should use values from input", () => { + it('should use values from input', () => { expect(component.typeChangeAllowed) .toBeTruthy(); expect(component.isMetric) .toBeTruthy(); expect(component.keyResultForm.value.unit) - .toEqual("PERCENT"); + .toEqual('PERCENT'); expect(component.keyResultForm.value.baseline) .toEqual(30); expect(component.keyResultForm.value.stretchGoal) @@ -105,44 +105,44 @@ describe("KeyresultTypeComponent", () => { .toBeNull(); }); - it("should switch type of KeyResult", () => { + it('should switch type of KeyResult', () => { component.isMetric = true; component.typeChangeAllowed = true; - component.switchKeyResultType("metric"); + component.switchKeyResultType('metric'); expect(component.isMetric) .toBeTruthy(); - component.switchKeyResultType("ordinal"); + component.switchKeyResultType('ordinal'); expect(component.isMetric) .toBeFalsy(); component.typeChangeAllowed = false; - component.switchKeyResultType("metric"); + component.switchKeyResultType('metric'); expect(component.isMetric) .toBeFalsy(); }); - it("should select metric tab", () => { + it('should select metric tab', () => { component.isMetric = true; - const activeTab = document.getElementsByClassName("active")[0]; + const activeTab = document.getElementsByClassName('active')[0]; expect(activeTab.innerHTML) - .toContain("Metrisch"); + .toContain('Metrisch'); }); - it("should change to ordinal from html click", () => { + it('should change to ordinal from html click', () => { component.typeChangeAllowed = true; expect(component.isMetric) .toBeTruthy(); - const ordinalTab = fixture.debugElement.query(By.css("[data-testId=\"ordinalTab\"]")); + const ordinalTab = fixture.debugElement.query(By.css('[data-testId="ordinalTab"]')); ordinalTab.nativeElement.click(); expect(component.isMetric) .toBeFalsy(); }); }); - describe("Edit Ordinal", () => { + describe('Edit Ordinal', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [KeyresultTypeComponent], @@ -159,12 +159,12 @@ describe("KeyresultTypeComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should use values from input", () => { + it('should use values from input', () => { expect(component.typeChangeAllowed) .toBeTruthy(); expect(component.keyResultForm.value.unit) @@ -174,53 +174,53 @@ describe("KeyresultTypeComponent", () => { expect(component.keyResultForm.value.stretchGoal) .toBeNull(); expect(component.keyResultForm.value.commitZone) - .toEqual("Commit"); + .toEqual('Commit'); expect(component.keyResultForm.value.targetZone) - .toEqual("Target"); + .toEqual('Target'); expect(component.keyResultForm.value.stretchZone) - .toEqual("Stretch"); + .toEqual('Stretch'); }); - it("should switch type of KeyResult", () => { + it('should switch type of KeyResult', () => { component.isMetric = true; component.typeChangeAllowed = true; - component.switchKeyResultType("metric"); + component.switchKeyResultType('metric'); expect(component.isMetric) .toBeTruthy(); - component.switchKeyResultType("ordinal"); + component.switchKeyResultType('ordinal'); expect(component.isMetric) .toBeFalsy(); component.typeChangeAllowed = false; - component.switchKeyResultType("metric"); + component.switchKeyResultType('metric'); expect(component.isMetric) .toBeFalsy(); }); - it("should select ordinal tab", () => { + it('should select ordinal tab', () => { component.isMetric = false; fixture.detectChanges(); - const activeTab = document.getElementsByClassName("active")[0]; + const activeTab = document.getElementsByClassName('active')[0]; expect(activeTab.innerHTML) - .toContain("Ordinal"); + .toContain('Ordinal'); }); - it("should change to metric from html click", () => { + it('should change to metric from html click', () => { component.typeChangeAllowed = true; component.isMetric = false; expect(component.isMetric) .toBeFalsy(); - const metricTab = fixture.debugElement.query(By.css("[data-testId=\"metricTab\"]")); + const metricTab = fixture.debugElement.query(By.css('[data-testId="metricTab"]')); metricTab.nativeElement.click(); expect(component.isMetric) .toBeTruthy(); }); }); - describe("Create", () => { + describe('Create', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [KeyresultTypeComponent], @@ -237,12 +237,12 @@ describe("KeyresultTypeComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should use default values", () => { + it('should use default values', () => { expect(component.keyResultForm.value.unit) .toBeNull(); expect(component.keyResultForm.value.baseline) @@ -257,37 +257,37 @@ describe("KeyresultTypeComponent", () => { .toBeNull(); }); - it("should switch type of KeyResult", () => { + it('should switch type of KeyResult', () => { component.isMetric = true; component.typeChangeAllowed = true; - component.switchKeyResultType("metric"); + component.switchKeyResultType('metric'); expect(component.isMetric) .toBeTruthy(); - component.switchKeyResultType("ordinal"); + component.switchKeyResultType('ordinal'); expect(component.isMetric) .toBeFalsy(); component.typeChangeAllowed = false; - component.switchKeyResultType("metric"); + component.switchKeyResultType('metric'); expect(component.isMetric) .toBeFalsy(); }); - it("should select metric tab", () => { + it('should select metric tab', () => { component.isMetric = true; - const activeTab = document.getElementsByClassName("active")[0]; + const activeTab = document.getElementsByClassName('active')[0]; expect(activeTab.innerHTML) - .toContain("Metrisch"); + .toContain('Metrisch'); }); - it("should change to ordinal from html click", () => { + it('should change to ordinal from html click', () => { component.typeChangeAllowed = true; expect(component.isMetric) .toBeTruthy(); - const ordinalTab = fixture.debugElement.query(By.css("[data-testId=\"ordinalTab\"]")); + const ordinalTab = fixture.debugElement.query(By.css('[data-testId="ordinalTab"]')); ordinalTab.nativeElement.click(); expect(component.isMetric) .toBeFalsy(); diff --git a/frontend/src/app/components/keyresult-type/keyresult-type.component.ts b/frontend/src/app/components/keyresult-type/keyresult-type.component.ts index e8725cee19..8ce304db71 100644 --- a/frontend/src/app/components/keyresult-type/keyresult-type.component.ts +++ b/frontend/src/app/components/keyresult-type/keyresult-type.component.ts @@ -1,16 +1,16 @@ -import { Component, Input, OnInit } from "@angular/core"; -import { KeyResult } from "../../shared/types/model/KeyResult"; -import { FormGroup, Validators } from "@angular/forms"; -import { KeyResultMetric } from "../../shared/types/model/KeyResultMetric"; -import { KeyResultOrdinal } from "../../shared/types/model/KeyResultOrdinal"; -import { Unit } from "../../shared/types/enums/Unit"; -import { formInputCheck, hasFormFieldErrors } from "../../shared/common"; -import { TranslateService } from "@ngx-translate/core"; +import { Component, Input, OnInit } from '@angular/core'; +import { KeyResult } from '../../shared/types/model/KeyResult'; +import { FormGroup, Validators } from '@angular/forms'; +import { KeyResultMetric } from '../../shared/types/model/KeyResultMetric'; +import { KeyResultOrdinal } from '../../shared/types/model/KeyResultOrdinal'; +import { Unit } from '../../shared/types/enums/Unit'; +import { formInputCheck, hasFormFieldErrors } from '../../shared/common'; +import { TranslateService } from '@ngx-translate/core'; @Component({ - selector: "app-keyresult-type", - templateUrl: "./keyresult-type.component.html", - styleUrls: ["./keyresult-type.component.scss"] + selector: 'app-keyresult-type', + templateUrl: './keyresult-type.component.html', + styleUrls: ['./keyresult-type.component.scss'] }) export class KeyresultTypeComponent implements OnInit { @Input() keyResultForm!: FormGroup; @@ -34,7 +34,7 @@ export class KeyresultTypeComponent implements OnInit { ngOnInit(): void { if (this.keyresult) { this.typeChangeAllowed = (this.keyresult as KeyResultMetric | KeyResultOrdinal).lastCheckIn?.id == null; - this.isMetric = this.keyresult.keyResultType == "metric"; + this.isMetric = this.keyresult.keyResultType == 'metric'; this.isMetric ? this.keyResultForm.patchValue({ ...this.castToMetric(this.keyresult) }) : this.keyResultForm.patchValue({ ...this.castToOrdinal(this.keyresult) }); @@ -68,39 +68,39 @@ export class KeyresultTypeComponent implements OnInit { } setValidatorsMetric() { - this.keyResultForm.controls["unit"].setValidators([Validators.required]); - this.keyResultForm.controls["baseline"].setValidators([Validators.required, - Validators.pattern("^-?\\d+\\.?\\d*$")]); - this.keyResultForm.controls["stretchGoal"].setValidators([Validators.required, - Validators.pattern("^-?\\d+\\.?\\d*$")]); + this.keyResultForm.controls['unit'].setValidators([Validators.required]); + this.keyResultForm.controls['baseline'].setValidators([Validators.required, + Validators.pattern('^-?\\d+\\.?\\d*$')]); + this.keyResultForm.controls['stretchGoal'].setValidators([Validators.required, + Validators.pattern('^-?\\d+\\.?\\d*$')]); } setValidatorsOrdinal() { - this.keyResultForm.controls["commitZone"].setValidators([Validators.required, + this.keyResultForm.controls['commitZone'].setValidators([Validators.required, Validators.maxLength(400)]); - this.keyResultForm.controls["targetZone"].setValidators([Validators.required, + this.keyResultForm.controls['targetZone'].setValidators([Validators.required, Validators.maxLength(400)]); - this.keyResultForm.controls["stretchZone"].setValidators([Validators.required, + this.keyResultForm.controls['stretchZone'].setValidators([Validators.required, Validators.maxLength(400)]); } clearValidatorsMetric() { - this.keyResultForm.controls["unit"].clearValidators(); - this.keyResultForm.controls["baseline"].clearValidators(); - this.keyResultForm.controls["stretchGoal"].clearValidators(); + this.keyResultForm.controls['unit'].clearValidators(); + this.keyResultForm.controls['baseline'].clearValidators(); + this.keyResultForm.controls['stretchGoal'].clearValidators(); } clearValidatorsOrdinal() { - this.keyResultForm.controls["commitZone"].clearValidators(); - this.keyResultForm.controls["targetZone"].clearValidators(); - this.keyResultForm.controls["stretchZone"].clearValidators(); + this.keyResultForm.controls['commitZone'].clearValidators(); + this.keyResultForm.controls['targetZone'].clearValidators(); + this.keyResultForm.controls['stretchZone'].clearValidators(); } switchKeyResultType(type: string) { - if ((type == "metric" && !this.isMetric || type == "ordinal" && this.isMetric) && this.typeChangeAllowed) { + if ((type == 'metric' && !this.isMetric || type == 'ordinal' && this.isMetric) && this.typeChangeAllowed) { this.isMetric = !this.isMetric; - const keyResultType = this.isMetric ? "metric" : "ordinal"; - this.keyResultForm.controls["keyResultType"].setValue(keyResultType); + const keyResultType = this.isMetric ? 'metric' : 'ordinal'; + this.keyResultForm.controls['keyResultType'].setValue(keyResultType); this.switchValidators(); } } @@ -108,7 +108,7 @@ export class KeyresultTypeComponent implements OnInit { getErrorMessage( error: string, field: string, firstNumber: number | null, secondNumber: number | null ): string { - return field + this.translate.instant("DIALOG_ERRORS." + error) + return field + this.translate.instant('DIALOG_ERRORS.' + error) .format(firstNumber, secondNumber); } } diff --git a/frontend/src/app/components/keyresult/keyresult.component.spec.ts b/frontend/src/app/components/keyresult/keyresult.component.spec.ts index 779e9d514e..88fc5f84dc 100644 --- a/frontend/src/app/components/keyresult/keyresult.component.spec.ts +++ b/frontend/src/app/components/keyresult/keyresult.component.spec.ts @@ -1,12 +1,12 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { KeyresultComponent } from "./keyresult.component"; -import { keyResultMetricMin } from "../../shared/testData"; -import { MatDialogModule } from "@angular/material/dialog"; -import { ScoringComponent } from "../../shared/custom/scoring/scoring.component"; -import { ConfidenceComponent } from "../confidence/confidence.component"; -import { provideHttpClient, withInterceptorsFromDi } from "@angular/common/http"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { KeyresultComponent } from './keyresult.component'; +import { keyResultMetricMin } from '../../shared/testData'; +import { MatDialogModule } from '@angular/material/dialog'; +import { ScoringComponent } from '../../shared/custom/scoring/scoring.component'; +import { ConfidenceComponent } from '../confidence/confidence.component'; +import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -describe("KeyresultComponent", () => { +describe('KeyresultComponent', () => { let component: KeyresultComponent; let fixture: ComponentFixture; @@ -26,7 +26,7 @@ describe("KeyresultComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); diff --git a/frontend/src/app/components/keyresult/keyresult.component.ts b/frontend/src/app/components/keyresult/keyresult.component.ts index ac02ce252d..791fc5eaf8 100644 --- a/frontend/src/app/components/keyresult/keyresult.component.ts +++ b/frontend/src/app/components/keyresult/keyresult.component.ts @@ -1,14 +1,14 @@ -import { ChangeDetectionStrategy, Component, Input } from "@angular/core"; -import { KeyresultMin } from "../../shared/types/model/KeyresultMin"; -import { Router } from "@angular/router"; -import { DATE_FORMAT } from "../../shared/constantLibary"; -import { KeyResultMetricMin } from "../../shared/types/model/KeyResultMetricMin"; -import { KeyResultOrdinalMin } from "../../shared/types/model/KeyResultOrdinalMin"; +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { KeyresultMin } from '../../shared/types/model/KeyresultMin'; +import { Router } from '@angular/router'; +import { DATE_FORMAT } from '../../shared/constantLibary'; +import { KeyResultMetricMin } from '../../shared/types/model/KeyResultMetricMin'; +import { KeyResultOrdinalMin } from '../../shared/types/model/KeyResultOrdinalMin'; @Component({ - selector: "app-keyresult", - templateUrl: "./keyresult.component.html", - styleUrls: ["./keyresult.component.scss"], + selector: 'app-keyresult', + templateUrl: './keyresult.component.html', + styleUrls: ['./keyresult.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class KeyresultComponent { @@ -19,12 +19,12 @@ export class KeyresultComponent { constructor(private router: Router) {} openDrawer() { - this.router.navigate(["details/keyresult", + this.router.navigate(['details/keyresult', this.keyResult.id]); } getKeyResultWithCorrectType(): KeyResultOrdinalMin | KeyResultMetricMin { - if (this.keyResult.keyResultType === "metric") { + if (this.keyResult.keyResultType === 'metric') { return this.keyResult as KeyResultMetricMin; } else { return this.keyResult as KeyResultOrdinalMin; diff --git a/frontend/src/app/components/objective-detail/objective-detail.component.spec.ts b/frontend/src/app/components/objective-detail/objective-detail.component.spec.ts index caf11bf00d..6a00efe244 100644 --- a/frontend/src/app/components/objective-detail/objective-detail.component.spec.ts +++ b/frontend/src/app/components/objective-detail/objective-detail.component.spec.ts @@ -1,15 +1,15 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ObjectiveDetailComponent } from "./objective-detail.component"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { By } from "@angular/platform-browser"; -import { ObjectiveService } from "../../services/objective.service"; -import { objective, objectiveWriteableFalse } from "../../shared/testData"; -import { of } from "rxjs"; -import { MatDialogModule } from "@angular/material/dialog"; -import { ActivatedRoute } from "@angular/router"; -import { MatIconModule } from "@angular/material/icon"; -import { TranslateModule } from "@ngx-translate/core"; +import { ObjectiveDetailComponent } from './objective-detail.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { By } from '@angular/platform-browser'; +import { ObjectiveService } from '../../services/objective.service'; +import { objective, objectiveWriteableFalse } from '../../shared/testData'; +import { of } from 'rxjs'; +import { MatDialogModule } from '@angular/material/dialog'; +import { ActivatedRoute } from '@angular/router'; +import { MatIconModule } from '@angular/material/icon'; +import { TranslateModule } from '@ngx-translate/core'; const objectiveService = { getFullObjective: jest.fn() @@ -23,7 +23,7 @@ const activatedRouteMock = { } }; -describe("ObjectiveDetailComponent", () => { +describe('ObjectiveDetailComponent', () => { let component: ObjectiveDetailComponent; let fixture: ComponentFixture; @@ -50,39 +50,39 @@ describe("ObjectiveDetailComponent", () => { activatedRouteMock.snapshot.paramMap.get.mockReturnValue(of(1)); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should throw an exception, if id is undefined", () => { + it('should throw an exception, if id is undefined', () => { activatedRouteMock.snapshot.paramMap.get = () => undefined; expect(() => component.ngOnInit()) - .toThrowError("objective id is undefined"); + .toThrowError('objective id is undefined'); }); - it("get data from backend", () => { + it('get data from backend', () => { fixture.detectChanges(); component.objectiveId = 2; - const title = fixture.debugElement.query(By.css("[data-testId=\"objective-title\"]"))?.nativeElement.innerHTML; - const description = fixture.debugElement.query(By.css("[data-testId=\"description\"]"))?.nativeElement.innerHTML; + const title = fixture.debugElement.query(By.css('[data-testId="objective-title"]'))?.nativeElement.innerHTML; + const description = fixture.debugElement.query(By.css('[data-testId="description"]'))?.nativeElement.innerHTML; expect(title) .toContain(objective.title); expect(description) .toContain(objective.description); }); - it("should display add keyresult button if writeable is true", async() => { + it('should display add keyresult button if writeable is true', async() => { fixture.detectChanges(); - const button = fixture.debugElement.query(By.css("[data-testId=\"add-keyResult-objective-detail\"]")); + const button = fixture.debugElement.query(By.css('[data-testId="add-keyResult-objective-detail"]')); expect(button) .toBeTruthy(); }); - it("should not display add keyresult button if writeable is false", async() => { + it('should not display add keyresult button if writeable is false', async() => { objectiveService.getFullObjective.mockReturnValue(of(objectiveWriteableFalse)); fixture.detectChanges(); - const button = fixture.debugElement.query(By.css("[data-testId=\"add-keyResult-objective-detail\"]")); + const button = fixture.debugElement.query(By.css('[data-testId="add-keyResult-objective-detail"]')); expect(button) .toBeFalsy(); }); diff --git a/frontend/src/app/components/objective-detail/objective-detail.component.ts b/frontend/src/app/components/objective-detail/objective-detail.component.ts index f8e71d78a7..d9c32f9249 100644 --- a/frontend/src/app/components/objective-detail/objective-detail.component.ts +++ b/frontend/src/app/components/objective-detail/objective-detail.component.ts @@ -1,17 +1,17 @@ -import { ChangeDetectionStrategy, Component, OnInit } from "@angular/core"; -import { Objective } from "../../shared/types/model/Objective"; -import { ObjectiveService } from "../../services/objective.service"; -import { BehaviorSubject, catchError, EMPTY } from "rxjs"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { KeyresultDialogComponent } from "../keyresult-dialog/keyresult-dialog.component"; -import { ObjectiveFormComponent } from "../../shared/dialog/objective-dialog/objective-form.component"; -import { ActivatedRoute, Router } from "@angular/router"; -import { DialogService } from "../../services/dialog.service"; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { Objective } from '../../shared/types/model/Objective'; +import { ObjectiveService } from '../../services/objective.service'; +import { BehaviorSubject, catchError, EMPTY } from 'rxjs'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { KeyresultDialogComponent } from '../keyresult-dialog/keyresult-dialog.component'; +import { ObjectiveFormComponent } from '../../shared/dialog/objective-dialog/objective-form.component'; +import { ActivatedRoute, Router } from '@angular/router'; +import { DialogService } from '../../services/dialog.service'; @Component({ - selector: "app-objective-detail", - templateUrl: "./objective-detail.component.html", - styleUrl: "objective-detail.component.scss", + selector: 'app-objective-detail', + templateUrl: './objective-detail.component.html', + styleUrl: 'objective-detail.component.scss', changeDetection: ChangeDetectionStrategy.OnPush }) export class ObjectiveDetailComponent implements OnInit { @@ -33,9 +33,9 @@ export class ObjectiveDetailComponent implements OnInit { } private getIdFromParams(): number { - const id = this.route.snapshot.paramMap.get("id"); + const id = this.route.snapshot.paramMap.get('id'); if (!id) { - throw Error("objective id is undefined"); + throw Error('objective id is undefined'); } return parseInt(id); } @@ -86,6 +86,6 @@ export class ObjectiveDetailComponent implements OnInit { } backToOverview() { - this.router.navigate([""]); + this.router.navigate(['']); } } diff --git a/frontend/src/app/components/objective-filter/objective-filter.component.spec.ts b/frontend/src/app/components/objective-filter/objective-filter.component.spec.ts index b69533a10c..68601268d8 100644 --- a/frontend/src/app/components/objective-filter/objective-filter.component.spec.ts +++ b/frontend/src/app/components/objective-filter/objective-filter.component.spec.ts @@ -1,23 +1,23 @@ -import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; -import { ObjectiveFilterComponent } from "./objective-filter.component"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { AppRoutingModule } from "../../app-routing.module"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { MatIconModule } from "@angular/material/icon"; -import { FormsModule } from "@angular/forms"; -import { MatInputModule } from "@angular/material/input"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { HarnessLoader } from "@angular/cdk/testing"; -import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed"; -import { MatInputHarness } from "@angular/material/input/testing"; -import { Router } from "@angular/router"; -import { RouterTestingHarness } from "@angular/router/testing"; -import { authGuard } from "../../guards/auth.guard"; -import { OverviewComponent } from "../overview/overview.component"; -import { OAuthService } from "angular-oauth2-oidc"; +import { ObjectiveFilterComponent } from './objective-filter.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { AppRoutingModule } from '../../app-routing.module'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { FormsModule } from '@angular/forms'; +import { MatInputModule } from '@angular/material/input'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { MatInputHarness } from '@angular/material/input/testing'; +import { Router } from '@angular/router'; +import { RouterTestingHarness } from '@angular/router/testing'; +import { authGuard } from '../../guards/auth.guard'; +import { OverviewComponent } from '../overview/overview.component'; +import { OAuthService } from 'angular-oauth2-oidc'; -describe("ObjectiveFilterComponent", () => { +describe('ObjectiveFilterComponent', () => { let component: ObjectiveFilterComponent; let fixture: ComponentFixture; let loader: HarnessLoader; @@ -61,17 +61,17 @@ describe("ObjectiveFilterComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should route correctly", fakeAsync(() => { + it('should route correctly', fakeAsync(() => { loader.getHarness(MatInputHarness) .then((search) => { - jest.spyOn(router, "navigate"); - jest.spyOn(component, "updateURL"); - search.setValue("this is a test"); + jest.spyOn(router, 'navigate'); + jest.spyOn(component, 'updateURL'); + search.setValue('this is a test'); fixture.detectChanges(); component.refresh.next(); tick(200); @@ -79,13 +79,13 @@ describe("ObjectiveFilterComponent", () => { .toHaveBeenCalledTimes(0); tick(200); expect(router.navigate) - .toHaveBeenCalledWith([], { queryParams: { objectiveQuery: "this is a test" } }); + .toHaveBeenCalledWith([], { queryParams: { objectiveQuery: 'this is a test' } }); expect(router.url) - .toBe("/?objectiveQuery=this%20is%20a%20test"); + .toBe('/?objectiveQuery=this%20is%20a%20test'); }); })); - it("should read from query correctly", fakeAsync(() => { + it('should read from query correctly', fakeAsync(() => { const searchPromise = loader.getHarness(MatInputHarness); const routerPromise = RouterTestingHarness.create(); @@ -93,11 +93,11 @@ describe("ObjectiveFilterComponent", () => { routerPromise]) .then(([search, router]: [MatInputHarness, RouterTestingHarness]) => { - router.navigateByUrl("/?objectiveQuery=this%20is%20a%20test"); + router.navigateByUrl('/?objectiveQuery=this%20is%20a%20test'); tick(500); fixture.detectChanges(); expect(component.query) - .toBe("this is a test"); + .toBe('this is a test'); }); })); }); diff --git a/frontend/src/app/components/objective-filter/objective-filter.component.ts b/frontend/src/app/components/objective-filter/objective-filter.component.ts index 769989c306..ab4c587236 100644 --- a/frontend/src/app/components/objective-filter/objective-filter.component.ts +++ b/frontend/src/app/components/objective-filter/objective-filter.component.ts @@ -1,18 +1,18 @@ -import { ChangeDetectionStrategy, Component, OnInit } from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; -import { getQueryString, optionalReplaceWithNulls, sanitize } from "../../shared/common"; -import { debounceTime, map, Subject } from "rxjs"; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { getQueryString, optionalReplaceWithNulls, sanitize } from '../../shared/common'; +import { debounceTime, map, Subject } from 'rxjs'; @Component({ - selector: "app-objective-filter", - templateUrl: "./objective-filter.component.html", - styleUrls: ["./objective-filter.component.scss"], + selector: 'app-objective-filter', + templateUrl: './objective-filter.component.html', + styleUrls: ['./objective-filter.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class ObjectiveFilterComponent implements OnInit { refresh = new Subject(); - query = ""; + query = ''; constructor(private router: Router, private route: ActivatedRoute) { @@ -28,7 +28,7 @@ export class ObjectiveFilterComponent implements OnInit { } ngOnInit() { - this.route.queryParams.pipe(map((p) => p["objectiveQuery"])) + this.route.queryParams.pipe(map((p) => p['objectiveQuery'])) .subscribe((query) => { const objectiveQuery = getQueryString(query); if (sanitize(this.query) !== objectiveQuery) { diff --git a/frontend/src/app/components/objective/ObjectiveMenuActions.ts b/frontend/src/app/components/objective/ObjectiveMenuActions.ts index 44e80cbd3b..c270765aef 100644 --- a/frontend/src/app/components/objective/ObjectiveMenuActions.ts +++ b/frontend/src/app/components/objective/ObjectiveMenuActions.ts @@ -1,14 +1,14 @@ -import { DialogService } from "../../services/dialog.service"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { ObjectiveMin } from "../../shared/types/model/ObjectiveMin"; -import { ObjectiveFormComponent } from "../../shared/dialog/objective-dialog/objective-form.component"; -import { CompleteDialogComponent } from "../../shared/dialog/complete-dialog/complete-dialog.component"; +import { DialogService } from '../../services/dialog.service'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { ObjectiveMin } from '../../shared/types/model/ObjectiveMin'; +import { ObjectiveFormComponent } from '../../shared/dialog/objective-dialog/objective-form.component'; +import { CompleteDialogComponent } from '../../shared/dialog/complete-dialog/complete-dialog.component'; import { ObjectiveMenuAction, ObjectiveMenuAfterAction, ObjectiveMenuEntry -} from "../../services/objective-menu-actions.service"; -import { ObjectiveMenuAfterActions } from "./ObjectiveMenuAfterActions"; +} from '../../services/objective-menu-actions.service'; +import { ObjectiveMenuAfterActions } from './ObjectiveMenuAfterActions'; export class ObjectiveMenuActions { constructor(private readonly dialogService: DialogService, @@ -16,19 +16,19 @@ export class ObjectiveMenuActions { private readonly afterActions: ObjectiveMenuAfterActions) {} releaseFromQuarterAction(): ObjectiveMenuEntry { - const action: ObjectiveMenuAction = () => this.dialogService.openConfirmDialog("CONFIRMATION.RELEASE"); + const action: ObjectiveMenuAction = () => this.dialogService.openConfirmDialog('CONFIRMATION.RELEASE'); const afterAction: ObjectiveMenuAfterAction = (objective: ObjectiveMin) => this.afterActions.releaseFromQuarter(objective); - return { displayName: "Objective veröffentlichen", + return { displayName: 'Objective veröffentlichen', action: action, afterAction: afterAction }; } releaseFromBacklogAction(objective: ObjectiveMin): ObjectiveMenuEntry { const config = { data: { objective: { objectiveId: objective.id }, - action: "releaseBacklog" } }; + action: 'releaseBacklog' } }; const action: ObjectiveMenuAction = () => this.dialogService.open(ObjectiveFormComponent, config); const afterAction: ObjectiveMenuAfterAction = () => this.refreshDataService.markDataRefresh(); - return { displayName: "Objective veröffentlichen", + return { displayName: 'Objective veröffentlichen', action: action, afterAction }; } @@ -39,17 +39,17 @@ export class ObjectiveMenuActions { const afterAction: ObjectiveMenuAfterAction = () => { this.refreshDataService.markDataRefresh(); }; - return { displayName: "Objective bearbeiten", + return { displayName: 'Objective bearbeiten', action: action, afterAction: afterAction }; } duplicateObjectiveAction(objective: ObjectiveMin): ObjectiveMenuEntry { const config = { data: { objective: { objectiveId: objective.id }, - action: "duplicate" } }; + action: 'duplicate' } }; const action: ObjectiveMenuAction = () => this.dialogService.open(ObjectiveFormComponent, config); const afterAction: ObjectiveMenuAfterAction = () => this.refreshDataService.markDataRefresh(); - return { displayName: "Objective duplizieren", + return { displayName: 'Objective duplizieren', action: action, afterAction: afterAction }; } @@ -61,25 +61,25 @@ export class ObjectiveMenuActions { const action: ObjectiveMenuAction = () => this.dialogService.open(CompleteDialogComponent, config); const afterAction: ObjectiveMenuAfterAction = (obj: ObjectiveMin, result: any) => this.afterActions.completeObjective(obj, result); - return { displayName: "Objective abschliessen", + return { displayName: 'Objective abschliessen', action: action, afterAction: afterAction }; } objectiveBackToDraft(): ObjectiveMenuEntry { - const action: ObjectiveMenuAction = () => this.dialogService.openConfirmDialog("CONFIRMATION.TO_DRAFT"); + const action: ObjectiveMenuAction = () => this.dialogService.openConfirmDialog('CONFIRMATION.TO_DRAFT'); const afterAction: ObjectiveMenuAfterAction = (obj: ObjectiveMin) => this.afterActions.objectiveBackToDraft(obj); - return { displayName: "Objective als Draft speichern", + return { displayName: 'Objective als Draft speichern', action: action, afterAction: afterAction }; } objectiveReopen(): ObjectiveMenuEntry { - const action: ObjectiveMenuAction = () => this.dialogService.openConfirmDialog("CONFIRMATION.REOPEN"); + const action: ObjectiveMenuAction = () => this.dialogService.openConfirmDialog('CONFIRMATION.REOPEN'); const afterAction: ObjectiveMenuAfterAction = (obj: ObjectiveMin) => this.afterActions.objectiveReopen(obj); - return { displayName: "Objective wiedereröffnen", + return { displayName: 'Objective wiedereröffnen', action: action, afterAction: afterAction }; } diff --git a/frontend/src/app/components/objective/ObjectiveMenuAfterActions.ts b/frontend/src/app/components/objective/ObjectiveMenuAfterActions.ts index 1eed2796ae..dc525282a0 100644 --- a/frontend/src/app/components/objective/ObjectiveMenuAfterActions.ts +++ b/frontend/src/app/components/objective/ObjectiveMenuAfterActions.ts @@ -1,10 +1,10 @@ -import { Objective } from "../../shared/types/model/Objective"; -import { State } from "../../shared/types/enums/State"; -import { Completed } from "../../shared/types/model/Completed"; -import { ObjectiveService } from "../../services/objective.service"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { ObjectiveMin } from "../../shared/types/model/ObjectiveMin"; -import { CompletedService } from "../../services/completed.servce"; +import { Objective } from '../../shared/types/model/Objective'; +import { State } from '../../shared/types/enums/State'; +import { Completed } from '../../shared/types/model/Completed'; +import { ObjectiveService } from '../../services/objective.service'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { ObjectiveMin } from '../../shared/types/model/ObjectiveMin'; +import { CompletedService } from '../../services/completed.servce'; export class ObjectiveMenuAfterActions { constructor(private readonly objectiveService: ObjectiveService, @@ -36,7 +36,7 @@ export class ObjectiveMenuAfterActions { releaseFromQuarter(objectiveMin: ObjectiveMin) { this.objectiveService.getFullObjective(objectiveMin.id) .subscribe((objective: Objective) => { - objective.state = "ONGOING" as State; + objective.state = 'ONGOING' as State; this.objectiveService.updateObjective(objective) .subscribe(() => { this.refreshDataService.markDataRefresh(); @@ -47,7 +47,7 @@ export class ObjectiveMenuAfterActions { objectiveBackToDraft(objectiveMin: ObjectiveMin) { this.objectiveService.getFullObjective(objectiveMin.id) .subscribe((objective: Objective) => { - objective.state = "DRAFT" as State; + objective.state = 'DRAFT' as State; this.objectiveService.updateObjective(objective) .subscribe(() => { this.refreshDataService.markDataRefresh(); @@ -58,7 +58,7 @@ export class ObjectiveMenuAfterActions { objectiveReopen(objectiveMin: ObjectiveMin) { this.objectiveService.getFullObjective(objectiveMin.id) .subscribe((objective: Objective) => { - objective.state = "ONGOING" as State; + objective.state = 'ONGOING' as State; this.objectiveService.updateObjective(objective) .subscribe(() => { this.completedService.deleteCompleted(objective.id) diff --git a/frontend/src/app/components/objective/objective.component.spec.ts b/frontend/src/app/components/objective/objective.component.spec.ts index 77c10dc99a..5c4106124f 100644 --- a/frontend/src/app/components/objective/objective.component.spec.ts +++ b/frontend/src/app/components/objective/objective.component.spec.ts @@ -1,28 +1,28 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { ObjectiveComponent } from "./objective.component"; -import { MatMenuModule } from "@angular/material/menu"; -import { MatCardModule } from "@angular/material/card"; -import { HarnessLoader } from "@angular/cdk/testing"; -import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { By } from "@angular/platform-browser"; -import { State } from "../../shared/types/enums/State"; -import { OverviewService } from "../../services/overview.service"; -import { objectiveMin } from "../../shared/testData"; -import { MatMenuHarness } from "@angular/material/menu/testing"; -import { KeyresultComponent } from "../keyresult/keyresult.component"; -import { MatDialogModule } from "@angular/material/dialog"; -import { MatIconModule } from "@angular/material/icon"; -import { MatTooltipModule } from "@angular/material/tooltip"; -import { ScoringComponent } from "../../shared/custom/scoring/scoring.component"; -import { ConfidenceComponent } from "../confidence/confidence.component"; -import { ReactiveFormsModule } from "@angular/forms"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ObjectiveComponent } from './objective.component'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatCardModule } from '@angular/material/card'; +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { By } from '@angular/platform-browser'; +import { State } from '../../shared/types/enums/State'; +import { OverviewService } from '../../services/overview.service'; +import { objectiveMin } from '../../shared/testData'; +import { MatMenuHarness } from '@angular/material/menu/testing'; +import { KeyresultComponent } from '../keyresult/keyresult.component'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatIconModule } from '@angular/material/icon'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { ScoringComponent } from '../../shared/custom/scoring/scoring.component'; +import { ConfidenceComponent } from '../confidence/confidence.component'; +import { ReactiveFormsModule } from '@angular/forms'; // @ts-ignore -import * as de from "../../../assets/i18n/de.json"; -import { TranslateTestingModule } from "ngx-translate-testing"; -import { ObjectiveService } from "../../services/objective.service"; -import { CompletedService } from "../../services/completed.servce"; -import { provideHttpClient, withInterceptorsFromDi } from "@angular/common/http"; +import * as de from '../../../assets/i18n/de.json'; +import { TranslateTestingModule } from 'ngx-translate-testing'; +import { ObjectiveService } from '../../services/objective.service'; +import { CompletedService } from '../../services/completed.servce'; +import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; const overviewServiceMock = { getObjectiveWithKeyresults: jest.fn() @@ -37,7 +37,7 @@ const completedServiceMock = { deleteCompleted: jest.fn() }; -describe("ObjectiveColumnComponent", () => { +describe('ObjectiveColumnComponent', () => { let component: ObjectiveComponent; let fixture: ComponentFixture; let loader: HarnessLoader; @@ -83,16 +83,16 @@ describe("ObjectiveColumnComponent", () => { component.objective = objectiveMin; }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - test("Mat-menu should open and close", async() => { + test('Mat-menu should open and close', async() => { component.isWritable = true; fixture.detectChanges(); - const menu = await loader.getHarness(MatMenuHarness.with({ selector: "[data-testid=\"three-dot-menu\"]" })); + const menu = await loader.getHarness(MatMenuHarness.with({ selector: '[data-testid="three-dot-menu"]' })); expect(await menu.isOpen()) .toBeFalsy(); await menu.open(); @@ -105,34 +105,34 @@ describe("ObjectiveColumnComponent", () => { test.each([ [State.DRAFT, - "assets/icons/draft-icon.svg"], + 'assets/icons/draft-icon.svg'], [State.ONGOING, - "assets/icons/ongoing-icon.svg"], + 'assets/icons/ongoing-icon.svg'], [State.SUCCESSFUL, - "assets/icons/successful-icon.svg"], + 'assets/icons/successful-icon.svg'], [State.NOTSUCCESSFUL, - "assets/icons/not-successful-icon.svg"] - ])("Status-indicator should change based on the state given by the service", (state: State, path) => { + 'assets/icons/not-successful-icon.svg'] + ])('Status-indicator should change based on the state given by the service', (state: State, path) => { component.objective = { ...objectiveMin, state: state }; fixture.detectChanges(); - const image = fixture.debugElement.query(By.css("[data-testid=\"objective-state\"]")); - const statusIndicatorSrc = image.attributes["src"]; + const image = fixture.debugElement.query(By.css('[data-testid="objective-state"]')); + const statusIndicatorSrc = image.attributes['src']; expect(statusIndicatorSrc) .toBe(path); }); - test("Mat-menu should not be present if writeable is false", async() => { + test('Mat-menu should not be present if writeable is false', async() => { component.isWritable = false; fixture.detectChanges(); - const menu = fixture.debugElement.query(By.css("[data-testid=\"objective-menu\"]")); + const menu = fixture.debugElement.query(By.css('[data-testid="objective-menu"]')); expect(menu) .toBeFalsy(); }); - test("Create keyresult button should not be present if writeable is false", async() => { + test('Create keyresult button should not be present if writeable is false', async() => { component.isWritable = false; - const button = fixture.debugElement.query(By.css("[data-testId=\"add-keyResult\"]")); + const button = fixture.debugElement.query(By.css('[data-testId="add-keyResult"]')); expect(button) .toBeFalsy(); }); diff --git a/frontend/src/app/components/objective/objective.component.ts b/frontend/src/app/components/objective/objective.component.ts index 00cb405643..9596777046 100644 --- a/frontend/src/app/components/objective/objective.component.ts +++ b/frontend/src/app/components/objective/objective.component.ts @@ -1,20 +1,20 @@ -import { Component, Input, ViewChild } from "@angular/core"; -import { ObjectiveMin } from "../../shared/types/model/ObjectiveMin"; -import { Router } from "@angular/router"; -import { distinct, map, ReplaySubject, take } from "rxjs"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { trackByFn } from "../../shared/common"; -import { KeyresultDialogComponent } from "../keyresult-dialog/keyresult-dialog.component"; -import { TranslateService } from "@ngx-translate/core"; -import { DialogService } from "../../services/dialog.service"; -import { ObjectiveMenuActionsService, ObjectiveMenuEntry } from "../../services/objective-menu-actions.service"; -import { State } from "../../shared/types/enums/State"; -import { MatMenuTrigger } from "@angular/material/menu"; +import { Component, Input, ViewChild } from '@angular/core'; +import { ObjectiveMin } from '../../shared/types/model/ObjectiveMin'; +import { Router } from '@angular/router'; +import { distinct, map, ReplaySubject, take } from 'rxjs'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { trackByFn } from '../../shared/common'; +import { KeyresultDialogComponent } from '../keyresult-dialog/keyresult-dialog.component'; +import { TranslateService } from '@ngx-translate/core'; +import { DialogService } from '../../services/dialog.service'; +import { ObjectiveMenuActionsService, ObjectiveMenuEntry } from '../../services/objective-menu-actions.service'; +import { State } from '../../shared/types/enums/State'; +import { MatMenuTrigger } from '@angular/material/menu'; @Component({ - selector: "app-objective-column", - templateUrl: "./objective.component.html", - styleUrls: ["./objective.component.scss"] + selector: 'app-objective-column', + templateUrl: './objective.component.html', + styleUrls: ['./objective.component.scss'] }) export class ObjectiveComponent { @Input() isWritable!: boolean; @@ -43,7 +43,7 @@ export class ObjectiveComponent { getStateTooltip(stateString: string): string { const state = this.getStateByValue(stateString); - return this.translate.instant("INFORMATION.OBJECTIVE_STATE_TOOLTIP", { state: state }); + return this.translate.instant('INFORMATION.OBJECTIVE_STATE_TOOLTIP', { state: state }); } redirect(menuEntry: ObjectiveMenuEntry, objectiveMin: ObjectiveMin) { @@ -60,7 +60,7 @@ export class ObjectiveComponent { } openObjectiveDetail(objectiveId: number) { - this.router.navigate(["details/objective", + this.router.navigate(['details/objective', objectiveId]); } @@ -87,6 +87,6 @@ export class ObjectiveComponent { getStateByValue(value: string): string { return Object.keys(State) - .find((key) => State[key as keyof typeof State] === value) ?? ""; + .find((key) => State[key as keyof typeof State] === value) ?? ''; } } diff --git a/frontend/src/app/components/overview/overview.component.spec.ts b/frontend/src/app/components/overview/overview.component.spec.ts index 60c61539fb..6b57c2c406 100644 --- a/frontend/src/app/components/overview/overview.component.spec.ts +++ b/frontend/src/app/components/overview/overview.component.spec.ts @@ -1,21 +1,21 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; - -import { OverviewComponent } from "./overview.component"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { overViewEntity1 } from "../../shared/testData"; -import { BehaviorSubject, of, Subject } from "rxjs"; -import { OverviewService } from "../../services/overview.service"; -import { AppRoutingModule } from "../../app-routing.module"; -import { RouterTestingHarness } from "@angular/router/testing"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { authGuard } from "../../guards/auth.guard"; -import { ApplicationBannerComponent } from "../application-banner/application-banner.component"; -import { ApplicationTopBarComponent } from "../application-top-bar/application-top-bar.component"; -import { DateTimeProvider, OAuthLogger, OAuthService, UrlHelperService } from "angular-oauth2-oidc"; -import { MatDialogModule, MatDialogRef } from "@angular/material/dialog"; -import { MatIconModule } from "@angular/material/icon"; -import { MatMenuModule } from "@angular/material/menu"; -import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OverviewComponent } from './overview.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { overViewEntity1 } from '../../shared/testData'; +import { BehaviorSubject, of, Subject } from 'rxjs'; +import { OverviewService } from '../../services/overview.service'; +import { AppRoutingModule } from '../../app-routing.module'; +import { RouterTestingHarness } from '@angular/router/testing'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { authGuard } from '../../guards/auth.guard'; +import { ApplicationBannerComponent } from '../application-banner/application-banner.component'; +import { ApplicationTopBarComponent } from '../application-top-bar/application-top-bar.component'; +import { DateTimeProvider, OAuthLogger, OAuthService, UrlHelperService } from 'angular-oauth2-oidc'; +import { MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { MatIconModule } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; const overviewService = { getOverview: jest.fn() @@ -40,7 +40,7 @@ class ResizeObserverMock { disconnect() {} } -describe("OverviewComponent", () => { +describe('OverviewComponent', () => { // @ts-ignore global.ResizeObserver = ResizeObserverMock; @@ -90,72 +90,72 @@ describe("OverviewComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should load default overview when no quarter is defined in route-params", () => { - jest.spyOn(overviewService, "getOverview"); + it('should load default overview when no quarter is defined in route-params', () => { + jest.spyOn(overviewService, 'getOverview'); markFiltersAsReady(); expect(overviewService.getOverview) .toHaveBeenCalled(); }); - it("should load default overview on init", async() => { - jest.spyOn(overviewService, "getOverview"); + it('should load default overview on init', async() => { + jest.spyOn(overviewService, 'getOverview'); markFiltersAsReady(); expect(overviewService.getOverview) - .toHaveBeenCalledWith(undefined, [], ""); + .toHaveBeenCalledWith(undefined, [], ''); }); it.each([ [ - "?quarter=7", + '?quarter=7', 7, [], - "" + '' ], [ - "?teams=1,2", + '?teams=1,2', undefined, [1, 2], - "" + '' ], [ - "?objectiveQuery=a%20a", + '?objectiveQuery=a%20a', undefined, [], - "a a" + 'a a' ], [ - "?teams=1,2&objectiveQuery=a%20a", + '?teams=1,2&objectiveQuery=a%20a', undefined, [1, 2], - "a a" + 'a a' ], [ - "?teams=1,2&quarter=7", + '?teams=1,2&quarter=7', 7, [1, 2], - "" + '' ], [ - "?quarter=7&objectiveQuery=a%20a", + '?quarter=7&objectiveQuery=a%20a', 7, [], - "a a" + 'a a' ] - ])("should load overview based on queryparams", async( + ])('should load overview based on queryparams', async( query: string, quarterParam?: number, teamsParam?: number[], objectiveQueryParam?: string ) => { - jest.spyOn(overviewService, "getOverview"); - jest.spyOn(component, "loadOverview"); + jest.spyOn(overviewService, 'getOverview'); + jest.spyOn(component, 'loadOverview'); const routerHarness = await RouterTestingHarness.create(); - await routerHarness.navigateByUrl("/" + query); + await routerHarness.navigateByUrl('/' + query); routerHarness.detectChanges(); component.loadOverviewWithParams(); expect(overviewService.getOverview) @@ -164,9 +164,9 @@ describe("OverviewComponent", () => { .toHaveBeenCalledWith(quarterParam, teamsParam, objectiveQueryParam); }); - it("should refresh overview Entities after getOverview is called", async() => { - jest.spyOn(component.overviewEntities$, "next"); - jest.spyOn(component, "loadOverview"); + it('should refresh overview Entities after getOverview is called', async() => { + jest.spyOn(component.overviewEntities$, 'next'); + jest.spyOn(component, 'loadOverview'); component.loadOverview(); expect(component.loadOverview) .toHaveBeenCalledTimes(1); @@ -174,10 +174,10 @@ describe("OverviewComponent", () => { .toHaveBeenCalledWith([overViewEntity1]); }); - it("should get default if call throws error", async() => { - overviewService.getOverview.mockReturnValue(of(new Error(""))); + it('should get default if call throws error', async() => { + overviewService.getOverview.mockReturnValue(of(new Error(''))); - jest.spyOn(component, "loadOverview"); + jest.spyOn(component, 'loadOverview'); component.loadOverview(); expect(component.loadOverview) .toHaveBeenLastCalledWith(); diff --git a/frontend/src/app/components/overview/overview.component.ts b/frontend/src/app/components/overview/overview.component.ts index 4b7efb6a79..c0724cbf63 100644 --- a/frontend/src/app/components/overview/overview.component.ts +++ b/frontend/src/app/components/overview/overview.component.ts @@ -1,5 +1,5 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from "@angular/core"; -import { OverviewEntity } from "../../shared/types/model/OverviewEntity"; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { OverviewEntity } from '../../shared/types/model/OverviewEntity'; import { BehaviorSubject, catchError, @@ -9,17 +9,17 @@ import { Subject, take, takeUntil -} from "rxjs"; -import { OverviewService } from "../../services/overview.service"; -import { ActivatedRoute } from "@angular/router"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { getQueryString, getValueFromQuery, isMobileDevice, trackByFn } from "../../shared/common"; -import { ConfigService } from "../../services/config.service"; +} from 'rxjs'; +import { OverviewService } from '../../services/overview.service'; +import { ActivatedRoute } from '@angular/router'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { getQueryString, getValueFromQuery, isMobileDevice, trackByFn } from '../../shared/common'; +import { ConfigService } from '../../services/config.service'; @Component({ - selector: "app-overview", - templateUrl: "./overview.component.html", - styleUrls: ["./overview.component.scss"], + selector: 'app-overview', + templateUrl: './overview.component.html', + styleUrls: ['./overview.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class OverviewComponent implements OnInit, OnDestroy { @@ -31,7 +31,7 @@ export class OverviewComponent implements OnInit, OnDestroy { overviewPadding = new Subject(); - backgroundLogoSrc$ = new BehaviorSubject("assets/images/empty.svg"); + backgroundLogoSrc$ = new BehaviorSubject('assets/images/empty.svg'); constructor( private overviewService: OverviewService, @@ -61,7 +61,7 @@ export class OverviewComponent implements OnInit, OnDestroy { this.changeDetector.detectChanges(); }); if (!isMobileDevice()) { - document.getElementById("overview")?.classList.add("bottom-shadow-space"); + document.getElementById('overview')?.classList.add('bottom-shadow-space'); } this.configService.config$.subscribe({ next: (config) => { @@ -73,9 +73,9 @@ export class OverviewComponent implements OnInit, OnDestroy { } loadOverviewWithParams() { - const quarterQuery = this.activatedRoute.snapshot.queryParams["quarter"]; - const teamQuery = this.activatedRoute.snapshot.queryParams["teams"]; - const objectiveQuery = this.activatedRoute.snapshot.queryParams["objectiveQuery"]; + const quarterQuery = this.activatedRoute.snapshot.queryParams['quarter']; + const teamQuery = this.activatedRoute.snapshot.queryParams['teams']; + const objectiveQuery = this.activatedRoute.snapshot.queryParams['objectiveQuery']; const teamIds = getValueFromQuery(teamQuery); const quarterId = getValueFromQuery(quarterQuery)[0]; diff --git a/frontend/src/app/components/quarter-filter/quarter-filter.component.spec.ts b/frontend/src/app/components/quarter-filter/quarter-filter.component.spec.ts index d0ac2c9ba0..aae2470805 100644 --- a/frontend/src/app/components/quarter-filter/quarter-filter.component.spec.ts +++ b/frontend/src/app/components/quarter-filter/quarter-filter.component.spec.ts @@ -1,19 +1,19 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { QuarterFilterComponent } from "./quarter-filter.component"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { OverviewService } from "../../services/overview.service"; -import { Observable, of } from "rxjs"; -import { Quarter } from "../../shared/types/model/Quarter"; -import { QuarterService } from "../../services/quarter.service"; -import { RouterTestingHarness, RouterTestingModule } from "@angular/router/testing"; -import { FormsModule } from "@angular/forms"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { MatSelectModule } from "@angular/material/select"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { HarnessLoader } from "@angular/cdk/testing"; -import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed"; -import { MatSelectHarness } from "@angular/material/select/testing"; -import { Router } from "@angular/router"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { QuarterFilterComponent } from './quarter-filter.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { OverviewService } from '../../services/overview.service'; +import { Observable, of } from 'rxjs'; +import { Quarter } from '../../shared/types/model/Quarter'; +import { QuarterService } from '../../services/quarter.service'; +import { RouterTestingHarness, RouterTestingModule } from '@angular/router/testing'; +import { FormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatSelectModule } from '@angular/material/select'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { MatSelectHarness } from '@angular/material/select/testing'; +import { Router } from '@angular/router'; const overviewService = { getOverview: jest.fn() @@ -21,16 +21,16 @@ const overviewService = { const quarters = [ new Quarter( - 999, "Backlog", null, null + 999, 'Backlog', null, null ), new Quarter( - 2, "23.02.2025", new Date(), new Date() + 2, '23.02.2025', new Date(), new Date() ), new Quarter( - 5, "23.02.2025", new Date(), new Date() + 5, '23.02.2025', new Date(), new Date() ), new Quarter( - 7, "23.02.2025", new Date(), new Date() + 7, '23.02.2025', new Date(), new Date() ) ]; @@ -43,7 +43,7 @@ const quarterService = { } }; -describe("QuarterFilterComponent", () => { +describe('QuarterFilterComponent', () => { let component: QuarterFilterComponent; let fixture: ComponentFixture; let loader: HarnessLoader; @@ -72,14 +72,14 @@ describe("QuarterFilterComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should set correct default quarter if no route param is defined", async() => { - jest.spyOn(component, "changeDisplayedQuarter"); - jest.spyOn(quarters[2] as any, "isCurrent") + it('should set correct default quarter if no route param is defined', async() => { + jest.spyOn(component, 'changeDisplayedQuarter'); + jest.spyOn(quarters[2] as any, 'isCurrent') .mockReturnValue(true); const quarterSelect = await loader.getHarness(MatSelectHarness); expect(quarterSelect) @@ -89,20 +89,20 @@ describe("QuarterFilterComponent", () => { expect(component.currentQuarterId) .toBe(quarters[2].id); expect(await quarterSelect.getValueText()) - .toBe(quarters[2].label + " Aktuell"); + .toBe(quarters[2].label + ' Aktuell'); expect(component.changeDisplayedQuarter) .toHaveBeenCalledTimes(1); }); - it("should set correct value in form according to route param", async() => { - jest.spyOn(component, "changeDisplayedQuarter"); + it('should set correct value in form according to route param', async() => { + jest.spyOn(component, 'changeDisplayedQuarter'); const routerHarnessPromise = RouterTestingHarness.create(); const quarterSelectPromise = loader.getHarness(MatSelectHarness); await Promise.all([routerHarnessPromise, quarterSelectPromise]) .then(async([routerHarness, quarterSelect]) => { - await routerHarness.navigateByUrl("/?quarter=" + quarters[3].id); + await routerHarness.navigateByUrl('/?quarter=' + quarters[3].id); expect(quarterSelect) .toBeTruthy(); @@ -119,12 +119,12 @@ describe("QuarterFilterComponent", () => { }); }); - it("should set default quarter if quarter id in route params does not exist", async() => { - jest.spyOn(component, "changeDisplayedQuarter"); + it('should set default quarter if quarter id in route params does not exist', async() => { + jest.spyOn(component, 'changeDisplayedQuarter'); const quarterSelect = await loader.getHarness(MatSelectHarness); const routerHarness = await RouterTestingHarness.create(); - await routerHarness.navigateByUrl("/?quarter=1000"); + await routerHarness.navigateByUrl('/?quarter=1000'); expect(quarterSelect) .toBeTruthy(); @@ -134,10 +134,10 @@ describe("QuarterFilterComponent", () => { expect(component.currentQuarterId) .toBe(quarters[2].id); expect(await quarterSelect.getValueText()) - .toBe(quarters[2].label + " Aktuell"); + .toBe(quarters[2].label + ' Aktuell'); expect(component.changeDisplayedQuarter) .toHaveBeenCalledTimes(1); expect(router.url) - .toBe("/?quarter=" + quarters[2].id); + .toBe('/?quarter=' + quarters[2].id); }); }); diff --git a/frontend/src/app/components/quarter-filter/quarter-filter.component.ts b/frontend/src/app/components/quarter-filter/quarter-filter.component.ts index 2efaf4b813..5b2fb3da16 100644 --- a/frontend/src/app/components/quarter-filter/quarter-filter.component.ts +++ b/frontend/src/app/components/quarter-filter/quarter-filter.component.ts @@ -1,14 +1,14 @@ -import { ChangeDetectionStrategy, Component, EventEmitter, OnInit, Output } from "@angular/core"; -import { QuarterService } from "../../services/quarter.service"; -import { Quarter } from "../../shared/types/model/Quarter"; -import { BehaviorSubject, forkJoin } from "rxjs"; -import { ActivatedRoute, Router } from "@angular/router"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { getValueFromQuery } from "../../shared/common"; +import { ChangeDetectionStrategy, Component, EventEmitter, OnInit, Output } from '@angular/core'; +import { QuarterService } from '../../services/quarter.service'; +import { Quarter } from '../../shared/types/model/Quarter'; +import { BehaviorSubject, forkJoin } from 'rxjs'; +import { ActivatedRoute, Router } from '@angular/router'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { getValueFromQuery } from '../../shared/common'; @Component({ - selector: "app-quarter-filter", - templateUrl: "./quarter-filter.component.html", + selector: 'app-quarter-filter', + templateUrl: './quarter-filter.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) export class QuarterFilterComponent implements OnInit { @@ -33,7 +33,7 @@ export class QuarterFilterComponent implements OnInit { .subscribe(([quarters, currentQuarter]) => { this.quarters.next(quarters); - const quarterQuery = this.route.snapshot.queryParams["quarter"]; + const quarterQuery = this.route.snapshot.queryParams['quarter']; const quarterId: number = getValueFromQuery(quarterQuery)[0]; if (quarters.map((quarter) => quarter.id) .includes(quarterId)) { @@ -47,7 +47,7 @@ export class QuarterFilterComponent implements OnInit { this.refreshDataService.quarterFilterReady.next(); } } - const quarterLabel = quarters.find((e) => e.id == this.currentQuarterId)?.label || ""; + const quarterLabel = quarters.find((e) => e.id == this.currentQuarterId)?.label || ''; this.quarterLabel$.next(quarterLabel); }); } @@ -55,7 +55,7 @@ export class QuarterFilterComponent implements OnInit { changeDisplayedQuarter() { const id = this.currentQuarterId; const quarterLabel = this.quarters.getValue() - .find((e) => e.id == id)?.label || ""; + .find((e) => e.id == id)?.label || ''; this.quarterLabel$.next(quarterLabel); this.router diff --git a/frontend/src/app/components/team-filter/team-filter.component.spec.ts b/frontend/src/app/components/team-filter/team-filter.component.spec.ts index fed210b8c8..66d00871af 100644 --- a/frontend/src/app/components/team-filter/team-filter.component.spec.ts +++ b/frontend/src/app/components/team-filter/team-filter.component.spec.ts @@ -1,18 +1,18 @@ -import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from "@angular/core/testing"; - -import { TeamFilterComponent } from "./team-filter.component"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { RouterTestingHarness, RouterTestingModule } from "@angular/router/testing"; -import { MatChipsModule } from "@angular/material/chips"; -import { TeamService } from "../../services/team.service"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { BehaviorSubject, of, Subject } from "rxjs"; -import { team1, team2, team3, teamList, testUser } from "../../shared/testData"; -import { Router } from "@angular/router"; -import { MatIconModule } from "@angular/material/icon"; -import { UserService } from "../../services/user.service"; -import { extractTeamsFromUser } from "../../shared/types/model/User"; -import { ApplicationBannerComponent } from "../application-banner/application-banner.component"; +import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing'; + +import { TeamFilterComponent } from './team-filter.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { RouterTestingHarness, RouterTestingModule } from '@angular/router/testing'; +import { MatChipsModule } from '@angular/material/chips'; +import { TeamService } from '../../services/team.service'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { BehaviorSubject, of, Subject } from 'rxjs'; +import { team1, team2, team3, teamList, testUser } from '../../shared/testData'; +import { Router } from '@angular/router'; +import { MatIconModule } from '@angular/material/icon'; +import { UserService } from '../../services/user.service'; +import { extractTeamsFromUser } from '../../shared/types/model/User'; +import { ApplicationBannerComponent } from '../application-banner/application-banner.component'; const teamServiceMock = { getAllTeams: jest.fn() @@ -28,7 +28,7 @@ const userServiceMock = { getCurrentUser: jest.fn() }; -describe("TeamFilterComponent", () => { +describe('TeamFilterComponent', () => { let component: TeamFilterComponent; let fixture: ComponentFixture; let router: Router; @@ -61,14 +61,14 @@ describe("TeamFilterComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should select all chips per default", waitForAsync(async() => { - jest.spyOn(component.teams$, "next"); - jest.spyOn(component, "changeTeamFilterParams"); + it('should select all chips per default', waitForAsync(async() => { + jest.spyOn(component.teams$, 'next'); + jest.spyOn(component, 'changeTeamFilterParams'); component.ngOnInit(); fixture.detectChanges(); @@ -80,14 +80,14 @@ describe("TeamFilterComponent", () => { .toHaveBeenCalledTimes(1); })); - it("should select the right chips", waitForAsync(async() => { + it('should select the right chips', waitForAsync(async() => { const teamIds = teamList.map((e) => e.id) .filter((e, i) => i < 2); - jest.spyOn(component.teams$, "next"); - jest.spyOn(component, "changeTeamFilterParams"); + jest.spyOn(component.teams$, 'next'); + jest.spyOn(component, 'changeTeamFilterParams'); const routerHarness = await RouterTestingHarness.create(); - await routerHarness.navigateByUrl("/?teams=" + teamIds.join(",")); + await routerHarness.navigateByUrl('/?teams=' + teamIds.join(',')); component.ngOnInit(); fixture.detectChanges(); @@ -102,13 +102,13 @@ describe("TeamFilterComponent", () => { .toHaveBeenCalledTimes(1); })); - it("activeTeams array should contain every team when all teams are shown", waitForAsync(async() => { + it('activeTeams array should contain every team when all teams are shown', waitForAsync(async() => { const teamIds = teamList.map((e) => e.id); - jest.spyOn(component.teams$, "next"); - jest.spyOn(component, "changeTeamFilterParams"); + jest.spyOn(component.teams$, 'next'); + jest.spyOn(component, 'changeTeamFilterParams'); const routerHarness = await RouterTestingHarness.create(); - await routerHarness.navigateByUrl("/?teams=" + teamIds.join(",")); + await routerHarness.navigateByUrl('/?teams=' + teamIds.join(',')); component.ngOnInit(); fixture.detectChanges(); @@ -123,12 +123,12 @@ describe("TeamFilterComponent", () => { .toHaveBeenCalledTimes(1); })); - it("change filter params and reload", fakeAsync(async() => { + it('change filter params and reload', fakeAsync(async() => { component.activeTeams = teamList.map((e) => e.id) .filter((e, i) => i < 2); const routerHarness = await RouterTestingHarness.create(); - jest.spyOn(component, "changeTeamFilterParams"); - jest.spyOn(refreshDataServiceMock, "markDataRefresh"); + jest.spyOn(component, 'changeTeamFilterParams'); + jest.spyOn(refreshDataServiceMock, 'markDataRefresh'); component.activeTeams = [8, 5, @@ -139,7 +139,7 @@ describe("TeamFilterComponent", () => { expect(component.changeTeamFilterParams) .toHaveBeenCalledTimes(1); expect(router.url) - .toBe("/?teams=8,5,10"); + .toBe('/?teams=8,5,10'); })); it.each([ @@ -163,10 +163,10 @@ describe("TeamFilterComponent", () => { [[3], 3, []] - ])("toggle Selection", (activeTeams: number[], selected: number, expected: number[]) => { + ])('toggle Selection', (activeTeams: number[], selected: number, expected: number[]) => { component.activeTeams = activeTeams; - jest.spyOn(component, "areAllTeamsShown"); - jest.spyOn(component, "changeTeamFilterParams"); + jest.spyOn(component, 'areAllTeamsShown'); + jest.spyOn(component, 'changeTeamFilterParams'); component.toggleSelection(selected); fixture.detectChanges(); @@ -194,7 +194,7 @@ describe("TeamFilterComponent", () => { 2, 4], false] - ])("are all teams shown", (activeTeams: number[], expected: boolean) => { + ])('are all teams shown', (activeTeams: number[], expected: boolean) => { component.activeTeams = activeTeams; expect(component.areAllTeamsShown()) .toBe(expected); @@ -218,9 +218,9 @@ describe("TeamFilterComponent", () => { 2, 3], []] - ])("select all", (currentTeams: number[], expectedTeams: number[]) => { + ])('select all', (currentTeams: number[], expectedTeams: number[]) => { component.activeTeams = currentTeams; - jest.spyOn(component, "changeTeamFilterParams"); + jest.spyOn(component, 'changeTeamFilterParams'); component.toggleAll(); expect(component.changeTeamFilterParams) .toHaveBeenCalledTimes(1); @@ -228,7 +228,7 @@ describe("TeamFilterComponent", () => { .toStrictEqual(expectedTeams); }); - it("should refresh teams on data refresh", () => { + it('should refresh teams on data refresh', () => { component.ngOnInit(); component.activeTeams = [team2.id, team3.id]; @@ -249,14 +249,14 @@ describe("TeamFilterComponent", () => { .toStrictEqual([team1.id]); }); - it("should use teams of user if no known teams are in url", async() => { + it('should use teams of user if no known teams are in url', async() => { const teamIds = [654, 478]; - jest.spyOn(component.teams$, "next"); - jest.spyOn(component, "changeTeamFilterParams"); + jest.spyOn(component.teams$, 'next'); + jest.spyOn(component, 'changeTeamFilterParams'); const routerHarness = await RouterTestingHarness.create(); - await routerHarness.navigateByUrl("/?teams=" + teamIds.join(",")); + await routerHarness.navigateByUrl('/?teams=' + teamIds.join(',')); component.ngOnInit(); fixture.detectChanges(); @@ -270,12 +270,12 @@ describe("TeamFilterComponent", () => { .toHaveBeenCalledTimes(1); }); - it("should use teams of user if no teams are in url", async() => { - jest.spyOn(component.teams$, "next"); - jest.spyOn(component, "changeTeamFilterParams"); + it('should use teams of user if no teams are in url', async() => { + jest.spyOn(component.teams$, 'next'); + jest.spyOn(component, 'changeTeamFilterParams'); const routerHarness = await RouterTestingHarness.create(); - await routerHarness.navigateByUrl(""); + await routerHarness.navigateByUrl(''); component.ngOnInit(); fixture.detectChanges(); @@ -292,12 +292,12 @@ describe("TeamFilterComponent", () => { it.each([[[1, 2, 3], - "1,2,3"], + '1,2,3'], [[], - null]])("changeTeamFilterParams", async(currentTeams: number[], routingTeams: string | null) => { + null]])('changeTeamFilterParams', async(currentTeams: number[], routingTeams: string | null) => { component.activeTeams = currentTeams; - jest.spyOn(router, "navigate"); + jest.spyOn(router, 'navigate'); fixture.detectChanges(); await component.changeTeamFilterParams(); @@ -308,23 +308,23 @@ describe("TeamFilterComponent", () => { .toHaveBeenCalledWith([], { queryParams: { teams: routingTeams } }); }); - it("should filter teams by toggled priority and then by name", async() => { + it('should filter teams by toggled priority and then by name', async() => { const teams = [ { id: 1, version: 0, - name: "Team D", + name: 'Team D', writeable: true }, { id: 2, version: 0, - name: "Team C", + name: 'Team C', writeable: true }, { id: 3, version: 0, - name: "Team B", + name: 'Team B', writeable: true }, { id: 4, version: 0, - name: "Team A", + name: 'Team A', writeable: true } ]; @@ -338,19 +338,19 @@ describe("TeamFilterComponent", () => { .toEqual([ { id: 4, version: 0, - name: "Team A", + name: 'Team A', writeable: true }, { id: 3, version: 0, - name: "Team B", + name: 'Team B', writeable: true }, { id: 2, version: 0, - name: "Team C", + name: 'Team C', writeable: true }, { id: 1, version: 0, - name: "Team D", + name: 'Team D', writeable: true } ]); }); diff --git a/frontend/src/app/components/team-filter/team-filter.component.ts b/frontend/src/app/components/team-filter/team-filter.component.ts index 01354ba46e..f4dd5ea46d 100644 --- a/frontend/src/app/components/team-filter/team-filter.component.ts +++ b/frontend/src/app/components/team-filter/team-filter.component.ts @@ -1,18 +1,18 @@ -import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from "@angular/core"; -import { BehaviorSubject, filter, Subject, Subscription, takeUntil } from "rxjs"; -import { Team } from "../../shared/types/model/Team"; -import { TeamService } from "../../services/team.service"; -import { ActivatedRoute, Router } from "@angular/router"; -import { areEqual, getValueFromQuery, optionalReplaceWithNulls, trackByFn } from "../../shared/common"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { UserService } from "../../services/user.service"; -import { extractTeamsFromUser } from "../../shared/types/model/User"; -import { BreakpointObserver } from "@angular/cdk/layout"; +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { BehaviorSubject, filter, Subject, Subscription, takeUntil } from 'rxjs'; +import { Team } from '../../shared/types/model/Team'; +import { TeamService } from '../../services/team.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { areEqual, getValueFromQuery, optionalReplaceWithNulls, trackByFn } from '../../shared/common'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { UserService } from '../../services/user.service'; +import { extractTeamsFromUser } from '../../shared/types/model/User'; +import { BreakpointObserver } from '@angular/cdk/layout'; @Component({ - selector: "app-team-filter", - templateUrl: "./team-filter.component.html", - styleUrls: ["./team-filter.component.scss"], + selector: 'app-team-filter', + templateUrl: './team-filter.component.html', + styleUrls: ['./team-filter.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class TeamFilterComponent implements OnInit, OnDestroy { @@ -48,7 +48,7 @@ export class TeamFilterComponent implements OnInit, OnDestroy { this.refreshTeamData(); this.breakpointObserver - .observe(["(min-width: 1px) and (max-width: 767px)"]) + .observe(['(min-width: 1px) and (max-width: 767px)']) .pipe(takeUntil(this.unsubscribe$)) .subscribe((result) => { this.isMobile = result.matches; @@ -64,7 +64,7 @@ export class TeamFilterComponent implements OnInit, OnDestroy { .pipe(takeUntil(this.unsubscribe$), filter((teams) => teams.length > 0)) .subscribe((teams: Team[]) => { this.teams$.next(teams); - const teamQuery = this.route.snapshot.queryParams["teams"]; + const teamQuery = this.route.snapshot.queryParams['teams']; const teamIds = getValueFromQuery(teamQuery); const knownTeams = this.getAllTeamIds() .filter((teamId) => teamIds?.includes(teamId)); @@ -87,7 +87,7 @@ export class TeamFilterComponent implements OnInit, OnDestroy { } changeTeamFilterParams() { - const params = { teams: this.activeTeams.join(",") }; + const params = { teams: this.activeTeams.join(',') }; const optionalParams = optionalReplaceWithNulls(params); this.router .navigate([], { queryParams: optionalParams }) @@ -126,7 +126,7 @@ export class TeamFilterComponent implements OnInit, OnDestroy { getTeamName(id: number): string { const teamName = this.teams$.getValue() .find((team) => team.id === id)?.name; - return teamName ?? "no team name"; + return teamName ?? 'no team name'; } sortTeamsToggledPriority() { diff --git a/frontend/src/app/components/team/team.component.spec.ts b/frontend/src/app/components/team/team.component.spec.ts index 3f279e5232..4f042ec920 100644 --- a/frontend/src/app/components/team/team.component.spec.ts +++ b/frontend/src/app/components/team/team.component.spec.ts @@ -1,25 +1,25 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { TeamComponent } from "./team.component"; -import { MatIcon } from "@angular/material/icon"; -import { overViewEntity1, overViewEntity2 } from "../../shared/testData"; -import { ObjectiveComponent } from "../objective/objective.component"; -import { RouterTestingModule } from "@angular/router/testing"; -import { MatMenuModule } from "@angular/material/menu"; -import { KeyresultComponent } from "../keyresult/keyresult.component"; -import { MatDialogModule } from "@angular/material/dialog"; -import { By } from "@angular/platform-browser"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { TranslateTestingModule } from "ngx-translate-testing"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { TeamComponent } from './team.component'; +import { MatIcon } from '@angular/material/icon'; +import { overViewEntity1, overViewEntity2 } from '../../shared/testData'; +import { ObjectiveComponent } from '../objective/objective.component'; +import { RouterTestingModule } from '@angular/router/testing'; +import { MatMenuModule } from '@angular/material/menu'; +import { KeyresultComponent } from '../keyresult/keyresult.component'; +import { MatDialogModule } from '@angular/material/dialog'; +import { By } from '@angular/platform-browser'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { TranslateTestingModule } from 'ngx-translate-testing'; // @ts-ignore -import * as de from "../../../assets/i18n/de.json"; -import { MatTooltipModule } from "@angular/material/tooltip"; -import { ConfidenceComponent } from "../confidence/confidence.component"; -import { ScoringComponent } from "../../shared/custom/scoring/scoring.component"; -import { ChangeDetectionStrategy } from "@angular/core"; -import { DialogService } from "../../services/dialog.service"; -import { ConfigService } from "../../services/config.service"; -import { of } from "rxjs"; -import { provideHttpClient, withInterceptorsFromDi } from "@angular/common/http"; +import * as de from '../../../assets/i18n/de.json'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { ConfidenceComponent } from '../confidence/confidence.component'; +import { ScoringComponent } from '../../shared/custom/scoring/scoring.component'; +import { ChangeDetectionStrategy } from '@angular/core'; +import { DialogService } from '../../services/dialog.service'; +import { ConfigService } from '../../services/config.service'; +import { of } from 'rxjs'; +import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; const dialogService = { open: jest.fn() @@ -28,7 +28,7 @@ const dialogService = { const configServiceDefined = { config$: of({ customStyles: { - "okr-add-objective-icon": "new-icon-from-config-service.svg" + 'okr-add-objective-icon': 'new-icon-from-config-service.svg' } }) }; @@ -36,7 +36,7 @@ const configServiceDefined = { const configServiceUndefined = { config$: of({ customStyles: { - "okr-add-objective-icon": undefined + 'okr-add-objective-icon': undefined } }) }; @@ -45,7 +45,7 @@ const refreshDataServiceMock = { markDataRefresh: jest.fn() }; -describe("TeamComponent", () => { +describe('TeamComponent', () => { let component: TeamComponent; let fixture: ComponentFixture; @@ -95,38 +95,38 @@ describe("TeamComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { fixture.detectChanges(); expect(component) .toBeTruthy(); }); - it("should display add objective button if writeable is true", async() => { + it('should display add objective button if writeable is true', async() => { fixture.detectChanges(); - const button = fixture.debugElement.query(By.css("[data-testId=\"add-objective\"]")); + const button = fixture.debugElement.query(By.css('[data-testId="add-objective"]')); expect(button) .toBeTruthy(); }); - it("should not display add objective button if writeable is false", () => { + it('should not display add objective button if writeable is false', () => { component.overviewEntity = { ...overViewEntity2 }; component.overviewEntity.writeable = false; fixture.detectChanges(); - const button = fixture.debugElement.query(By.css("[data-testId=\"add-objective\"]")); + const button = fixture.debugElement.query(By.css('[data-testId="add-objective"]')); expect(button) .toBeFalsy(); }); - it("should set value of addIconSrc if src from config service is defined", () => { + it('should set value of addIconSrc if src from config service is defined', () => { expect(component.addIconSrc.value) - .toBe("new-icon-from-config-service.svg"); - const addObjectiveIcon = fixture.debugElement.query(By.css("[data-testId=\"add-objective-icon\"]")); - expect(addObjectiveIcon.attributes["src"]) - .toBe("new-icon-from-config-service.svg"); + .toBe('new-icon-from-config-service.svg'); + const addObjectiveIcon = fixture.debugElement.query(By.css('[data-testId="add-objective-icon"]')); + expect(addObjectiveIcon.attributes['src']) + .toBe('new-icon-from-config-service.svg'); }); }); -describe("TeamComponent undefined values in config service", () => { +describe('TeamComponent undefined values in config service', () => { let component: TeamComponent; let fixture: ComponentFixture; @@ -154,11 +154,11 @@ describe("TeamComponent undefined values in config service", () => { fixture.detectChanges(); }); - it("should keep default value of addIconSrc if src from config service is undefined", () => { + it('should keep default value of addIconSrc if src from config service is undefined', () => { expect(component.addIconSrc.value) - .toBe("assets/icons/new-icon.svg"); - const addObjectiveIcon = fixture.debugElement.query(By.css("[data-testId=\"add-objective-icon\"]")); - expect(addObjectiveIcon.attributes["src"]) - .toBe("assets/icons/new-icon.svg"); + .toBe('assets/icons/new-icon.svg'); + const addObjectiveIcon = fixture.debugElement.query(By.css('[data-testId="add-objective-icon"]')); + expect(addObjectiveIcon.attributes['src']) + .toBe('assets/icons/new-icon.svg'); }); }); diff --git a/frontend/src/app/components/team/team.component.ts b/frontend/src/app/components/team/team.component.ts index 814fa28653..6e86c8f7fb 100644 --- a/frontend/src/app/components/team/team.component.ts +++ b/frontend/src/app/components/team/team.component.ts @@ -1,33 +1,33 @@ -import { ChangeDetectionStrategy, Component, Input, TrackByFunction } from "@angular/core"; -import { OverviewEntity } from "../../shared/types/model/OverviewEntity"; -import { ObjectiveFormComponent } from "../../shared/dialog/objective-dialog/objective-form.component"; -import { RefreshDataService } from "../../services/refresh-data.service"; -import { Objective } from "../../shared/types/model/Objective"; -import { KeyresultDialogComponent } from "../keyresult-dialog/keyresult-dialog.component"; -import { ObjectiveMin } from "../../shared/types/model/ObjectiveMin"; -import { DialogService } from "../../services/dialog.service"; -import { ConfigService } from "../../services/config.service"; -import { ClientConfig } from "../../shared/types/model/ClientConfig"; -import { BehaviorSubject, first } from "rxjs"; +import { ChangeDetectionStrategy, Component, Input, TrackByFunction } from '@angular/core'; +import { OverviewEntity } from '../../shared/types/model/OverviewEntity'; +import { ObjectiveFormComponent } from '../../shared/dialog/objective-dialog/objective-form.component'; +import { RefreshDataService } from '../../services/refresh-data.service'; +import { Objective } from '../../shared/types/model/Objective'; +import { KeyresultDialogComponent } from '../keyresult-dialog/keyresult-dialog.component'; +import { ObjectiveMin } from '../../shared/types/model/ObjectiveMin'; +import { DialogService } from '../../services/dialog.service'; +import { ConfigService } from '../../services/config.service'; +import { ClientConfig } from '../../shared/types/model/ClientConfig'; +import { BehaviorSubject, first } from 'rxjs'; @Component({ - selector: "app-team", - templateUrl: "./team.component.html", - styleUrls: ["./team.component.scss"], + selector: 'app-team', + templateUrl: './team.component.html', + styleUrls: ['./team.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class TeamComponent { @Input({ required: true }) public overviewEntity!: OverviewEntity; - addIconSrc = new BehaviorSubject("assets/icons/new-icon.svg"); + addIconSrc = new BehaviorSubject('assets/icons/new-icon.svg'); constructor(private dialogService: DialogService, private refreshDataService: RefreshDataService, private configService: ConfigService) { this.configService.config$.pipe(first()) .subscribe((config: ClientConfig) => { - const configuredIconSrc = config.customStyles["okr-add-objective-icon"]; + const configuredIconSrc = config.customStyles['okr-add-objective-icon']; if (configuredIconSrc) this.addIconSrc.next(configuredIconSrc); }); } diff --git a/frontend/src/app/guards/auth.guard.spec.ts b/frontend/src/app/guards/auth.guard.spec.ts index a2d21cb3a9..5687143c4d 100644 --- a/frontend/src/app/guards/auth.guard.spec.ts +++ b/frontend/src/app/guards/auth.guard.spec.ts @@ -1,9 +1,9 @@ -import { TestBed } from "@angular/core/testing"; -import { CanActivateFn, Router } from "@angular/router"; +import { TestBed } from '@angular/core/testing'; +import { CanActivateFn, Router } from '@angular/router'; -import { authGuard } from "./auth.guard"; -import { OAuthService } from "angular-oauth2-oidc"; -import { of } from "rxjs"; +import { authGuard } from './auth.guard'; +import { OAuthService } from 'angular-oauth2-oidc'; +import { of } from 'rxjs'; const oAuthMock = { initCodeFlow: jest.fn(), @@ -18,7 +18,7 @@ const routerMock = { const route = { queryParamMap: new Map() }; -describe("authGuard", () => { +describe('authGuard', () => { const executeGuard: CanActivateFn = (...guardParameters) => TestBed.runInInjectionContext(() => authGuard(...guardParameters)); beforeEach(() => { @@ -32,13 +32,13 @@ describe("authGuard", () => { useValue: routerMock }] }); - jest.spyOn(oAuthMock, "initCodeFlow") + jest.spyOn(oAuthMock, 'initCodeFlow') .mockReturnValue(true); - jest.spyOn(oAuthMock, "loadDiscoveryDocumentAndTryLogin") + jest.spyOn(oAuthMock, 'loadDiscoveryDocumentAndTryLogin') .mockReturnValue(Promise.resolve(true)); - jest.spyOn(oAuthMock, "setupAutomaticSilentRefresh") + jest.spyOn(oAuthMock, 'setupAutomaticSilentRefresh') .mockReturnValue(true); - jest.spyOn(routerMock, "navigateByUrl") + jest.spyOn(routerMock, 'navigateByUrl') .mockReturnValue(of() .toPromise()); oAuthMock.initCodeFlow.mockReset(); @@ -46,15 +46,15 @@ describe("authGuard", () => { routerMock.navigateByUrl.mockReset(); }); - it("should be created", () => { + it('should be created', () => { expect(executeGuard) .toBeTruthy(); }); - it("should not call initCodeFlow if token is valid and call router if state param exist", async() => { - jest.spyOn(oAuthMock, "hasValidIdToken") + it('should not call initCodeFlow if token is valid and call router if state param exist', async() => { + jest.spyOn(oAuthMock, 'hasValidIdToken') .mockReturnValue(true); - route.queryParamMap.set("state", 1234); + route.queryParamMap.set('state', 1234); const result = await runAuthGuardWithContext(authGuard); @@ -70,10 +70,10 @@ describe("authGuard", () => { .toHaveBeenCalled(); }); - it("should not call router if state param does not exist", async() => { - jest.spyOn(oAuthMock, "hasValidIdToken") + it('should not call router if state param does not exist', async() => { + jest.spyOn(oAuthMock, 'hasValidIdToken') .mockReturnValue(true); - route.queryParamMap.set("state", null); + route.queryParamMap.set('state', null); const result = await runAuthGuardWithContext(authGuard); @@ -82,8 +82,8 @@ describe("authGuard", () => { expect(routerMock.navigateByUrl).not.toHaveBeenCalled(); }); - it("should call initCodeFlow if token is invalid", async() => { - jest.spyOn(oAuthMock, "hasValidIdToken") + it('should call initCodeFlow if token is invalid', async() => { + jest.spyOn(oAuthMock, 'hasValidIdToken') .mockReturnValue(false); const result = await runAuthGuardWithContext(authGuard); diff --git a/frontend/src/app/guards/auth.guard.ts b/frontend/src/app/guards/auth.guard.ts index 779848683a..cbccbc8166 100644 --- a/frontend/src/app/guards/auth.guard.ts +++ b/frontend/src/app/guards/auth.guard.ts @@ -1,6 +1,6 @@ -import { CanActivateFn, Router } from "@angular/router"; -import { inject } from "@angular/core"; -import { OAuthService } from "angular-oauth2-oidc"; +import { CanActivateFn, Router } from '@angular/router'; +import { inject } from '@angular/core'; +import { OAuthService } from 'angular-oauth2-oidc'; export const authGuard: CanActivateFn = (route, state) => { const oauthService = inject(OAuthService); @@ -15,8 +15,8 @@ export const authGuard: CanActivateFn = (route, state) => { } oauthService.setupAutomaticSilentRefresh(); // redirect route to remove state query param. do it only, if this param exist to avoid infinite loop - if (route.queryParamMap.get("state")) { - await router.navigateByUrl(""); + if (route.queryParamMap.get('state')) { + await router.navigateByUrl(''); return false; } return true; diff --git a/frontend/src/app/interceptors/error-interceptor.service.ts b/frontend/src/app/interceptors/error-interceptor.service.ts index c0496d5ef1..8386c3a1aa 100644 --- a/frontend/src/app/interceptors/error-interceptor.service.ts +++ b/frontend/src/app/interceptors/error-interceptor.service.ts @@ -1,18 +1,18 @@ -import { Injectable } from "@angular/core"; -import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from "@angular/common/http"; -import { catchError, filter, Observable, tap, throwError } from "rxjs"; -import { Router } from "@angular/router"; +import { Injectable } from '@angular/core'; +import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http'; +import { catchError, filter, Observable, tap, throwError } from 'rxjs'; +import { Router } from '@angular/router'; import { DRAWER_ROUTES, ERROR_MESSAGE_KEY_PREFIX, GJ_REGEX_PATTERN, SUCCESS_MESSAGE_KEY_PREFIX, SUCCESS_MESSAGE_MAP -} from "../shared/constantLibary"; -import { ToasterService } from "../services/toaster.service"; -import { TranslateService } from "@ngx-translate/core"; -import { HttpType } from "../shared/types/enums/HttpType"; -import { ToasterType } from "../shared/types/enums/ToasterType"; +} from '../shared/constantLibary'; +import { ToasterService } from '../services/toaster.service'; +import { TranslateService } from '@ngx-translate/core'; +import { HttpType } from '../shared/types/enums/HttpType'; +import { ToasterType } from '../shared/types/enums/ToasterType'; @Injectable() export class ErrorInterceptor implements HttpInterceptor { @@ -45,7 +45,7 @@ export class ErrorInterceptor implements HttpInterceptor { handleDrawerError(request: any) { if (DRAWER_ROUTES.some((route) => request.url.includes(route))) { - this.router.navigate([""]); + this.router.navigate(['']); } } @@ -55,8 +55,8 @@ export class ErrorInterceptor implements HttpInterceptor { let messageKey = successMessageObj.key; const isBacklogQuarter = !GJ_REGEX_PATTERN.test(response.body?.quarterLabel); - if (messageKey == "OBJECTIVE.POST" && isBacklogQuarter) { - messageKey += "_BACKLOG"; + if (messageKey == 'OBJECTIVE.POST' && isBacklogQuarter) { + messageKey += '_BACKLOG'; } const message = this.translate.instant(SUCCESS_MESSAGE_KEY_PREFIX + messageKey); this.toasterService.showCustomToaster(message, successMessageObj.toasterType); @@ -71,12 +71,12 @@ export class ErrorInterceptor implements HttpInterceptor { if (toasterMessage.method == method) { for (const codeKey of toasterMessage.keysForCode || []) { if (codeKey.code == statusCode) { - const messageKey = value.KEY + "." + codeKey.key; + const messageKey = value.KEY + '.' + codeKey.key; return { key: messageKey, toasterType: codeKey.toaster }; } } - const messageKey = value.KEY + "." + method; + const messageKey = value.KEY + '.' + method; return { key: messageKey, toasterType: ToasterType.SUCCESS }; } @@ -87,6 +87,6 @@ export class ErrorInterceptor implements HttpInterceptor { checkForToaster(response: any): boolean { const requestURL = new URL(response.url); - return window.location.hostname == requestURL.hostname && requestURL.pathname.startsWith("/api"); + return window.location.hostname == requestURL.hostname && requestURL.pathname.startsWith('/api'); } } diff --git a/frontend/src/app/interceptors/error.interceptor.spec.ts b/frontend/src/app/interceptors/error.interceptor.spec.ts index f3fba4d646..8131a8896e 100644 --- a/frontend/src/app/interceptors/error.interceptor.spec.ts +++ b/frontend/src/app/interceptors/error.interceptor.spec.ts @@ -1,14 +1,14 @@ -import { TestBed } from "@angular/core/testing"; -import { ErrorInterceptor } from "./error-interceptor.service"; -import { ToasterService } from "../services/toaster.service"; -import { TranslateModule, TranslateService } from "@ngx-translate/core"; -import { Router } from "@angular/router"; -import { ToastrModule } from "ngx-toastr"; -import "../../global"; -import { HttpType } from "../shared/types/enums/HttpType"; -import { ToasterType } from "../shared/types/enums/ToasterType"; +import { TestBed } from '@angular/core/testing'; +import { ErrorInterceptor } from './error-interceptor.service'; +import { ToasterService } from '../services/toaster.service'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { Router } from '@angular/router'; +import { ToastrModule } from 'ngx-toastr'; +import '../../global'; +import { HttpType } from '../shared/types/enums/HttpType'; +import { ToasterType } from '../shared/types/enums/ToasterType'; -describe("ErrorInterceptor", () => { +describe('ErrorInterceptor', () => { let interceptor: ErrorInterceptor; let router: Router; let translator: TranslateService; @@ -28,19 +28,19 @@ describe("ErrorInterceptor", () => { toaster = TestBed.inject(ToasterService); }); - it("should be created", () => { + it('should be created', () => { expect(interceptor) .toBeTruthy(); }); - it.each([["test", + it.each([['test', 0], - ["objective", + ['objective', 1], - ["keyresult", - 1]])("handleDrawerError on route %p should be called %p times", (url: string, isCalledTimes: number) => { + ['keyresult', + 1]])('handleDrawerError on route %p should be called %p times', (url: string, isCalledTimes: number) => { const requestMock = { url: url }; - jest.spyOn(router, "navigate"); + jest.spyOn(router, 'navigate'); interceptor.handleDrawerError(requestMock); @@ -48,14 +48,14 @@ describe("ErrorInterceptor", () => { .toHaveBeenCalledTimes(isCalledTimes); }); - it.each([["NOT_AUTHORIZED_TO_READ", - ["Objective"]], - ["NOT_AUTHORIZED_TO_WRITE", - ["Check-in"]]])("handleErrorToaster should show correct toaster", (key: string, params: string[]) => { - const ERROR_PREFIX = "ERROR."; - jest.spyOn(translator, "instant"); - jest.spyOn(toaster, "showError"); - jest.spyOn(String.prototype, "format"); + it.each([['NOT_AUTHORIZED_TO_READ', + ['Objective']], + ['NOT_AUTHORIZED_TO_WRITE', + ['Check-in']]])('handleErrorToaster should show correct toaster', (key: string, params: string[]) => { + const ERROR_PREFIX = 'ERROR.'; + jest.spyOn(translator, 'instant'); + jest.spyOn(toaster, 'showError'); + jest.spyOn(String.prototype, 'format'); const requestMock = { error: { errors: [{ @@ -75,36 +75,36 @@ describe("ErrorInterceptor", () => { }); it.each([[ - "/objective/1", + '/objective/1', 200, HttpType.POST, - "OBJECTIVE", + 'OBJECTIVE', ToasterType.SUCCESS, - "Objective erstellt" + 'Objective erstellt' ], [ - "/keyresult/1", + '/keyresult/1', 200, HttpType.PUT, - "KEYRESULT", + 'KEYRESULT', ToasterType.SUCCESS, - "Keyresult wurde aktualisiert" + 'Keyresult wurde aktualisiert' ], [ - "/keyresult/1", + '/keyresult/1', 200, HttpType.DELETE, - "KEYRESULT", + 'KEYRESULT', ToasterType.SUCCESS, - "Keyresult wurde gelöscht" - ]])("handleSuccessToaster should show toaster ", ( + 'Keyresult wurde gelöscht' + ]])('handleSuccessToaster should show toaster ', ( url: string, code: number, method: HttpType, key: string, toasterType: ToasterType, message: string ) => { - const SUCCESS_PREFIX = "SUCCESS."; - jest.spyOn(translator, "instant") + const SUCCESS_PREFIX = 'SUCCESS.'; + jest.spyOn(translator, 'instant') .mockReturnValue(message); - jest.spyOn(toaster, "showCustomToaster"); - jest.spyOn(interceptor, "getSuccessMessageKey") + jest.spyOn(toaster, 'showCustomToaster'); + jest.spyOn(interceptor, 'getSuccessMessageKey') .mockReturnValue({ key: key, toasterType: toasterType }); @@ -123,26 +123,26 @@ describe("ErrorInterceptor", () => { }); it.each([[ - "/objective/1", + '/objective/1', 200, HttpType.GET, - "OBJECTIVE" + 'OBJECTIVE' ], [ - "/keyresult/1", + '/keyresult/1', 200, HttpType.GET, - "KEYRESULT" + 'KEYRESULT' ], [ - "/keyresult/1", + '/keyresult/1', 200, HttpType.GET, - "KEYRESULT" - ]])("handleSuccessToaster should not show toaster ", (url: string, code: number, method: HttpType) => { - jest.spyOn(translator, "instant"); - jest.spyOn(toaster, "showCustomToaster"); - jest.spyOn(interceptor, "getSuccessMessageKey") + 'KEYRESULT' + ]])('handleSuccessToaster should not show toaster ', (url: string, code: number, method: HttpType) => { + jest.spyOn(translator, 'instant'); + jest.spyOn(toaster, 'showCustomToaster'); + jest.spyOn(interceptor, 'getSuccessMessageKey') .mockReturnValue(undefined); const requestMock = { @@ -162,130 +162,130 @@ describe("ErrorInterceptor", () => { it.each([ [ - "/teams/1", + '/teams/1', 200, HttpType.GET, undefined ], [ - "/teams/1", + '/teams/1', 200, HttpType.PUT, - { key: "TEAM.PUT", + { key: 'TEAM.PUT', toasterType: ToasterType.SUCCESS } ], [ - "/teams/1", + '/teams/1', 200, HttpType.POST, - { key: "TEAM.POST", + { key: 'TEAM.POST', toasterType: ToasterType.SUCCESS } ], [ - "/teams/1", + '/teams/1', 200, HttpType.DELETE, - { key: "TEAM.DELETE", + { key: 'TEAM.DELETE', toasterType: ToasterType.SUCCESS } ], [ - "/objectives/1", + '/objectives/1', 200, HttpType.GET, undefined ], [ - "/objectives/1", + '/objectives/1', 200, HttpType.PUT, - { key: "OBJECTIVE.PUT", + { key: 'OBJECTIVE.PUT', toasterType: ToasterType.SUCCESS } ], [ - "/objectives/1", + '/objectives/1', 200, HttpType.POST, - { key: "OBJECTIVE.POST", + { key: 'OBJECTIVE.POST', toasterType: ToasterType.SUCCESS } ], [ - "/objectives/1", + '/objectives/1', 200, HttpType.DELETE, - { key: "OBJECTIVE.DELETE", + { key: 'OBJECTIVE.DELETE', toasterType: ToasterType.SUCCESS } ], [ - "/objectives/1", + '/objectives/1', 226, HttpType.PUT, - { key: "OBJECTIVE.IM_USED", + { key: 'OBJECTIVE.IM_USED', toasterType: ToasterType.WARN } ], [ - "/keyresults/1", + '/keyresults/1', 200, HttpType.GET, undefined ], [ - "/keyresults/1", + '/keyresults/1', 200, HttpType.PUT, - { key: "KEY_RESULT.PUT", + { key: 'KEY_RESULT.PUT', toasterType: ToasterType.SUCCESS } ], [ - "/keyresults/1", + '/keyresults/1', 200, HttpType.POST, - { key: "KEY_RESULT.POST", + { key: 'KEY_RESULT.POST', toasterType: ToasterType.SUCCESS } ], [ - "/keyresults/1", + '/keyresults/1', 200, HttpType.DELETE, - { key: "KEY_RESULT.DELETE", + { key: 'KEY_RESULT.DELETE', toasterType: ToasterType.SUCCESS } ], [ - "/keyresults/1", + '/keyresults/1', 226, HttpType.PUT, - { key: "KEY_RESULT.IM_USED", + { key: 'KEY_RESULT.IM_USED', toasterType: ToasterType.WARN } ], [ - "/checkIns/1", + '/checkIns/1', 200, HttpType.GET, undefined ], [ - "/checkIns/1", + '/checkIns/1', 200, HttpType.PUT, - { key: "CHECK_IN.PUT", + { key: 'CHECK_IN.PUT', toasterType: ToasterType.SUCCESS } ], [ - "/checkIns/1", + '/checkIns/1', 200, HttpType.POST, - { key: "CHECK_IN.POST", + { key: 'CHECK_IN.POST', toasterType: ToasterType.SUCCESS } ], [ - "/checkIns/1", + '/checkIns/1', 200, HttpType.DELETE, undefined ] - ])("getSuccessMessageKey should work", ( + ])('getSuccessMessageKey should work', ( url: string, code: number, method: HttpType, result: any ) => { const successMessageKey = interceptor.getSuccessMessageKey(url, code, method); @@ -293,15 +293,15 @@ describe("ErrorInterceptor", () => { .toStrictEqual(result); }); - it.each([["http://localhost:4200/", - "http://localhost:4200/api/objecive/1", + it.each([['http://localhost:4200/', + 'http://localhost:4200/api/objecive/1', true], - ["http://localhost:4200/", - "http://habasch:4200/api/objecive/1", + ['http://localhost:4200/', + 'http://habasch:4200/api/objecive/1', false], - ["http://localhost:4200/", - "http://habasch:4200/objecive/1", - false]])("checkIfSuccessToasterIsShown should work as intended", (currentURL: string, requestURL: string, result: boolean) => { + ['http://localhost:4200/', + 'http://habasch:4200/objecive/1', + false]])('checkIfSuccessToasterIsShown should work as intended', (currentURL: string, requestURL: string, result: boolean) => { const requestMock = { url: requestURL }; window.location.assign(currentURL); @@ -310,29 +310,29 @@ describe("ErrorInterceptor", () => { .toBe(result); }); - it("should return custom success message on objective creation in backlog", () => { - jest.spyOn(translator, "instant") - .mockReturnValue("Das Objective wurde als Draft im Backlog gespeichert."); - jest.spyOn(toaster, "showCustomToaster"); - jest.spyOn(interceptor, "getSuccessMessageKey") - .mockReturnValue({ key: "OBJECTIVE.POST", + it('should return custom success message on objective creation in backlog', () => { + jest.spyOn(translator, 'instant') + .mockReturnValue('Das Objective wurde als Draft im Backlog gespeichert.'); + jest.spyOn(toaster, 'showCustomToaster'); + jest.spyOn(interceptor, 'getSuccessMessageKey') + .mockReturnValue({ key: 'OBJECTIVE.POST', toasterType: undefined }); const mockHttpResponse = { - url: "\"http://localhost:4200/api/v2/objectives\"", + url: '"http://localhost:4200/api/v2/objectives"', status: 201, - statusText: "Created", + statusText: 'Created', ok: true, body: { - objectiveTitle: "Das ist der Titel", + objectiveTitle: 'Das ist der Titel', quarterId: 999 } }; interceptor.handleSuccessToaster(mockHttpResponse, HttpType.POST); expect(translator.instant) - .toBeCalledWith("SUCCESS.OBJECTIVE.POST_BACKLOG"); + .toBeCalledWith('SUCCESS.OBJECTIVE.POST_BACKLOG'); expect(toaster.showCustomToaster) - .toBeCalledWith("Das Objective wurde als Draft im Backlog gespeichert.", undefined); + .toBeCalledWith('Das Objective wurde als Draft im Backlog gespeichert.', undefined); }); }); diff --git a/frontend/src/app/interceptors/oauth.interceptor.spec.ts b/frontend/src/app/interceptors/oauth.interceptor.spec.ts index 65b11cdf3d..23c1370842 100644 --- a/frontend/src/app/interceptors/oauth.interceptor.spec.ts +++ b/frontend/src/app/interceptors/oauth.interceptor.spec.ts @@ -1,10 +1,10 @@ -import { TestBed } from "@angular/core/testing"; +import { TestBed } from '@angular/core/testing'; -import { OauthInterceptor } from "./oauth.interceptor"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { DateTimeProvider, OAuthLogger, OAuthService, UrlHelperService } from "angular-oauth2-oidc"; +import { OauthInterceptor } from './oauth.interceptor'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { DateTimeProvider, OAuthLogger, OAuthService, UrlHelperService } from 'angular-oauth2-oidc'; -describe("OauthInterceptor", () => { +describe('OauthInterceptor', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [ @@ -16,7 +16,7 @@ describe("OauthInterceptor", () => { ] })); - it("should be created", () => { + it('should be created', () => { const interceptor: OauthInterceptor = TestBed.inject(OauthInterceptor); expect(interceptor) .toBeTruthy(); diff --git a/frontend/src/app/interceptors/oauth.interceptor.ts b/frontend/src/app/interceptors/oauth.interceptor.ts index 29c4194a57..03e18cc6d1 100644 --- a/frontend/src/app/interceptors/oauth.interceptor.ts +++ b/frontend/src/app/interceptors/oauth.interceptor.ts @@ -1,10 +1,10 @@ -import { Injectable } from "@angular/core"; -import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http"; -import { filter, map, merge, mergeMap, Observable, of, take, timeout } from "rxjs"; -import { OAuthService } from "angular-oauth2-oidc"; +import { Injectable } from '@angular/core'; +import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; +import { filter, map, merge, mergeMap, Observable, of, take, timeout } from 'rxjs'; +import { OAuthService } from 'angular-oauth2-oidc'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class OauthInterceptor implements HttpInterceptor { constructor(private oauthService: OAuthService) {} @@ -15,11 +15,11 @@ export class OauthInterceptor implements HttpInterceptor { } return merge(of(this.oauthService.getAccessToken()) - .pipe(filter((token) => !!token)), this.oauthService.events.pipe(filter((e) => e.type === "token_received"), timeout(500), map((_) => this.oauthService.getAccessToken()))) + .pipe(filter((token) => !!token)), this.oauthService.events.pipe(filter((e) => e.type === 'token_received'), timeout(500), map((_) => this.oauthService.getAccessToken()))) .pipe(take(1), mergeMap((token) => { if (token) { - const header = "Bearer " + token; - const headers = req.headers.set("Authorization", header); + const header = 'Bearer ' + token; + const headers = req.headers.set('Authorization', header); req = req.clone({ headers }); } diff --git a/frontend/src/app/services/action.service.spec.ts b/frontend/src/app/services/action.service.spec.ts index c2ff89b0e4..d1fe965b63 100644 --- a/frontend/src/app/services/action.service.spec.ts +++ b/frontend/src/app/services/action.service.spec.ts @@ -1,8 +1,8 @@ -import { TestBed } from "@angular/core/testing"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { ActionService } from "./action.service"; +import { TestBed } from '@angular/core/testing'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { ActionService } from './action.service'; -describe("ActionService", () => { +describe('ActionService', () => { let service: ActionService; beforeEach(() => { @@ -12,7 +12,7 @@ describe("ActionService", () => { service = TestBed.inject(ActionService); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); diff --git a/frontend/src/app/services/action.service.ts b/frontend/src/app/services/action.service.ts index cbe2aeb497..55599c73f4 100644 --- a/frontend/src/app/services/action.service.ts +++ b/frontend/src/app/services/action.service.ts @@ -1,16 +1,16 @@ -import { Injectable } from "@angular/core"; -import { HttpClient } from "@angular/common/http"; -import { Observable } from "rxjs"; -import { Action } from "../shared/types/model/Action"; +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { Action } from '../shared/types/model/Action'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class ActionService { constructor(private httpClient: HttpClient) {} updateActions(actionList: Action[]): Observable { - return this.httpClient.put("/api/v2/action", actionList); + return this.httpClient.put('/api/v2/action', actionList); } deleteAction(actionId: number): Observable { diff --git a/frontend/src/app/services/check-in.service.spec.ts b/frontend/src/app/services/check-in.service.spec.ts index 6cf2740cff..611e08a121 100644 --- a/frontend/src/app/services/check-in.service.spec.ts +++ b/frontend/src/app/services/check-in.service.spec.ts @@ -1,11 +1,11 @@ -import { TestBed } from "@angular/core/testing"; +import { TestBed } from '@angular/core/testing'; -import { CheckInService } from "./check-in.service"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { firstCheckIn, keyResultMetricWithIdEight, secondCheckIn } from "../shared/testData"; -import { CheckInMetricMin } from "../shared/types/model/CheckInMetricMin"; +import { CheckInService } from './check-in.service'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { firstCheckIn, keyResultMetricWithIdEight, secondCheckIn } from '../shared/testData'; +import { CheckInMetricMin } from '../shared/types/model/CheckInMetricMin'; -describe("CheckInService", () => { +describe('CheckInService', () => { let service: CheckInService; beforeEach(() => { @@ -15,12 +15,12 @@ describe("CheckInService", () => { service = TestBed.inject(CheckInService); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); - it("should map correctly", () => { + it('should map correctly', () => { service.getAllCheckInOfKeyResult(keyResultMetricWithIdEight.id) .subscribe((checkIns) => { // Check first CheckIn of this KeyResult diff --git a/frontend/src/app/services/check-in.service.ts b/frontend/src/app/services/check-in.service.ts index a9cd986764..873e31be05 100644 --- a/frontend/src/app/services/check-in.service.ts +++ b/frontend/src/app/services/check-in.service.ts @@ -1,11 +1,11 @@ -import { Injectable } from "@angular/core"; -import { HttpClient } from "@angular/common/http"; -import { CheckInMin } from "../shared/types/model/CheckInMin"; -import { Observable } from "rxjs"; -import { CheckIn } from "../shared/types/model/CheckIn"; +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { CheckInMin } from '../shared/types/model/CheckInMin'; +import { Observable } from 'rxjs'; +import { CheckIn } from '../shared/types/model/CheckIn'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class CheckInService { constructor(private httpclient: HttpClient) {} @@ -16,9 +16,9 @@ export class CheckInService { saveCheckIn(checkIn: CheckIn) { if (checkIn.id) { - return this.httpclient.put("/api/v2/checkIns/" + checkIn.id, checkIn); + return this.httpclient.put('/api/v2/checkIns/' + checkIn.id, checkIn); } else { - return this.httpclient.post("/api/v2/checkIns", checkIn); + return this.httpclient.post('/api/v2/checkIns', checkIn); } } } diff --git a/frontend/src/app/services/completed.servce.ts b/frontend/src/app/services/completed.servce.ts index 79ea644e6b..5cfd95f666 100644 --- a/frontend/src/app/services/completed.servce.ts +++ b/frontend/src/app/services/completed.servce.ts @@ -1,19 +1,19 @@ -import { Injectable } from "@angular/core"; -import { HttpClient } from "@angular/common/http"; -import { Observable } from "rxjs"; -import { Completed } from "../shared/types/model/Completed"; +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { Completed } from '../shared/types/model/Completed'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class CompletedService { constructor(private httpClient: HttpClient) {} createCompleted(completed: Completed): Observable { - return this.httpClient.post("/api/v2/completed", completed); + return this.httpClient.post('/api/v2/completed', completed); } deleteCompleted(objectiveId: number): Observable { - return this.httpClient.delete("/api/v2/completed/" + objectiveId); + return this.httpClient.delete('/api/v2/completed/' + objectiveId); } } diff --git a/frontend/src/app/services/completed.service.spec.ts b/frontend/src/app/services/completed.service.spec.ts index d3e39f7979..995a6f8546 100644 --- a/frontend/src/app/services/completed.service.spec.ts +++ b/frontend/src/app/services/completed.service.spec.ts @@ -1,8 +1,8 @@ -import { TestBed } from "@angular/core/testing"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { CompletedService } from "./completed.servce"; +import { TestBed } from '@angular/core/testing'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { CompletedService } from './completed.servce'; -describe("CompletedService", () => { +describe('CompletedService', () => { let service: CompletedService; beforeEach(() => { @@ -12,7 +12,7 @@ describe("CompletedService", () => { service = TestBed.inject(CompletedService); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); diff --git a/frontend/src/app/services/config.service.spec.ts b/frontend/src/app/services/config.service.spec.ts index 9299ee9424..36f9aff60b 100644 --- a/frontend/src/app/services/config.service.spec.ts +++ b/frontend/src/app/services/config.service.spec.ts @@ -1,9 +1,9 @@ -import { TestBed } from "@angular/core/testing"; +import { TestBed } from '@angular/core/testing'; -import { ConfigService } from "./config.service"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; +import { ConfigService } from './config.service'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; -describe("ConfigService", () => { +describe('ConfigService', () => { let service: ConfigService; beforeEach(() => { @@ -13,7 +13,7 @@ describe("ConfigService", () => { service = TestBed.inject(ConfigService); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); diff --git a/frontend/src/app/services/config.service.ts b/frontend/src/app/services/config.service.ts index e84f28aad3..4d128def97 100644 --- a/frontend/src/app/services/config.service.ts +++ b/frontend/src/app/services/config.service.ts @@ -1,16 +1,16 @@ -import { Injectable } from "@angular/core"; -import { HttpClient } from "@angular/common/http"; -import { Observable, shareReplay } from "rxjs"; -import { ClientConfig } from "../shared/types/model/ClientConfig"; +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable, shareReplay } from 'rxjs'; +import { ClientConfig } from '../shared/types/model/ClientConfig'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class ConfigService { public config$: Observable; constructor(private httpClient: HttpClient) { - this.config$ = this.httpClient.get("/config") + this.config$ = this.httpClient.get('/config') .pipe(shareReplay()); } } diff --git a/frontend/src/app/services/customization.service.spec.ts b/frontend/src/app/services/customization.service.spec.ts index 7bef700a4f..e6130449df 100644 --- a/frontend/src/app/services/customization.service.spec.ts +++ b/frontend/src/app/services/customization.service.spec.ts @@ -1,7 +1,7 @@ -import { CustomizationService } from "./customization.service"; -import { BehaviorSubject } from "rxjs"; -import { ClientConfig } from "../shared/types/model/ClientConfig"; -import { ConfigService } from "./config.service"; +import { CustomizationService } from './customization.service'; +import { BehaviorSubject } from 'rxjs'; +import { ClientConfig } from '../shared/types/model/ClientConfig'; +import { ConfigService } from './config.service'; class CallRecorder { private calls: Record = {}; @@ -26,18 +26,18 @@ class CallRecorder { } } -describe("CustomizationService", () => { +describe('CustomizationService', () => { const body: ClientConfig = { - activeProfile: "test", - issuer: "some-issuer.com", - clientId: "my-client-id", - title: "title", - favicon: "favicon", - logo: "logo", - triangles: "triangles", - backgroundLogo: "backgroundLogo", - helpSiteUrl: "https://wiki.puzzle.ch/Puzzle/OKRs", - customStyles: { cssVar1: "foo" } + activeProfile: 'test', + issuer: 'some-issuer.com', + clientId: 'my-client-id', + title: 'title', + favicon: 'favicon', + logo: 'logo', + triangles: 'triangles', + backgroundLogo: 'backgroundLogo', + helpSiteUrl: 'https://wiki.puzzle.ch/Puzzle/OKRs', + customStyles: { cssVar1: 'foo' } }; let service: CustomizationService; @@ -80,7 +80,7 @@ describe("CustomizationService", () => { service = new CustomizationService(configServiceMock, documentMock); }); - it("should call correct apis when config is ready", () => { + it('should call correct apis when config is ready', () => { const currentConfig = service.getCurrentConfig(); expect(currentConfig?.title) .toBe(body.title); @@ -94,42 +94,42 @@ describe("CustomizationService", () => { .toBe(body.backgroundLogo); expect(currentConfig?.helpSiteUrl) .toBe(body.helpSiteUrl); - expect(currentConfig?.customStyles["cssVar1"]) - .toBe(body.customStyles["cssVar1"]); + expect(currentConfig?.customStyles['cssVar1']) + .toBe(body.customStyles['cssVar1']); - expect(callRecorder.getCallCount("title.innerHTML")) + expect(callRecorder.getCallCount('title.innerHTML')) .toBe(1); - expect(callRecorder.getCallCount("favicon-setAttribute")) + expect(callRecorder.getCallCount('favicon-setAttribute')) .toBe(1); - expect(callRecorder.getCallCount("html.style.setProperty")) + expect(callRecorder.getCallCount('html.style.setProperty')) .toBe(1); - expect(callRecorder.getCallCount("html.style.removeProperty")) + expect(callRecorder.getCallCount('html.style.removeProperty')) .toBe(0); - expect(callRecorder.getCallByIdx("title.innerHTML", 0)[0]) - .toBe("title"); - expect(callRecorder.getCallByIdx("favicon-setAttribute", 0)[0]) - .toBe("href"); - expect(callRecorder.getCallByIdx("favicon-setAttribute", 0)[1]) - .toBe("favicon"); - expect(callRecorder.getCallByIdx("html.style.setProperty", 0)[0]) - .toBe("--cssVar1"); - expect(callRecorder.getCallByIdx("html.style.setProperty", 0)[1]) - .toBe("foo"); + expect(callRecorder.getCallByIdx('title.innerHTML', 0)[0]) + .toBe('title'); + expect(callRecorder.getCallByIdx('favicon-setAttribute', 0)[0]) + .toBe('href'); + expect(callRecorder.getCallByIdx('favicon-setAttribute', 0)[1]) + .toBe('favicon'); + expect(callRecorder.getCallByIdx('html.style.setProperty', 0)[0]) + .toBe('--cssVar1'); + expect(callRecorder.getCallByIdx('html.style.setProperty', 0)[1]) + .toBe('foo'); }); - it("should update if config changed afterwards", () => { + it('should update if config changed afterwards', () => { const bodySecond = { - activeProfile: "test-second", - issuer: "some-issuer.com-second", - clientId: "my-client-id-second", - title: "title-second", - favicon: "favicon-second", - logo: "logo-second", - triangles: "triangles-second", - backgroundLogo: "backgroundLogo-second", - helpSiteUrl: "https://wiki.puzzle.ch/Puzzle/OKRs", - customStyles: { cssVarNew: "bar" } + activeProfile: 'test-second', + issuer: 'some-issuer.com-second', + clientId: 'my-client-id-second', + title: 'title-second', + favicon: 'favicon-second', + logo: 'logo-second', + triangles: 'triangles-second', + backgroundLogo: 'backgroundLogo-second', + helpSiteUrl: 'https://wiki.puzzle.ch/Puzzle/OKRs', + customStyles: { cssVarNew: 'bar' } }; configSubject.next(bodySecond); @@ -146,29 +146,29 @@ describe("CustomizationService", () => { .toBe(bodySecond.backgroundLogo); expect(currentConfig?.helpSiteUrl) .toBe(bodySecond.helpSiteUrl); - expect(currentConfig?.customStyles["cssVarNew"]) - .toBe(bodySecond.customStyles["cssVarNew"]); - expect(currentConfig?.customStyles["cssVar1"]) + expect(currentConfig?.customStyles['cssVarNew']) + .toBe(bodySecond.customStyles['cssVarNew']); + expect(currentConfig?.customStyles['cssVar1']) .toBe(undefined); - expect(callRecorder.getCallCount("title.innerHTML")) + expect(callRecorder.getCallCount('title.innerHTML')) .toBe(2); - expect(callRecorder.getCallCount("favicon-setAttribute")) + expect(callRecorder.getCallCount('favicon-setAttribute')) .toBe(2); - expect(callRecorder.getCallCount("html.style.setProperty")) + expect(callRecorder.getCallCount('html.style.setProperty')) .toBe(2); - expect(callRecorder.getCallCount("html.style.removeProperty")) + expect(callRecorder.getCallCount('html.style.removeProperty')) .toBe(1); - expect(callRecorder.getCallByIdx("title.innerHTML", 1)[0]) - .toBe("title-second"); - expect(callRecorder.getCallByIdx("favicon-setAttribute", 1)[0]) - .toBe("href"); - expect(callRecorder.getCallByIdx("favicon-setAttribute", 1)[1]) - .toBe("favicon-second"); - expect(callRecorder.getCallByIdx("html.style.setProperty", 1)[0]) - .toBe("--cssVarNew"); - expect(callRecorder.getCallByIdx("html.style.setProperty", 1)[1]) - .toBe("bar"); + expect(callRecorder.getCallByIdx('title.innerHTML', 1)[0]) + .toBe('title-second'); + expect(callRecorder.getCallByIdx('favicon-setAttribute', 1)[0]) + .toBe('href'); + expect(callRecorder.getCallByIdx('favicon-setAttribute', 1)[1]) + .toBe('favicon-second'); + expect(callRecorder.getCallByIdx('html.style.setProperty', 1)[0]) + .toBe('--cssVarNew'); + expect(callRecorder.getCallByIdx('html.style.setProperty', 1)[1]) + .toBe('bar'); }); }); diff --git a/frontend/src/app/services/customization.service.ts b/frontend/src/app/services/customization.service.ts index f1e86843b2..6e01f9e189 100644 --- a/frontend/src/app/services/customization.service.ts +++ b/frontend/src/app/services/customization.service.ts @@ -1,10 +1,10 @@ -import { Inject, Injectable } from "@angular/core"; -import { DOCUMENT } from "@angular/common"; -import { CustomizationConfig, CustomStyles } from "../shared/types/model/ClientConfig"; -import { ConfigService } from "./config.service"; +import { Inject, Injectable } from '@angular/core'; +import { DOCUMENT } from '@angular/common'; +import { CustomizationConfig, CustomStyles } from '../shared/types/model/ClientConfig'; +import { ConfigService } from './config.service'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class CustomizationService { private currentConfig?: CustomizationConfig; @@ -37,8 +37,8 @@ export class CustomizationService { return; } - this.document.getElementById("favicon") - ?.setAttribute("href", favicon); + this.document.getElementById('favicon') + ?.setAttribute('href', favicon); } private setTitle(title: string) { @@ -50,7 +50,7 @@ export class CustomizationService { return; } - (this.document.querySelector("title") as HTMLTitleElement).innerHTML = title; + (this.document.querySelector('title') as HTMLTitleElement).innerHTML = title; } private setStyleCustomizations(customStylesMap: CustomStyles) { @@ -75,7 +75,7 @@ export class CustomizationService { return; } - const styles = (this.document.querySelector("html") as HTMLHtmlElement).style; + const styles = (this.document.querySelector('html') as HTMLHtmlElement).style; if (!styles) { return; } @@ -92,7 +92,7 @@ export class CustomizationService { return; } - const styles = (this.document.querySelector("html") as HTMLHtmlElement).style; + const styles = (this.document.querySelector('html') as HTMLHtmlElement).style; if (!styles) { return; } diff --git a/frontend/src/app/services/dialog.service.spec.ts b/frontend/src/app/services/dialog.service.spec.ts index 98cb4fb892..a4abec609a 100644 --- a/frontend/src/app/services/dialog.service.spec.ts +++ b/frontend/src/app/services/dialog.service.spec.ts @@ -1,15 +1,15 @@ -import { TestBed } from "@angular/core/testing"; - -import { ConfirmDialogData, DialogService } from "./dialog.service"; -import { TranslateModule, TranslateService } from "@ngx-translate/core"; -import { MatDialog, MatDialogRef } from "@angular/material/dialog"; -import { ConfirmDialogComponent } from "../shared/dialog/confirm-dialog/confirm-dialog.component"; -import { AddEditTeamDialogComponent } from "../team-management/add-edit-team-dialog/add-edit-team-dialog.component"; -import { provideHttpClientTesting } from "@angular/common/http/testing"; -import { provideHttpClient } from "@angular/common/http"; -import { ButtonState } from "../shared/types/enums/ButtonState"; - -describe("DialogService", () => { +import { TestBed } from '@angular/core/testing'; + +import { ConfirmDialogData, DialogService } from './dialog.service'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { ConfirmDialogComponent } from '../shared/dialog/confirm-dialog/confirm-dialog.component'; +import { AddEditTeamDialogComponent } from '../team-management/add-edit-team-dialog/add-edit-team-dialog.component'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { provideHttpClient } from '@angular/common/http'; +import { ButtonState } from '../shared/types/enums/ButtonState'; + +describe('DialogService', () => { let service: DialogService; let matDialogSpy: MatDialog; let translateServiceSpy: TranslateService; @@ -24,7 +24,7 @@ describe("DialogService", () => { matDialogSpy = TestBed.inject(MatDialog); service = TestBed.inject(DialogService); translateServiceSpy = TestBed.inject(TranslateService); - jest.spyOn(matDialogSpy, "open"); + jest.spyOn(matDialogSpy, 'open'); }); function expectData(current: ConfirmDialogData, expected: ConfirmDialogData) { @@ -68,15 +68,15 @@ describe("DialogService", () => { .toBe(true); } - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); - it("should open dialog", () => { + it('should open dialog', () => { const dialog = service.open(AddEditTeamDialogComponent, { data: { - aProperty: "aValue" + aProperty: 'aValue' } }); expect(dialog) @@ -89,18 +89,18 @@ describe("DialogService", () => { panelClass: service.DIALOG_PANEL_CLASS_DEFAULT, ...service.DIALOG_CONFIG, data: { - aProperty: "aValue" + aProperty: 'aValue' } }); }); - it("should open confirm dialog", () => { + it('should open confirm dialog', () => { const i18nData = { - team: "the a-team" + team: 'the a-team' }; - jest.spyOn(service, "open"); - jest.spyOn(translateServiceSpy, "instant"); - const dialog = service.openConfirmDialog("DELETE.TEAM", i18nData); + jest.spyOn(service, 'open'); + jest.spyOn(translateServiceSpy, 'instant'); + const dialog = service.openConfirmDialog('DELETE.TEAM', i18nData); // Call function of own service expect(service.open) @@ -110,9 +110,9 @@ describe("DialogService", () => { expect(translateServiceSpy.instant) .toHaveBeenCalledTimes(2); expect(translateServiceSpy.instant) - .toHaveBeenCalledWith("DELETE.TEAM.TITLE", i18nData); + .toHaveBeenCalledWith('DELETE.TEAM.TITLE', i18nData); expect(translateServiceSpy.instant) - .toHaveBeenCalledWith("DELETE.TEAM.TEXT", i18nData); + .toHaveBeenCalledWith('DELETE.TEAM.TEXT', i18nData); // Call function of angular material dialog expect(matDialogSpy.open) @@ -120,33 +120,33 @@ describe("DialogService", () => { expect(dialog.componentInstance) .toBeInstanceOf(ConfirmDialogComponent); expect(dialog.componentInstance.data.title) - .toBe("DELETE.TEAM.TITLE"); + .toBe('DELETE.TEAM.TITLE'); expect(dialog.componentInstance.data.text) - .toBe("DELETE.TEAM.TEXT"); + .toBe('DELETE.TEAM.TEXT'); expect(matDialogSpy.open) .toHaveBeenCalledWith(ConfirmDialogComponent, { panelClass: service.DIALOG_PANEL_CLASS_SMALL, ...service.DIALOG_CONFIG, data: { - title: "DELETE.TEAM.TITLE", - text: "DELETE.TEAM.TEXT" + title: 'DELETE.TEAM.TITLE', + text: 'DELETE.TEAM.TEXT' } }); }); - it("should open customized confirm dialog with default visibility properties", () => { + it('should open customized confirm dialog with default visibility properties', () => { // arrange const data: ConfirmDialogData = { - title: "Test title", - text: "Test description", + title: 'Test title', + text: 'Test description', yesButtonState: undefined, noButtonState: undefined, closeButtonState: undefined }; - jest.spyOn(service, "open"); - jest.spyOn(translateServiceSpy, "instant"); + jest.spyOn(service, 'open'); + jest.spyOn(translateServiceSpy, 'instant'); // act const dialog = service.openCustomizedConfirmDialog(data); @@ -177,18 +177,18 @@ describe("DialogService", () => { expectCloseButtonIsHiddenAndEnabled(confirmDialogInstance); }); - it("should open customized confirm dialog with explicit visibility properties", () => { + it('should open customized confirm dialog with explicit visibility properties', () => { // arrange const data: ConfirmDialogData = { - title: "Test title", - text: "Test description", + title: 'Test title', + text: 'Test description', yesButtonState: ButtonState.VisibleEnabled, noButtonState: ButtonState.VisibleDisabled, closeButtonState: ButtonState.Hidden }; - jest.spyOn(service, "open"); - jest.spyOn(translateServiceSpy, "instant"); + jest.spyOn(service, 'open'); + jest.spyOn(translateServiceSpy, 'instant'); // act const dialog = service.openCustomizedConfirmDialog(data); diff --git a/frontend/src/app/services/dialog.service.ts b/frontend/src/app/services/dialog.service.ts index 7693223355..b0d1eb49a2 100644 --- a/frontend/src/app/services/dialog.service.ts +++ b/frontend/src/app/services/dialog.service.ts @@ -1,9 +1,9 @@ -import { Injectable } from "@angular/core"; -import { MatDialog, MatDialogConfig, MatDialogRef } from "@angular/material/dialog"; -import { ComponentType } from "@angular/cdk/overlay"; -import { ConfirmDialogComponent } from "../shared/dialog/confirm-dialog/confirm-dialog.component"; -import { TranslateService } from "@ngx-translate/core"; -import { ButtonState } from "../shared/types/enums/ButtonState"; +import { Injectable } from '@angular/core'; +import { MatDialog, MatDialogConfig, MatDialogRef } from '@angular/material/dialog'; +import { ComponentType } from '@angular/cdk/overlay'; +import { ConfirmDialogComponent } from '../shared/dialog/confirm-dialog/confirm-dialog.component'; +import { TranslateService } from '@ngx-translate/core'; +import { ButtonState } from '../shared/types/enums/ButtonState'; export interface ConfirmDialogData { title: string; @@ -14,17 +14,17 @@ export interface ConfirmDialogData { } @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class DialogService { - DIALOG_PANEL_CLASS_DEFAULT = "okr-dialog-panel-default"; + DIALOG_PANEL_CLASS_DEFAULT = 'okr-dialog-panel-default'; - DIALOG_PANEL_CLASS_SMALL = "okr-dialog-panel-small"; + DIALOG_PANEL_CLASS_SMALL = 'okr-dialog-panel-small'; DIALOG_CONFIG: MatDialogConfig = { - maxWidth: "100vw", // Used to override the default maxWidth of angular material dialog + maxWidth: '100vw', // Used to override the default maxWidth of angular material dialog restoreFocus: true, - autoFocus: "first-tabbable" + autoFocus: 'first-tabbable' }; constructor(private readonly dialog: MatDialog, diff --git a/frontend/src/app/services/keyresult.service.spec.ts b/frontend/src/app/services/keyresult.service.spec.ts index e834ab3db5..b13efe1965 100644 --- a/frontend/src/app/services/keyresult.service.spec.ts +++ b/frontend/src/app/services/keyresult.service.spec.ts @@ -1,9 +1,9 @@ -import { TestBed } from "@angular/core/testing"; +import { TestBed } from '@angular/core/testing'; -import { KeyresultService } from "./keyresult.service"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; +import { KeyresultService } from './keyresult.service'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; -describe("KeyresultService", () => { +describe('KeyresultService', () => { let service: KeyresultService; beforeEach(() => { @@ -11,7 +11,7 @@ describe("KeyresultService", () => { service = TestBed.inject(KeyresultService); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); diff --git a/frontend/src/app/services/keyresult.service.ts b/frontend/src/app/services/keyresult.service.ts index 086e6de029..2f6e90b4a3 100644 --- a/frontend/src/app/services/keyresult.service.ts +++ b/frontend/src/app/services/keyresult.service.ts @@ -1,17 +1,17 @@ -import { Injectable } from "@angular/core"; -import { HttpClient } from "@angular/common/http"; -import { KeyResult } from "../shared/types/model/KeyResult"; -import { map, Observable } from "rxjs"; -import { KeyResultDTO } from "../shared/types/DTOs/KeyResultDTO"; +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { KeyResult } from '../shared/types/model/KeyResult'; +import { map, Observable } from 'rxjs'; +import { KeyResultDTO } from '../shared/types/DTOs/KeyResultDTO'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class KeyresultService { constructor(private httpClient: HttpClient) {} getFullKeyResult(keyresultId: number): Observable { - return this.httpClient.get("/api/v2/keyresults/" + keyresultId) + return this.httpClient.get('/api/v2/keyresults/' + keyresultId) .pipe(map((keyresult: any) => { keyresult.objective.quarter = keyresult.objective.keyResultQuarterDto; return keyresult; @@ -20,13 +20,13 @@ export class KeyresultService { saveKeyResult(keyResultDTO: KeyResultDTO): Observable { if (keyResultDTO.id) { - return this.httpClient.put("/api/v2/keyresults/" + keyResultDTO.id, keyResultDTO); + return this.httpClient.put('/api/v2/keyresults/' + keyResultDTO.id, keyResultDTO); } else { - return this.httpClient.post("/api/v2/keyresults", keyResultDTO); + return this.httpClient.post('/api/v2/keyresults', keyResultDTO); } } deleteKeyResult(keyResultId: number): Observable { - return this.httpClient.delete("/api/v2/keyresults/" + keyResultId); + return this.httpClient.delete('/api/v2/keyresults/' + keyResultId); } } diff --git a/frontend/src/app/services/objective-menu-actions.service.spec.ts b/frontend/src/app/services/objective-menu-actions.service.spec.ts index 91ec0340bf..2f252f5f1d 100644 --- a/frontend/src/app/services/objective-menu-actions.service.spec.ts +++ b/frontend/src/app/services/objective-menu-actions.service.spec.ts @@ -1,15 +1,15 @@ -import { TestBed } from "@angular/core/testing"; +import { TestBed } from '@angular/core/testing'; -import { ObjectiveMenuActionsService } from "./objective-menu-actions.service"; -import { TranslateModule, TranslateService } from "@ngx-translate/core"; -import { provideRouter } from "@angular/router"; -import { provideHttpClient } from "@angular/common/http"; -import { provideHttpClientTesting } from "@angular/common/http/testing"; -import { ObjectiveMin } from "../shared/types/model/ObjectiveMin"; -import { State } from "../shared/types/enums/State"; -import { objectiveMin } from "../shared/testData"; +import { ObjectiveMenuActionsService } from './objective-menu-actions.service'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { provideRouter } from '@angular/router'; +import { provideHttpClient } from '@angular/common/http'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { ObjectiveMin } from '../shared/types/model/ObjectiveMin'; +import { State } from '../shared/types/enums/State'; +import { objectiveMin } from '../shared/testData'; -describe("ObjectiveMenuActionsService", () => { +describe('ObjectiveMenuActionsService', () => { let service: ObjectiveMenuActionsService; let specificMenuEntriesSpy: jest.SpyInstance; @@ -25,17 +25,17 @@ describe("ObjectiveMenuActionsService", () => { }); service = TestBed.inject(ObjectiveMenuActionsService); - specificMenuEntriesSpy = jest.spyOn(service as any, "getSpecificMenuEntries"); + specificMenuEntriesSpy = jest.spyOn(service as any, 'getSpecificMenuEntries'); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); - describe("getMenu", () => { - it("should return default and specific menu entries for an ongoing objective", () => { - const spyOn = jest.spyOn(service as any, "getOngoingMenuActions"); + describe('getMenu', () => { + it('should return default and specific menu entries for an ongoing objective', () => { + const spyOn = jest.spyOn(service as any, 'getOngoingMenuActions'); const objectiveMinLocal: ObjectiveMin = objectiveMin; objectiveMinLocal.state = State.ONGOING; @@ -44,8 +44,8 @@ describe("ObjectiveMenuActionsService", () => { .toHaveBeenCalledTimes(1); }); - it("should return draft menu entries for a draft objective", () => { - const spyOn = jest.spyOn(service as any, "getDraftMenuActions"); + it('should return draft menu entries for a draft objective', () => { + const spyOn = jest.spyOn(service as any, 'getDraftMenuActions'); const objectiveMinLocal: ObjectiveMin = objectiveMin; objectiveMinLocal.state = State.DRAFT; @@ -54,8 +54,8 @@ describe("ObjectiveMenuActionsService", () => { .toHaveBeenCalledTimes(1); }); - it("should return completed menu entries for a successful objective", () => { - const spyOn = jest.spyOn(service as any, "getCompletedMenuActions"); + it('should return completed menu entries for a successful objective', () => { + const spyOn = jest.spyOn(service as any, 'getCompletedMenuActions'); const objectiveMinLocal: ObjectiveMin = objectiveMin; objectiveMinLocal.state = State.SUCCESSFUL; @@ -64,8 +64,8 @@ describe("ObjectiveMenuActionsService", () => { .toHaveBeenCalledTimes(1); }); - it("should return completed menu entries for a non-successful objective", () => { - const spyOn = jest.spyOn(service as any, "getCompletedMenuActions"); + it('should return completed menu entries for a non-successful objective', () => { + const spyOn = jest.spyOn(service as any, 'getCompletedMenuActions'); const objectiveMinLocal: ObjectiveMin = objectiveMin; objectiveMinLocal.state = State.NOTSUCCESSFUL; @@ -79,11 +79,11 @@ describe("ObjectiveMenuActionsService", () => { }); }); - describe("getReleaseAction", () => { - it("should return release from backlog action for an objective in backlog quarter", () => { - jest.spyOn(service as any, "isInBacklogQuarter") + describe('getReleaseAction', () => { + it('should return release from backlog action for an objective in backlog quarter', () => { + jest.spyOn(service as any, 'isInBacklogQuarter') .mockReturnValue(true); - const spyOn = jest.spyOn(service as any, "isInBacklogQuarter") + const spyOn = jest.spyOn(service as any, 'isInBacklogQuarter') .mockReturnValue(true); // @ts-expect-error service.getReleaseAction(objectiveMin); @@ -91,8 +91,8 @@ describe("ObjectiveMenuActionsService", () => { .toHaveBeenCalledTimes(1); }); - it("should return release from quarter action for an objective in non-backlog quarter", () => { - const spyOn = jest.spyOn(service as any, "isInBacklogQuarter") + it('should return release from quarter action for an objective in non-backlog quarter', () => { + const spyOn = jest.spyOn(service as any, 'isInBacklogQuarter') .mockReturnValue(false); // @ts-expect-error service.getReleaseAction(objectiveMin); diff --git a/frontend/src/app/services/objective-menu-actions.service.ts b/frontend/src/app/services/objective-menu-actions.service.ts index 83a2df4fd6..d901307294 100644 --- a/frontend/src/app/services/objective-menu-actions.service.ts +++ b/frontend/src/app/services/objective-menu-actions.service.ts @@ -1,14 +1,14 @@ -import { Injectable } from "@angular/core"; -import { DialogService } from "./dialog.service"; -import { MatDialogRef } from "@angular/material/dialog"; -import { ObjectiveMin } from "../shared/types/model/ObjectiveMin"; -import { State } from "../shared/types/enums/State"; -import { ObjectiveMenuAfterActions } from "../components/objective/ObjectiveMenuAfterActions"; -import { ObjectiveService } from "./objective.service"; -import { RefreshDataService } from "./refresh-data.service"; -import { ObjectiveMenuActions } from "../components/objective/ObjectiveMenuActions"; -import { GJ_REGEX_PATTERN } from "../shared/constantLibary"; -import { CompletedService } from "./completed.servce"; +import { Injectable } from '@angular/core'; +import { DialogService } from './dialog.service'; +import { MatDialogRef } from '@angular/material/dialog'; +import { ObjectiveMin } from '../shared/types/model/ObjectiveMin'; +import { State } from '../shared/types/enums/State'; +import { ObjectiveMenuAfterActions } from '../components/objective/ObjectiveMenuAfterActions'; +import { ObjectiveService } from './objective.service'; +import { RefreshDataService } from './refresh-data.service'; +import { ObjectiveMenuActions } from '../components/objective/ObjectiveMenuActions'; +import { GJ_REGEX_PATTERN } from '../shared/constantLibary'; +import { CompletedService } from './completed.servce'; export type ObjectiveMenuAction = () => MatDialogRef; export type ObjectiveMenuAfterAction = (objective: ObjectiveMin, dialogResult: any) => any; @@ -20,7 +20,7 @@ export interface ObjectiveMenuEntry { } @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class ObjectiveMenuActionsService { afterActions: ObjectiveMenuAfterActions; @@ -50,7 +50,7 @@ export class ObjectiveMenuActionsService { } else if (objective.state === State.DRAFT) { return this.getDraftMenuActions(objective); } - throw new Error("Objective invalid"); + throw new Error('Objective invalid'); } private getDefaultActions(objective: ObjectiveMin): ObjectiveMenuEntry[] { diff --git a/frontend/src/app/services/objective.service.spec.ts b/frontend/src/app/services/objective.service.spec.ts index d9b770ed73..3d2204da84 100644 --- a/frontend/src/app/services/objective.service.spec.ts +++ b/frontend/src/app/services/objective.service.spec.ts @@ -1,9 +1,9 @@ -import { TestBed } from "@angular/core/testing"; +import { TestBed } from '@angular/core/testing'; -import { ObjectiveService } from "./objective.service"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; +import { ObjectiveService } from './objective.service'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; -describe("ObjectiveService", () => { +describe('ObjectiveService', () => { let service: ObjectiveService; beforeEach(() => { @@ -13,7 +13,7 @@ describe("ObjectiveService", () => { service = TestBed.inject(ObjectiveService); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); diff --git a/frontend/src/app/services/objective.service.ts b/frontend/src/app/services/objective.service.ts index c32fd4610c..894f4c23a1 100644 --- a/frontend/src/app/services/objective.service.ts +++ b/frontend/src/app/services/objective.service.ts @@ -1,28 +1,28 @@ -import { Injectable } from "@angular/core"; -import { HttpClient } from "@angular/common/http"; -import { Objective } from "../shared/types/model/Objective"; -import { Observable } from "rxjs"; -import { KeyResultDTO } from "../shared/types/DTOs/KeyResultDTO"; -import { User } from "../shared/types/model/User"; -import { CheckIn } from "../shared/types/model/CheckIn"; -import { Action } from "../shared/types/model/Action"; +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Objective } from '../shared/types/model/Objective'; +import { Observable } from 'rxjs'; +import { KeyResultDTO } from '../shared/types/DTOs/KeyResultDTO'; +import { User } from '../shared/types/model/User'; +import { CheckIn } from '../shared/types/model/CheckIn'; +import { Action } from '../shared/types/model/Action'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class ObjectiveService { constructor(private httpClient: HttpClient) {} getFullObjective(id: number) { - return this.httpClient.get("/api/v2/objectives/" + id); + return this.httpClient.get('/api/v2/objectives/' + id); } getAllKeyResultsByObjective(id: number): Observable { - return this.httpClient.get("api/v2/objectives/" + id + "/keyResults"); + return this.httpClient.get('api/v2/objectives/' + id + '/keyResults'); } createObjective(objectiveDTO: Objective): Observable { - return this.httpClient.post("/api/v2/objectives", objectiveDTO); + return this.httpClient.post('/api/v2/objectives', objectiveDTO); } updateObjective(objectiveDTO: Objective): Observable { diff --git a/frontend/src/app/services/overview.service.spec.ts b/frontend/src/app/services/overview.service.spec.ts index e3d478e56a..6afb1bb09d 100644 --- a/frontend/src/app/services/overview.service.spec.ts +++ b/frontend/src/app/services/overview.service.spec.ts @@ -1,16 +1,16 @@ -import { TestBed } from "@angular/core/testing"; +import { TestBed } from '@angular/core/testing'; -import { OverviewService } from "./overview.service"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { of } from "rxjs"; -import { HttpClient } from "@angular/common/http"; -import { overviews } from "../shared/testData"; +import { OverviewService } from './overview.service'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { of } from 'rxjs'; +import { HttpClient } from '@angular/common/http'; +import { overviews } from '../shared/testData'; const httpClient = { get: jest.fn() }; -describe("OverviewService", () => { +describe('OverviewService', () => { let service: OverviewService; beforeEach(() => { @@ -23,18 +23,18 @@ describe("OverviewService", () => { service = TestBed.inject(OverviewService); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); - it("should set state of objectives correctly", (done) => { - jest.spyOn(httpClient, "get") + it('should set state of objectives correctly', (done) => { + jest.spyOn(httpClient, 'get') .mockReturnValue(of(overviews)); service.getOverview() .subscribe(() => { overviews.forEach((overview) => overview.objectives.forEach((objective) => expect(typeof objective.state) - .toBe("string"))); + .toBe('string'))); done(); }); }); diff --git a/frontend/src/app/services/overview.service.ts b/frontend/src/app/services/overview.service.ts index b70dad3767..74ec7bcb41 100644 --- a/frontend/src/app/services/overview.service.ts +++ b/frontend/src/app/services/overview.service.ts @@ -1,12 +1,12 @@ -import { Injectable } from "@angular/core"; -import { HttpClient } from "@angular/common/http"; -import { map, Observable } from "rxjs"; -import { optionalValue } from "../shared/common"; -import { State } from "../shared/types/enums/State"; -import { OverviewEntity } from "../shared/types/model/OverviewEntity"; +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { map, Observable } from 'rxjs'; +import { optionalValue } from '../shared/common'; +import { State } from '../shared/types/enums/State'; +import { OverviewEntity } from '../shared/types/model/OverviewEntity'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class OverviewService { constructor(private http: HttpClient) {} @@ -17,7 +17,7 @@ export class OverviewService { team: teamIds, objectiveQuery: objectiveQuery }); - return this.http.get("/api/v2/overview", { params: params }) + return this.http.get('/api/v2/overview', { params: params }) .pipe(map((overviews) => { overviews.forEach((overview) => { overview.objectives.forEach((objective) => { diff --git a/frontend/src/app/services/quarter.service.spec.ts b/frontend/src/app/services/quarter.service.spec.ts index c6f0e8d609..8b28f871d0 100644 --- a/frontend/src/app/services/quarter.service.spec.ts +++ b/frontend/src/app/services/quarter.service.spec.ts @@ -1,9 +1,9 @@ -import { TestBed } from "@angular/core/testing"; +import { TestBed } from '@angular/core/testing'; -import { QuarterService } from "./quarter.service"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; +import { QuarterService } from './quarter.service'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; -describe("QuarterService", () => { +describe('QuarterService', () => { let service: QuarterService; beforeEach(() => { @@ -13,7 +13,7 @@ describe("QuarterService", () => { service = TestBed.inject(QuarterService); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); diff --git a/frontend/src/app/services/quarter.service.ts b/frontend/src/app/services/quarter.service.ts index eab90817dd..4a03acb815 100644 --- a/frontend/src/app/services/quarter.service.ts +++ b/frontend/src/app/services/quarter.service.ts @@ -1,23 +1,23 @@ -import { Injectable } from "@angular/core"; -import { HttpClient } from "@angular/common/http"; -import { Quarter } from "../shared/types/model/Quarter"; -import { map, Observable } from "rxjs"; +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Quarter } from '../shared/types/model/Quarter'; +import { map, Observable } from 'rxjs'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class QuarterService { constructor(private http: HttpClient) {} getAllQuarters(): Observable { return this.http - .get("/api/v2/quarters") + .get('/api/v2/quarters') .pipe(map((quarters) => quarters.map((quarter) => new Quarter( quarter.id, quarter.label, quarter.startDate, quarter.endDate )))); } getCurrentQuarter(): Observable { - return this.http.get("/api/v2/quarters/current"); + return this.http.get('/api/v2/quarters/current'); } } diff --git a/frontend/src/app/services/refresh-data.service.spec.ts b/frontend/src/app/services/refresh-data.service.spec.ts index 633ca5cdec..406590eec2 100644 --- a/frontend/src/app/services/refresh-data.service.spec.ts +++ b/frontend/src/app/services/refresh-data.service.spec.ts @@ -1,8 +1,8 @@ -import { TestBed } from "@angular/core/testing"; +import { TestBed } from '@angular/core/testing'; -import { RefreshDataService } from "./refresh-data.service"; +import { RefreshDataService } from './refresh-data.service'; -describe("RefreshDataService", () => { +describe('RefreshDataService', () => { let service: RefreshDataService; beforeEach(() => { @@ -10,7 +10,7 @@ describe("RefreshDataService", () => { service = TestBed.inject(RefreshDataService); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); diff --git a/frontend/src/app/services/refresh-data.service.ts b/frontend/src/app/services/refresh-data.service.ts index 766632ea2b..4b4e5d86d5 100644 --- a/frontend/src/app/services/refresh-data.service.ts +++ b/frontend/src/app/services/refresh-data.service.ts @@ -1,9 +1,9 @@ -import { Injectable } from "@angular/core"; -import { BehaviorSubject, Subject } from "rxjs"; -import { DEFAULT_HEADER_HEIGHT_PX } from "../shared/constantLibary"; +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Subject } from 'rxjs'; +import { DEFAULT_HEADER_HEIGHT_PX } from '../shared/constantLibary'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class RefreshDataService { public reloadOverviewSubject = new Subject(); diff --git a/frontend/src/app/services/team.service.spec.ts b/frontend/src/app/services/team.service.spec.ts index 54903b2c9d..dcde7d864c 100644 --- a/frontend/src/app/services/team.service.spec.ts +++ b/frontend/src/app/services/team.service.spec.ts @@ -1,9 +1,9 @@ -import { TestBed } from "@angular/core/testing"; +import { TestBed } from '@angular/core/testing'; -import { TeamService } from "./team.service"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; +import { TeamService } from './team.service'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; -describe("TeamService", () => { +describe('TeamService', () => { let service: TeamService; beforeEach(() => { @@ -13,7 +13,7 @@ describe("TeamService", () => { service = TestBed.inject(TeamService); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); diff --git a/frontend/src/app/services/team.service.ts b/frontend/src/app/services/team.service.ts index 473b98019c..76c52a0c72 100644 --- a/frontend/src/app/services/team.service.ts +++ b/frontend/src/app/services/team.service.ts @@ -1,12 +1,12 @@ -import { Injectable } from "@angular/core"; -import { HttpClient } from "@angular/common/http"; -import { Team } from "../shared/types/model/Team"; -import { BehaviorSubject, Observable, tap } from "rxjs"; -import { User } from "../shared/types/model/User"; -import { UserTeam } from "../shared/types/model/UserTeam"; +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Team } from '../shared/types/model/Team'; +import { BehaviorSubject, Observable, tap } from 'rxjs'; +import { User } from '../shared/types/model/User'; +import { UserTeam } from '../shared/types/model/UserTeam'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class TeamService { constructor(private http: HttpClient) {} @@ -15,7 +15,7 @@ export class TeamService { private teamsLoaded = false; - private readonly API_URL = "/api/v2/teams"; + private readonly API_URL = '/api/v2/teams'; getAllTeams(): Observable { if (!this.teamsLoaded) { diff --git a/frontend/src/app/services/toaster.service.spec.ts b/frontend/src/app/services/toaster.service.spec.ts index 29d2923260..fbcaf5934c 100644 --- a/frontend/src/app/services/toaster.service.spec.ts +++ b/frontend/src/app/services/toaster.service.spec.ts @@ -1,10 +1,10 @@ -import { TestBed } from "@angular/core/testing"; +import { TestBed } from '@angular/core/testing'; -import { ToasterService } from "./toaster.service"; -import { ToastrModule, ToastrService } from "ngx-toastr"; -import { ToasterType } from "../shared/types/enums/ToasterType"; +import { ToasterService } from './toaster.service'; +import { ToastrModule, ToastrService } from 'ngx-toastr'; +import { ToasterType } from '../shared/types/enums/ToasterType'; -describe("ToasterService", () => { +describe('ToasterService', () => { let service: ToasterService; let toastr: ToastrService; @@ -17,46 +17,46 @@ describe("ToasterService", () => { toastr = TestBed.inject(ToastrService); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); - it("showSuccess should call right method", () => { - jest.spyOn(toastr, "success"); - service.showSuccess("test"); + it('showSuccess should call right method', () => { + jest.spyOn(toastr, 'success'); + service.showSuccess('test'); expect(toastr.success) - .toBeCalledWith("test", "Erfolgreich!"); + .toBeCalledWith('test', 'Erfolgreich!'); }); - it("showError should call right method", () => { - jest.spyOn(toastr, "error"); - service.showError("test"); + it('showError should call right method', () => { + jest.spyOn(toastr, 'error'); + service.showError('test'); expect(toastr.error) - .toBeCalledWith("test", "Fehler!"); + .toBeCalledWith('test', 'Fehler!'); }); - it("showWarn should call right method", () => { - jest.spyOn(toastr, "warning"); - service.showWarn("test"); + it('showWarn should call right method', () => { + jest.spyOn(toastr, 'warning'); + service.showWarn('test'); expect(toastr.warning) - .toBeCalledWith("test", "Warnung!"); + .toBeCalledWith('test', 'Warnung!'); }); it.each([ [ToasterType.SUCCESS, - "message", - "showSuccess"], + 'message', + 'showSuccess'], [ToasterType.WARN, - "message", - "showWarn"], + 'message', + 'showWarn'], [ToasterType.ERROR, - "message", - "showError"], + 'message', + 'showError'], [999, - "message", - "showSuccess"] - ])("showWarn should call right method", (toasterType: number, message: string, func: any) => { + 'message', + 'showSuccess'] + ])('showWarn should call right method', (toasterType: number, message: string, func: any) => { const spy = jest.spyOn(service, func); service.showCustomToaster(message, toasterType); diff --git a/frontend/src/app/services/toaster.service.ts b/frontend/src/app/services/toaster.service.ts index 70e237df9b..0fce4c106f 100644 --- a/frontend/src/app/services/toaster.service.ts +++ b/frontend/src/app/services/toaster.service.ts @@ -1,23 +1,23 @@ -import { Injectable } from "@angular/core"; -import { ToastrService } from "ngx-toastr"; -import { ToasterType } from "../shared/types/enums/ToasterType"; +import { Injectable } from '@angular/core'; +import { ToastrService } from 'ngx-toastr'; +import { ToasterType } from '../shared/types/enums/ToasterType'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class ToasterService { constructor(private toastr: ToastrService) {} showSuccess(msg: string) { - this.toastr.success(msg, "Erfolgreich!"); + this.toastr.success(msg, 'Erfolgreich!'); } showError(msg: string) { - this.toastr.error(msg, "Fehler!"); + this.toastr.error(msg, 'Fehler!'); } showWarn(msg: string) { - this.toastr.warning(msg, "Warnung!"); + this.toastr.warning(msg, 'Warnung!'); } showCustomToaster(msg: string, type?: ToasterType) { diff --git a/frontend/src/app/services/user.service.spec.ts b/frontend/src/app/services/user.service.spec.ts index 749e1a12ff..bf6dc74a85 100644 --- a/frontend/src/app/services/user.service.spec.ts +++ b/frontend/src/app/services/user.service.spec.ts @@ -1,12 +1,12 @@ -import { fakeAsync, getTestBed, TestBed, tick } from "@angular/core/testing"; -import { HttpClientTestingModule, HttpTestingController } from "@angular/common/http/testing"; -import { UserService } from "./user.service"; -import { testUser, users } from "../shared/testData"; +import { fakeAsync, getTestBed, TestBed, tick } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; +import { UserService } from './user.service'; +import { testUser, users } from '../shared/testData'; -describe("UserService", () => { +describe('UserService', () => { let service: UserService; let httpMock: HttpTestingController; - const URL = "api/v1/users"; + const URL = 'api/v1/users'; beforeEach(() => { TestBed.configureTestingModule({ @@ -21,13 +21,13 @@ describe("UserService", () => { httpMock.verify(); }); - it("should be created", () => { + it('should be created', () => { expect(service) .toBeTruthy(); }); - it("getUsers should only reload users when they are not loaded yet", (done) => { - const spy = jest.spyOn(service, "reloadUsers"); + it('getUsers should only reload users when they are not loaded yet', (done) => { + const spy = jest.spyOn(service, 'reloadUsers'); service.getUsers() .subscribe(() => { expect(spy) @@ -44,25 +44,25 @@ describe("UserService", () => { }); }); - it("get current user should throw error, when not loaded", () => { + it('get current user should throw error, when not loaded', () => { expect(() => service.getCurrentUser()) - .toThrowError("user should not be undefined here"); + .toThrowError('user should not be undefined here'); }); - it("init current user should load user", (done) => { + it('init current user should load user', (done) => { expect(() => service.getCurrentUser()) - .toThrowError("user should not be undefined here"); + .toThrowError('user should not be undefined here'); service.getOrInitCurrentUser() .subscribe(() => { expect(service.getCurrentUser()) .toBe(users[0]); done(); }); - const req = httpMock.expectOne("api/v1/users/current"); + const req = httpMock.expectOne('api/v1/users/current'); req.flush(users[0]); }); - it("setIsOkrChampion should call put operation, reloadUsers and reloadCurrentUser", fakeAsync(() => { + it('setIsOkrChampion should call put operation, reloadUsers and reloadCurrentUser', fakeAsync(() => { service.setIsOkrChampion(testUser, true) .subscribe(); const req = httpMock.expectOne(`api/v1/users/${testUser.id}/isokrchampion/true`); @@ -70,25 +70,25 @@ describe("UserService", () => { tick(); - const req2 = httpMock.expectOne("api/v1/users"); - const req3 = httpMock.expectOne("api/v1/users/current"); + const req2 = httpMock.expectOne('api/v1/users'); + const req3 = httpMock.expectOne('api/v1/users/current'); req2.flush({}); req3.flush({}); })); - it("createUsers should call createAll and reloadUsers", fakeAsync(() => { + it('createUsers should call createAll and reloadUsers', fakeAsync(() => { service.createUsers(users) .subscribe(); - const req = httpMock.expectOne("api/v1/users/createall"); + const req = httpMock.expectOne('api/v1/users/createall'); req.flush(users); tick(); - const req2 = httpMock.expectOne("api/v1/users"); + const req2 = httpMock.expectOne('api/v1/users'); req2.flush({}); })); - it("deleteUser should call /userId and reloadUsers", fakeAsync(() => { + it('deleteUser should call /userId and reloadUsers', fakeAsync(() => { service.deleteUser(testUser) .subscribe(); const req = httpMock.expectOne(`api/v1/users/${testUser.id}`); @@ -96,7 +96,7 @@ describe("UserService", () => { tick(); - const req2 = httpMock.expectOne("api/v1/users"); + const req2 = httpMock.expectOne('api/v1/users'); req2.flush({}); })); }); diff --git a/frontend/src/app/services/user.service.ts b/frontend/src/app/services/user.service.ts index f88f4a4c8d..65fad6cbb8 100644 --- a/frontend/src/app/services/user.service.ts +++ b/frontend/src/app/services/user.service.ts @@ -1,15 +1,15 @@ -import { Injectable } from "@angular/core"; -import { BehaviorSubject, Observable, of, tap } from "rxjs"; -import { HttpClient } from "@angular/common/http"; -import { User } from "../shared/types/model/User"; -import { NewUser } from "../shared/types/model/NewUser"; -import { UserOkrData } from "../shared/types/model/UserOkrData"; +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable, of, tap } from 'rxjs'; +import { HttpClient } from '@angular/common/http'; +import { User } from '../shared/types/model/User'; +import { NewUser } from '../shared/types/model/NewUser'; +import { UserOkrData } from '../shared/types/model/UserOkrData'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class UserService { - private readonly API_URL = "api/v1/users"; + private readonly API_URL = 'api/v1/users'; private _currentUser: User | undefined; @@ -27,13 +27,13 @@ export class UserService { } public reloadCurrentUser(): Observable { - return this.httpClient.get(this.API_URL + "/current") + return this.httpClient.get(this.API_URL + '/current') .pipe(tap((u) => this._currentUser = u)); } public getCurrentUser(): User { if (!this._currentUser) { - throw new Error("user should not be undefined here"); + throw new Error('user should not be undefined here'); } return this._currentUser; } @@ -52,7 +52,7 @@ export class UserService { } getUserById(id: number): Observable { - return this.httpClient.get(this.API_URL + "/" + id); + return this.httpClient.get(this.API_URL + '/' + id); } setIsOkrChampion(user: User, isOkrChampion: boolean) { diff --git a/frontend/src/app/shared/common.spec.ts b/frontend/src/app/shared/common.spec.ts index 240062bf82..2a92a36ffc 100644 --- a/frontend/src/app/shared/common.spec.ts +++ b/frontend/src/app/shared/common.spec.ts @@ -8,96 +8,96 @@ import { optionalReplaceWithNulls, optionalValue, sanitize -} from "./common"; -import { FormControl, FormGroup, Validators } from "@angular/forms"; -import { keyResultMetricMinScoring, keyResultOrdinalMinScoring } from "./testData"; -import { KeyResultMetricMin } from "./types/model/KeyResultMetricMin"; +} from './common'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { keyResultMetricMinScoring, keyResultOrdinalMinScoring } from './testData'; +import { KeyResultMetricMin } from './types/model/KeyResultMetricMin'; -describe("test common functions", () => { - describe("getNumberOrNull", () => { - test("should get simple number correctly", () => { - expect(getNumberOrNull("-123456789")) +describe('test common functions', () => { + describe('getNumberOrNull', () => { + test('should get simple number correctly', () => { + expect(getNumberOrNull('-123456789')) .toBe(-123456789); - expect(getNumberOrNull("-5")) + expect(getNumberOrNull('-5')) .toBe(-5); - expect(getNumberOrNull("-0")) + expect(getNumberOrNull('-0')) .toBe(-0); - expect(getNumberOrNull("0")) + expect(getNumberOrNull('0')) .toBe(0); - expect(getNumberOrNull("+0")) + expect(getNumberOrNull('+0')) .toBe(0); - expect(getNumberOrNull("3")) + expect(getNumberOrNull('3')) .toBe(3); - expect(getNumberOrNull("123456789")) + expect(getNumberOrNull('123456789')) .toBe(123456789); }); - test("should get special number correctly", () => { - expect(getNumberOrNull("03")) + test('should get special number correctly', () => { + expect(getNumberOrNull('03')) .toBe(3); - expect(getNumberOrNull(" 3")) + expect(getNumberOrNull(' 3')) .toBe(3); - expect(getNumberOrNull(" 3 ")) + expect(getNumberOrNull(' 3 ')) .toBe(3); - expect(getNumberOrNull("3 ")) + expect(getNumberOrNull('3 ')) .toBe(3); - expect(getNumberOrNull("+3 ")) + expect(getNumberOrNull('+3 ')) .toBe(3); - expect(getNumberOrNull("-3 ")) + expect(getNumberOrNull('-3 ')) .toBe(-3); - expect(getNumberOrNull("3foo")) + expect(getNumberOrNull('3foo')) .toBe(3); - expect(getNumberOrNull("+3foo")) + expect(getNumberOrNull('+3foo')) .toBe(3); - expect(getNumberOrNull("-3foo")) + expect(getNumberOrNull('-3foo')) .toBe(-3); - expect(getNumberOrNull(" 3foo")) + expect(getNumberOrNull(' 3foo')) .toBe(3); - expect(getNumberOrNull(" +3foo")) + expect(getNumberOrNull(' +3foo')) .toBe(3); - expect(getNumberOrNull(" -3foo")) + expect(getNumberOrNull(' -3foo')) .toBe(-3); - expect(getNumberOrNull("03.2")) + expect(getNumberOrNull('03.2')) .toBe(3); - expect(getNumberOrNull("03,2")) + expect(getNumberOrNull('03,2')) .toBe(3); - expect(getNumberOrNull("3+2")) + expect(getNumberOrNull('3+2')) .toBe(3); }); - test("should get null if the argument has no digit", () => { + test('should get null if the argument has no digit', () => { expect(getNumberOrNull(null)) .toBe(null); - expect(getNumberOrNull("")) + expect(getNumberOrNull('')) .toBe(null); - expect(getNumberOrNull(" ")) + expect(getNumberOrNull(' ')) .toBe(null); - expect(getNumberOrNull("foo")) + expect(getNumberOrNull('foo')) .toBe(null); - expect(getNumberOrNull("null")) + expect(getNumberOrNull('null')) .toBe(null); - expect(getNumberOrNull("undefined")) + expect(getNumberOrNull('undefined')) .toBe(null); }); - test("should get null if the argument more that spaces, + or - a the beginning", () => { - expect(getNumberOrNull("foo3")) + test('should get null if the argument more that spaces, + or - a the beginning', () => { + expect(getNumberOrNull('foo3')) .toBe(null); - expect(getNumberOrNull("foo+3")) + expect(getNumberOrNull('foo+3')) .toBe(null); - expect(getNumberOrNull("+foo3")) + expect(getNumberOrNull('+foo3')) .toBe(null); - expect(getNumberOrNull(" + 3")) + expect(getNumberOrNull(' + 3')) .toBe(null); - expect(getNumberOrNull("+ 3")) + expect(getNumberOrNull('+ 3')) .toBe(null); - expect(getNumberOrNull("+ 3 ")) + expect(getNumberOrNull('+ 3 ')) .toBe(null); - expect(getNumberOrNull(" - 3")) + expect(getNumberOrNull(' - 3')) .toBe(null); - expect(getNumberOrNull("- 3")) + expect(getNumberOrNull('- 3')) .toBe(null); - expect(getNumberOrNull("- 3 ")) + expect(getNumberOrNull('- 3 ')) .toBe(null); }); }); @@ -155,7 +155,7 @@ describe("test common functions", () => { 2, 1], true] - ])("should give correct output for deep equal", (arr1: number[], arr2: number[], output: boolean) => { + ])('should give correct output for deep equal', (arr1: number[], arr2: number[], output: boolean) => { expect(areEqual(arr1, arr2)) .toBe(output); expect(areEqual(arr2, arr1)) @@ -169,7 +169,7 @@ describe("test common functions", () => { [undefined, undefined, []], - ["", + ['', undefined, []], [[1], @@ -180,23 +180,23 @@ describe("test common functions", () => { undefined, [1]], [[1, - "", + '', 3], undefined, [1, 3]], - ["1,3", + ['1,3', undefined, [1, 3]], - ["1,3.5", + ['1,3.5', undefined, [1]], - ["1,3.5,3", + ['1,3.5,3', undefined, [1, 3]], - ["1,nonsense,3", + ['1,nonsense,3', undefined, [1, 3]], @@ -206,24 +206,24 @@ describe("test common functions", () => { [[0], undefined, [0]], - ["0", + ['0', undefined, [0]], - ["1,0", + ['1,0', undefined, [1, 0]], - ["0,1", + ['0,1', undefined, [0, 1]], - ["", + ['', 1, [1]], [[], 1, [1]] - ])("should give correct output for getValueFromQuery", (value: any, fallback: number | undefined, arr2: number[]) => { + ])('should give correct output for getValueFromQuery', (value: any, fallback: number | undefined, arr2: number[]) => { expect(getValueFromQuery(value, fallback)) .toStrictEqual(arr2); }); @@ -231,7 +231,7 @@ describe("test common functions", () => { it.each([ [{ v: undefined }, {}], - [{ v: "" }, + [{ v: '' }, {}], [{ v: [] }, {}], @@ -245,15 +245,15 @@ describe("test common functions", () => { [{ v: undefined, v2: 1 }, { v2: 1 }] - ])("should give correct output for optionalValue", (value: Record, expected: Record) => { + ])('should give correct output for optionalValue', (value: Record, expected: Record) => { expect(optionalValue(value)) .toStrictEqual(expected); }); - it.each([[" test ", - "test"], - ["ffF", - "fff"]])("test sanitize function", (str: any, expected: string) => { + it.each([[' test ', + 'test'], + ['ffF', + 'fff']])('test sanitize function', (str: any, expected: string) => { expect(sanitize(str)) .toBe(expected); }); @@ -301,7 +301,7 @@ describe("test common functions", () => { -10, 0 ] - ])("should calculate progress correctly", async( + ])('should calculate progress correctly', async( baseline: number, stretchGoal: number, value: number, filledPercentage: number ) => { const keyResult = { @@ -317,17 +317,17 @@ describe("test common functions", () => { }); it.each([ - ["t%20t", - "t t"], - ["%20", - ""], - ["f%20", - "f"], - ["%20f", - "f"], - ["test", - "test"] - ])("test getQueryString function", (str: any, expected: string) => { + ['t%20t', + 't t'], + ['%20', + ''], + ['f%20', + 'f'], + ['%20f', + 'f'], + ['test', + 'test'] + ])('test getQueryString function', (str: any, expected: string) => { expect(getQueryString(str)) .toBe(expected); }); @@ -335,7 +335,7 @@ describe("test common functions", () => { it.each([ [{ v: undefined }, { v: null }], - [{ v: "" }, + [{ v: '' }, { v: null }], [{ v: [] }, { v: null }], @@ -351,40 +351,40 @@ describe("test common functions", () => { v2: 1 }, { v: null, v2: 1 }] - ])("should give correct output for optionalReplaceWithNulls", (obj1: Record, obj2: Record) => { + ])('should give correct output for optionalReplaceWithNulls', (obj1: Record, obj2: Record) => { expect(optionalReplaceWithNulls(obj1)) .toStrictEqual(obj2); }); - test("should return correct class", () => { + test('should return correct class', () => { const testForm = new FormGroup({ title: new FormControl(undefined, [Validators.required, Validators.minLength(2), Validators.maxLength(250)]), - description: new FormControl("", [Validators.maxLength(4096)]), + description: new FormControl('', [Validators.maxLength(4096)]), code: new FormControl(0, [Validators.min(5), Validators.max(10)]) }); - testForm.controls["code"].markAsDirty(); - testForm.controls["title"].markAsTouched(); - testForm.controls["description"].markAsDirty(); + testForm.controls['code'].markAsDirty(); + testForm.controls['title'].markAsTouched(); + testForm.controls['description'].markAsDirty(); // False check - expect(formInputCheck(testForm, "code")) - .toBe("dialog-form-field-error"); - expect(formInputCheck(testForm, "title")) - .toBe("dialog-form-field-error"); + expect(formInputCheck(testForm, 'code')) + .toBe('dialog-form-field-error'); + expect(formInputCheck(testForm, 'title')) + .toBe('dialog-form-field-error'); // Fill in value to match validation testForm.controls.code.setValue(8); - testForm.controls.title.setValue("Test"); + testForm.controls.title.setValue('Test'); // True check - expect(formInputCheck(testForm, "description")) - .toBe("dialog-form-field"); - expect(formInputCheck(testForm, "code")) - .toBe("dialog-form-field"); - expect(formInputCheck(testForm, "title")) - .toBe("dialog-form-field"); + expect(formInputCheck(testForm, 'description')) + .toBe('dialog-form-field'); + expect(formInputCheck(testForm, 'code')) + .toBe('dialog-form-field'); + expect(formInputCheck(testForm, 'title')) + .toBe('dialog-form-field'); }); }); diff --git a/frontend/src/app/shared/common.ts b/frontend/src/app/shared/common.ts index 33ea56c924..ca41ce46ba 100644 --- a/frontend/src/app/shared/common.ts +++ b/frontend/src/app/shared/common.ts @@ -1,9 +1,9 @@ -import { FormGroup } from "@angular/forms"; -import { KeyResultMetricMin } from "./types/model/KeyResultMetricMin"; +import { FormGroup } from '@angular/forms'; +import { KeyResultMetricMin } from './types/model/KeyResultMetricMin'; export function getNumberOrNull(str: string | null | undefined): number | null { if (str === null || str === undefined || str.toString() - .trim() === "") { + .trim() === '') { return null; } const number: number = parseInt(str, 10); @@ -13,9 +13,9 @@ export function getNumberOrNull(str: string | null | undefined): number | null { export function getValueFromQuery(query: any, fallback?: number): number[] { const values = Array.from([query]) .flat() - .filter((e) => e !== "") + .filter((e) => e !== '') .map((e) => { - return typeof e == "string" ? e.split(",") : e; + return typeof e == 'string' ? e.split(',') : e; }) .flat() .map((id: any) => Number(id)) @@ -29,7 +29,7 @@ export function optionalValue(param: object): Record { .filter(([_, v]) => v != undefined) .filter(([_, - v]) => v != "") + v]) => v != '') .filter(([_, v]) => { if (Array.isArray(v)) { @@ -59,7 +59,7 @@ export function sanitize(query: string) { } export function getQueryString(query?: string) { - const queryString = query || ""; + const queryString = query || ''; return sanitize(decodeURI(queryString)); } @@ -92,15 +92,15 @@ export function trackByFn(id: any): any { export function formInputCheck(form: FormGroup, propertyName: string) { if ((form.get(propertyName)?.dirty || form.get(propertyName)?.touched) && form.get(propertyName)?.invalid) { - return "dialog-form-field-error"; + return 'dialog-form-field-error'; } else { - return "dialog-form-field"; + return 'dialog-form-field'; } } export function isMobileDevice() { return window.navigator.userAgent.toLowerCase() - .includes("mobile"); + .includes('mobile'); } export function hasFormFieldErrors(formGroup: FormGroup, field: string) { diff --git a/frontend/src/app/shared/constantLibary.ts b/frontend/src/app/shared/constantLibary.ts index e1c21d1847..0d12f58144 100644 --- a/frontend/src/app/shared/constantLibary.ts +++ b/frontend/src/app/shared/constantLibary.ts @@ -1,6 +1,6 @@ -import { HttpType } from "./types/enums/HttpType"; -import { ToasterType } from "./types/enums/ToasterType"; -import { HttpStatusCode } from "@angular/common/http"; +import { HttpType } from './types/enums/HttpType'; +import { ToasterType } from './types/enums/ToasterType'; +import { HttpStatusCode } from '@angular/common/http'; type MessageKeyMap = Record = of({}); - @Input() title = ""; + @Input() title = ''; isValueReady(obj: any): boolean { if (obj == null) { diff --git a/frontend/src/app/shared/custom/okr-tangram/okr-tangram.component.ts b/frontend/src/app/shared/custom/okr-tangram/okr-tangram.component.ts index dbc463cbbc..2a7ff7d6cc 100644 --- a/frontend/src/app/shared/custom/okr-tangram/okr-tangram.component.ts +++ b/frontend/src/app/shared/custom/okr-tangram/okr-tangram.component.ts @@ -1,14 +1,14 @@ -import { Component } from "@angular/core"; -import { ConfigService } from "../../../services/config.service"; -import { map, Observable } from "rxjs"; +import { Component } from '@angular/core'; +import { ConfigService } from '../../../services/config.service'; +import { map, Observable } from 'rxjs'; @Component({ - selector: "app-okr-tangram", - templateUrl: "okr-tangram.component.html", - styleUrl: "okr-tangram.component.scss" + selector: 'app-okr-tangram', + templateUrl: 'okr-tangram.component.html', + styleUrl: 'okr-tangram.component.scss' }) export class OkrTangramComponent { - private readonly DEFAULT_TRIANGLE_SRC = "assets/images/empty.svg"; + private readonly DEFAULT_TRIANGLE_SRC = 'assets/images/empty.svg'; trianglesSrc$ = new Observable(); diff --git a/frontend/src/app/shared/custom/puzzle-icon-button/puzzle-icon-button.component.ts b/frontend/src/app/shared/custom/puzzle-icon-button/puzzle-icon-button.component.ts index 782dce0506..f8c44bbd53 100644 --- a/frontend/src/app/shared/custom/puzzle-icon-button/puzzle-icon-button.component.ts +++ b/frontend/src/app/shared/custom/puzzle-icon-button/puzzle-icon-button.component.ts @@ -1,9 +1,9 @@ -import { Component, Input } from "@angular/core"; +import { Component, Input } from '@angular/core'; @Component({ - selector: "app-puzzle-icon-button", - templateUrl: "./puzzle-icon-button.component.html", - styleUrl: "./puzzle-icon-button.component.scss" + selector: 'app-puzzle-icon-button', + templateUrl: './puzzle-icon-button.component.html', + styleUrl: './puzzle-icon-button.component.scss' }) export class PuzzleIconButtonComponent { @Input({ required: true }) @@ -21,8 +21,8 @@ export class PuzzleIconButtonComponent { getStyle() { return { - "border-radius": this.size / 2 + "px", - padding: this.padding + "px" + 'border-radius': this.size / 2 + 'px', + padding: this.padding + 'px' }; } } diff --git a/frontend/src/app/shared/custom/puzzle-icon/puzzle-icon.component.ts b/frontend/src/app/shared/custom/puzzle-icon/puzzle-icon.component.ts index b51c96bbb1..d8e76bd9a0 100644 --- a/frontend/src/app/shared/custom/puzzle-icon/puzzle-icon.component.ts +++ b/frontend/src/app/shared/custom/puzzle-icon/puzzle-icon.component.ts @@ -1,8 +1,8 @@ -import { Component, Input } from "@angular/core"; +import { Component, Input } from '@angular/core'; @Component({ - selector: "app-puzzle-icon", - templateUrl: "./puzzle-icon.component.html" + selector: 'app-puzzle-icon', + templateUrl: './puzzle-icon.component.html' }) export class PuzzleIconComponent { @Input({ required: true }) diff --git a/frontend/src/app/shared/custom/scoring/scoring.component.spec.ts b/frontend/src/app/shared/custom/scoring/scoring.component.spec.ts index 1a89f22322..b401e85621 100644 --- a/frontend/src/app/shared/custom/scoring/scoring.component.spec.ts +++ b/frontend/src/app/shared/custom/scoring/scoring.component.spec.ts @@ -1,23 +1,23 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { ScoringComponent } from "./scoring.component"; -import { keyResultMetricMinScoring, keyResultOrdinalMinScoring } from "../../testData"; -import { Router } from "@angular/router"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { Zone } from "../../types/enums/Zone"; -import { CheckInOrdinalMin } from "../../types/model/CheckInOrdinalMin"; - -describe("ScoringComponent", () => { +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ScoringComponent } from './scoring.component'; +import { keyResultMetricMinScoring, keyResultOrdinalMinScoring } from '../../testData'; +import { Router } from '@angular/router'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { Zone } from '../../types/enums/Zone'; +import { CheckInOrdinalMin } from '../../types/model/CheckInOrdinalMin'; + +describe('ScoringComponent', () => { let component: ScoringComponent; let fixture: ComponentFixture; - describe("Basic function tests", () => { + describe('Basic function tests', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [ScoringComponent], providers: [{ provide: Router, useValue: { - url: "/okr/overview" + url: '/okr/overview' } }], imports: [HttpClientTestingModule] @@ -30,16 +30,16 @@ describe("ScoringComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should fill out star if target percentage is over 100", () => { + it('should fill out star if target percentage is over 100', () => { component.stretched = true; component.ngAfterViewInit(); expect(component.iconPath) - .toBe("filled"); + .toBe('filled'); }); it.each([ @@ -47,43 +47,43 @@ describe("ScoringComponent", () => { commit: 0, target: 0, className: null, - borderClass: "none" }], + borderClass: 'none' }], [{ fail: 99, commit: 0, target: 0, - className: "score-red", - borderClass: "fail" }], + className: 'score-red', + borderClass: 'fail' }], [{ fail: 100, commit: 0, target: 0, - className: "score-yellow", - borderClass: "commit" }], + className: 'score-yellow', + borderClass: 'commit' }], [{ fail: 100, commit: 99, target: 0, - className: "score-yellow", - borderClass: "commit" }], + className: 'score-yellow', + borderClass: 'commit' }], [{ fail: 100, commit: 100, target: 0, - className: "score-green", - borderClass: "target" }], + className: 'score-green', + borderClass: 'target' }], [{ fail: 100, commit: 100, target: 99, - className: "score-green", - borderClass: "target" }], + className: 'score-green', + borderClass: 'target' }], [{ fail: 100, commit: 100, target: 100, - className: "score-green", - borderClass: "target" }], + className: 'score-green', + borderClass: 'target' }], [{ fail: 100, commit: 100, target: 101, - className: "score-stretch", - borderClass: "none" }] - ])("should set styles correctly", async(object: any) => { + className: 'score-stretch', + borderClass: 'none' }] + ])('should set styles correctly', async(object: any) => { component.targetPercent = object.target; component.commitPercent = object.commit; component.failPercent = object.fail; @@ -94,14 +94,14 @@ describe("ScoringComponent", () => { }); }); - describe("KeyResult metric", () => { + describe('KeyResult metric', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [ScoringComponent], providers: [{ provide: Router, useValue: { - url: "/okr/overview" + url: '/okr/overview' } }], imports: [HttpClientTestingModule] @@ -114,20 +114,20 @@ describe("ScoringComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); }); - describe("KeyResult ordinal", () => { + describe('KeyResult ordinal', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [ScoringComponent], providers: [{ provide: Router, useValue: { - url: "/okr/overview" + url: '/okr/overview' } }], imports: [HttpClientTestingModule] @@ -140,7 +140,7 @@ describe("ScoringComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); @@ -156,7 +156,7 @@ describe("ScoringComponent", () => { [{ zoneValue: Zone.TARGET, fail: 100, commit: 100, - target: 100 }]])("should set percentages correctly", (object: any) => { + target: 100 }]])('should set percentages correctly', (object: any) => { // Reset component component.targetPercent = 0; component.commitPercent = 0; diff --git a/frontend/src/app/shared/custom/scoring/scoring.component.ts b/frontend/src/app/shared/custom/scoring/scoring.component.ts index 744893ab5e..2e6009424d 100644 --- a/frontend/src/app/shared/custom/scoring/scoring.component.ts +++ b/frontend/src/app/shared/custom/scoring/scoring.component.ts @@ -9,18 +9,18 @@ import { OnInit, SimpleChanges, ViewChild -} from "@angular/core"; -import { Zone } from "../../types/enums/Zone"; -import { KeyResultMetricMin } from "../../types/model/KeyResultMetricMin"; -import { Observable, of } from "rxjs"; -import { calculateCurrentPercentage, isLastCheckInNegative } from "../../common"; -import { KeyResultOrdinalMin } from "../../types/model/KeyResultOrdinalMin"; -import { CheckInOrdinalMin } from "../../types/model/CheckInOrdinalMin"; +} from '@angular/core'; +import { Zone } from '../../types/enums/Zone'; +import { KeyResultMetricMin } from '../../types/model/KeyResultMetricMin'; +import { Observable, of } from 'rxjs'; +import { calculateCurrentPercentage, isLastCheckInNegative } from '../../common'; +import { KeyResultOrdinalMin } from '../../types/model/KeyResultOrdinalMin'; +import { CheckInOrdinalMin } from '../../types/model/CheckInOrdinalMin'; @Component({ - selector: "app-scoring", - templateUrl: "./scoring.component.html", - styleUrls: ["./scoring.component.scss"], + selector: 'app-scoring', + templateUrl: './scoring.component.html', + styleUrls: ['./scoring.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class ScoringComponent implements OnInit, AfterViewInit, OnChanges { @@ -28,7 +28,7 @@ export class ScoringComponent implements OnInit, AfterViewInit, OnChanges { @Input() isDetail!: boolean; - iconPath = "empty"; + iconPath = 'empty'; failPercent = 0; @@ -42,16 +42,16 @@ export class ScoringComponent implements OnInit, AfterViewInit, OnChanges { protected readonly isLastCheckInNegative = isLastCheckInNegative; - @ViewChild("fail") + @ViewChild('fail') private failElement: ElementRef | undefined = undefined; - @ViewChild("commit") + @ViewChild('commit') private commitElement: ElementRef | undefined = undefined; - @ViewChild("target") + @ViewChild('target') private targetElement: ElementRef | undefined = undefined; - @ViewChild("valueLabel") + @ViewChild('valueLabel') private valueLabel: ElementRef | undefined = undefined; constructor(private changeDetectionRef: ChangeDetectorRef) { @@ -61,7 +61,7 @@ export class ScoringComponent implements OnInit, AfterViewInit, OnChanges { ngOnInit() { this.stretched = false; if (this.keyResult.lastCheckIn) { - if (this.keyResult.keyResultType === "metric") { + if (this.keyResult.keyResultType === 'metric') { this.calculatePercentageMetric(); } else { this.calculatePercentageOrdinal(); @@ -74,13 +74,13 @@ export class ScoringComponent implements OnInit, AfterViewInit, OnChanges { * Define width of scoring elements * All checked individually because that if one is undefined, the others can still be set */ - if (this.failElement) this.failElement.nativeElement.style.width = this.failPercent + "%"; - if (this.commitElement) this.commitElement.nativeElement.style.width = this.commitPercent + "%"; - if (this.targetElement) this.targetElement.nativeElement.style.width = this.targetPercent + "%"; + if (this.failElement) this.failElement.nativeElement.style.width = this.failPercent + '%'; + if (this.commitElement) this.commitElement.nativeElement.style.width = this.commitPercent + '%'; + if (this.targetElement) this.targetElement.nativeElement.style.width = this.targetPercent + '%'; - if (this.keyResult.keyResultType == "metric") { + if (this.keyResult.keyResultType == 'metric') { this.labelPercentage.subscribe((value) => { - if (this.valueLabel) this.valueLabel.nativeElement.style.width = value + "%"; + if (this.valueLabel) this.valueLabel.nativeElement.style.width = value + '%'; this.changeDetectionRef.detectChanges(); }); } @@ -96,7 +96,7 @@ export class ScoringComponent implements OnInit, AfterViewInit, OnChanges { // Fill out icon if target percent has reached 100 percent or more if (this.stretched) { - this.iconPath = "filled"; + this.iconPath = 'filled'; this.changeDetectionRef.detectChanges(); } } @@ -149,25 +149,25 @@ export class ScoringComponent implements OnInit, AfterViewInit, OnChanges { getScoringColorClassAndSetBorder(): string | null { if (this.targetPercent > 100) { - return "score-stretch"; - } else if (this.targetPercent > 0 || this.commitPercent == 100 && this.keyResult.keyResultType === "metric") { - return "score-green"; - } else if (this.commitPercent > 0 || this.failPercent == 100 && this.keyResult.keyResultType === "metric") { - return "score-yellow"; + return 'score-stretch'; + } else if (this.targetPercent > 0 || this.commitPercent == 100 && this.keyResult.keyResultType === 'metric') { + return 'score-green'; + } else if (this.commitPercent > 0 || this.failPercent == 100 && this.keyResult.keyResultType === 'metric') { + return 'score-yellow'; } else if (this.failPercent >= 3.3333) { // 3.3333% because if lower fail is not visible in overview and we display ! - return "score-red"; + return 'score-red'; } else { return null; } } ngOnChanges(changes: SimpleChanges): void { - if (changes["keyResult"]?.currentValue !== undefined || changes["keyResult"]?.currentValue !== null) { + if (changes['keyResult']?.currentValue !== undefined || changes['keyResult']?.currentValue !== null) { if (this.commitElement != undefined) { this.resetPercentagesToZero(); this.removeStyleClass(); - this.iconPath = "empty"; + this.iconPath = 'empty'; this.ngOnInit(); this.ngAfterViewInit(); } @@ -182,11 +182,11 @@ export class ScoringComponent implements OnInit, AfterViewInit, OnChanges { removeStyleClass() { const classArray: string[] = [ - "score-red", - "score-green", - "score-yellow", - "score-stretch", - "border-right" + 'score-red', + 'score-green', + 'score-yellow', + 'score-stretch', + 'border-right' ]; for (const classToRemove of classArray) { this.commitElement?.nativeElement.classList.remove(classToRemove); diff --git a/frontend/src/app/shared/custom/spinner/spinner.component.ts b/frontend/src/app/shared/custom/spinner/spinner.component.ts index 8eede410e5..64a8b02c0c 100644 --- a/frontend/src/app/shared/custom/spinner/spinner.component.ts +++ b/frontend/src/app/shared/custom/spinner/spinner.component.ts @@ -1,9 +1,9 @@ -import { Component, Input } from "@angular/core"; +import { Component, Input } from '@angular/core'; @Component({ - selector: "app-spinner", - templateUrl: "./spinner.component.html", - styleUrl: "./spinner.component.scss" + selector: 'app-spinner', + templateUrl: './spinner.component.html', + styleUrl: './spinner.component.scss' }) export class SpinnerComponent { @Input({ required: false }) diff --git a/frontend/src/app/shared/customRouter.ts b/frontend/src/app/shared/customRouter.ts index 9048d6445b..7e90cbee8f 100644 --- a/frontend/src/app/shared/customRouter.ts +++ b/frontend/src/app/shared/customRouter.ts @@ -1,5 +1,5 @@ -import { Injectable } from "@angular/core"; -import { NavigationExtras, Router } from "@angular/router"; +import { Injectable } from '@angular/core'; +import { NavigationExtras, Router } from '@angular/router'; @Injectable() export class CustomRouter extends Router { @@ -9,7 +9,7 @@ export class CustomRouter extends Router { override navigate(commands: any[], extras?: NavigationExtras | undefined): Promise { const customExtras = { ...extras, - queryParamsHandling: "merge" } as NavigationExtras; + queryParamsHandling: 'merge' } as NavigationExtras; return super.navigate(commands, customExtras); } } diff --git a/frontend/src/app/shared/dialog/complete-dialog/complete-dialog.component.spec.ts b/frontend/src/app/shared/dialog/complete-dialog/complete-dialog.component.spec.ts index 7e159e1011..43b7fa5f5d 100644 --- a/frontend/src/app/shared/dialog/complete-dialog/complete-dialog.component.spec.ts +++ b/frontend/src/app/shared/dialog/complete-dialog/complete-dialog.component.spec.ts @@ -1,15 +1,15 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; - -import { CompleteDialogComponent } from "./complete-dialog.component"; -import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from "@angular/material/dialog"; -import { TranslateService } from "@ngx-translate/core"; -import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { MatIconModule } from "@angular/material/icon"; -import { DialogTemplateCoreComponent } from "../../custom/dialog-template-core/dialog-template-core.component"; -import { MatDividerModule } from "@angular/material/divider"; -import { provideRouter } from "@angular/router"; -import { provideHttpClient } from "@angular/common/http"; -import { provideHttpClientTesting } from "@angular/common/http/testing"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CompleteDialogComponent } from './complete-dialog.component'; +import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { TranslateService } from '@ngx-translate/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatIconModule } from '@angular/material/icon'; +import { DialogTemplateCoreComponent } from '../../custom/dialog-template-core/dialog-template-core.component'; +import { MatDividerModule } from '@angular/material/divider'; +import { provideRouter } from '@angular/router'; +import { provideHttpClient } from '@angular/common/http'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; const dialogMock = { close: jest.fn() @@ -23,7 +23,7 @@ const matDataMock: { objective: { objectiveId: number | undefined; } }; -describe("CompleteDialogComponent", () => { +describe('CompleteDialogComponent', () => { let component: CompleteDialogComponent; let fixture: ComponentFixture; let debugElement: any; @@ -57,16 +57,16 @@ describe("CompleteDialogComponent", () => { debugElement = fixture.debugElement.nativeElement; }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should set right classes on init", () => { - const elements = document.querySelectorAll(".valuation-card"); - const successful = document.querySelectorAll(".card-hover-successful"); - const notSuccessful = document.querySelectorAll(".card-hover-not-successful"); - const submitButton = debugElement.querySelector("[data-testid=\"submit\"]"); + it('should set right classes on init', () => { + const elements = document.querySelectorAll('.valuation-card'); + const successful = document.querySelectorAll('.card-hover-successful'); + const notSuccessful = document.querySelectorAll('.card-hover-not-successful'); + const submitButton = debugElement.querySelector('[data-testid="submit"]'); expect(elements.length) .toEqual(2); @@ -80,14 +80,14 @@ describe("CompleteDialogComponent", () => { .toBeNull(); expect(component.completeForm.invalid) .toBeTruthy(); - expect(submitButton!.hasAttribute("disabled")) + expect(submitButton!.hasAttribute('disabled')) .toBeTruthy(); }); - it("should change isSuccessful value on card click and remove class card-hover", () => { - component.switchSuccessState("successful"); - let elements = document.querySelectorAll(".card-hover"); - const submitButton = debugElement.querySelector("[data-testid=\"submit\"]"); + it('should change isSuccessful value on card click and remove class card-hover', () => { + component.switchSuccessState('successful'); + let elements = document.querySelectorAll('.card-hover'); + const submitButton = debugElement.querySelector('[data-testid="submit"]'); expect(component.completeForm.value.isSuccessful) .toBeTruthy(); @@ -95,12 +95,12 @@ describe("CompleteDialogComponent", () => { .toBeFalsy(); expect(elements.length) .toEqual(0); - expect(submitButton!.hasAttribute("disabled")) + expect(submitButton!.hasAttribute('disabled')) .toBeTruthy(); component.completeForm.patchValue({ isSuccessful: null }); - component.switchSuccessState("notSuccessful"); - elements = document.querySelectorAll(".card-hover"); + component.switchSuccessState('notSuccessful'); + elements = document.querySelectorAll('.card-hover'); expect(component.completeForm.value.isSuccessful) .toBeFalsy(); @@ -108,26 +108,26 @@ describe("CompleteDialogComponent", () => { .toEqual(0); }); - it("should set active and non-active classes on switch", () => { - component.switchSuccessState("successful"); + it('should set active and non-active classes on switch', () => { + component.switchSuccessState('successful'); fixture.detectChanges(); - let nonActiveElement = document.querySelector(".active-successful"); + let nonActiveElement = document.querySelector('.active-successful'); expect(nonActiveElement!.innerHTML) - .toContain("Objective erreicht"); + .toContain('Objective erreicht'); - component.switchSuccessState("notSuccessful"); + component.switchSuccessState('notSuccessful'); fixture.detectChanges(); - nonActiveElement = document.querySelector(".active-not-successful"); + nonActiveElement = document.querySelector('.active-not-successful'); expect(nonActiveElement!.innerHTML) - .toContain("Objective nicht erreicht"); + .toContain('Objective nicht erreicht'); }); - it("should close dialog with right data", () => { + it('should close dialog with right data', () => { component.completeForm.patchValue({ isSuccessful: true, - comment: "My new comment" + comment: 'My new comment' }); component.closeDialog(); @@ -135,8 +135,8 @@ describe("CompleteDialogComponent", () => { .toHaveBeenCalledTimes(1); expect(dialogMock.close) .toHaveBeenCalledWith({ - endState: "SUCCESSFUL", - comment: "My new comment" + endState: 'SUCCESSFUL', + comment: 'My new comment' }); }); }); diff --git a/frontend/src/app/shared/dialog/complete-dialog/complete-dialog.component.ts b/frontend/src/app/shared/dialog/complete-dialog/complete-dialog.component.ts index d4f178461f..cc08e50be9 100644 --- a/frontend/src/app/shared/dialog/complete-dialog/complete-dialog.component.ts +++ b/frontend/src/app/shared/dialog/complete-dialog/complete-dialog.component.ts @@ -1,13 +1,13 @@ -import { Component, Inject } from "@angular/core"; -import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; -import { FormControl, FormGroup, Validators } from "@angular/forms"; -import { formInputCheck, hasFormFieldErrors } from "../../common"; -import { TranslateService } from "@ngx-translate/core"; +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { formInputCheck, hasFormFieldErrors } from '../../common'; +import { TranslateService } from '@ngx-translate/core'; @Component({ - selector: "app-complete-dialog", - templateUrl: "./complete-dialog.component.html", - styleUrls: ["./complete-dialog.component.scss"] + selector: 'app-complete-dialog', + templateUrl: './complete-dialog.component.html', + styleUrls: ['./complete-dialog.component.scss'] }) export class CompleteDialogComponent { completeForm = new FormGroup({ @@ -28,30 +28,30 @@ export class CompleteDialogComponent { let successfulValue = this.completeForm.value.isSuccessful; if ( successfulValue == null || - input == "successful" && !successfulValue || - input == "notSuccessful" && successfulValue + input == 'successful' && !successfulValue || + input == 'notSuccessful' && successfulValue ) { - successfulValue = input == "successful"; + successfulValue = input == 'successful'; this.completeForm.patchValue({ isSuccessful: successfulValue }); } } closeDialog() { this.dialogRef.close({ - endState: this.completeForm.value.isSuccessful ? "SUCCESSFUL" : "NOTSUCCESSFUL", + endState: this.completeForm.value.isSuccessful ? 'SUCCESSFUL' : 'NOTSUCCESSFUL', comment: this.completeForm.value.comment }); } removeStandardHover() { - const elements = document.querySelectorAll(".card-hover"); + const elements = document.querySelectorAll('.card-hover'); elements.forEach((el) => { - el.classList.remove("card-hover"); + el.classList.remove('card-hover'); }); } getErrorMessage(error: string, field: string, maxLength: number): string { - return field + this.translate.instant("DIALOG_ERRORS." + error) + return field + this.translate.instant('DIALOG_ERRORS.' + error) .format(maxLength); } } diff --git a/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.spec.ts b/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.spec.ts index eef0106962..ed2b68a891 100644 --- a/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.spec.ts +++ b/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.spec.ts @@ -1,26 +1,26 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ConfirmDialogComponent } from "./confirm-dialog.component"; -import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from "@angular/material/dialog"; -import { HarnessLoader } from "@angular/cdk/testing"; -import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed"; -import { MatButtonHarness } from "@angular/material/button/testing"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { MatSelectModule } from "@angular/material/select"; -import { MatInputModule } from "@angular/material/input"; -import { MatRadioModule } from "@angular/material/radio"; -import { ReactiveFormsModule } from "@angular/forms"; -import { TranslateModule, TranslateService } from "@ngx-translate/core"; -import { MatIconModule } from "@angular/material/icon"; -import { ConfirmDialogData } from "../../../services/dialog.service"; -import { DialogTemplateCoreComponent } from "../../custom/dialog-template-core/dialog-template-core.component"; -import { MatDividerModule } from "@angular/material/divider"; +import { ConfirmDialogComponent } from './confirm-dialog.component'; +import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { MatButtonHarness } from '@angular/material/button/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatSelectModule } from '@angular/material/select'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { ReactiveFormsModule } from '@angular/forms'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { MatIconModule } from '@angular/material/icon'; +import { ConfirmDialogData } from '../../../services/dialog.service'; +import { DialogTemplateCoreComponent } from '../../custom/dialog-template-core/dialog-template-core.component'; +import { MatDividerModule } from '@angular/material/divider'; const dialogRefMock = { close: jest.fn() }; -describe("ConfirmDialogComponent", () => { +describe('ConfirmDialogComponent', () => { let component: ConfirmDialogComponent; let fixture: ComponentFixture; let loader: HarnessLoader; @@ -42,8 +42,8 @@ describe("ConfirmDialogComponent", () => { DialogTemplateCoreComponent], providers: [TranslateService, { provide: MAT_DIALOG_DATA, - useValue: { title: "", - text: "" } as ConfirmDialogData }, + useValue: { title: '', + text: '' } as ConfirmDialogData }, { provide: MatDialogRef, useValue: dialogRefMock }] }); @@ -53,12 +53,12 @@ describe("ConfirmDialogComponent", () => { loader = TestbedHarnessEnvironment.loader(fixture); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should call close method with parameter: true if clicked to submit button", async() => { + it('should call close method with parameter: true if clicked to submit button', async() => { const buttons = await loader.getAllHarnesses(MatButtonHarness); const submitButton = buttons[1]; await submitButton.click(); @@ -67,12 +67,12 @@ describe("ConfirmDialogComponent", () => { .toHaveBeenCalledWith(true); }); - it("should call close method with parameter: \"\" if clicked to cancel button", async() => { + it('should call close method with parameter: "" if clicked to cancel button', async() => { const buttons = await loader.getAllHarnesses(MatButtonHarness); const cancelButton = buttons[0]; await cancelButton.click(); expect(dialogRefMock.close) - .toHaveBeenCalledWith(""); + .toHaveBeenCalledWith(''); }); }); diff --git a/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.ts b/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.ts index 84cc85ed11..819d45a093 100644 --- a/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.ts +++ b/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.ts @@ -1,17 +1,17 @@ -import { Component, Inject, OnInit } from "@angular/core"; -import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; -import { ConfirmDialogData } from "../../../services/dialog.service"; -import { ButtonState } from "../../types/enums/ButtonState"; +import { Component, Inject, OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { ConfirmDialogData } from '../../../services/dialog.service'; +import { ButtonState } from '../../types/enums/ButtonState'; @Component({ - selector: "app-confirm-dialog", - templateUrl: "./confirm-dialog.component.html", - styleUrls: ["./confirm-dialog.component.scss"] + selector: 'app-confirm-dialog', + templateUrl: './confirm-dialog.component.html', + styleUrls: ['./confirm-dialog.component.scss'] }) export class ConfirmDialogComponent implements OnInit { - dialogTitle = ""; + dialogTitle = ''; - dialogText = ""; + dialogText = ''; yesButtonState?: ButtonState; diff --git a/frontend/src/app/shared/dialog/example-dialog/example-dialog.component.spec.ts b/frontend/src/app/shared/dialog/example-dialog/example-dialog.component.spec.ts index 09240ca4b5..abe9d93312 100644 --- a/frontend/src/app/shared/dialog/example-dialog/example-dialog.component.spec.ts +++ b/frontend/src/app/shared/dialog/example-dialog/example-dialog.component.spec.ts @@ -1,23 +1,23 @@ -import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from "@angular/core/testing"; -import { ExampleDialogComponent } from "./example-dialog.component"; -import { HarnessLoader } from "@angular/cdk/testing"; -import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from "@angular/material/dialog"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed"; -import { MatSelectModule } from "@angular/material/select"; -import { MatInputModule } from "@angular/material/input"; -import { MatRadioModule } from "@angular/material/radio"; -import { ReactiveFormsModule } from "@angular/forms"; -import { MatRadioButtonHarness } from "@angular/material/radio/testing"; -import { MatInputHarness } from "@angular/material/input/testing"; -import { MatSelectHarness } from "@angular/material/select/testing"; -import { By } from "@angular/platform-browser"; +import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; +import { ExampleDialogComponent } from './example-dialog.component'; +import { HarnessLoader } from '@angular/cdk/testing'; +import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { MatSelectModule } from '@angular/material/select'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatRadioButtonHarness } from '@angular/material/radio/testing'; +import { MatInputHarness } from '@angular/material/input/testing'; +import { MatSelectHarness } from '@angular/material/select/testing'; +import { By } from '@angular/platform-browser'; // @ts-ignore -import * as errorData from "../../../../assets/errors/error-messages.json"; -import { ObjectiveComponent } from "../../../components/objective/objective.component"; -import { MatOptionHarness } from "@angular/material/core/testing"; +import * as errorData from '../../../../assets/errors/error-messages.json'; +import { ObjectiveComponent } from '../../../components/objective/objective.component'; +import { MatOptionHarness } from '@angular/material/core/testing'; -describe("ExampleDialogComponent", () => { +describe('ExampleDialogComponent', () => { let component: ExampleDialogComponent; let fixture: ComponentFixture; let loader: HarnessLoader; @@ -52,47 +52,47 @@ describe("ExampleDialogComponent", () => { loader = TestbedHarnessEnvironment.loader(fixture); }); - it("should create", fakeAsync(() => { + it('should create', fakeAsync(() => { expect(component) .toBeTruthy(); })); - it("should be able to set name", waitForAsync(async() => { + it('should be able to set name', waitForAsync(async() => { // Insert values into name input const nameInput = await loader.getHarness(MatInputHarness); - await nameInput.setValue("Name"); + await nameInput.setValue('Name'); // Check if save button is disabled - const submitButton = fixture.debugElement.query(By.css("[data-testId=\"submit\"]")); + const submitButton = fixture.debugElement.query(By.css('[data-testId="submit"]')); expect(await submitButton.nativeElement.disabled) .toBeTruthy(); // Validate if object was created correctly const formObject = fixture.componentInstance.dialogForm.value; expect(formObject.name) - .toBe("Name"); + .toBe('Name'); })); - it("should be able to set buttons", waitForAsync(async() => { + it('should be able to set buttons', waitForAsync(async() => { // Check radio button const buttons = await loader.getAllHarnesses(MatRadioButtonHarness); await buttons[0].check(); // Check if save button is disabled - const submitButton = fixture.debugElement.query(By.css("[data-testId=\"submit\"]")); + const submitButton = fixture.debugElement.query(By.css('[data-testId="submit"]')); expect(await submitButton.nativeElement.disabled) .toBeTruthy(); // Validate if object was created correctly const formObject = fixture.componentInstance.dialogForm.value; expect(formObject.name) - .toBe(""); + .toBe(''); expect(formObject.gender) .toBe(await buttons[0].getValue()); })); - it("should be able to set select", async() => { - let option = ""; + it('should be able to set select', async() => { + let option = ''; // Get mat-select element and click it (dropdown) await loader.getHarness(MatSelectHarness) .then(fakeAsync((matSelect: MatSelectHarness) => { @@ -108,59 +108,59 @@ describe("ExampleDialogComponent", () => { })); // Check if save button is disabled - const submitButton = fixture.debugElement.query(By.css("[data-testId=\"submit\"]")); + const submitButton = fixture.debugElement.query(By.css('[data-testId="submit"]')); expect(await submitButton.nativeElement.disabled) .toBeTruthy(); // Validate if object was created correctly const formObject = fixture.componentInstance.dialogForm.value; expect(formObject.name) - .toBe(""); + .toBe(''); expect(option) .toBe(formObject.hobby); }); - it("should display error message of too short input", waitForAsync(async() => { + it('should display error message of too short input', waitForAsync(async() => { // Insert values into name input which don't match length validator const nameInput = await loader.getHarness(MatInputHarness); - await nameInput.setValue("Na"); + await nameInput.setValue('Na'); // Verify error message - const errorMessage = fixture.debugElement.query(By.css("mat-error")); + const errorMessage = fixture.debugElement.query(By.css('mat-error')); expect(errorMessage.nativeElement.textContent) .toContain(errors.MINLENGTH); // Check if submit button is disabled - const submitButton = fixture.debugElement.query(By.css("[data-testId=\"submit\"]")); + const submitButton = fixture.debugElement.query(By.css('[data-testId="submit"]')); expect(submitButton.nativeElement.disabled) .toBeTruthy(); })); - it("should display error message of required dropdown", waitForAsync(async() => { + it('should display error message of required dropdown', waitForAsync(async() => { // Open and close mat-select element to trigger validation const matSelect = await loader.getHarness(MatSelectHarness); await matSelect.open(); await matSelect.close(); // Verify error message - const errorMessage = fixture.debugElement.query(By.css("mat-error")); + const errorMessage = fixture.debugElement.query(By.css('mat-error')); expect(errorMessage.nativeElement.textContent) .toContain(errors.REQUIRED); // Check if submit button is disabled - const submitButton = fixture.debugElement.query(By.css("[data-testId=\"submit\"]")); + const submitButton = fixture.debugElement.query(By.css('[data-testId="submit"]')); expect(submitButton.nativeElement.disabled) .toBeTruthy(); })); - it("should not save form unless radio button is checked", async() => { + it('should not save form unless radio button is checked', async() => { // Insert value into input const nameInput = loader.getHarness(MatInputHarness); const matSelect = loader.getHarness(MatSelectHarness); const radioButtons = loader.getAllHarnesses(MatRadioButtonHarness); // Verify that the submit button is disabled because the radio button is not checked yet - const submitButton = fixture.debugElement.query(By.css("[data-testId=\"submit\"]")); + const submitButton = fixture.debugElement.query(By.css('[data-testId="submit"]')); expect(submitButton.nativeElement.disabled) .toBeTruthy(); @@ -170,7 +170,7 @@ describe("ExampleDialogComponent", () => { .then(fakeAsync(([nameInput, matSelect, radioButtons]: [MatInputHarness, MatSelectHarness, MatRadioButtonHarness[]]) => { - nameInput.setValue("Name"); + nameInput.setValue('Name'); advance(); matSelect.open() .then(() => { @@ -188,9 +188,9 @@ describe("ExampleDialogComponent", () => { expect(submitButton.nativeElement.disabled) .toBeFalsy(); expect(formObject.name) - .toBe("Name"); + .toBe('Name'); expect(gender) - .toBe("female"); + .toBe('female'); expect(hobby) .toBe(formObject.hobby); }); diff --git a/frontend/src/app/shared/dialog/example-dialog/example-dialog.component.ts b/frontend/src/app/shared/dialog/example-dialog/example-dialog.component.ts index 9f7d822638..6581465a38 100644 --- a/frontend/src/app/shared/dialog/example-dialog/example-dialog.component.ts +++ b/frontend/src/app/shared/dialog/example-dialog/example-dialog.component.ts @@ -1,20 +1,20 @@ -import { Component, Inject } from "@angular/core"; -import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; -import { FormControl, FormGroup, Validators } from "@angular/forms"; -import errorMessages from "../../../../assets/errors/error-messages.json"; -import { formInputCheck } from "../../common"; +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import errorMessages from '../../../../assets/errors/error-messages.json'; +import { formInputCheck } from '../../common'; @Component({ - selector: "app-example-dialog", - templateUrl: "./example-dialog.component.html" + selector: 'app-example-dialog', + templateUrl: './example-dialog.component.html' }) export class ExampleDialogComponent { hobbies = [ - "fishing", - "football", - "videogames", - "tennis", - "other" + 'fishing', + 'football', + 'videogames', + 'tennis', + 'other' ]; protected readonly errorMessages: any = errorMessages; @@ -22,11 +22,11 @@ export class ExampleDialogComponent { protected readonly formInputCheck = formInputCheck; dialogForm = new FormGroup({ - name: new FormControl("", [Validators.required, + name: new FormControl('', [Validators.required, Validators.minLength(3), Validators.maxLength(50)]), - gender: new FormControl("", [Validators.required]), - hobby: new FormControl("", [Validators.required]) + gender: new FormControl('', [Validators.required]), + hobby: new FormControl('', [Validators.required]) }); constructor(public dialog: MatDialogRef, diff --git a/frontend/src/app/shared/dialog/objective-dialog/objective-form.component.spec.ts b/frontend/src/app/shared/dialog/objective-dialog/objective-form.component.spec.ts index 6432f5f744..5fe03c1621 100644 --- a/frontend/src/app/shared/dialog/objective-dialog/objective-form.component.spec.ts +++ b/frontend/src/app/shared/dialog/objective-dialog/objective-form.component.spec.ts @@ -1,35 +1,35 @@ -import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; - -import { ObjectiveFormComponent } from "./objective-form.component"; -import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from "@angular/material/dialog"; -import { MatInputModule } from "@angular/material/input"; -import { MatIconModule } from "@angular/material/icon"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { MatSelectModule } from "@angular/material/select"; -import { ReactiveFormsModule } from "@angular/forms"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { ObjectiveService } from "../../../services/objective.service"; -import { keyResult, objective, quarter, quarterList } from "../../testData"; -import { Observable, of } from "rxjs"; -import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed"; -import { HarnessLoader } from "@angular/cdk/testing"; -import { MatCheckboxModule } from "@angular/material/checkbox"; -import { Quarter } from "../../types/model/Quarter"; -import { QuarterService } from "../../../services/quarter.service"; -import { TeamService } from "../../../services/team.service"; -import { State } from "../../types/enums/State"; -import { By } from "@angular/platform-browser"; -import { MatCheckboxHarness } from "@angular/material/checkbox/testing"; -import { RouterTestingHarness } from "@angular/router/testing"; -import { TranslateTestingModule } from "ngx-translate-testing"; +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; + +import { ObjectiveFormComponent } from './objective-form.component'; +import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { MatInputModule } from '@angular/material/input'; +import { MatIconModule } from '@angular/material/icon'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatSelectModule } from '@angular/material/select'; +import { ReactiveFormsModule } from '@angular/forms'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { ObjectiveService } from '../../../services/objective.service'; +import { keyResult, objective, quarter, quarterList } from '../../testData'; +import { Observable, of } from 'rxjs'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { HarnessLoader } from '@angular/cdk/testing'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { Quarter } from '../../types/model/Quarter'; +import { QuarterService } from '../../../services/quarter.service'; +import { TeamService } from '../../../services/team.service'; +import { State } from '../../types/enums/State'; +import { By } from '@angular/platform-browser'; +import { MatCheckboxHarness } from '@angular/material/checkbox/testing'; +import { RouterTestingHarness } from '@angular/router/testing'; +import { TranslateTestingModule } from 'ngx-translate-testing'; // @ts-ignore -import * as de from "../../../../assets/i18n/de.json"; -import { ActivatedRoute, provideRouter } from "@angular/router"; -import { provideHttpClient } from "@angular/common/http"; -import { provideHttpClientTesting } from "@angular/common/http/testing"; -import { DialogTemplateCoreComponent } from "../../custom/dialog-template-core/dialog-template-core.component"; -import { MatDividerModule } from "@angular/material/divider"; -import { Team } from "../../types/model/Team"; +import * as de from '../../../../assets/i18n/de.json'; +import { ActivatedRoute, provideRouter } from '@angular/router'; +import { provideHttpClient } from '@angular/common/http'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { DialogTemplateCoreComponent } from '../../custom/dialog-template-core/dialog-template-core.component'; +import { MatDividerModule } from '@angular/material/divider'; +import { Team } from '../../types/model/Team'; const objectiveService = { getFullObjective: jest.fn(), @@ -53,7 +53,7 @@ const quarterService = { 2, quarter.label, quarter.startDate, quarter.endDate ), new Quarter( - 999, "Backlog", null, null + 999, 'Backlog', null, null )]); }, getCurrentQuarter(): Observable { @@ -70,12 +70,12 @@ const teamService = { // Mock the return value of getAllTeams teamService.getAllTeams.mockReturnValue(of([{ id: 1, version: 2, - name: "Marketing Team", + name: 'Marketing Team', writeable: true, organisations: [] }, { id: 4, version: 5, - name: "Team 2", + name: 'Team 2', writeable: true, organisations: [] }])); @@ -93,17 +93,17 @@ const matDataMock: MatDialogDataInterface = { const mockActivatedRoute = { snapshot: { queryParams: { - quarter: "999" + quarter: '999' } } }; -describe("ObjectiveDialogComponent", () => { +describe('ObjectiveDialogComponent', () => { let component: ObjectiveFormComponent; let fixture: ComponentFixture; let loader: HarnessLoader; - describe("Normal Objective dialog", () => { + describe('Normal Objective dialog', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [ @@ -144,16 +144,16 @@ describe("ObjectiveDialogComponent", () => { loader = TestbedHarnessEnvironment.loader(fixture); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it.each([["DRAFT"], - ["ONGOING"]])("onSubmit create", fakeAsync((state: string) => { + it.each([['DRAFT'], + ['ONGOING']])('onSubmit create', fakeAsync((state: string) => { // Prepare data - const title = "title"; - const description = "description"; + const title = 'title'; + const description = 'description'; const createKeyresults = true; let quarter = 0; let team = 0; @@ -167,20 +167,20 @@ describe("ObjectiveDialogComponent", () => { }); // Get input elements and set values - const titleInput: HTMLInputElement = fixture.debugElement.query(By.css("[data-testId=\"title\"]")).nativeElement; + const titleInput: HTMLInputElement = fixture.debugElement.query(By.css('[data-testId="title"]')).nativeElement; titleInput.value = title; - const descriptionInput: HTMLInputElement = fixture.debugElement.query(By.css("[data-testId=\"description\"]")).nativeElement; + const descriptionInput: HTMLInputElement = fixture.debugElement.query(By.css('[data-testId="description"]')).nativeElement; descriptionInput.value = description; loader.getHarness(MatCheckboxHarness) .then((checkBox) => checkBox.check()); tick(200); - const quarterSelect: HTMLSelectElement = fixture.debugElement.query(By.css("[data-testId=\"quarterSelect\"]")).nativeElement; + const quarterSelect: HTMLSelectElement = fixture.debugElement.query(By.css('[data-testId="quarterSelect"]')).nativeElement; quarterSelect.value = quarter.toString(); // Trigger update of form fixture.detectChanges(); - titleInput.dispatchEvent(new Event("input")); - descriptionInput.dispatchEvent(new Event("input")); - quarterSelect.dispatchEvent(new Event("change")); + titleInput.dispatchEvent(new Event('input')); + descriptionInput.dispatchEvent(new Event('input')); + quarterSelect.dispatchEvent(new Event('change')); const rawFormValue = component.objectiveForm.getRawValue(); expect(rawFormValue.description) @@ -207,7 +207,7 @@ describe("ObjectiveDialogComponent", () => { id: 5, version: 1, quarterId: 2, - quarterLabel: "GJ 22/23-Q2", + quarterLabel: 'GJ 22/23-Q2', state: State[state as keyof typeof State], teamId: 2, title: title, @@ -217,11 +217,11 @@ describe("ObjectiveDialogComponent", () => { }); })); - it("should create objective", () => { + it('should create objective', () => { matDataMock.objective.objectiveId = undefined; component.objectiveForm.setValue({ - title: "Test title", - description: "Test description", + title: 'Test title', + description: 'Test description', quarter: 0, team: 0, relation: 0, @@ -230,27 +230,27 @@ describe("ObjectiveDialogComponent", () => { }); objectiveService.createObjective.mockReturnValue(of({ ...objective, - state: "DRAFT" })); - component.onSubmit("DRAFT"); + state: 'DRAFT' })); + component.onSubmit('DRAFT'); fixture.detectChanges(); expect(objectiveService.createObjective) .toHaveBeenCalledWith({ - description: "Test description", + description: 'Test description', id: undefined, - state: "DRAFT", - title: "Test title", + state: 'DRAFT', + title: 'Test title', quarterId: 0, teamId: 0 }); }); - it("should update objective", () => { + it('should update objective', () => { matDataMock.objective.objectiveId = 1; component.objectiveForm.setValue({ - title: "Test title", - description: "Test description", + title: 'Test title', + description: 'Test description', quarter: 1, team: 1, relation: 0, @@ -259,23 +259,23 @@ describe("ObjectiveDialogComponent", () => { }); objectiveService.updateObjective.mockReturnValue(of({ ...objective, - state: "ONGOING" })); - component.onSubmit("DRAFT"); + state: 'ONGOING' })); + component.onSubmit('DRAFT'); fixture.detectChanges(); expect(objectiveService.updateObjective) .toHaveBeenCalledWith({ - description: "Test description", + description: 'Test description', id: 1, - state: "DRAFT", - title: "Test title", + state: 'DRAFT', + title: 'Test title', quarterId: 1, teamId: 1 }); }); - it("should load default values into form onInit with undefined objectiveId", () => { + it('should load default values into form onInit with undefined objectiveId', () => { matDataMock.objective.objectiveId = undefined; matDataMock.objective.teamId = 1; component.ngOnInit(); @@ -294,10 +294,10 @@ describe("ObjectiveDialogComponent", () => { }); }); - it("should load default values into form onInit with defined objectiveId", async() => { + it('should load default values into form onInit with defined objectiveId', async() => { matDataMock.objective.objectiveId = 1; const routerHarness = await RouterTestingHarness.create(); - await routerHarness.navigateByUrl("/?quarter=2"); + await routerHarness.navigateByUrl('/?quarter=2'); objectiveService.getFullObjective.mockReturnValue(of(objective)); objectiveService.getAllKeyResultsByObjective.mockReturnValue(of(keyResult)); component.ngOnInit(); @@ -312,11 +312,11 @@ describe("ObjectiveDialogComponent", () => { .toBe(objective.quarterId); }); - it("should set teams$ observable correctly on ngOnInit", () => { + it('should set teams$ observable correctly on ngOnInit', () => { const mockTeams = [{ id: 1, - name: "Team A" }, + name: 'Team A' }, { id: 2, - name: "Team B" }]; + name: 'Team B' }]; teamService.getAllTeams.mockReturnValue(of(mockTeams)); component.ngOnInit(); @@ -327,9 +327,9 @@ describe("ObjectiveDialogComponent", () => { }); }); - it("should set keyResults$ observable correctly when objectiveId is defined", () => { + it('should set keyResults$ observable correctly when objectiveId is defined', () => { const mockKeyResults = [{ id: 1, - name: "Key Result A" }]; + name: 'Key Result A' }]; matDataMock.objective.objectiveId = 1; objectiveService.getAllKeyResultsByObjective.mockReturnValue(of(mockKeyResults)); @@ -341,25 +341,25 @@ describe("ObjectiveDialogComponent", () => { }); }); - it("should return correct value if allowed to save to backlog", async() => { + it('should return correct value if allowed to save to backlog', async() => { component.quarters = quarterList; - const isBacklogQuarterSpy = jest.spyOn(component, "isBacklogQuarter"); + const isBacklogQuarterSpy = jest.spyOn(component, 'isBacklogQuarter'); isBacklogQuarterSpy.mockReturnValue(false); - component.data.action = "duplicate"; + component.data.action = 'duplicate'; fixture.detectChanges(); expect(component.allowedToSaveBacklog()) .toBeTruthy(); component.objectiveForm.controls.quarter.setValue(999); - component.data.action = ""; + component.data.action = ''; component.data.objective.objectiveId = 5; - component.state = "DRAFT"; + component.state = 'DRAFT'; fixture.detectChanges(); expect(component.allowedToSaveBacklog()) .toBeTruthy(); - component.state = "ONGOING"; + component.state = 'ONGOING'; fixture.detectChanges(); expect(component.allowedToSaveBacklog()) .toBeFalsy(); @@ -384,19 +384,19 @@ describe("ObjectiveDialogComponent", () => { .toBeTruthy(); }); - it("should return if option is allowed for quarter select", async() => { + it('should return if option is allowed for quarter select', async() => { const quarter: Quarter = new Quarter( - 1, "Backlog", null, null + 1, 'Backlog', null, null ); const data = { - action: "duplicate", + action: 'duplicate', objective: { objectiveId: 22 } }; component.data = data; - component.state = "DRAFT"; + component.state = 'DRAFT'; fixture.detectChanges(); expect(component.allowedOption(quarter)) @@ -404,24 +404,24 @@ describe("ObjectiveDialogComponent", () => { expect(component.allowedOption(quarter)) .toBeTruthy(); - data.action = "releaseBacklog"; + data.action = 'releaseBacklog'; fixture.detectChanges(); expect(component.allowedOption(quarter)) .toBeFalsy(); - data.action = "edit"; + data.action = 'edit'; fixture.detectChanges(); expect(component.allowedOption(quarter)) .toBeTruthy(); - component.state = "ONGOING"; + component.state = 'ONGOING'; fixture.detectChanges(); expect(component.allowedOption(quarter)) .toBeFalsy(); component.data = { - action: "duplicate", + action: 'duplicate', objective: {} }; @@ -431,7 +431,7 @@ describe("ObjectiveDialogComponent", () => { }); }); - describe("Backlog quarter", () => { + describe('Backlog quarter', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [ @@ -474,25 +474,25 @@ describe("ObjectiveDialogComponent", () => { loader = TestbedHarnessEnvironment.loader(fixture); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should set correct default value if objective is released in backlog", async() => { + it('should set correct default value if objective is released in backlog', async() => { component.data = { objective: { objectiveId: 1, teamId: 1 }, - action: "releaseBacklog" + action: 'releaseBacklog' }; - const isBacklogQuarterSpy = jest.spyOn(component, "isBacklogQuarter"); + const isBacklogQuarterSpy = jest.spyOn(component, 'isBacklogQuarter'); isBacklogQuarterSpy.mockReturnValue(false); const routerHarness = await RouterTestingHarness.create(); - await routerHarness.navigateByUrl("/?quarter=999"); + await routerHarness.navigateByUrl('/?quarter=999'); objectiveService.getFullObjective.mockReturnValue(of(objective)); fixture.detectChanges(); component.ngOnInit(); diff --git a/frontend/src/app/shared/dialog/objective-dialog/objective-form.component.ts b/frontend/src/app/shared/dialog/objective-dialog/objective-form.component.ts index 4de1a3ae5b..31093a6156 100644 --- a/frontend/src/app/shared/dialog/objective-dialog/objective-form.component.ts +++ b/frontend/src/app/shared/dialog/objective-dialog/objective-form.component.ts @@ -1,34 +1,34 @@ -import { ChangeDetectionStrategy, Component, Inject, OnDestroy, OnInit } from "@angular/core"; -import { FormArray, FormControl, FormGroup, Validators } from "@angular/forms"; -import { Quarter } from "../../types/model/Quarter"; -import { TeamService } from "../../../services/team.service"; -import { Team } from "../../types/model/Team"; -import { QuarterService } from "../../../services/quarter.service"; -import { forkJoin, Observable, of, Subject, takeUntil } from "rxjs"; -import { ObjectiveService } from "../../../services/objective.service"; -import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; -import { State } from "../../types/enums/State"; -import { ObjectiveMin } from "../../types/model/ObjectiveMin"; -import { Objective } from "../../types/model/Objective"; -import { formInputCheck, getValueFromQuery, hasFormFieldErrors } from "../../common"; -import { ActivatedRoute } from "@angular/router"; -import { GJ_REGEX_PATTERN } from "../../constantLibary"; -import { TranslateService } from "@ngx-translate/core"; -import { DialogService } from "../../../services/dialog.service"; -import { KeyResultDTO } from "../../types/DTOs/KeyResultDTO"; +import { ChangeDetectionStrategy, Component, Inject, OnDestroy, OnInit } from '@angular/core'; +import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms'; +import { Quarter } from '../../types/model/Quarter'; +import { TeamService } from '../../../services/team.service'; +import { Team } from '../../types/model/Team'; +import { QuarterService } from '../../../services/quarter.service'; +import { forkJoin, Observable, of, Subject, takeUntil } from 'rxjs'; +import { ObjectiveService } from '../../../services/objective.service'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { State } from '../../types/enums/State'; +import { ObjectiveMin } from '../../types/model/ObjectiveMin'; +import { Objective } from '../../types/model/Objective'; +import { formInputCheck, getValueFromQuery, hasFormFieldErrors } from '../../common'; +import { ActivatedRoute } from '@angular/router'; +import { GJ_REGEX_PATTERN } from '../../constantLibary'; +import { TranslateService } from '@ngx-translate/core'; +import { DialogService } from '../../../services/dialog.service'; +import { KeyResultDTO } from '../../types/DTOs/KeyResultDTO'; @Component({ - selector: "app-objective-form", - templateUrl: "./objective-form.component.html", - styleUrls: ["./objective-form.component.scss"], + selector: 'app-objective-form', + templateUrl: './objective-form.component.html', + styleUrls: ['./objective-form.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class ObjectiveFormComponent implements OnInit, OnDestroy { objectiveForm = new FormGroup({ - title: new FormControl("", [Validators.required, + title: new FormControl('', [Validators.required, Validators.minLength(2), Validators.maxLength(250)]), - description: new FormControl("", [Validators.maxLength(4096)]), + description: new FormControl('', [Validators.maxLength(4096)]), quarter: new FormControl(0, [Validators.required]), team: new FormControl({ value: 0, @@ -146,9 +146,9 @@ export class ObjectiveFormComponent implements OnInit, OnDestroy { // Determine the team ID to set in the form: existing team for editing or default team for new objectives const teamId = isEditing ? objective.teamId : this.data.objective.teamId; const newEditQuarter = isEditing ? currentQuarter.id : objective.quarterId; - let quarterId = getValueFromQuery(this.route.snapshot.queryParams["quarter"], newEditQuarter)[0]; + let quarterId = getValueFromQuery(this.route.snapshot.queryParams['quarter'], newEditQuarter)[0]; - if (currentQuarter && !this.isBacklogQuarter(currentQuarter.label) && this.data.action == "releaseBacklog") { + if (currentQuarter && !this.isBacklogQuarter(currentQuarter.label) && this.data.action == 'releaseBacklog') { quarterId = quarters[1].id; } @@ -180,9 +180,9 @@ export class ObjectiveFormComponent implements OnInit, OnDestroy { } getSubmitFunction(id: number | undefined, objectiveDTO: any): Observable { - if (this.data.action == "duplicate" && id) { + if (this.data.action == 'duplicate' && id) { objectiveDTO.id = null; - objectiveDTO.state = "DRAFT" as State; + objectiveDTO.state = 'DRAFT' as State; return this.objectiveService.duplicateObjective(id, { objective: objectiveDTO, keyResults: this.keyResults @@ -193,7 +193,7 @@ export class ObjectiveFormComponent implements OnInit, OnDestroy { })) }); } else { - if (this.data.action == "releaseBacklog") objectiveDTO.state = "ONGOING" as State; + if (this.data.action == 'releaseBacklog') objectiveDTO.state = 'ONGOING' as State; if (this.data.objective.objectiveId && id) { objectiveDTO.id = id; return this.objectiveService.updateObjective(objectiveDTO); @@ -203,7 +203,7 @@ export class ObjectiveFormComponent implements OnInit, OnDestroy { } deleteObjective() { - const dialog = this.dialogService.openConfirmDialog("CONFIRMATION.DELETE.OBJECTIVE"); + const dialog = this.dialogService.openConfirmDialog('CONFIRMATION.DELETE.OBJECTIVE'); dialog.afterClosed() .subscribe((result) => { if (result && this.data.objective.objectiveId) { @@ -242,16 +242,16 @@ export class ObjectiveFormComponent implements OnInit, OnDestroy { getErrorMessage( error: string, field: string, firstNumber: number | null, secondNumber: number | null ): string { - return field + this.translate.instant("DIALOG_ERRORS." + error) + return field + this.translate.instant('DIALOG_ERRORS.' + error) .format(firstNumber, secondNumber); } getDefaultObjective() { return { id: 0, - title: "", - description: "", - state: "DRAFT" as State, + title: '', + description: '', + state: 'DRAFT' as State, teamId: 0, quarterId: 0 } as Objective; @@ -261,9 +261,9 @@ export class ObjectiveFormComponent implements OnInit, OnDestroy { const currentQuarter: Quarter | undefined = this.quarters.find((quarter) => quarter.id == this.objectiveForm.value.quarter); if (currentQuarter) { const isBacklogCurrent = !this.isBacklogQuarter(currentQuarter.label); - if (this.data.action == "duplicate") return true; + if (this.data.action == 'duplicate') return true; if (this.data.objective.objectiveId) { - return isBacklogCurrent ? this.state == "DRAFT" : true; + return isBacklogCurrent ? this.state == 'DRAFT' : true; } else { return !isBacklogCurrent; } @@ -273,13 +273,13 @@ export class ObjectiveFormComponent implements OnInit, OnDestroy { } allowedOption(quarter: Quarter) { - if (quarter.label == "Backlog") { - if (this.data.action == "duplicate") { + if (quarter.label == 'Backlog') { + if (this.data.action == 'duplicate') { return true; - } else if (this.data.action == "releaseBacklog") { + } else if (this.data.action == 'releaseBacklog') { return false; } else if (this.data.objective.objectiveId) { - return this.state == "DRAFT"; + return this.state == 'DRAFT'; } else { return true; } @@ -293,22 +293,22 @@ export class ObjectiveFormComponent implements OnInit, OnDestroy { } getDialogTitle(teamName: string): string { - if (this.data.action === "duplicate") { + if (this.data.action === 'duplicate') { return `Objective von ${teamName} duplizieren`; } - if (this.data.action === "releaseBacklog") { - return "Objective veröffentlichen"; + if (this.data.action === 'releaseBacklog') { + return 'Objective veröffentlichen'; } if (!this.data.objective.objectiveId) { return `Objective für ${teamName} erfassen`; } - if (this.data.objective.objectiveId && this.data.action !== "releaseBacklog") { + if (this.data.objective.objectiveId && this.data.action !== 'releaseBacklog') { return `Objective von ${teamName} bearbeiten`; } - return ""; + return ''; } } diff --git a/frontend/src/app/shared/pipes/unit-transformation/unit-transformation.pipe.spec.ts b/frontend/src/app/shared/pipes/unit-transformation/unit-transformation.pipe.spec.ts index a3641f2e1e..3bb3d2cb2e 100644 --- a/frontend/src/app/shared/pipes/unit-transformation/unit-transformation.pipe.spec.ts +++ b/frontend/src/app/shared/pipes/unit-transformation/unit-transformation.pipe.spec.ts @@ -1,64 +1,64 @@ -import { UnitTransformationPipe } from "./unit-transformation.pipe"; -import { Unit } from "../../types/enums/Unit"; +import { UnitTransformationPipe } from './unit-transformation.pipe'; +import { Unit } from '../../types/enums/Unit'; -describe("UnitTransformationPipe", () => { - it("create an instance", () => { +describe('UnitTransformationPipe', () => { + it('create an instance', () => { const pipe = new UnitTransformationPipe(); expect(pipe) .toBeTruthy(); }); - it("Format Percent label", () => { + it('Format Percent label', () => { const pipe = new UnitTransformationPipe(); expect(pipe.transform(1, Unit.PERCENT)) - .toBe("1%"); + .toBe('1%'); }); - it("Format FTE label", () => { + it('Format FTE label', () => { const pipe = new UnitTransformationPipe(); expect(pipe.transform(1, Unit.FTE)) - .toBe("1 " + Unit.FTE); + .toBe('1 ' + Unit.FTE); }); - it("Format CHF label", () => { + it('Format CHF label', () => { const pipe = new UnitTransformationPipe(); expect(pipe.transform(1, Unit.CHF)) - .toBe("1 " + Unit.CHF); + .toBe('1 ' + Unit.CHF); }); - it("Format EUR label", () => { + it('Format EUR label', () => { const pipe = new UnitTransformationPipe(); expect(pipe.transform(1, Unit.EUR)) - .toBe("1 " + Unit.EUR); + .toBe('1 ' + Unit.EUR); }); - it("Format Number label", () => { + it('Format Number label', () => { const pipe = new UnitTransformationPipe(); expect(pipe.transform(1, Unit.NUMBER)) - .toBe("1"); + .toBe('1'); }); - it("should format as Percent", () => { + it('should format as Percent', () => { const pipe = new UnitTransformationPipe(); expect(pipe.transform(38, Unit.PERCENT)) - .toBe("38%"); + .toBe('38%'); }); - it("should format as Number", () => { + it('should format as Number', () => { const pipe = new UnitTransformationPipe(); expect(pipe.transform(38000, Unit.NUMBER)) - .toBe("38'000"); + .toBe('38\'000'); }); - it("should format as CHF as double value", () => { + it('should format as CHF as double value', () => { const pipe = new UnitTransformationPipe(); expect(pipe.transform(380.987, Unit.NUMBER)) - .toBe("380.99"); + .toBe('380.99'); }); - it("should return with no format if unit is not known", () => { + it('should return with no format if unit is not known', () => { const pipe = new UnitTransformationPipe(); - expect(pipe.transform(134, "Some Unit")) - .toBe("134"); + expect(pipe.transform(134, 'Some Unit')) + .toBe('134'); }); }); diff --git a/frontend/src/app/shared/pipes/unit-transformation/unit-transformation.pipe.ts b/frontend/src/app/shared/pipes/unit-transformation/unit-transformation.pipe.ts index 28ab671938..7f19df97f4 100644 --- a/frontend/src/app/shared/pipes/unit-transformation/unit-transformation.pipe.ts +++ b/frontend/src/app/shared/pipes/unit-transformation/unit-transformation.pipe.ts @@ -1,8 +1,8 @@ -import { Unit } from "../../types/enums/Unit"; -import { Pipe, PipeTransform } from "@angular/core"; +import { Unit } from '../../types/enums/Unit'; +import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ - name: "unitTransformation" + name: 'unitTransformation' }) export class UnitTransformationPipe implements PipeTransform { transform(value: number, label: string): string { @@ -10,27 +10,27 @@ export class UnitTransformationPipe implements PipeTransform { } transformValue(value: number): string { - return Number.isNaN(value) ? "0" : this.roundAndAddThousandSplitSign(value); + return Number.isNaN(value) ? '0' : this.roundAndAddThousandSplitSign(value); } roundAndAddThousandSplitSign(value: number): string { - return (+value.toFixed(2)).toLocaleString("en-US") - .replace(/,/g, "'"); + return (+value.toFixed(2)).toLocaleString('en-US') + .replace(/,/g, '\''); } transformLabel(label: string): string { switch (label) { case Unit.PERCENT: - return "%"; + return '%'; case Unit.FTE: - return " " + Unit.FTE; + return ' ' + Unit.FTE; case Unit.CHF: - return " " + Unit.CHF; + return ' ' + Unit.CHF; case Unit.EUR: - return " " + Unit.EUR; + return ' ' + Unit.EUR; case Unit.NUMBER: default: - return ""; + return ''; } } } diff --git a/frontend/src/app/shared/regexLibrary.ts b/frontend/src/app/shared/regexLibrary.ts index 569f84c3be..812d6cc364 100644 --- a/frontend/src/app/shared/regexLibrary.ts +++ b/frontend/src/app/shared/regexLibrary.ts @@ -1,2 +1,2 @@ -export const PERCENT_REGEX = "^-?[0-9][0-9]?(\\.[0-9]*)?$|^100$"; -export const NUMBER_REGEX = "^-?[0-9][0-9]*.?[0-9]*?$"; +export const PERCENT_REGEX = '^-?[0-9][0-9]?(\\.[0-9]*)?$|^100$'; +export const NUMBER_REGEX = '^-?[0-9][0-9]*.?[0-9]*?$'; diff --git a/frontend/src/app/shared/routeUtils.spec.ts b/frontend/src/app/shared/routeUtils.spec.ts index 1bae11ab22..28668d669a 100644 --- a/frontend/src/app/shared/routeUtils.spec.ts +++ b/frontend/src/app/shared/routeUtils.spec.ts @@ -1,32 +1,32 @@ -import { getRouteToTeam, getRouteToUserDetails } from "./routeUtils"; +import { getRouteToTeam, getRouteToUserDetails } from './routeUtils'; -describe("routeUtils", () => { - describe("getRouteToUserDetails", () => { - it("should not include team fragment when teamId is missing", () => { +describe('routeUtils', () => { + describe('getRouteToUserDetails', () => { + it('should not include team fragment when teamId is missing', () => { expect(getRouteToUserDetails(1)) - .toBe("/team-management/details/member/1"); + .toBe('/team-management/details/member/1'); }); - it("should include team fragment when teamId is missing", () => { + it('should include team fragment when teamId is missing', () => { expect(getRouteToUserDetails(1, 11)) - .toBe("/team-management/11/details/member/1"); + .toBe('/team-management/11/details/member/1'); }); - it("should work with id=0", () => { + it('should work with id=0', () => { expect(getRouteToUserDetails(0, 0)) - .toBe("/team-management/0/details/member/0"); + .toBe('/team-management/0/details/member/0'); }); }); - describe("getRouteToTeam", () => { - it("should work with normal id", () => { + describe('getRouteToTeam', () => { + it('should work with normal id', () => { expect(getRouteToTeam(1)) - .toBe("/team-management/1"); + .toBe('/team-management/1'); }); - it("should work with id=0", () => { + it('should work with id=0', () => { expect(getRouteToTeam(0)) - .toBe("/team-management/0"); + .toBe('/team-management/0'); }); }); }); diff --git a/frontend/src/app/shared/routeUtils.ts b/frontend/src/app/shared/routeUtils.ts index 3f3ab7e8f7..ce92eb314d 100644 --- a/frontend/src/app/shared/routeUtils.ts +++ b/frontend/src/app/shared/routeUtils.ts @@ -1,6 +1,6 @@ export const getRouteToUserDetails = (userId: number, teamId?: number) => { - const teamFragment = teamId !== undefined ? `/${teamId}` : ""; + const teamFragment = teamId !== undefined ? `/${teamId}` : ''; return `/team-management${teamFragment}/details/member/${userId}`; }; export const getRouteToTeam = (teamId: number) => `${getRouteToAllTeams()}/${teamId}`; -export const getRouteToAllTeams = () => "/team-management"; +export const getRouteToAllTeams = () => '/team-management'; diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts index d039ac75f6..4c6c53185e 100644 --- a/frontend/src/app/shared/shared.module.ts +++ b/frontend/src/app/shared/shared.module.ts @@ -1,30 +1,30 @@ -import { NgModule } from "@angular/core"; -import { CommonModule, NgOptimizedImage } from "@angular/common"; -import { ExampleDialogComponent } from "./dialog/example-dialog/example-dialog.component"; -import { ObjectiveFormComponent } from "./dialog/objective-dialog/objective-form.component"; -import { ConfirmDialogComponent } from "./dialog/confirm-dialog/confirm-dialog.component"; -import { ScoringComponent } from "./custom/scoring/scoring.component"; -import { CompleteDialogComponent } from "./dialog/complete-dialog/complete-dialog.component"; -import { MatDialogModule } from "@angular/material/dialog"; -import { MatCheckboxModule } from "@angular/material/checkbox"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { MatSelectModule } from "@angular/material/select"; -import { MatRadioModule } from "@angular/material/radio"; -import { MatIconModule } from "@angular/material/icon"; -import { OkrTangramComponent } from "./custom/okr-tangram/okr-tangram.component"; -import { MatButtonModule } from "@angular/material/button"; -import { SidepanelComponent } from "./sidepanel/sidepanel.component"; -import { MatSidenavModule } from "@angular/material/sidenav"; -import { CdkConnectedOverlay, CdkOverlayOrigin } from "@angular/cdk/overlay"; -import { A11yModule } from "@angular/cdk/a11y"; -import { RouterOutlet } from "@angular/router"; -import { SpinnerComponent } from "./custom/spinner/spinner.component"; -import { MatProgressSpinnerModule } from "@angular/material/progress-spinner"; -import { DialogTemplateCoreComponent } from "./custom/dialog-template-core/dialog-template-core.component"; -import { MatDividerModule } from "@angular/material/divider"; -import { UnitTransformationPipe } from "./pipes/unit-transformation/unit-transformation.pipe"; -import { MatTooltip } from "@angular/material/tooltip"; +import { NgModule } from '@angular/core'; +import { CommonModule, NgOptimizedImage } from '@angular/common'; +import { ExampleDialogComponent } from './dialog/example-dialog/example-dialog.component'; +import { ObjectiveFormComponent } from './dialog/objective-dialog/objective-form.component'; +import { ConfirmDialogComponent } from './dialog/confirm-dialog/confirm-dialog.component'; +import { ScoringComponent } from './custom/scoring/scoring.component'; +import { CompleteDialogComponent } from './dialog/complete-dialog/complete-dialog.component'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatSelectModule } from '@angular/material/select'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatIconModule } from '@angular/material/icon'; +import { OkrTangramComponent } from './custom/okr-tangram/okr-tangram.component'; +import { MatButtonModule } from '@angular/material/button'; +import { SidepanelComponent } from './sidepanel/sidepanel.component'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay'; +import { A11yModule } from '@angular/cdk/a11y'; +import { RouterOutlet } from '@angular/router'; +import { SpinnerComponent } from './custom/spinner/spinner.component'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { DialogTemplateCoreComponent } from './custom/dialog-template-core/dialog-template-core.component'; +import { MatDividerModule } from '@angular/material/divider'; +import { UnitTransformationPipe } from './pipes/unit-transformation/unit-transformation.pipe'; +import { MatTooltip } from '@angular/material/tooltip'; @NgModule({ declarations: [ diff --git a/frontend/src/app/shared/sidepanel/sidepanel.component.ts b/frontend/src/app/shared/sidepanel/sidepanel.component.ts index 61d1978030..5732df0f81 100644 --- a/frontend/src/app/shared/sidepanel/sidepanel.component.ts +++ b/frontend/src/app/shared/sidepanel/sidepanel.component.ts @@ -6,32 +6,32 @@ import { ElementRef, OnDestroy, ViewChild -} from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; -import { ConnectedPosition } from "@angular/cdk/overlay"; // ESM +} from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { ConnectedPosition } from '@angular/cdk/overlay'; // ESM @Component({ - selector: "app-sidepanel", - templateUrl: "./sidepanel.component.html", - styleUrls: ["./sidepanel.component.scss"], + selector: 'app-sidepanel', + templateUrl: './sidepanel.component.html', + styleUrls: ['./sidepanel.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class SidepanelComponent implements AfterContentInit, OnDestroy { - leaveKeys = ["Escape"]; + leaveKeys = ['Escape']; - right = "-100%"; + right = '-100%'; loaded = false; - @ViewChild("sidebar") + @ViewChild('sidebar') sidebar!: ElementRef; position: ConnectedPosition[] = [{ - originX: "end", - originY: "bottom", - overlayX: "end", - overlayY: "top" + originX: 'end', + originY: 'bottom', + overlayX: 'end', + overlayY: 'top' }]; constructor(private router: Router, @@ -39,18 +39,18 @@ export class SidepanelComponent implements AfterContentInit, OnDestroy { private route: ActivatedRoute) {} ngAfterContentInit(): void { - document.body.classList.add("disable-scrolling"); - this.right = "0"; + document.body.classList.add('disable-scrolling'); + this.right = '0'; this.loaded = true; this.cd.markForCheck(); } ngOnDestroy() { - document.body.classList.remove("disable-scrolling"); + document.body.classList.remove('disable-scrolling'); } close() { - this.router.navigate(["../"], { relativeTo: this.route }); + this.router.navigate(['../'], { relativeTo: this.route }); } closeOnKeydown($event: KeyboardEvent) { diff --git a/frontend/src/app/shared/testData.ts b/frontend/src/app/shared/testData.ts index b9f1bcb3d4..28be1e9f73 100644 --- a/frontend/src/app/shared/testData.ts +++ b/frontend/src/app/shared/testData.ts @@ -1,59 +1,59 @@ -import { State } from "./types/enums/State"; -import { KeyResultMetricMin } from "./types/model/KeyResultMetricMin"; -import { KeyResultOrdinalMin } from "./types/model/KeyResultOrdinalMin"; -import { KeyresultMin } from "./types/model/KeyresultMin"; -import { ObjectiveMin } from "./types/model/ObjectiveMin"; -import { OverviewEntity } from "./types/model/OverviewEntity"; -import { KeyResultObjective } from "./types/model/KeyResultObjective"; -import { Quarter } from "./types/model/Quarter"; -import { KeyResultOrdinal } from "./types/model/KeyResultOrdinal"; -import { Objective } from "./types/model/Objective"; -import { User } from "./types/model/User"; -import { KeyResultMetric } from "./types/model/KeyResultMetric"; -import { Unit } from "./types/enums/Unit"; -import { Team } from "./types/model/Team"; -import { Action } from "./types/model/Action"; -import { CheckInOrdinal } from "./types/model/CheckInOrdinal"; -import { CheckInMetric } from "./types/model/CheckInMetric"; -import { CheckInOrdinalMin } from "./types/model/CheckInOrdinalMin"; -import { CheckInMetricMin } from "./types/model/CheckInMetricMin"; +import { State } from './types/enums/State'; +import { KeyResultMetricMin } from './types/model/KeyResultMetricMin'; +import { KeyResultOrdinalMin } from './types/model/KeyResultOrdinalMin'; +import { KeyresultMin } from './types/model/KeyresultMin'; +import { ObjectiveMin } from './types/model/ObjectiveMin'; +import { OverviewEntity } from './types/model/OverviewEntity'; +import { KeyResultObjective } from './types/model/KeyResultObjective'; +import { Quarter } from './types/model/Quarter'; +import { KeyResultOrdinal } from './types/model/KeyResultOrdinal'; +import { Objective } from './types/model/Objective'; +import { User } from './types/model/User'; +import { KeyResultMetric } from './types/model/KeyResultMetric'; +import { Unit } from './types/enums/Unit'; +import { Team } from './types/model/Team'; +import { Action } from './types/model/Action'; +import { CheckInOrdinal } from './types/model/CheckInOrdinal'; +import { CheckInMetric } from './types/model/CheckInMetric'; +import { CheckInOrdinalMin } from './types/model/CheckInOrdinalMin'; +import { CheckInMetricMin } from './types/model/CheckInMetricMin'; export const teamFormObject = { - name: "newTeamName" + name: 'newTeamName' }; export const marketingTeamWriteable: Team = { id: 1, version: 2, - name: "Marketing Team", + name: 'Marketing Team', writeable: true }; export const marketingTeamNotWriteable: Team = { id: 1, version: 3, - name: "Marketing Team", + name: 'Marketing Team', writeable: false }; export const team1: Team = { id: 1, version: 2, - name: "Team1", + name: 'Team1', writeable: false }; export const team2: Team = { id: 2, version: 3, - name: "Team2", + name: 'Team2', writeable: false }; export const team3: Team = { id: 3, version: 4, - name: "Team3", + name: 'Team3', writeable: false }; @@ -64,7 +64,7 @@ export const teamList = [team1, export const action1: Action = { id: 33, version: 1, - action: "Drucker kaufen", + action: 'Drucker kaufen', priority: 0, isChecked: false, keyResultId: 1 @@ -73,7 +73,7 @@ export const action1: Action = { export const action2: Action = { id: 44, version: 1, - action: "Blätter kaufen", + action: 'Blätter kaufen', priority: 1, isChecked: true, keyResultId: 2 @@ -82,32 +82,32 @@ export const action2: Action = { export const action3: Action = { id: null, version: 1, - action: "", + action: '', priority: 3, isChecked: false, keyResultId: null }; export const addedAction: Action = { - action: "", + action: '', priority: 0, keyResultId: 1 } as Action; export const quarterMin: Quarter = new Quarter( - 1, "GJ 23/24-Q1", null, null + 1, 'GJ 23/24-Q1', null, null ); export const quarter1: Quarter = new Quarter( - 1, "GJ 22/23-Q4", new Date("2023-04-01"), new Date("2023-07-30") + 1, 'GJ 22/23-Q4', new Date('2023-04-01'), new Date('2023-07-30') ); export const quarter2: Quarter = new Quarter( - 2, "GJ 22/23-Q3", new Date("2023-01-01"), new Date("2023-03-31") + 2, 'GJ 22/23-Q3', new Date('2023-01-01'), new Date('2023-03-31') ); export const quarterBacklog: Quarter = new Quarter( - 999, "GJ 23/24-Q1", null, null + 999, 'GJ 23/24-Q1', null, null ); export const quarterList: Quarter[] = [quarter1, @@ -119,9 +119,9 @@ export const checkInMetric: CheckInMetricMin = { version: 1, value: 15, confidence: 5, - createdOn: "2023-07-20T12:34:56Z" as unknown as Date, - initiatives: "Initiatives metric", - changeInfo: "Changeinfo metric", + createdOn: '2023-07-20T12:34:56Z' as unknown as Date, + initiatives: 'Initiatives metric', + changeInfo: 'Changeinfo metric', writeable: true } as CheckInMetricMin; @@ -130,41 +130,41 @@ export const checkInMetricWriteableFalse: CheckInMetricMin = { version: 1, value: 15, confidence: 6, - createdOn: "2023-07-20T12:34:56Z" as unknown as Date, - initiatives: "Initiatives metric writeable false", - changeInfo: "Changeinfo metric writeable false", + createdOn: '2023-07-20T12:34:56Z' as unknown as Date, + initiatives: 'Initiatives metric writeable false', + changeInfo: 'Changeinfo metric writeable false', writeable: false } as CheckInMetricMin; export const checkInOrdinal: CheckInOrdinalMin = { id: 816, version: 2, - zone: "COMMIT", + zone: 'COMMIT', confidence: 7, - createdOn: "2023-07-22T08:45:21Z" as unknown as Date, - initiatives: "Initiatives ordinal", - changeInfo: "Changeinfo ordinal", + createdOn: '2023-07-22T08:45:21Z' as unknown as Date, + initiatives: 'Initiatives ordinal', + changeInfo: 'Changeinfo ordinal', writeable: true } as CheckInOrdinalMin; export const keyResultMetricMin: KeyResultMetricMin = { id: 201, version: 1, - title: "Achieve 20% Increase in Daily Active Users", - keyResultType: "metric", - unit: "%", + title: 'Achieve 20% Increase in Daily Active Users', + keyResultType: 'metric', + unit: '%', baseline: 10.0, stretchGoal: 25.0, lastCheckIn: checkInMetric, - type: "keyResult" + type: 'keyResult' } as KeyResultMetricMin; export const keyResultMetricMinScoring: KeyResultMetricMin = { id: 201, version: 1, - title: "Achieve 20% Increase in Daily Active Users", - keyResultType: "metric", - unit: "%", + title: 'Achieve 20% Increase in Daily Active Users', + keyResultType: 'metric', + unit: '%', baseline: 25.0, stretchGoal: 75.0, lastCheckIn: { @@ -174,19 +174,19 @@ export const keyResultMetricMinScoring: KeyResultMetricMin = { confidence: 4, createdOn: new Date(), modifiedOn: new Date(), - changeInfo: "Half way through", - initiatives: "Quality before quantity", + changeInfo: 'Half way through', + initiatives: 'Quality before quantity', writeable: true }, - type: "keyResult" + type: 'keyResult' } as KeyResultMetricMin; export const keyResultMetricMinScoringInversion: KeyResultMetricMin = { id: 306, version: 1, - title: "Achieve 20% Increase in Daily Active Users", - keyResultType: "metric", - unit: "%", + title: 'Achieve 20% Increase in Daily Active Users', + keyResultType: 'metric', + unit: '%', baseline: 50.0, stretchGoal: 0.0, lastCheckIn: { @@ -196,47 +196,47 @@ export const keyResultMetricMinScoringInversion: KeyResultMetricMin = { confidence: 4, createdOn: new Date(), modifiedOn: new Date(), - changeInfo: "More Changes", - initiatives: "Some initatives", + changeInfo: 'More Changes', + initiatives: 'Some initatives', writeable: true }, - type: "keyResult" + type: 'keyResult' } as KeyResultMetricMin; export const keyResultOrdinalMinScoring: KeyResultOrdinalMin = { id: 202, version: 1, - title: "We want to bake 10 cakes", - keyResultType: "ordinal", - commitZone: "5 cakes", - targetZone: "10 cakes", - stretchGoal: "13 cakes", + title: 'We want to bake 10 cakes', + keyResultType: 'ordinal', + commitZone: '5 cakes', + targetZone: '10 cakes', + stretchGoal: '13 cakes', lastCheckIn: { id: 830, version: 1, - zone: "COMMIT", + zone: 'COMMIT', confidence: 8, - createdOn: "2023-07-22T08:45:21Z" as unknown as Date, - initiatives: "Initiatives of ordinal", - changeInfo: "Changeinfo ordinal" + createdOn: '2023-07-22T08:45:21Z' as unknown as Date, + initiatives: 'Initiatives of ordinal', + changeInfo: 'Changeinfo ordinal' } as CheckInOrdinalMin } as KeyResultOrdinalMin; export const keyResultOrdinalMin: KeyResultOrdinalMin = { id: 202, version: 1, - title: "Reduce Bounce Rate", - keyResultType: "ordinal", - commitZone: "3 Birnen", - targetZone: "2 Birnen und 2 Äpfel", - stretchGoal: "Alle Früchte", + title: 'Reduce Bounce Rate', + keyResultType: 'ordinal', + commitZone: '3 Birnen', + targetZone: '2 Birnen und 2 Äpfel', + stretchGoal: 'Alle Früchte', lastCheckIn: checkInOrdinal } as KeyResultOrdinalMin; export const objectiveMin: ObjectiveMin = { id: 101, version: 1, - title: "Increase User Engagement", + title: 'Increase User Engagement', state: State.ONGOING, quarter: quarterMin, keyResults: [keyResultMetricMin, @@ -246,8 +246,8 @@ export const objectiveMin: ObjectiveMin = { export const objectiveResponse1: any = { id: 101, version: 1, - title: "Increase Environment Engagement", - state: "ONGOING", + title: 'Increase Environment Engagement', + state: 'ONGOING', quarter: quarterMin, keyResults: [keyResultMetricMin, keyResultOrdinalMin] as KeyresultMin[] @@ -256,8 +256,8 @@ export const objectiveResponse1: any = { export const objectiveResponse2: any = { id: 102, version: 1, - title: "Increase Social Engagement", - state: "DRAFT", + title: 'Increase Social Engagement', + state: 'DRAFT', quarter: quarterMin, keyResults: [keyResultMetricMin, keyResultOrdinalMin] as KeyresultMin[] @@ -266,8 +266,8 @@ export const objectiveResponse2: any = { export const objectiveResponse3: any = { id: 103, version: 1, - title: "Increase Member Engagement", - state: "NOTSUCCESSFUL", + title: 'Increase Member Engagement', + state: 'NOTSUCCESSFUL', quarter: quarterMin, keyResults: [keyResultMetricMin, keyResultOrdinalMin] as KeyresultMin[] @@ -276,8 +276,8 @@ export const objectiveResponse3: any = { export const objectiveResponse4: any = { id: 104, version: 1, - title: "Increase Company Engagement", - state: "SUCCESSFUL", + title: 'Increase Company Engagement', + state: 'SUCCESSFUL', quarter: quarterMin, keyResults: [keyResultMetricMin, keyResultOrdinalMin] as KeyresultMin[] @@ -317,7 +317,7 @@ export const overviews: OverviewEntity[] = [overViewEntityResponse1, overViewEntityResponse2]; export const quarter: Quarter = new Quarter( - 1, "23.02.2025", new Date(), new Date() + 1, '23.02.2025', new Date(), new Date() ); export const keyResultObjective: KeyResultObjective = { @@ -329,22 +329,22 @@ export const keyResultObjective: KeyResultObjective = { export const keyResultMetricWithIdEight: KeyResultMetricMin = { id: 8, version: 1, - title: "KeyResult Title", - unit: "CHF", + title: 'KeyResult Title', + unit: 'CHF', baseline: 5.0, stretchGoal: 15.0, lastCheckIn: checkInMetric, - keyResultType: "keyResult" + keyResultType: 'keyResult' } as KeyResultMetricMin; export const objective: Objective = { id: 5, version: 1, - title: "title", - description: "description", + title: 'title', + description: 'description', teamId: 2, quarterId: 2, - quarterLabel: "GJ 22/23-Q2", + quarterLabel: 'GJ 22/23-Q2', state: State.SUCCESSFUL, writeable: true }; @@ -352,11 +352,11 @@ export const objective: Objective = { export const objectiveWriteableFalse: Objective = { id: 6, version: 1, - title: "titleWriteableFalse", - description: "descriptionWriteableFalse", + title: 'titleWriteableFalse', + description: 'descriptionWriteableFalse', teamId: 2, quarterId: 2, - quarterLabel: "GJ 22/23-Q2", + quarterLabel: 'GJ 22/23-Q2', state: State.NOTSUCCESSFUL, writeable: false }; @@ -366,8 +366,8 @@ export const firstCheckIn: CheckInMetricMin = { version: 1, value: 77, confidence: 5, - changeInfo: "", - initiatives: "", + changeInfo: '', + initiatives: '', createdOn: new Date(), writeable: true }; @@ -377,81 +377,81 @@ export const secondCheckIn: CheckInMetricMin = { version: 1, value: 89, confidence: 5, - changeInfo: "", - initiatives: "", + changeInfo: '', + initiatives: '', createdOn: new Date(), writeable: true }; export const testUser: User = { id: 1, - firstname: "Bob", - lastname: "Baumeister", + firstname: 'Bob', + lastname: 'Baumeister', isOkrChampion: false, userTeamList: [{ id: 1, team: team1, isTeamAdmin: false }], - email: "bob.baumeister@puzzle.ch" + email: 'bob.baumeister@puzzle.ch' }; export const users: User[] = [ testUser, { id: 2, - firstname: "Paco", - lastname: "Egiman", + firstname: 'Paco', + lastname: 'Egiman', isOkrChampion: true, userTeamList: [], - email: "peggimann@puzzle.ch" + email: 'peggimann@puzzle.ch' }, { id: 3, - firstname: "Robin", - lastname: "Papier", + firstname: 'Robin', + lastname: 'Papier', isOkrChampion: false, userTeamList: [], - email: "robin.papier@puzzle.ch" + email: 'robin.papier@puzzle.ch' }, { id: 4, - firstname: "Key Result", - lastname: "Owner", + firstname: 'Key Result', + lastname: 'Owner', isOkrChampion: false, userTeamList: [], - email: "keyresult.owner@puzzle.ch" + email: 'keyresult.owner@puzzle.ch' } ]; export const keyResult: KeyResultOrdinal = { id: 101, version: 1, - title: "Ausbauen des Früchtesortiments", - description: "Dient zur Gesunderhaltung der Members", - commitZone: "Äpfel", - targetZone: "Äpfel und Birnen", - stretchZone: "Äpfel, Birnen, Bananen und Erdberen", + title: 'Ausbauen des Früchtesortiments', + description: 'Dient zur Gesunderhaltung der Members', + commitZone: 'Äpfel', + targetZone: 'Äpfel und Birnen', + stretchZone: 'Äpfel, Birnen, Bananen und Erdberen', owner: users[3], - keyResultType: "ordinal", + keyResultType: 'ordinal', objective: { id: 301, version: 1, state: State.DRAFT, quarter: new Quarter( - 1, "GJ 23/24-Q1", new Date(), new Date() + 1, 'GJ 23/24-Q1', new Date(), new Date() ), writeable: true } as KeyResultObjective, lastCheckIn: { id: 745, version: 1, - zone: "FAIL", + zone: 'FAIL', confidence: 8, createdOn: new Date(), modifiedOn: new Date(), - changeInfo: "info", - initiatives: "some", + changeInfo: 'info', + initiatives: 'some', writeable: true } as CheckInOrdinal, createdOn: new Date(), @@ -463,31 +463,31 @@ export const keyResult: KeyResultOrdinal = { export const keyResultOrdinal: KeyResultOrdinal = { id: 101, version: 1, - title: "Bauen eines Hauses", - description: "Ein neues Haus für die Puzzle Members", - commitZone: "Grundriss steht", - targetZone: "Gebäude gebaut", - stretchZone: "Inneneinrichtung gestaltet", + title: 'Bauen eines Hauses', + description: 'Ein neues Haus für die Puzzle Members', + commitZone: 'Grundriss steht', + targetZone: 'Gebäude gebaut', + stretchZone: 'Inneneinrichtung gestaltet', owner: users[3], - keyResultType: "ordinal", + keyResultType: 'ordinal', objective: { id: 301, version: 1, state: State.DRAFT, quarter: new Quarter( - 1, "GJ 23/24-Q1", new Date(), new Date() + 1, 'GJ 23/24-Q1', new Date(), new Date() ), writeable: true } as KeyResultObjective, lastCheckIn: { id: 746, version: 1, - zone: "FAIL", + zone: 'FAIL', confidence: 3, createdOn: new Date(), modifiedOn: new Date(), - changeInfo: "Does not look good", - initiatives: "We have to be faster", + changeInfo: 'Does not look good', + initiatives: 'We have to be faster', writeable: true } as CheckInOrdinal, createdOn: new Date(), @@ -499,31 +499,31 @@ export const keyResultOrdinal: KeyResultOrdinal = { export const keyResultWriteableFalse: KeyResultOrdinal = { id: 101, version: 1, - title: "This is not writeable", - description: "Still not writeable", - commitZone: "Not writeable", - targetZone: "Not writeable", - stretchZone: "Not writeable", + title: 'This is not writeable', + description: 'Still not writeable', + commitZone: 'Not writeable', + targetZone: 'Not writeable', + stretchZone: 'Not writeable', owner: users[3], - keyResultType: "ordinal", + keyResultType: 'ordinal', objective: { id: 301, version: 1, state: State.DRAFT, quarter: new Quarter( - 1, "GJ 23/24-Q1", new Date(), new Date() + 1, 'GJ 23/24-Q1', new Date(), new Date() ), writeable: false } as KeyResultObjective, lastCheckIn: { id: 746, version: 1, - zone: "FAIL", + zone: 'FAIL', confidence: 3, createdOn: new Date(), modifiedOn: new Date(), - changeInfo: "Also not writeable", - initiatives: "Perhaps make it writeable", + changeInfo: 'Also not writeable', + initiatives: 'Perhaps make it writeable', writeable: false } as CheckInOrdinal, createdOn: new Date(), @@ -535,19 +535,19 @@ export const keyResultWriteableFalse: KeyResultOrdinal = { export const keyResultMetric: KeyResultMetric = { id: 102, version: 1, - title: "100% aller Schweizer Kunden betreuen", - description: "Puzzle ITC erledigt die IT-Aufträge für 100% aller Unternehmen.", + title: '100% aller Schweizer Kunden betreuen', + description: 'Puzzle ITC erledigt die IT-Aufträge für 100% aller Unternehmen.', baseline: 30, stretchGoal: 100, unit: Unit.PERCENT, owner: users[3], - keyResultType: "metric", + keyResultType: 'metric', objective: { id: 302, version: 1, state: State.DRAFT, quarter: new Quarter( - 1, "GJ 23/24-Q1", new Date(), new Date() + 1, 'GJ 23/24-Q1', new Date(), new Date() ), writeable: true } as KeyResultObjective, @@ -558,8 +558,8 @@ export const keyResultMetric: KeyResultMetric = { confidence: 7, createdOn: new Date(), modifiedOn: new Date(), - changeInfo: "So far so good", - initiatives: "Work a bit harder", + changeInfo: 'So far so good', + initiatives: 'Work a bit harder', writeable: true } as CheckInMetric, createdOn: new Date(), @@ -572,18 +572,18 @@ export const keyResultMetric: KeyResultMetric = { export const keyResultActions: KeyResultMetric = { id: 334, version: 1, - title: "Das Büro ist modern und vollständig", - description: "Puzzle ITC hat schöne Büros, wo es alles hat.", + title: 'Das Büro ist modern und vollständig', + description: 'Puzzle ITC hat schöne Büros, wo es alles hat.', baseline: 10, stretchGoal: 30, unit: Unit.PERCENT, owner: users[3], - keyResultType: "metric", + keyResultType: 'metric', objective: { id: 302, state: State.DRAFT, quarter: new Quarter( - 1, "GJ 23/24-Q1", new Date(), new Date() + 1, 'GJ 23/24-Q1', new Date(), new Date() ), writeable: true } as KeyResultObjective, @@ -593,8 +593,8 @@ export const keyResultActions: KeyResultMetric = { confidence: 7, createdOn: new Date(), modifiedOn: new Date(), - changeInfo: "So far so good", - initiatives: "Work a bit harder", + changeInfo: 'So far so good', + initiatives: 'Work a bit harder', writeable: true } as CheckInMetric, createdOn: new Date(), diff --git a/frontend/src/app/shared/types/DTOs/KeyResultDTO.ts b/frontend/src/app/shared/types/DTOs/KeyResultDTO.ts index 5958ac023f..a534770c30 100644 --- a/frontend/src/app/shared/types/DTOs/KeyResultDTO.ts +++ b/frontend/src/app/shared/types/DTOs/KeyResultDTO.ts @@ -1,7 +1,7 @@ -import { User } from "../model/User"; -import { Objective } from "../model/Objective"; -import { CheckIn } from "../model/CheckIn"; -import { Action } from "../model/Action"; +import { User } from '../model/User'; +import { Objective } from '../model/Objective'; +import { CheckIn } from '../model/CheckIn'; +import { Action } from '../model/Action'; export interface KeyResultDTO { id: number | undefined; diff --git a/frontend/src/app/shared/types/DTOs/KeyResultMetricDTO.ts b/frontend/src/app/shared/types/DTOs/KeyResultMetricDTO.ts index 5c2c0dd70c..2c67ce87c4 100644 --- a/frontend/src/app/shared/types/DTOs/KeyResultMetricDTO.ts +++ b/frontend/src/app/shared/types/DTOs/KeyResultMetricDTO.ts @@ -1,4 +1,4 @@ -import { KeyResultDTO } from "./KeyResultDTO"; +import { KeyResultDTO } from './KeyResultDTO'; export interface KeyResultMetricDTO extends KeyResultDTO { unit: string | null; diff --git a/frontend/src/app/shared/types/DTOs/KeyResultOrdinalDTO.ts b/frontend/src/app/shared/types/DTOs/KeyResultOrdinalDTO.ts index d86e030e1b..0c4fd1d1da 100644 --- a/frontend/src/app/shared/types/DTOs/KeyResultOrdinalDTO.ts +++ b/frontend/src/app/shared/types/DTOs/KeyResultOrdinalDTO.ts @@ -1,4 +1,4 @@ -import { KeyResultDTO } from "./KeyResultDTO"; +import { KeyResultDTO } from './KeyResultDTO'; export interface KeyResultOrdinalDTO extends KeyResultDTO { commitZone: string | undefined; diff --git a/frontend/src/app/shared/types/enums/HttpType.ts b/frontend/src/app/shared/types/enums/HttpType.ts index 16f1da38f3..447847de66 100644 --- a/frontend/src/app/shared/types/enums/HttpType.ts +++ b/frontend/src/app/shared/types/enums/HttpType.ts @@ -1,6 +1,6 @@ export enum HttpType { - GET = "GET", - POST = "POST", - PUT = "PUT", - DELETE = "DELETE" + GET = 'GET', + POST = 'POST', + PUT = 'PUT', + DELETE = 'DELETE' } diff --git a/frontend/src/app/shared/types/enums/State.ts b/frontend/src/app/shared/types/enums/State.ts index 0179e56998..30de3e8ba6 100644 --- a/frontend/src/app/shared/types/enums/State.ts +++ b/frontend/src/app/shared/types/enums/State.ts @@ -1,6 +1,6 @@ export enum State { - ONGOING = "ongoing-icon.svg", - NOTSUCCESSFUL = "not-successful-icon.svg", - SUCCESSFUL = "successful-icon.svg", - DRAFT = "draft-icon.svg" + ONGOING = 'ongoing-icon.svg', + NOTSUCCESSFUL = 'not-successful-icon.svg', + SUCCESSFUL = 'successful-icon.svg', + DRAFT = 'draft-icon.svg' } diff --git a/frontend/src/app/shared/types/enums/Unit.ts b/frontend/src/app/shared/types/enums/Unit.ts index 666adae0fa..3d54f43a62 100644 --- a/frontend/src/app/shared/types/enums/Unit.ts +++ b/frontend/src/app/shared/types/enums/Unit.ts @@ -1,7 +1,7 @@ export enum Unit { - PERCENT = "PERCENT", - CHF = "CHF", - EUR = "EUR", - FTE = "FTE", - NUMBER = "NUMBER" + PERCENT = 'PERCENT', + CHF = 'CHF', + EUR = 'EUR', + FTE = 'FTE', + NUMBER = 'NUMBER' } diff --git a/frontend/src/app/shared/types/enums/UserRole.ts b/frontend/src/app/shared/types/enums/UserRole.ts index 1c27871d00..edf0331a48 100644 --- a/frontend/src/app/shared/types/enums/UserRole.ts +++ b/frontend/src/app/shared/types/enums/UserRole.ts @@ -1,5 +1,5 @@ export enum UserRole { - OKR_CHAMPION = "OKR_CHAMPION", - TEAM_ADMIN = "TEAM_ADMIN", - TEAM_MEMBER = "TEAM_MEMBER" + OKR_CHAMPION = 'OKR_CHAMPION', + TEAM_ADMIN = 'TEAM_ADMIN', + TEAM_MEMBER = 'TEAM_MEMBER' } diff --git a/frontend/src/app/shared/types/enums/Zone.ts b/frontend/src/app/shared/types/enums/Zone.ts index 252eddabf7..5647887540 100644 --- a/frontend/src/app/shared/types/enums/Zone.ts +++ b/frontend/src/app/shared/types/enums/Zone.ts @@ -1,6 +1,6 @@ export enum Zone { - FAIL = "FAIL", - COMMIT = "COMMIT", - TARGET = "TARGET", - STRETCH = "STRETCH" + FAIL = 'FAIL', + COMMIT = 'COMMIT', + TARGET = 'TARGET', + STRETCH = 'STRETCH' } diff --git a/frontend/src/app/shared/types/model/CheckInMetric.ts b/frontend/src/app/shared/types/model/CheckInMetric.ts index 3176488927..ad7da9d1ce 100644 --- a/frontend/src/app/shared/types/model/CheckInMetric.ts +++ b/frontend/src/app/shared/types/model/CheckInMetric.ts @@ -1,4 +1,4 @@ -import { CheckIn } from "./CheckIn"; +import { CheckIn } from './CheckIn'; export interface CheckInMetric extends CheckIn { value: number; diff --git a/frontend/src/app/shared/types/model/CheckInMetricMin.ts b/frontend/src/app/shared/types/model/CheckInMetricMin.ts index 3da9521e6f..d29a18aa62 100644 --- a/frontend/src/app/shared/types/model/CheckInMetricMin.ts +++ b/frontend/src/app/shared/types/model/CheckInMetricMin.ts @@ -1,4 +1,4 @@ -import { CheckInMin } from "./CheckInMin"; +import { CheckInMin } from './CheckInMin'; export interface CheckInMetricMin extends CheckInMin { value: number | undefined; diff --git a/frontend/src/app/shared/types/model/CheckInOrdinal.ts b/frontend/src/app/shared/types/model/CheckInOrdinal.ts index fc3dfeda5b..23471a041b 100644 --- a/frontend/src/app/shared/types/model/CheckInOrdinal.ts +++ b/frontend/src/app/shared/types/model/CheckInOrdinal.ts @@ -1,4 +1,4 @@ -import { CheckIn } from "./CheckIn"; +import { CheckIn } from './CheckIn'; export interface CheckInOrdinal extends CheckIn { zone: string; diff --git a/frontend/src/app/shared/types/model/CheckInOrdinalMin.ts b/frontend/src/app/shared/types/model/CheckInOrdinalMin.ts index e20f4e5cbd..278e561fd7 100644 --- a/frontend/src/app/shared/types/model/CheckInOrdinalMin.ts +++ b/frontend/src/app/shared/types/model/CheckInOrdinalMin.ts @@ -1,4 +1,4 @@ -import { CheckInMin } from "./CheckInMin"; +import { CheckInMin } from './CheckInMin'; export interface CheckInOrdinalMin extends CheckInMin { zone: string | undefined; diff --git a/frontend/src/app/shared/types/model/Completed.ts b/frontend/src/app/shared/types/model/Completed.ts index 25e156cd4c..5db6c04e18 100644 --- a/frontend/src/app/shared/types/model/Completed.ts +++ b/frontend/src/app/shared/types/model/Completed.ts @@ -1,4 +1,4 @@ -import { Objective } from "./Objective"; +import { Objective } from './Objective'; export interface Completed { id: number | null; diff --git a/frontend/src/app/shared/types/model/KeyResult.ts b/frontend/src/app/shared/types/model/KeyResult.ts index b9e91d6e2f..ae9adaff26 100644 --- a/frontend/src/app/shared/types/model/KeyResult.ts +++ b/frontend/src/app/shared/types/model/KeyResult.ts @@ -1,6 +1,6 @@ -import { KeyResultObjective } from "./KeyResultObjective"; -import { User } from "./User"; -import { Action } from "./Action"; +import { KeyResultObjective } from './KeyResultObjective'; +import { User } from './User'; +import { Action } from './Action'; export interface KeyResult { id: number; diff --git a/frontend/src/app/shared/types/model/KeyResultMetric.ts b/frontend/src/app/shared/types/model/KeyResultMetric.ts index a7f5e1a228..d8e0645f44 100644 --- a/frontend/src/app/shared/types/model/KeyResultMetric.ts +++ b/frontend/src/app/shared/types/model/KeyResultMetric.ts @@ -1,5 +1,5 @@ -import { KeyResult } from "./KeyResult"; -import { CheckInMetric } from "./CheckInMetric"; +import { KeyResult } from './KeyResult'; +import { CheckInMetric } from './CheckInMetric'; export interface KeyResultMetric extends KeyResult { lastCheckIn: CheckInMetric | null; diff --git a/frontend/src/app/shared/types/model/KeyResultMetricMin.ts b/frontend/src/app/shared/types/model/KeyResultMetricMin.ts index fa40de7be3..c1d4399eea 100644 --- a/frontend/src/app/shared/types/model/KeyResultMetricMin.ts +++ b/frontend/src/app/shared/types/model/KeyResultMetricMin.ts @@ -1,5 +1,5 @@ -import { KeyresultMin } from "./KeyresultMin"; -import { CheckInMetricMin } from "./CheckInMetricMin"; +import { KeyresultMin } from './KeyresultMin'; +import { CheckInMetricMin } from './CheckInMetricMin'; export interface KeyResultMetricMin extends KeyresultMin { baseline: number; diff --git a/frontend/src/app/shared/types/model/KeyResultObjective.ts b/frontend/src/app/shared/types/model/KeyResultObjective.ts index c4ee2ac564..f1f2b143b0 100644 --- a/frontend/src/app/shared/types/model/KeyResultObjective.ts +++ b/frontend/src/app/shared/types/model/KeyResultObjective.ts @@ -1,5 +1,5 @@ -import { State } from "../enums/State"; -import { Quarter } from "./Quarter"; +import { State } from '../enums/State'; +import { Quarter } from './Quarter'; export interface KeyResultObjective { id: number; diff --git a/frontend/src/app/shared/types/model/KeyResultOrdinal.ts b/frontend/src/app/shared/types/model/KeyResultOrdinal.ts index 4c03c93f3a..bdc6ee563a 100644 --- a/frontend/src/app/shared/types/model/KeyResultOrdinal.ts +++ b/frontend/src/app/shared/types/model/KeyResultOrdinal.ts @@ -1,5 +1,5 @@ -import { KeyResult } from "./KeyResult"; -import { CheckInOrdinal } from "./CheckInOrdinal"; +import { KeyResult } from './KeyResult'; +import { CheckInOrdinal } from './CheckInOrdinal'; export interface KeyResultOrdinal extends KeyResult { lastCheckIn: CheckInOrdinal | null; diff --git a/frontend/src/app/shared/types/model/KeyResultOrdinalMin.ts b/frontend/src/app/shared/types/model/KeyResultOrdinalMin.ts index 07a35d30bf..43ebb46a63 100644 --- a/frontend/src/app/shared/types/model/KeyResultOrdinalMin.ts +++ b/frontend/src/app/shared/types/model/KeyResultOrdinalMin.ts @@ -1,5 +1,5 @@ -import { KeyresultMin } from "./KeyresultMin"; -import { CheckInOrdinalMin } from "./CheckInOrdinalMin"; +import { KeyresultMin } from './KeyresultMin'; +import { CheckInOrdinalMin } from './CheckInOrdinalMin'; export interface KeyResultOrdinalMin extends KeyresultMin { commitZone: string; diff --git a/frontend/src/app/shared/types/model/Objective.ts b/frontend/src/app/shared/types/model/Objective.ts index 882883a5e5..4126c61fd5 100644 --- a/frontend/src/app/shared/types/model/Objective.ts +++ b/frontend/src/app/shared/types/model/Objective.ts @@ -1,5 +1,5 @@ -import { State } from "../enums/State"; -import { User } from "./User"; +import { State } from '../enums/State'; +import { User } from './User'; export interface Objective { id: number; diff --git a/frontend/src/app/shared/types/model/ObjectiveMin.ts b/frontend/src/app/shared/types/model/ObjectiveMin.ts index b58a4f7ee1..a3d07b97d6 100644 --- a/frontend/src/app/shared/types/model/ObjectiveMin.ts +++ b/frontend/src/app/shared/types/model/ObjectiveMin.ts @@ -1,6 +1,6 @@ -import { KeyresultMin } from "./KeyresultMin"; -import { QuarterMin } from "./QuarterMin"; -import { State } from "../enums/State"; +import { KeyresultMin } from './KeyresultMin'; +import { QuarterMin } from './QuarterMin'; +import { State } from '../enums/State'; export interface ObjectiveMin { id: number; diff --git a/frontend/src/app/shared/types/model/OverviewEntity.ts b/frontend/src/app/shared/types/model/OverviewEntity.ts index ba6be85b03..e679a6101f 100644 --- a/frontend/src/app/shared/types/model/OverviewEntity.ts +++ b/frontend/src/app/shared/types/model/OverviewEntity.ts @@ -1,5 +1,5 @@ -import { ObjectiveMin } from "./ObjectiveMin"; -import { TeamMin } from "./TeamMin"; +import { ObjectiveMin } from './ObjectiveMin'; +import { TeamMin } from './TeamMin'; export interface OverviewEntity { team: TeamMin; diff --git a/frontend/src/app/shared/types/model/Quarter.ts b/frontend/src/app/shared/types/model/Quarter.ts index a069b8aa57..4668e78b9e 100644 --- a/frontend/src/app/shared/types/model/Quarter.ts +++ b/frontend/src/app/shared/types/model/Quarter.ts @@ -17,7 +17,7 @@ export class Quarter { readonly endDate: Date | null; fullLabel(): string { - return this.isCurrent() ? this.label + " Aktuell" : this.label; + return this.isCurrent() ? this.label + ' Aktuell' : this.label; } private isCurrent(): boolean { diff --git a/frontend/src/app/shared/types/model/User.ts b/frontend/src/app/shared/types/model/User.ts index 327e9ba8a4..736edc9bb9 100644 --- a/frontend/src/app/shared/types/model/User.ts +++ b/frontend/src/app/shared/types/model/User.ts @@ -1,5 +1,5 @@ -import { UserTeam } from "./UserTeam"; -import { UserTableEntry } from "./UserTableEntry"; +import { UserTeam } from './UserTeam'; +import { UserTableEntry } from './UserTableEntry'; export interface User { id: number; diff --git a/frontend/src/app/shared/types/model/UserTableEntry.ts b/frontend/src/app/shared/types/model/UserTableEntry.ts index 0c10f343fa..eb631f0d11 100644 --- a/frontend/src/app/shared/types/model/UserTableEntry.ts +++ b/frontend/src/app/shared/types/model/UserTableEntry.ts @@ -1,6 +1,6 @@ -import { User } from "./User"; -import { UserRole } from "../enums/UserRole"; -import { UserTeam } from "./UserTeam"; +import { User } from './User'; +import { UserRole } from '../enums/UserRole'; +import { UserTeam } from './UserTeam'; export interface UserTableEntry { id: number; diff --git a/frontend/src/app/shared/types/model/UserTeam.ts b/frontend/src/app/shared/types/model/UserTeam.ts index 1d70d37e33..aaca2eeaaf 100644 --- a/frontend/src/app/shared/types/model/UserTeam.ts +++ b/frontend/src/app/shared/types/model/UserTeam.ts @@ -1,4 +1,4 @@ -import { Team } from "./Team"; +import { Team } from './Team'; export interface UserTeam { id?: number; diff --git a/frontend/src/app/shared/validators.ts b/frontend/src/app/shared/validators.ts index 448d3a6ca1..1bd6ab32f3 100644 --- a/frontend/src/app/shared/validators.ts +++ b/frontend/src/app/shared/validators.ts @@ -1,9 +1,9 @@ -import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator, ValidatorFn } from "@angular/forms"; -import { Directive, Input } from "@angular/core"; -import { NUMBER_REGEX, PERCENT_REGEX } from "./regexLibrary"; +import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator, ValidatorFn } from '@angular/forms'; +import { Directive, Input } from '@angular/core'; +import { NUMBER_REGEX, PERCENT_REGEX } from './regexLibrary'; @Directive({ - selector: "[unitValueValidator]", + selector: '[unitValueValidator]', providers: [{ provide: NG_VALIDATORS, useExisting: UnitValueValidator, @@ -11,21 +11,21 @@ import { NUMBER_REGEX, PERCENT_REGEX } from "./regexLibrary"; }] }) export class UnitValueValidator implements Validator { - @Input("unitValueValidator") unit: string | null = ""; + @Input('unitValueValidator') unit: string | null = ''; validate(control: AbstractControl): ValidationErrors | null { const value: string = control.value; switch (this.unit) { - case "PERCENT": { + case 'PERCENT': { return this.proceedRegex(value, PERCENT_REGEX); } - case "CHF": { + case 'CHF': { return this.proceedRegex(value, NUMBER_REGEX); } - case "EUR": { + case 'EUR': { return this.proceedRegex(value, NUMBER_REGEX); } - case "NUMBER": { + case 'NUMBER': { return this.proceedRegex(value, NUMBER_REGEX); } default: { diff --git a/frontend/src/app/team-management/add-edit-team-dialog/add-edit-team-dialog.component.spec.ts b/frontend/src/app/team-management/add-edit-team-dialog/add-edit-team-dialog.component.spec.ts index b8487c77d4..1f2122c7ec 100644 --- a/frontend/src/app/team-management/add-edit-team-dialog/add-edit-team-dialog.component.spec.ts +++ b/frontend/src/app/team-management/add-edit-team-dialog/add-edit-team-dialog.component.spec.ts @@ -1,24 +1,24 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { provideHttpClientTesting } from "@angular/common/http/testing"; -import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from "@angular/material/dialog"; -import { MatIconModule } from "@angular/material/icon"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { MatSelectModule } from "@angular/material/select"; -import { ReactiveFormsModule } from "@angular/forms"; -import { MatInputModule } from "@angular/material/input"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { MatCheckboxModule } from "@angular/material/checkbox"; -import { TeamService } from "../../services/team.service"; -import { of } from "rxjs"; -import { marketingTeamWriteable, teamFormObject } from "../../shared/testData"; -import { Team } from "../../shared/types/model/Team"; -import { TranslateService } from "@ngx-translate/core"; -import { DialogService } from "../../services/dialog.service"; -import { provideRouter } from "@angular/router"; -import { provideHttpClient } from "@angular/common/http"; -import { DialogTemplateCoreComponent } from "../../shared/custom/dialog-template-core/dialog-template-core.component"; -import { MatDividerModule } from "@angular/material/divider"; -import { AddEditTeamDialogComponent } from "./add-edit-team-dialog.component"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { MatIconModule } from '@angular/material/icon'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatSelectModule } from '@angular/material/select'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatInputModule } from '@angular/material/input'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { TeamService } from '../../services/team.service'; +import { of } from 'rxjs'; +import { marketingTeamWriteable, teamFormObject } from '../../shared/testData'; +import { Team } from '../../shared/types/model/Team'; +import { TranslateService } from '@ngx-translate/core'; +import { DialogService } from '../../services/dialog.service'; +import { provideRouter } from '@angular/router'; +import { provideHttpClient } from '@angular/common/http'; +import { DialogTemplateCoreComponent } from '../../shared/custom/dialog-template-core/dialog-template-core.component'; +import { MatDividerModule } from '@angular/material/divider'; +import { AddEditTeamDialogComponent } from './add-edit-team-dialog.component'; const dialogRefMock = { close: jest.fn() @@ -34,7 +34,7 @@ const teamServiceMock = { deleteTeam: jest.fn() }; -describe("TeamManagementComponent", () => { +describe('TeamManagementComponent', () => { let component: AddEditTeamDialogComponent; let fixture: ComponentFixture; @@ -82,14 +82,14 @@ describe("TeamManagementComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should call service method to save team", async() => { + it('should call service method to save team', async() => { component.teamForm.setValue(teamFormObject); - jest.spyOn(teamServiceMock, "createTeam") + jest.spyOn(teamServiceMock, 'createTeam') .mockReturnValue(of(teamFormObject)); fixture.detectChanges(); component.saveTeam(); @@ -99,10 +99,10 @@ describe("TeamManagementComponent", () => { .toHaveBeenCalledWith(teamFormObject as Team); }); - it("should call service method to update team if data input is not null", async() => { + it('should call service method to update team if data input is not null', async() => { component.data = { team: marketingTeamWriteable }; component.teamForm.setValue(teamFormObject); - jest.spyOn(teamServiceMock, "updateTeam") + jest.spyOn(teamServiceMock, 'updateTeam') .mockReturnValue(of(teamFormObject)); fixture.detectChanges(); component.saveTeam(); @@ -116,7 +116,7 @@ describe("TeamManagementComponent", () => { } as Team); }); - it("should set team values in from on init if data is not null", async() => { + it('should set team values in from on init if data is not null', async() => { component.data = { team: marketingTeamWriteable }; component.ngOnInit(); expect(component.teamForm.controls.name.value) diff --git a/frontend/src/app/team-management/add-edit-team-dialog/add-edit-team-dialog.component.ts b/frontend/src/app/team-management/add-edit-team-dialog/add-edit-team-dialog.component.ts index d461669a01..bd927f2b7f 100644 --- a/frontend/src/app/team-management/add-edit-team-dialog/add-edit-team-dialog.component.ts +++ b/frontend/src/app/team-management/add-edit-team-dialog/add-edit-team-dialog.component.ts @@ -1,21 +1,21 @@ -import { Component, Inject, OnInit } from "@angular/core"; -import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; -import { formInputCheck, hasFormFieldErrors } from "../../shared/common"; -import { FormControl, FormGroup, Validators } from "@angular/forms"; -import { TeamService } from "../../services/team.service"; -import { Team } from "../../shared/types/model/Team"; -import { TranslateService } from "@ngx-translate/core"; -import { UserService } from "../../services/user.service"; -import { Router } from "@angular/router"; +import { Component, Inject, OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { formInputCheck, hasFormFieldErrors } from '../../shared/common'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { TeamService } from '../../services/team.service'; +import { Team } from '../../shared/types/model/Team'; +import { TranslateService } from '@ngx-translate/core'; +import { UserService } from '../../services/user.service'; +import { Router } from '@angular/router'; @Component({ - selector: "app-add-edit-team-dialog", - templateUrl: "./add-edit-team-dialog.component.html", - styleUrls: ["./add-edit-team-dialog.component.scss"] + selector: 'app-add-edit-team-dialog', + templateUrl: './add-edit-team-dialog.component.html', + styleUrls: ['./add-edit-team-dialog.component.scss'] }) export class AddEditTeamDialogComponent implements OnInit { teamForm = new FormGroup({ - name: new FormControl("", [Validators.required, + name: new FormControl('', [Validators.required, Validators.minLength(2), Validators.maxLength(250)]) }); @@ -63,7 +63,7 @@ export class AddEditTeamDialogComponent implements OnInit { this.userService.reloadCurrentUser() .subscribe(); this.dialogRef.close(result); - this.router.navigateByUrl("/team-management/" + result.id); + this.router.navigateByUrl('/team-management/' + result.id); }); } @@ -84,11 +84,11 @@ export class AddEditTeamDialogComponent implements OnInit { getErrorMessage( error: string, field: string, firstNumber: number | null, secondNumber: number | null ): string { - return field + this.translate.instant("DIALOG_ERRORS." + error) + return field + this.translate.instant('DIALOG_ERRORS.' + error) .format(firstNumber, secondNumber); } getDialogTitle(): string { - return this.data ? "Team bearbeiten" : "Team erfassen"; + return this.data ? 'Team bearbeiten' : 'Team erfassen'; } } diff --git a/frontend/src/app/team-management/add-member-to-team-dialog/add-member-to-team-dialog.component.spec.ts b/frontend/src/app/team-management/add-member-to-team-dialog/add-member-to-team-dialog.component.spec.ts index 70b9c97cbf..8c01c8952e 100644 --- a/frontend/src/app/team-management/add-member-to-team-dialog/add-member-to-team-dialog.component.spec.ts +++ b/frontend/src/app/team-management/add-member-to-team-dialog/add-member-to-team-dialog.component.spec.ts @@ -1,17 +1,17 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { UserService } from "../../services/user.service"; -import { TeamService } from "../../services/team.service"; -import { AddMemberToTeamDialogComponent } from "./add-member-to-team-dialog.component"; -import { SharedModule } from "../../shared/shared.module"; -import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from "@angular/material/dialog"; -import { team1, users } from "../../shared/testData"; -import { BehaviorSubject, of, skip } from "rxjs"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { MatAutocompleteModule } from "@angular/material/autocomplete"; -import { User } from "../../shared/types/model/User"; -import { MatTable } from "@angular/material/table"; - -describe("AddMemberToTeamDialogComponent", () => { +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { UserService } from '../../services/user.service'; +import { TeamService } from '../../services/team.service'; +import { AddMemberToTeamDialogComponent } from './add-member-to-team-dialog.component'; +import { SharedModule } from '../../shared/shared.module'; +import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; +import { team1, users } from '../../shared/testData'; +import { BehaviorSubject, of, skip } from 'rxjs'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { User } from '../../shared/types/model/User'; +import { MatTable } from '@angular/material/table'; + +describe('AddMemberToTeamDialogComponent', () => { let component: AddMemberToTeamDialogComponent; let fixture: ComponentFixture; @@ -65,12 +65,12 @@ describe("AddMemberToTeamDialogComponent", () => { component.selectedUsers$ = new BehaviorSubject([]); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should set allPossibleUsers correctly", () => { + it('should set allPossibleUsers correctly', () => { component.ngOnInit(); component.usersForSelection$!.subscribe((filteredUsers) => { expect(filteredUsers.length) @@ -79,9 +79,9 @@ describe("AddMemberToTeamDialogComponent", () => { }); }); - it("should set filteredUsers correctly: search by PaCo", (done) => { + it('should set filteredUsers correctly: search by PaCo', (done) => { component.search = { - valueChanges: of("PaCo") + valueChanges: of('PaCo') } as any; component.ngOnInit(); @@ -90,14 +90,14 @@ describe("AddMemberToTeamDialogComponent", () => { expect(filteredUsers.length) .toBe(1); expect(filteredUsers[0].email) - .toBe("peggimann@puzzle.ch"); + .toBe('peggimann@puzzle.ch'); done(); }); }); - it("should set filteredUsers correctly: dont show already selected users", (done) => { + it('should set filteredUsers correctly: dont show already selected users', (done) => { component.search = { - valueChanges: of("puzzle.ch") + valueChanges: of('puzzle.ch') } as any; component.selectedUsers$.next([users[1]]); @@ -113,23 +113,23 @@ describe("AddMemberToTeamDialogComponent", () => { }); }); - it("should set teamname correctly", () => { + it('should set teamname correctly', () => { expect(component.getDialogTitle()) .toBe(`Members zu Team ${team1.name} hinzufügen`); }); - it("should return correct display value", () => { + it('should return correct display value', () => { expect(component.getDisplayValue(users[0])) .toBe(`${users[0].firstname} ${users[0].lastname} (${users[0].email})`); }); - it("should add user to selected users and restore search value", () => { - component.search.setValue("test"); + it('should add user to selected users and restore search value', () => { + component.search.setValue('test'); component.selectedUsers$.next([users[1], users[2]]); component.selectUser(users[3]); expect(component.search.value) - .toBe(""); + .toBe(''); expect(component.selectedUsers$.getValue().length) .toBe(3); expect(component.selectedUsers$.getValue() @@ -139,7 +139,7 @@ describe("AddMemberToTeamDialogComponent", () => { users[3].id]); }); - it("should remove user from selected users", () => { + it('should remove user from selected users', () => { component.selectedUsers$.next([...users]); component.remove(users[0]); expect(component.selectedUsers$.getValue().length) diff --git a/frontend/src/app/team-management/add-member-to-team-dialog/add-member-to-team-dialog.component.ts b/frontend/src/app/team-management/add-member-to-team-dialog/add-member-to-team-dialog.component.ts index 395f3e0e3f..74daf8a4df 100644 --- a/frontend/src/app/team-management/add-member-to-team-dialog/add-member-to-team-dialog.component.ts +++ b/frontend/src/app/team-management/add-member-to-team-dialog/add-member-to-team-dialog.component.ts @@ -1,13 +1,13 @@ -import { Component, Inject, OnDestroy, OnInit, ViewChild } from "@angular/core"; -import { BehaviorSubject, combineLatest, filter, map, Observable, startWith, Subject, takeUntil } from "rxjs"; -import { Team } from "../../shared/types/model/Team"; -import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog"; -import { User } from "../../shared/types/model/User"; -import { UserService } from "../../services/user.service"; -import { FormControl } from "@angular/forms"; -import { MatTable, MatTableDataSource } from "@angular/material/table"; -import { TeamService } from "../../services/team.service"; -import { UserTableEntry } from "../../shared/types/model/UserTableEntry"; +import { Component, Inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { BehaviorSubject, combineLatest, filter, map, Observable, startWith, Subject, takeUntil } from 'rxjs'; +import { Team } from '../../shared/types/model/Team'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { User } from '../../shared/types/model/User'; +import { UserService } from '../../services/user.service'; +import { FormControl } from '@angular/forms'; +import { MatTable, MatTableDataSource } from '@angular/material/table'; +import { TeamService } from '../../services/team.service'; +import { UserTableEntry } from '../../shared/types/model/UserTableEntry'; export interface AddMemberToTeamDialogComponentData { team: Team; @@ -15,21 +15,21 @@ export interface AddMemberToTeamDialogComponentData { } @Component({ - selector: "app-add-member-to-team-dialog", - templateUrl: "./add-member-to-team-dialog.component.html", - styleUrl: "./add-member-to-team-dialog.component.scss" + selector: 'app-add-member-to-team-dialog', + templateUrl: './add-member-to-team-dialog.component.html', + styleUrl: './add-member-to-team-dialog.component.scss' }) export class AddMemberToTeamDialogComponent implements OnInit, OnDestroy { @ViewChild(MatTable) table!: MatTable; selectedUsers$: BehaviorSubject = new BehaviorSubject([]); - search = new FormControl(""); + search = new FormControl(''); usersForSelection$: Observable | undefined; - displayedColumns = ["name", - "delete"]; + displayedColumns = ['name', + 'delete']; dataSource: MatTableDataSource | undefined; @@ -49,11 +49,11 @@ export class AddMemberToTeamDialogComponent implements OnInit, OnDestroy { // directly after selecting object, filtervalue is an object. this.usersForSelection$ = combineLatest([this.userService.getUsers(), this.selectedUsers$, - this.search.valueChanges.pipe(startWith(""), filter((searchValue) => typeof searchValue === "string"))]) + this.search.valueChanges.pipe(startWith(''), filter((searchValue) => typeof searchValue === 'string'))]) .pipe(takeUntil(this.unsubscribe$), map(([allPossibleUsers, selectedUsers, filterValue]) => { - return this.filter(allPossibleUsers, filterValue || "", selectedUsers); + return this.filter(allPossibleUsers, filterValue || '', selectedUsers); })); } @@ -92,9 +92,9 @@ export class AddMemberToTeamDialogComponent implements OnInit, OnDestroy { }); } - getDisplayValue(user: User | ""): string { + getDisplayValue(user: User | ''): string { if (!user) { - return ""; + return ''; } return `${user.firstname} ${user.lastname} (${user.email})`; } @@ -103,7 +103,7 @@ export class AddMemberToTeamDialogComponent implements OnInit, OnDestroy { const newUsers = this.selectedUsers$.getValue(); newUsers.push(user); this.selectedUsers$.next(newUsers); - this.search.setValue(""); + this.search.setValue(''); } remove(user: User): void { diff --git a/frontend/src/app/team-management/add-user-team/add-user-team.component.spec.ts b/frontend/src/app/team-management/add-user-team/add-user-team.component.spec.ts index 16291a037c..37a116f676 100644 --- a/frontend/src/app/team-management/add-user-team/add-user-team.component.spec.ts +++ b/frontend/src/app/team-management/add-user-team/add-user-team.component.spec.ts @@ -1,10 +1,10 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { AddUserTeamComponent } from "./add-user-team.component"; -import { TeamService } from "../../services/team.service"; -import { team1, team2, team3, testUser } from "../../shared/testData"; -import { of } from "rxjs"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { AddUserTeamComponent } from './add-user-team.component'; +import { TeamService } from '../../services/team.service'; +import { team1, team2, team3, testUser } from '../../shared/testData'; +import { of } from 'rxjs'; -describe("AddUserTeamComponent", () => { +describe('AddUserTeamComponent', () => { let component: AddUserTeamComponent; let fixture: ComponentFixture; const team1Copy = { ...team1 }; @@ -36,12 +36,12 @@ describe("AddUserTeamComponent", () => { fixture.detectChanges(); }); - it("should create the component", () => { + it('should create the component', () => { expect(component) .toBeTruthy(); }); - it("should filter selectableAdminTeams correctly", (done) => { + it('should filter selectableAdminTeams correctly', (done) => { team1Copy.writeable = true; team2Copy.writeable = true; team3Copy.writeable = false; @@ -55,7 +55,7 @@ describe("AddUserTeamComponent", () => { }); }); - it("should filter allAdminTeams correctly", (done) => { + it('should filter allAdminTeams correctly', (done) => { team1Copy.writeable = true; team2Copy.writeable = true; team3Copy.writeable = false; @@ -73,7 +73,7 @@ describe("AddUserTeamComponent", () => { }); }); - it("createUserTeam should create the userTeam", () => { + it('createUserTeam should create the userTeam', () => { component.createUserTeam(team1Copy); expect(component.userTeam) .toStrictEqual({ @@ -82,12 +82,12 @@ describe("AddUserTeamComponent", () => { }); }); - it("save should throw exception if userTeam is undefined", () => { + it('save should throw exception if userTeam is undefined', () => { expect(() => component.save()) - .toThrowError("UserTeam should be defined here"); + .toThrowError('UserTeam should be defined here'); }); - it("save should emit addUserTeam event and set userTeam to undefined", (done) => { + it('save should emit addUserTeam event and set userTeam to undefined', (done) => { component.userTeam = testUser.userTeamList[0]; component.addUserTeam.subscribe(() => { done(); @@ -97,7 +97,7 @@ describe("AddUserTeamComponent", () => { .toBe(undefined); }); - it("should test showAddButton", () => { + it('should test showAddButton', () => { component.userTeam = testUser.userTeamList[0]; expect(component.showAddButton(null)) .toBeFalsy(); @@ -112,7 +112,7 @@ describe("AddUserTeamComponent", () => { .toBeTruthy(); }); - it("should test addButtonDisabled", () => { + it('should test addButtonDisabled', () => { expect(component.addButtonDisabled([team1Copy])) .toBeFalsy(); expect(component.addButtonDisabled([])) diff --git a/frontend/src/app/team-management/add-user-team/add-user-team.component.ts b/frontend/src/app/team-management/add-user-team/add-user-team.component.ts index 8b795d059b..b0dbcd3e19 100644 --- a/frontend/src/app/team-management/add-user-team/add-user-team.component.ts +++ b/frontend/src/app/team-management/add-user-team/add-user-team.component.ts @@ -1,13 +1,13 @@ -import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; -import { Team } from "../../shared/types/model/Team"; -import { TeamService } from "../../services/team.service"; -import { combineLatest, map, Observable, Subject, takeUntil } from "rxjs"; -import { UserTeam } from "../../shared/types/model/UserTeam"; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { Team } from '../../shared/types/model/Team'; +import { TeamService } from '../../services/team.service'; +import { combineLatest, map, Observable, Subject, takeUntil } from 'rxjs'; +import { UserTeam } from '../../shared/types/model/UserTeam'; @Component({ - selector: "app-add-user-team", - templateUrl: "./add-user-team.component.html", - styleUrl: "./add-user-team.component.scss" + selector: 'app-add-user-team', + templateUrl: './add-user-team.component.html', + styleUrl: './add-user-team.component.scss' }) export class AddUserTeamComponent implements OnInit, OnDestroy { @Output() @@ -58,7 +58,7 @@ export class AddUserTeamComponent implements OnInit, OnDestroy { save(): void { if (!this.userTeam) { - throw new Error("UserTeam should be defined here"); + throw new Error('UserTeam should be defined here'); } this.addUserTeam.next(this.userTeam); this.userTeam = undefined; diff --git a/frontend/src/app/team-management/delete-user/delete-user.component.spec.ts b/frontend/src/app/team-management/delete-user/delete-user.component.spec.ts index b0581357c3..5c528383b2 100644 --- a/frontend/src/app/team-management/delete-user/delete-user.component.spec.ts +++ b/frontend/src/app/team-management/delete-user/delete-user.component.spec.ts @@ -1,15 +1,15 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { UserService } from "../../services/user.service"; -import { DeleteUserComponent } from "./delete-user.component"; -import { of, Subject } from "rxjs"; -import { testUser } from "../../shared/testData"; -import { MatDialogRef } from "@angular/material/dialog"; -import { ConfirmDialogComponent } from "../../shared/dialog/confirm-dialog/confirm-dialog.component"; -import { DialogService } from "../../services/dialog.service"; -import { Location } from "@angular/common"; -import { ButtonState } from "../../shared/types/enums/ButtonState"; - -describe("DeleteUserComponent", () => { +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { UserService } from '../../services/user.service'; +import { DeleteUserComponent } from './delete-user.component'; +import { of, Subject } from 'rxjs'; +import { testUser } from '../../shared/testData'; +import { MatDialogRef } from '@angular/material/dialog'; +import { ConfirmDialogComponent } from '../../shared/dialog/confirm-dialog/confirm-dialog.component'; +import { DialogService } from '../../services/dialog.service'; +import { Location } from '@angular/common'; +import { ButtonState } from '../../shared/types/enums/ButtonState'; + +describe('DeleteUserComponent', () => { let component: DeleteUserComponent; let fixture: ComponentFixture; @@ -42,11 +42,11 @@ describe("DeleteUserComponent", () => { component = fixture.componentInstance; component.user = { id: 2, - firstname: "Hans", - lastname: "Muster", + firstname: 'Hans', + lastname: 'Muster', isOkrChampion: false, userTeamList: [], - email: "hans.muster@puzzle.ch" + email: 'hans.muster@puzzle.ch' }; component.currentTeams$ = new Subject(); userServiceMock.getOrInitCurrentUser.mockReturnValue(of(testUser)); @@ -61,15 +61,15 @@ describe("DeleteUserComponent", () => { dialogServiceMock.openCustomizedConfirmDialog.mockReset(); }); - it("should create component", () => { + it('should create component', () => { expect(component) .toBeTruthy(); }); - it("deleteUser() should delete user and reload users", () => { + it('deleteUser() should delete user and reload users', () => { // arrange userServiceMock.deleteUser.mockReturnValue(of(userServiceMock.deleteUser)); - dialogRefMock.afterClosed.mockReturnValue(of("some data")); + dialogRefMock.afterClosed.mockReturnValue(of('some data')); dialogServiceMock.openCustomizedConfirmDialog.mockReturnValue(dialogRefMock); // act @@ -84,16 +84,16 @@ describe("DeleteUserComponent", () => { .toHaveBeenCalledTimes(1); }); - it("deleteUser() should not reload users when UserService throws an error", () => { + it('deleteUser() should not reload users when UserService throws an error', () => { // arrange function createErrorSubject() { const myError = new Subject(); - myError.error("uups"); + myError.error('uups'); return myError; } userServiceMock.deleteUser.mockReturnValue(createErrorSubject()); - dialogRefMock.afterClosed.mockReturnValue(of("some data")); + dialogRefMock.afterClosed.mockReturnValue(of('some data')); dialogServiceMock.openCustomizedConfirmDialog.mockReturnValue(dialogRefMock); // act @@ -108,7 +108,7 @@ describe("DeleteUserComponent", () => { .toHaveBeenCalledTimes(0); }); - it("deleteUserWithChecks() should not delete user which is member of a Team", () => { + it('deleteUserWithChecks() should not delete user which is member of a Team', () => { // arrange (user is member of team Lorem) component.userIsMemberOfTeams = true; component.user.userTeamList = [{ @@ -116,7 +116,7 @@ describe("DeleteUserComponent", () => { team: { id: 1, version: 2, - name: "Lorem", + name: 'Lorem', writeable: true }, isTeamAdmin: false @@ -130,23 +130,23 @@ describe("DeleteUserComponent", () => { .toHaveBeenCalledTimes(1); expect(dialogServiceMock.openCustomizedConfirmDialog) .toHaveBeenCalledWith({ - title: "User kann nicht gelöscht werden", - text: "Hans Muster ist in folgenden Teams und kann daher nicht gelöscht werden: Lorem", + title: 'User kann nicht gelöscht werden', + text: 'Hans Muster ist in folgenden Teams und kann daher nicht gelöscht werden: Lorem', yesButtonState: ButtonState.Hidden, noButtonState: ButtonState.Hidden, closeButtonState: ButtonState.VisibleEnabled }); }); - it("deleteUserWithChecks() should not delete user which has KeyResults", () => { + it('deleteUserWithChecks() should not delete user which has KeyResults', () => { // arrange (user has KeyResult one) component.userIsMemberOfTeams = false; component.userOkrData = { keyResults: [{ keyResultId: 1, - keyResultName: "one", + keyResultName: 'one', objectiveId: 2, - objectiveName: "two" + objectiveName: 'two' }] }; @@ -158,21 +158,21 @@ describe("DeleteUserComponent", () => { .toHaveBeenCalledTimes(1); expect(dialogServiceMock.openCustomizedConfirmDialog) .toHaveBeenCalledWith({ - title: "User kann nicht gelöscht werden", - text: "Hans Muster ist Owner folgender KeyResults und kann daher nicht gelöscht werden: \n\none\n(Objective: two)", + title: 'User kann nicht gelöscht werden', + text: 'Hans Muster ist Owner folgender KeyResults und kann daher nicht gelöscht werden: \n\none\n(Objective: two)', yesButtonState: ButtonState.Hidden, noButtonState: ButtonState.Hidden, closeButtonState: ButtonState.VisibleEnabled }); }); - it("deleteUserWithChecks() should delete user which is not member of a Team and has no KeyResults", () => { + it('deleteUserWithChecks() should delete user which is not member of a Team and has no KeyResults', () => { // arrange component.userIsMemberOfTeams = false; component.userOkrData = { keyResults: [] }; userServiceMock.deleteUser.mockReturnValue(of(userServiceMock.deleteUser)); - dialogRefMock.afterClosed.mockReturnValue(of("some data")); + dialogRefMock.afterClosed.mockReturnValue(of('some data')); dialogServiceMock.openCustomizedConfirmDialog.mockReturnValue(dialogRefMock); // act @@ -183,15 +183,15 @@ describe("DeleteUserComponent", () => { .toHaveBeenCalledTimes(1); expect(dialogServiceMock.openCustomizedConfirmDialog) .toHaveBeenCalledWith({ - title: "User löschen", - text: "Möchtest du den User Hans Muster wirklich löschen?", + title: 'User löschen', + text: 'Möchtest du den User Hans Muster wirklich löschen?', yesButtonState: ButtonState.VisibleEnabled, noButtonState: ButtonState.VisibleEnabled, closeButtonState: ButtonState.Hidden }); }); - it("updateUserTeamsStatusWhenTeamOfUserChanges() does not update userIsMemberOfTeams property if currentTeams$ does not emit a value ", () => { + it('updateUserTeamsStatusWhenTeamOfUserChanges() does not update userIsMemberOfTeams property if currentTeams$ does not emit a value ', () => { // arrange (currentTeams$ does not emit a value) component.currentTeams$ = of(); @@ -207,14 +207,14 @@ describe("DeleteUserComponent", () => { .toBe(undefined); }); - it("updateUserTeamsStatusWhenTeamOfUserChanges() does update userIsMemberOfTeams property if currentTeams$ does emit a value ", () => { + it('updateUserTeamsStatusWhenTeamOfUserChanges() does update userIsMemberOfTeams property if currentTeams$ does emit a value ', () => { // arrange (currentTeams$ does emit a value) component.currentTeams$ = of([{ id: 100, team: { id: 1, version: 2, - name: "Lorem", + name: 'Lorem', writeable: true }, isTeamAdmin: false diff --git a/frontend/src/app/team-management/delete-user/delete-user.component.ts b/frontend/src/app/team-management/delete-user/delete-user.component.ts index 8949bac421..c2253dcaaa 100644 --- a/frontend/src/app/team-management/delete-user/delete-user.component.ts +++ b/frontend/src/app/team-management/delete-user/delete-user.component.ts @@ -1,17 +1,17 @@ -import { Component, Input, OnInit, OnDestroy } from "@angular/core"; -import { UserService } from "../../services/user.service"; -import { getFullNameFromUser, User } from "../../shared/types/model/User"; -import { Location } from "@angular/common"; -import { Observable, Subject, takeUntil, tap } from "rxjs"; -import { UserTeam } from "../../shared/types/model/UserTeam"; -import { ConfirmDialogData, DialogService } from "../../services/dialog.service"; -import { ButtonState } from "../../shared/types/enums/ButtonState"; -import { UserOkrData } from "../../shared/types/model/UserOkrData"; +import { Component, Input, OnInit, OnDestroy } from '@angular/core'; +import { UserService } from '../../services/user.service'; +import { getFullNameFromUser, User } from '../../shared/types/model/User'; +import { Location } from '@angular/common'; +import { Observable, Subject, takeUntil, tap } from 'rxjs'; +import { UserTeam } from '../../shared/types/model/UserTeam'; +import { ConfirmDialogData, DialogService } from '../../services/dialog.service'; +import { ButtonState } from '../../shared/types/enums/ButtonState'; +import { UserOkrData } from '../../shared/types/model/UserOkrData'; @Component({ - selector: "app-delete-user", - templateUrl: "./delete-user.component.html", - styleUrl: "./delete-user.component.scss" + selector: 'app-delete-user', + templateUrl: './delete-user.component.html', + styleUrl: './delete-user.component.scss' }) export class DeleteUserComponent implements OnInit, OnDestroy { @Input({ required: true }) user!: User; @@ -75,12 +75,12 @@ export class DeleteUserComponent implements OnInit, OnDestroy { deleteUserWithChecks() { if (this.isUserMemberOfTeams()) { - const dialogTitle = "User kann nicht gelöscht werden"; + const dialogTitle = 'User kann nicht gelöscht werden'; const dialogText = `${getFullNameFromUser(this.user)} ist in folgenden Teams und kann daher nicht gelöscht werden: ${this.dialogDetailsUserTeams()}`; this.showUnableToDeleteUserDialog(dialogTitle, dialogText); return; } else if (this.isUserOwnerOfKeyResults()) { - const dialogTitle = "User kann nicht gelöscht werden"; + const dialogTitle = 'User kann nicht gelöscht werden'; const dialogText = `${getFullNameFromUser(this.user)} ist Owner folgender KeyResults und kann daher nicht gelöscht werden: \n\n${this.dialogDetailsUserKeyResults()}`; this.showUnableToDeleteUserDialog(dialogTitle, dialogText); return; @@ -100,18 +100,18 @@ export class DeleteUserComponent implements OnInit, OnDestroy { if (this.userOkrData) { return this.user.userTeamList // .map((userTeam) => userTeam.team.name) - .join(", "); + .join(', '); } - return ""; + return ''; } dialogDetailsUserKeyResults() { if (this.userOkrData) { return this.userOkrData.keyResults - .map((data) => data.keyResultName + "\n(Objective: " + data.objectiveName + ")") - .join("\n\n"); + .map((data) => data.keyResultName + '\n(Objective: ' + data.objectiveName + ')') + .join('\n\n'); } - return ""; + return ''; } showUnableToDeleteUserDialog(dialogTitle: string, dialogText: string) { @@ -127,7 +127,7 @@ export class DeleteUserComponent implements OnInit, OnDestroy { deleteUser() { const data: ConfirmDialogData = { - title: "User löschen", + title: 'User löschen', text: `Möchtest du den User ${this.user.firstname} ${this.user.lastname} wirklich löschen?`, yesButtonState: ButtonState.VisibleEnabled, noButtonState: ButtonState.VisibleEnabled, diff --git a/frontend/src/app/team-management/edit-okr-champion/edit-okr-champion.component.ts b/frontend/src/app/team-management/edit-okr-champion/edit-okr-champion.component.ts index 0351900639..a4a5dbfe9d 100644 --- a/frontend/src/app/team-management/edit-okr-champion/edit-okr-champion.component.ts +++ b/frontend/src/app/team-management/edit-okr-champion/edit-okr-champion.component.ts @@ -1,12 +1,12 @@ -import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, Output } from "@angular/core"; -import { User } from "../../shared/types/model/User"; -import { UserService } from "../../services/user.service"; -import { TeamService } from "../../services/team.service"; +import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, Output } from '@angular/core'; +import { User } from '../../shared/types/model/User'; +import { UserService } from '../../services/user.service'; +import { TeamService } from '../../services/team.service'; @Component({ - selector: "app-edit-okr-champion", - templateUrl: "./edit-okr-champion.component.html", - styleUrl: "./edit-okr-champion.component.scss" + selector: 'app-edit-okr-champion', + templateUrl: './edit-okr-champion.component.html', + styleUrl: './edit-okr-champion.component.scss' }) export class EditOkrChampionComponent { @Input({ required: true }) user!: User; @@ -22,7 +22,7 @@ export class EditOkrChampionComponent { private elementRef: ElementRef ) {} - @HostListener("document:click", ["$event"]) + @HostListener('document:click', ['$event']) clickOutside(event: MouseEvent) { if (this.elementRef.nativeElement.contains(event.target)) { return; diff --git a/frontend/src/app/team-management/invite-user-dialog/invite-user-dialog.component.spec.ts b/frontend/src/app/team-management/invite-user-dialog/invite-user-dialog.component.spec.ts index b7ca9d0933..052c844d55 100644 --- a/frontend/src/app/team-management/invite-user-dialog/invite-user-dialog.component.spec.ts +++ b/frontend/src/app/team-management/invite-user-dialog/invite-user-dialog.component.spec.ts @@ -1,32 +1,32 @@ -import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; - -import { InviteUserDialogComponent } from "./invite-user-dialog.component"; -import { MatDialogModule } from "@angular/material/dialog"; -import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { NewUserComponent } from "../new-user/new-user.component"; -import { PuzzleIconComponent } from "../../shared/custom/puzzle-icon/puzzle-icon.component"; -import { PuzzleIconButtonComponent } from "../../shared/custom/puzzle-icon-button/puzzle-icon-button.component"; -import { UserService } from "../../services/user.service"; -import { testUser } from "../../shared/testData"; -import { DialogRef } from "@angular/cdk/dialog"; -import { of } from "rxjs"; -import { UniqueEmailValidator } from "../new-user/unique-mail.validator"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { NO_ERRORS_SCHEMA } from "@angular/core"; - -describe("InviteUserDialogComponent", () => { +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; + +import { InviteUserDialogComponent } from './invite-user-dialog.component'; +import { MatDialogModule } from '@angular/material/dialog'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { NewUserComponent } from '../new-user/new-user.component'; +import { PuzzleIconComponent } from '../../shared/custom/puzzle-icon/puzzle-icon.component'; +import { PuzzleIconButtonComponent } from '../../shared/custom/puzzle-icon-button/puzzle-icon-button.component'; +import { UserService } from '../../services/user.service'; +import { testUser } from '../../shared/testData'; +import { DialogRef } from '@angular/cdk/dialog'; +import { of } from 'rxjs'; +import { UniqueEmailValidator } from '../new-user/unique-mail.validator'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; + +describe('InviteUserDialogComponent', () => { let component: InviteUserDialogComponent; let fixture: ComponentFixture; - const user1 = { firstname: "user1", - lastname: "1user", - email: "user1@user.ch" }; - const user2 = { firstname: "user2", - lastname: "2user", - email: "user2@user.ch" }; - const user3 = { firstname: "user3", - lastname: "3user", - email: "user3@user.ch" }; + const user1 = { firstname: 'user1', + lastname: '1user', + email: 'user1@user.ch' }; + const user2 = { firstname: 'user2', + lastname: '2user', + email: 'user2@user.ch' }; + const user3 = { firstname: 'user3', + lastname: '3user', + email: 'user3@user.ch' }; const userServiceMock = { createUsers: jest.fn(), @@ -77,18 +77,18 @@ describe("InviteUserDialogComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("addUser should add a user to the existing users", () => { + it('addUser should add a user to the existing users', () => { component.addUser(); expect(component.form.controls.length) .toBe(2); }); - it("removeUser should remove given user from users array", () => { + it('removeUser should remove given user from users array', () => { component.addUser(); component.addUser(); component.addUser(); @@ -105,7 +105,7 @@ describe("InviteUserDialogComponent", () => { .toStrictEqual(user3); }); - it("registerUsers should call createUsers and close dialog if form is valid", fakeAsync(() => { + it('registerUsers should call createUsers and close dialog if form is valid', fakeAsync(() => { userServiceMock.createUsers.mockReturnValue(of([testUser])); component.form.controls[0].setValue(user1); @@ -121,7 +121,7 @@ describe("InviteUserDialogComponent", () => { .toBeCalledTimes(1); })); - it("registerUsers should not call createUsers form is not valid", fakeAsync(() => { + it('registerUsers should not call createUsers form is not valid', fakeAsync(() => { component.registerUsers(); tick(); diff --git a/frontend/src/app/team-management/invite-user-dialog/invite-user-dialog.component.ts b/frontend/src/app/team-management/invite-user-dialog/invite-user-dialog.component.ts index a1e69e7288..e008c91fee 100644 --- a/frontend/src/app/team-management/invite-user-dialog/invite-user-dialog.component.ts +++ b/frontend/src/app/team-management/invite-user-dialog/invite-user-dialog.component.ts @@ -1,16 +1,16 @@ -import { Component } from "@angular/core"; -import { NewUser } from "../../shared/types/model/NewUser"; -import { FormArray, FormControl, FormGroup, NonNullableFormBuilder, Validators } from "@angular/forms"; -import { UserService } from "../../services/user.service"; -import { DialogRef } from "@angular/cdk/dialog"; -import { NewUserForm } from "../../shared/types/model/NewUserForm"; -import { UniqueEmailValidator } from "../new-user/unique-mail.validator"; -import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { Component } from '@angular/core'; +import { NewUser } from '../../shared/types/model/NewUser'; +import { FormArray, FormControl, FormGroup, NonNullableFormBuilder, Validators } from '@angular/forms'; +import { UserService } from '../../services/user.service'; +import { DialogRef } from '@angular/cdk/dialog'; +import { NewUserForm } from '../../shared/types/model/NewUserForm'; +import { UniqueEmailValidator } from '../new-user/unique-mail.validator'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @Component({ - selector: "app-invite-user-dialog", - templateUrl: "./invite-user-dialog.component.html", - styleUrl: "./invite-user-dialog.component.scss" + selector: 'app-invite-user-dialog', + templateUrl: './invite-user-dialog.component.html', + styleUrl: './invite-user-dialog.component.scss' }) export class InviteUserDialogComponent { form: FormArray>>; @@ -52,11 +52,11 @@ export class InviteUserDialogComponent { private createUserFormGroup() { return this.formBuilder.group({ - firstname: this.formBuilder.control("", [Validators.required, + firstname: this.formBuilder.control('', [Validators.required, Validators.minLength(1)]), - lastname: this.formBuilder.control("", [Validators.required, + lastname: this.formBuilder.control('', [Validators.required, Validators.minLength(1)]), - email: this.formBuilder.control("", [ + email: this.formBuilder.control('', [ Validators.required, Validators.minLength(1), Validators.email, diff --git a/frontend/src/app/team-management/member-detail/member-detail.component.spec.ts b/frontend/src/app/team-management/member-detail/member-detail.component.spec.ts index c956d8e01a..24213edc02 100644 --- a/frontend/src/app/team-management/member-detail/member-detail.component.spec.ts +++ b/frontend/src/app/team-management/member-detail/member-detail.component.spec.ts @@ -1,27 +1,27 @@ -import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; -import { MemberDetailComponent } from "./member-detail.component"; -import { ActivatedRoute, provideRouter } from "@angular/router"; -import { delay, of } from "rxjs"; -import { TranslateModule } from "@ngx-translate/core"; -import { BrowserModule } from "@angular/platform-browser"; -import { SharedModule } from "../../shared/shared.module"; -import { UserService } from "../../services/user.service"; -import { testUser } from "../../shared/testData"; -import { AddUserTeamComponent } from "../add-user-team/add-user-team.component"; -import { MatTableModule } from "@angular/material/table"; -import { MatIconModule } from "@angular/material/icon"; -import { TeamService } from "../../services/team.service"; -import { ShowEditRoleComponent } from "../show-edit-role/show-edit-role.component"; -import { PuzzleIconButtonComponent } from "../../shared/custom/puzzle-icon-button/puzzle-icon-button.component"; -import { PuzzleIconComponent } from "../../shared/custom/puzzle-icon/puzzle-icon.component"; -import { CommonModule } from "@angular/common"; -import { NO_ERRORS_SCHEMA } from "@angular/core"; -import { DialogService } from "../../services/dialog.service"; -import { provideHttpClient } from "@angular/common/http"; -import { provideHttpClientTesting } from "@angular/common/http/testing"; -import { DialogTemplateCoreComponent } from "../../shared/custom/dialog-template-core/dialog-template-core.component"; - -describe("MemberDetailComponent", () => { +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { MemberDetailComponent } from './member-detail.component'; +import { ActivatedRoute, provideRouter } from '@angular/router'; +import { delay, of } from 'rxjs'; +import { TranslateModule } from '@ngx-translate/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { SharedModule } from '../../shared/shared.module'; +import { UserService } from '../../services/user.service'; +import { testUser } from '../../shared/testData'; +import { AddUserTeamComponent } from '../add-user-team/add-user-team.component'; +import { MatTableModule } from '@angular/material/table'; +import { MatIconModule } from '@angular/material/icon'; +import { TeamService } from '../../services/team.service'; +import { ShowEditRoleComponent } from '../show-edit-role/show-edit-role.component'; +import { PuzzleIconButtonComponent } from '../../shared/custom/puzzle-icon-button/puzzle-icon-button.component'; +import { PuzzleIconComponent } from '../../shared/custom/puzzle-icon/puzzle-icon.component'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { DialogService } from '../../services/dialog.service'; +import { provideHttpClient } from '@angular/common/http'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { DialogTemplateCoreComponent } from '../../shared/custom/dialog-template-core/dialog-template-core.component'; + +describe('MemberDetailComponent', () => { let component: MemberDetailComponent; let fixture: ComponentFixture; @@ -104,12 +104,12 @@ describe("MemberDetailComponent", () => { teamServiceMock.removeUserFromTeam.mockReset(); }); - it("should create the component", () => { + it('should create the component', () => { expect(component) .toBeTruthy(); }); - it("should set selectedUserIsLoggedInUser and currentUserTeams correctly", (done) => { + it('should set selectedUserIsLoggedInUser and currentUserTeams correctly', (done) => { component.ngOnInit(); component.currentUserTeams$.subscribe((userTeams) => { expect(userTeams) @@ -122,7 +122,7 @@ describe("MemberDetailComponent", () => { }); }); - it("removeUserFromTeam should call removeUserFromTeam and loadUser", fakeAsync(() => { + it('removeUserFromTeam should call removeUserFromTeam and loadUser', fakeAsync(() => { const user = testUser; const userTeam = testUser.userTeamList[0]; teamServiceMock.removeUserFromTeam.mockReturnValue(of()); @@ -142,7 +142,7 @@ describe("MemberDetailComponent", () => { .toHaveBeenCalledWith(user.id); })); - it("removeUserFromTeam should not call removeUserFromTeam if dialog canceled", fakeAsync(() => { + it('removeUserFromTeam should not call removeUserFromTeam if dialog canceled', fakeAsync(() => { const user = testUser; const userTeam = testUser.userTeamList[0]; teamServiceMock.removeUserFromTeam.mockReturnValue(of()); @@ -158,7 +158,7 @@ describe("MemberDetailComponent", () => { .toHaveBeenCalledTimes(0); })); - it("addTeamRole should call updateOrAddTeamMembership, loadUser, reloadUsers and set userTeamEditId to null", fakeAsync(() => { + it('addTeamRole should call updateOrAddTeamMembership, loadUser, reloadUsers and set userTeamEditId to null', fakeAsync(() => { const user = testUser; const userTeam = testUser.userTeamList[0]; @@ -176,7 +176,7 @@ describe("MemberDetailComponent", () => { .toHaveBeenCalledWith(user.id); })); - it("updateTeamRole should call updateOrAddTeamMembership, loadUser, reloadUsers and set userTeamEditId to null", fakeAsync(() => { + it('updateTeamRole should call updateOrAddTeamMembership, loadUser, reloadUsers and set userTeamEditId to null', fakeAsync(() => { const user = testUser; const userTeam = testUser.userTeamList[0]; @@ -194,7 +194,7 @@ describe("MemberDetailComponent", () => { .toHaveBeenCalledWith(user.id); })); - it("updateTeamRole should set isAdmin only after successfull request", fakeAsync(() => { + it('updateTeamRole should set isAdmin only after successfull request', fakeAsync(() => { const user = testUser; const userTeam = { ...testUser.userTeamList[0] }; userTeam.isTeamAdmin = false; diff --git a/frontend/src/app/team-management/member-detail/member-detail.component.ts b/frontend/src/app/team-management/member-detail/member-detail.component.ts index d844643543..9522cd34df 100644 --- a/frontend/src/app/team-management/member-detail/member-detail.component.ts +++ b/frontend/src/app/team-management/member-detail/member-detail.component.ts @@ -1,19 +1,19 @@ -import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild } from "@angular/core"; -import { UserService } from "../../services/user.service"; -import { BehaviorSubject, filter, mergeMap, Subject, takeUntil, tap } from "rxjs"; -import { getFullNameFromUser, User } from "../../shared/types/model/User"; -import { ActivatedRoute, ParamMap, Router } from "@angular/router"; -import { Team } from "../../shared/types/model/Team"; -import { UserTeam } from "../../shared/types/model/UserTeam"; -import { TranslateService } from "@ngx-translate/core"; -import { MatTable } from "@angular/material/table"; -import { TeamService } from "../../services/team.service"; -import { DialogService } from "../../services/dialog.service"; +import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { UserService } from '../../services/user.service'; +import { BehaviorSubject, filter, mergeMap, Subject, takeUntil, tap } from 'rxjs'; +import { getFullNameFromUser, User } from '../../shared/types/model/User'; +import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { Team } from '../../shared/types/model/Team'; +import { UserTeam } from '../../shared/types/model/UserTeam'; +import { TranslateService } from '@ngx-translate/core'; +import { MatTable } from '@angular/material/table'; +import { TeamService } from '../../services/team.service'; +import { DialogService } from '../../services/dialog.service'; @Component({ - selector: "app-member-detail", - templateUrl: "./member-detail.component.html", - styleUrl: "./member-detail.component.scss" + selector: 'app-member-detail', + templateUrl: './member-detail.component.html', + styleUrl: './member-detail.component.scss' }) export class MemberDetailComponent implements OnInit, OnDestroy { @ViewChild(MatTable) table!: MatTable; @@ -30,9 +30,9 @@ export class MemberDetailComponent implements OnInit, OnDestroy { userTeamEditId: number | undefined; - readonly displayedColumns = ["team", - "role", - "delete"]; + readonly displayedColumns = ['team', + 'role', + 'delete']; readonly getFullNameFromUser = getFullNameFromUser; @@ -76,9 +76,9 @@ export class MemberDetailComponent implements OnInit, OnDestroy { } private getIdFromParams(params: ParamMap): number { - const id = params.get("id"); + const id = params.get('id'); if (!id) { - throw Error("member id is undefined"); + throw Error('member id is undefined'); } return parseInt(id); } @@ -89,7 +89,7 @@ export class MemberDetailComponent implements OnInit, OnDestroy { team: userTeam.team.name }; this.dialogService - .openConfirmDialog("CONFIRMATION.DELETE.USER_FROM_TEAM", i18nData) + .openConfirmDialog('CONFIRMATION.DELETE.USER_FROM_TEAM', i18nData) .afterClosed() .pipe(filter((confirm) => confirm), mergeMap(() => this.teamService.removeUserFromTeam(user.id, userTeam.team))) .subscribe(() => { @@ -129,7 +129,7 @@ export class MemberDetailComponent implements OnInit, OnDestroy { } navigateBack() { - this.router.navigate(["../"], { relativeTo: this.route.parent }); + this.router.navigate(['../'], { relativeTo: this.route.parent }); } isOkrChampionChange(okrChampion: boolean, user: User) { diff --git a/frontend/src/app/team-management/member-list/member-list-mobile/member-list-mobile.component.spec.ts b/frontend/src/app/team-management/member-list/member-list-mobile/member-list-mobile.component.spec.ts index 7d99beb783..83848a4591 100644 --- a/frontend/src/app/team-management/member-list/member-list-mobile/member-list-mobile.component.spec.ts +++ b/frontend/src/app/team-management/member-list/member-list-mobile/member-list-mobile.component.spec.ts @@ -1,13 +1,13 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MemberListMobileComponent } from "./member-list-mobile.component"; -import { Team } from "../../../shared/types/model/Team"; -import { BehaviorSubject } from "rxjs"; -import { team1 } from "../../../shared/testData"; -import { UserTableEntry } from "../../../shared/types/model/UserTableEntry"; -import { MatTableDataSource } from "@angular/material/table"; +import { MemberListMobileComponent } from './member-list-mobile.component'; +import { Team } from '../../../shared/types/model/Team'; +import { BehaviorSubject } from 'rxjs'; +import { team1 } from '../../../shared/testData'; +import { UserTableEntry } from '../../../shared/types/model/UserTableEntry'; +import { MatTableDataSource } from '@angular/material/table'; -describe("MemberListMobileComponent", () => { +describe('MemberListMobileComponent', () => { let component: MemberListMobileComponent; let fixture: ComponentFixture; @@ -25,21 +25,21 @@ describe("MemberListMobileComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should navigate to correct path if no team is selected", () => { + it('should navigate to correct path if no team is selected', () => { component.selectedTeam$ = new BehaviorSubject(undefined); const userTableEntry: any = { id: 1 }; expect(component.getMemberDetailsLink(userTableEntry)) - .toStrictEqual("/team-management/details/member/1"); + .toStrictEqual('/team-management/details/member/1'); }); - it("should navigate to correct path team is selected", () => { + it('should navigate to correct path team is selected', () => { component.selectedTeam$ = new BehaviorSubject(team1); const userTableEntry: any = { id: 1 diff --git a/frontend/src/app/team-management/member-list/member-list-mobile/member-list-mobile.component.ts b/frontend/src/app/team-management/member-list/member-list-mobile/member-list-mobile.component.ts index 9ae8669ae0..97d77e427f 100644 --- a/frontend/src/app/team-management/member-list/member-list-mobile/member-list-mobile.component.ts +++ b/frontend/src/app/team-management/member-list/member-list-mobile/member-list-mobile.component.ts @@ -1,15 +1,15 @@ -import { Component, Input } from "@angular/core"; -import { UserTableEntry } from "../../../shared/types/model/UserTableEntry"; -import { MatTableDataSource } from "@angular/material/table"; -import { BehaviorSubject } from "rxjs"; -import { Team } from "../../../shared/types/model/Team"; -import { getFullNameFromUser } from "../../../shared/types/model/User"; -import { getRouteToUserDetails } from "../../../shared/routeUtils"; +import { Component, Input } from '@angular/core'; +import { UserTableEntry } from '../../../shared/types/model/UserTableEntry'; +import { MatTableDataSource } from '@angular/material/table'; +import { BehaviorSubject } from 'rxjs'; +import { Team } from '../../../shared/types/model/Team'; +import { getFullNameFromUser } from '../../../shared/types/model/User'; +import { getRouteToUserDetails } from '../../../shared/routeUtils'; @Component({ - selector: "app-member-list-mobile", - templateUrl: "./member-list-mobile.component.html", - styleUrl: "./member-list-mobile.component.scss" + selector: 'app-member-list-mobile', + templateUrl: './member-list-mobile.component.html', + styleUrl: './member-list-mobile.component.scss' }) export class MemberListMobileComponent { @Input({ required: true }) dataSource!: MatTableDataSource; diff --git a/frontend/src/app/team-management/member-list/member-list-table/member-list-table.component.spec.ts b/frontend/src/app/team-management/member-list/member-list-table/member-list-table.component.spec.ts index 29035814f1..47521af029 100644 --- a/frontend/src/app/team-management/member-list/member-list-table/member-list-table.component.spec.ts +++ b/frontend/src/app/team-management/member-list/member-list-table/member-list-table.component.spec.ts @@ -1,16 +1,16 @@ -import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; - -import { MemberListTableComponent } from "./member-list-table.component"; -import { team1, testUser } from "../../../shared/testData"; -import { BehaviorSubject, of } from "rxjs"; -import { UserTableEntry } from "../../../shared/types/model/UserTableEntry"; -import { UserService } from "../../../services/user.service"; -import { TeamService } from "../../../services/team.service"; -import { Team } from "../../../shared/types/model/Team"; -import { MatTableModule } from "@angular/material/table"; -import { DialogService } from "../../../services/dialog.service"; - -describe("MemberListTableComponent", () => { +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; + +import { MemberListTableComponent } from './member-list-table.component'; +import { team1, testUser } from '../../../shared/testData'; +import { BehaviorSubject, of } from 'rxjs'; +import { UserTableEntry } from '../../../shared/types/model/UserTableEntry'; +import { UserService } from '../../../services/user.service'; +import { TeamService } from '../../../services/team.service'; +import { Team } from '../../../shared/types/model/Team'; +import { MatTableModule } from '@angular/material/table'; +import { DialogService } from '../../../services/dialog.service'; + +describe('MemberListTableComponent', () => { let component: MemberListTableComponent; let fixture: ComponentFixture; @@ -61,53 +61,53 @@ describe("MemberListTableComponent", () => { teamServiceMock.removeUserFromTeam.mockReset(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should set displayedColumns for all teams correctly", fakeAsync(() => { + it('should set displayedColumns for all teams correctly', fakeAsync(() => { component.selectedTeam$.next(undefined); tick(); expect(component.displayedColumns) .toStrictEqual([ - "icon", - "name", - "roles", - "teams", - "okr_champion" + 'icon', + 'name', + 'roles', + 'teams', + 'okr_champion' ]); })); - it("should set displayedColumns for admin team correctly", fakeAsync(() => { + it('should set displayedColumns for admin team correctly', fakeAsync(() => { component.selectedTeam$.next(team1); tick(); expect(component.displayedColumns) - .toStrictEqual(["icon", - "name", - "role"]); + .toStrictEqual(['icon', + 'name', + 'role']); })); - it("should set displayedColumns for admin team correctly", fakeAsync(() => { + it('should set displayedColumns for admin team correctly', fakeAsync(() => { const team = { ...team1 }; team.writeable = true; component.selectedTeam$.next(team); tick(); expect(component.displayedColumns) .toStrictEqual([ - "icon", - "name", - "role", - "menu" + 'icon', + 'name', + 'role', + 'menu' ]); })); - it("should return correct memberDetailsLink", () => { + it('should return correct memberDetailsLink', () => { expect(component.getMemberDetailsLink(testUser)) - .toStrictEqual("/team-management/details/member/" + testUser.id); + .toStrictEqual('/team-management/details/member/' + testUser.id); }); - it("removeMemberFromTeam should call removeUserFromTeam and reloadUsers if confirmed", fakeAsync(() => { + it('removeMemberFromTeam should call removeUserFromTeam and reloadUsers if confirmed', fakeAsync(() => { const entry = { id: 1 }; @@ -119,7 +119,7 @@ describe("MemberListTableComponent", () => { afterClosed: () => of(true) }); - component.removeMemberFromTeam(entry as UserTableEntry, new MouseEvent("click")); + component.removeMemberFromTeam(entry as UserTableEntry, new MouseEvent('click')); tick(); expect(teamServiceMock.removeUserFromTeam) @@ -132,7 +132,7 @@ describe("MemberListTableComponent", () => { .toBeCalledTimes(1); })); - it("removeMemberFromTeam should not call removeUserFromTeam and reloadUsers if not confirmed", fakeAsync(() => { + it('removeMemberFromTeam should not call removeUserFromTeam and reloadUsers if not confirmed', fakeAsync(() => { const entry = { id: 1 }; @@ -144,7 +144,7 @@ describe("MemberListTableComponent", () => { afterClosed: () => of(false) }); - component.removeMemberFromTeam(entry as UserTableEntry, new MouseEvent("click")); + component.removeMemberFromTeam(entry as UserTableEntry, new MouseEvent('click')); tick(); expect(teamServiceMock.removeUserFromTeam) @@ -155,7 +155,7 @@ describe("MemberListTableComponent", () => { .toBeCalledTimes(0); })); - it("saveUserTeamRole should call updateOrAddTeamMembership and reload users", fakeAsync(() => { + it('saveUserTeamRole should call updateOrAddTeamMembership and reload users', fakeAsync(() => { teamServiceMock.updateOrAddTeamMembership.mockReturnValue(of(null)); userServiceMock.reloadCurrentUser.mockReturnValue(of()); const entry = { @@ -172,7 +172,7 @@ describe("MemberListTableComponent", () => { .toHaveBeenCalledTimes(1); })); - it("getSingleUserTeam should return first userTeam uf userTableEntry", () => { + it('getSingleUserTeam should return first userTeam uf userTableEntry', () => { const ut = { userTeamList: [testUser.userTeamList[0]] } as any; @@ -180,15 +180,15 @@ describe("MemberListTableComponent", () => { .toStrictEqual(testUser.userTeamList[0]); }); - it("getSingleUserTeam should throw error if userTeamList.length is not 1", () => { + it('getSingleUserTeam should throw error if userTeamList.length is not 1', () => { const ut = { userTeamList: [testUser.userTeamList[0], testUser.userTeamList[0]] } as any; expect(() => component.getSingleUserTeam(ut)) - .toThrowError("it should have exactly one UserTeam at this point"); + .toThrowError('it should have exactly one UserTeam at this point'); ut.userTeamList = []; expect(() => component.getSingleUserTeam(ut)) - .toThrowError("it should have exactly one UserTeam at this point"); + .toThrowError('it should have exactly one UserTeam at this point'); }); }); diff --git a/frontend/src/app/team-management/member-list/member-list-table/member-list-table.component.ts b/frontend/src/app/team-management/member-list/member-list-table/member-list-table.component.ts index ccc7e91fba..0f8319337a 100644 --- a/frontend/src/app/team-management/member-list/member-list-table/member-list-table.component.ts +++ b/frontend/src/app/team-management/member-list/member-list-table/member-list-table.component.ts @@ -1,19 +1,19 @@ -import { Component, Input, OnDestroy, OnInit } from "@angular/core"; -import { MatTableDataSource } from "@angular/material/table"; -import { UserTableEntry } from "../../../shared/types/model/UserTableEntry"; -import { User } from "../../../shared/types/model/User"; -import { Team } from "../../../shared/types/model/Team"; -import { TeamService } from "../../../services/team.service"; -import { UserService } from "../../../services/user.service"; -import { getRouteToUserDetails } from "../../../shared/routeUtils"; -import { BehaviorSubject, filter, mergeMap, Subject, takeUntil } from "rxjs"; -import { UserTeam } from "../../../shared/types/model/UserTeam"; -import { DialogService } from "../../../services/dialog.service"; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { MatTableDataSource } from '@angular/material/table'; +import { UserTableEntry } from '../../../shared/types/model/UserTableEntry'; +import { User } from '../../../shared/types/model/User'; +import { Team } from '../../../shared/types/model/Team'; +import { TeamService } from '../../../services/team.service'; +import { UserService } from '../../../services/user.service'; +import { getRouteToUserDetails } from '../../../shared/routeUtils'; +import { BehaviorSubject, filter, mergeMap, Subject, takeUntil } from 'rxjs'; +import { UserTeam } from '../../../shared/types/model/UserTeam'; +import { DialogService } from '../../../services/dialog.service'; @Component({ - selector: "app-member-list-table", - templateUrl: "./member-list-table.component.html", - styleUrl: "./member-list-table.component.scss" + selector: 'app-member-list-table', + templateUrl: './member-list-table.component.html', + styleUrl: './member-list-table.component.scss' }) export class MemberListTableComponent implements OnInit, OnDestroy { @Input({ required: true }) dataSource!: MatTableDataSource; @@ -21,16 +21,16 @@ export class MemberListTableComponent implements OnInit, OnDestroy { @Input({ required: true }) selectedTeam$!: BehaviorSubject; private allColumns = [ - "icon", - "name", - "roles", - "teams", - "okr_champion" + 'icon', + 'name', + 'roles', + 'teams', + 'okr_champion' ]; - private teamColumns = ["icon", - "name", - "role"]; + private teamColumns = ['icon', + 'name', + 'role']; private unsubscribe$ = new Subject(); @@ -56,7 +56,7 @@ export class MemberListTableComponent implements OnInit, OnDestroy { private setColumnForTeam(team: Team) { this.displayedColumns = [...this.teamColumns]; if (team.writeable) { - this.displayedColumns.push("menu"); + this.displayedColumns.push('menu'); } } @@ -72,7 +72,7 @@ export class MemberListTableComponent implements OnInit, OnDestroy { team: this.selectedTeam$.value?.name }; this.dialogService - .openConfirmDialog("CONFIRMATION.DELETE.USER_FROM_TEAM", i18nData) + .openConfirmDialog('CONFIRMATION.DELETE.USER_FROM_TEAM', i18nData) .afterClosed() .pipe(filter((confirm) => confirm), mergeMap(() => this.teamService.removeUserFromTeam(entry.id, this.selectedTeam$.value as Team))) .subscribe(() => { @@ -105,7 +105,7 @@ export class MemberListTableComponent implements OnInit, OnDestroy { */ getSingleUserTeam(userTableEntry: UserTableEntry): UserTeam { if (userTableEntry.userTeamList.length !== 1) { - throw Error("it should have exactly one UserTeam at this point"); + throw Error('it should have exactly one UserTeam at this point'); } return userTableEntry.userTeamList[0]; } diff --git a/frontend/src/app/team-management/member-list/member-list.component.spec.ts b/frontend/src/app/team-management/member-list/member-list.component.spec.ts index 93b942fd07..cb426481b6 100644 --- a/frontend/src/app/team-management/member-list/member-list.component.spec.ts +++ b/frontend/src/app/team-management/member-list/member-list.component.spec.ts @@ -1,24 +1,24 @@ -import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; -import { ActivatedRoute, provideRouter, Router } from "@angular/router"; -import { ChangeDetectorRef } from "@angular/core"; -import { of } from "rxjs"; -import { MemberListComponent } from "./member-list.component"; -import { UserService } from "../../services/user.service"; -import { provideHttpClientTesting } from "@angular/common/http/testing"; -import { User } from "../../shared/types/model/User"; -import { team1, team2, team3, testUser, users } from "../../shared/testData"; -import { convertFromUser, convertFromUsers, UserTableEntry } from "../../shared/types/model/UserTableEntry"; -import { UserRole } from "../../shared/types/enums/UserRole"; -import { TeamService } from "../../services/team.service"; -import { AddMemberToTeamDialogComponent } from "../add-member-to-team-dialog/add-member-to-team-dialog.component"; -import { AddEditTeamDialogComponent } from "../add-edit-team-dialog/add-edit-team-dialog.component"; -import { TranslateTestingModule } from "ngx-translate-testing"; -import { MatTableDataSource } from "@angular/material/table"; -import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import { MemberListTableComponent } from "./member-list-table/member-list-table.component"; -import { MemberListMobileComponent } from "./member-list-mobile/member-list-mobile.component"; -import { DialogService } from "../../services/dialog.service"; -import { provideHttpClient } from "@angular/common/http"; +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { ActivatedRoute, provideRouter, Router } from '@angular/router'; +import { ChangeDetectorRef } from '@angular/core'; +import { of } from 'rxjs'; +import { MemberListComponent } from './member-list.component'; +import { UserService } from '../../services/user.service'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { User } from '../../shared/types/model/User'; +import { team1, team2, team3, testUser, users } from '../../shared/testData'; +import { convertFromUser, convertFromUsers, UserTableEntry } from '../../shared/types/model/UserTableEntry'; +import { UserRole } from '../../shared/types/enums/UserRole'; +import { TeamService } from '../../services/team.service'; +import { AddMemberToTeamDialogComponent } from '../add-member-to-team-dialog/add-member-to-team-dialog.component'; +import { AddEditTeamDialogComponent } from '../add-edit-team-dialog/add-edit-team-dialog.component'; +import { TranslateTestingModule } from 'ngx-translate-testing'; +import { MatTableDataSource } from '@angular/material/table'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { MemberListTableComponent } from './member-list-table/member-list-table.component'; +import { MemberListMobileComponent } from './member-list-mobile/member-list-mobile.component'; +import { DialogService } from '../../services/dialog.service'; +import { provideHttpClient } from '@angular/common/http'; const userServiceMock = { getUsers: jest.fn(), @@ -46,7 +46,7 @@ const dialogService = { openConfirmDialog: jest.fn() }; -describe("MemberListComponent", () => { +describe('MemberListComponent', () => { let component: MemberListComponent; let fixture: ComponentFixture; @@ -85,7 +85,7 @@ describe("MemberListComponent", () => { userServiceMock.reloadCurrentUser.mockReset(); userServiceMock.reloadUsers.mockReset(); - jest.spyOn(userServiceMock, "getUsers") + jest.spyOn(userServiceMock, 'getUsers') .mockReturnValue(of([])); userServiceMock.reloadCurrentUser.mockReturnValue(of(testUser)); userServiceMock.getCurrentUser.mockReturnValue(of(testUser)); @@ -95,12 +95,12 @@ describe("MemberListComponent", () => { teamServiceMock.deleteTeam.mockReset(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should test method convertFromUser", () => { + it('should test method convertFromUser', () => { const user: User = { ...testUser }; let userTableEntry = convertFromUser(user); @@ -142,7 +142,7 @@ describe("MemberListComponent", () => { .toStrictEqual(user.userTeamList); }); - it("should test method convertFromUsers", () => { + it('should test method convertFromUsers', () => { const usersCopy: User[] = JSON.parse(JSON.stringify(users)); usersCopy[0].userTeamList.push({ id: 1, @@ -178,14 +178,14 @@ describe("MemberListComponent", () => { // should be sorted expect(userTableEntries.map((ut) => ut.firstname)) .toStrictEqual([ - "Bob", - "Key Result", - "Paco", - "Robin" + 'Bob', + 'Key Result', + 'Paco', + 'Robin' ]); }); - it("ngAfterViewInit should load all Users, set teamId, selectedTeam and update data source correctly", fakeAsync(() => { + it('ngAfterViewInit should load all Users, set teamId, selectedTeam and update data source correctly', fakeAsync(() => { userServiceMock.getUsers.mockReturnValue(of(users)); teamServiceMock.getAllTeams.mockReturnValue(of([team1, team2, @@ -202,7 +202,7 @@ describe("MemberListComponent", () => { .toBe(team1.name); })); - it("ngAfterViewInit should load all Users, set teamId, selectedTeam and update data source correctly if teamIdParam is null", fakeAsync(() => { + it('ngAfterViewInit should load all Users, set teamId, selectedTeam and update data source correctly if teamIdParam is null', fakeAsync(() => { activatedRouteMock.paramMap = of({ get: () => null }); @@ -220,7 +220,7 @@ describe("MemberListComponent", () => { }); })); - it("deleteTeam should trigger teamService.deleteTeam and navigate", fakeAsync(() => { + it('deleteTeam should trigger teamService.deleteTeam and navigate', fakeAsync(() => { routerMock.navigateByUrl.mockReturnValue(of(null)); teamServiceMock.deleteTeam.mockReturnValue(of(null)); dialogService.openConfirmDialog.mockReturnValue({ @@ -237,7 +237,7 @@ describe("MemberListComponent", () => { expect(teamServiceMock.deleteTeam) .toBeCalledWith(team.id); expect(routerMock.navigateByUrl) - .toBeCalledWith("team-management"); + .toBeCalledWith('team-management'); expect(routerMock.navigateByUrl) .toBeCalledTimes(1); expect(userServiceMock.reloadUsers) @@ -246,7 +246,7 @@ describe("MemberListComponent", () => { .toBeCalledTimes(1); })); - it("deleteTeam should not trigger teamService.deleteTeam if dialog is canceled", fakeAsync(() => { + it('deleteTeam should not trigger teamService.deleteTeam if dialog is canceled', fakeAsync(() => { routerMock.navigateByUrl.mockReturnValue(of(null)); teamServiceMock.deleteTeam.mockReturnValue(of(null)); dialogService.openConfirmDialog.mockReturnValue({ @@ -260,7 +260,7 @@ describe("MemberListComponent", () => { .toBeCalledTimes(0); })); - it("addMemberToTeam should open dialog", () => { + it('addMemberToTeam should open dialog', () => { component.selectedTeam$.next(team1); component.dataSource = new MatTableDataSource([]); dialogService.open.mockReturnValue({ @@ -277,7 +277,7 @@ describe("MemberListComponent", () => { })); }); - it("should showAddMemberToTeam if selectedTeam is set and selectedTeam is writable", () => { + it('should showAddMemberToTeam if selectedTeam is set and selectedTeam is writable', () => { component.selectedTeam$.next(undefined); expect(component.showAddMemberToTeam()) .toBeFalsy(); @@ -291,7 +291,7 @@ describe("MemberListComponent", () => { .toBeTruthy(); }); - it("edit team should open dialog", () => { + it('edit team should open dialog', () => { component.selectedTeam$.next(team1); dialogService.open.mockReturnValue({ afterClosed: () => of(null) diff --git a/frontend/src/app/team-management/member-list/member-list.component.ts b/frontend/src/app/team-management/member-list/member-list.component.ts index 13456971b1..7451efb924 100644 --- a/frontend/src/app/team-management/member-list/member-list.component.ts +++ b/frontend/src/app/team-management/member-list/member-list.component.ts @@ -1,21 +1,21 @@ -import { AfterViewInit, ChangeDetectorRef, Component, OnDestroy } from "@angular/core"; -import { UserService } from "../../services/user.service"; -import { ActivatedRoute, Router } from "@angular/router"; -import { BehaviorSubject, combineLatest, filter, map, mergeMap, ReplaySubject, Subject, takeUntil } from "rxjs"; -import { User } from "../../shared/types/model/User"; -import { convertFromUsers, UserTableEntry } from "../../shared/types/model/UserTableEntry"; -import { TeamService } from "../../services/team.service"; -import { Team } from "../../shared/types/model/Team"; -import { AddMemberToTeamDialogComponent } from "../add-member-to-team-dialog/add-member-to-team-dialog.component"; -import { AddEditTeamDialogComponent } from "../add-edit-team-dialog/add-edit-team-dialog.component"; -import { MatTableDataSource } from "@angular/material/table"; -import { InviteUserDialogComponent } from "../invite-user-dialog/invite-user-dialog.component"; -import { DialogService } from "../../services/dialog.service"; +import { AfterViewInit, ChangeDetectorRef, Component, OnDestroy } from '@angular/core'; +import { UserService } from '../../services/user.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { BehaviorSubject, combineLatest, filter, map, mergeMap, ReplaySubject, Subject, takeUntil } from 'rxjs'; +import { User } from '../../shared/types/model/User'; +import { convertFromUsers, UserTableEntry } from '../../shared/types/model/UserTableEntry'; +import { TeamService } from '../../services/team.service'; +import { Team } from '../../shared/types/model/Team'; +import { AddMemberToTeamDialogComponent } from '../add-member-to-team-dialog/add-member-to-team-dialog.component'; +import { AddEditTeamDialogComponent } from '../add-edit-team-dialog/add-edit-team-dialog.component'; +import { MatTableDataSource } from '@angular/material/table'; +import { InviteUserDialogComponent } from '../invite-user-dialog/invite-user-dialog.component'; +import { DialogService } from '../../services/dialog.service'; @Component({ - selector: "app-member-list", - templateUrl: "./member-list.component.html", - styleUrl: "./member-list.component.scss" + selector: 'app-member-list', + templateUrl: './member-list.component.html', + styleUrl: './member-list.component.scss' }) export class MemberListComponent implements OnDestroy, AfterViewInit { dataSource: MatTableDataSource = new MatTableDataSource([]); @@ -40,7 +40,7 @@ export class MemberListComponent implements OnDestroy, AfterViewInit { .getUsers() .pipe(takeUntil(this.unsubscribe$)) .subscribe((users) => this.allUsersSubj.next(users)); - const teamId$ = this.route.paramMap.pipe(map((params) => params.get("teamId"))); + const teamId$ = this.route.paramMap.pipe(map((params) => params.get('teamId'))); combineLatest([this.allUsersSubj.asObservable(), teamId$, this.teamService.getAllTeams()]) @@ -93,14 +93,14 @@ export class MemberListComponent implements OnDestroy, AfterViewInit { }; this.dialogService - .openConfirmDialog("CONFIRMATION.DELETE.TEAM", data) + .openConfirmDialog('CONFIRMATION.DELETE.TEAM', data) .afterClosed() .pipe(filter((confirm) => confirm), mergeMap(() => this.teamService.deleteTeam(selectedTeam.id))) .subscribe(() => { this.userService.reloadUsers(); this.userService.reloadCurrentUser() .subscribe(); - this.router.navigateByUrl("team-management"); + this.router.navigateByUrl('team-management'); }); } diff --git a/frontend/src/app/team-management/new-user/new-user.component.spec.ts b/frontend/src/app/team-management/new-user/new-user.component.spec.ts index b3869b5ae5..c39f8c50bd 100644 --- a/frontend/src/app/team-management/new-user/new-user.component.spec.ts +++ b/frontend/src/app/team-management/new-user/new-user.component.spec.ts @@ -1,14 +1,14 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { NewUserComponent } from "./new-user.component"; -import { FormControl, FormGroup, FormsModule, NgForm, ReactiveFormsModule } from "@angular/forms"; -import { SharedModule } from "../../shared/shared.module"; -import { PuzzleIconButtonComponent } from "../../shared/custom/puzzle-icon-button/puzzle-icon-button.component"; -import { PuzzleIconComponent } from "../../shared/custom/puzzle-icon/puzzle-icon.component"; -import { CommonModule } from "@angular/common"; -import { NewUserForm } from "../../shared/types/model/NewUserForm"; +import { NewUserComponent } from './new-user.component'; +import { FormControl, FormGroup, FormsModule, NgForm, ReactiveFormsModule } from '@angular/forms'; +import { SharedModule } from '../../shared/shared.module'; +import { PuzzleIconButtonComponent } from '../../shared/custom/puzzle-icon-button/puzzle-icon-button.component'; +import { PuzzleIconComponent } from '../../shared/custom/puzzle-icon/puzzle-icon.component'; +import { CommonModule } from '@angular/common'; +import { NewUserForm } from '../../shared/types/model/NewUserForm'; -describe("NewUserComponent", () => { +describe('NewUserComponent', () => { let component: NewUserComponent; let fixture: ComponentFixture; @@ -31,15 +31,15 @@ describe("NewUserComponent", () => { component = fixture.componentInstance; component.userFormGroup = new FormGroup>({ - firstname: new FormControl("user1"), - lastname: new FormControl("user"), - email: new FormControl("test@test.ch") + firstname: new FormControl('user1'), + lastname: new FormControl('user'), + email: new FormControl('test@test.ch') }); fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); diff --git a/frontend/src/app/team-management/new-user/new-user.component.ts b/frontend/src/app/team-management/new-user/new-user.component.ts index d9dec0cabf..c0c8f5cc8d 100644 --- a/frontend/src/app/team-management/new-user/new-user.component.ts +++ b/frontend/src/app/team-management/new-user/new-user.component.ts @@ -6,14 +6,14 @@ import { Input, Output, ViewChild -} from "@angular/core"; -import { ControlContainer, FormControl, FormGroup, NgForm } from "@angular/forms"; -import { NewUserForm } from "../../shared/types/model/NewUserForm"; +} from '@angular/core'; +import { ControlContainer, FormControl, FormGroup, NgForm } from '@angular/forms'; +import { NewUserForm } from '../../shared/types/model/NewUserForm'; @Component({ - selector: "app-new-user", - templateUrl: "./new-user.component.html", - styleUrl: "./new-user.component.scss", + selector: 'app-new-user', + templateUrl: './new-user.component.html', + styleUrl: './new-user.component.scss', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], changeDetection: ChangeDetectionStrategy.Default @@ -31,7 +31,7 @@ export class NewUserComponent implements AfterViewInit { @Output() removeUser: EventEmitter = new EventEmitter(); - @ViewChild("firstInput") firstInput: any; + @ViewChild('firstInput') firstInput: any; ngAfterViewInit(): void { this.firstInput.nativeElement.focus(); diff --git a/frontend/src/app/team-management/new-user/unique-mail.directive.spec.ts b/frontend/src/app/team-management/new-user/unique-mail.directive.spec.ts index 105345963d..8b56f6115a 100644 --- a/frontend/src/app/team-management/new-user/unique-mail.directive.spec.ts +++ b/frontend/src/app/team-management/new-user/unique-mail.directive.spec.ts @@ -1,10 +1,10 @@ -import { UniqueEmailValidator } from "./unique-mail.validator"; -import { users } from "../../shared/testData"; -import { TestBed } from "@angular/core/testing"; -import { of } from "rxjs"; -import { AbstractControl } from "@angular/forms"; +import { UniqueEmailValidator } from './unique-mail.validator'; +import { users } from '../../shared/testData'; +import { TestBed } from '@angular/core/testing'; +import { of } from 'rxjs'; +import { AbstractControl } from '@angular/forms'; -describe("UniqueMailDirective", () => { +describe('UniqueMailDirective', () => { const userServiceMock = { getUsers: jest.fn() } as any; @@ -13,7 +13,7 @@ describe("UniqueMailDirective", () => { userServiceMock.getUsers.mockReturnValue(of(users)); }); - it("should create an instance", () => { + it('should create an instance', () => { TestBed.runInInjectionContext(() => { const directive = new UniqueEmailValidator(userServiceMock); expect(directive) @@ -21,7 +21,7 @@ describe("UniqueMailDirective", () => { }); }); - it("should return validationError if user exists, otherwise null", () => { + it('should return validationError if user exists, otherwise null', () => { TestBed.runInInjectionContext(() => { const directive = new UniqueEmailValidator(userServiceMock); @@ -29,7 +29,7 @@ describe("UniqueMailDirective", () => { expect(directive.validate(control)) .toStrictEqual({ notUniqueMail: { value: users[0].email } }); - const notExistingMail = "notexistinguser@test.com"; + const notExistingMail = 'notexistinguser@test.com'; control = { value: notExistingMail } as AbstractControl; expect(directive.validate(control)) .toStrictEqual(null); diff --git a/frontend/src/app/team-management/new-user/unique-mail.validator.ts b/frontend/src/app/team-management/new-user/unique-mail.validator.ts index 84b5e3817d..fa905a580e 100644 --- a/frontend/src/app/team-management/new-user/unique-mail.validator.ts +++ b/frontend/src/app/team-management/new-user/unique-mail.validator.ts @@ -1,9 +1,9 @@ -import { Injectable } from "@angular/core"; -import { AbstractControl, ValidationErrors, Validator } from "@angular/forms"; -import { UserService } from "../../services/user.service"; -import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { Injectable } from '@angular/core'; +import { AbstractControl, ValidationErrors, Validator } from '@angular/forms'; +import { UserService } from '../../services/user.service'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -@Injectable({ providedIn: "root" }) +@Injectable({ providedIn: 'root' }) export class UniqueEmailValidator implements Validator { private existingUserMails: string[] = []; // mails exsiting already in backend diff --git a/frontend/src/app/team-management/okr-champion.pipe.spec.ts b/frontend/src/app/team-management/okr-champion.pipe.spec.ts index f3c3d0e8c8..ee7058ad4f 100644 --- a/frontend/src/app/team-management/okr-champion.pipe.spec.ts +++ b/frontend/src/app/team-management/okr-champion.pipe.spec.ts @@ -1,25 +1,25 @@ -import { OkrChampionPipe } from "./okr-champion.pipe"; +import { OkrChampionPipe } from './okr-champion.pipe'; -describe("OkrChampionPipe", () => { +describe('OkrChampionPipe', () => { const translateMock = { - instant: () => "Ja" + instant: () => 'Ja' } as any; - it("create an instance", () => { + it('create an instance', () => { const pipe = new OkrChampionPipe(translateMock); expect(pipe) .toBeTruthy(); }); - it("should display \"Ja\" if user is okrChampion", () => { + it('should display "Ja" if user is okrChampion', () => { const pipe = new OkrChampionPipe(translateMock); expect(pipe.transform(true)) - .toBe("Ja"); + .toBe('Ja'); }); - it("should display \"-\" if user is not okrChampion", () => { + it('should display "-" if user is not okrChampion', () => { const pipe = new OkrChampionPipe(translateMock); expect(pipe.transform(false)) - .toBe("-"); + .toBe('-'); }); }); diff --git a/frontend/src/app/team-management/okr-champion.pipe.ts b/frontend/src/app/team-management/okr-champion.pipe.ts index 13c681deaa..e1434ad1d0 100644 --- a/frontend/src/app/team-management/okr-champion.pipe.ts +++ b/frontend/src/app/team-management/okr-champion.pipe.ts @@ -1,14 +1,14 @@ -import { Pipe, PipeTransform } from "@angular/core"; -import { TranslateService } from "@ngx-translate/core"; +import { Pipe, PipeTransform } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; @Pipe({ - name: "okrChampion", + name: 'okrChampion', standalone: true }) export class OkrChampionPipe implements PipeTransform { constructor(private readonly translate: TranslateService) {} transform(isOkrChampion: boolean): string { - return isOkrChampion ? this.translate.instant("SHARED.JA") : "-"; + return isOkrChampion ? this.translate.instant('SHARED.JA') : '-'; } } diff --git a/frontend/src/app/team-management/roles.pipe.ts b/frontend/src/app/team-management/roles.pipe.ts index 03ed1e0e3d..620ff0a6f6 100644 --- a/frontend/src/app/team-management/roles.pipe.ts +++ b/frontend/src/app/team-management/roles.pipe.ts @@ -1,18 +1,18 @@ -import { Pipe, PipeTransform } from "@angular/core"; -import { UserRole } from "../shared/types/enums/UserRole"; -import { TranslateService } from "@ngx-translate/core"; +import { Pipe, PipeTransform } from '@angular/core'; +import { UserRole } from '../shared/types/enums/UserRole'; +import { TranslateService } from '@ngx-translate/core'; @Pipe({ - name: "roles" + name: 'roles' }) export class RolesPipe implements PipeTransform { constructor(private translate: TranslateService) {} transform(roles: UserRole[]): string { if (!roles?.length) { - return ""; + return ''; } - return roles.map((r) => this.translate.instant("USER_ROLE." + r)) - .join(", "); + return roles.map((r) => this.translate.instant('USER_ROLE.' + r)) + .join(', '); } } diff --git a/frontend/src/app/team-management/search-team-management/search-team-management.component.spec.ts b/frontend/src/app/team-management/search-team-management/search-team-management.component.spec.ts index d13d408fe4..3e381802cf 100644 --- a/frontend/src/app/team-management/search-team-management/search-team-management.component.spec.ts +++ b/frontend/src/app/team-management/search-team-management/search-team-management.component.spec.ts @@ -1,76 +1,76 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { RouterTestingModule } from "@angular/router/testing"; -import { MatAutocompleteModule } from "@angular/material/autocomplete"; -import { SharedModule } from "../../shared/shared.module"; -import { MatInputModule } from "@angular/material/input"; -import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import { FilteredTeam, FilteredUser, SearchTeamManagementComponent } from "./search-team-management.component"; -import { TranslateTestingModule } from "ngx-translate-testing"; -import * as de from "../../../assets/i18n/de.json"; -import { MatIconModule } from "@angular/material/icon"; -import { ReactiveFormsModule } from "@angular/forms"; -import { TeamService } from "../../services/team.service"; -import { UserService } from "../../services/user.service"; -import { of } from "rxjs"; -import { Team } from "../../shared/types/model/Team"; -import { User } from "../../shared/types/model/User"; -import { ActivatedRoute, ActivatedRouteSnapshot, Router } from "@angular/router"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { SharedModule } from '../../shared/shared.module'; +import { MatInputModule } from '@angular/material/input'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { FilteredTeam, FilteredUser, SearchTeamManagementComponent } from './search-team-management.component'; +import { TranslateTestingModule } from 'ngx-translate-testing'; +import * as de from '../../../assets/i18n/de.json'; +import { MatIconModule } from '@angular/material/icon'; +import { ReactiveFormsModule } from '@angular/forms'; +import { TeamService } from '../../services/team.service'; +import { UserService } from '../../services/user.service'; +import { of } from 'rxjs'; +import { Team } from '../../shared/types/model/Team'; +import { User } from '../../shared/types/model/User'; +import { ActivatedRoute, ActivatedRouteSnapshot, Router } from '@angular/router'; import Spy = jasmine.Spy; const teams: Team[] = [ { id: 1, version: 1, - name: "ZZ the Puzzle Team - Keyword", + name: 'ZZ the Puzzle Team - Keyword', writeable: false }, { id: 2, version: 1, - name: "The Puzzle Team - Keyword", + name: 'The Puzzle Team - Keyword', writeable: false }, { id: 3, version: 1, - name: "Puzzle Team - No", + name: 'Puzzle Team - No', writeable: false }, { id: 4, version: 1, - name: "Team Ruedi - Noname", + name: 'Team Ruedi - Noname', writeable: false } ]; const users: User[] = [{ id: 2, - firstname: "Pete", - lastname: "Parrot", - email: "parrot@puzzle.ch", + firstname: 'Pete', + lastname: 'Parrot', + email: 'parrot@puzzle.ch', userTeamList: [], isOkrChampion: false }, { id: 1, - firstname: "Martin", - lastname: "Käser", - email: "kaeser@puzzle.ch", + firstname: 'Martin', + lastname: 'Käser', + email: 'kaeser@puzzle.ch', userTeamList: [], isOkrChampion: false }, { id: 3, - firstname: "Ruedi", - lastname: "Peters", - email: "rpeter@gmail.com", + firstname: 'Ruedi', + lastname: 'Peters', + email: 'rpeter@gmail.com', userTeamList: [], isOkrChampion: false }]; -describe("SearchTeamManagementComponent", () => { +describe('SearchTeamManagementComponent', () => { let component: SearchTeamManagementComponent; let fixture: ComponentFixture; @@ -130,7 +130,7 @@ describe("SearchTeamManagementComponent", () => { .compileComponents(); }); beforeEach(() => { - navigateSpy = jest.spyOn(TestBed.inject(Router), "navigateByUrl") as unknown as Spy; + navigateSpy = jest.spyOn(TestBed.inject(Router), 'navigateByUrl') as unknown as Spy; fixture = TestBed.createComponent(SearchTeamManagementComponent); component = fixture.componentInstance; @@ -144,25 +144,25 @@ describe("SearchTeamManagementComponent", () => { const getDisplayValues = (value: FilteredUser | FilteredTeam) => value.displayValue; const getHTMLValues = (value: FilteredUser | FilteredTeam) => value.htmlValue; - it("should filter out entries and order them according to the position in which the search value occurs", () => { - component.search.setValue("puz"); + it('should filter out entries and order them according to the position in which the search value occurs', () => { + component.search.setValue('puz'); fixture.detectChanges(); jest.advanceTimersByTime(250); const filteredUsers = component.filteredUsers$.getValue(); const filteredTeams = component.filteredTeams$.getValue(); expect(filteredUsers.map(getDisplayValues)) - .toEqual(["Pete Parrot (parrot@puzzle.ch)", - "Martin Käser (kaeser@puzzle.ch)"]); + .toEqual(['Pete Parrot (parrot@puzzle.ch)', + 'Martin Käser (kaeser@puzzle.ch)']); expect(filteredTeams.map(getDisplayValues)) - .toEqual(["Puzzle Team - No", - "The Puzzle Team - Keyword", - "ZZ the Puzzle Team - Keyword"]); + .toEqual(['Puzzle Team - No', + 'The Puzzle Team - Keyword', + 'ZZ the Puzzle Team - Keyword']); }); - it("should generate html values correctly", () => { - component.search.setValue("Ruedi"); + it('should generate html values correctly', () => { + component.search.setValue('Ruedi'); fixture.detectChanges(); jest.advanceTimersByTime(250); @@ -170,14 +170,14 @@ describe("SearchTeamManagementComponent", () => { const filteredTeams = component.filteredTeams$.getValue(); expect(filteredUsers.map(getHTMLValues)) - .toEqual(["Ruedi Peters (rpeter@gmail.com)"]); + .toEqual(['Ruedi Peters (rpeter@gmail.com)']); expect(filteredTeams.map(getHTMLValues)) - .toEqual(["Team Ruedi - Noname"]); + .toEqual(['Team Ruedi - Noname']); }); - it("should debounce inputs correctly", () => { - component.search.setValue("Ruedi"); + it('should debounce inputs correctly', () => { + component.search.setValue('Ruedi'); fixture.detectChanges(); jest.advanceTimersByTime(100); // After 100ms @@ -191,28 +191,28 @@ describe("SearchTeamManagementComponent", () => { expect(component.filteredTeams$.getValue()).not.toHaveLength(0); }); - it("should stay on current team page when a user is selected", () => { - activatedRouteMock!.snapshot!.params["teamId"] = "42"; + it('should stay on current team page when a user is selected', () => { + activatedRouteMock!.snapshot!.params['teamId'] = '42'; component.selectUser(users[1]); expect(navigateSpy) - .toHaveBeenCalledWith("/team-management/42/details/member/2"); + .toHaveBeenCalledWith('/team-management/42/details/member/2'); }); - it("should stay on current root page when a user is selected", () => { + it('should stay on current root page when a user is selected', () => { activatedRouteMock!.snapshot!.params = {}; component.selectUser(users[1]); expect(navigateSpy) - .toHaveBeenCalledWith("/team-management/details/member/2"); + .toHaveBeenCalledWith('/team-management/details/member/2'); }); - it("should switch to teams page when selected", () => { + it('should switch to teams page when selected', () => { component.selectTeam(teams[0]); expect(navigateSpy) - .toHaveBeenCalledWith("/team-management/1"); + .toHaveBeenCalledWith('/team-management/1'); }); }); diff --git a/frontend/src/app/team-management/search-team-management/search-team-management.component.ts b/frontend/src/app/team-management/search-team-management/search-team-management.component.ts index 6597ed8368..8ed5a50229 100644 --- a/frontend/src/app/team-management/search-team-management/search-team-management.component.ts +++ b/frontend/src/app/team-management/search-team-management/search-team-management.component.ts @@ -1,13 +1,13 @@ -import { Component } from "@angular/core"; -import { FormControl } from "@angular/forms"; -import { UserService } from "../../services/user.service"; -import { TeamService } from "../../services/team.service"; -import { Team } from "../../shared/types/model/Team"; -import { User } from "../../shared/types/model/User"; -import { BehaviorSubject, combineLatest, debounceTime, distinctUntilChanged, map } from "rxjs"; -import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; -import { getRouteToTeam, getRouteToUserDetails } from "../../shared/routeUtils"; -import { ActivatedRoute, Router } from "@angular/router"; +import { Component } from '@angular/core'; +import { FormControl } from '@angular/forms'; +import { UserService } from '../../services/user.service'; +import { TeamService } from '../../services/team.service'; +import { Team } from '../../shared/types/model/Team'; +import { User } from '../../shared/types/model/User'; +import { BehaviorSubject, combineLatest, debounceTime, distinctUntilChanged, map } from 'rxjs'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { getRouteToTeam, getRouteToUserDetails } from '../../shared/routeUtils'; +import { ActivatedRoute, Router } from '@angular/router'; export interface FilteredUser extends User { displayValue: string; @@ -20,20 +20,20 @@ export interface FilteredTeam extends Team { } @Component({ - selector: "app-search-team-management", - templateUrl: "./search-team-management.component.html", - styleUrl: "./search-team-management.component.scss" + selector: 'app-search-team-management', + templateUrl: './search-team-management.component.html', + styleUrl: './search-team-management.component.scss' }) export class SearchTeamManagementComponent { static MAX_SUGGESTIONS = 3; - search = new FormControl(""); + search = new FormControl(''); filteredUsers$ = new BehaviorSubject([]); filteredTeams$ = new BehaviorSubject([]); - searchValue$ = new BehaviorSubject(""); + searchValue$ = new BehaviorSubject(''); private teams: Team[] = []; @@ -56,7 +56,7 @@ export class SearchTeamManagementComponent { this.search.valueChanges .pipe( - takeUntilDestroyed(), debounceTime(200), map((v) => (v ?? "").trim()), distinctUntilChanged() + takeUntilDestroyed(), debounceTime(200), map((v) => (v ?? '').trim()), distinctUntilChanged() ) .subscribe((searchValue) => { this.searchValue$.next(searchValue); @@ -69,14 +69,14 @@ export class SearchTeamManagementComponent { } selectUser(user: User) { - this.search.setValue(""); - const teamId: number = this.activatedRoute.snapshot.params["teamId"]; + this.search.setValue(''); + const teamId: number = this.activatedRoute.snapshot.params['teamId']; this.router.navigateByUrl(getRouteToUserDetails(user.id, teamId)) .then(); } selectTeam(team: Team) { - this.search.setValue(""); + this.search.setValue(''); this.router.navigateByUrl(getRouteToTeam(team.id)) .then(); } @@ -149,6 +149,6 @@ export class SearchTeamManagementComponent { } private formatText(value: string, text: string): string { - return value.replaceAll(new RegExp(`(${text})`, "ig"), "$1"); + return value.replaceAll(new RegExp(`(${text})`, 'ig'), '$1'); } } diff --git a/frontend/src/app/team-management/show-edit-role/show-edit-role.component.spec.ts b/frontend/src/app/team-management/show-edit-role/show-edit-role.component.spec.ts index f8ac7c1fc2..348bda27cd 100644 --- a/frontend/src/app/team-management/show-edit-role/show-edit-role.component.spec.ts +++ b/frontend/src/app/team-management/show-edit-role/show-edit-role.component.spec.ts @@ -1,11 +1,11 @@ -import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; -import { ShowEditRoleComponent } from "./show-edit-role.component"; -import { testUser } from "../../shared/testData"; -import { TranslateTestingModule } from "ngx-translate-testing"; -import * as de from "../../../assets/i18n/de.json"; +import { ShowEditRoleComponent } from './show-edit-role.component'; +import { testUser } from '../../shared/testData'; +import { TranslateTestingModule } from 'ngx-translate-testing'; +import * as de from '../../../assets/i18n/de.json'; -describe("ShowEditRoleComponent", () => { +describe('ShowEditRoleComponent', () => { let component: ShowEditRoleComponent; let fixture: ComponentFixture; const userTeam = { ...testUser.userTeamList[0] }; @@ -25,19 +25,19 @@ describe("ShowEditRoleComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("saveIsAdmin should set edit to false", () => { + it('saveIsAdmin should set edit to false', () => { component.edit = true; component.saveIsAdmin(true); expect(component.edit) .toBeFalsy(); }); - it("setEditAsync should set edit to given value", fakeAsync(() => { + it('setEditAsync should set edit to given value', fakeAsync(() => { component.edit = false; const mouseEvent = { stopPropagation: () => undefined diff --git a/frontend/src/app/team-management/show-edit-role/show-edit-role.component.ts b/frontend/src/app/team-management/show-edit-role/show-edit-role.component.ts index 415cdae624..cb57ebb83a 100644 --- a/frontend/src/app/team-management/show-edit-role/show-edit-role.component.ts +++ b/frontend/src/app/team-management/show-edit-role/show-edit-role.component.ts @@ -1,11 +1,11 @@ -import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, Output } from "@angular/core"; -import { UserTeam } from "../../shared/types/model/UserTeam"; -import { TranslateService } from "@ngx-translate/core"; +import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, Output } from '@angular/core'; +import { UserTeam } from '../../shared/types/model/UserTeam'; +import { TranslateService } from '@ngx-translate/core'; @Component({ - selector: "app-show-edit-role", - templateUrl: "./show-edit-role.component.html", - styleUrl: "./show-edit-role.component.scss" + selector: 'app-show-edit-role', + templateUrl: './show-edit-role.component.html', + styleUrl: './show-edit-role.component.scss' }) export class ShowEditRoleComponent { @Input({ required: true }) userTeam!: UserTeam; @@ -19,7 +19,7 @@ export class ShowEditRoleComponent { private readonly elementRef: ElementRef, private readonly cd: ChangeDetectorRef) {} - @HostListener("document:click", ["$event"]) + @HostListener('document:click', ['$event']) clickOutside(event: MouseEvent) { if (this.elementRef.nativeElement.contains(event.target)) { return; @@ -46,9 +46,9 @@ export class ShowEditRoleComponent { getRole(): string { if (this.userTeam.isTeamAdmin) { - return this.translate.instant("USER_ROLE.TEAM_ADMIN"); + return this.translate.instant('USER_ROLE.TEAM_ADMIN'); } - return this.translate.instant("USER_ROLE.TEAM_MEMBER"); + return this.translate.instant('USER_ROLE.TEAM_MEMBER'); } isEditable() { diff --git a/frontend/src/app/team-management/team-list/team-list.component.spec.ts b/frontend/src/app/team-management/team-list/team-list.component.spec.ts index 368b57f3bc..30bb277ff3 100644 --- a/frontend/src/app/team-management/team-list/team-list.component.spec.ts +++ b/frontend/src/app/team-management/team-list/team-list.component.spec.ts @@ -1,10 +1,10 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { of } from "rxjs"; -import { ActivatedRoute } from "@angular/router"; -import { TeamService } from "../../services/team.service"; -import { TeamListComponent } from "./team-list.component"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { of } from 'rxjs'; +import { ActivatedRoute } from '@angular/router'; +import { TeamService } from '../../services/team.service'; +import { TeamListComponent } from './team-list.component'; -describe("TeamListComponent", () => { +describe('TeamListComponent', () => { let component: TeamListComponent; let fixture: ComponentFixture; const paramTeamId = 1; @@ -37,18 +37,18 @@ describe("TeamListComponent", () => { fixture.detectChanges(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should set selected teamid", () => { + it('should set selected teamid', () => { component.ngOnInit(); expect(component.selectedTeamId) .toBe(paramTeamId); }); - it("should set selected teamid", () => { + it('should set selected teamid', () => { activatedRouteMock.paramMap = of({ get: () => undefined }); diff --git a/frontend/src/app/team-management/team-list/team-list.component.ts b/frontend/src/app/team-management/team-list/team-list.component.ts index 424404bdbb..1e0734c69c 100644 --- a/frontend/src/app/team-management/team-list/team-list.component.ts +++ b/frontend/src/app/team-management/team-list/team-list.component.ts @@ -1,13 +1,13 @@ -import { Component, OnDestroy, OnInit } from "@angular/core"; -import { TeamService } from "../../services/team.service"; -import { Observable, Subject, takeUntil } from "rxjs"; -import { Team } from "../../shared/types/model/Team"; -import { ActivatedRoute } from "@angular/router"; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { TeamService } from '../../services/team.service'; +import { Observable, Subject, takeUntil } from 'rxjs'; +import { Team } from '../../shared/types/model/Team'; +import { ActivatedRoute } from '@angular/router'; @Component({ - selector: "app-team-list", - templateUrl: "./team-list.component.html", - styleUrl: "./team-list.component.scss" + selector: 'app-team-list', + templateUrl: './team-list.component.html', + styleUrl: './team-list.component.scss' }) export class TeamListComponent implements OnInit, OnDestroy { public teams$: Observable; @@ -24,7 +24,7 @@ export class TeamListComponent implements OnInit, OnDestroy { public ngOnInit(): void { this.route.paramMap.pipe(takeUntil(this.unsubscribe$)) .subscribe((params) => { - const teamId = params.get("teamId"); + const teamId = params.get('teamId'); this.selectedTeamId = teamId ? parseInt(teamId) : undefined; }); } diff --git a/frontend/src/app/team-management/team-management-banner/team-management-banner.component.spec.ts b/frontend/src/app/team-management/team-management-banner/team-management-banner.component.spec.ts index 3b02fe25e2..cbcab692e4 100644 --- a/frontend/src/app/team-management/team-management-banner/team-management-banner.component.spec.ts +++ b/frontend/src/app/team-management/team-management-banner/team-management-banner.component.spec.ts @@ -1,19 +1,19 @@ -import { TeamManagementBannerComponent } from "./team-management-banner.component"; -import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; -import { MatDialogModule } from "@angular/material/dialog"; -import { of } from "rxjs"; -import { AddEditTeamDialogComponent } from "../add-edit-team-dialog/add-edit-team-dialog.component"; -import { SearchTeamManagementComponent } from "../search-team-management/search-team-management.component"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { MatIconModule } from "@angular/material/icon"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { TranslateModule } from "@ngx-translate/core"; -import { MatAutocompleteModule } from "@angular/material/autocomplete"; -import { ActivatedRoute } from "@angular/router"; -import { DialogService } from "../../services/dialog.service"; -import { OkrTangramComponent } from "../../shared/custom/okr-tangram/okr-tangram.component"; +import { TeamManagementBannerComponent } from './team-management-banner.component'; +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { MatDialogModule } from '@angular/material/dialog'; +import { of } from 'rxjs'; +import { AddEditTeamDialogComponent } from '../add-edit-team-dialog/add-edit-team-dialog.component'; +import { SearchTeamManagementComponent } from '../search-team-management/search-team-management.component'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { TranslateModule } from '@ngx-translate/core'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { ActivatedRoute } from '@angular/router'; +import { DialogService } from '../../services/dialog.service'; +import { OkrTangramComponent } from '../../shared/custom/okr-tangram/okr-tangram.component'; -describe("TeamManagementBannerComponent", () => { +describe('TeamManagementBannerComponent', () => { let component: TeamManagementBannerComponent; let fixture: ComponentFixture; @@ -47,12 +47,12 @@ describe("TeamManagementBannerComponent", () => { component = fixture.componentInstance; }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("createTeam should open dialog", fakeAsync(() => { + it('createTeam should open dialog', fakeAsync(() => { dialogServiceMock.open.mockReturnValue({ afterClosed: () => of() }); diff --git a/frontend/src/app/team-management/team-management-banner/team-management-banner.component.ts b/frontend/src/app/team-management/team-management-banner/team-management-banner.component.ts index b846c4e097..51806f85ae 100644 --- a/frontend/src/app/team-management/team-management-banner/team-management-banner.component.ts +++ b/frontend/src/app/team-management/team-management-banner/team-management-banner.component.ts @@ -1,12 +1,12 @@ -import { Component } from "@angular/core"; -import { MatDialogRef } from "@angular/material/dialog"; -import { AddEditTeamDialogComponent } from "../add-edit-team-dialog/add-edit-team-dialog.component"; -import { DialogService } from "../../services/dialog.service"; +import { Component } from '@angular/core'; +import { MatDialogRef } from '@angular/material/dialog'; +import { AddEditTeamDialogComponent } from '../add-edit-team-dialog/add-edit-team-dialog.component'; +import { DialogService } from '../../services/dialog.service'; @Component({ - selector: "app-team-management-banner", - templateUrl: "./team-management-banner.component.html", - styleUrl: "./team-management-banner.component.scss" + selector: 'app-team-management-banner', + templateUrl: './team-management-banner.component.html', + styleUrl: './team-management-banner.component.scss' }) export class TeamManagementBannerComponent { private dialogRef!: MatDialogRef | undefined; diff --git a/frontend/src/app/team-management/team-management-mobile-filter/team-management-mobile-filter.component.spec.ts b/frontend/src/app/team-management/team-management-mobile-filter/team-management-mobile-filter.component.spec.ts index ee4a7303ef..b0bfa092a7 100644 --- a/frontend/src/app/team-management/team-management-mobile-filter/team-management-mobile-filter.component.spec.ts +++ b/frontend/src/app/team-management/team-management-mobile-filter/team-management-mobile-filter.component.spec.ts @@ -1,30 +1,30 @@ -import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing"; +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; -import { TeamManagementMobileFilterComponent } from "./team-management-mobile-filter.component"; -import { TeamService } from "../../services/team.service"; -import { team1, teamList } from "../../shared/testData"; -import { BehaviorSubject, of } from "rxjs"; -import { ActivatedRoute, Router } from "@angular/router"; -import { SearchTeamManagementComponent } from "../search-team-management/search-team-management.component"; -import { HttpClientModule } from "@angular/common/http"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { MatSelectModule } from "@angular/material/select"; -import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { TranslateTestingModule } from "ngx-translate-testing"; -import * as de from "../../../assets/i18n/de.json"; -import { MatAutocompleteModule } from "@angular/material/autocomplete"; -import { MatIconModule } from "@angular/material/icon"; -import { BrowserModule } from "@angular/platform-browser"; -import { MatInputModule } from "@angular/material/input"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; -import { getRouteToAllTeams, getRouteToTeam } from "../../shared/routeUtils"; +import { TeamManagementMobileFilterComponent } from './team-management-mobile-filter.component'; +import { TeamService } from '../../services/team.service'; +import { team1, teamList } from '../../shared/testData'; +import { BehaviorSubject, of } from 'rxjs'; +import { ActivatedRoute, Router } from '@angular/router'; +import { SearchTeamManagementComponent } from '../search-team-management/search-team-management.component'; +import { HttpClientModule } from '@angular/common/http'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatSelectModule } from '@angular/material/select'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TranslateTestingModule } from 'ngx-translate-testing'; +import * as de from '../../../assets/i18n/de.json'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatIconModule } from '@angular/material/icon'; +import { BrowserModule } from '@angular/platform-browser'; +import { MatInputModule } from '@angular/material/input'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { getRouteToAllTeams, getRouteToTeam } from '../../shared/routeUtils'; -describe("TeamManagementMobileFilterComponent", () => { +describe('TeamManagementMobileFilterComponent', () => { let component: TeamManagementMobileFilterComponent; let fixture: ComponentFixture; const teamIdSubj = new BehaviorSubject({ - get: (): string | undefined => "1" + get: (): string | undefined => '1' }); const teamServiceMock = { @@ -78,12 +78,12 @@ describe("TeamManagementMobileFilterComponent", () => { routerMock.navigateByUrl.mockReset(); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("should set allTeams and selectedTeam correctly", fakeAsync(() => { + it('should set allTeams and selectedTeam correctly', fakeAsync(() => { tick(); expect(component.selectedTeam) .toStrictEqual(team1); @@ -91,7 +91,7 @@ describe("TeamManagementMobileFilterComponent", () => { .toStrictEqual(teamList); })); - it("should set allTeams and selectedTeam correctly if no teamId given", fakeAsync(() => { + it('should set allTeams and selectedTeam correctly if no teamId given', fakeAsync(() => { teamIdSubj.next({ get: () => undefined }); @@ -102,7 +102,7 @@ describe("TeamManagementMobileFilterComponent", () => { .toStrictEqual(teamList); })); - it("navigate should navigate to team ", () => { + it('navigate should navigate to team ', () => { component.navigate(team1); expect(routerMock.navigateByUrl) .toBeCalledTimes(1); @@ -110,7 +110,7 @@ describe("TeamManagementMobileFilterComponent", () => { .toBeCalledWith(getRouteToTeam(team1.id)); }); - it("navigate should navigate to all teams ", () => { + it('navigate should navigate to all teams ', () => { component.navigate(component.ALL_TEAMS); expect(routerMock.navigateByUrl) .toBeCalledTimes(1); diff --git a/frontend/src/app/team-management/team-management-mobile-filter/team-management-mobile-filter.component.ts b/frontend/src/app/team-management/team-management-mobile-filter/team-management-mobile-filter.component.ts index 5f04cb6a7a..b4eb421be3 100644 --- a/frontend/src/app/team-management/team-management-mobile-filter/team-management-mobile-filter.component.ts +++ b/frontend/src/app/team-management/team-management-mobile-filter/team-management-mobile-filter.component.ts @@ -1,21 +1,21 @@ -import { Component } from "@angular/core"; -import { TeamService } from "../../services/team.service"; -import { Team } from "../../shared/types/model/Team"; -import { ActivatedRoute, ParamMap, Router } from "@angular/router"; -import { getRouteToAllTeams, getRouteToTeam } from "../../shared/routeUtils"; -import { combineLatest } from "rxjs"; -import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { Component } from '@angular/core'; +import { TeamService } from '../../services/team.service'; +import { Team } from '../../shared/types/model/Team'; +import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { getRouteToAllTeams, getRouteToTeam } from '../../shared/routeUtils'; +import { combineLatest } from 'rxjs'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @Component({ - selector: "app-team-management-mobile-filter", - templateUrl: "./team-management-mobile-filter.component.html" + selector: 'app-team-management-mobile-filter', + templateUrl: './team-management-mobile-filter.component.html' }) export class TeamManagementMobileFilterComponent { - readonly ALL_TEAMS = "alle"; + readonly ALL_TEAMS = 'alle'; teams: Team[] = []; - selectedTeam: Team | undefined | "alle"; + selectedTeam: Team | undefined | 'alle'; constructor(private readonly teamService: TeamService, private readonly router: Router, @@ -27,7 +27,7 @@ export class TeamManagementMobileFilterComponent { params]) => this.setTeamsAndSelectedTeam(teams, params)); } - navigate(team: Team | "alle") { + navigate(team: Team | 'alle') { team == this.ALL_TEAMS ? this.navigateToAllTeams() : this.navigateToTeam(team); } @@ -41,7 +41,7 @@ export class TeamManagementMobileFilterComponent { private setTeamsAndSelectedTeam(teams: Team[], params: ParamMap) { this.teams = teams; - const teamId = params.get("teamId"); + const teamId = params.get('teamId'); if (teamId) { this.selectedTeam = teams.find((t) => t.id === parseInt(teamId)); return; diff --git a/frontend/src/app/team-management/team-management-routing.module.ts b/frontend/src/app/team-management/team-management-routing.module.ts index 903db8d70c..0bf2e5db25 100644 --- a/frontend/src/app/team-management/team-management-routing.module.ts +++ b/frontend/src/app/team-management/team-management-routing.module.ts @@ -1,25 +1,25 @@ -import { NgModule } from "@angular/core"; -import { RouterModule, Routes } from "@angular/router"; -import { TeamManagementComponent } from "./team-management.component"; -import { SidepanelComponent } from "../shared/sidepanel/sidepanel.component"; -import { MemberDetailComponent } from "./member-detail/member-detail.component"; +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { TeamManagementComponent } from './team-management.component'; +import { SidepanelComponent } from '../shared/sidepanel/sidepanel.component'; +import { MemberDetailComponent } from './member-detail/member-detail.component'; const children = [{ - path: "details", + path: 'details', component: SidepanelComponent, children: [{ - path: "member/:id", + path: 'member/:id', component: MemberDetailComponent }] }]; const routes: Routes = [{ - path: "", + path: '', component: TeamManagementComponent, children }, { - path: ":teamId", + path: ':teamId', component: TeamManagementComponent, children }]; diff --git a/frontend/src/app/team-management/team-management.component.spec.ts b/frontend/src/app/team-management/team-management.component.spec.ts index 3c1b31336f..92d190f08e 100644 --- a/frontend/src/app/team-management/team-management.component.spec.ts +++ b/frontend/src/app/team-management/team-management.component.spec.ts @@ -1,31 +1,31 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { TeamManagementComponent } from "./team-management.component"; -import { TeamManagementBannerComponent } from "./team-management-banner/team-management-banner.component"; -import { TeamListComponent } from "./team-list/team-list.component"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { ActivatedRoute, RouterModule } from "@angular/router"; -import { MemberListComponent } from "./member-list/member-list.component"; -import { SearchTeamManagementComponent } from "./search-team-management/search-team-management.component"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { MatIconModule } from "@angular/material/icon"; -import { of } from "rxjs"; -import { SharedModule } from "../shared/shared.module"; -import { MatInputModule } from "@angular/material/input"; -import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import { MatListModule } from "@angular/material/list"; -import { TranslateModule } from "@ngx-translate/core"; -import { MatAutocompleteModule } from "@angular/material/autocomplete"; -import { TeamManagementMobileFilterComponent } from "./team-management-mobile-filter/team-management-mobile-filter.component"; -import { MatSelectModule } from "@angular/material/select"; -import { MemberListTableComponent } from "./member-list/member-list-table/member-list-table.component"; -import { MemberListMobileComponent } from "./member-list/member-list-mobile/member-list-mobile.component"; -import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { MatTableModule } from "@angular/material/table"; -import { testUser, users } from "../shared/testData"; -import { UserService } from "../services/user.service"; -import { ConfigService } from "../services/config.service"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { TeamManagementComponent } from './team-management.component'; +import { TeamManagementBannerComponent } from './team-management-banner/team-management-banner.component'; +import { TeamListComponent } from './team-list/team-list.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { ActivatedRoute, RouterModule } from '@angular/router'; +import { MemberListComponent } from './member-list/member-list.component'; +import { SearchTeamManagementComponent } from './search-team-management/search-team-management.component'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { of } from 'rxjs'; +import { SharedModule } from '../shared/shared.module'; +import { MatInputModule } from '@angular/material/input'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { MatListModule } from '@angular/material/list'; +import { TranslateModule } from '@ngx-translate/core'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { TeamManagementMobileFilterComponent } from './team-management-mobile-filter/team-management-mobile-filter.component'; +import { MatSelectModule } from '@angular/material/select'; +import { MemberListTableComponent } from './member-list/member-list-table/member-list-table.component'; +import { MemberListMobileComponent } from './member-list/member-list-mobile/member-list-mobile.component'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatTableModule } from '@angular/material/table'; +import { testUser, users } from '../shared/testData'; +import { UserService } from '../services/user.service'; +import { ConfigService } from '../services/config.service'; -describe("TeamManagementComponent", () => { +describe('TeamManagementComponent', () => { let component: TeamManagementComponent; let fixture: ComponentFixture; @@ -89,7 +89,7 @@ describe("TeamManagementComponent", () => { }); }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); diff --git a/frontend/src/app/team-management/team-management.component.ts b/frontend/src/app/team-management/team-management.component.ts index d62d3bd924..82c232ea56 100644 --- a/frontend/src/app/team-management/team-management.component.ts +++ b/frontend/src/app/team-management/team-management.component.ts @@ -1,8 +1,8 @@ -import { Component } from "@angular/core"; +import { Component } from '@angular/core'; @Component({ - selector: "app-team-management", - templateUrl: "./team-management.component.html", - styleUrl: "./team-management.component.scss" + selector: 'app-team-management', + templateUrl: './team-management.component.html', + styleUrl: './team-management.component.scss' }) export class TeamManagementComponent {} diff --git a/frontend/src/app/team-management/team-management.module.ts b/frontend/src/app/team-management/team-management.module.ts index dbee77e6b0..5f6d6af3a5 100644 --- a/frontend/src/app/team-management/team-management.module.ts +++ b/frontend/src/app/team-management/team-management.module.ts @@ -1,47 +1,47 @@ -import { NgModule } from "@angular/core"; -import { CommonModule, NgOptimizedImage } from "@angular/common"; -import { TeamManagementComponent } from "./team-management.component"; -import { TeamManagementRoutingModule } from "./team-management-routing.module"; -import { AddEditTeamDialogComponent } from "./add-edit-team-dialog/add-edit-team-dialog.component"; -import { SharedModule } from "../shared/shared.module"; -import { MatDialogModule } from "@angular/material/dialog"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { TeamManagementBannerComponent } from "./team-management-banner/team-management-banner.component"; -import { TeamListComponent } from "./team-list/team-list.component"; -import { MemberListComponent } from "./member-list/member-list.component"; -import { MatListModule } from "@angular/material/list"; -import { MatTableModule } from "@angular/material/table"; -import { RolesPipe } from "./roles.pipe"; -import { TeamsPipe } from "./teams.pipe"; -import { MatIconModule } from "@angular/material/icon"; -import { MatInputModule } from "@angular/material/input"; -import { MatButtonModule } from "@angular/material/button"; -import { MatMenuModule } from "@angular/material/menu"; -import { SearchTeamManagementComponent } from "./search-team-management/search-team-management.component"; -import { AddMemberToTeamDialogComponent } from "./add-member-to-team-dialog/add-member-to-team-dialog.component"; -import { MatAutocompleteModule } from "@angular/material/autocomplete"; -import { MemberDetailComponent } from "./member-detail/member-detail.component"; -import { MatProgressSpinnerModule } from "@angular/material/progress-spinner"; -import { TeamRoleDropdownComponent } from "./team-role-dropdown/team-role-dropdown.component"; -import { MatSelectModule } from "@angular/material/select"; -import { TranslateModule } from "@ngx-translate/core"; -import { AddUserTeamComponent } from "./add-user-team/add-user-team.component"; -import { A11yModule } from "@angular/cdk/a11y"; -import { TeamManagementMobileFilterComponent } from "./team-management-mobile-filter/team-management-mobile-filter.component"; -import { MemberListTableComponent } from "./member-list/member-list-table/member-list-table.component"; -import { MemberListMobileComponent } from "./member-list/member-list-mobile/member-list-mobile.component"; -import { OkrChampionPipe } from "./okr-champion.pipe"; -import { PuzzleIconComponent } from "../shared/custom/puzzle-icon/puzzle-icon.component"; -import { PuzzleIconButtonComponent } from "../shared/custom/puzzle-icon-button/puzzle-icon-button.component"; -import { ShowEditRoleComponent } from "./show-edit-role/show-edit-role.component"; -import { MatCheckboxModule } from "@angular/material/checkbox"; -import { EditOkrChampionComponent } from "./edit-okr-champion/edit-okr-champion.component"; -import { MatTooltipModule } from "@angular/material/tooltip"; -import { NewUserComponent } from "./new-user/new-user.component"; -import { InviteUserDialogComponent } from "./invite-user-dialog/invite-user-dialog.component"; -import { DeleteUserComponent } from "./delete-user/delete-user.component"; -import { MatChip } from "@angular/material/chips"; +import { NgModule } from '@angular/core'; +import { CommonModule, NgOptimizedImage } from '@angular/common'; +import { TeamManagementComponent } from './team-management.component'; +import { TeamManagementRoutingModule } from './team-management-routing.module'; +import { AddEditTeamDialogComponent } from './add-edit-team-dialog/add-edit-team-dialog.component'; +import { SharedModule } from '../shared/shared.module'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TeamManagementBannerComponent } from './team-management-banner/team-management-banner.component'; +import { TeamListComponent } from './team-list/team-list.component'; +import { MemberListComponent } from './member-list/member-list.component'; +import { MatListModule } from '@angular/material/list'; +import { MatTableModule } from '@angular/material/table'; +import { RolesPipe } from './roles.pipe'; +import { TeamsPipe } from './teams.pipe'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatButtonModule } from '@angular/material/button'; +import { MatMenuModule } from '@angular/material/menu'; +import { SearchTeamManagementComponent } from './search-team-management/search-team-management.component'; +import { AddMemberToTeamDialogComponent } from './add-member-to-team-dialog/add-member-to-team-dialog.component'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MemberDetailComponent } from './member-detail/member-detail.component'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { TeamRoleDropdownComponent } from './team-role-dropdown/team-role-dropdown.component'; +import { MatSelectModule } from '@angular/material/select'; +import { TranslateModule } from '@ngx-translate/core'; +import { AddUserTeamComponent } from './add-user-team/add-user-team.component'; +import { A11yModule } from '@angular/cdk/a11y'; +import { TeamManagementMobileFilterComponent } from './team-management-mobile-filter/team-management-mobile-filter.component'; +import { MemberListTableComponent } from './member-list/member-list-table/member-list-table.component'; +import { MemberListMobileComponent } from './member-list/member-list-mobile/member-list-mobile.component'; +import { OkrChampionPipe } from './okr-champion.pipe'; +import { PuzzleIconComponent } from '../shared/custom/puzzle-icon/puzzle-icon.component'; +import { PuzzleIconButtonComponent } from '../shared/custom/puzzle-icon-button/puzzle-icon-button.component'; +import { ShowEditRoleComponent } from './show-edit-role/show-edit-role.component'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { EditOkrChampionComponent } from './edit-okr-champion/edit-okr-champion.component'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { NewUserComponent } from './new-user/new-user.component'; +import { InviteUserDialogComponent } from './invite-user-dialog/invite-user-dialog.component'; +import { DeleteUserComponent } from './delete-user/delete-user.component'; +import { MatChip } from '@angular/material/chips'; @NgModule({ declarations: [ diff --git a/frontend/src/app/team-management/team-role-dropdown/team-role-dropdown.component.spec.ts b/frontend/src/app/team-management/team-role-dropdown/team-role-dropdown.component.spec.ts index e59fb3bfe8..25da7cd1bf 100644 --- a/frontend/src/app/team-management/team-role-dropdown/team-role-dropdown.component.spec.ts +++ b/frontend/src/app/team-management/team-role-dropdown/team-role-dropdown.component.spec.ts @@ -1,12 +1,12 @@ -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { TeamRoleDropdownComponent } from "./team-role-dropdown.component"; -import { FormControl, FormsModule, ReactiveFormsModule, Validators } from "@angular/forms"; -import { CommonModule } from "@angular/common"; -import { MatOptionModule } from "@angular/material/core"; -import { TranslateModule } from "@ngx-translate/core"; -import { takeLast } from "rxjs"; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { TeamRoleDropdownComponent } from './team-role-dropdown.component'; +import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; +import { CommonModule } from '@angular/common'; +import { MatOptionModule } from '@angular/material/core'; +import { TranslateModule } from '@ngx-translate/core'; +import { takeLast } from 'rxjs'; -describe("TeamRoleDropdownComponent", () => { +describe('TeamRoleDropdownComponent', () => { let component: TeamRoleDropdownComponent; let fixture: ComponentFixture; @@ -29,19 +29,19 @@ describe("TeamRoleDropdownComponent", () => { component = fixture.componentInstance; }); - it("should create", () => { + it('should create', () => { expect(component) .toBeTruthy(); }); - it("component onInit should create formControl", () => { + it('component onInit should create formControl', () => { component.isAdmin = false; component.ngOnInit(); expect(JSON.stringify(component.adminControl)) .toStrictEqual(JSON.stringify(new FormControl(component.isAdmin, [Validators.required]))); }); - it("triggerIsAdminChange should submit next value", (done) => { + it('triggerIsAdminChange should submit next value', (done) => { component.isAdminChange.pipe(takeLast(1)) .subscribe((val) => { expect(val) diff --git a/frontend/src/app/team-management/team-role-dropdown/team-role-dropdown.component.ts b/frontend/src/app/team-management/team-role-dropdown/team-role-dropdown.component.ts index 9e3e939f6c..4ee2e4e520 100644 --- a/frontend/src/app/team-management/team-role-dropdown/team-role-dropdown.component.ts +++ b/frontend/src/app/team-management/team-role-dropdown/team-role-dropdown.component.ts @@ -1,10 +1,10 @@ -import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; -import { FormControl, Validators } from "@angular/forms"; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { FormControl, Validators } from '@angular/forms'; @Component({ - selector: "app-team-role-dropdown", - templateUrl: "./team-role-dropdown.component.html", - styleUrl: "./team-role-dropdown.component.scss" + selector: 'app-team-role-dropdown', + templateUrl: './team-role-dropdown.component.html', + styleUrl: './team-role-dropdown.component.scss' }) export class TeamRoleDropdownComponent implements OnInit { @Input({ required: true }) diff --git a/frontend/src/app/team-management/teams.pipe.spec.ts b/frontend/src/app/team-management/teams.pipe.spec.ts index 11fc091b57..75740f3319 100644 --- a/frontend/src/app/team-management/teams.pipe.spec.ts +++ b/frontend/src/app/team-management/teams.pipe.spec.ts @@ -1,6 +1,6 @@ -import { TeamsPipe } from "./teams.pipe"; +import { TeamsPipe } from './teams.pipe'; -describe("TeamsPipe", () => { +describe('TeamsPipe', () => { let pipe: TeamsPipe; const translateMock: any = { instant: jest.fn() @@ -10,31 +10,31 @@ describe("TeamsPipe", () => { pipe = new TeamsPipe(translateMock); }); - it("should return an empty string if teams array is empty", () => { + it('should return an empty string if teams array is empty', () => { expect(pipe.transform([], 2)) - .toEqual(""); + .toEqual(''); }); - it("should join all team names if maxEntries is not defined", () => { - expect(pipe.transform(["team1", - "team2", - "team3"], undefined)) - .toEqual("team1, team2, team3"); + it('should join all team names if maxEntries is not defined', () => { + expect(pipe.transform(['team1', + 'team2', + 'team3'], undefined)) + .toEqual('team1, team2, team3'); }); - it("should limit the number of teams if maxEntries is defined", () => { - translateMock.instant.mockReturnValue("+ 1 Weitere"); - expect(pipe.transform(["team1", - "team2", - "team3"], 2)) - .toEqual("team1, team2, + 1 Weitere"); + it('should limit the number of teams if maxEntries is defined', () => { + translateMock.instant.mockReturnValue('+ 1 Weitere'); + expect(pipe.transform(['team1', + 'team2', + 'team3'], 2)) + .toEqual('team1, team2, + 1 Weitere'); expect(translateMock.instant) - .toBeCalledWith("TEAM_MANAGEMENT.WEITERE", { overflow: 1 }); + .toBeCalledWith('TEAM_MANAGEMENT.WEITERE', { overflow: 1 }); }); - it("should join all of teams if maxEntries is defined and matched", () => { - expect(pipe.transform(["team1", - "team2"], 2)) - .toEqual("team1, team2"); + it('should join all of teams if maxEntries is defined and matched', () => { + expect(pipe.transform(['team1', + 'team2'], 2)) + .toEqual('team1, team2'); }); }); diff --git a/frontend/src/app/team-management/teams.pipe.ts b/frontend/src/app/team-management/teams.pipe.ts index ddf4eaa3ec..c4622564e2 100644 --- a/frontend/src/app/team-management/teams.pipe.ts +++ b/frontend/src/app/team-management/teams.pipe.ts @@ -1,17 +1,17 @@ -import { Pipe, PipeTransform } from "@angular/core"; -import { TranslateService } from "@ngx-translate/core"; +import { Pipe, PipeTransform } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; @Pipe({ - name: "teams" + name: 'teams' }) export class TeamsPipe implements PipeTransform { - private readonly SEPARATOR = ", "; + private readonly SEPARATOR = ', '; constructor(private readonly translate: TranslateService) {} transform(teams: string[], maxEntries: number | undefined): string { if (!teams?.length) { - return ""; + return ''; } if (!maxEntries) { return teams.join(this.SEPARATOR); @@ -21,8 +21,8 @@ export class TeamsPipe implements PipeTransform { return ( teams.slice(0, maxEntries) .join(this.SEPARATOR) + - ", " + - this.translate.instant("TEAM_MANAGEMENT.WEITERE", { overflow }) + ', ' + + this.translate.instant('TEAM_MANAGEMENT.WEITERE', { overflow }) ); } return teams.join(this.SEPARATOR); diff --git a/frontend/src/app/version.ts b/frontend/src/app/version.ts index bd9e5d65e7..90c611bdcb 100644 --- a/frontend/src/app/version.ts +++ b/frontend/src/app/version.ts @@ -1 +1 @@ -export const version = "v2.0.133"; +export const version = 'v2.0.133'; diff --git a/frontend/src/environments/environment.prod.ts b/frontend/src/environments/environment.prod.ts index 594570d1fa..b191677473 100644 --- a/frontend/src/environments/environment.prod.ts +++ b/frontend/src/environments/environment.prod.ts @@ -1,4 +1,4 @@ -import { AuthConfig } from "angular-oauth2-oidc"; +import { AuthConfig } from 'angular-oauth2-oidc'; export const environment = { production: true, @@ -6,12 +6,12 @@ export const environment = { oauth: { decreaseExpirationBySec: 30, clearHashAfterLogin: true, - issuer: "https://sso.puzzle.ch/auth/realms/pitc", + issuer: 'https://sso.puzzle.ch/auth/realms/pitc', strictDiscoveryDocumentValidation: false, redirectUri: `${window.location.protocol}//${window.location.hostname}:${window.location.port}`, - scope: "profile openid", - clientId: "pitc_okr_prod", - responseType: "code", + scope: 'profile openid', + clientId: 'pitc_okr_prod', + responseType: 'code', showDebugInformation: true } as AuthConfig }; diff --git a/frontend/src/environments/environment.ts b/frontend/src/environments/environment.ts index 7fc7eb4cfd..b9d6b2ba89 100644 --- a/frontend/src/environments/environment.ts +++ b/frontend/src/environments/environment.ts @@ -4,7 +4,7 @@ * The list of file replacements can be found in `angular.json`. */ -import { AuthConfig } from "angular-oauth2-oidc"; +import { AuthConfig } from 'angular-oauth2-oidc'; export const environment = { production: false, @@ -12,12 +12,12 @@ export const environment = { oauth: { decreaseExpirationBySec: 30, clearHashAfterLogin: true, - issuer: "", + issuer: '', strictDiscoveryDocumentValidation: false, redirectUri: `${window.location.protocol}//${window.location.hostname}:${window.location.port}`, - scope: "openid profile", - clientId: "", - responseType: "code", + scope: 'openid profile', + clientId: '', + responseType: 'code', showDebugInformation: true } as AuthConfig }; diff --git a/frontend/src/global.ts b/frontend/src/global.ts index 024a652493..eae1b04851 100644 --- a/frontend/src/global.ts +++ b/frontend/src/global.ts @@ -8,6 +8,6 @@ declare global { String.prototype.format = function(...args: any[]): string { args.flat(); return this.replace(/{(\d+)}/g, function(match, index) { - return typeof args[index] == "undefined" ? match : args[index]; + return typeof args[index] == 'undefined' ? match : args[index]; }); }; diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 56460062fd..5a879e4701 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -1,9 +1,9 @@ -import { enableProdMode } from "@angular/core"; -import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { AppModule } from "./app/app.module"; -import { environment } from "./environments/environment"; -import "./global"; +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; +import './global'; if (environment.production) { enableProdMode();