Skip to content

Commit 47302ac

Browse files
authored
Merge pull request DSpace#1282 from tdonohue/test_ssr_working
SEO + SSR fixes: Fix <meta> tag syntax and add a basic test that SSR is working
2 parents 4292af4 + 91bb5e2 commit 47302ac

3 files changed

Lines changed: 59 additions & 36 deletions

File tree

.github/workflows/build.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,28 @@ jobs:
117117
chromedriver --url-base='/wd/hub' --port=4444 &
118118
yarn run e2e:ci
119119
120+
# Start up the app with SSR enabled (run in background)
121+
- name: Start app in SSR (server-side rendering) mode
122+
run: |
123+
nohup yarn run serve:ssr &
124+
printf 'Waiting for app to start'
125+
until curl --output /dev/null --silent --head --fail http://localhost:4000/home; do
126+
printf '.'
127+
sleep 2
128+
done
129+
echo "App started successfully."
130+
131+
# Get homepage and verify that the <meta name="title"> tag includes "DSpace".
132+
# If it does, then SSR is working, as this tag is created by our MetadataService.
133+
# This step also prints entire HTML of homepage for easier debugging if grep fails.
134+
- name: Verify SSR (server-side rendering)
135+
run: |
136+
result=$(wget -O- -q http://localhost:4000/home)
137+
echo "$result"
138+
echo "$result" | grep -oE "<meta name=\"title\" [^>]*>" | grep DSpace
139+
140+
- name: Stop running app
141+
run: kill -9 $(lsof -t -i:4000)
142+
120143
- name: Shutdown Docker containers
121144
run: docker-compose -f ./docker/docker-compose-ci.yml down

src/app/core/metadata/metadata.service.spec.ts

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -107,18 +107,18 @@ describe('MetadataService', () => {
107107
tick();
108108
expect(title.setTitle).toHaveBeenCalledWith('Test PowerPoint Document');
109109
expect(meta.addTag).toHaveBeenCalledWith({
110-
property: 'citation_title',
110+
name: 'citation_title',
111111
content: 'Test PowerPoint Document'
112112
});
113-
expect(meta.addTag).toHaveBeenCalledWith({ property: 'citation_author', content: 'Doe, Jane' });
113+
expect(meta.addTag).toHaveBeenCalledWith({ name: 'citation_author', content: 'Doe, Jane' });
114114
expect(meta.addTag).toHaveBeenCalledWith({
115-
property: 'citation_publication_date',
115+
name: 'citation_publication_date',
116116
content: '1650-06-26'
117117
});
118-
expect(meta.addTag).toHaveBeenCalledWith({ property: 'citation_issn', content: '123456789' });
119-
expect(meta.addTag).toHaveBeenCalledWith({ property: 'citation_language', content: 'en' });
118+
expect(meta.addTag).toHaveBeenCalledWith({ name: 'citation_issn', content: '123456789' });
119+
expect(meta.addTag).toHaveBeenCalledWith({ name: 'citation_language', content: 'en' });
120120
expect(meta.addTag).toHaveBeenCalledWith({
121-
property: 'citation_keywords',
121+
name: 'citation_keywords',
122122
content: 'keyword1; keyword2; keyword3'
123123
});
124124
}));
@@ -133,11 +133,11 @@ describe('MetadataService', () => {
133133
});
134134
tick();
135135
expect(meta.addTag).toHaveBeenCalledWith({
136-
property: 'citation_dissertation_name',
136+
name: 'citation_dissertation_name',
137137
content: 'Test PowerPoint Document'
138138
});
139139
expect(meta.addTag).toHaveBeenCalledWith({
140-
property: 'citation_pdf_url',
140+
name: 'citation_pdf_url',
141141
content: 'https://request.org/bitstreams/4db100c1-e1f5-4055-9404-9bc3e2d15f29/download'
142142
});
143143
}));
@@ -152,7 +152,7 @@ describe('MetadataService', () => {
152152
});
153153
tick();
154154
expect(meta.addTag).toHaveBeenCalledWith({
155-
property: 'citation_technical_report_institution',
155+
name: 'citation_technical_report_institution',
156156
content: 'Mock Publisher'
157157
});
158158
}));
@@ -170,11 +170,11 @@ describe('MetadataService', () => {
170170
tick();
171171
expect(title.setTitle).toHaveBeenCalledWith('DSpace :: Dummy Title');
172172
expect(meta.addTag).toHaveBeenCalledWith({
173-
property: 'title',
173+
name: 'title',
174174
content: 'DSpace :: Dummy Title'
175175
});
176176
expect(meta.addTag).toHaveBeenCalledWith({
177-
property: 'description',
177+
name: 'description',
178178
content: 'This is a dummy item component for testing!'
179179
});
180180
}));
@@ -191,7 +191,7 @@ describe('MetadataService', () => {
191191
metadataService.listenForRouteChange();
192192
tick();
193193
expect(meta.addTag).toHaveBeenCalledWith({
194-
property: 'Generator',
194+
name: 'Generator',
195195
content: 'mock-dspace-version'
196196
});
197197
}));
@@ -208,7 +208,7 @@ describe('MetadataService', () => {
208208
});
209209
tick();
210210
expect(meta.addTag).toHaveBeenCalledWith({
211-
property: 'citation_abstract_html_url',
211+
name: 'citation_abstract_html_url',
212212
content: 'https://ddg.gg'
213213
});
214214
}));
@@ -223,7 +223,7 @@ describe('MetadataService', () => {
223223
});
224224
tick();
225225
expect(meta.addTag).toHaveBeenCalledWith({
226-
property: 'citation_abstract_html_url',
226+
name: 'citation_abstract_html_url',
227227
content: 'https://request.org/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357'
228228
});
229229
}));
@@ -240,11 +240,11 @@ describe('MetadataService', () => {
240240
});
241241
tick();
242242
expect(meta.addTag).toHaveBeenCalledWith({
243-
property: 'citation_dissertation_institution',
243+
name: 'citation_dissertation_institution',
244244
content: 'Mock Publisher'
245245
});
246-
expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ property: 'citation_technical_report_institution' }));
247-
expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ property: 'citation_publisher' }));
246+
expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ name: 'citation_technical_report_institution' }));
247+
expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ name: 'citation_publisher' }));
248248
}));
249249

250250
it('should use citation_tech_report_institution tag for tech reports', fakeAsync(() => {
@@ -256,12 +256,12 @@ describe('MetadataService', () => {
256256
}
257257
});
258258
tick();
259-
expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ property: 'citation_dissertation_institution' }));
259+
expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ name: 'citation_dissertation_institution' }));
260260
expect(meta.addTag).toHaveBeenCalledWith({
261-
property: 'citation_technical_report_institution',
261+
name: 'citation_technical_report_institution',
262262
content: 'Mock Publisher'
263263
});
264-
expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ property: 'citation_publisher' }));
264+
expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ name: 'citation_publisher' }));
265265
}));
266266

267267
it('should use citation_publisher for other item types', fakeAsync(() => {
@@ -273,10 +273,10 @@ describe('MetadataService', () => {
273273
}
274274
});
275275
tick();
276-
expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ property: 'citation_dissertation_institution' }));
277-
expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ property: 'citation_technical_report_institution' }));
276+
expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ name: 'citation_dissertation_institution' }));
277+
expect(meta.addTag).not.toHaveBeenCalledWith(jasmine.objectContaining({ name: 'citation_technical_report_institution' }));
278278
expect(meta.addTag).toHaveBeenCalledWith({
279-
property: 'citation_publisher',
279+
name: 'citation_publisher',
280280
content: 'Mock Publisher'
281281
});
282282
}));
@@ -295,7 +295,7 @@ describe('MetadataService', () => {
295295
});
296296
tick();
297297
expect(meta.addTag).toHaveBeenCalledWith({
298-
property: 'citation_pdf_url',
298+
name: 'citation_pdf_url',
299299
content: 'https://request.org/bitstreams/4db100c1-e1f5-4055-9404-9bc3e2d15f29/download'
300300
});
301301
}));
@@ -313,7 +313,7 @@ describe('MetadataService', () => {
313313
});
314314
tick();
315315
expect(meta.addTag).toHaveBeenCalledWith({
316-
property: 'citation_pdf_url',
316+
name: 'citation_pdf_url',
317317
content: 'https://request.org/bitstreams/4db100c1-e1f5-4055-9404-9bc3e2d15f29/download'
318318
});
319319
}));
@@ -334,7 +334,7 @@ describe('MetadataService', () => {
334334
});
335335
tick();
336336
expect(meta.addTag).toHaveBeenCalledWith({
337-
property: 'citation_pdf_url',
337+
name: 'citation_pdf_url',
338338
content: 'https://request.org/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713/download'
339339
});
340340
}));
@@ -354,8 +354,8 @@ describe('MetadataService', () => {
354354
}));
355355

356356
it('should remove previous tags on route change', fakeAsync(() => {
357-
expect(meta.removeTag).toHaveBeenCalledWith('property=\'title\'');
358-
expect(meta.removeTag).toHaveBeenCalledWith('property=\'description\'');
357+
expect(meta.removeTag).toHaveBeenCalledWith('name=\'title\'');
358+
expect(meta.removeTag).toHaveBeenCalledWith('name=\'description\'');
359359
}));
360360

361361
it('should clear all tags and add new ones on route change', () => {

src/app/core/metadata/metadata.service.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ export class MetadataService {
403403
*/
404404
private setGenerator(): void {
405405
this.rootService.findRoot().pipe(getFirstSucceededRemoteDataPayload()).subscribe((root) => {
406-
this.meta.addTag({ property: 'Generator', content: root.dspaceVersion });
406+
this.meta.addTag({ name: 'Generator', content: root.dspaceVersion });
407407
});
408408
}
409409

@@ -447,17 +447,17 @@ export class MetadataService {
447447
return this.currentObject.value.allMetadataValues(keys);
448448
}
449449

450-
private addMetaTag(property: string, content: string): void {
450+
private addMetaTag(name: string, content: string): void {
451451
if (content) {
452-
const tag = { property, content } as MetaDefinition;
452+
const tag = { name, content } as MetaDefinition;
453453
this.meta.addTag(tag);
454-
this.storeTag(property);
454+
this.storeTag(name);
455455
}
456456
}
457457

458-
private addMetaTags(property: string, content: string[]): void {
458+
private addMetaTags(name: string, content: string[]): void {
459459
for (const value of content) {
460-
this.addMetaTag(property, value);
460+
this.addMetaTag(name, value);
461461
}
462462
}
463463

@@ -470,8 +470,8 @@ export class MetadataService {
470470
select(tagsInUseSelector),
471471
take(1)
472472
).subscribe((tagsInUse: string[]) => {
473-
for (const property of tagsInUse) {
474-
this.meta.removeTag('property=\'' + property + '\'');
473+
for (const name of tagsInUse) {
474+
this.meta.removeTag('name=\'' + name + '\'');
475475
}
476476
this.store.dispatch(new ClearMetaTagAction());
477477
});

0 commit comments

Comments
 (0)