mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
113169: Renamed the service in charge of adding metadata head tags to you HTML to HeadTagService & made its methods protected to make it easier to override them
This commit is contained in:
@@ -9,11 +9,11 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { AppComponent } from './app.component';
|
||||
import { HostWindowState } from './shared/search/host-window.reducer';
|
||||
import { HostWindowResizeAction } from './shared/host-window.actions';
|
||||
import { MetadataService } from './core/metadata/metadata.service';
|
||||
import { HeadTagService } from './core/metadata/head-tag.service';
|
||||
|
||||
import { NativeWindowRef, NativeWindowService } from './core/services/window.service';
|
||||
import { TranslateLoaderMock } from './shared/mocks/translate-loader.mock';
|
||||
import { MetadataServiceMock } from './shared/mocks/metadata-service.mock';
|
||||
import { HeadTagServiceMock } from './shared/mocks/head-tag-service.mock';
|
||||
import { AngularticsProviderMock } from './shared/mocks/angulartics-provider.service.mock';
|
||||
import { AuthServiceMock } from './shared/mocks/auth.service.mock';
|
||||
import { AuthService } from './core/auth/auth.service';
|
||||
@@ -71,7 +71,7 @@ describe('App component', () => {
|
||||
declarations: [AppComponent], // declare the test component
|
||||
providers: [
|
||||
{ provide: NativeWindowService, useValue: new NativeWindowRef() },
|
||||
{ provide: MetadataService, useValue: new MetadataServiceMock() },
|
||||
{ provide: HeadTagService, useValue: new HeadTagServiceMock() },
|
||||
{ provide: Angulartics2DSpace, useValue: new AngularticsProviderMock() },
|
||||
{ provide: AuthService, useValue: new AuthServiceMock() },
|
||||
{ provide: Router, useValue: new RouterMock() },
|
||||
|
@@ -3,14 +3,10 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { CommunityDataService } from '../core/data/community-data.service';
|
||||
import { RemoteData } from '../core/data/remote-data';
|
||||
import { Bitstream } from '../core/shared/bitstream.model';
|
||||
|
||||
import { Community } from '../core/shared/community.model';
|
||||
|
||||
import { MetadataService } from '../core/metadata/metadata.service';
|
||||
|
||||
import { fadeInOut } from '../shared/animations/fade';
|
||||
import { hasValue } from '../shared/empty.util';
|
||||
import { getAllSucceededRemoteDataPayload} from '../core/shared/operators';
|
||||
@@ -53,8 +49,6 @@ export class CommunityPageComponent implements OnInit {
|
||||
communityPageRoute$: Observable<string>;
|
||||
|
||||
constructor(
|
||||
private communityDataService: CommunityDataService,
|
||||
private metadata: MetadataService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private authService: AuthService,
|
||||
|
@@ -64,7 +64,7 @@ import { Group } from './eperson/models/group.model';
|
||||
import { JsonPatchOperationsBuilder } from './json-patch/builder/json-patch-operations-builder';
|
||||
import { MetadataField } from './metadata/metadata-field.model';
|
||||
import { MetadataSchema } from './metadata/metadata-schema.model';
|
||||
import { MetadataService } from './metadata/metadata.service';
|
||||
import { HeadTagService } from './metadata/head-tag.service';
|
||||
import { RegistryService } from './registry/registry.service';
|
||||
import { RoleService } from './roles/role.service';
|
||||
import { FeedbackDataService } from './feedback/feedback-data.service';
|
||||
@@ -218,7 +218,7 @@ const PROVIDERS = [
|
||||
HALEndpointService,
|
||||
HostWindowService,
|
||||
ItemDataService,
|
||||
MetadataService,
|
||||
HeadTagService,
|
||||
ObjectCacheService,
|
||||
PaginationComponentOptions,
|
||||
ResourcePolicyDataService,
|
||||
|
@@ -19,7 +19,7 @@ import { PaginatedList } from '../data/paginated-list.model';
|
||||
import { Bitstream } from '../shared/bitstream.model';
|
||||
import { MetadataValue } from '../shared/metadata.models';
|
||||
|
||||
import { MetadataService } from './metadata.service';
|
||||
import { HeadTagService } from './head-tag.service';
|
||||
import { RootDataService } from '../data/root-data.service';
|
||||
import { Bundle } from '../shared/bundle.model';
|
||||
import { createPaginatedList } from '../../shared/testing/utils.test';
|
||||
@@ -31,8 +31,8 @@ import { AddMetaTagAction, ClearMetaTagAction } from './meta-tag.actions';
|
||||
import { AuthorizationDataService } from '../data/feature-authorization/authorization-data.service';
|
||||
import { AppConfig } from '../../../config/app-config.interface';
|
||||
|
||||
describe('MetadataService', () => {
|
||||
let metadataService: MetadataService;
|
||||
describe('HeadTagService', () => {
|
||||
let headTagService: HeadTagService;
|
||||
|
||||
let meta: Meta;
|
||||
|
||||
@@ -41,7 +41,6 @@ describe('MetadataService', () => {
|
||||
let dsoNameService: DSONameService;
|
||||
|
||||
let bundleDataService;
|
||||
let bitstreamDataService;
|
||||
let rootService: RootDataService;
|
||||
let translateService: TranslateService;
|
||||
let hardRedirectService: HardRedirectService;
|
||||
@@ -59,9 +58,6 @@ describe('MetadataService', () => {
|
||||
rootService = jasmine.createSpyObj({
|
||||
findRoot: createSuccessfulRemoteDataObject$({ dspaceVersion: 'mock-dspace-version' })
|
||||
});
|
||||
bitstreamDataService = jasmine.createSpyObj({
|
||||
findListByHref: createSuccessfulRemoteDataObject$(createPaginatedList([MockBitstream3])),
|
||||
});
|
||||
bundleDataService = jasmine.createSpyObj({
|
||||
findByItemAndName: mockBundleRD$([MockBitstream3])
|
||||
});
|
||||
@@ -102,15 +98,13 @@ describe('MetadataService', () => {
|
||||
}
|
||||
} as any;
|
||||
|
||||
metadataService = new MetadataService(
|
||||
headTagService = new HeadTagService(
|
||||
router,
|
||||
translateService,
|
||||
meta,
|
||||
title,
|
||||
dsoNameService,
|
||||
bundleDataService,
|
||||
bitstreamDataService,
|
||||
undefined,
|
||||
rootService,
|
||||
store,
|
||||
hardRedirectService,
|
||||
@@ -120,7 +114,7 @@ describe('MetadataService', () => {
|
||||
});
|
||||
|
||||
it('items page should set meta tags', fakeAsync(() => {
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(ItemMock),
|
||||
@@ -147,7 +141,7 @@ describe('MetadataService', () => {
|
||||
}));
|
||||
|
||||
it('items page should set meta tags as published Thesis', fakeAsync(() => {
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(mockPublisher(mockType(ItemMock, 'Thesis'))),
|
||||
@@ -166,7 +160,7 @@ describe('MetadataService', () => {
|
||||
}));
|
||||
|
||||
it('items page should set meta tags as published Technical Report', fakeAsync(() => {
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(mockPublisher(mockType(ItemMock, 'Technical Report'))),
|
||||
@@ -182,7 +176,7 @@ describe('MetadataService', () => {
|
||||
|
||||
it('route titles should overwrite dso titles', fakeAsync(() => {
|
||||
(translateService.get as jasmine.Spy).and.returnValues(of('DSpace :: '), of('Translated Route Title'));
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(ItemMock),
|
||||
@@ -198,7 +192,7 @@ describe('MetadataService', () => {
|
||||
|
||||
it('other navigation should add title and description', fakeAsync(() => {
|
||||
(translateService.get as jasmine.Spy).and.returnValues(of('DSpace :: '), of('Dummy Title'), of('This is a dummy item component for testing!'));
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
title: 'Dummy Title',
|
||||
@@ -220,14 +214,14 @@ describe('MetadataService', () => {
|
||||
|
||||
describe(`listenForRouteChange`, () => {
|
||||
it(`should call processRouteChange`, fakeAsync(() => {
|
||||
spyOn(metadataService as any, 'processRouteChange').and.callFake(() => undefined);
|
||||
metadataService.listenForRouteChange();
|
||||
spyOn(headTagService as any, 'processRouteChange').and.callFake(() => undefined);
|
||||
headTagService.listenForRouteChange();
|
||||
tick();
|
||||
expect((metadataService as any).processRouteChange).toHaveBeenCalled();
|
||||
expect((headTagService as any).processRouteChange).toHaveBeenCalled();
|
||||
}));
|
||||
it(`should add Generator`, fakeAsync(() => {
|
||||
spyOn(metadataService as any, 'processRouteChange').and.callFake(() => undefined);
|
||||
metadataService.listenForRouteChange();
|
||||
spyOn(headTagService as any, 'processRouteChange').and.callFake(() => undefined);
|
||||
headTagService.listenForRouteChange();
|
||||
tick();
|
||||
expect(meta.addTag).toHaveBeenCalledWith({
|
||||
name: 'Generator',
|
||||
@@ -238,7 +232,7 @@ describe('MetadataService', () => {
|
||||
|
||||
describe('citation_abstract_html_url', () => {
|
||||
it('should use dc.identifier.uri if available', fakeAsync(() => {
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(mockUri(ItemMock, 'https://ddg.gg')),
|
||||
@@ -253,7 +247,7 @@ describe('MetadataService', () => {
|
||||
}));
|
||||
|
||||
it('should use current route as fallback', fakeAsync(() => {
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(mockUri(ItemMock)),
|
||||
@@ -270,7 +264,7 @@ describe('MetadataService', () => {
|
||||
|
||||
describe('citation_*_institution / citation_publisher', () => {
|
||||
it('should use citation_dissertation_institution tag for dissertations', fakeAsync(() => {
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(mockPublisher(mockType(ItemMock, 'Thesis'))),
|
||||
@@ -287,7 +281,7 @@ describe('MetadataService', () => {
|
||||
}));
|
||||
|
||||
it('should use citation_tech_report_institution tag for tech reports', fakeAsync(() => {
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(mockPublisher(mockType(ItemMock, 'Technical Report'))),
|
||||
@@ -304,7 +298,7 @@ describe('MetadataService', () => {
|
||||
}));
|
||||
|
||||
it('should use citation_publisher for other item types', fakeAsync(() => {
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(mockPublisher(mockType(ItemMock, 'Some Other Type'))),
|
||||
@@ -325,7 +319,7 @@ describe('MetadataService', () => {
|
||||
it('should link to primary Bitstream URL regardless of format', fakeAsync(() => {
|
||||
(bundleDataService.findByItemAndName as jasmine.Spy).and.returnValue(mockBundleRD$([], MockBitstream3));
|
||||
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(ItemMock),
|
||||
@@ -344,7 +338,7 @@ describe('MetadataService', () => {
|
||||
(bundleDataService.findByItemAndName as jasmine.Spy).and.returnValue(mockBundleRD$([MockBitstream3]));
|
||||
(authorizationService.isAuthorized as jasmine.Spy).and.returnValue(observableOf(false));
|
||||
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(ItemMock),
|
||||
@@ -361,7 +355,7 @@ describe('MetadataService', () => {
|
||||
it('should link to first and only Bitstream regardless of format', fakeAsync(() => {
|
||||
(bundleDataService.findByItemAndName as jasmine.Spy).and.returnValue(mockBundleRD$([MockBitstream3]));
|
||||
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(ItemMock),
|
||||
@@ -381,13 +375,10 @@ describe('MetadataService', () => {
|
||||
beforeEach(() => {
|
||||
bitstreams = [MockBitstream2, MockBitstream3, MockBitstream1];
|
||||
(bundleDataService.findByItemAndName as jasmine.Spy).and.returnValue(mockBundleRD$(bitstreams));
|
||||
(bitstreamDataService.findListByHref as jasmine.Spy).and.returnValues(
|
||||
...mockBitstreamPages$(bitstreams).map(bp => createSuccessfulRemoteDataObject$(bp)),
|
||||
);
|
||||
});
|
||||
|
||||
it('should link to first Bitstream with allowed format', fakeAsync(() => {
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(ItemMock),
|
||||
@@ -412,13 +403,10 @@ describe('MetadataService', () => {
|
||||
beforeEach(() => {
|
||||
bitstreams = [MockBitstream1, MockBitstream3, MockBitstream2];
|
||||
(bundleDataService.findByItemAndName as jasmine.Spy).and.returnValue(mockBundleRD$(bitstreams));
|
||||
(bitstreamDataService.findListByHref as jasmine.Spy).and.returnValues(
|
||||
...mockBitstreamPages$(bitstreams).map(bp => createSuccessfulRemoteDataObject$(bp)),
|
||||
);
|
||||
});
|
||||
|
||||
it(`shouldn't add a citation_pdf_url meta tag`, fakeAsync(() => {
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(ItemMock),
|
||||
@@ -437,7 +425,7 @@ describe('MetadataService', () => {
|
||||
|
||||
describe('tagstore', () => {
|
||||
beforeEach(fakeAsync(() => {
|
||||
(metadataService as any).processRouteChange({
|
||||
(headTagService as any).processRouteChange({
|
||||
data: {
|
||||
value: {
|
||||
dso: createSuccessfulRemoteDataObject(ItemMock),
|
@@ -17,8 +17,6 @@ import { filter, map, switchMap, take, mergeMap } from 'rxjs/operators';
|
||||
|
||||
import { hasNoValue, hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||
import { DSONameService } from '../breadcrumbs/dso-name.service';
|
||||
import { BitstreamDataService } from '../data/bitstream-data.service';
|
||||
import { BitstreamFormatDataService } from '../data/bitstream-format-data.service';
|
||||
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { BitstreamFormat } from '../shared/bitstream-format.model';
|
||||
@@ -64,7 +62,7 @@ const tagsInUseSelector =
|
||||
);
|
||||
|
||||
@Injectable()
|
||||
export class MetadataService {
|
||||
export class HeadTagService {
|
||||
|
||||
private currentObject: BehaviorSubject<DSpaceObject> = new BehaviorSubject<DSpaceObject>(undefined);
|
||||
|
||||
@@ -84,19 +82,17 @@ export class MetadataService {
|
||||
];
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private translate: TranslateService,
|
||||
private meta: Meta,
|
||||
private title: Title,
|
||||
private dsoNameService: DSONameService,
|
||||
private bundleDataService: BundleDataService,
|
||||
private bitstreamDataService: BitstreamDataService,
|
||||
private bitstreamFormatDataService: BitstreamFormatDataService,
|
||||
private rootService: RootDataService,
|
||||
private store: Store<CoreState>,
|
||||
private hardRedirectService: HardRedirectService,
|
||||
@Inject(APP_CONFIG) private appConfig: AppConfig,
|
||||
private authorizationService: AuthorizationDataService
|
||||
protected router: Router,
|
||||
protected translate: TranslateService,
|
||||
protected meta: Meta,
|
||||
protected title: Title,
|
||||
protected dsoNameService: DSONameService,
|
||||
protected bundleDataService: BundleDataService,
|
||||
protected rootService: RootDataService,
|
||||
protected store: Store<CoreState>,
|
||||
protected hardRedirectService: HardRedirectService,
|
||||
@Inject(APP_CONFIG) protected appConfig: AppConfig,
|
||||
protected authorizationService: AuthorizationDataService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -115,7 +111,7 @@ export class MetadataService {
|
||||
});
|
||||
}
|
||||
|
||||
private processRouteChange(routeInfo: any): void {
|
||||
protected processRouteChange(routeInfo: any): void {
|
||||
this.clearMetaTags();
|
||||
|
||||
if (hasValue(routeInfo.data.value.dso) && hasValue(routeInfo.data.value.dso.payload)) {
|
||||
@@ -138,14 +134,14 @@ export class MetadataService {
|
||||
}
|
||||
}
|
||||
|
||||
private getCurrentRoute(route: ActivatedRoute): ActivatedRoute {
|
||||
protected getCurrentRoute(route: ActivatedRoute): ActivatedRoute {
|
||||
while (route.firstChild) {
|
||||
route = route.firstChild;
|
||||
}
|
||||
return route;
|
||||
}
|
||||
|
||||
private setDSOMetaTags(): void {
|
||||
protected setDSOMetaTags(): void {
|
||||
|
||||
this.setTitleTag();
|
||||
this.setDescriptionTag();
|
||||
@@ -187,7 +183,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="title" ... > to the <head>
|
||||
*/
|
||||
private setTitleTag(): void {
|
||||
protected setTitleTag(): void {
|
||||
const value = this.dsoNameService.getName(this.currentObject.getValue());
|
||||
this.addMetaTag('title', value);
|
||||
this.title.setTitle(value);
|
||||
@@ -196,7 +192,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="description" ... > to the <head>
|
||||
*/
|
||||
private setDescriptionTag(): void {
|
||||
protected setDescriptionTag(): void {
|
||||
// TODO: truncate abstract
|
||||
const value = this.getMetaTagValue('dc.description.abstract');
|
||||
this.addMetaTag('description', value);
|
||||
@@ -205,7 +201,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="citation_title" ... > to the <head>
|
||||
*/
|
||||
private setCitationTitleTag(): void {
|
||||
protected setCitationTitleTag(): void {
|
||||
const value = this.getMetaTagValue('dc.title');
|
||||
this.addMetaTag('citation_title', value);
|
||||
}
|
||||
@@ -213,7 +209,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="citation_author" ... > to the <head>
|
||||
*/
|
||||
private setCitationAuthorTags(): void {
|
||||
protected setCitationAuthorTags(): void {
|
||||
const values: string[] = this.getMetaTagValues(['dc.author', 'dc.contributor.author', 'dc.creator']);
|
||||
this.addMetaTags('citation_author', values);
|
||||
}
|
||||
@@ -221,7 +217,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="citation_publication_date" ... > to the <head>
|
||||
*/
|
||||
private setCitationPublicationDateTag(): void {
|
||||
protected setCitationPublicationDateTag(): void {
|
||||
const value = this.getFirstMetaTagValue(['dc.date.copyright', 'dc.date.issued', 'dc.date.available', 'dc.date.accessioned']);
|
||||
this.addMetaTag('citation_publication_date', value);
|
||||
}
|
||||
@@ -229,7 +225,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="citation_issn" ... > to the <head>
|
||||
*/
|
||||
private setCitationISSNTag(): void {
|
||||
protected setCitationISSNTag(): void {
|
||||
const value = this.getMetaTagValue('dc.identifier.issn');
|
||||
this.addMetaTag('citation_issn', value);
|
||||
}
|
||||
@@ -237,7 +233,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="citation_isbn" ... > to the <head>
|
||||
*/
|
||||
private setCitationISBNTag(): void {
|
||||
protected setCitationISBNTag(): void {
|
||||
const value = this.getMetaTagValue('dc.identifier.isbn');
|
||||
this.addMetaTag('citation_isbn', value);
|
||||
}
|
||||
@@ -245,7 +241,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="citation_language" ... > to the <head>
|
||||
*/
|
||||
private setCitationLanguageTag(): void {
|
||||
protected setCitationLanguageTag(): void {
|
||||
const value = this.getFirstMetaTagValue(['dc.language', 'dc.language.iso']);
|
||||
this.addMetaTag('citation_language', value);
|
||||
}
|
||||
@@ -253,7 +249,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="citation_dissertation_name" ... > to the <head>
|
||||
*/
|
||||
private setCitationDissertationNameTag(): void {
|
||||
protected setCitationDissertationNameTag(): void {
|
||||
const value = this.getMetaTagValue('dc.title');
|
||||
this.addMetaTag('citation_dissertation_name', value);
|
||||
}
|
||||
@@ -261,7 +257,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add dc.publisher to the <head>. The tag name depends on the item type.
|
||||
*/
|
||||
private setCitationPublisherTag(): void {
|
||||
protected setCitationPublisherTag(): void {
|
||||
const value = this.getMetaTagValue('dc.publisher');
|
||||
if (this.isDissertation()) {
|
||||
this.addMetaTag('citation_dissertation_institution', value);
|
||||
@@ -275,7 +271,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="citation_keywords" ... > to the <head>
|
||||
*/
|
||||
private setCitationKeywordsTag(): void {
|
||||
protected setCitationKeywordsTag(): void {
|
||||
const value = this.getMetaTagValuesAndCombine('dc.subject');
|
||||
this.addMetaTag('citation_keywords', value);
|
||||
}
|
||||
@@ -283,7 +279,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="citation_abstract_html_url" ... > to the <head>
|
||||
*/
|
||||
private setCitationAbstractUrlTag(): void {
|
||||
protected setCitationAbstractUrlTag(): void {
|
||||
if (this.currentObject.value instanceof Item) {
|
||||
let url = this.getMetaTagValue('dc.identifier.uri');
|
||||
if (hasNoValue(url)) {
|
||||
@@ -296,7 +292,7 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="citation_pdf_url" ... > to the <head>
|
||||
*/
|
||||
private setCitationPdfUrlTag(): void {
|
||||
protected setCitationPdfUrlTag(): void {
|
||||
if (this.currentObject.value instanceof Item) {
|
||||
const item = this.currentObject.value as Item;
|
||||
|
||||
@@ -389,7 +385,7 @@ export class MetadataService {
|
||||
* @param bitstreamRd
|
||||
* @private
|
||||
*/
|
||||
private getFirstAllowedFormatBitstreamLink(bitstreamRd: RemoteData<PaginatedList<Bitstream>>): Observable<string> {
|
||||
protected getFirstAllowedFormatBitstreamLink(bitstreamRd: RemoteData<PaginatedList<Bitstream>>): Observable<string> {
|
||||
if (hasValue(bitstreamRd.payload) && isNotEmpty(bitstreamRd.payload.page)) {
|
||||
// Retrieve the formats of all bitstreams in the page sequentially
|
||||
return observableConcat(
|
||||
@@ -422,13 +418,13 @@ export class MetadataService {
|
||||
/**
|
||||
* Add <meta name="Generator" ... > to the <head> containing the current DSpace version
|
||||
*/
|
||||
private setGenerator(): void {
|
||||
protected setGenerator(): void {
|
||||
this.rootService.findRoot().pipe(getFirstSucceededRemoteDataPayload()).subscribe((root) => {
|
||||
this.meta.addTag({ name: 'Generator', content: root.dspaceVersion });
|
||||
});
|
||||
}
|
||||
|
||||
private hasType(value: string): boolean {
|
||||
protected hasType(value: string): boolean {
|
||||
return this.currentObject.value.hasMetadata('dc.type', { value: value, ignoreCase: true });
|
||||
}
|
||||
|
||||
@@ -438,7 +434,7 @@ export class MetadataService {
|
||||
* @returns {boolean}
|
||||
* true if this._item has a dc.type equal to 'Thesis'
|
||||
*/
|
||||
private isDissertation(): boolean {
|
||||
protected isDissertation(): boolean {
|
||||
return this.hasType('thesis');
|
||||
}
|
||||
|
||||
@@ -448,27 +444,27 @@ export class MetadataService {
|
||||
* @returns {boolean}
|
||||
* true if this._item has a dc.type equal to 'Technical Report'
|
||||
*/
|
||||
private isTechReport(): boolean {
|
||||
protected isTechReport(): boolean {
|
||||
return this.hasType('technical report');
|
||||
}
|
||||
|
||||
private getMetaTagValue(key: string): string {
|
||||
protected getMetaTagValue(key: string): string {
|
||||
return this.currentObject.value.firstMetadataValue(key);
|
||||
}
|
||||
|
||||
private getFirstMetaTagValue(keys: string[]): string {
|
||||
protected getFirstMetaTagValue(keys: string[]): string {
|
||||
return this.currentObject.value.firstMetadataValue(keys);
|
||||
}
|
||||
|
||||
private getMetaTagValuesAndCombine(key: string): string {
|
||||
protected getMetaTagValuesAndCombine(key: string): string {
|
||||
return this.getMetaTagValues([key]).join('; ');
|
||||
}
|
||||
|
||||
private getMetaTagValues(keys: string[]): string[] {
|
||||
protected getMetaTagValues(keys: string[]): string[] {
|
||||
return this.currentObject.value.allMetadataValues(keys);
|
||||
}
|
||||
|
||||
private addMetaTag(name: string, content: string): void {
|
||||
protected addMetaTag(name: string, content: string): void {
|
||||
if (content) {
|
||||
const tag = { name, content } as MetaDefinition;
|
||||
this.meta.addTag(tag);
|
||||
@@ -476,17 +472,17 @@ export class MetadataService {
|
||||
}
|
||||
}
|
||||
|
||||
private addMetaTags(name: string, content: string[]): void {
|
||||
protected addMetaTags(name: string, content: string[]): void {
|
||||
for (const value of content) {
|
||||
this.addMetaTag(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
private storeTag(key: string): void {
|
||||
protected storeTag(key: string): void {
|
||||
this.store.dispatch(new AddMetaTagAction(key));
|
||||
}
|
||||
|
||||
public clearMetaTags() {
|
||||
protected clearMetaTags(): void {
|
||||
this.store.pipe(
|
||||
select(tagsInUseSelector),
|
||||
take(1)
|
@@ -2,7 +2,7 @@ import { InitService } from './init.service';
|
||||
import { APP_CONFIG } from 'src/config/app-config.interface';
|
||||
import { APP_INITIALIZER, Injectable } from '@angular/core';
|
||||
import { inject, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { MetadataService } from './core/metadata/metadata.service';
|
||||
import { HeadTagService } from './core/metadata/head-tag.service';
|
||||
import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Store, StoreModule } from '@ngrx/store';
|
||||
@@ -31,6 +31,7 @@ import objectContaining = jasmine.objectContaining;
|
||||
import createSpyObj = jasmine.createSpyObj;
|
||||
import SpyObj = jasmine.SpyObj;
|
||||
import { getTestScheduler } from 'jasmine-marbles';
|
||||
import { HeadTagServiceMock } from './shared/mocks/head-tag-service.mock';
|
||||
|
||||
let spy: SpyObj<any>;
|
||||
|
||||
@@ -121,7 +122,7 @@ describe('InitService', () => {
|
||||
let correlationIdServiceSpy;
|
||||
let dspaceTransferStateSpy;
|
||||
let transferStateSpy;
|
||||
let metadataServiceSpy;
|
||||
let headTagService: HeadTagServiceMock;
|
||||
let breadcrumbsServiceSpy;
|
||||
let menuServiceSpy;
|
||||
|
||||
@@ -147,9 +148,7 @@ describe('InitService', () => {
|
||||
breadcrumbsServiceSpy = jasmine.createSpyObj('breadcrumbsServiceSpy', [
|
||||
'listenForRouteChanges',
|
||||
]);
|
||||
metadataServiceSpy = jasmine.createSpyObj('metadataService', [
|
||||
'listenForRouteChange',
|
||||
]);
|
||||
headTagService = new HeadTagServiceMock();
|
||||
menuServiceSpy = jasmine.createSpyObj('menuServiceSpy', [
|
||||
'listenForRouteChanges',
|
||||
]);
|
||||
@@ -173,7 +172,7 @@ describe('InitService', () => {
|
||||
{ provide: APP_CONFIG, useValue: environment },
|
||||
{ provide: LocaleService, useValue: getMockLocaleService() },
|
||||
{ provide: Angulartics2DSpace, useValue: new AngularticsProviderMock() },
|
||||
{ provide: MetadataService, useValue: metadataServiceSpy },
|
||||
{ provide: HeadTagService, useValue: headTagService },
|
||||
{ provide: BreadcrumbsService, useValue: breadcrumbsServiceSpy },
|
||||
{ provide: AuthService, useValue: new AuthServiceMock() },
|
||||
{ provide: Router, useValue: new RouterMock() },
|
||||
@@ -189,9 +188,9 @@ describe('InitService', () => {
|
||||
|
||||
describe('initRouteListeners', () => {
|
||||
it('should call listenForRouteChanges', inject([InitService], (service) => {
|
||||
// @ts-ignore
|
||||
spyOn(headTagService, 'listenForRouteChange');
|
||||
service.initRouteListeners();
|
||||
expect(metadataServiceSpy.listenForRouteChange).toHaveBeenCalledTimes(1);
|
||||
expect(headTagService.listenForRouteChange).toHaveBeenCalledTimes(1);
|
||||
expect(breadcrumbsServiceSpy.listenForRouteChanges).toHaveBeenCalledTimes(1);
|
||||
expect(breadcrumbsServiceSpy.listenForRouteChanges).toHaveBeenCalledTimes(1);
|
||||
}));
|
||||
|
@@ -17,7 +17,7 @@ import isEqual from 'lodash/isEqual';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { LocaleService } from './core/locale/locale.service';
|
||||
import { Angulartics2DSpace } from './statistics/angulartics/dspace-provider';
|
||||
import { MetadataService } from './core/metadata/metadata.service';
|
||||
import { HeadTagService } from './core/metadata/head-tag.service';
|
||||
import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service';
|
||||
import { ThemeService } from './shared/theme-support/theme.service';
|
||||
import { isAuthenticationBlocking } from './core/auth/selectors';
|
||||
@@ -49,7 +49,7 @@ export abstract class InitService {
|
||||
protected translate: TranslateService,
|
||||
protected localeService: LocaleService,
|
||||
protected angulartics2DSpace: Angulartics2DSpace,
|
||||
protected metadata: MetadataService,
|
||||
protected headTagService: HeadTagService,
|
||||
protected breadcrumbsService: BreadcrumbsService,
|
||||
protected themeService: ThemeService,
|
||||
protected menuService: MenuService,
|
||||
@@ -178,13 +178,13 @@ export abstract class InitService {
|
||||
|
||||
/**
|
||||
* Start route-listening subscriptions
|
||||
* - {@link MetadataService.listenForRouteChange}
|
||||
* - {@link HeadTagService.listenForRouteChange}
|
||||
* - {@link BreadcrumbsService.listenForRouteChanges}
|
||||
* - {@link ThemeService.listenForRouteChanges}
|
||||
* @protected
|
||||
*/
|
||||
protected initRouteListeners(): void {
|
||||
this.metadata.listenForRouteChange();
|
||||
this.headTagService.listenForRouteChange();
|
||||
this.breadcrumbsService.listenForRouteChanges();
|
||||
this.themeService.listenForRouteChanges();
|
||||
this.menuService.listenForRouteChanges();
|
||||
|
@@ -5,7 +5,7 @@ import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA, PLATFORM_ID } from '@angular/core';
|
||||
import { TruncatePipe } from '../../shared/utils/truncate.pipe';
|
||||
import { FullItemPageComponent } from './full-item-page.component';
|
||||
import { MetadataService } from '../../core/metadata/metadata.service';
|
||||
import { HeadTagService } from '../../core/metadata/head-tag.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ActivatedRouteStub } from '../../shared/testing/active-router.stub';
|
||||
import { VarDirective } from '../../shared/utils/var.directive';
|
||||
@@ -116,7 +116,7 @@ describe('FullItemPageComponent', () => {
|
||||
providers: [
|
||||
{ provide: ActivatedRoute, useValue: routeStub },
|
||||
{ provide: ItemDataService, useValue: {} },
|
||||
{ provide: MetadataService, useValue: metadataServiceStub },
|
||||
{ provide: HeadTagService, useValue: metadataServiceStub },
|
||||
{ provide: AuthService, useValue: authService },
|
||||
{ provide: AuthorizationDataService, useValue: authorizationDataService },
|
||||
{ provide: ServerResponseService, useValue: serverResponseService },
|
||||
|
@@ -6,7 +6,6 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA, PLATFORM_ID } from '@angular
|
||||
import { ItemPageComponent } from './item-page.component';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ActivatedRouteStub } from '../../shared/testing/active-router.stub';
|
||||
import { MetadataService } from '../../core/metadata/metadata.service';
|
||||
import { VarDirective } from '../../shared/utils/var.directive';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
@@ -63,12 +62,6 @@ describe('ItemPageComponent', () => {
|
||||
let signpostingDataService: jasmine.SpyObj<SignpostingDataService>;
|
||||
let linkHeadService: jasmine.SpyObj<LinkHeadService>;
|
||||
|
||||
const mockMetadataService = {
|
||||
/* eslint-disable no-empty,@typescript-eslint/no-empty-function */
|
||||
processRemoteData: () => {
|
||||
}
|
||||
/* eslint-enable no-empty, @typescript-eslint/no-empty-function */
|
||||
};
|
||||
const mockRoute = Object.assign(new ActivatedRouteStub(), {
|
||||
data: observableOf({ dso: createSuccessfulRemoteDataObject(mockItem) })
|
||||
});
|
||||
@@ -105,7 +98,6 @@ describe('ItemPageComponent', () => {
|
||||
providers: [
|
||||
{ provide: ActivatedRoute, useValue: mockRoute },
|
||||
{ provide: ItemDataService, useValue: {} },
|
||||
{ provide: MetadataService, useValue: mockMetadataService },
|
||||
{ provide: Router, useValue: {} },
|
||||
{ provide: AuthService, useValue: authService },
|
||||
{ provide: AuthorizationDataService, useValue: authorizationDataService },
|
||||
|
@@ -1,29 +1,14 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RootComponent } from './root.component';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { StoreModule } from '@ngrx/store';
|
||||
import { authReducer } from '../core/auth/auth.reducer';
|
||||
import { storeModuleConfig } from '../app.reducer';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { TranslateLoaderMock } from '../shared/mocks/translate-loader.mock';
|
||||
import { NativeWindowRef, NativeWindowService } from '../core/services/window.service';
|
||||
import { MetadataService } from '../core/metadata/metadata.service';
|
||||
import { MetadataServiceMock } from '../shared/mocks/metadata-service.mock';
|
||||
import { AngularticsProviderMock } from '../shared/mocks/angulartics-provider.service.mock';
|
||||
import { Angulartics2DSpace } from '../statistics/angulartics/dspace-provider';
|
||||
import { AuthService } from '../core/auth/auth.service';
|
||||
import { AuthServiceMock } from '../shared/mocks/auth.service.mock';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { RouterMock } from '../shared/mocks/router.mock';
|
||||
import { MockActivatedRoute } from '../shared/mocks/active-router.mock';
|
||||
import { MenuService } from '../shared/menu/menu.service';
|
||||
import { CSSVariableService } from '../shared/sass-helper/css-variable.service';
|
||||
import { CSSVariableServiceStub } from '../shared/testing/css-variable-service.stub';
|
||||
import { HostWindowService } from '../shared/host-window.service';
|
||||
import { HostWindowServiceStub } from '../shared/testing/host-window-service.stub';
|
||||
import { LocaleService } from '../core/locale/locale.service';
|
||||
import { provideMockStore } from '@ngrx/store/testing';
|
||||
import { RouteService } from '../core/services/route.service';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { MenuServiceStub } from '../shared/testing/menu-service.stub';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
@@ -37,29 +22,14 @@ describe('RootComponent', () => {
|
||||
imports: [
|
||||
CommonModule,
|
||||
NoopAnimationsModule,
|
||||
StoreModule.forRoot(authReducer, storeModuleConfig),
|
||||
TranslateModule.forRoot({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useClass: TranslateLoaderMock
|
||||
}
|
||||
}),
|
||||
TranslateModule.forRoot(),
|
||||
],
|
||||
declarations: [RootComponent], // declare the test component
|
||||
providers: [
|
||||
{ provide: NativeWindowService, useValue: new NativeWindowRef() },
|
||||
{ provide: MetadataService, useValue: new MetadataServiceMock() },
|
||||
{ provide: Angulartics2DSpace, useValue: new AngularticsProviderMock() },
|
||||
{ provide: AuthService, useValue: new AuthServiceMock() },
|
||||
{ provide: Router, useValue: new RouterMock() },
|
||||
{ provide: ActivatedRoute, useValue: new MockActivatedRoute() },
|
||||
{ provide: MenuService, useValue: new MenuServiceStub() },
|
||||
{ provide: CSSVariableService, useClass: CSSVariableServiceStub },
|
||||
{ provide: HostWindowService, useValue: new HostWindowServiceStub(800) },
|
||||
{ provide: LocaleService, useValue: {} },
|
||||
provideMockStore({ core: { auth: { loading: false } } } as any),
|
||||
RootComponent,
|
||||
RouteService
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
}).compileComponents();
|
||||
|
@@ -1,20 +1,12 @@
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
import { Component, Inject, Input, OnInit } from '@angular/core';
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { combineLatest as combineLatestObservable, Observable, of } from 'rxjs';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { MetadataService } from '../core/metadata/metadata.service';
|
||||
import { HostWindowState } from '../shared/search/host-window.reducer';
|
||||
import { NativeWindowRef, NativeWindowService } from '../core/services/window.service';
|
||||
import { AuthService } from '../core/auth/auth.service';
|
||||
import { CSSVariableService } from '../shared/sass-helper/css-variable.service';
|
||||
import { MenuService } from '../shared/menu/menu.service';
|
||||
import { HostWindowService } from '../shared/host-window.service';
|
||||
import { ThemeConfig } from '../../config/theme.model';
|
||||
import { Angulartics2DSpace } from '../statistics/angulartics/dspace-provider';
|
||||
import { environment } from '../../environments/environment';
|
||||
import { slideSidebarPadding } from '../shared/animations/slide';
|
||||
import { MenuID } from '../shared/menu/menu-id.model';
|
||||
@@ -47,12 +39,6 @@ export class RootComponent implements OnInit {
|
||||
@Input() shouldShowRouteLoader: boolean;
|
||||
|
||||
constructor(
|
||||
@Inject(NativeWindowService) private _window: NativeWindowRef,
|
||||
private translate: TranslateService,
|
||||
private store: Store<HostWindowState>,
|
||||
private metadata: MetadataService,
|
||||
private angulartics2DSpace: Angulartics2DSpace,
|
||||
private authService: AuthService,
|
||||
private router: Router,
|
||||
private cssService: CSSVariableService,
|
||||
private menuService: MenuService,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
|
||||
export class MetadataServiceMock {
|
||||
export class HeadTagServiceMock {
|
||||
|
||||
// eslint-disable-next-line no-empty, @typescript-eslint/no-empty-function
|
||||
public listenForRouteChange(): void {
|
@@ -19,7 +19,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { LocaleService } from '../../app/core/locale/locale.service';
|
||||
import { Angulartics2DSpace } from '../../app/statistics/angulartics/dspace-provider';
|
||||
import { GoogleAnalyticsService } from '../../app/statistics/google-analytics.service';
|
||||
import { MetadataService } from '../../app/core/metadata/metadata.service';
|
||||
import { HeadTagService } from '../../app/core/metadata/head-tag.service';
|
||||
import { BreadcrumbsService } from '../../app/breadcrumbs/breadcrumbs.service';
|
||||
import { KlaroService } from '../../app/shared/cookies/klaro.service';
|
||||
import { AuthService } from '../../app/core/auth/auth.service';
|
||||
@@ -50,7 +50,7 @@ export class BrowserInitService extends InitService {
|
||||
protected localeService: LocaleService,
|
||||
protected angulartics2DSpace: Angulartics2DSpace,
|
||||
protected googleAnalyticsService: GoogleAnalyticsService,
|
||||
protected metadata: MetadataService,
|
||||
protected headTagService: HeadTagService,
|
||||
protected breadcrumbsService: BreadcrumbsService,
|
||||
protected klaroService: KlaroService,
|
||||
protected authService: AuthService,
|
||||
@@ -65,7 +65,7 @@ export class BrowserInitService extends InitService {
|
||||
translate,
|
||||
localeService,
|
||||
angulartics2DSpace,
|
||||
metadata,
|
||||
headTagService,
|
||||
breadcrumbsService,
|
||||
themeService,
|
||||
menuService,
|
||||
|
@@ -16,7 +16,7 @@ import { Inject, Injectable } from '@angular/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { LocaleService } from '../../app/core/locale/locale.service';
|
||||
import { Angulartics2DSpace } from '../../app/statistics/angulartics/dspace-provider';
|
||||
import { MetadataService } from '../../app/core/metadata/metadata.service';
|
||||
import { HeadTagService } from '../../app/core/metadata/head-tag.service';
|
||||
import { BreadcrumbsService } from '../../app/breadcrumbs/breadcrumbs.service';
|
||||
import { ThemeService } from '../../app/shared/theme-support/theme.service';
|
||||
import { take } from 'rxjs/operators';
|
||||
@@ -35,7 +35,7 @@ export class ServerInitService extends InitService {
|
||||
protected translate: TranslateService,
|
||||
protected localeService: LocaleService,
|
||||
protected angulartics2DSpace: Angulartics2DSpace,
|
||||
protected metadata: MetadataService,
|
||||
protected headTagService: HeadTagService,
|
||||
protected breadcrumbsService: BreadcrumbsService,
|
||||
protected themeService: ThemeService,
|
||||
protected menuService: MenuService
|
||||
@@ -47,7 +47,7 @@ export class ServerInitService extends InitService {
|
||||
translate,
|
||||
localeService,
|
||||
angulartics2DSpace,
|
||||
metadata,
|
||||
headTagService,
|
||||
breadcrumbsService,
|
||||
themeService,
|
||||
menuService,
|
||||
|
Reference in New Issue
Block a user