diff --git a/src/app/static-page/static-page.component.html b/src/app/static-page/static-page.component.html index 99b85f71fb9..f6fe86f806e 100644 --- a/src/app/static-page/static-page.component.html +++ b/src/app/static-page/static-page.component.html @@ -1,3 +1,21 @@ -
+ +
+ +
+ + +
+ + +
+

404

+

{{"404.page-not-found" | translate}}

+
+

{{"404.help" | translate}}

+
+

+ {{"404.link.home-page" | translate}} +

+
diff --git a/src/app/static-page/static-page.component.spec.ts b/src/app/static-page/static-page.component.spec.ts index 1ad4e607c3c..a005ae5177f 100644 --- a/src/app/static-page/static-page.component.spec.ts +++ b/src/app/static-page/static-page.component.spec.ts @@ -1,4 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { StaticPageComponent } from './static-page.component'; import { HtmlContentService } from '../shared/html-content.service'; @@ -9,12 +11,14 @@ import { of } from 'rxjs'; import { APP_CONFIG } from '../../config/app-config.interface'; import { environment } from '../../environments/environment'; import { ClarinSafeHtmlPipe } from '../shared/utils/clarin-safehtml.pipe'; +import { ServerResponseService } from '../core/services/server-response.service'; describe('StaticPageComponent', () => { let component: StaticPageComponent; let fixture: ComponentFixture; - let htmlContentService: HtmlContentService; + let htmlContentService: jasmine.SpyObj; + let responseService: jasmine.SpyObj; let appConfig: any; const htmlContent = '
TEST MESSAGE
'; @@ -25,6 +29,8 @@ describe('StaticPageComponent', () => { getHmtlContentByPathAndLocale: Promise.resolve(htmlContent) }); + responseService = jasmine.createSpyObj('responseService', ['setNotFound']); + appConfig = Object.assign(environment, { ui: { namespace: 'testNamespace' @@ -34,13 +40,16 @@ describe('StaticPageComponent', () => { TestBed.configureTestingModule({ declarations: [ StaticPageComponent, ClarinSafeHtmlPipe ], imports: [ + CommonModule, TranslateModule.forRoot() ], providers: [ { provide: HtmlContentService, useValue: htmlContentService }, { provide: Router, useValue: new RouterMock() }, + { provide: ServerResponseService, useValue: responseService }, { provide: APP_CONFIG, useValue: appConfig } - ] + ], + schemas: [NO_ERRORS_SCHEMA] }); }); @@ -58,5 +67,14 @@ describe('StaticPageComponent', () => { it('should load html file content', async () => { await component.ngOnInit(); expect(component.htmlContent.value).toBe('
TEST MESSAGE
'); + expect(component.contentState).toBe('found'); + }); + + // When the file is missing, set a 404 status for SSR and switch to the not-found state + it('should set 404 status when content is not found', async () => { + htmlContentService.getHmtlContentByPathAndLocale.and.returnValue(Promise.resolve(undefined)); + await component.ngOnInit(); + expect(responseService.setNotFound).toHaveBeenCalled(); + expect(component.contentState).toBe('not-found'); }); }); diff --git a/src/app/static-page/static-page.component.ts b/src/app/static-page/static-page.component.ts index bb19403a704..05e6198131b 100644 --- a/src/app/static-page/static-page.component.ts +++ b/src/app/static-page/static-page.component.ts @@ -1,10 +1,11 @@ -import { Component, Inject, OnInit } from '@angular/core'; +import { ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core'; import { HtmlContentService } from '../shared/html-content.service'; -import { BehaviorSubject, firstValueFrom } from 'rxjs'; +import { BehaviorSubject } from 'rxjs'; import { Router } from '@angular/router'; import { isEmpty, isNotEmpty } from '../shared/empty.util'; -import { STATIC_FILES_DEFAULT_ERROR_PAGE_PATH, STATIC_PAGE_PATH } from './static-page-routing-paths'; +import { STATIC_PAGE_PATH } from './static-page-routing-paths'; import { APP_CONFIG, AppConfig } from '../../config/app-config.interface'; +import { ServerResponseService } from '../core/services/server-response.service'; /** * Component which load and show static files from the `static-files` folder. @@ -19,9 +20,12 @@ export class StaticPageComponent implements OnInit { static readonly no_static: string = 'no_static_'; htmlContent: BehaviorSubject = new BehaviorSubject(''); htmlFileName: string; + contentState: 'loading' | 'found' | 'not-found' = 'loading'; constructor(private htmlContentService: HtmlContentService, private router: Router, + private responseService: ServerResponseService, + private changeDetector: ChangeDetectorRef, @Inject(APP_CONFIG) protected appConfig?: AppConfig) { } async ngOnInit(): Promise { @@ -31,11 +35,15 @@ export class StaticPageComponent implements OnInit { const htmlContent = await this.htmlContentService.getHmtlContentByPathAndLocale(this.htmlFileName); if (isNotEmpty(htmlContent)) { this.htmlContent.next(htmlContent); + this.contentState = 'found'; + this.changeDetector.detectChanges(); return; } - // Show error page - await this.loadErrorPage(); + // Content not found - set 404 status for SSR and show the inline 404 page + this.responseService.setNotFound(); + this.contentState = 'not-found'; + this.changeDetector.detectChanges(); } /** @@ -119,24 +127,10 @@ export class StaticPageComponent implements OnInit { urlInList = urlInList.filter(n => n); // if length is 1 - html file name wasn't defined. if (isEmpty(urlInList) || urlInList.length === 1) { - void this.loadErrorPage(); return null; } // If the url is too long take just the first string after `/static` prefix. return urlInList[1]?.split('#')?.[0]; } - - /** - * Load `static-files/error.html` - * @private - */ - private async loadErrorPage() { - let errorPage = await firstValueFrom(this.htmlContentService.fetchHtmlContent(STATIC_FILES_DEFAULT_ERROR_PAGE_PATH)); - if (isEmpty(errorPage)) { - console.error('Cannot load error page from the path: ' + STATIC_FILES_DEFAULT_ERROR_PAGE_PATH); - return; - } - this.htmlContent.next(errorPage); - } }