Skip to content

Commit

Permalink
Merge pull request #623 from geonetwork/reactivate-filter-geometry-fa…
Browse files Browse the repository at this point in the history
…vorites

Reactivate filtering by favorites & geometry
  • Loading branch information
jahow committed Sep 19, 2023
2 parents 353be82 + d055be3 commit 033798c
Show file tree
Hide file tree
Showing 32 changed files with 286 additions and 96 deletions.
29 changes: 29 additions & 0 deletions apps/datahub-e2e/src/e2e/datasets.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,33 @@ describe('datasets', () => {
})
})
})

describe('filter by geometry', () => {
beforeEach(() => {
// this will enable spatial filtering
cy.intercept('GET', '/assets/configuration/default.toml', {
fixture: 'config-with-geometry.toml',
})
cy.visit('/search')
})
it('boosts records in the provided geometry', () => {
cy.get('gn-ui-results-list-item')
.eq(0)
.find('[data-cy=recordTitle]')
.invoke('text')
.invoke('trim')
.should(
'eql',
'Cartographie des sols agricoles de la plaine du Rhône'
)
cy.get('gn-ui-results-list-item')
.eq(1)
.find('[data-cy=recordTitle]')
.invoke('text')
.invoke('trim')
.should('eql', 'Alpine Convention')
})
})
})

describe('sorting results', () => {
Expand All @@ -408,6 +435,8 @@ describe('datasets', () => {
})
describe('sort by date', () => {
beforeEach(() => {
// first sort by popularity
cy.get('@sortBy').find('select').select('desc,userSavedCount')
cy.get('@results')
.find('[data-cy="recordTitle"]')
.then(($titles) =>
Expand Down
38 changes: 37 additions & 1 deletion apps/datahub-e2e/src/e2e/home.cy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
/* eslint-disable cypress/no-unnecessary-waiting */
import 'cypress-real-events'

describe('header', () => {
beforeEach(() => cy.visit('/home/news'))
beforeEach(() => cy.visit('/'))

describe('general display', () => {
it('should end up on the news page', () => {
cy.url().should('match', /^http:\/\/localhost:[0-9]+\/news$/)
})
it('should select the right tab', () => {
cy.get('datahub-navigation-menu')
.find('button')
Expand Down Expand Up @@ -70,4 +76,34 @@ describe('header', () => {
cy.url().should('include', '/organisations')
})
})

describe('my favorites button', () => {
beforeEach(() => {
cy.login()
cy.clearFavorites()
cy.visit('/')
})
beforeEach(() => {
// select the 6th record as the new favorite
cy.get('gn-ui-results-list-item').eq(6).as('favoriteItem')
cy.get('@favoriteItem')
.find('[data-cy=recordTitle]')
.invoke('text')
.as('favoriteTitle')
cy.get('@favoriteItem').find('gn-ui-favorite-star').click()

// show my favorites only
cy.get('datahub-header-badge-button[label$=favorites]').realClick()
})
it('only shows one record, same as the favorite one', () => {
cy.get('gn-ui-results-list-item').should('have.length', 1)
cy.get('gn-ui-results-list-item')
.eq(0)
.find('[data-cy=recordTitle]')
.invoke('text')
.then(function (resultTitle) {
expect(resultTitle).to.eql(this.favoriteTitle)
})
})
})
})
26 changes: 26 additions & 0 deletions apps/datahub-e2e/src/fixtures/config-with-geometry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[global]
geonetwork4_api_url = "/geonetwork/srv/api"
proxy_path = ""

[theme]
primary_color = "#c82850"
secondary_color = "#001638"
main_color = "#212029" # All-purpose text color
background_color = "#fdfbff"

[search]
filter_geometry_data = '''
{
"coordinates":
[[
[6.465947342741936,46.80654432188126],
[6.465947342741936,45.65557605314669],
[8.74050023387097,45.65557605314669],
[8.74050023387097,46.80654432188126],
[6.465947342741936,46.80654432188126]
]],
"type": "Polygon"
}
'''

[map]
36 changes: 36 additions & 0 deletions apps/datahub-e2e/src/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ declare namespace Cypress {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Chainable<Subject> {
login(): void
clearFavorites(): void
}
}

Expand All @@ -29,6 +30,41 @@ Cypress.Commands.add('login', () => {
cy.get('[name="gnSigninForm"]').submit()
})

/**
* This will most likely fail if the user is not logged in!
*/
Cypress.Commands.add('clearFavorites', () => {
cy.request({
url: '/geonetwork/srv/api/me',
headers: { accept: 'application/json' },
})
.its('body')
.its('id')
.as('myId')

cy.window().then(function () {
cy.request({
url: `/geonetwork/srv/api/userselections/0/${this.myId}`,
headers: { accept: 'application/json' },
})
.its('body')
.as('favoritesId')
})

cy.getCookie('XSRF-TOKEN')
.its('value')
.then(function (token) {
const favoritesId = this.favoritesId || []
cy.request({
url: `/geonetwork/srv/api/userselections/0/${
this.myId
}?uuid=${favoritesId.join('&uuid=')}`,
method: 'DELETE',
headers: { accept: 'application/json', 'X-XSRF-TOKEN': token },
})
})
})

// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
Expand Down
3 changes: 2 additions & 1 deletion apps/datahub/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import {
UtilSharedModule,
getGeometryFromGeoJSON,
} from '@geonetwork-ui/util/shared'
import { FeatureAuthModule, LOGIN_URL } from '@geonetwork-ui/feature/auth'
import { FeatureAuthModule } from '@geonetwork-ui/feature/auth'
import { EffectsModule } from '@ngrx/effects'
import { MetaReducer, StoreModule } from '@ngrx/store'
import { StoreDevtoolsModule } from '@ngrx/store-devtools'
Expand Down Expand Up @@ -69,6 +69,7 @@ import { LANGUAGES_LIST, UiCatalogModule } from '@geonetwork-ui/ui/catalog'
import { METADATA_LANGUAGE } from '@geonetwork-ui/api/repository'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
import { GN_UI_VERSION } from '@geonetwork-ui/feature/record'
import { LOGIN_URL } from '@geonetwork-ui/api/repository/gn4'

export const metaReducers: MetaReducer[] = !environment.production ? [] : []
// https://github.com/nrwl/nx/issues/191
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { NO_ERRORS_SCHEMA } from '@angular/core'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { By } from '@angular/platform-browser'
import { AuthService } from '@geonetwork-ui/feature/auth'
import {
RouterFacade,
ROUTER_ROUTE_SEARCH,
Expand All @@ -18,6 +17,7 @@ import { HeaderBadgeButtonComponent } from '../header-badge-button/header-badge-
import { HomeHeaderComponent } from './home-header.component'
import resetAllMocks = jest.resetAllMocks
import { SortByEnum } from '@geonetwork-ui/common/domain/search'
import { AuthService } from '@geonetwork-ui/api/repository/gn4'
import { _setLanguages } from '@geonetwork-ui/util/app-config'

jest.mock('@geonetwork-ui/util/app-config', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { marker } from '@biesbjerg/ngx-translate-extract-marker'
import { AuthService } from '@geonetwork-ui/feature/auth'
import {
RouterFacade,
ROUTER_ROUTE_SEARCH,
Expand All @@ -23,6 +22,7 @@ import { ROUTER_ROUTE_NEWS } from '../../router/constants'
import { lastValueFrom } from 'rxjs'
import { CatalogRecord } from '@geonetwork-ui/common/domain/record'
import { sortByFromString } from '@geonetwork-ui/util/shared'
import { AuthService } from '@geonetwork-ui/api/repository/gn4'

marker('datahub.header.myfavorites')
marker('datahub.header.lastRecords')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'

import { SearchHeaderComponent } from './search-header.component'
import { BehaviorSubject, of } from 'rxjs'
import {
AuthService,
AvatarServiceInterface,
} from '@geonetwork-ui/feature/auth'
import { summaryHits, USER_FIXTURE } from '@geonetwork-ui/common/fixtures'
import { StoreModule } from '@ngrx/store'
import { EffectsModule } from '@ngrx/effects'
Expand All @@ -15,6 +11,10 @@ import { TRANSLATE_DEFAULT_CONFIG } from '@geonetwork-ui/util/i18n'
import { Configuration } from '@geonetwork-ui/data-access/gn4'
import { OrganizationsServiceInterface } from '@geonetwork-ui/common/domain/organizations.service.interface'
import { SearchFacade, SearchService } from '@geonetwork-ui/feature/search'
import {
AuthService,
AvatarServiceInterface,
} from '@geonetwork-ui/api/repository/gn4'

const user = USER_FIXTURE()
class AuthServiceMock {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { CommonModule } from '@angular/common'
import { ChangeDetectionStrategy, Component } from '@angular/core'
import { MatIconModule } from '@angular/material/icon'
import {
AuthService,
AvatarServiceInterface,
} from '@geonetwork-ui/feature/auth'
import { LetDirective } from '@ngrx/component'
import { FeatureSearchModule } from '@geonetwork-ui/feature/search'
import { UiElementsModule } from '@geonetwork-ui/ui/elements'
import {
AuthService,
AvatarServiceInterface,
} from '@geonetwork-ui/api/repository/gn4'

@Component({
selector: 'md-editor-search-header',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'

import { MyOrgRecordsComponent } from './my-org-records.component'
import { SearchFacade, SearchService } from '@geonetwork-ui/feature/search'
import { Component, importProvidersFrom } from '@angular/core'
Expand All @@ -10,8 +9,8 @@ import {
USER_FIXTURE,
} from '@geonetwork-ui/common/fixtures'
import { BehaviorSubject, of } from 'rxjs'
import { AuthService } from '@geonetwork-ui/feature/auth'
import { OrganizationsServiceInterface } from '@geonetwork-ui/common/domain/organizations.service.interface'
import { AuthService } from '@geonetwork-ui/api/repository/gn4'

const user = USER_FIXTURE()
const filters = FILTERS_AGGREGATION
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { RecordsListComponent } from '../records-list.component'
import { SearchFacade } from '@geonetwork-ui/feature/search'
import { OrganizationsServiceInterface } from '@geonetwork-ui/common/domain/organizations.service.interface'
import { Organization } from '@geonetwork-ui/common/domain/record'
import { AuthService } from '@geonetwork-ui/feature/auth'
import { Subscription } from 'rxjs'
import { AuthService } from '@geonetwork-ui/api/repository/gn4'

@Component({
selector: 'md-editor-my-org-records',
Expand Down
4 changes: 3 additions & 1 deletion conf/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,13 @@ background_color = "#fdfbff"

# This section contains settings used for fine-tuning the search experience
[search]

# Optional; specify a GeoJSON object to be used as filter: all records contained inside the geometry will be boosted on top,
# all records which _do not_ intersect with the geometry will be excluded; can be specified as URL or inline
# all records which do not intersect with the geometry will be shown with lower priority; can be specified as URL or inline
# Note: if the GeoJSON object contains multiple features, only the geometry of the first one will be kept!
# filter_geometry_url = "https://my.domain.org/assets/boundary.geojson"
# filter_geometry_data = '{ "coordinates": [...], "type": "Polygon" }'

# The advanced search filters available to the user can be customized with this setting.
# The following fields can be used for filtering: 'publisher', 'format', 'publicationYear', 'standard', 'inspireKeyword', 'topic', 'isSpatial', 'license'
# any other field will be ignored
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Subject } from 'rxjs'
import { TestBed } from '@angular/core/testing'
import { MeApiService } from '@geonetwork-ui/data-access/gn4'
import { TranslateService } from '@ngx-translate/core'
import { AvatarServiceInterface } from './avatar/avatar.service.interface'
import { AvatarServiceInterface } from './avatar.service.interface'

const userMock = {
id: '21737',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { UserModel } from '@geonetwork-ui/common/domain/user.model'
import { TranslateService } from '@ngx-translate/core'
import { Observable } from 'rxjs'
import { map, shareReplay } from 'rxjs/operators'
import { AvatarServiceInterface } from './avatar/avatar.service.interface'
import { AvatarServiceInterface } from './avatar.service.interface'

export const DEFAULT_GN4_LOGIN_URL = `/geonetwork/srv/\${lang3}/catalog.signin?redirect=\${current_url}`
export const LOGIN_URL = new InjectionToken<string>('loginUrl')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { TestBed } from '@angular/core/testing'

import { GravatarService } from './gravatar.service'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { Gn4SettingsService } from '@geonetwork-ui/api/repository/gn4'
import { Gn4SettingsService } from '../settings/gn4-settings.service'
import { BehaviorSubject } from 'rxjs'

class Gn4SettingsServiceMock {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'
import { AvatarServiceInterface } from './avatar.service.interface'
import { Gn4SettingsService } from '@geonetwork-ui/api/repository/gn4'
import { Gn4SettingsService } from '../settings/gn4-settings.service'

@Injectable({
providedIn: 'root',
Expand Down
3 changes: 3 additions & 0 deletions libs/api/repository/src/lib/gn4/auth/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './auth.service'
export * from './avatar.service.interface'
export * from './gravatar.service'
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { FavoritesService } from './favorites.service'
import { AuthService } from '@geonetwork-ui/feature/auth'
import { AuthService } from '../auth/auth.service'
import {
MeResponseApiModel,
UserselectionsApiService,
} from '@geonetwork-ui/data-access/gn4'
import { of, throwError } from 'rxjs'
import { readFirst } from '@nx/angular/testing'
import { firstValueFrom, of, throwError } from 'rxjs'
import { delay } from 'rxjs/operators'
import { fakeAsync, tick } from '@angular/core/testing'

Expand Down Expand Up @@ -46,7 +45,7 @@ describe('FavoritesService', () => {
service = new FavoritesService(userSelectionsService, authService)
})
it('returns an empty array', async () => {
const uuids = await readFirst(service.myFavoritesUuid$)
const uuids = await firstValueFrom(service.myFavoritesUuid$)
expect(uuids).toEqual([])
})
})
Expand All @@ -59,15 +58,15 @@ describe('FavoritesService', () => {
it('throws an error', async () => {
expect.assertions(2)
try {
await readFirst(service.myFavoritesUuid$)
await firstValueFrom(service.myFavoritesUuid$)
} catch (e: any) {
expect(e.message).toContain('fetching favorite records')
expect(e.message).toContain('blargz')
}
})
})
it('emits a list of saved record uuids', async () => {
const uuids = await readFirst(service.myFavoritesUuid$)
const uuids = await firstValueFrom(service.myFavoritesUuid$)
expect(uuids).toEqual(['abcd', 'efgh', 'ijkl'])
})
describe('when subscribing multiple times', () => {
Expand Down
Loading

0 comments on commit 033798c

Please sign in to comment.