Skip to content

Commit

Permalink
Merge pull request #598 from geonetwork/ME/display-user-avatar
Browse files Browse the repository at this point in the history
feat: adding gravatar to metadata-editor
  • Loading branch information
f-necas authored Aug 30, 2023
2 parents a5fe079 + 8a7ac84 commit 3ed45e3
Show file tree
Hide file tree
Showing 34 changed files with 479 additions and 74 deletions.
10 changes: 10 additions & 0 deletions apps/metadata-editor-e2e/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
}
]
}
10 changes: 10 additions & 0 deletions apps/metadata-editor-e2e/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from 'cypress'
import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset'

export default defineConfig({
e2e: {
...nxE2EPreset(__dirname),
video: false,
downloadsFolder: 'cypress/downloads',
},
})
35 changes: 35 additions & 0 deletions apps/metadata-editor-e2e/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "metadata-editor-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/metadata-editor-e2e/src",
"projectType": "application",
"targets": {
"e2e": {
"executor": "@nx/cypress:cypress",
"options": {
"cypressConfig": "apps/metadata-editor-e2e/cypress.config.ts",
"devServerTarget": "metadata-editor:serve:development",
"testingType": "e2e"
},
"configurations": {
"production": {
"devServerTarget": "metadata-editor:serve:production"
}
},
"env": {
"browserPermissions": {
"write": "allow"
}
}
},
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/metadata-editor-e2e/**/*.{js,ts}"]
}
}
},
"tags": [],
"implicitDependencies": ["metadata-editor"]
}
62 changes: 62 additions & 0 deletions apps/metadata-editor-e2e/src/e2e/home.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const fakeUser = {
username: 'user',
password: 'Abcde12!',
email: '[email protected]',
name: 'Homer',
surname: 'Simpson',
}

const gnBaseUrl = 'http://localhost:8080/geonetwork/srv/eng/'

describe('avatar', () => {
describe('display avatar for user without gravatar hash', () => {
it('should display placeholder url', () => {
cy.loginGN('admin', 'admin', false)
cy.visit(`${gnBaseUrl}admin.console#/organization`)
cy.get('#gn-btn-user-add').click()
cy.get('#username').type(fakeUser.username)
cy.get('#gn-user-password').type(fakeUser.password)
cy.get('#gn-user-password2').type(fakeUser.password)
cy.get('[name="name"]').type(fakeUser.name)
cy.get('[name="surname"]').type(fakeUser.surname)
cy.get('[name="email"]').type(fakeUser.email)
cy.get('.fa-save').click()

cy.visit(`${gnBaseUrl}admin.console#/settings`)
cy.get('[id="system/users/identicon"]').type('{selectAll}{del}')
cy.get('#gn-btn-settings-save').click()

cy.visit('/')
cy.get('gn-ui-avatar')
.children('img')
.should('have.attr', 'src')
.should('eq', 'https://www.gravatar.com/avatar/?d=mp')
})
it('should display monsterid', () => {
cy.loginGN('admin', 'admin', false)
cy.visit(`${gnBaseUrl}admin.console#/settings`)
cy.get('[id="system/users/identicon"]').type(
'{selectAll}gravatar:monsterid'
)
cy.get('#gn-btn-settings-save').click()

cy.visit('/')
cy.get('gn-ui-avatar')
.children('img')
.should('have.attr', 'src')
.should('eq', 'https://www.gravatar.com/avatar/?d=monsterid')
})
})
describe('display avatar for user with hash', () => {
it('should display the correct profile picture', () => {
cy.loginGN(fakeUser.username, fakeUser.password)
cy.get('gn-ui-avatar')
.children('img')
.should('have.attr', 'src')
.should(
'eq',
'https://www.gravatar.com/avatar/09abd59eb5653a7183ba812b8261f48b?d=monsterid'
)
})
})
})
14 changes: 14 additions & 0 deletions apps/metadata-editor-e2e/src/plugins/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const {
cypressBrowserPermissionsPlugin,
} = require('cypress-browser-permissions')

module.exports = (on, config) => {
on('before:browser:launch', (browser = {}, launchOptions) => {
// if (browser.name === 'chrome') {
launchOptions.args.push('--lang=en')
return launchOptions
// }
})
config = cypressBrowserPermissionsPlugin(on, config)
return config
}
1 change: 1 addition & 0 deletions apps/metadata-editor-e2e/src/support/app.po.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const getGreeting = () => cy.get('h1')
62 changes: 62 additions & 0 deletions apps/metadata-editor-e2e/src/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************

/* eslint-disable cypress/no-unnecessary-waiting */
// eslint-disable-next-line @typescript-eslint/no-namespace
declare namespace Cypress {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Chainable<Subject> {
// login(email: string, password: string): void
loginGN(username: string, password: string, redirect?: boolean): void
signOutGN(): void
}
}
//
// -- This is a parent command --
/*Cypress.Commands.add('login', (email, password) => {
console.log('Custom command example: Login', email, password)
})*/

Cypress.Commands.add(
'loginGN',
(username: string, password: string, redirect = true) => {
cy.visit('http://localhost:8080/geonetwork/srv/eng/catalog.search#/home')
cy.get('.cookie-warning-actions').then(($cookie) => {
if ($cookie.is(':visible')) {
$cookie.find('button').eq(0).click()
cy.scrollTo('top')
}
})

cy.wait(250)
cy.get('li.signin-dropdown').click()
cy.get('#inputUsername').type(username)
cy.get('#inputPassword').type(password)
cy.get('[name="gnSigninForm"]').submit()
if (redirect) cy.visit('/')
}
)

Cypress.Commands.add('signOutGN', () => {
cy.visit('http://localhost:8080/geonetwork/srv/eng/catalog.search#/home')
cy.get('a[title="User details"]').click()
cy.get('a[title="Sign out"]').click()
})
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
17 changes: 17 additions & 0 deletions apps/metadata-editor-e2e/src/support/e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'
10 changes: 10 additions & 0 deletions apps/metadata-editor-e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"sourceMap": false,
"outDir": "../../dist/out-tsc",
"allowJs": true,
"types": ["cypress", "node"]
},
"include": ["src/**/*.ts", "src/**/*.js", "cypress.config.ts"]
}
10 changes: 10 additions & 0 deletions apps/metadata-editor/src/app/dashboard/dashboard.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import { DashboardMenuComponent } from './dashboard-menu/dashboard-menu.componen
import { DashboardPageComponent } from './dashboard-page.component'
import { SearchHeaderComponent } from './search-header/search-header.component'
import { SidebarComponent } from './sidebar/sidebar.component'
import {
AvatarServiceInterface,
GravatarService,
} from '@geonetwork-ui/feature/auth'

@NgModule({
declarations: [
Expand All @@ -37,5 +41,11 @@ import { SidebarComponent } from './sidebar/sidebar.component'
TranslateModule.forRoot(TRANSLATE_DEFAULT_CONFIG),
],
exports: [DashboardPageComponent],
providers: [
{
provide: AvatarServiceInterface,
useClass: GravatarService,
},
],
})
export class DashboardModule {}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="py-3 flex justify-around w-full">
<div class="py-3 px-12 flex justify-between w-full">
<div class="w-2/3">
<gn-ui-fuzzy-search></gn-ui-fuzzy-search>
</div>
Expand All @@ -16,5 +16,12 @@
<button>
<mat-icon class="icon-btn material-icons-outlined">settings</mat-icon>
</button>
<ng-container *ngrxLet="authService.user$ as user">
<gn-ui-user-preview
*ngIf="user && user.name"
[user]="user"
[avatarPlaceholder]="placeholder"
></gn-ui-user-preview>
</ng-container>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'
import { ComponentFixture, TestBed } from '@angular/core/testing'

import { SearchHeaderComponent } from './search-header.component'
import { BehaviorSubject } from 'rxjs'
import {
AuthService,
AvatarServiceInterface,
} from '@geonetwork-ui/feature/auth'
import { USER_FIXTURE } from '@geonetwork-ui/common/fixtures'

const user = USER_FIXTURE()
class AuthServiceMock {
user$ = new BehaviorSubject(user)
}

class AvatarServiceInterfaceMock {
placeholder = 'http://placeholder.com'
getProfileIcon = (hash: string) => `${hash}`
}

describe('SearchHeaderComponent', () => {
let component: SearchHeaderComponent
Expand All @@ -11,6 +27,13 @@ describe('SearchHeaderComponent', () => {
await TestBed.configureTestingModule({
declarations: [SearchHeaderComponent],
schemas: [NO_ERRORS_SCHEMA],
providers: [
{ provide: AuthService, useClass: AuthServiceMock },
{
provide: AvatarServiceInterface,
useClass: AvatarServiceInterfaceMock,
},
],
})
.overrideComponent(SearchHeaderComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { ChangeDetectionStrategy, Component } from '@angular/core'
import {
AuthService,
AvatarServiceInterface,
} from '@geonetwork-ui/feature/auth'

@Component({
selector: 'md-editor-search-header',
templateUrl: './search-header.component.html',
styleUrls: ['./search-header.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SearchHeaderComponent {}
export class SearchHeaderComponent {
public placeholder = this.avatarService.placeholder

constructor(
public authService: AuthService,
private avatarService: AvatarServiceInterface
) {}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
<div class="flex flex-col pt-9 px-5 gap-12">
<div class="">
<ng-container *ngrxLet="authService.user$ as user">
<gn-ui-user-preview [user]="user"></gn-ui-user-preview>
</ng-container>
</div>
<div>
<md-editor-dashboard-menu></md-editor-dashboard-menu>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,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 { USER_FIXTURE } from '@geonetwork-ui/common/fixtures'
import { LetDirective } from '@ngrx/component'
Expand Down Expand Up @@ -62,12 +61,4 @@ describe('SidebarComponent', () => {
it('should create', () => {
expect(component).toBeTruthy()
})
describe('when a user is logged', () => {
it('displays the user preview', () => {
const avatar = fixture.debugElement.query(
By.directive(UserPreviewComponent)
)
expect(avatar.componentInstance.user).toBe(user)
})
})
})
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { ChangeDetectionStrategy, Component } from '@angular/core'
import { AuthService } from '@geonetwork-ui/feature/auth'

@Component({
selector: 'md-editor-sidebar',
templateUrl: './sidebar.component.html',
styleUrls: ['./sidebar.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SidebarComponent {
constructor(public authService: AuthService) {}
}
export class SidebarComponent {}
1 change: 1 addition & 0 deletions libs/api/repository/src/lib/gn4/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './gn4-repository'
export * from './organizations'
export * from './elasticsearch'
export * from './settings/gn4-settings.service'
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { TestBed } from '@angular/core/testing'

import { Gn4SettingsService } from './gn4-settings.service'
import { HttpClientTestingModule } from '@angular/common/http/testing'

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

beforeEach(() => {
TestBed.configureTestingModule({ imports: [HttpClientTestingModule] })
service = TestBed.inject(Gn4SettingsService)
})

it('should be created', () => {
expect(service).toBeTruthy()
})
})
Loading

0 comments on commit 3ed45e3

Please sign in to comment.