Skip to content

Commit

Permalink
feat: add support for hash routing in line with other analytics apps …
Browse files Browse the repository at this point in the history
…[DHIS2-15762] (#3009)

Implements https://dhis2.atlassian.net/browse/DHIS2-15762

Continue to support the old url patterns for backwards compatibility

Supports:

/#/ZBjCfSaLSqD
/#/ZBjCfSaLSqD/download
/#/ZBjCfSaLSqD?interpretationId=yKqhXZdeJ6a
/#/ZBjCfSaLSqD?interpretationId=yKqhXZdeJ6a&initialFocus=true
/#/currentAnalyticalObject
/#/download (new map, in download mode)

// legacy urls
/?id=ZBjCfSaLSqD
/?id=ZBjCfSaLSqD&interpretationid=yKqhXZdeJ6a
/?id=ZBjCfSaLSqD&interpretationId=yKqhXZdeJ6a
/?currentAnalyticalObject=true

The app supports legacy urls (see above) because dashboard-app
still produces the legacy url for both opening the map, and opening an interpretation.
In addition, urls to maps may have been shared in other ways.
In maps-app, legacy urls are replaced with the new url style when the
maps-app first opens (AppWrapper)

FileMenu: push paths to history for the various actions.
Also, some renaming was done in the file to (hopefully) increase clarity.

useLoadMap: this is where all the map loading and history listening is set up.

Refactoring. Previously there were 3 components that dealt with initiating the maps app:
AppWrapper, App, AppLayout. App has become the former "AppLayout",
and all of the loading and navigating logic has been moved to the new custom hook useLoadMap
  • Loading branch information
jenniferarnesen authored Jan 12, 2024
1 parent 8110ed1 commit b25267d
Show file tree
Hide file tree
Showing 30 changed files with 886 additions and 566 deletions.
12 changes: 10 additions & 2 deletions cypress/integration/interpretations.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { EXTENDED_TIMEOUT } from '../support/util.js'
const MAP_TITLE = 'test ' + new Date().toUTCString().slice(-24, -4)
context('Interpretations', () => {
it('opens the interpretations panel for a map', () => {
cy.visit('/?id=ZBjCfSaLSqD', EXTENDED_TIMEOUT)
cy.visit('/#/ZBjCfSaLSqD', EXTENDED_TIMEOUT)
const Layer = new ThematicLayer()
Layer.validateCardTitle('ANC LLITN coverage')
cy.get('canvas.maplibregl-canvas').should('be.visible')
Expand Down Expand Up @@ -65,8 +65,12 @@ context('Interpretations', () => {
.find('canvas.maplibregl-canvas')
.should('be.visible')

cy.url().should('include', 'interpretationId=')

cy.get('button').contains('Hide interpretation').click()

cy.url().should('not.include', 'interpretationId=')

deleteMap()
})

Expand All @@ -75,7 +79,7 @@ context('Interpretations', () => {
'postDataStatistics'
)
cy.visit(
'/?id=ZBjCfSaLSqD&interpretationId=yKqhXZdeJ6a',
'/#/ZBjCfSaLSqD?interpretationId=yKqhXZdeJ6a',
EXTENDED_TIMEOUT
) //ANC: LLITN coverage district and facility

Expand All @@ -90,12 +94,16 @@ context('Interpretations', () => {
)
.should('be.visible')

cy.url().should('include', 'interpretationId=')

cy.getByDataTest('interpretation-modal')
.findByDataTest('dhis2-modal-close-button')
.click()

cy.getByDataTest('interpretation-modal').should('not.exist')

cy.url().should('not.include', 'interpretationId=')

cy.getByDataTest('interpretations-list').should('be.visible')
})
})
100 changes: 100 additions & 0 deletions cypress/integration/mapDownload.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { EXTENDED_TIMEOUT } from '../support/util.js'

const mapWithThematicLayer = {
id: 'eDlFx0jTtV9',
name: 'ANC: LLITN Cov Chiefdom this year',
downloadFileName: 'ANC LLITN Cov Chiefdom this year.png',
cardTitle: 'ANC LLITN coverage',
}

const assertDownloadSettingChecked = (label, isChecked) => {
cy.getByDataTest('download-settings')
.find('label')
.contains(label)
.find('input')
.should(`${isChecked ? '' : 'not.'}be.checked`)
}

const clickDownloadSetting = (label) => {
cy.getByDataTest('download-settings')
.find('label')
.contains(label)
.find('input')
.click()
}

describe('Map Download', () => {
beforeEach(() => {
cy.task('emptyDownloadsFolder')
})

it('downloads a map', () => {
cy.visit(`/#/${mapWithThematicLayer.id}`, EXTENDED_TIMEOUT)
cy.get('canvas', EXTENDED_TIMEOUT).should('be.visible')

cy.get('[data-test="layercard"]')
.find('h2')
.contains(mapWithThematicLayer.cardTitle, EXTENDED_TIMEOUT)

cy.getByDataTest('dhis2-analytics-hovermenubar')
.find('button')
.contains('Download')
.click()

cy.log('confirm that download page is open')
cy.getByDataTest('download-settings').should('be.visible')
cy.get('canvas.maplibregl-canvas').should('be.visible')
cy.get('button').contains('Exit download mode').should('be.visible')
cy.url().should('contain', `/#/${mapWithThematicLayer.id}/download`)

// check the current settings
assertDownloadSettingChecked('Show map name', true)

cy.getByDataTest('download-map-info')
.find('h1')
.contains(mapWithThematicLayer.name)
.should('be.visible')

assertDownloadSettingChecked('Show map description', false)
assertDownloadSettingChecked('Show legend', true)
cy.getByDataTest('download-map-info')
.findByDataTest('download-legend-title')
.should('have.length', 1)

assertDownloadSettingChecked('Show overview map', true)
cy.getByDataTest('download-map-info')
.findByDataTest('overview-map')
.should('be.visible')

// make some changes
clickDownloadSetting('Show map name')
cy.getByDataTest('download-map-info').find('h1').should('not.exist')

cy.getByDataTest('download-settings')
.find('button')
.contains('Download')
.click()

// check for downloaded file
cy.wait(3000) // eslint-disable-line cypress/no-unnecessary-waiting
cy.waitUntil(
() => cy.task('getLastDownloadFilePath').then((result) => result),
{ timeout: 3000, interval: 100 }
).then((filePath) => {
expect(filePath).to.include(mapWithThematicLayer.downloadFileName)

cy.readFile(filePath, EXTENDED_TIMEOUT).should((buffer) =>
expect(buffer.length).to.be.gt(10000)
)
})

// leave download mode
cy.get('button').contains('Exit download mode').click()
cy.url().should('contain', `/#/${mapWithThematicLayer.id}`)
cy.url().should('not.contain', '/download')
cy.getByDataTest('download-settings').should('not.exist')
cy.get('[data-test="layercard"]')
.find('h2')
.contains(mapWithThematicLayer.cardTitle, EXTENDED_TIMEOUT)
})
})
175 changes: 175 additions & 0 deletions cypress/integration/routes.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { ThematicLayer } from '../elements/thematic_layer.js'
import { EXTENDED_TIMEOUT } from '../support/util.js'

context('Routes', () => {
it('loads root route', () => {
cy.visit('/', { timeout: 50000 })
cy.get('canvas', EXTENDED_TIMEOUT).should('be.visible')
cy.title().should('equal', 'Maps | DHIS2')
})

it('loads with map id (legacy)', () => {
cy.intercept({ method: 'POST', url: /dataStatistics/ }).as(
'postDataStatistics'
)
cy.visit('/?id=ytkZY3ChM6J', EXTENDED_TIMEOUT) //ANC: 3rd visit coverage last year by district

cy.wait('@postDataStatistics')
.its('response.statusCode')
.should('eq', 201)

cy.get('canvas', EXTENDED_TIMEOUT).should('be.visible')

const Layer = new ThematicLayer()
Layer.validateCardTitle('ANC 3 Coverage')
})

it('loads with map id (hash)', () => {
cy.visit('/#/zDP78aJU8nX', EXTENDED_TIMEOUT) //ANC: 1st visit coverage (%) by district last year

cy.get('canvas', EXTENDED_TIMEOUT).should('be.visible')

const Layer = new ThematicLayer()
Layer.validateCardTitle('ANC 1 Coverage')
})

it('loads currentAnalyticalObject (legacy)', () => {
cy.intercept('**/userDataStore/analytics/settings', {
fixture: 'analyticalObject.json',
})

cy.visit('/?currentAnalyticalObject=true', EXTENDED_TIMEOUT)
cy.get('canvas', EXTENDED_TIMEOUT).should('be.visible')

cy.contains('button', 'Proceed').click()

const Layer = new ThematicLayer()
Layer.validateCardTitle('ANC 1 Coverage')
cy.get('canvas.maplibregl-canvas').should('be.visible')
})

it('loads currentAnalyticalObject (hash)', () => {
cy.intercept('**/userDataStore/analytics/settings', {
fixture: 'analyticalObject.json',
})

cy.visit('/#/currentAnalyticalObject', EXTENDED_TIMEOUT)
cy.get('canvas', EXTENDED_TIMEOUT).should('be.visible')

cy.contains('button', 'Proceed').click()

const Layer = new ThematicLayer()
Layer.validateCardTitle('ANC 1 Coverage')
cy.get('canvas.maplibregl-canvas').should('be.visible')
})

it('loads with map id (legacy) and interpretationid lowercase', () => {
cy.intercept({ method: 'POST', url: /dataStatistics/ }).as(
'postDataStatistics'
)
cy.visit(
'/?id=ZBjCfSaLSqD&interpretationid=yKqhXZdeJ6a',
EXTENDED_TIMEOUT
) //ANC: LLITN coverage district and facility

cy.wait('@postDataStatistics')
.its('response.statusCode')
.should('eq', 201)

cy.getByDataTest('interpretation-modal')
.find('h1')
.contains(
'Viewing interpretation: ANC: LLITN coverage district and facility'
)
.should('be.visible')
})

it('loads with map id (legacy) and interpretationId uppercase', () => {
cy.intercept({ method: 'POST', url: /dataStatistics/ }).as(
'postDataStatistics'
)
cy.visit(
'/?id=ZBjCfSaLSqD&interpretationId=yKqhXZdeJ6a',
EXTENDED_TIMEOUT
) //ANC: LLITN coverage district and facility

cy.wait('@postDataStatistics')
.its('response.statusCode')
.should('eq', 201)

cy.getByDataTest('interpretation-modal')
.find('h1')
.contains(
'Viewing interpretation: ANC: LLITN coverage district and facility'
)
.should('be.visible')
})

it('loads with map id (hash) and interpretationId', () => {
cy.intercept({ method: 'POST', url: /dataStatistics/ }).as(
'postDataStatistics'
)
cy.visit(
'/#/ZBjCfSaLSqD?interpretationId=yKqhXZdeJ6a',
EXTENDED_TIMEOUT
) //ANC: LLITN coverage district and facility

cy.wait('@postDataStatistics')
.its('response.statusCode')
.should('eq', 201)

cy.getByDataTest('interpretation-modal')
.find('h1')
.contains(
'Viewing interpretation: ANC: LLITN coverage district and facility'
)
.should('be.visible')
})

it('loads download page for map id (hash)', () => {
cy.intercept({ method: 'POST', url: /dataStatistics/ }).as(
'postDataStatistics'
)
cy.visit('/#/ZBjCfSaLSqD/download', EXTENDED_TIMEOUT) //ANC: LLITN coverage district and facility

cy.wait('@postDataStatistics')
.its('response.statusCode')
.should('eq', 201)

cy.getByDataTest('download-settings').should('be.visible')
cy.get('canvas.maplibregl-canvas').should('be.visible')
cy.get('button').contains('Exit download mode').should('be.visible')
})

it('loads download page currentAnalyticalObject (hash)', () => {
cy.intercept('**/userDataStore/analytics/settings', {
fixture: 'analyticalObject.json',
})

cy.visit('/#/currentAnalyticalObject/download', EXTENDED_TIMEOUT)

cy.contains('button', 'Proceed').click()

cy.getByDataTest('download-settings').should('be.visible')
cy.get('canvas.maplibregl-canvas').should('be.visible')
cy.get('button').contains('Exit download mode').should('be.visible')
})

it.only('loads download page for new map', () => {
cy.visit('/', EXTENDED_TIMEOUT)

cy.get('canvas.maplibregl-canvas').should('be.visible')
cy.get('button').contains('Download').click()

cy.getByDataTest('download-settings').should('be.visible')
cy.get('canvas.maplibregl-canvas').should('be.visible')
cy.get('button').contains('Exit download mode').should('be.visible')
cy.url().should('include', '#/download')

cy.get('button').contains('Exit download mode').click()

cy.url().should('not.include', 'download')

cy.get('button').contains('Add layer').should('be.visible')
})
})
Loading

0 comments on commit b25267d

Please sign in to comment.