From e10630f131e71a61e1eec617fb0eed7ba7572e68 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 12 Apr 2024 01:38:34 +0200 Subject: [PATCH] Added functionality to disable COAR notify support link in footer Also fixed error that showed a blank page instead of a 404 when disabling EULA/Privacy Policy pages --- config/config.example.yml | 3 +- src/app/app-routing-paths.ts | 1 - src/app/footer/footer.component.html | 4 +- src/app/footer/footer.component.spec.ts | 46 +++++-------------- src/app/footer/footer.component.ts | 36 ++++++++++----- src/app/info/info-routes.ts | 25 +++++++++- src/app/info/info-routing-paths.ts | 5 ++ .../notify-info/notify-info.component.html | 0 .../notify-info/notify-info.component.scss | 0 .../notify-info/notify-info.component.spec.ts | 4 +- .../notify-info/notify-info.component.ts | 2 +- src/assets/i18n/en.json5 | 10 ++-- src/config/default-app-config.ts | 4 ++ src/config/info-config.interface.ts | 1 + src/environments/environment.test.ts | 1 + 15 files changed, 83 insertions(+), 59 deletions(-) rename src/app/{core/coar-notify => info}/notify-info/notify-info.component.html (100%) rename src/app/{core/coar-notify => info}/notify-info/notify-info.component.scss (100%) rename src/app/{core/coar-notify => info}/notify-info/notify-info.component.spec.ts (87%) rename src/app/{core/coar-notify => info}/notify-info/notify-info.component.ts (93%) diff --git a/config/config.example.yml b/config/config.example.yml index 407b5b958ed..82c061dab22 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -407,10 +407,11 @@ mediaViewer: # Whether the end user agreement is required before users use the repository. # If enabled, the user will be required to accept the agreement before they can use the repository. -# And whether the privacy statement should exist or not. +# And whether the privacy statement/COAR notify support page should exist or not. info: enableEndUserAgreement: true enablePrivacyStatement: true + enableCOARNotifySupport: true # Whether to enable Markdown (https://commonmark.org/) and MathJax (https://www.mathjax.org/) # display in supported metadata fields. By default, only dc.description.abstract is supported. diff --git a/src/app/app-routing-paths.ts b/src/app/app-routing-paths.ts index d6df53ffaf4..7d202f16e9c 100644 --- a/src/app/app-routing-paths.ts +++ b/src/app/app-routing-paths.ts @@ -34,7 +34,6 @@ export function getBitstreamRequestACopyRoute(item, bitstream): { routerLink: st }, }; } -export const COAR_NOTIFY_SUPPORT = 'coar-notify-support'; export const HOME_PAGE_PATH = 'home'; diff --git a/src/app/footer/footer.component.html b/src/app/footer/footer.component.html index b937b2ce60c..35487f91ae2 100644 --- a/src/app/footer/footer.component.html +++ b/src/app/footer/footer.component.html @@ -82,10 +82,10 @@
Footer Content
-
+
diff --git a/src/app/footer/footer.component.spec.ts b/src/app/footer/footer.component.spec.ts index 8608eeaf5e3..527e5703643 100644 --- a/src/app/footer/footer.component.spec.ts +++ b/src/app/footer/footer.component.spec.ts @@ -1,9 +1,3 @@ -// ... test imports -import { CommonModule } from '@angular/common'; -import { - CUSTOM_ELEMENTS_SCHEMA, - DebugElement, -} from '@angular/core'; import { ComponentFixture, fakeAsync, @@ -13,28 +7,19 @@ import { } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { ActivatedRoute } from '@angular/router'; -import { StoreModule } from '@ngrx/store'; -import { - TranslateLoader, - TranslateModule, -} from '@ngx-translate/core'; +import { TranslateModule } from '@ngx-translate/core'; import { of } from 'rxjs'; -import { environment } from 'src/environments/environment'; -import { storeModuleConfig } from '../app.reducer'; +import { APP_CONFIG } from '../../config/app-config.interface'; +import { environment } from '../../environments/environment.test'; import { NotifyInfoService } from '../core/coar-notify/notify-info/notify-info.service'; import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service'; -import { TranslateLoaderMock } from '../shared/mocks/translate-loader.mock'; import { ActivatedRouteStub } from '../shared/testing/active-router.stub'; import { AuthorizationDataServiceStub } from '../shared/testing/authorization-service.stub'; -// Load the implementations that should be tested import { FooterComponent } from './footer.component'; let comp: FooterComponent; -let compAny: any; let fixture: ComponentFixture; -let de: DebugElement; -let el: HTMLElement; let notifyInfoService = { isCoarConfigEnabled: () => of(true), @@ -43,19 +28,16 @@ let notifyInfoService = { describe('Footer component', () => { beforeEach(waitForAsync(() => { return TestBed.configureTestingModule({ - imports: [CommonModule, StoreModule.forRoot({}, storeModuleConfig), TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useClass: TranslateLoaderMock, - }, - }), FooterComponent], + imports: [ + TranslateModule.forRoot(), + ], providers: [ FooterComponent, { provide: AuthorizationDataService, useClass: AuthorizationDataServiceStub }, { provide: NotifyInfoService, useValue: notifyInfoService }, { provide: ActivatedRoute, useValue: new ActivatedRouteStub() }, + { provide: APP_CONFIG, useValue: environment }, ], - schemas: [CUSTOM_ELEMENTS_SCHEMA], }); })); @@ -63,10 +45,6 @@ describe('Footer component', () => { beforeEach(() => { fixture = TestBed.createComponent(FooterComponent); comp = fixture.componentInstance; - compAny = comp as any; - // query for the title

by CSS element selector - de = fixture.debugElement.query(By.css('p')); - el = de.nativeElement; }); it('should create footer', inject([FooterComponent], (app: FooterComponent) => { @@ -76,23 +54,25 @@ describe('Footer component', () => { it('should set showPrivacyPolicy to the value of environment.info.enablePrivacyStatement', () => { + comp.ngOnInit(); expect(comp.showPrivacyPolicy).toBe(environment.info.enablePrivacyStatement); }); it('should set showEndUserAgreement to the value of environment.info.enableEndUserAgreement', () => { + comp.ngOnInit(); expect(comp.showEndUserAgreement).toBe(environment.info.enableEndUserAgreement); }); describe('showCookieSettings', () => { it('should call cookies.showSettings() if cookies is defined', () => { const cookies = jasmine.createSpyObj('cookies', ['showSettings']); - compAny.cookies = cookies; + comp.cookies = cookies; comp.showCookieSettings(); expect(cookies.showSettings).toHaveBeenCalled(); }); it('should not call cookies.showSettings() if cookies is undefined', () => { - compAny.cookies = undefined; + comp.cookies = undefined; expect(() => comp.showCookieSettings()).not.toThrow(); }); @@ -107,9 +87,7 @@ describe('Footer component', () => { fixture.detectChanges(); }); - it('should set coarLdnEnabled based on notifyInfoService', () => { - expect(comp.coarLdnEnabled).toBeTruthy(); - // Check if COAR Notify section is rendered + it('should render COAR notify support link', () => { const notifySection = fixture.debugElement.query(By.css('.notify-enabled')); expect(notifySection).toBeTruthy(); }); diff --git a/src/app/footer/footer.component.ts b/src/app/footer/footer.component.ts index 3043cf32847..f9fdde78346 100644 --- a/src/app/footer/footer.component.ts +++ b/src/app/footer/footer.component.ts @@ -5,13 +5,21 @@ import { } from '@angular/common'; import { Component, + Inject, + OnInit, Optional, } from '@angular/core'; import { RouterLink } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; -import { Observable } from 'rxjs'; +import { + Observable, + of as observableOf, +} from 'rxjs'; -import { environment } from '../../environments/environment'; +import { + APP_CONFIG, + AppConfig, +} from '../../config/app-config.interface'; import { NotifyInfoService } from '../core/coar-notify/notify-info/notify-info.service'; import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../core/data/feature-authorization/feature-id'; @@ -25,27 +33,31 @@ import { hasValue } from '../shared/empty.util'; standalone: true, imports: [NgIf, RouterLink, AsyncPipe, DatePipe, TranslateModule], }) -export class FooterComponent { +export class FooterComponent implements OnInit { dateObj: number = Date.now(); /** * A boolean representing if to show or not the top footer container */ showTopFooter = false; - showPrivacyPolicy = environment.info.enablePrivacyStatement; - showEndUserAgreement = environment.info.enableEndUserAgreement; + showPrivacyPolicy: boolean; + showEndUserAgreement: boolean; showSendFeedback$: Observable; - coarLdnEnabled: boolean; + coarLdnEnabled$: Observable; constructor( - @Optional() private cookies: KlaroService, - private authorizationService: AuthorizationDataService, - private notifyInfoService: NotifyInfoService, + @Optional() public cookies: KlaroService, + protected authorizationService: AuthorizationDataService, + protected notifyInfoService: NotifyInfoService, + @Inject(APP_CONFIG) protected appConfig: AppConfig, ) { + } + + ngOnInit(): void { + this.showPrivacyPolicy = this.appConfig.info.enablePrivacyStatement; + this.showEndUserAgreement = this.appConfig.info.enableEndUserAgreement; + this.coarLdnEnabled$ = this.appConfig.info.enableCOARNotifySupport ? this.notifyInfoService.isCoarConfigEnabled() : observableOf(false); this.showSendFeedback$ = this.authorizationService.isAuthorized(FeatureID.CanSendFeedback); - this.notifyInfoService.isCoarConfigEnabled().subscribe(coarLdnEnabled => { - this.coarLdnEnabled = coarLdnEnabled; - }); } showCookieSettings() { diff --git a/src/app/info/info-routes.ts b/src/app/info/info-routes.ts index 423a93ea451..8d70ac740fc 100644 --- a/src/app/info/info-routes.ts +++ b/src/app/info/info-routes.ts @@ -1,17 +1,26 @@ +import { + Route, + Routes, +} from '@angular/router'; + import { environment } from '../../environments/environment'; import { i18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver'; +import { notifyInfoGuard } from '../core/coar-notify/notify-info/notify-info.guard'; import { feedbackGuard } from '../core/feedback/feedback.guard'; +import { hasValue } from '../shared/empty.util'; import { ThemedEndUserAgreementComponent } from './end-user-agreement/themed-end-user-agreement.component'; import { ThemedFeedbackComponent } from './feedback/themed-feedback.component'; import { + COAR_NOTIFY_SUPPORT, END_USER_AGREEMENT_PATH, FEEDBACK_PATH, PRIVACY_PATH, } from './info-routing-paths'; +import { NotifyInfoComponent } from './notify-info/notify-info.component'; import { ThemedPrivacyComponent } from './privacy/themed-privacy.component'; -export const ROUTES = [ +export const ROUTES: Routes = [ { path: FEEDBACK_PATH, component: ThemedFeedbackComponent, @@ -31,4 +40,16 @@ export const ROUTES = [ resolve: { breadcrumb: i18nBreadcrumbResolver }, data: { title: 'info.privacy.title', breadcrumbKey: 'info.privacy' }, } : undefined, -]; + environment.info.enableCOARNotifySupport ? { + path: COAR_NOTIFY_SUPPORT, + component: NotifyInfoComponent, + canActivate: [notifyInfoGuard], + resolve: { + breadcrumb: i18nBreadcrumbResolver, + }, + data: { + title: 'info.coar-notify-support.title', + breadcrumbKey: 'info.coar-notify-support', + }, + } : undefined, +].filter((route: Route) => hasValue(route)); diff --git a/src/app/info/info-routing-paths.ts b/src/app/info/info-routing-paths.ts index a7fba45a6c3..cd42dd9c1d4 100644 --- a/src/app/info/info-routing-paths.ts +++ b/src/app/info/info-routing-paths.ts @@ -3,6 +3,7 @@ import { getInfoModulePath } from '../app-routing-paths'; export const END_USER_AGREEMENT_PATH = 'end-user-agreement'; export const PRIVACY_PATH = 'privacy'; export const FEEDBACK_PATH = 'feedback'; +export const COAR_NOTIFY_SUPPORT = 'coar-notify-support'; export function getEndUserAgreementPath() { return getSubPath(END_USER_AGREEMENT_PATH); @@ -16,6 +17,10 @@ export function getFeedbackPath() { return getSubPath(FEEDBACK_PATH); } +export function getCOARNotifySupportPath(): string { + return getSubPath(COAR_NOTIFY_SUPPORT); +} + function getSubPath(path: string) { return `${getInfoModulePath()}/${path}`; } diff --git a/src/app/core/coar-notify/notify-info/notify-info.component.html b/src/app/info/notify-info/notify-info.component.html similarity index 100% rename from src/app/core/coar-notify/notify-info/notify-info.component.html rename to src/app/info/notify-info/notify-info.component.html diff --git a/src/app/core/coar-notify/notify-info/notify-info.component.scss b/src/app/info/notify-info/notify-info.component.scss similarity index 100% rename from src/app/core/coar-notify/notify-info/notify-info.component.scss rename to src/app/info/notify-info/notify-info.component.scss diff --git a/src/app/core/coar-notify/notify-info/notify-info.component.spec.ts b/src/app/info/notify-info/notify-info.component.spec.ts similarity index 87% rename from src/app/core/coar-notify/notify-info/notify-info.component.spec.ts rename to src/app/info/notify-info/notify-info.component.spec.ts index 337a874866a..010227b326a 100644 --- a/src/app/core/coar-notify/notify-info/notify-info.component.spec.ts +++ b/src/app/info/notify-info/notify-info.component.spec.ts @@ -6,9 +6,9 @@ import { ActivatedRoute } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; import { of } from 'rxjs'; -import { ActivatedRouteStub } from '../../../shared/testing/active-router.stub'; +import { NotifyInfoService } from '../../core/coar-notify/notify-info/notify-info.service'; +import { ActivatedRouteStub } from '../../shared/testing/active-router.stub'; import { NotifyInfoComponent } from './notify-info.component'; -import { NotifyInfoService } from './notify-info.service'; describe('NotifyInfoComponent', () => { let component: NotifyInfoComponent; diff --git a/src/app/core/coar-notify/notify-info/notify-info.component.ts b/src/app/info/notify-info/notify-info.component.ts similarity index 93% rename from src/app/core/coar-notify/notify-info/notify-info.component.ts rename to src/app/info/notify-info/notify-info.component.ts index 9822a07f9ba..38bbf445951 100644 --- a/src/app/core/coar-notify/notify-info/notify-info.component.ts +++ b/src/app/info/notify-info/notify-info.component.ts @@ -11,7 +11,7 @@ import { of, } from 'rxjs'; -import { NotifyInfoService } from './notify-info.service'; +import { NotifyInfoService } from '../../core/coar-notify/notify-info/notify-info.service'; @Component({ selector: 'ds-notify-info', diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 43e1d48fb0e..d4731f9bb92 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1886,6 +1886,8 @@ "footer.link.feedback": "Send Feedback", + "footer.link.coar-notify-support": "COAR Notify", + "forgot-email.form.header": "Forgot Password", "forgot-email.form.info": "Enter the email address associated with the account.", @@ -2150,6 +2152,10 @@ "info.feedback.page_help": "The page related to your feedback", + "info.coar-notify-support.title": "COAR Notify Support", + + "info.coar-notify-support.breadcrumbs": "COAR Notify Support", + "item.alerts.private": "This item is non-discoverable", "item.alerts.withdrawn": "This item has been withdrawn", @@ -6173,10 +6179,6 @@ "ldn-register-new-service.notification.success.title": "Success", "ldn-register-new-service.notification.success.content": "The process was successfully created", - "info.coar-notify-support.title": "Notify Support", - - "info.coar-notify.breadcrumbs": "Notify Support", - "submission.sections.notify.info": "The selected service is compatible with the item according to its current status. {{ service.name }}: {{ service.description }}", "item.page.endorsement": "Endorsement", diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index d148dee148c..d826c9848b3 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -468,9 +468,13 @@ export class DefaultAppConfig implements AppConfig { // Disabling the privacy policy feature will result in: // - A 404 page if you manually try to navigate to the privacy policy page at info/privacy // - All mentions of the privacy policy being removed from the UI (e.g. in the footer) + // Disabling the COAR notify support page feature will result in: + // - A 404 page if you manually try to navigate to the COAR notify support page + // - All mentions of the COAR notify support page being removed from the UI (e.g. in the footer) info: InfoConfig = { enableEndUserAgreement: true, enablePrivacyStatement: true, + enableCOARNotifySupport: true, }; // Whether to enable Markdown (https://commonmark.org/) and MathJax (https://www.mathjax.org/) diff --git a/src/config/info-config.interface.ts b/src/config/info-config.interface.ts index b1831962b5b..445936ff0a1 100644 --- a/src/config/info-config.interface.ts +++ b/src/config/info-config.interface.ts @@ -3,4 +3,5 @@ import { Config } from './config.interface'; export interface InfoConfig extends Config { enableEndUserAgreement: boolean; enablePrivacyStatement: boolean; + enableCOARNotifySupport: boolean; } diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index 0fc03f2a4cb..3610755bb12 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -314,6 +314,7 @@ export const environment: BuildConfig = { info: { enableEndUserAgreement: true, enablePrivacyStatement: true, + enableCOARNotifySupport: true, }, markdown: { enabled: false,