mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Merge pull request #2651 from alexandrevryghem/theme-fixes_contribute-main
Fixed ItemSearchResultListElementComponent not fully themable
This commit is contained in:
@@ -1,7 +1,4 @@
|
|||||||
import {
|
import { ChangeDetectionStrategy } from '@angular/core';
|
||||||
ChangeDetectionStrategy,
|
|
||||||
NO_ERRORS_SCHEMA,
|
|
||||||
} from '@angular/core';
|
|
||||||
import {
|
import {
|
||||||
ComponentFixture,
|
ComponentFixture,
|
||||||
fakeAsync,
|
fakeAsync,
|
||||||
@@ -11,29 +8,31 @@ import {
|
|||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { provideMockStore } from '@ngrx/store/testing';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { of } from 'rxjs';
|
|
||||||
import { AuthRequestService } from 'src/app/core/auth/auth-request.service';
|
|
||||||
import { CookieService } from 'src/app/core/services/cookie.service';
|
|
||||||
import { HardRedirectService } from 'src/app/core/services/hard-redirect.service';
|
|
||||||
import { XSRFService } from 'src/app/core/xsrf/xsrf.service';
|
|
||||||
import { CookieServiceMock } from 'src/app/shared/mocks/cookie.service.mock';
|
|
||||||
import { getMockThemeService } from 'src/app/shared/mocks/theme-service.mock';
|
|
||||||
import { AuthRequestServiceStub } from 'src/app/shared/testing/auth-request-service.stub';
|
|
||||||
|
|
||||||
import {
|
import { APP_CONFIG } from '../../../../../config/app-config.interface';
|
||||||
APP_CONFIG,
|
import { environment } from '../../../../../environments/environment.test';
|
||||||
APP_DATA_SERVICES_MAP,
|
import { AuthService } from '../../../../core/auth/auth.service';
|
||||||
} from '../../../../../config/app-config.interface';
|
import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service';
|
||||||
import { REQUEST } from '../../../../../express.tokens';
|
import { AuthorizationDataService } from '../../../../core/data/feature-authorization/authorization-data.service';
|
||||||
import { Context } from '../../../../core/shared/context.model';
|
import { Context } from '../../../../core/shared/context.model';
|
||||||
|
import { FileService } from '../../../../core/shared/file.service';
|
||||||
import { GenericConstructor } from '../../../../core/shared/generic-constructor';
|
import { GenericConstructor } from '../../../../core/shared/generic-constructor';
|
||||||
import { ListableModule } from '../../../../core/shared/listable.module';
|
import { ListableModule } from '../../../../core/shared/listable.module';
|
||||||
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
||||||
|
import { XSRFService } from '../../../../core/xsrf/xsrf.service';
|
||||||
import { DynamicComponentLoaderDirective } from '../../../abstract-component-loader/dynamic-component-loader.directive';
|
import { DynamicComponentLoaderDirective } from '../../../abstract-component-loader/dynamic-component-loader.directive';
|
||||||
|
import { DSONameServiceMock } from '../../../mocks/dso-name.service.mock';
|
||||||
|
import { getMockThemeService } from '../../../mocks/theme-service.mock';
|
||||||
import { ItemListElementComponent } from '../../../object-list/item-list-element/item-types/item/item-list-element.component';
|
import { ItemListElementComponent } from '../../../object-list/item-list-element/item-types/item/item-list-element.component';
|
||||||
|
import { SearchResultListElementComponent } from '../../../object-list/search-result-list-element/search-result-list-element.component';
|
||||||
|
import { ActivatedRouteStub } from '../../../testing/active-router.stub';
|
||||||
|
import { AuthServiceStub } from '../../../testing/auth-service.stub';
|
||||||
|
import { AuthorizationDataServiceStub } from '../../../testing/authorization-service.stub';
|
||||||
|
import { FileServiceStub } from '../../../testing/file-service.stub';
|
||||||
|
import { TruncatableServiceStub } from '../../../testing/truncatable-service.stub';
|
||||||
import { ThemeService } from '../../../theme-support/theme.service';
|
import { ThemeService } from '../../../theme-support/theme.service';
|
||||||
|
import { TruncatableService } from '../../../truncatable/truncatable.service';
|
||||||
import { ListableObject } from '../listable-object.model';
|
import { ListableObject } from '../listable-object.model';
|
||||||
import { ListableObjectComponentLoaderComponent } from './listable-object-component-loader.component';
|
import { ListableObjectComponentLoaderComponent } from './listable-object-component-loader.component';
|
||||||
|
|
||||||
@@ -57,8 +56,22 @@ describe('ListableObjectComponentLoaderComponent', () => {
|
|||||||
let comp: ListableObjectComponentLoaderComponent;
|
let comp: ListableObjectComponentLoaderComponent;
|
||||||
let fixture: ComponentFixture<ListableObjectComponentLoaderComponent>;
|
let fixture: ComponentFixture<ListableObjectComponentLoaderComponent>;
|
||||||
|
|
||||||
|
let activatedRoute: ActivatedRouteStub;
|
||||||
|
let authService: AuthServiceStub;
|
||||||
|
let authorizationService: AuthorizationDataServiceStub;
|
||||||
|
let fileService: FileServiceStub;
|
||||||
|
let themeService: ThemeService;
|
||||||
|
let truncatableService: TruncatableServiceStub;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
activatedRoute = new ActivatedRouteStub();
|
||||||
|
authService = new AuthServiceStub();
|
||||||
|
authorizationService = new AuthorizationDataServiceStub();
|
||||||
|
fileService = new FileServiceStub();
|
||||||
|
themeService = getMockThemeService();
|
||||||
|
truncatableService = new TruncatableServiceStub();
|
||||||
|
|
||||||
|
void TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule.forRoot(),
|
TranslateModule.forRoot(),
|
||||||
ListableObjectComponentLoaderComponent,
|
ListableObjectComponentLoaderComponent,
|
||||||
@@ -66,21 +79,16 @@ describe('ListableObjectComponentLoaderComponent', () => {
|
|||||||
ItemListElementComponent,
|
ItemListElementComponent,
|
||||||
DynamicComponentLoaderDirective,
|
DynamicComponentLoaderDirective,
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA],
|
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: HardRedirectService, useValue: jasmine.createSpyObj('hardRedirectService', ['redirect']) },
|
{ provide: APP_CONFIG, useValue: environment },
|
||||||
{ provide: AuthRequestService, useValue: new AuthRequestServiceStub() },
|
{ provide: ActivatedRoute, useValue: activatedRoute },
|
||||||
{ provide: CookieService, useValue: new CookieServiceMock() },
|
{ provide: AuthService, useValue: authService },
|
||||||
|
{ provide: AuthorizationDataService, useValue: authorizationService },
|
||||||
|
{ provide: DSONameService, useValue: new DSONameServiceMock() },
|
||||||
|
{ provide: FileService, useValue: fileService },
|
||||||
|
{ provide: ThemeService, useValue: themeService },
|
||||||
|
{ provide: TruncatableService, useValue: truncatableService },
|
||||||
{ provide: XSRFService, useValue: {} },
|
{ provide: XSRFService, useValue: {} },
|
||||||
{ provide: REQUEST, useValue: {} },
|
|
||||||
{
|
|
||||||
provide: ActivatedRoute,
|
|
||||||
useValue: { data: of({ dso: { payload: {} } }), params: of({}) },
|
|
||||||
},
|
|
||||||
provideMockStore({}),
|
|
||||||
{ provide: ThemeService, useValue: getMockThemeService('dspace') },
|
|
||||||
{ provide: APP_CONFIG, useValue: { browseBy: { showThumbnails: true } } },
|
|
||||||
{ provide: APP_DATA_SERVICES_MAP, useValue: {} },
|
|
||||||
],
|
],
|
||||||
}).overrideComponent(ListableObjectComponentLoaderComponent, {
|
}).overrideComponent(ListableObjectComponentLoaderComponent, {
|
||||||
set: {
|
set: {
|
||||||
@@ -95,7 +103,7 @@ describe('ListableObjectComponentLoaderComponent', () => {
|
|||||||
comp.object = new TestType();
|
comp.object = new TestType();
|
||||||
comp.viewMode = testViewMode;
|
comp.viewMode = testViewMode;
|
||||||
comp.context = testContext;
|
comp.context = testContext;
|
||||||
spyOn(comp, 'getComponent').and.returnValue(ItemListElementComponent as any);
|
spyOn(comp, 'getComponent').and.returnValue(SearchResultListElementComponent as any);
|
||||||
spyOn(comp as any, 'connectInputsAndOutputs').and.callThrough();
|
spyOn(comp as any, 'connectInputsAndOutputs').and.callThrough();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
@@ -119,7 +127,7 @@ describe('ListableObjectComponentLoaderComponent', () => {
|
|||||||
spyOn(comp, 'instantiateComponent').and.returnValue(null);
|
spyOn(comp, 'instantiateComponent').and.returnValue(null);
|
||||||
spyOn(comp.contentChange, 'emit').and.returnValue(null);
|
spyOn(comp.contentChange, 'emit').and.returnValue(null);
|
||||||
|
|
||||||
listableComponent = fixture.debugElement.query(By.css('ds-item-list-element')).componentInstance;
|
listableComponent = fixture.debugElement.query(By.css('ds-search-result-list-element')).componentInstance;
|
||||||
reloadedObject = 'object';
|
reloadedObject = 'object';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1 +1,5 @@
|
|||||||
<ds-item-search-result-list-element [showLabel]="showLabel" [object]="{ indexableObject: object, hitHighlights: {} }" [linkType]="linkType"></ds-item-search-result-list-element>
|
<ds-listable-object-component-loader
|
||||||
|
[object]="itemSearchResult"
|
||||||
|
[viewMode]="viewMode"
|
||||||
|
[linkType]="linkType">
|
||||||
|
</ds-listable-object-component-loader>
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
|
import { ChangeDetectionStrategy } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ComponentFixture,
|
||||||
NO_ERRORS_SCHEMA,
|
|
||||||
} from '@angular/core';
|
|
||||||
import {
|
|
||||||
TestBed,
|
TestBed,
|
||||||
waitForAsync,
|
waitForAsync,
|
||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
@@ -10,20 +8,21 @@ import { By } from '@angular/platform-browser';
|
|||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
import { APP_CONFIG } from 'src/config/app-config.interface';
|
|
||||||
import { environment } from 'src/environments/environment.test';
|
|
||||||
|
|
||||||
|
import { APP_CONFIG } from '../../../../../../config/app-config.interface';
|
||||||
|
import { environment } from '../../../../../../environments/environment.test';
|
||||||
import { AuthService } from '../../../../../core/auth/auth.service';
|
import { AuthService } from '../../../../../core/auth/auth.service';
|
||||||
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
|
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
|
||||||
import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service';
|
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 { XSRFService } from '../../../../../core/xsrf/xsrf.service';
|
import { XSRFService } from '../../../../../core/xsrf/xsrf.service';
|
||||||
import { AuthServiceMock } from '../../../../../shared/mocks/auth.service.mock';
|
|
||||||
import { mockTruncatableService } from '../../../../../shared/mocks/mock-trucatable.service';
|
|
||||||
import { getMockThemeService } from '../../../../../shared/mocks/theme-service.mock';
|
|
||||||
import { ActivatedRouteStub } from '../../../../../shared/testing/active-router.stub';
|
|
||||||
import { ThemeService } from '../../../../../shared/theme-support/theme.service';
|
|
||||||
import { DSONameServiceMock } from '../../../../mocks/dso-name.service.mock';
|
import { DSONameServiceMock } from '../../../../mocks/dso-name.service.mock';
|
||||||
|
import { getMockThemeService } from '../../../../mocks/theme-service.mock';
|
||||||
|
import { ActivatedRouteStub } from '../../../../testing/active-router.stub';
|
||||||
|
import { AuthServiceStub } from '../../../../testing/auth-service.stub';
|
||||||
|
import { AuthorizationDataServiceStub } from '../../../../testing/authorization-service.stub';
|
||||||
|
import { TruncatableServiceStub } from '../../../../testing/truncatable-service.stub';
|
||||||
|
import { ThemeService } from '../../../../theme-support/theme.service';
|
||||||
import { TruncatableService } from '../../../../truncatable/truncatable.service';
|
import { TruncatableService } from '../../../../truncatable/truncatable.service';
|
||||||
import { TruncatePipe } from '../../../../utils/truncate.pipe';
|
import { TruncatePipe } from '../../../../utils/truncate.pipe';
|
||||||
import { ItemListElementComponent } from './item-list-element.component';
|
import { ItemListElementComponent } from './item-list-element.component';
|
||||||
@@ -65,23 +64,39 @@ const mockItem: Item = Object.assign(new Item(), {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('ItemListElementComponent', () => {
|
describe('ItemListElementComponent', () => {
|
||||||
let comp;
|
let comp: ItemListElementComponent;
|
||||||
let fixture;
|
let fixture: ComponentFixture<ItemListElementComponent>;
|
||||||
|
|
||||||
|
let activatedRoute: ActivatedRouteStub;
|
||||||
|
let authService: AuthServiceStub;
|
||||||
|
let authorizationService: AuthorizationDataServiceStub;
|
||||||
|
let themeService: ThemeService;
|
||||||
|
let truncatableService: TruncatableServiceStub;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
activatedRoute = new ActivatedRouteStub();
|
||||||
imports: [TruncatePipe, TranslateModule.forRoot(), ItemListElementComponent],
|
authService = new AuthServiceStub();
|
||||||
|
authorizationService = new AuthorizationDataServiceStub();
|
||||||
|
themeService = getMockThemeService();
|
||||||
|
truncatableService = new TruncatableServiceStub();
|
||||||
|
|
||||||
|
void TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
TranslateModule.forRoot(),
|
||||||
|
TruncatePipe,
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: DSONameService, useValue: new DSONameServiceMock() },
|
{ provide: DSONameService, useValue: new DSONameServiceMock() },
|
||||||
{ provide: TruncatableService, useValue: mockTruncatableService },
|
|
||||||
{ provide: APP_CONFIG, useValue: environment },
|
{ provide: APP_CONFIG, useValue: environment },
|
||||||
{ provide: ThemeService, useValue: getMockThemeService() },
|
{ provide: ActivatedRoute, useValue: activatedRoute },
|
||||||
{ provide: ActivatedRoute, useValue: new ActivatedRouteStub() },
|
{ provide: AuthService, useValue: authService },
|
||||||
{ provide: AuthService, useValue: new AuthServiceMock() },
|
{ provide: AuthorizationDataService, useValue: authorizationService },
|
||||||
{ provide: AuthorizationDataService, useValue: {} },
|
{ provide: ThemeService, useValue: themeService },
|
||||||
|
{ provide: TruncatableService, useValue: truncatableService },
|
||||||
{ provide: XSRFService, useValue: {} },
|
{ provide: XSRFService, useValue: {} },
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA],
|
|
||||||
}).overrideComponent(ItemListElementComponent, {
|
}).overrideComponent(ItemListElementComponent, {
|
||||||
set: { changeDetection: ChangeDetectionStrategy.Default },
|
set: { changeDetection: ChangeDetectionStrategy.Default },
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
@@ -95,6 +110,7 @@ describe('ItemListElementComponent', () => {
|
|||||||
describe(`when the publication is rendered`, () => {
|
describe(`when the publication is rendered`, () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
comp.object = mockItem;
|
comp.object = mockItem;
|
||||||
|
comp.ngOnChanges();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,10 +1,15 @@
|
|||||||
import { Component } from '@angular/core';
|
import {
|
||||||
|
Component,
|
||||||
|
OnChanges,
|
||||||
|
} from '@angular/core';
|
||||||
|
|
||||||
import { Item } from '../../../../../core/shared/item.model';
|
import { Item } from '../../../../../core/shared/item.model';
|
||||||
import { ViewMode } from '../../../../../core/shared/view-mode.model';
|
import { ViewMode } from '../../../../../core/shared/view-mode.model';
|
||||||
|
import { hasValue } from '../../../../empty.util';
|
||||||
|
import { ItemSearchResult } from '../../../../object-collection/shared/item-search-result.model';
|
||||||
import { listableObjectComponent } from '../../../../object-collection/shared/listable-object/listable-object.decorator';
|
import { listableObjectComponent } from '../../../../object-collection/shared/listable-object/listable-object.decorator';
|
||||||
|
import { ListableObjectComponentLoaderComponent } from '../../../../object-collection/shared/listable-object/listable-object-component-loader.component';
|
||||||
import { AbstractListableElementComponent } from '../../../../object-collection/shared/object-collection-element/abstract-listable-element.component';
|
import { AbstractListableElementComponent } from '../../../../object-collection/shared/object-collection-element/abstract-listable-element.component';
|
||||||
import { ItemSearchResultListElementComponent } from '../../../search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component';
|
|
||||||
|
|
||||||
@listableObjectComponent('Publication', ViewMode.ListElement)
|
@listableObjectComponent('Publication', ViewMode.ListElement)
|
||||||
@listableObjectComponent(Item, ViewMode.ListElement)
|
@listableObjectComponent(Item, ViewMode.ListElement)
|
||||||
@@ -13,10 +18,23 @@ import { ItemSearchResultListElementComponent } from '../../../search-result-lis
|
|||||||
styleUrls: ['./item-list-element.component.scss'],
|
styleUrls: ['./item-list-element.component.scss'],
|
||||||
templateUrl: './item-list-element.component.html',
|
templateUrl: './item-list-element.component.html',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [ItemSearchResultListElementComponent],
|
imports: [
|
||||||
|
ListableObjectComponentLoaderComponent,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
/**
|
/**
|
||||||
* The component for displaying a list element for an item of the type Publication
|
* The component for displaying a list element for an item of the type Publication
|
||||||
*/
|
*/
|
||||||
export class ItemListElementComponent extends AbstractListableElementComponent<Item> {
|
export class ItemListElementComponent extends AbstractListableElementComponent<Item> implements OnChanges {
|
||||||
|
|
||||||
|
itemSearchResult: ItemSearchResult;
|
||||||
|
|
||||||
|
ngOnChanges(): void {
|
||||||
|
if (hasValue(this.object)) {
|
||||||
|
this.itemSearchResult = Object.assign(new ItemSearchResult(), {
|
||||||
|
indexableObject: this.object,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
24
src/app/shared/testing/truncatable-service.stub.ts
Normal file
24
src/app/shared/testing/truncatable-service.stub.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import {
|
||||||
|
Observable,
|
||||||
|
of as observableOf,
|
||||||
|
} from 'rxjs';
|
||||||
|
|
||||||
|
export class TruncatableServiceStub {
|
||||||
|
|
||||||
|
isCollapsed(_id: string): Observable<boolean> {
|
||||||
|
return observableOf(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-empty, @typescript-eslint/no-empty-function
|
||||||
|
public toggle(_id: string): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-empty, @typescript-eslint/no-empty-function
|
||||||
|
public collapse(_id: string): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-empty, @typescript-eslint/no-empty-function
|
||||||
|
public expand(_id: string): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user