diff --git a/cypress/e2e/map/createStop.cy.ts b/cypress/e2e/map/createStop.cy.ts index 9299c15bd..7dab9d40b 100644 --- a/cypress/e2e/map/createStop.cy.ts +++ b/cypress/e2e/map/createStop.cy.ts @@ -227,7 +227,7 @@ describe('Stop creation tests', () => { // NOTE: After adding the name inputs to stop creation flow, this will fail and // needs to be updated to the correct names - stopDetailsPage.names().shouldHaveText('T0001|-'); + stopDetailsPage.titleRow.names().shouldHaveText('T0001|-'); }, ); }); diff --git a/cypress/e2e/stop-registry/stopDetails.cy.ts b/cypress/e2e/stop-registry/stopDetails.cy.ts index feec30bc8..a3a6ea6ad 100644 --- a/cypress/e2e/stop-registry/stopDetails.cy.ts +++ b/cypress/e2e/stop-registry/stopDetails.cy.ts @@ -9,7 +9,6 @@ import { mapToGetInfrastructureLinksByExternalIdsQuery, seedInfoSpots, seedOrganisations, - seedTerminals, stopPlaceH2003, stopPlaceV1562, } from '@hsl/jore4-test-db-manager'; @@ -150,7 +149,9 @@ describe('Stop details', () => { insertToDbHelper(dbResources); toast = new Toast(); cy.task('insertStopRegistryData', { - terminals: seedTerminals, + // Inserting the terminals here causes it's child stop H0003, + // to generate extra versions of it's quay, which breaks info spots. + // terminals: seedTerminals, stopPlaces: stopPlaceData, organisations: seedOrganisations, infoSpots: seedInfoSpots, @@ -317,33 +318,47 @@ describe('Stop details', () => { }); }; + const verifyInfoSpotJP1234568 = (expectedLocation: { + readonly lat: string; + readonly lon: string; + readonly stops: string; + }) => { + const infoSpotView = stopDetailsPage.infoSpots.viewCard; + + infoSpotView + .getDescription() + .shouldHaveText('Ensimmäinen kerros, portaiden vieressä'); + infoSpotView.getLabel().shouldHaveText('JP1234568'); + infoSpotView.getInfoSpotType().shouldHaveText('Staattinen'); + infoSpotView.getPurpose().shouldHaveText('Tiedotteet'); + infoSpotView.getLatitude().shouldHaveText(expectedLocation.lat); + infoSpotView.getLongitude().shouldHaveText(expectedLocation.lon); + infoSpotView.getBacklight().shouldHaveText('Kyllä'); + infoSpotView.getPosterPlaceSize().shouldHaveText('80x120cm'); + infoSpotView + .getMaintenance() + .shouldHaveText('Huoltotietojen tekstit tähän...'); + infoSpotView.getPosterSize().shouldHaveText('a4'); + infoSpotView.getPosterLabel().shouldHaveText('PT1234'); + infoSpotView.getPosterLines().shouldHaveText('1, 6, 17'); + infoSpotView.getFloor().shouldHaveText('1'); + infoSpotView.getRailInformation().shouldHaveText('7'); + infoSpotView.getStops().shouldHaveText(expectedLocation.stops); + infoSpotView.getTerminals().shouldHaveText('-'); + infoSpotView.getZoneLabel().shouldHaveText('A'); + + infoSpotView.getDisplayType().should('not.exist'); + infoSpotView.getSpeechProperty().should('not.exist'); + }; + const verifyInitialInfoSpots = () => { const infoSpotView = stopDetailsPage.infoSpots.viewCard; infoSpotView.getNthSectionContainer(0).within(() => { - infoSpotView - .getDescription() - .shouldHaveText('Ensimmäinen kerros, portaiden vieressä'); - infoSpotView.getLabel().shouldHaveText('JP1234568'); - infoSpotView.getInfoSpotType().shouldHaveText('Staattinen'); - infoSpotView.getPurpose().shouldHaveText('Tiedotteet'); - infoSpotView.getLatitude().shouldHaveText('60.16490775039894'); - infoSpotView.getLongitude().shouldHaveText('24.92904198486008'); - infoSpotView.getBacklight().shouldHaveText('Kyllä'); - infoSpotView.getPosterPlaceSize().shouldHaveText('80x120cm'); - infoSpotView - .getMaintenance() - .shouldHaveText('Huoltotietojen tekstit tähän...'); - infoSpotView.getPosterSize().shouldHaveText('a4'); - infoSpotView.getPosterLabel().shouldHaveText('PT1234'); - infoSpotView.getPosterLines().shouldHaveText('1, 6, 17'); - infoSpotView.getFloor().shouldHaveText('1'); - infoSpotView.getRailInformation().shouldHaveText('7'); - infoSpotView.getStops().shouldHaveText('V1562'); - infoSpotView.getTerminals().shouldHaveText('-'); - infoSpotView.getZoneLabel().shouldHaveText('A'); - - infoSpotView.getDisplayType().should('not.exist'); - infoSpotView.getSpeechProperty().should('not.exist'); + verifyInfoSpotJP1234568({ + lat: '60.16490775039894', + lon: '24.92904198486008', + stops: 'V1562', + }); }); infoSpotView.getNthSectionContainer(1).within(() => { @@ -402,8 +417,8 @@ describe('Stop details', () => { stopDetailsPage.visit('H2003'); stopDetailsPage.page().shouldBeVisible(); - stopDetailsPage.label().shouldHaveText('H2003'); - stopDetailsPage + stopDetailsPage.titleRow.label().shouldHaveText('H2003'); + stopDetailsPage.titleRow .names() .shouldHaveText('Pohjoisesplanadi|Norraesplanaden'); stopDetailsPage.validityPeriod().should('contain', '20.3.2020-31.5.2050'); @@ -759,7 +774,7 @@ describe('Stop details', () => { beforeEach(() => { stopDetailsPage.visit('H2003'); stopDetailsPage.page().shouldBeVisible(); - stopDetailsPage.label().shouldHaveText('H2003'); + stopDetailsPage.titleRow.label().shouldHaveText('H2003'); stopDetailsPage.technicalFeaturesTabButton().click(); }); @@ -1564,7 +1579,7 @@ describe('Stop details', () => { stopDetailsPage.visit('V1562'); stopDetailsPage.page().shouldBeVisible(); - stopDetailsPage.label().shouldHaveText('V1562'); + stopDetailsPage.titleRow.label().shouldHaveText('V1562'); stopDetailsPage.infoSpotsTabButton().click(); @@ -2243,6 +2258,69 @@ describe('Stop details', () => { ); }); + describe('version and copies', () => { + it('should create a copy', () => { + stopDetailsPage.visit('H2003'); + + stopDetailsPage.titleRow.actionsMenuButton().click(); + stopDetailsPage.titleRow + .actionsMenuCopyButton() + .should('not.be.disabled') + .click(); + + const { copyModal } = stopDetailsPage; + copyModal + .modal() + .should('exist') + .within(() => { + copyModal + .names() + .should('contain.text', 'H2003') + .and('contain.text', 'Pohjoisesplanadi') + .and('contain.text', 'Norraesplanaden'); + + copyModal + .validity() + .should('contain.text', 'Perusversio') + .and('contain.text', '20.3.2020-31.5.2050'); + + const { form } = copyModal; + form.versionName().clearAndType('Uusi versio'); + form.versionDescription().shouldBeDisabled(); + form.priority.setPriority(Priority.Temporary); + form.validity.fillForm({ validityStartISODate: '2050-06-01' }); + form.submitButton().click(); + }); + + toast.expectSuccessToast('Uusi versio luotu Avataan uusi versio'); + copyModal.modal().should('not.exist'); + stopDetailsPage.loadingStopDetails().should('not.exist'); + + stopDetailsPage.validityPeriod().shouldHaveText('1.6.2050-'); + + verifyInitialBasicDetails(); + verifyInitialLocationDetails(); + verifyInitialSignageDetails(); + + stopDetailsPage.technicalFeaturesTabButton().click(); + verifyInitialShelters(); + verifyInitialMeasurements(); + verifyInitialMaintenanceDetails(); + + stopDetailsPage.infoSpotsTabButton().click(); + + stopDetailsPage.infoSpots.viewCard + .getNthSectionContainer(0) + .within(() => { + verifyInfoSpotJP1234568({ + lat: '60.166003223527824', + lon: '24.932072417514647', + stops: 'H2003', + }); + }); + }); + }); + // A regression test to ensure that our mutations don't eg. reset any fields they are not supposed to. it('should keep stop place intact when submitting without actual changes', () => { stopDetailsPage.visit('H2003'); diff --git a/cypress/pageObjects/stop-registry/StopDetailsPage.ts b/cypress/pageObjects/stop-registry/StopDetailsPage.ts index aebe45045..d249162cc 100644 --- a/cypress/pageObjects/stop-registry/StopDetailsPage.ts +++ b/cypress/pageObjects/stop-registry/StopDetailsPage.ts @@ -1,11 +1,13 @@ import { BasicDetailsSection, + CreateCopyModal, InfoSpotsSection, LocationDetailsSection, MaintenanceSection, MeasurementsSection, SheltersSection, SignageDetailsSection, + TitleRow, } from './stop-details'; export class StopDetailsPage { @@ -23,6 +25,10 @@ export class StopDetailsPage { maintenance = new MaintenanceSection(); + titleRow = new TitleRow(); + + copyModal = new CreateCopyModal(); + visit(label: string) { cy.visit(`/stop-registry/stops/${label}`); } @@ -31,14 +37,6 @@ export class StopDetailsPage { return cy.getByTestId('StopDetailsPage::page'); } - label() { - return cy.getByTestId('StopTitleRow::label'); - } - - names() { - return cy.getByTestId('StopTitleRow::names'); - } - validityPeriod() { return cy.getByTestId('StopDetailsPage::validityPeriod'); } @@ -66,4 +64,8 @@ export class StopDetailsPage { infoSpotsTabPanel() { return cy.getByTestId('StopDetailsPage::infoSpotsTabPanel'); } + + loadingStopDetails() { + return cy.getByTestId('StopDetailsPage::loadingStopDetails'); + } } diff --git a/cypress/pageObjects/stop-registry/stop-details/CreateCopyModal.ts b/cypress/pageObjects/stop-registry/stop-details/CreateCopyModal.ts new file mode 100644 index 000000000..af2215ef7 --- /dev/null +++ b/cypress/pageObjects/stop-registry/stop-details/CreateCopyModal.ts @@ -0,0 +1,17 @@ +import { StopVersionForm } from './StopVersionForm'; + +export class CreateCopyModal { + form = new StopVersionForm(); + + modal() { + return cy.getByTestId('CopyStopModal::modal'); + } + + names() { + return cy.getByTestId('CopyStopModal::names'); + } + + validity() { + return cy.getByTestId('CopyStopModal::validity'); + } +} diff --git a/cypress/pageObjects/stop-registry/stop-details/StopVersionForm.ts b/cypress/pageObjects/stop-registry/stop-details/StopVersionForm.ts new file mode 100644 index 000000000..b57672376 --- /dev/null +++ b/cypress/pageObjects/stop-registry/stop-details/StopVersionForm.ts @@ -0,0 +1,28 @@ +import { PriorityForm } from '../../PriorityForm'; +import { ValidityPeriodForm } from '../../ValidityPeriodForm'; + +export class StopVersionForm { + priority = new PriorityForm(); + + validity = new ValidityPeriodForm(); + + form() { + return cy.getByTestId('StopVersionForm::form'); + } + + versionName() { + return cy.getByTestId('StopVersionForm::versionName'); + } + + versionDescription() { + return cy.getByTestId('StopVersionForm::versionDescription'); + } + + submitButton() { + return cy.getByTestId('StopVersionForm::submitButton'); + } + + cancelButton() { + return cy.getByTestId('StopVersionForm::cancelButton'); + } +} diff --git a/cypress/pageObjects/stop-registry/stop-details/TitleRow.ts b/cypress/pageObjects/stop-registry/stop-details/TitleRow.ts new file mode 100644 index 000000000..97a45ed65 --- /dev/null +++ b/cypress/pageObjects/stop-registry/stop-details/TitleRow.ts @@ -0,0 +1,25 @@ +export class TitleRow { + label() { + return cy.getByTestId('StopTitleRow::label'); + } + + names() { + return cy.getByTestId('StopTitleRow::names'); + } + + editValidityButton() { + return cy.getByTestId('StopTitleRow::editValidityButton'); + } + + openOnMapButton() { + return cy.getByTestId('StopTitleRow::StopTitleRow::openOnMapButton'); + } + + actionsMenuButton() { + return cy.getByTestId('StopTitleRow::extraActions::menu'); + } + + actionsMenuCopyButton() { + return cy.getByTestId('StopTitleRow::extraActions::copy'); + } +} diff --git a/cypress/pageObjects/stop-registry/stop-details/index.ts b/cypress/pageObjects/stop-registry/stop-details/index.ts index 59382e877..f2747944d 100644 --- a/cypress/pageObjects/stop-registry/stop-details/index.ts +++ b/cypress/pageObjects/stop-registry/stop-details/index.ts @@ -1,6 +1,7 @@ export * from './BasicDetailsForm'; export * from './BasicDetailsSection'; export * from './BasicDetailsViewCard'; +export * from './CreateCopyModal'; export * from './InfoSpotSection'; export * from './InfoSpotsForm'; export * from './InfoSpotViewCard'; @@ -20,3 +21,4 @@ export * from './ShelterViewCard'; export * from './SignageDetailsForm'; export * from './SignageDetailsSection'; export * from './SignageDetailsViewCard'; +export * from './TitleRow'; diff --git a/test-db-manager/src/datasets/stopRegistry/infoSpots.ts b/test-db-manager/src/datasets/stopRegistry/infoSpots.ts index d2813591d..af20c7f35 100644 --- a/test-db-manager/src/datasets/stopRegistry/infoSpots.ts +++ b/test-db-manager/src/datasets/stopRegistry/infoSpots.ts @@ -16,80 +16,92 @@ const mapToInfoSpotInput = (seedInfoSpot: InfoSpotInput): InfoSpotInput => { return seedInfoSpot; }; +const infoSpotJP1234568: StopRegistryInfoSpotInput = { + description: { + lang: 'fi', + value: 'Ensimmäinen kerros, portaiden vieressä', + }, + floor: '1', + label: 'JP1234568', + maintenance: 'Huoltotietojen tekstit tähän...', + infoSpotType: StopRegistryInfoSpotType.Static, + purpose: 'Tiedotteet', + railInformation: '7', + zoneLabel: 'A', + displayType: null, // Only set if posterPlaceType = Dynamic + speechProperty: null, // Only set if posterPlaceType = Dynamic + backlight: true, // Only set if posterPlaceType = Static + posterPlaceSize: StopRegistryPosterPlaceSize.Cm80x120, // Only set if posterPlaceType = Static + poster: [ + // Only set if posterPlaceType = Static + { + label: 'PT1234', + posterSize: StopRegistryPosterPlaceSize.A4, + lines: '1, 6, 17', + }, + ], +}; + +const infoSpotJP1234567: StopRegistryInfoSpotInput = { + description: { + lang: 'fi', + value: 'Ensimmäinen kerros, portaiden takana', + }, + floor: '1', + label: 'JP1234567', + maintenance: 'Huoltotietojen tekstit tähän...', + purpose: 'Dynaaminen näyttö', + railInformation: '8', + zoneLabel: 'B', + infoSpotType: StopRegistryInfoSpotType.Dynamic, + displayType: StopRegistryDisplayType.BatteryMultiRow, // Only set if posterPlaceType = Dynamic + speechProperty: true, // Only set if posterPlaceType = Dynamic + backlight: null, // Only set if posterPlaceType = Static + posterPlaceSize: null, // Only set if posterPlaceType = Static + poster: null, // Only set if posterPlaceType = Static +}; + +const infoSpotJP1234569: StopRegistryInfoSpotInput = { + infoSpotType: StopRegistryInfoSpotType.SoundBeacon, + description: { + lang: 'fi', + value: 'Tolpassa', + }, + floor: '1', + label: 'JP1234569', + maintenance: 'Huoltotietojen tekstit tähän...', + purpose: 'Infopaikan käyttötarkoitus', + railInformation: '9', + zoneLabel: 'C', + displayType: null, // Only set if posterPlaceType = Dynamic + speechProperty: null, // Only set if posterPlaceType = Dynamic + backlight: null, // Only set if posterPlaceType = Static + posterPlaceSize: null, // Only set if posterPlaceType = Static + poster: null, // Only set if posterPlaceType = Static +}; + const infoSpots: Array = [ { - infoSpot: { - description: { - lang: 'fi', - value: 'Ensimmäinen kerros, portaiden vieressä', - }, - floor: '1', - label: 'JP1234568', - maintenance: 'Huoltotietojen tekstit tähän...', - infoSpotType: StopRegistryInfoSpotType.Static, - purpose: 'Tiedotteet', - railInformation: '7', - zoneLabel: 'A', - displayType: null, // Only set if posterPlaceType = Dynamic - speechProperty: null, // Only set if posterPlaceType = Dynamic - backlight: true, // Only set if posterPlaceType = Static - posterPlaceSize: StopRegistryPosterPlaceSize.Cm80x120, // Only set if posterPlaceType = Static - poster: [ - // Only set if posterPlaceType = Static - { - label: 'PT1234', - posterSize: StopRegistryPosterPlaceSize.A4, - lines: '1, 6, 17', - }, - ], - }, + infoSpot: infoSpotJP1234568, locatedOnStopLabel: 'V1562', associatedShelter: 0, }, { - infoSpot: { - description: { - lang: 'fi', - value: 'Ensimmäinen kerros, portaiden takana', - }, - floor: '1', - label: 'JP1234567', - maintenance: 'Huoltotietojen tekstit tähän...', - purpose: 'Dynaaminen näyttö', - railInformation: '8', - zoneLabel: 'B', - infoSpotType: StopRegistryInfoSpotType.Dynamic, - displayType: StopRegistryDisplayType.BatteryMultiRow, // Only set if posterPlaceType = Dynamic - speechProperty: true, // Only set if posterPlaceType = Dynamic - backlight: null, // Only set if posterPlaceType = Static - posterPlaceSize: null, // Only set if posterPlaceType = Static - poster: null, // Only set if posterPlaceType = Static - }, + infoSpot: infoSpotJP1234567, locatedOnStopLabel: 'V1562', associatedShelter: 1, }, { - infoSpot: { - infoSpotType: StopRegistryInfoSpotType.SoundBeacon, - description: { - lang: 'fi', - value: 'Tolpassa', - }, - floor: '1', - label: 'JP1234569', - maintenance: 'Huoltotietojen tekstit tähän...', - purpose: 'Infopaikan käyttötarkoitus', - railInformation: '9', - zoneLabel: 'C', - displayType: null, // Only set if posterPlaceType = Dynamic - speechProperty: null, // Only set if posterPlaceType = Dynamic - backlight: null, // Only set if posterPlaceType = Static - posterPlaceSize: null, // Only set if posterPlaceType = Static - poster: null, // Only set if posterPlaceType = Static - }, + infoSpot: infoSpotJP1234569, locatedOnStopLabel: 'V1562', associatedShelter: 2, }, + { + // Reusing info same spot on another stop + infoSpot: infoSpotJP1234568, + locatedOnStopLabel: 'H2003', + associatedShelter: 0, + }, ]; const seedData: Array = [...infoSpots]; diff --git a/ui/src/components/stop-registry/stops/stop-details/title-row/EditValidityButton.tsx b/ui/src/components/stop-registry/stops/stop-details/title-row/EditValidityButton.tsx index dadd42ca2..a4437c002 100644 --- a/ui/src/components/stop-registry/stops/stop-details/title-row/EditValidityButton.tsx +++ b/ui/src/components/stop-registry/stops/stop-details/title-row/EditValidityButton.tsx @@ -5,7 +5,7 @@ import { StopWithDetails } from '../../../../../hooks'; const DISABLE_UNTIL_IMPLEMENTED = true; const testIds = { - button: 'StopDetailsPage::editValidityButton', + button: 'StopTitleRow::editValidityButton', }; type EditValidityButtonProps = { diff --git a/ui/src/components/stop-registry/stops/stop-details/title-row/ExtraActions.tsx b/ui/src/components/stop-registry/stops/stop-details/title-row/ExtraActions.tsx index 0e196210d..718d006e5 100644 --- a/ui/src/components/stop-registry/stops/stop-details/title-row/ExtraActions.tsx +++ b/ui/src/components/stop-registry/stops/stop-details/title-row/ExtraActions.tsx @@ -10,8 +10,8 @@ import { import { CopyStopModal } from '../stop-version'; const testIds = { - actionMenu: 'StopDetailsPage::extraActions::menu', - copy: 'StopDetailsPage::extraActions::copy', + actionMenu: 'StopTitleRow::extraActions::menu', + copy: 'StopTitleRow::extraActions::copy', }; type ExtraActionsProps = { diff --git a/ui/src/components/stop-registry/stops/stop-details/title-row/OpenOnMapButton.tsx b/ui/src/components/stop-registry/stops/stop-details/title-row/OpenOnMapButton.tsx index fe59c352d..9d7aaf8ba 100644 --- a/ui/src/components/stop-registry/stops/stop-details/title-row/OpenOnMapButton.tsx +++ b/ui/src/components/stop-registry/stops/stop-details/title-row/OpenOnMapButton.tsx @@ -5,6 +5,10 @@ import { StopWithDetails } from '../../../../../hooks'; import { LocatorButton } from '../../../../../uiComponents'; import { useOpenStopOnMap } from '../../../search/StopTableRow/utils'; +const testIds = { + button: 'StopTitleRow::openOnMapButton', +}; + type OpenOnMapButtonProps = { readonly className?: string; readonly label: string; @@ -30,6 +34,7 @@ export const OpenOnMapButton: FC = ({ className={twMerge('h-11 w-11', className)} disabled={!stop} onClick={onClick} + testId={testIds.button} tooltipText={t('accessibility:common.showOnMap', { label })} /> );