diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c856e8f5fe..6f4a11acc8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -117,5 +117,28 @@ jobs: chromedriver --url-base='/wd/hub' --port=4444 & yarn run e2e:ci + # Start up the app with SSR enabled (run in background) + - name: Start app in SSR (server-side rendering) mode + run: | + nohup yarn run serve:ssr & + printf 'Waiting for app to start' + until curl --output /dev/null --silent --head --fail http://localhost:4000/home; do + printf '.' + sleep 2 + done + echo "App started successfully." + + # Get homepage and verify that the tag includes "DSpace". + # If it does, then SSR is working, as this tag is created by our MetadataService. + # This step also prints entire HTML of homepage for easier debugging if grep fails. + - name: Verify SSR (server-side rendering) + run: | + result=$(wget -O- -q http://localhost:4000/home) + echo "$result" + echo "$result" | grep -oE "]*>" | grep DSpace + + - name: Stop running app + run: kill -9 $(lsof -t -i:4000) + - name: Shutdown Docker containers run: docker-compose -f ./docker/docker-compose-ci.yml down diff --git a/src/app/core/metadata/metadata.service.spec.ts b/src/app/core/metadata/metadata.service.spec.ts index 9f3f782406..985851c321 100644 --- a/src/app/core/metadata/metadata.service.spec.ts +++ b/src/app/core/metadata/metadata.service.spec.ts @@ -107,18 +107,18 @@ describe('MetadataService', () => { tick(); expect(title.setTitle).toHaveBeenCalledWith('Test PowerPoint Document'); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_title', + name: 'citation_title', content: 'Test PowerPoint Document' }); - expect(meta.addTag).toHaveBeenCalledWith({ property: 'citation_author', content: 'Doe, Jane' }); + expect(meta.addTag).toHaveBeenCalledWith({ name: 'citation_author', content: 'Doe, Jane' }); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_publication_date', + name: 'citation_publication_date', content: '1650-06-26' }); - expect(meta.addTag).toHaveBeenCalledWith({ property: 'citation_issn', content: '123456789' }); - expect(meta.addTag).toHaveBeenCalledWith({ property: 'citation_language', content: 'en' }); + expect(meta.addTag).toHaveBeenCalledWith({ name: 'citation_issn', content: '123456789' }); + expect(meta.addTag).toHaveBeenCalledWith({ name: 'citation_language', content: 'en' }); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_keywords', + name: 'citation_keywords', content: 'keyword1; keyword2; keyword3' }); })); @@ -133,11 +133,11 @@ describe('MetadataService', () => { }); tick(); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_dissertation_name', + name: 'citation_dissertation_name', content: 'Test PowerPoint Document' }); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_pdf_url', + name: 'citation_pdf_url', content: 'https://request.org/bitstreams/4db100c1-e1f5-4055-9404-9bc3e2d15f29/download' }); })); @@ -152,7 +152,7 @@ describe('MetadataService', () => { }); tick(); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_technical_report_institution', + name: 'citation_technical_report_institution', content: 'Mock Publisher' }); })); @@ -170,11 +170,11 @@ describe('MetadataService', () => { tick(); expect(title.setTitle).toHaveBeenCalledWith('DSpace :: Dummy Title'); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'title', + name: 'title', content: 'DSpace :: Dummy Title' }); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'description', + name: 'description', content: 'This is a dummy item component for testing!' }); })); @@ -191,7 +191,7 @@ describe('MetadataService', () => { metadataService.listenForRouteChange(); tick(); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'Generator', + name: 'Generator', content: 'mock-dspace-version' }); })); @@ -208,7 +208,7 @@ describe('MetadataService', () => { }); tick(); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_abstract_html_url', + name: 'citation_abstract_html_url', content: 'https://ddg.gg' }); })); @@ -223,7 +223,7 @@ describe('MetadataService', () => { }); tick(); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_abstract_html_url', + name: 'citation_abstract_html_url', content: 'https://request.org/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357' }); })); @@ -240,11 +240,11 @@ describe('MetadataService', () => { }); tick(); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_dissertation_institution', + name: 'citation_dissertation_institution', content: 'Mock Publisher' }); - expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ property: 'citation_technical_report_institution' })); - expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ property: 'citation_publisher' })); + expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ name: 'citation_technical_report_institution' })); + expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ name: 'citation_publisher' })); })); it('should use citation_tech_report_institution tag for tech reports', fakeAsync(() => { @@ -256,12 +256,12 @@ describe('MetadataService', () => { } }); tick(); - expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ property: 'citation_dissertation_institution' })); + expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ name: 'citation_dissertation_institution' })); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_technical_report_institution', + name: 'citation_technical_report_institution', content: 'Mock Publisher' }); - expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ property: 'citation_publisher' })); + expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ name: 'citation_publisher' })); })); it('should use citation_publisher for other item types', fakeAsync(() => { @@ -273,10 +273,10 @@ describe('MetadataService', () => { } }); tick(); - expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ property: 'citation_dissertation_institution' })); - expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ property: 'citation_technical_report_institution' })); + expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ name: 'citation_dissertation_institution' })); + expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ name: 'citation_technical_report_institution' })); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_publisher', + name: 'citation_publisher', content: 'Mock Publisher' }); })); @@ -295,7 +295,7 @@ describe('MetadataService', () => { }); tick(); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_pdf_url', + name: 'citation_pdf_url', content: 'https://request.org/bitstreams/4db100c1-e1f5-4055-9404-9bc3e2d15f29/download' }); })); @@ -313,7 +313,7 @@ describe('MetadataService', () => { }); tick(); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_pdf_url', + name: 'citation_pdf_url', content: 'https://request.org/bitstreams/4db100c1-e1f5-4055-9404-9bc3e2d15f29/download' }); })); @@ -334,7 +334,7 @@ describe('MetadataService', () => { }); tick(); expect(meta.addTag).toHaveBeenCalledWith({ - property: 'citation_pdf_url', + name: 'citation_pdf_url', content: 'https://request.org/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713/download' }); })); @@ -354,8 +354,8 @@ describe('MetadataService', () => { })); it('should remove previous tags on route change', fakeAsync(() => { - expect(meta.removeTag).toHaveBeenCalledWith('property=\'title\''); - expect(meta.removeTag).toHaveBeenCalledWith('property=\'description\''); + expect(meta.removeTag).toHaveBeenCalledWith('name=\'title\''); + expect(meta.removeTag).toHaveBeenCalledWith('name=\'description\''); })); it('should clear all tags and add new ones on route change', () => { diff --git a/src/app/core/metadata/metadata.service.ts b/src/app/core/metadata/metadata.service.ts index 6f07ecbb06..1c6946b0d3 100644 --- a/src/app/core/metadata/metadata.service.ts +++ b/src/app/core/metadata/metadata.service.ts @@ -403,7 +403,7 @@ export class MetadataService { */ private setGenerator(): void { this.rootService.findRoot().pipe(getFirstSucceededRemoteDataPayload()).subscribe((root) => { - this.meta.addTag({ property: 'Generator', content: root.dspaceVersion }); + this.meta.addTag({ name: 'Generator', content: root.dspaceVersion }); }); } @@ -447,17 +447,17 @@ export class MetadataService { return this.currentObject.value.allMetadataValues(keys); } - private addMetaTag(property: string, content: string): void { + private addMetaTag(name: string, content: string): void { if (content) { - const tag = { property, content } as MetaDefinition; + const tag = { name, content } as MetaDefinition; this.meta.addTag(tag); - this.storeTag(property); + this.storeTag(name); } } - private addMetaTags(property: string, content: string[]): void { + private addMetaTags(name: string, content: string[]): void { for (const value of content) { - this.addMetaTag(property, value); + this.addMetaTag(name, value); } } @@ -470,8 +470,8 @@ export class MetadataService { select(tagsInUseSelector), take(1) ).subscribe((tagsInUse: string[]) => { - for (const property of tagsInUse) { - this.meta.removeTag('property=\'' + property + '\''); + for (const name of tagsInUse) { + this.meta.removeTag('name=\'' + name + '\''); } this.store.dispatch(new ClearMetaTagAction()); });