diff --git a/.prettierignore b/.prettierignore
index 3859ddbc13..3f0fb7ea3c 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -6,3 +6,4 @@
/docs/.vitepress/dist
# OpenAPI generated specs
**/spec.yaml
+/.nx
diff --git a/apps/metadata-editor/src/app/dashboard/search-header/search-header.component.html b/apps/metadata-editor/src/app/dashboard/search-header/search-header.component.html
index 2326ec526b..9b0edbaf48 100644
--- a/apps/metadata-editor/src/app/dashboard/search-header/search-header.component.html
+++ b/apps/metadata-editor/src/app/dashboard/search-header/search-header.component.html
@@ -20,7 +20,7 @@
diff --git a/apps/metadata-editor/src/app/dashboard/search-header/search-header.component.spec.ts b/apps/metadata-editor/src/app/dashboard/search-header/search-header.component.spec.ts
index d50f0279c0..5633823269 100644
--- a/apps/metadata-editor/src/app/dashboard/search-header/search-header.component.spec.ts
+++ b/apps/metadata-editor/src/app/dashboard/search-header/search-header.component.spec.ts
@@ -6,7 +6,7 @@ import {
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { SearchHeaderComponent } from './search-header.component'
-import { BehaviorSubject } from 'rxjs'
+import { BehaviorSubject, of } from 'rxjs'
import { USER_FIXTURE } from '@geonetwork-ui/common/fixtures'
import { StoreModule } from '@ngrx/store'
import { EffectsModule } from '@ngrx/effects'
@@ -16,8 +16,8 @@ import { PlatformServiceInterface } from '@geonetwork-ui/common/domain/platform.
import { AvatarServiceInterface } from '@geonetwork-ui/api/repository/gn4'
class AvatarServiceInterfaceMock {
- placeholder = 'http://placeholder.com'
- getProfileIcon = (hash: string) => `${hash}`
+ getPlaceholder = () => of('http://placeholder.com')
+ getProfileIcon = (hash: string) => of(`${hash}`)
}
const me$ = new BehaviorSubject(USER_FIXTURE())
diff --git a/apps/metadata-editor/src/app/dashboard/search-header/search-header.component.ts b/apps/metadata-editor/src/app/dashboard/search-header/search-header.component.ts
index 7ce966490d..ddc5d3219f 100644
--- a/apps/metadata-editor/src/app/dashboard/search-header/search-header.component.ts
+++ b/apps/metadata-editor/src/app/dashboard/search-header/search-header.component.ts
@@ -22,7 +22,7 @@ import { PlatformServiceInterface } from '@geonetwork-ui/common/domain/platform.
],
})
export class SearchHeaderComponent {
- public placeholder = this.avatarService.placeholder
+ public placeholder$ = this.avatarService.getPlaceholder()
constructor(
public platformService: PlatformServiceInterface,
diff --git a/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.ts b/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.ts
index 3beadf4174..2ef85b8dc6 100644
--- a/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.ts
+++ b/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.ts
@@ -1,4 +1,6 @@
+import { Observable } from 'rxjs'
+
export abstract class AvatarServiceInterface {
- public abstract placeholder: string
- public abstract getProfileIcon(...args): string
+ public abstract getPlaceholder(): Observable
+ public abstract getProfileIcon(...args): Observable
}
diff --git a/libs/api/repository/src/lib/gn4/auth/gravatar.service.spec.ts b/libs/api/repository/src/lib/gn4/auth/gravatar.service.spec.ts
index 64c2d54b05..6f31600dd7 100644
--- a/libs/api/repository/src/lib/gn4/auth/gravatar.service.spec.ts
+++ b/libs/api/repository/src/lib/gn4/auth/gravatar.service.spec.ts
@@ -2,7 +2,7 @@ import { TestBed } from '@angular/core/testing'
import { GravatarService } from './gravatar.service'
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { Gn4SettingsService } from '../settings/gn4-settings.service'
-import { BehaviorSubject } from 'rxjs'
+import { BehaviorSubject, firstValueFrom } from 'rxjs'
class Gn4SettingsServiceMock {
identicon$ = new BehaviorSubject('404')
@@ -10,6 +10,7 @@ class Gn4SettingsServiceMock {
describe('GravatarService', () => {
let service: GravatarService
+ let settingsService: Gn4SettingsService
beforeEach(() => {
TestBed.configureTestingModule({
@@ -19,22 +20,31 @@ describe('GravatarService', () => {
],
})
service = TestBed.inject(GravatarService)
+ settingsService = TestBed.inject(Gn4SettingsService)
})
it('should be created', () => {
expect(service).toBeTruthy()
})
- it('returns correct Url without data', () => {
- expect(service.getProfileIcon('')).toEqual(
- 'https://www.gravatar.com/avatar/?d=404'
- )
- })
- it('returns correct Url with data but without placeholder', () => {
- expect(service.getProfileIcon('abc')).toEqual(
- 'https://www.gravatar.com/avatar/abc?d=404'
- )
+ describe('#getProfileIcon', () => {
+ it('returns correct Url without data', async () => {
+ const icon = await firstValueFrom(service.getProfileIcon(''))
+ expect(icon).toEqual('https://www.gravatar.com/avatar/?d=404')
+ })
+ it('returns correct Url with data but without placeholder', async () => {
+ const icon = await firstValueFrom(service.getProfileIcon('abc'))
+ expect(icon).toEqual('https://www.gravatar.com/avatar/abc?d=404')
+ })
})
- it('returns plaholder to be mp', () => {
- expect(service.placeholder).toEqual('https://www.gravatar.com/avatar/?d=mp')
+ describe('#getPlaceholder', () => {
+ it('returns url with identicon value, without hash', async () => {
+ const placeholder = await firstValueFrom(service.getPlaceholder())
+ expect(placeholder).toEqual('https://www.gravatar.com/avatar/?d=404')
+ })
+ it('returns placeholder to be mp if no identicon value', async () => {
+ settingsService.identicon$.next('')
+ const placeholder = await firstValueFrom(service.getPlaceholder())
+ expect(placeholder).toEqual('https://www.gravatar.com/avatar/?d=mp')
+ })
})
})
diff --git a/libs/api/repository/src/lib/gn4/auth/gravatar.service.ts b/libs/api/repository/src/lib/gn4/auth/gravatar.service.ts
index d7839f7e3d..ce02bddb68 100644
--- a/libs/api/repository/src/lib/gn4/auth/gravatar.service.ts
+++ b/libs/api/repository/src/lib/gn4/auth/gravatar.service.ts
@@ -1,6 +1,8 @@
import { Injectable } from '@angular/core'
import { AvatarServiceInterface } from './avatar.service.interface'
import { Gn4SettingsService } from '../settings/gn4-settings.service'
+import { map } from 'rxjs/operators'
+import { Observable } from 'rxjs'
@Injectable({
providedIn: 'root',
@@ -9,16 +11,19 @@ export class GravatarService implements AvatarServiceInterface {
private GRAVATAR_URL = 'https://www.gravatar.com/avatar/'
private GRAVATAR_IDENTICON = 'mp'
- constructor(private gn4SettingsService: Gn4SettingsService) {
- this.gn4SettingsService.identicon$.subscribe(
- (identicon) =>
- (this.GRAVATAR_IDENTICON = identicon.replace('gravatar:', ''))
- )
- }
+ private readonly identicon$ = this.gn4SettingsService.identicon$.pipe(
+ map((identicon) => identicon?.replace('gravatar:', ''))
+ )
+ constructor(private gn4SettingsService: Gn4SettingsService) {}
- placeholder = this.getProfileIcon('')
+ getPlaceholder(): Observable {
+ return this.getProfileIcon('')
+ }
- getProfileIcon(hash: string): string {
- return `${this.GRAVATAR_URL}${hash}?d=${this.GRAVATAR_IDENTICON}`
+ getProfileIcon(hash: string): Observable {
+ return this.identicon$.pipe(
+ map((identicon) => identicon || this.GRAVATAR_IDENTICON),
+ map((identicon) => `${this.GRAVATAR_URL}${hash}?d=${identicon}`)
+ )
}
}
diff --git a/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.ts b/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.ts
index bb34126673..14c73492f0 100644
--- a/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.ts
+++ b/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.ts
@@ -5,12 +5,14 @@ import {
import { UserModel } from '@geonetwork-ui/common/domain/model/user/user.model'
import { Injectable } from '@angular/core'
import { AvatarServiceInterface } from '../auth/avatar.service.interface'
+import { map } from 'rxjs/operators'
+import { Observable, of } from 'rxjs'
@Injectable()
export class Gn4PlatformMapper {
constructor(private avatarService: AvatarServiceInterface) {}
- userFromMeApi(apiUser: MeResponseApiModel): UserModel {
- if (!apiUser) return null
+ userFromMeApi(apiUser: MeResponseApiModel): Observable {
+ if (!apiUser) return of(null)
const {
hash,
groupsWithRegisteredUser,
@@ -20,8 +22,10 @@ export class Gn4PlatformMapper {
admin,
...user
} = apiUser
- const icon = this.avatarService.getProfileIcon(hash)
- return { ...user, profileIcon: icon } as UserModel
+
+ return this.avatarService
+ .getProfileIcon(hash)
+ .pipe(map((profileIcon) => ({ ...user, profileIcon } as UserModel)))
}
userFromApi(apiUser: UserApiModel): UserModel {
if (!apiUser) return null
diff --git a/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.spec.ts b/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.spec.ts
index 4d42efc935..804b7698e5 100644
--- a/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.spec.ts
+++ b/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.spec.ts
@@ -35,8 +35,8 @@ class MeApiMock {
}
class AvatarServiceInterfaceMock {
- placeholder = 'http://placeholder.com'
- getProfileIcon = jest.fn((hash: string) => `http://icon_service.com/${hash}`)
+ getPlaceholder = () => of('http://placeholder.com')
+ getProfileIcon = (hash: string) => of(`http://icon_service.com/${hash}`)
}
class SiteApiServiceMock {
diff --git a/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts b/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts
index 5e4807ade3..e90c04759f 100644
--- a/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts
+++ b/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts
@@ -45,7 +45,7 @@ export class Gn4PlatformService implements PlatformServiceInterface {
private mapper: Gn4PlatformMapper
) {
this.me$ = this.meApi.getMe().pipe(
- map((apiUser) => this.mapper.userFromMeApi(apiUser)),
+ switchMap((apiUser) => this.mapper.userFromMeApi(apiUser)),
shareReplay({ bufferSize: 1, refCount: true })
)
this.isAnonymous$ = this.me$.pipe(map((user) => !user || !('id' in user)))