Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions apps/datahub-e2e/src/e2e/dataset/datasetDetailPage.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,19 @@ describe('dataset pages', () => {
})

it('PREVIEW SECTION : display & functions', () => {
// Testing a dataset with TMS endpoint in error
cy.visit('/dataset/zzz_nl_test_wfs_syth_la_ciotat')

// it should show the map and display an error message
cy.get('gn-ui-map-container').should('exist')
cy.get('gn-ui-popup-alert').should('be.visible')

// it should have API links
cy.get('datahub-record-apis')
.find('gn-ui-api-card')
.should('have.length.gt', 0)

// Testing a dataset for default behavior on preview section
cy.visit('/dataset/04bcec79-5b25-4b16-b635-73115f7456e4')

cy.get('datahub-record-metadata')
Expand Down
1 change: 1 addition & 0 deletions apps/datahub-e2e/src/e2e/datasets.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ describe('datasets', () => {
'Géo2France (1)',
"Helpdesk carto du SPW (SPW - Secrétariat général - SPW Digital - Département de la Géomatique - Direction de l'Intégration des géodonnées) (12)",
'Métropole Européenne de Lille (2)',
'Moi même (1)',
'Office France de la Biodiversité (1)',
'Région Hauts-de-France (1)',
'Réseau Ongulés sauvages OFB-FNC-FDC (1)',
Expand Down
8 changes: 4 additions & 4 deletions apps/datahub-e2e/src/e2e/header/filters.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('filters and sorts', () => {
cy.get('@inlineFilter-service').should('not.be.checked')
cy.get('@inlineFilter-reuse').should('not.be.checked')
cy.url().should('not.contain', 'recordKind=')
cy.get('[data-cy="resultsHitsFound"]').should('contain.text', '27 ')
cy.get('[data-cy="resultsHitsFound"]').should('contain.text', '28 ')
})
})

Expand All @@ -59,23 +59,23 @@ describe('filters and sorts', () => {
cy.get('@inlineFilter-service').should('not.be.checked')
cy.get('@inlineFilter-reuse').should('not.be.checked')
cy.url().should('contain', 'recordKind=dataset')
cy.get('[data-cy="resultsHitsFound"]').should('contain.text', '16 ')
cy.get('[data-cy="resultsHitsFound"]').should('contain.text', '17 ')

cy.get('@inlineFilter-service').check({ force: true })
cy.get('@inlineFilter-all').should('not.be.checked')
cy.get('@inlineFilter-dataset').should('be.checked')
cy.get('@inlineFilter-service').should('be.checked')
cy.get('@inlineFilter-reuse').should('not.be.checked')
cy.url().should('contain', 'recordKind=dataset,service')
cy.get('[data-cy="resultsHitsFound"]').should('contain.text', '26 ')
cy.get('[data-cy="resultsHitsFound"]').should('contain.text', '27 ')

cy.get('@inlineFilter-all').check({ force: true })
cy.get('@inlineFilter-all').should('be.checked')
cy.get('@inlineFilter-dataset').should('not.be.checked')
cy.get('@inlineFilter-service').should('not.be.checked')
cy.get('@inlineFilter-reuse').should('not.be.checked')
cy.url().should('not.contain', 'recordKind=')
cy.get('[data-cy="resultsHitsFound"]').should('contain.text', '27 ')
cy.get('[data-cy="resultsHitsFound"]').should('contain.text', '28 ')
})
})

Expand Down
2 changes: 1 addition & 1 deletion apps/datahub-e2e/src/e2e/organizations.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ describe('organizations', () => {
it('should go to next page with arrow', () => {
cy.then(() => {
cy.get('@pagination').find('[data-cy=next-page]').click()
cy.get('@organizations').should('have.length', 9)
cy.get('@organizations').should('have.length', 10)
})
})
it('should go back to the first page with arrow', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@ export class RecordApisComponent implements OnInit {
switchMap(async (apiLinks) => {
const linksPromises = apiLinks.map((link) => {
if (link.type === 'service' && link.accessServiceProtocol === 'tms') {
return this.dataService.getGeodataLinksFromTms(link, true)
// WARNING: when using "getGeodataLinksFromTms", make sure to add error handling to prevent the rest of the logic from failing
// this may happen when TMS endpoint is in error
return this.dataService
.getGeodataLinksFromTms(link, true)
.catch(() => {
return link
})
}
return Promise.resolve(link)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@
></gn-ui-metadata-quality>
</div>
<div
*ngIf="kind === 'dataset' && sourceLabel$ | async as sourceLabel"
*ngIf="
(kind$ | async) === 'dataset' && sourceLabel$
| async as sourceLabel
"
class="border border-gray-300 rounded-lg py-4 px-5"
>
<gn-ui-metadata-catalog [sourceLabel]="sourceLabel">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ describe('RecordMetadataComponent', () => {
let catalogComponent: MetadataCatalogComponent

beforeEach(() => {
facade.metadata$.next({ ...SAMPLE_RECORD, ...{ kind: 'dataset' } })
facade.isPresent$.next(true)
component.kind = 'dataset'
fixture.detectChanges()
metadataInfo = fixture.debugElement.query(
By.directive(MetadataInfoComponent)
Expand Down Expand Up @@ -138,7 +138,7 @@ describe('RecordMetadataComponent', () => {
describe('if metadata present and kind is service', () => {
beforeEach(() => {
facade.isPresent$.next(true)
component.kind = 'service'
facade.metadata$.next({ ...SAMPLE_RECORD, ...{ kind: 'service' } })
fixture.detectChanges()
})
it('does not display the metadata catalog component', () => {
Expand Down Expand Up @@ -192,7 +192,7 @@ describe('RecordMetadataComponent', () => {
})
describe('when DOWNLOAD link and kind is dataset', () => {
beforeEach(() => {
component.kind = 'dataset'
facade.metadata$.next({ ...SAMPLE_RECORD, ...{ kind: 'dataset' } })
facade.downloadLinks$.next(['link'])
fixture.detectChanges()
downloadsComponent = fixture.debugElement.query(
Expand All @@ -205,7 +205,7 @@ describe('RecordMetadataComponent', () => {
})
describe('when DOWNLOAD link and kind is other than dataset', () => {
beforeEach(() => {
component.kind = 'service'
facade.metadata$.next({ ...SAMPLE_RECORD, ...{ kind: 'service' } })
facade.downloadLinks$.next(['link'])
fixture.detectChanges()
downloadsComponent = fixture.debugElement.query(
Expand Down Expand Up @@ -258,7 +258,7 @@ describe('RecordMetadataComponent', () => {
})
describe('when API link and kind is dataset', () => {
beforeEach(() => {
component.kind = 'dataset'
facade.metadata$.next({ ...SAMPLE_RECORD, ...{ kind: 'dataset' } })
facade.apiLinks$.next(['link'])
fixture.detectChanges()
apiComponent = fixture.debugElement.query(
Expand All @@ -271,7 +271,7 @@ describe('RecordMetadataComponent', () => {
})
describe('when API link and kind is other than dataset', () => {
beforeEach(() => {
component.kind = 'reuse'
facade.metadata$.next({ ...SAMPLE_RECORD, ...{ kind: 'reuse' } })
facade.apiLinks$.next(['link'])
fixture.detectChanges()
apiComponent = fixture.debugElement.query(
Expand Down Expand Up @@ -398,7 +398,7 @@ describe('RecordMetadataComponent', () => {

describe('When the metadata is not fully loaded', () => {
beforeEach(() => {
component.kind = 'dataset'
facade.metadata$.next({ ...SAMPLE_RECORD, ...{ kind: 'dataset' } })
facade.isMetadataLoading$.next(false)
facade.apiLinks$.next([])
facade.downloadLinks$.next([])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
MetadataQualityComponent,
ServiceCapabilitiesComponent,
} from '@geonetwork-ui/ui/elements'
import { combineLatest, ReplaySubject } from 'rxjs'
import { combineLatest } from 'rxjs'
import { filter, map, mergeMap, startWith } from 'rxjs/operators'
import { OrganizationsServiceInterface } from '@geonetwork-ui/common/domain/organizations.service.interface'
import {
Expand Down Expand Up @@ -70,16 +70,6 @@ import { RecordLinkedRecordsComponent } from '../record-linked-records/record-li
})
export class RecordMetadataComponent {
@Input() metadataQualityDisplay: boolean
private kindValue: 'dataset' | 'service' | 'reuse' = null
@Input()
set kind(value: 'dataset' | 'service' | 'reuse') {
this.kindValue = value
this.kind$.next(value)
}
get kind() {
return this.kindValue
}
private kind$ = new ReplaySubject<'dataset' | 'service' | 'reuse'>(1)
@ViewChild('userFeedbacks') userFeedbacks: ElementRef<HTMLElement>

private readonly displayConditions = {
Expand Down Expand Up @@ -108,6 +98,11 @@ export class RecordMetadataComponent {

apiLinks$ = this.metadataViewFacade.apiLinks$

kind$ = this.metadataViewFacade.metadata$.pipe(
map((record) => record?.kind),
filter((kind) => kind !== undefined)
)

displayDownload$ = combineLatest([
this.metadataViewFacade.downloadLinks$,
this.kind$,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,5 @@
></datahub-header-record>
<datahub-record-metadata
[metadataQualityDisplay]="metadataQualityDisplay"
[kind]="(mdViewFacade.metadata$ | async).kind"
></datahub-record-metadata>
</div>
13 changes: 13 additions & 0 deletions libs/feature/dataviz/src/lib/service/data.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,19 @@ describe('DataService', () => {
const styles = await service.getGeodataLinksFromTms(noStyleLink)
expect(styles).toEqual([noStyleLink])
})

it('throws an error', async () => {
const noStyleLink = {
...tmsLink,
url: new URL('http://error.http/tms'),
}

try {
await service.getGeodataLinksFromTms(noStyleLink)
} catch (e) {
expect((e as Error).message).toBe('ogc.unreachable.unknown')
}
})
})
})

Expand Down
6 changes: 4 additions & 2 deletions libs/feature/dataviz/src/lib/service/data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export class DataService {
? endpoint.getCollectionItem(collections[0], '1')
: null
})
.catch((error) => {
.catch(() => {
throw new Error(`ogc.unreachable.unknown`)
})
}
Expand All @@ -237,7 +237,9 @@ export class DataService {
keepOriginalLink = false
): Promise<DatasetServiceDistribution[]> {
const endpoint = new TmsEndpoint(tmsLink.url.toString())
const tileMaps = await endpoint.allTileMaps
const tileMaps = await endpoint.allTileMaps.catch(() => {
throw new Error(`ogc.unreachable.unknown`)
})
if (!tileMaps?.length) return null

// TODO: at some point use the identifierInService field if more that one layers in the TMS service
Expand Down
70 changes: 66 additions & 4 deletions libs/feature/record/src/lib/map-view/map-view.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { DropdownSelectorComponent } from '@geonetwork-ui/ui/inputs'
import { of, Subject, throwError } from 'rxjs'
import { MapViewComponent } from './map-view.component'
import { TranslateModule, TranslateService } from '@ngx-translate/core'
import { delay, tap } from 'rxjs/operators'
import { delay } from 'rxjs/operators'
import { pointFeatureCollectionFixture } from '@geonetwork-ui/common/fixtures'
import { Collection } from 'ol'
import { Interaction } from 'ol/interaction'
Expand All @@ -34,8 +34,6 @@ import { ExternalViewerButtonComponent } from '../external-viewer-button/externa
import { LoadingMaskComponent } from '@geonetwork-ui/ui/widgets'
import { FetchError } from '@geonetwork-ui/data-fetcher'

// jest.useFakeTimers()

jest.mock('@geonetwork-ui/ui/map', () => ({
...jest.requireActual('@geonetwork-ui/ui/map'),
prioritizePageScroll: jest.fn(),
Expand Down Expand Up @@ -108,7 +106,11 @@ class DataServiceMock {
? throwError(() => new Error('data loading error'))
: of(SAMPLE_GEOJSON).pipe(delay(100))
)
getGeodataLinksFromTms = jest.fn((mapLink) => Promise.resolve([mapLink]))
getGeodataLinksFromTms = jest.fn((mapLink) => {
return mapLink.url.toString().indexOf('error') > -1
? Promise.reject([mapLink])
: Promise.resolve([mapLink])
})
}

class OpenLayersMapMock {
Expand Down Expand Up @@ -535,6 +537,34 @@ describe('MapViewComponent', () => {
})
})
})
describe('when endpoint is in error', () => {
beforeEach(fakeAsync(() => {
mdViewFacade.mapApiLinks$.next([
{
url: new URL('http://error.com/tms'),
name: 'tmserror',
type: 'service',
accessServiceProtocol: 'tms',
},
])
mdViewFacade.geoDataLinksWithGeometry$.next([])
tick(200)
fixture.detectChanges()
}))
it('still emits a map context using mvt tile format with root url', () => {
expect(mapComponent.context).toEqual({
layers: [
{
name: 'tmserror',
type: 'xyz',
tileFormat: 'application/vnd.mapbox-vector-tile',
url: 'http://error.com/tms/{z}/{x}/{y}.pbf',
},
],
view: expect.any(Object),
})
})
})
})

describe('with a link using ESRI:REST protocol', () => {
Expand Down Expand Up @@ -1022,6 +1052,37 @@ describe('MapViewComponent', () => {
})
})
describe('style selector with TMS', () => {
it('handles error when TMS endpoint is in error', fakeAsync(() => {
const dataService = TestBed.inject(
DataService
) as unknown as DataServiceMock
dataService.getGeodataLinksFromTms.mockImplementation((link) =>
Promise.reject(new Error('Endpoint is in error'))
)
mdViewFacade.mapApiLinks$.next([
{
url: new URL('http://abcd.com/tms'),
name: 'orthophoto',
type: 'service',
accessServiceProtocol: 'tms',
},
])
mdViewFacade.geoDataLinksWithGeometry$.next([])
tick(200)
fixture.detectChanges()
const dropdowns = fixture.debugElement.queryAll(
By.directive(DropdownSelectorComponent)
)
const styleDropdown = dropdowns[1]
.componentInstance as DropdownSelectorComponent
expect(styleDropdown.disabled).toBeTruthy()
expect(styleDropdown.choices).toEqual([
{
label: '\u00A0\u00A0\u00A0\u00A0',
value: 0,
},
])
}))
it('enables and populates styles for selected TMS', fakeAsync(() => {
const dataService = TestBed.inject(
DataService
Expand Down Expand Up @@ -1149,6 +1210,7 @@ describe('MapViewComponent', () => {
'http://abcd.com/tms/style/a.json'
)
}))

it('disables style dropdown when no TMS is present', fakeAsync(() => {
mdViewFacade.mapApiLinks$.next([
{
Expand Down
Loading
Loading