Commit 33bd557b authored by Tifenn Guillas's avatar Tifenn Guillas
Browse files

Merge branch '151-display-auth-buttons-depending-on-instance-config' into 'develop'

Resolve "Display auth buttons depending on instance config"

Closes #151

See merge request !163
parents 86e33b0a d6511893
Pipeline #3458 passed with stages
in 8 minutes and 26 seconds
...@@ -6,13 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ...@@ -6,13 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [3.5.0] - 2020-xx ## [3.5.0] - 2020-xx
### Added ### Added
- #140 => Add description tooltip on search multiple datasetsranch - #140 => Add description tooltip on search multiple datasets page
- #136 => Add detail view for spectra type object and default object - #136 => Add detail view for spectra type object and default object
### Fixed ### Fixed
- #142 => Fix bug datatable: attribute disappeared in specific circonstances - #142 => Fix bug datatable: attribute disappeared in specific circonstances
### Changed ### Changed
- #151 => Display authentication actions buttons if instance configuration allows it
- #145 => Display public datasets only when no user logged in - #145 => Display public datasets only when no user logged in
- #134 => Result search summary into accordion - #134 => Result search summary into accordion
- #139 => Datasets selected in search multiple is a configurable option in anis-admin - #139 => Datasets selected in search multiple is a configurable option in anis-admin
......
...@@ -8,6 +8,7 @@ module.exports = function (config) { ...@@ -8,6 +8,7 @@ module.exports = function (config) {
plugins: [ plugins: [
require('karma-jasmine'), require('karma-jasmine'),
require('karma-chrome-launcher'), require('karma-chrome-launcher'),
require('karma-spec-reporter'),
require('karma-jasmine-html-reporter'), require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'), require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma') require('@angular-devkit/build-angular/plugins/karma')
...@@ -20,7 +21,7 @@ module.exports = function (config) { ...@@ -20,7 +21,7 @@ module.exports = function (config) {
reports: ['html', 'lcovonly', 'text-summary'], reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true fixWebpackSourcePaths: true
}, },
reporters: ['progress', 'kjhtml'], reporters: ['progress', 'kjhtml', 'spec'],
port: 9876, port: 9876,
colors: true, colors: true,
logLevel: config.LOG_INFO, logLevel: config.LOG_INFO,
......
...@@ -12,28 +12,29 @@ ...@@ -12,28 +12,29 @@
<span class="fas fa-home"></span> Home <span class="fas fa-home"></span> Home
</a> </a>
</li> </li>
<li *ngIf="isSearchAllowed()" id="search_link" class="nav-item"> <li *ngIf="getConfig('search', 'allowed')" id="search_link" class="nav-item">
<a class="nav-link" routerLink="/search" routerLinkActive="active"> <a class="nav-link" routerLink="/search" routerLinkActive="active">
<span class="fas fa-search"></span> Search <span class="fas fa-search"></span> Search
</a> </a>
</li> </li>
<li *ngIf="isSearchMultipleAllowed()" id="search_multiple_link" class="nav-item"> <li *ngIf="getConfig('search_multiple', 'allowed')" id="search_multiple_link" class="nav-item">
<a class="nav-link" routerLink="/search-multiple" routerLinkActive="active"> <a class="nav-link" routerLink="/search-multiple" routerLinkActive="active">
<span class="fas fa-search-plus"></span> Search multiple <span class="fas fa-search-plus"></span> Search multiple
</a> </a>
</li> </li>
<li *ngIf="isDocumentationAllowed()" id="documentation_link" class="nav-item"> <li *ngIf="getConfig('documentation', 'allowed')" id="documentation_link" class="nav-item">
<a class="nav-link" routerLink="/documentation" routerLinkActive="active"> <a class="nav-link" routerLink="/documentation" routerLinkActive="active">
<span class="fas fa-question"></span> Documentation <span class="fas fa-question"></span> Documentation
</a> </a>
</li> </li>
</ul> </ul>
<button *ngIf="!isAuthenticated" class="btn btn-outline-success my-2 my-sm-0" <button *ngIf="getConfig('authentication', 'allowed') && !isAuthenticated"
class="btn btn-outline-success my-2 my-sm-0"
id="button-sign-in" id="button-sign-in"
(click)="emitLogin()"> (click)="login.emit()">
Sign In / Register Sign In / Register
</button> </button>
<span *ngIf="isAuthenticated" id="dropdown-menu" dropdown> <span *ngIf="getConfig('authentication', 'allowed') && isAuthenticated" id="dropdown-menu" dropdown>
<button id="button-basic" dropdownToggle type="button" class="btn btn-light" aria-controls="dropdown-basic"> <button id="button-basic" dropdownToggle type="button" class="btn btn-light" aria-controls="dropdown-basic">
<span class="fa-stack theme-color"> <span class="fa-stack theme-color">
<span class="fas fa-circle fa-2x"></span> <span class="fas fa-circle fa-2x"></span>
...@@ -49,15 +50,15 @@ ...@@ -49,15 +50,15 @@
</li> </li>
<li class="divider dropdown-divider"></li> <li class="divider dropdown-divider"></li>
<li role="menuitem"> <li role="menuitem">
<a class="dropdown-item pointer" (click)="emitOpenEditProfile()"> <button class="dropdown-item pointer" (click)="openEditProfile.emit()">
<span class="fas fa-id-card"></span> Edit profile <span class="fas fa-id-card"></span> Edit profile
</a> </button>
</li> </li>
<li class="divider dropdown-divider"></li> <li class="divider dropdown-divider"></li>
<li role="menuitem"> <li role="menuitem">
<a class="dropdown-item text-danger pointer" (click)="emitLogout()"> <button class="dropdown-item text-danger pointer" (click)="logout.emit()">
<span class="fas fa-sign-out-alt fa-fw"></span> Sign Out <span class="fas fa-sign-out-alt fa-fw"></span> Sign Out
</a> </button>
</li> </li>
</ul> </ul>
</span> </span>
...@@ -70,46 +71,48 @@ ...@@ -70,46 +71,48 @@
</button> </button>
<ul id="basic-link-dropdown" *dropdownMenu class="dropdown-menu dropdown-menu-right dropdown-up" role="menu" <ul id="basic-link-dropdown" *dropdownMenu class="dropdown-menu dropdown-menu-right dropdown-up" role="menu"
aria-labelledby="basic-link"> aria-labelledby="basic-link">
<li *ngIf="isAuthenticated" role="menuitem"> <li *ngIf="getConfig('authentication', 'allowed') && isAuthenticated" role="menuitem">
<span class="dropdown-item font-italic">{{ userProfile.email }}</span> <span class="dropdown-item font-italic">{{ userProfile.email }}</span>
</li> </li>
<li *ngIf="isAuthenticated" class="divider dropdown-divider"></li> <li *ngIf="getConfig('authentication', 'allowed') && isAuthenticated" class="divider dropdown-divider"></li>
<li role="menuitem"> <li role="menuitem">
<a class="dropdown-item" routerLink="/home"> <a class="dropdown-item" routerLink="/home">
<span class="fas fa-home fa-fw"></span> Home <span class="fas fa-home fa-fw"></span> Home
</a> </a>
</li> </li>
<li *ngIf="isSearchAllowed()" role="menuitem"> <li *ngIf="getConfig('search', 'allowed')" role="menuitem">
<a class="dropdown-item" routerLink="/search"> <a class="dropdown-item" routerLink="/search">
<span class="fas fa-search fa-fw"></span> Search <span class="fas fa-search fa-fw"></span> Search
</a> </a>
</li> </li>
<li *ngIf="isSearchMultipleAllowed()" role="menuitem"> <li *ngIf="getConfig('search_multiple', 'allowed')" role="menuitem">
<a class="dropdown-item" routerLink="/search-multiple"> <a class="dropdown-item" routerLink="/search-multiple">
<span class="fas fa-search-plus fa-fw"></span> Search multiple <span class="fas fa-search-plus fa-fw"></span> Search multiple
</a> </a>
</li> </li>
<li *ngIf="isDocumentationAllowed()" role="menuitem"> <li *ngIf="getConfig('documentation', 'allowed')" role="menuitem">
<a class="dropdown-item" routerLink="/documentation"> <a class="dropdown-item" routerLink="/documentation">
<span class="fas fa-question fa-fw"></span> Documentation <span class="fas fa-question fa-fw"></span> Documentation
</a> </a>
</li> </li>
<li *ngIf="isAuthenticated" class="divider dropdown-divider"></li> <li *ngIf="getConfig('authentication', 'allowed') && isAuthenticated" class="divider dropdown-divider"></li>
<li *ngIf="isAuthenticated" role="menuitem"> <li *ngIf="getConfig('authentication', 'allowed') && isAuthenticated" role="menuitem">
<a class="dropdown-item pointer" (click)="emitOpenEditProfile()"> <button class="dropdown-item pointer" (click)="openEditProfile.emit()">
<span class="fas fa-id-card"></span> Edit profile <span class="fas fa-id-card"></span> Edit profile
</a> </button>
</li> </li>
<li class="divider dropdown-divider"></li> <li *ngIf="getConfig('authentication', 'allowed')" class="divider dropdown-divider"></li>
<li role="menuitem"> <li role="menuitem">
<a *ngIf="!isAuthenticated" class="dropdown-item text-success" routerLink="/login"> <button *ngIf="getConfig('authentication', 'allowed') && !isAuthenticated"
class="dropdown-item text-success"
(click)="login.emit()">
<span class="fas fa-sign-in-alt fa-fw"></span> Sign In / Register <span class="fas fa-sign-in-alt fa-fw"></span> Sign In / Register
</a> </button>
</li> </li>
<li role="menuitem"> <li role="menuitem">
<a *ngIf="isAuthenticated" class="dropdown-item pointer text-danger" (click)="logout.emit()"> <button *ngIf="getConfig('authentication', 'allowed') && isAuthenticated" class="dropdown-item pointer text-danger" (click)="logout.emit()">
<span class="fas fa-sign-out-alt fa-fw"></span> Sign Out <span class="fas fa-sign-out-alt fa-fw"></span> Sign Out
</a> </button>
</li> </li>
</ul> </ul>
</span> </span>
......
...@@ -19,49 +19,23 @@ describe('[Core] Component: NavComponent', () => { ...@@ -19,49 +19,23 @@ describe('[Core] Component: NavComponent', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should display the Sign In button if no user logged in', () => { it('should display the Sign In button if authentication allowed and no user logged in', () => {
component.instance = INSTANCE;
component.isAuthenticated = false; component.isAuthenticated = false;
fixture.detectChanges(); fixture.detectChanges();
const template = fixture.nativeElement; const template = fixture.nativeElement;
expect(template.querySelector('#button-sign-in')).toBeTruthy(); expect(template.querySelector('#button-sign-in')).toBeTruthy();
}); });
it('should not display the dropdown menu if no user logged in', () => {
component.isAuthenticated = false;
fixture.detectChanges();
const template = fixture.nativeElement;
expect(template.querySelector('#dropdown-menu')).toBeFalsy();
});
it('should display the dropdown menu if user logged in', () => {
component.isAuthenticated = true;
fixture.detectChanges();
const template = fixture.nativeElement;
expect(template.querySelector('#dropdown-menu')).toBeTruthy();
});
it('should not display the Sign In button if user logged in', () => { it('should not display the Sign In button if user logged in', () => {
component.instance = INSTANCE;
component.isAuthenticated = true; component.isAuthenticated = true;
fixture.detectChanges(); fixture.detectChanges();
const template = fixture.nativeElement; const template = fixture.nativeElement;
expect(template.querySelector('#button-sign-in')).toBeFalsy(); expect(template.querySelector('#button-sign-in')).toBeFalsy();
}); });
it('raises the logout event when clicked', () => { it('should not display the Sign In button if authentication not allowed', () => {
component.logout.subscribe((event) => expect(event).toBe(undefined));
component.emitLogout();
});
it('should display search, search multiple and documentation links if instance config allows it', () => {
component.instance = INSTANCE;
fixture.detectChanges();
const template = fixture.nativeElement;
expect(template.querySelector('#search_link')).toBeTruthy();
expect(template.querySelector('#search_multiple_link')).toBeTruthy();
expect(template.querySelector('#documentation_link')).toBeNull();
});
it('should not display search, search multiple and documentation links if instance config don\'t allows it', () => {
component.instance = { component.instance = {
name: 'toto', name: 'toto',
label: 'Toto', label: 'Toto',
...@@ -69,21 +43,28 @@ describe('[Core] Component: NavComponent', () => { ...@@ -69,21 +43,28 @@ describe('[Core] Component: NavComponent', () => {
nb_dataset_families: 1, nb_dataset_families: 1,
nb_datasets: 1, nb_datasets: 1,
config: { config: {
search: false, authentication: {
allowed: false
},
search: {
allowed: false
},
search_multiple: { search_multiple: {
allowed: false, allowed: false,
all_datasets_selected: false all_datasets_selected: false
}, },
documentation: false documentation: {
} }; allowed: false
}
}
};
component.isAuthenticated = true;
fixture.detectChanges(); fixture.detectChanges();
const template = fixture.nativeElement; const template = fixture.nativeElement;
expect(template.querySelector('#search_link')).toBeFalsy(); expect(template.querySelector('#button-sign-in')).toBeFalsy();
expect(template.querySelector('#search_multiple_link')).toBeFalsy();
expect(template.querySelector('#documentation_link')).toBeFalsy();
}); });
it('#isSearchAllowed() return if search link has to be displayed', () => { it('should not display the dropdown menu if authentication not allowed', () => {
component.instance = { component.instance = {
name: 'toto', name: 'toto',
label: 'Toto', label: 'Toto',
...@@ -91,33 +72,53 @@ describe('[Core] Component: NavComponent', () => { ...@@ -91,33 +72,53 @@ describe('[Core] Component: NavComponent', () => {
nb_dataset_families: 1, nb_dataset_families: 1,
nb_datasets: 1, nb_datasets: 1,
config: { config: {
search: true, authentication: {
allowed: false
},
search: {
allowed: false
},
search_multiple: { search_multiple: {
allowed: false, allowed: false,
all_datasets_selected: false all_datasets_selected: false
}, },
documentation: false documentation: {
allowed: false
}
} }
}; };
expect(component.isSearchAllowed()).toBeTruthy(); component.isAuthenticated = true;
component.instance = { fixture.detectChanges();
name: 'toto', const template = fixture.nativeElement;
label: 'Toto', expect(template.querySelector('#dropdown-menu')).toBeFalsy();
client_url: '',
nb_dataset_families: 1,
nb_datasets: 1,
config: {
search: false,
search_multiple: {
allowed: false,
all_datasets_selected: false
},
documentation: false
} };
expect(component.isSearchAllowed()).toBeFalsy();
}); });
it('#isSearchMultipleAllowed() return if search multiple link has to be displayed', () => { it('should not display the dropdown menu if no user logged in', () => {
component.instance = INSTANCE;
component.isAuthenticated = false;
fixture.detectChanges();
const template = fixture.nativeElement;
expect(template.querySelector('#dropdown-menu')).toBeFalsy();
});
it('should display the dropdown menu if authentication allowed and user logged in', () => {
component.instance = INSTANCE;
component.isAuthenticated = true;
fixture.detectChanges();
const template = fixture.nativeElement;
expect(template.querySelector('#dropdown-menu')).toBeTruthy();
});
it('should display search, search multiple and documentation links if instance config allows it', () => {
component.instance = INSTANCE;
fixture.detectChanges();
const template = fixture.nativeElement;
expect(template.querySelector('#search_link')).toBeTruthy();
expect(template.querySelector('#search_multiple_link')).toBeTruthy();
expect(template.querySelector('#documentation_link')).toBeNull();
});
it('should not display search, search multiple and documentation links if instance config don\'t allows it', () => {
component.instance = { component.instance = {
name: 'toto', name: 'toto',
label: 'Toto', label: 'Toto',
...@@ -125,34 +126,28 @@ describe('[Core] Component: NavComponent', () => { ...@@ -125,34 +126,28 @@ describe('[Core] Component: NavComponent', () => {
nb_dataset_families: 1, nb_dataset_families: 1,
nb_datasets: 1, nb_datasets: 1,
config: { config: {
search: true, authentication: {
search_multiple: { allowed: false
allowed: true, },
all_datasets_selected: false search: {
allowed: false
}, },
documentation: false
}
};
expect(component.isSearchMultipleAllowed()).toBeTruthy();
component.instance = {
name: 'toto',
label: 'Toto',
client_url: '',
nb_dataset_families: 1,
nb_datasets: 1,
config: {
search: true,
search_multiple: { search_multiple: {
allowed: false, allowed: false,
all_datasets_selected: false all_datasets_selected: false
}, },
documentation: false documentation: {
} allowed: false
}; }
expect(component.isSearchMultipleAllowed()).toBeFalsy(); } };
fixture.detectChanges();
const template = fixture.nativeElement;
expect(template.querySelector('#search_link')).toBeFalsy();
expect(template.querySelector('#search_multiple_link')).toBeFalsy();
expect(template.querySelector('#documentation_link')).toBeFalsy();
}); });
it('#isDocumentationAllowed() return if documentation link has to be displayed', () => { it('#getConfig() return if the given kay is allowed for the given instance configuration propriety', () => {
component.instance = { component.instance = {
name: 'toto', name: 'toto',
label: 'Toto', label: 'Toto',
...@@ -160,30 +155,23 @@ describe('[Core] Component: NavComponent', () => { ...@@ -160,30 +155,23 @@ describe('[Core] Component: NavComponent', () => {
nb_dataset_families: 1, nb_dataset_families: 1,
nb_datasets: 1, nb_datasets: 1,
config: { config: {
search: true, authentication: {
search_multiple: { allowed: false
allowed: true, },
all_datasets_selected: false search: {
allowed: true
}, },
documentation: true
}
};
expect(component.isDocumentationAllowed()).toBeTruthy();
component.instance = {
name: 'toto',
label: 'Toto',
client_url: '',
nb_dataset_families: 1,
nb_datasets: 1,
config: {
search: true,
search_multiple: { search_multiple: {
allowed: true, allowed: false,
all_datasets_selected: false all_datasets_selected: false
}, },
documentation: false documentation: {
allowed: false
}
} }
}; };
expect(component.isDocumentationAllowed()).toBeFalsy(); expect(component.getConfig('search', 'allowed')).toBeTruthy();
expect(component.getConfig('search_multiple', 'allowed')).toBeFalsy();
expect(component.getConfig('documentation', 'allowed')).toBeFalsy();
}); });
}); });
...@@ -34,65 +34,17 @@ export class NavComponent { ...@@ -34,65 +34,17 @@ export class NavComponent {
baseHref: string = environment.baseHref; baseHref: string = environment.baseHref;
/** /**
* Checks if search link is allowed. * Checks if given key for the given configuration propriety is allowed.
* *
* @return boolean * @param {string} prop - The configuration propriety.
*/ * @param {string} key - The key in configuration propriety.
isSearchAllowed(): boolean {
if (this.instance && this.instance.config.search) {
return this.instance.config.search;
}
return false;
}
/**
* Checks if search multiple link is allowed.
*
* @return boolean
*/
isSearchMultipleAllowed(): boolean {
if (this.instance && this.instance.config.search_multiple) {
return this.instance.config.search_multiple.allowed;
}
return false;
}
/**
* Checks if documentation link is allowed.
* *
* @return boolean * @return boolean
*/ */
isDocumentationAllowed(): boolean { getConfig(prop: string, key: string): boolean {
if (this.instance && this.instance.config.documentation) { if (this.instance && this.instance.config[prop] && this.instance.config[prop][key]) {
return this.instance.config.documentation; return this.instance.config[prop][key];
} }
return false; return false;
} }