mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Fix tests pt. 1
This commit is contained in:
@@ -79,17 +79,14 @@ describe('ExpandableAdminSidebarSectionComponent', () => {
|
|||||||
describe('when there are no subsections', () => {
|
describe('when there are no subsections', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [NoopAnimationsModule, TranslateModule.forRoot()],
|
imports: [NoopAnimationsModule, TranslateModule.forRoot(), ExpandableAdminSidebarSectionComponent, TestComponent],
|
||||||
declarations: [ExpandableAdminSidebarSectionComponent, TestComponent],
|
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: 'sectionDataProvider', useValue: { icon: iconString, model: {} } },
|
{ provide: 'sectionDataProvider', useValue: { icon: iconString, model: {} } },
|
||||||
{ provide: MenuService, useValue: menuService },
|
{ provide: MenuService, useValue: menuService },
|
||||||
{ provide: CSSVariableService, useClass: CSSVariableServiceStub },
|
{ provide: CSSVariableService, useClass: CSSVariableServiceStub },
|
||||||
{ provide: Router, useValue: new RouterStub() },
|
{ provide: Router, useValue: new RouterStub() },
|
||||||
],
|
],
|
||||||
}).overrideComponent(ExpandableAdminSidebarSectionComponent, {
|
}).compileComponents();
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@@ -74,8 +74,7 @@ describe('DsoEditMenuExpandableSectionComponent', () => {
|
|||||||
describe('when there are no subsections', () => {
|
describe('when there are no subsections', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot()],
|
imports: [TranslateModule.forRoot(), DsoEditMenuExpandableSectionComponent, TestComponent],
|
||||||
declarations: [DsoEditMenuExpandableSectionComponent, TestComponent],
|
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: 'sectionDataProvider', useValue: dummySection },
|
{ provide: 'sectionDataProvider', useValue: dummySection },
|
||||||
{ provide: MenuService, useValue: menuService },
|
{ provide: MenuService, useValue: menuService },
|
||||||
|
@@ -23,6 +23,7 @@ import { AbstractMenuSectionComponent } from './abstract-menu-section.component'
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-some-menu-section',
|
selector: 'ds-some-menu-section',
|
||||||
template: '',
|
template: '',
|
||||||
|
standalone: true,
|
||||||
})
|
})
|
||||||
class SomeMenuSectionComponent extends AbstractMenuSectionComponent {
|
class SomeMenuSectionComponent extends AbstractMenuSectionComponent {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -47,8 +48,7 @@ describe('MenuSectionComponent', () => {
|
|||||||
active: false,
|
active: false,
|
||||||
} as any;
|
} as any;
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot(), NoopAnimationsModule, SomeMenuSectionComponent],
|
imports: [TranslateModule.forRoot(), NoopAnimationsModule, SomeMenuSectionComponent, AbstractMenuSectionComponent],
|
||||||
declarations: [AbstractMenuSectionComponent],
|
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: Injector, useValue: {} },
|
{ provide: Injector, useValue: {} },
|
||||||
{ provide: MenuService, useClass: MenuServiceStub },
|
{ provide: MenuService, useClass: MenuServiceStub },
|
||||||
|
@@ -54,6 +54,7 @@ const mockMenuID = 'mock-menuID' as MenuID;
|
|||||||
// eslint-disable-next-line @angular-eslint/component-selector
|
// eslint-disable-next-line @angular-eslint/component-selector
|
||||||
selector: '',
|
selector: '',
|
||||||
template: '',
|
template: '',
|
||||||
|
standalone: true,
|
||||||
})
|
})
|
||||||
@rendersSectionForMenu(mockMenuID, true)
|
@rendersSectionForMenu(mockMenuID, true)
|
||||||
class TestExpandableMenuComponent {
|
class TestExpandableMenuComponent {
|
||||||
@@ -63,6 +64,7 @@ class TestExpandableMenuComponent {
|
|||||||
// eslint-disable-next-line @angular-eslint/component-selector
|
// eslint-disable-next-line @angular-eslint/component-selector
|
||||||
selector: '',
|
selector: '',
|
||||||
template: '',
|
template: '',
|
||||||
|
standalone: true,
|
||||||
})
|
})
|
||||||
@rendersSectionForMenu(mockMenuID, false)
|
@rendersSectionForMenu(mockMenuID, false)
|
||||||
class TestMenuComponent {
|
class TestMenuComponent {
|
||||||
@@ -85,8 +87,6 @@ describe('MenuComponent', () => {
|
|||||||
visible: true,
|
visible: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockMenuID = 'mock-menuID' as MenuID;
|
|
||||||
|
|
||||||
const mockStatisticSection = { 'id': 'statistics_site', 'active': true, 'visible': true, 'index': 2, 'type': 'statistics', 'model': { 'type': 1, 'text': 'menu.section.statistics', 'link': 'statistics' } };
|
const mockStatisticSection = { 'id': 'statistics_site', 'active': true, 'visible': true, 'index': 2, 'type': 'statistics', 'model': { 'type': 1, 'text': 'menu.section.statistics', 'link': 'statistics' } };
|
||||||
|
|
||||||
let authorizationService: AuthorizationDataService;
|
let authorizationService: AuthorizationDataService;
|
||||||
@@ -144,7 +144,7 @@ describe('MenuComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot(), NoopAnimationsModule, RouterTestingModule, MenuComponent, StoreModule.forRoot(authReducer, storeModuleConfig)],
|
imports: [TranslateModule.forRoot(), NoopAnimationsModule, RouterTestingModule, MenuComponent, StoreModule.forRoot(authReducer, storeModuleConfig), TestExpandableMenuComponent, TestMenuComponent],
|
||||||
providers: [
|
providers: [
|
||||||
Injector,
|
Injector,
|
||||||
{ provide: ThemeService, useValue: getMockThemeService() },
|
{ provide: ThemeService, useValue: getMockThemeService() },
|
||||||
@@ -152,8 +152,6 @@ describe('MenuComponent', () => {
|
|||||||
provideMockStore({ initialState }),
|
provideMockStore({ initialState }),
|
||||||
{ provide: AuthorizationDataService, useValue: authorizationService },
|
{ provide: AuthorizationDataService, useValue: authorizationService },
|
||||||
{ provide: ActivatedRoute, useValue: routeStub },
|
{ provide: ActivatedRoute, useValue: routeStub },
|
||||||
TestExpandableMenuComponent,
|
|
||||||
TestMenuComponent,
|
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA],
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
}).overrideComponent(MenuComponent, {
|
}).overrideComponent(MenuComponent, {
|
||||||
@@ -272,35 +270,4 @@ describe('MenuComponent', () => {
|
|||||||
expect(menuService.collapseMenuPreview).toHaveBeenCalledWith(comp.menuID);
|
expect(menuService.collapseMenuPreview).toHaveBeenCalledWith(comp.menuID);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when unauthorized statistics', () => {
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
(authorizationService as any).isAuthorized.and.returnValue(observableOf(false));
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return observable of empty object', done => {
|
|
||||||
comp.getAuthorizedStatistics(mockStatisticSection).subscribe((res) => {
|
|
||||||
expect(res).toEqual({});
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('get authorized statistics', () => {
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
(authorizationService as any).isAuthorized.and.returnValue(observableOf(true));
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return observable of statistics section menu', done => {
|
|
||||||
comp.getAuthorizedStatistics(mockStatisticSection).subscribe((res) => {
|
|
||||||
expect(res).toEqual(mockStatisticSection);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -9,29 +9,26 @@ import { ActivatedRoute } from '@angular/router';
|
|||||||
import {
|
import {
|
||||||
BehaviorSubject,
|
BehaviorSubject,
|
||||||
Observable,
|
Observable,
|
||||||
of as observableOf,
|
|
||||||
Subscription,
|
Subscription,
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
import {
|
import {
|
||||||
distinctUntilChanged,
|
distinctUntilChanged,
|
||||||
map,
|
map,
|
||||||
mergeMap,
|
|
||||||
switchMap,
|
switchMap,
|
||||||
} from 'rxjs/operators';
|
} from 'rxjs/operators';
|
||||||
|
|
||||||
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
|
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
|
||||||
import { FeatureID } from '../../core/data/feature-authorization/feature-id';
|
|
||||||
import { GenericConstructor } from '../../core/shared/generic-constructor';
|
import { GenericConstructor } from '../../core/shared/generic-constructor';
|
||||||
import {
|
import {
|
||||||
hasValue,
|
hasValue,
|
||||||
isNotEmptyOperator,
|
isNotEmptyOperator,
|
||||||
} from '../empty.util';
|
} from '../empty.util';
|
||||||
import { ThemeService } from '../theme-support/theme.service';
|
import { ThemeService } from '../theme-support/theme.service';
|
||||||
import { MenuService } from './menu.service';
|
|
||||||
import { MenuID } from './menu-id.model';
|
import { MenuID } from './menu-id.model';
|
||||||
import { getComponentForMenu } from './menu-section.decorator';
|
import { getComponentForMenu } from './menu-section.decorator';
|
||||||
import { MenuSection } from './menu-section.model';
|
import { MenuSection } from './menu-section.model';
|
||||||
import { AbstractMenuSectionComponent } from './menu-section/abstract-menu-section.component';
|
import { AbstractMenuSectionComponent } from './menu-section/abstract-menu-section.component';
|
||||||
|
import { MenuService } from './menu.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A basic implementation of a MenuComponent
|
* A basic implementation of a MenuComponent
|
||||||
@@ -93,8 +90,12 @@ export class MenuComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
private activatedRouteLastChild: ActivatedRoute;
|
private activatedRouteLastChild: ActivatedRoute;
|
||||||
|
|
||||||
constructor(protected menuService: MenuService, protected injector: Injector, public authorizationService: AuthorizationDataService,
|
constructor(
|
||||||
public route: ActivatedRoute, protected themeService: ThemeService,
|
protected menuService: MenuService,
|
||||||
|
protected injector: Injector,
|
||||||
|
public authorizationService: AuthorizationDataService,
|
||||||
|
public route: ActivatedRoute,
|
||||||
|
protected themeService: ThemeService,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,12 +114,6 @@ export class MenuComponent implements OnInit, OnDestroy {
|
|||||||
// if you return an array from a switchMap it will emit each element as a separate event.
|
// if you return an array from a switchMap it will emit each element as a separate event.
|
||||||
// So this switchMap is equivalent to a subscribe with a forEach inside
|
// So this switchMap is equivalent to a subscribe with a forEach inside
|
||||||
switchMap((sections: MenuSection[]) => sections),
|
switchMap((sections: MenuSection[]) => sections),
|
||||||
mergeMap((section: MenuSection) => {
|
|
||||||
if (section.id.includes('statistics')) {
|
|
||||||
return this.getAuthorizedStatistics(section);
|
|
||||||
}
|
|
||||||
return observableOf(section);
|
|
||||||
}),
|
|
||||||
isNotEmptyOperator(),
|
isNotEmptyOperator(),
|
||||||
switchMap((section: MenuSection) => this.getSectionComponent(section).pipe(
|
switchMap((section: MenuSection) => this.getSectionComponent(section).pipe(
|
||||||
map((component: GenericConstructor<AbstractMenuSectionComponent>) => ({ section, component })),
|
map((component: GenericConstructor<AbstractMenuSectionComponent>) => ({ section, component })),
|
||||||
@@ -146,32 +141,6 @@ export class MenuComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get section of statistics after checking authorization
|
|
||||||
*/
|
|
||||||
getAuthorizedStatistics(section) {
|
|
||||||
return this.activatedRouteLastChild.data.pipe(
|
|
||||||
switchMap((data) => {
|
|
||||||
return this.authorizationService.isAuthorized(FeatureID.CanViewUsageStatistics, this.getObjectUrl(data)).pipe(
|
|
||||||
map((canViewUsageStatistics: boolean) => {
|
|
||||||
if (!canViewUsageStatistics) {
|
|
||||||
return {};
|
|
||||||
} else {
|
|
||||||
return section;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get statistics route dso data
|
|
||||||
*/
|
|
||||||
getObjectUrl(data) {
|
|
||||||
const object = data.site ? data.site : data.dso?.payload;
|
|
||||||
return object?._links?.self?.href;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collapse this menu when it's currently expanded, expand it when its currently collapsed
|
* Collapse this menu when it's currently expanded, expand it when its currently collapsed
|
||||||
* @param {Event} event The user event that triggered this method
|
* @param {Event} event The user event that triggered this method
|
||||||
|
@@ -51,7 +51,7 @@ describe('BrowseMenuProvider', () => {
|
|||||||
|
|
||||||
|
|
||||||
let provider: BrowseMenuProvider;
|
let provider: BrowseMenuProvider;
|
||||||
let browseServiceStub = new BrowseServiceStub();
|
let browseServiceStub = BrowseServiceStub;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(browseServiceStub, 'getBrowseDefinitions').and.returnValue(
|
spyOn(browseServiceStub, 'getBrowseDefinitions').and.returnValue(
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
|
import { inject } from '@angular/core';
|
||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||||
|
|
||||||
import { Item } from '../../../core/shared/item.model';
|
import { Item } from '../../../core/shared/item.model';
|
||||||
import { ITEM } from '../../../core/shared/item.resource-type';
|
import { ITEM } from '../../../core/shared/item.resource-type';
|
||||||
@@ -34,6 +37,18 @@ describe('StatisticsMenuProvider', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const expectedSectionsForItemInvisible: PartialMenuSection[] = [
|
||||||
|
{
|
||||||
|
visible: false,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.statistics',
|
||||||
|
link: `statistics/items/test-item-uuid`,
|
||||||
|
},
|
||||||
|
icon: 'chart-line',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
let provider: StatisticsMenuProvider;
|
let provider: StatisticsMenuProvider;
|
||||||
|
|
||||||
const item: Item = Object.assign(new Item(), {
|
const item: Item = Object.assign(new Item(), {
|
||||||
@@ -57,13 +72,18 @@ describe('StatisticsMenuProvider', () => {
|
|||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
let authorizationService: AuthorizationDataService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
authorizationService = jasmine.createSpyObj('authorizationService', {
|
||||||
|
isAuthorized: observableOf(true),
|
||||||
|
});
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot()],
|
imports: [TranslateModule.forRoot()],
|
||||||
providers: [
|
providers: [
|
||||||
StatisticsMenuProvider,
|
StatisticsMenuProvider,
|
||||||
|
{ provide: AuthorizationDataService, useValue: authorizationService },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
provider = TestBed.inject(StatisticsMenuProvider);
|
provider = TestBed.inject(StatisticsMenuProvider);
|
||||||
@@ -86,6 +106,13 @@ describe('StatisticsMenuProvider', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('should not return anything if not authorized to view statistics', (done) => {
|
||||||
|
(TestBed.inject(AuthorizationDataService) as any).isAuthorized.and.returnValue(observableOf(false));
|
||||||
|
provider.getSectionsForContext(item).subscribe((sections) => {
|
||||||
|
expect(sections).toEqual(expectedSectionsForItemInvisible);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getRouteContext', () => {
|
describe('getRouteContext', () => {
|
||||||
|
@@ -12,11 +12,15 @@ import {
|
|||||||
RouterStateSnapshot,
|
RouterStateSnapshot,
|
||||||
} from '@angular/router';
|
} from '@angular/router';
|
||||||
import {
|
import {
|
||||||
|
combineLatest,
|
||||||
|
map,
|
||||||
Observable,
|
Observable,
|
||||||
of,
|
of,
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
|
|
||||||
import { getDSORoute } from '../../../app-routing-paths';
|
import { getDSORoute } from '../../../app-routing-paths';
|
||||||
|
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||||
|
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
import {
|
import {
|
||||||
@@ -34,6 +38,11 @@ import { AbstractRouteContextMenuProvider } from './helper-providers/route-conte
|
|||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class StatisticsMenuProvider extends AbstractRouteContextMenuProvider<DSpaceObject> {
|
export class StatisticsMenuProvider extends AbstractRouteContextMenuProvider<DSpaceObject> {
|
||||||
|
constructor(
|
||||||
|
protected authorizationService: AuthorizationDataService,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
public getRouteContext(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<DSpaceObject> {
|
public getRouteContext(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<DSpaceObject> {
|
||||||
let dsoRD: RemoteData<DSpaceObject> = route.data.dso;
|
let dsoRD: RemoteData<DSpaceObject> = route.data.dso;
|
||||||
@@ -51,28 +60,32 @@ export class StatisticsMenuProvider extends AbstractRouteContextMenuProvider<DSp
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getSectionsForContext(dso: DSpaceObject): Observable<PartialMenuSection[]> {
|
public getSectionsForContext(dso: DSpaceObject): Observable<PartialMenuSection[]> {
|
||||||
|
return combineLatest([
|
||||||
|
this.authorizationService.isAuthorized(FeatureID.CanViewUsageStatistics, dso?._links.self.href),
|
||||||
|
]).pipe(
|
||||||
|
map(([authorized]) => {
|
||||||
|
let link = `statistics`;
|
||||||
|
|
||||||
let link = `statistics`;
|
let dsoRoute;
|
||||||
|
if (hasValue(dso)) {
|
||||||
|
dsoRoute = getDSORoute(dso);
|
||||||
|
if (hasValue(dsoRoute)) {
|
||||||
|
link = `statistics${dsoRoute}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let dsoRoute;
|
return [
|
||||||
if (hasValue(dso)) {
|
{
|
||||||
dsoRoute = getDSORoute(dso);
|
visible: authorized,
|
||||||
if (hasValue(dsoRoute)) {
|
model: {
|
||||||
link = `statistics${dsoRoute}`;
|
type: MenuItemType.LINK,
|
||||||
}
|
text: 'menu.section.statistics',
|
||||||
}
|
link,
|
||||||
|
},
|
||||||
return of([
|
icon: 'chart-line',
|
||||||
{
|
},
|
||||||
visible: true,
|
];
|
||||||
model: {
|
}),
|
||||||
type: MenuItemType.LINK,
|
);
|
||||||
text: 'menu.section.statistics',
|
|
||||||
link,
|
|
||||||
},
|
|
||||||
icon: 'chart-line',
|
|
||||||
},
|
|
||||||
] as PartialMenuSection[]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user