From b62a4f6c538077f37295ce9b131af1fc65aff20a Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Tue, 18 Oct 2022 12:58:49 +0200 Subject: [PATCH 01/25] [CST-6171] Navbar border --- src/app/navbar/navbar.component.scss | 2 +- src/themes/dspace/app/navbar/navbar.component.scss | 2 +- src/themes/dspace/styles/_theme_css_variable_overrides.scss | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/navbar/navbar.component.scss b/src/app/navbar/navbar.component.scss index 3a9a302b06..320ce414ec 100644 --- a/src/app/navbar/navbar.component.scss +++ b/src/app/navbar/navbar.component.scss @@ -1,5 +1,5 @@ nav.navbar { - border-bottom: 1px var(--bs-gray-400) solid; + border-bottom: 1px var(--ds-header-navbar-border-bottom-color) solid; align-items: baseline; } diff --git a/src/themes/dspace/app/navbar/navbar.component.scss b/src/themes/dspace/app/navbar/navbar.component.scss index 1ad95cb8aa..45d188a264 100644 --- a/src/themes/dspace/app/navbar/navbar.component.scss +++ b/src/themes/dspace/app/navbar/navbar.component.scss @@ -1,6 +1,6 @@ nav.navbar { border-top: 1px var(--ds-header-navbar-border-top-color) solid; - border-bottom: 5px var(--bs-green) solid; + border-bottom: 5px var(--ds-header-navbar-border-bottom-color) solid; align-items: baseline; color: var(--ds-header-icon-color); } diff --git a/src/themes/dspace/styles/_theme_css_variable_overrides.scss b/src/themes/dspace/styles/_theme_css_variable_overrides.scss index e4b4b61f45..516eff9f7e 100644 --- a/src/themes/dspace/styles/_theme_css_variable_overrides.scss +++ b/src/themes/dspace/styles/_theme_css_variable_overrides.scss @@ -6,5 +6,6 @@ --ds-banner-background-gradient-width: 300px; --ds-home-news-link-color: #{$green}; --ds-home-news-link-hover-color: #{darken($green, 15%)}; + --ds-header-navbar-border-bottom-color: #{$green}; } From a69f61e4f36730ec3204a8092259b07c659cd263 Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Wed, 19 Oct 2022 00:58:59 +0200 Subject: [PATCH 02/25] [CST-6171] Item status type badge colors --- .../my-dspace-item-status.component.spec.ts | 10 ++++---- .../my-dspace-item-status.component.ts | 10 ++++---- src/styles/_global-styles.scss | 24 +++++++++++++++++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.spec.ts b/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.spec.ts index 44e6a44b70..59fc29424d 100644 --- a/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.spec.ts +++ b/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.spec.ts @@ -55,34 +55,34 @@ describe('MyDSpaceItemStatusComponent', () => { component.status = MyDspaceItemStatusType.VALIDATION; fixture.detectChanges(); expect(component.badgeContent).toBe(MyDspaceItemStatusType.VALIDATION); - expect(component.badgeClass).toBe('text-light badge badge-warning'); + expect(component.badgeClass).toBe('text-light badge badge-validation'); }); it('should init badge content and class', () => { component.status = MyDspaceItemStatusType.WAITING_CONTROLLER; fixture.detectChanges(); expect(component.badgeContent).toBe(MyDspaceItemStatusType.WAITING_CONTROLLER); - expect(component.badgeClass).toBe('text-light badge badge-info'); + expect(component.badgeClass).toBe('text-light badge badge-waiting-controller'); }); it('should init badge content and class', () => { component.status = MyDspaceItemStatusType.WORKSPACE; fixture.detectChanges(); expect(component.badgeContent).toBe(MyDspaceItemStatusType.WORKSPACE); - expect(component.badgeClass).toBe('text-light badge badge-primary'); + expect(component.badgeClass).toBe('text-light badge badge-workspace'); }); it('should init badge content and class', () => { component.status = MyDspaceItemStatusType.ARCHIVED; fixture.detectChanges(); expect(component.badgeContent).toBe(MyDspaceItemStatusType.ARCHIVED); - expect(component.badgeClass).toBe('text-light badge badge-success'); + expect(component.badgeClass).toBe('text-light badge badge-archived'); }); it('should init badge content and class', () => { component.status = MyDspaceItemStatusType.WORKFLOW; fixture.detectChanges(); expect(component.badgeContent).toBe(MyDspaceItemStatusType.WORKFLOW); - expect(component.badgeClass).toBe('text-light badge badge-info'); + expect(component.badgeClass).toBe('text-light badge badge-workflow'); }); }); diff --git a/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.ts b/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.ts index 917dd45acc..83b2656fbd 100644 --- a/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.ts +++ b/src/app/shared/object-collection/shared/mydspace-item-status/my-dspace-item-status.component.ts @@ -34,19 +34,19 @@ export class MyDSpaceItemStatusComponent implements OnInit { this.badgeClass = 'text-light badge '; switch (this.status) { case MyDspaceItemStatusType.VALIDATION: - this.badgeClass += 'badge-warning'; + this.badgeClass += 'badge-validation'; break; case MyDspaceItemStatusType.WAITING_CONTROLLER: - this.badgeClass += 'badge-info'; + this.badgeClass += 'badge-waiting-controller'; break; case MyDspaceItemStatusType.WORKSPACE: - this.badgeClass += 'badge-primary'; + this.badgeClass += 'badge-workspace'; break; case MyDspaceItemStatusType.ARCHIVED: - this.badgeClass += 'badge-success'; + this.badgeClass += 'badge-archived'; break; case MyDspaceItemStatusType.WORKFLOW: - this.badgeClass += 'badge-info'; + this.badgeClass += 'badge-workflow'; break; } } diff --git a/src/styles/_global-styles.scss b/src/styles/_global-styles.scss index 930384cf64..1bc0c8c435 100644 --- a/src/styles/_global-styles.scss +++ b/src/styles/_global-styles.scss @@ -204,3 +204,27 @@ ds-dynamic-form-control-container.d-none { } + +.badge-validation { + background-color: #{map-get($theme-colors, warning)}; +} + +.badge-waiting-controller { + background-color: #{map-get($theme-colors, info)}; +} + +.badge-workspace { + background-color: #{map-get($theme-colors, primary)}; +} + +.badge-archived { + background-color: #{map-get($theme-colors, success)}; +} + +.badge-workflow { + background-color: #{map-get($theme-colors, info)}; +} + +.badge-item-type { + background-color: #{map-get($theme-colors, info)}; +} From f109e97a0ca61b8c4a520f6661d17f25b894b861 Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Fri, 21 Oct 2022 12:50:59 +0200 Subject: [PATCH 03/25] [CST-6171] Semantic color scheme --- .../styles/_theme_sass_variable_overrides.scss | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/themes/dspace/styles/_theme_sass_variable_overrides.scss b/src/themes/dspace/styles/_theme_sass_variable_overrides.scss index 9257bc46dd..b5799c9749 100644 --- a/src/themes/dspace/styles/_theme_sass_variable_overrides.scss +++ b/src/themes/dspace/styles/_theme_sass_variable_overrides.scss @@ -10,7 +10,7 @@ $font-family-sans-serif: 'Nunito', -apple-system, BlinkMacSystemFont, "Segoe UI" $navbar-dark-color: #FFFFFF; /* Reassign color vars to semantic color scheme */ -$blue: #43515f !default; +$blue: #2b4e72 !default; $green: #92C642 !default; $cyan: #207698 !default; $yellow: #ec9433 !default; @@ -18,6 +18,7 @@ $red: #CF4444 !default; $dark: #43515f !default; $gray-800: #343a40 !default; +$gray-700: #495057 !default; $gray-400: #ced4da !default; $gray-100: #f8f9fa !default; @@ -27,3 +28,14 @@ $table-accent-bg: $gray-100 !default; // Bootstrap $gray-100 $table-hover-bg: $gray-400 !default; // Bootstrap $gray-400 $yiq-contrasted-threshold: 170 !default; + +$theme-colors: ( + primary: $dark, + secondary: $gray-700, + success: $green, + info: $cyan, + warning: $yellow, + danger: $red, + light: $gray-100, + dark: $dark +) !default; From e6065b7504867334690cc7748f1dacbb8c8ad769 Mon Sep 17 00:00:00 2001 From: Ying Jin Date: Wed, 16 Nov 2022 10:34:00 -0600 Subject: [PATCH 04/25] add captioning support for video/audio files --- .../core/shared/media-viewer-item.model.ts | 5 + .../media-viewer-video/caption-info.ts | 4 + .../media-viewer-video/language-helper.ts | 190 ++++++++++++++++++ .../media-viewer-video.component.html | 11 +- .../media-viewer-video.component.ts | 38 +++- .../media-viewer/media-viewer.component.ts | 1 + 6 files changed, 245 insertions(+), 4 deletions(-) create mode 100644 src/app/item-page/media-viewer/media-viewer-video/caption-info.ts create mode 100644 src/app/item-page/media-viewer/media-viewer-video/language-helper.ts diff --git a/src/app/core/shared/media-viewer-item.model.ts b/src/app/core/shared/media-viewer-item.model.ts index cd3a31bd0b..38c53944d1 100644 --- a/src/app/core/shared/media-viewer-item.model.ts +++ b/src/app/core/shared/media-viewer-item.model.ts @@ -14,6 +14,11 @@ export class MediaViewerItem { */ format: string; + /** + * Incoming Bitsream format mime type + */ + minetype: string; + /** * Incoming Bitsream thumbnail */ diff --git a/src/app/item-page/media-viewer/media-viewer-video/caption-info.ts b/src/app/item-page/media-viewer/media-viewer-video/caption-info.ts new file mode 100644 index 0000000000..011249027f --- /dev/null +++ b/src/app/item-page/media-viewer/media-viewer-video/caption-info.ts @@ -0,0 +1,4 @@ +export class CaptionInfo { + constructor(public src: string, public srclang: string, public langLabel: string ) { + } +} diff --git a/src/app/item-page/media-viewer/media-viewer-video/language-helper.ts b/src/app/item-page/media-viewer/media-viewer-video/language-helper.ts new file mode 100644 index 0000000000..b27ab9983f --- /dev/null +++ b/src/app/item-page/media-viewer/media-viewer-video/language-helper.ts @@ -0,0 +1,190 @@ +export const languageHelper = { + ab: 'Abkhazian', + aa: 'Afar', + af: 'Afrikaans', + ak: 'Akan', + sq: 'Albanian', + am: 'Amharic', + ar: 'Arabic', + an: 'Aragonese', + hy: 'Armenian', + as: 'Assamese', + av: 'Avaric', + ae: 'Avestan', + ay: 'Aymara', + az: 'Azerbaijani', + bm: 'Bambara', + ba: 'Bashkir', + eu: 'Basque', + be: 'Belarusian', + bn: 'Bengali (Bangla)', + bh: 'Bihari', + bi: 'Bislama', + bs: 'Bosnian', + br: 'Breton', + bg: 'Bulgarian', + my: 'Burmese', + ca: 'Catalan', + ch: 'Chamorro', + ce: 'Chechen', + ny: 'Chichewa, Chewa, Nyanja', + zh: 'Chinese', + cv: 'Chuvash', + kw: 'Cornish', + co: 'Corsican', + cr: 'Cree', + hr: 'Croatian', + cs: 'Czech', + da: 'Danish', + dv: 'Divehi, Dhivehi, Maldivian', + nl: 'Dutch', + dz: 'Dzongkha', + en: 'English', + eo: 'Esperanto', + et: 'Estonian', + ee: 'Ewe', + fo: 'Faroese', + fj: 'Fijian', + fi: 'Finnish', + fr: 'French', + ff: 'Fula, Fulah, Pulaar, Pular', + gl: 'Galician', + gd: 'Gaelic (Scottish)', + gv: 'Gaelic (Manx)', + ka: 'Georgian', + de: 'German', + el: 'Greek', + gn: 'Guarani', + gu: 'Gujarati', + ht: 'Haitian Creole', + ha: 'Hausa', + he: 'Hebrew', + hz: 'Herero', + hi: 'Hindi', + ho: 'Hiri Motu', + hu: 'Hungarian', + is: 'Icelandic', + io: 'Ido', + ig: 'Igbo', + in: 'Indonesian', + ia: 'Interlingua', + ie: 'Interlingue', + iu: 'Inuktitut', + ik: 'Inupiak', + ga: 'Irish', + it: 'Italian', + ja: 'Japanese', + jv: 'Javanese', + kl: 'Kalaallisut, Greenlandic', + kn: 'Kannada', + kr: 'Kanuri', + ks: 'Kashmiri', + kk: 'Kazakh', + km: 'Khmer', + ki: 'Kikuyu', + rw: 'Kinyarwanda (Rwanda)', + rn: 'Kirundi', + ky: 'Kyrgyz', + kv: 'Komi', + kg: 'Kongo', + ko: 'Korean', + ku: 'Kurdish', + kj: 'Kwanyama', + lo: 'Lao', + la: 'Latin', + lv: 'Latvian (Lettish)', + li: 'Limburgish ( Limburger)', + ln: 'Lingala', + lt: 'Lithuanian', + lu: 'Luga-Katanga', + lg: 'Luganda, Ganda', + lb: 'Luxembourgish', + mk: 'Macedonian', + mg: 'Malagasy', + ms: 'Malay', + ml: 'Malayalam', + mt: 'Maltese', + mi: 'Maori', + mr: 'Marathi', + mh: 'Marshallese', + mo: 'Moldavian', + mn: 'Mongolian', + na: 'Nauru', + nv: 'Navajo', + ng: 'Ndonga', + nd: 'Northern Ndebele', + ne: 'Nepali', + no: 'Norwegian', + nb: 'Norwegian bokmål', + nn: 'Norwegian nynorsk', + oc: 'Occitan', + oj: 'Ojibwe', + cu: 'Old Church Slavonic, Old Bulgarian', + or: 'Oriya', + om: 'Oromo (Afaan Oromo)', + os: 'Ossetian', + pi: 'Pāli', + ps: 'Pashto, Pushto', + fa: 'Persian (Farsi)', + pl: 'Polish', + pt: 'Portuguese', + pa: 'Punjabi (Eastern)', + qu: 'Quechua', + rm: 'Romansh', + ro: 'Romanian', + ru: 'Russian', + se: 'Sami', + sm: 'Samoan', + sg: 'Sango', + sa: 'Sanskrit', + sr: 'Serbian', + sh: 'Serbo-Croatian', + st: 'Sesotho', + tn: 'Setswana', + sn: 'Shona', + ii: 'Sichuan Yi, Nuosu', + sd: 'Sindhi', + si: 'Sinhalese', + ss: 'Siswati (Swati)', + sk: 'Slovak', + sl: 'Slovenian', + so: 'Somali', + nr: 'Southern Ndebele', + es: 'Spanish', + su: 'Sundanese', + sw: 'Swahili (Kiswahili)', + sv: 'Swedish', + tl: 'Tagalog', + ty: 'Tahitian', + tg: 'Tajik', + ta: 'Tamil', + tt: 'Tatar', + te: 'Telugu', + th: 'Thai', + bo: 'Tibetan', + ti: 'Tigrinya', + to: 'Tonga', + ts: 'Tsonga', + tr: 'Turkish', + tk: 'Turkmen', + tw: 'Twi', + ug: 'Uyghur', + uk: 'Ukrainian', + ur: 'Urdu', + uz: 'Uzbek', + ve: 'Venda', + vi: 'Vietnamese', + vo: 'Volapük', + wa: 'Wallon', + cy: 'Welsh', + wo: 'Wolof', + fy: 'Western Frisian', + xh: 'Xhosa', + yi: 'Yiddish', + yo: 'Yoruba', + za: 'Zhuang, Chuang', + zu: 'Zulu' +}; + + + diff --git a/src/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.html b/src/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.html index a4493e36fc..5e74437393 100644 --- a/src/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.html +++ b/src/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.html @@ -1,4 +1,5 @@ +> + + + + + + + +
diff --git a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.scss b/src/app/shared/log-in/methods/log-in-external-provider/log-in-external-provider.component.scss similarity index 100% rename from src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.scss rename to src/app/shared/log-in/methods/log-in-external-provider/log-in-external-provider.component.scss diff --git a/src/app/shared/log-in/methods/orcid/log-in-orcid.component.spec.ts b/src/app/shared/log-in/methods/log-in-external-provider/log-in-external-provider.component.spec.ts similarity index 88% rename from src/app/shared/log-in/methods/orcid/log-in-orcid.component.spec.ts rename to src/app/shared/log-in/methods/log-in-external-provider/log-in-external-provider.component.spec.ts index 001f0a4959..de4f62eb9e 100644 --- a/src/app/shared/log-in/methods/orcid/log-in-orcid.component.spec.ts +++ b/src/app/shared/log-in/methods/log-in-external-provider/log-in-external-provider.component.spec.ts @@ -14,18 +14,17 @@ import { AuthServiceStub } from '../../../testing/auth-service.stub'; import { storeModuleConfig } from '../../../../app.reducer'; import { AuthMethod } from '../../../../core/auth/models/auth.method'; import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; -import { LogInOrcidComponent } from './log-in-orcid.component'; +import { LogInExternalProviderComponent } from './log-in-external-provider.component'; import { NativeWindowService } from '../../../../core/services/window.service'; import { RouterStub } from '../../../testing/router.stub'; import { ActivatedRouteStub } from '../../../testing/active-router.stub'; import { NativeWindowMockFactory } from '../../../mocks/mock-native-window-ref'; import { HardRedirectService } from '../../../../core/services/hard-redirect.service'; +describe('LogInExternalProviderComponent', () => { -describe('LogInOrcidComponent', () => { - - let component: LogInOrcidComponent; - let fixture: ComponentFixture; + let component: LogInExternalProviderComponent; + let fixture: ComponentFixture; let page: Page; let user: EPerson; let componentAsAny: any; @@ -66,7 +65,7 @@ describe('LogInOrcidComponent', () => { TranslateModule.forRoot() ], declarations: [ - LogInOrcidComponent + LogInExternalProviderComponent ], providers: [ { provide: AuthService, useClass: AuthServiceStub }, @@ -88,7 +87,7 @@ describe('LogInOrcidComponent', () => { beforeEach(() => { // create component and test fixture - fixture = TestBed.createComponent(LogInOrcidComponent); + fixture = TestBed.createComponent(LogInExternalProviderComponent); // get test component from the fixture component = fixture.componentInstance; @@ -109,7 +108,7 @@ describe('LogInOrcidComponent', () => { expect(componentAsAny.injectedAuthMethodModel.location).toBe(location); expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl); - component.redirectToOrcid(); + component.redirectToExternalProvider(); expect(setHrefSpy).toHaveBeenCalledWith(currentUrl); @@ -124,7 +123,7 @@ describe('LogInOrcidComponent', () => { expect(componentAsAny.injectedAuthMethodModel.location).toBe(location); expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl); - component.redirectToOrcid(); + component.redirectToExternalProvider(); expect(setHrefSpy).toHaveBeenCalledWith(currentUrl); @@ -143,7 +142,7 @@ class Page { public navigateSpy: jasmine.Spy; public passwordInput: HTMLInputElement; - constructor(private component: LogInOrcidComponent, private fixture: ComponentFixture) { + constructor(private component: LogInExternalProviderComponent, private fixture: ComponentFixture) { // use injector to get services const injector = fixture.debugElement.injector; const store = injector.get(Store); diff --git a/src/app/shared/log-in/methods/log-in-external-provider.component.ts b/src/app/shared/log-in/methods/log-in-external-provider/log-in-external-provider.component.ts similarity index 73% rename from src/app/shared/log-in/methods/log-in-external-provider.component.ts rename to src/app/shared/log-in/methods/log-in-external-provider/log-in-external-provider.component.ts index 037fc40e90..f182968457 100644 --- a/src/app/shared/log-in/methods/log-in-external-provider.component.ts +++ b/src/app/shared/log-in/methods/log-in-external-provider/log-in-external-provider.component.ts @@ -4,22 +4,27 @@ import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; import { select, Store } from '@ngrx/store'; -import { AuthMethod } from '../../../core/auth/models/auth.method'; +import { AuthMethod } from '../../../../core/auth/models/auth.method'; -import { isAuthenticated, isAuthenticationLoading } from '../../../core/auth/selectors'; -import { NativeWindowRef, NativeWindowService } from '../../../core/services/window.service'; -import { isEmpty, isNotNull } from '../../empty.util'; -import { AuthService } from '../../../core/auth/auth.service'; -import { HardRedirectService } from '../../../core/services/hard-redirect.service'; -import { URLCombiner } from '../../../core/url-combiner/url-combiner'; -import { CoreState } from '../../../core/core-state.model'; +import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/selectors'; +import { NativeWindowRef, NativeWindowService } from '../../../../core/services/window.service'; +import { isEmpty, isNotNull } from '../../../empty.util'; +import { AuthService } from '../../../../core/auth/auth.service'; +import { HardRedirectService } from '../../../../core/services/hard-redirect.service'; +import { URLCombiner } from '../../../../core/url-combiner/url-combiner'; +import { CoreState } from '../../../../core/core-state.model'; +import { renderAuthMethodFor } from '../log-in.methods-decorator'; +import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; @Component({ selector: 'ds-log-in-external-provider', - template: '' - + templateUrl: './log-in-external-provider.component.html', + styleUrls: ['./log-in-external-provider.component.scss'] }) -export abstract class LogInExternalProviderComponent implements OnInit { +@renderAuthMethodFor(AuthMethodType.Oidc) +@renderAuthMethodFor(AuthMethodType.Shibboleth) +@renderAuthMethodFor(AuthMethodType.Orcid) +export class LogInExternalProviderComponent implements OnInit { /** * The authentication method data. @@ -107,4 +112,7 @@ export abstract class LogInExternalProviderComponent implements OnInit { } + getButtonLabel() { + return `login.form.${this.authMethod.authMethodType}`; + } } diff --git a/src/app/shared/log-in/methods/oidc/log-in-oidc.component.html b/src/app/shared/log-in/methods/oidc/log-in-oidc.component.html deleted file mode 100644 index 7e78834305..0000000000 --- a/src/app/shared/log-in/methods/oidc/log-in-oidc.component.html +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/src/app/shared/log-in/methods/oidc/log-in-oidc.component.spec.ts b/src/app/shared/log-in/methods/oidc/log-in-oidc.component.spec.ts deleted file mode 100644 index 078a58dd5a..0000000000 --- a/src/app/shared/log-in/methods/oidc/log-in-oidc.component.spec.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; - -import { provideMockStore } from '@ngrx/store/testing'; -import { Store, StoreModule } from '@ngrx/store'; -import { TranslateModule } from '@ngx-translate/core'; - -import { EPerson } from '../../../../core/eperson/models/eperson.model'; -import { EPersonMock } from '../../../testing/eperson.mock'; -import { authReducer } from '../../../../core/auth/auth.reducer'; -import { AuthService } from '../../../../core/auth/auth.service'; -import { AuthServiceStub } from '../../../testing/auth-service.stub'; -import { storeModuleConfig } from '../../../../app.reducer'; -import { AuthMethod } from '../../../../core/auth/models/auth.method'; -import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; -import { LogInOidcComponent } from './log-in-oidc.component'; -import { NativeWindowService } from '../../../../core/services/window.service'; -import { RouterStub } from '../../../testing/router.stub'; -import { ActivatedRouteStub } from '../../../testing/active-router.stub'; -import { NativeWindowMockFactory } from '../../../mocks/mock-native-window-ref'; -import { HardRedirectService } from '../../../../core/services/hard-redirect.service'; - - -describe('LogInOidcComponent', () => { - - let component: LogInOidcComponent; - let fixture: ComponentFixture; - let page: Page; - let user: EPerson; - let componentAsAny: any; - let setHrefSpy; - let oidcBaseUrl; - let location; - let initialState: any; - let hardRedirectService: HardRedirectService; - - beforeEach(() => { - user = EPersonMock; - oidcBaseUrl = 'dspace-rest.test/oidc?redirectUrl='; - location = oidcBaseUrl + 'http://dspace-angular.test/home'; - - hardRedirectService = jasmine.createSpyObj('hardRedirectService', { - getCurrentRoute: {}, - redirect: {} - }); - - initialState = { - core: { - auth: { - authenticated: false, - loaded: false, - blocking: false, - loading: false, - authMethods: [] - } - } - }; - }); - - beforeEach(waitForAsync(() => { - // refine the test module by declaring the test component - TestBed.configureTestingModule({ - imports: [ - StoreModule.forRoot({ auth: authReducer }, storeModuleConfig), - TranslateModule.forRoot() - ], - declarations: [ - LogInOidcComponent - ], - providers: [ - { provide: AuthService, useClass: AuthServiceStub }, - { provide: 'authMethodProvider', useValue: new AuthMethod(AuthMethodType.Oidc, location) }, - { provide: 'isStandalonePage', useValue: true }, - { provide: NativeWindowService, useFactory: NativeWindowMockFactory }, - { provide: Router, useValue: new RouterStub() }, - { provide: ActivatedRoute, useValue: new ActivatedRouteStub() }, - { provide: HardRedirectService, useValue: hardRedirectService }, - provideMockStore({ initialState }), - ], - schemas: [ - CUSTOM_ELEMENTS_SCHEMA - ] - }) - .compileComponents(); - - })); - - beforeEach(() => { - // create component and test fixture - fixture = TestBed.createComponent(LogInOidcComponent); - - // get test component from the fixture - component = fixture.componentInstance; - componentAsAny = component; - - // create page - page = new Page(component, fixture); - setHrefSpy = spyOnProperty(componentAsAny._window.nativeWindow.location, 'href', 'set').and.callThrough(); - - }); - - it('should set the properly a new redirectUrl', () => { - const currentUrl = 'http://dspace-angular.test/collections/12345'; - componentAsAny._window.nativeWindow.location.href = currentUrl; - - fixture.detectChanges(); - - expect(componentAsAny.injectedAuthMethodModel.location).toBe(location); - expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl); - - component.redirectToOidc(); - - expect(setHrefSpy).toHaveBeenCalledWith(currentUrl); - - }); - - it('should not set a new redirectUrl', () => { - const currentUrl = 'http://dspace-angular.test/home'; - componentAsAny._window.nativeWindow.location.href = currentUrl; - - fixture.detectChanges(); - - expect(componentAsAny.injectedAuthMethodModel.location).toBe(location); - expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl); - - component.redirectToOidc(); - - expect(setHrefSpy).toHaveBeenCalledWith(currentUrl); - - }); - -}); - -/** - * I represent the DOM elements and attach spies. - * - * @class Page - */ -class Page { - - public emailInput: HTMLInputElement; - public navigateSpy: jasmine.Spy; - public passwordInput: HTMLInputElement; - - constructor(private component: LogInOidcComponent, private fixture: ComponentFixture) { - // use injector to get services - const injector = fixture.debugElement.injector; - const store = injector.get(Store); - - // add spies - this.navigateSpy = spyOn(store, 'dispatch'); - } - -} diff --git a/src/app/shared/log-in/methods/oidc/log-in-oidc.component.ts b/src/app/shared/log-in/methods/oidc/log-in-oidc.component.ts deleted file mode 100644 index 882996b207..0000000000 --- a/src/app/shared/log-in/methods/oidc/log-in-oidc.component.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Component, } from '@angular/core'; - -import { renderAuthMethodFor } from '../log-in.methods-decorator'; -import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; -import { LogInExternalProviderComponent } from '../log-in-external-provider.component'; - -@Component({ - selector: 'ds-log-in-oidc', - templateUrl: './log-in-oidc.component.html', -}) -@renderAuthMethodFor(AuthMethodType.Oidc) -export class LogInOidcComponent extends LogInExternalProviderComponent { - - /** - * Redirect to orcid authentication url - */ - redirectToOidc() { - this.redirectToExternalProvider(); - } - -} diff --git a/src/app/shared/log-in/methods/orcid/log-in-orcid.component.html b/src/app/shared/log-in/methods/orcid/log-in-orcid.component.html deleted file mode 100644 index 6f5453fd60..0000000000 --- a/src/app/shared/log-in/methods/orcid/log-in-orcid.component.html +++ /dev/null @@ -1,3 +0,0 @@ - \ No newline at end of file diff --git a/src/app/shared/log-in/methods/orcid/log-in-orcid.component.ts b/src/app/shared/log-in/methods/orcid/log-in-orcid.component.ts deleted file mode 100644 index e0b1da3db5..0000000000 --- a/src/app/shared/log-in/methods/orcid/log-in-orcid.component.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Component, } from '@angular/core'; - -import { renderAuthMethodFor } from '../log-in.methods-decorator'; -import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; -import { LogInExternalProviderComponent } from '../log-in-external-provider.component'; - -@Component({ - selector: 'ds-log-in-orcid', - templateUrl: './log-in-orcid.component.html', -}) -@renderAuthMethodFor(AuthMethodType.Orcid) -export class LogInOrcidComponent extends LogInExternalProviderComponent { - - /** - * Redirect to orcid authentication url - */ - redirectToOrcid() { - this.redirectToExternalProvider(); - } - -} diff --git a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.html b/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.html deleted file mode 100644 index 3a3b935cfa..0000000000 --- a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.html +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.spec.ts b/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.spec.ts deleted file mode 100644 index 075d33d98e..0000000000 --- a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.spec.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; - -import { provideMockStore } from '@ngrx/store/testing'; -import { Store, StoreModule } from '@ngrx/store'; -import { TranslateModule } from '@ngx-translate/core'; - -import { EPerson } from '../../../../core/eperson/models/eperson.model'; -import { EPersonMock } from '../../../testing/eperson.mock'; -import { authReducer } from '../../../../core/auth/auth.reducer'; -import { AuthService } from '../../../../core/auth/auth.service'; -import { AuthServiceStub } from '../../../testing/auth-service.stub'; -import { storeModuleConfig } from '../../../../app.reducer'; -import { AuthMethod } from '../../../../core/auth/models/auth.method'; -import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; -import { LogInShibbolethComponent } from './log-in-shibboleth.component'; -import { NativeWindowService } from '../../../../core/services/window.service'; -import { RouterStub } from '../../../testing/router.stub'; -import { ActivatedRouteStub } from '../../../testing/active-router.stub'; -import { NativeWindowMockFactory } from '../../../mocks/mock-native-window-ref'; -import { HardRedirectService } from '../../../../core/services/hard-redirect.service'; - - -describe('LogInShibbolethComponent', () => { - - let component: LogInShibbolethComponent; - let fixture: ComponentFixture; - let page: Page; - let user: EPerson; - let componentAsAny: any; - let setHrefSpy; - let shibbolethBaseUrl; - let location; - let initialState: any; - let hardRedirectService: HardRedirectService; - - beforeEach(() => { - user = EPersonMock; - shibbolethBaseUrl = 'dspace-rest.test/shibboleth?redirectUrl='; - location = shibbolethBaseUrl + 'http://dspace-angular.test/home'; - - hardRedirectService = jasmine.createSpyObj('hardRedirectService', { - getCurrentRoute: {}, - redirect: {} - }); - - initialState = { - core: { - auth: { - authenticated: false, - loaded: false, - blocking: false, - loading: false, - authMethods: [] - } - } - }; - }); - - beforeEach(waitForAsync(() => { - // refine the test module by declaring the test component - TestBed.configureTestingModule({ - imports: [ - StoreModule.forRoot({ auth: authReducer }, storeModuleConfig), - TranslateModule.forRoot() - ], - declarations: [ - LogInShibbolethComponent - ], - providers: [ - { provide: AuthService, useClass: AuthServiceStub }, - { provide: 'authMethodProvider', useValue: new AuthMethod(AuthMethodType.Shibboleth, location) }, - { provide: 'isStandalonePage', useValue: true }, - { provide: NativeWindowService, useFactory: NativeWindowMockFactory }, - { provide: Router, useValue: new RouterStub() }, - { provide: ActivatedRoute, useValue: new ActivatedRouteStub() }, - { provide: HardRedirectService, useValue: hardRedirectService }, - provideMockStore({ initialState }), - ], - schemas: [ - CUSTOM_ELEMENTS_SCHEMA - ] - }) - .compileComponents(); - - })); - - beforeEach(() => { - // create component and test fixture - fixture = TestBed.createComponent(LogInShibbolethComponent); - - // get test component from the fixture - component = fixture.componentInstance; - componentAsAny = component; - - // create page - page = new Page(component, fixture); - setHrefSpy = spyOnProperty(componentAsAny._window.nativeWindow.location, 'href', 'set').and.callThrough(); - - }); - - it('should set the properly a new redirectUrl', () => { - const currentUrl = 'http://dspace-angular.test/collections/12345'; - componentAsAny._window.nativeWindow.location.href = currentUrl; - - fixture.detectChanges(); - - expect(componentAsAny.injectedAuthMethodModel.location).toBe(location); - expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl); - - component.redirectToShibboleth(); - - expect(setHrefSpy).toHaveBeenCalledWith(currentUrl); - - }); - - it('should not set a new redirectUrl', () => { - const currentUrl = 'http://dspace-angular.test/home'; - componentAsAny._window.nativeWindow.location.href = currentUrl; - - fixture.detectChanges(); - - expect(componentAsAny.injectedAuthMethodModel.location).toBe(location); - expect(componentAsAny._window.nativeWindow.location.href).toBe(currentUrl); - - component.redirectToShibboleth(); - - expect(setHrefSpy).toHaveBeenCalledWith(currentUrl); - - }); - -}); - -/** - * I represent the DOM elements and attach spies. - * - * @class Page - */ -class Page { - - public emailInput: HTMLInputElement; - public navigateSpy: jasmine.Spy; - public passwordInput: HTMLInputElement; - - constructor(private component: LogInShibbolethComponent, private fixture: ComponentFixture) { - // use injector to get services - const injector = fixture.debugElement.injector; - const store = injector.get(Store); - - // add spies - this.navigateSpy = spyOn(store, 'dispatch'); - } - -} diff --git a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts b/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts deleted file mode 100644 index dcfb3ccfc3..0000000000 --- a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Component, } from '@angular/core'; - -import { renderAuthMethodFor } from '../log-in.methods-decorator'; -import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; -import { LogInExternalProviderComponent } from '../log-in-external-provider.component'; - -@Component({ - selector: 'ds-log-in-shibboleth', - templateUrl: './log-in-shibboleth.component.html', - styleUrls: ['./log-in-shibboleth.component.scss'], - -}) -@renderAuthMethodFor(AuthMethodType.Shibboleth) -export class LogInShibbolethComponent extends LogInExternalProviderComponent { - - /** - * Redirect to shibboleth authentication url - */ - redirectToShibboleth() { - this.redirectToExternalProvider(); - } - -} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index e4abf0d907..777ad03c1d 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -186,7 +186,6 @@ import { ImportableListItemControlComponent } from './object-collection/shared/importable-list-item-control/importable-list-item-control.component'; import { LogInContainerComponent } from './log-in/container/log-in-container.component'; -import { LogInShibbolethComponent } from './log-in/methods/shibboleth/log-in-shibboleth.component'; import { LogInPasswordComponent } from './log-in/methods/password/log-in-password.component'; import { LogInComponent } from './log-in/log-in.component'; import { MissingTranslationHelper } from './translate/missing-translation.helper'; @@ -229,9 +228,7 @@ import { SearchNavbarComponent } from '../search-navbar/search-navbar.component' import { ThemedSearchNavbarComponent } from '../search-navbar/themed-search-navbar.component'; import { ScopeSelectorModalComponent } from './search-form/scope-selector-modal/scope-selector-modal.component'; import { DsSelectComponent } from './ds-select/ds-select.component'; -import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; import { RSSComponent } from './rss-feed/rss.component'; -import { LogInOrcidComponent } from './log-in/methods/orcid/log-in-orcid.component'; import { BrowserOnlyPipe } from './utils/browser-only.pipe'; import { ThemedLoadingComponent } from './loading/themed-loading.component'; import { SearchExportCsvComponent } from './search/search-export-csv/search-export-csv.component'; @@ -246,6 +243,8 @@ import { } from './object-list/listable-notification-object/listable-notification-object.component'; import { ThemedCollectionDropdownComponent } from './collection-dropdown/themed-collection-dropdown.component'; import { MetadataFieldWrapperComponent } from './metadata-field-wrapper/metadata-field-wrapper.component'; +import { LogInExternalProviderComponent } from './log-in/methods/log-in-external-provider/log-in-external-provider.component'; + const MODULES = [ CommonModule, @@ -386,9 +385,7 @@ const ENTRY_COMPONENTS = [ MetadataRepresentationListElementComponent, ItemMetadataRepresentationListElementComponent, LogInPasswordComponent, - LogInShibbolethComponent, - LogInOidcComponent, - LogInOrcidComponent, + LogInExternalProviderComponent, CollectionDropdownComponent, ThemedCollectionDropdownComponent, FileDownloadLinkComponent,