Skip to content

Commit

Permalink
Merge pull request #712 from geonetwork/fix-chart-wc
Browse files Browse the repository at this point in the history
Fix gravatar service calls
  • Loading branch information
fgravin authored Dec 8, 2023
2 parents 6d4aec4 + d16f177 commit 17fd38f
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 35 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
/docs/.vitepress/dist
# OpenAPI generated specs
**/spec.yaml
/.nx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<gn-ui-user-preview
*ngIf="user && user.name"
[user]="user"
[avatarPlaceholder]="placeholder"
[avatarPlaceholder]="placeholder$ | async"
></gn-ui-user-preview>
</ng-container>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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<string>
public abstract getProfileIcon(...args): Observable<string>
}
34 changes: 22 additions & 12 deletions libs/api/repository/src/lib/gn4/auth/gravatar.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ 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')
}

describe('GravatarService', () => {
let service: GravatarService
let settingsService: Gn4SettingsService

beforeEach(() => {
TestBed.configureTestingModule({
Expand All @@ -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')
})
})
})
23 changes: 14 additions & 9 deletions libs/api/repository/src/lib/gn4/auth/gravatar.service.ts
Original file line number Diff line number Diff line change
@@ -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',
Expand All @@ -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<string> {
return this.getProfileIcon('')
}

getProfileIcon(hash: string): string {
return `${this.GRAVATAR_URL}${hash}?d=${this.GRAVATAR_IDENTICON}`
getProfileIcon(hash: string): Observable<string> {
return this.identicon$.pipe(
map((identicon) => identicon || this.GRAVATAR_IDENTICON),
map((identicon) => `${this.GRAVATAR_URL}${hash}?d=${identicon}`)
)
}
}
12 changes: 8 additions & 4 deletions libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<UserModel | null> {
if (!apiUser) return of(null)
const {
hash,
groupsWithRegisteredUser,
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down

0 comments on commit 17fd38f

Please sign in to comment.