1- import { ComponentFixture , TestBed , waitForAsync } from '@angular/core/testing' ;
21import { ChangeDetectionStrategy , NO_ERRORS_SCHEMA } from '@angular/core' ;
3- import { PlainTextMetadataListElementComponent } from './plain-text-metadata-list-element.component' ;
4- import { MetadatumRepresentation } from '../../../../core/shared/metadata-representation/metadatum/metadatum-representation.model' ;
52import { By } from '@angular/platform-browser' ;
3+ import { ComponentFixture , TestBed , waitForAsync } from '@angular/core/testing' ;
4+
5+ import { ConfigurationDataService } from '../../../../core/data/configuration-data.service' ;
6+ import { MetadatumRepresentation } from '../../../../core/shared/metadata-representation/metadatum/metadatum-representation.model' ;
7+ import { createSuccessfulRemoteDataObject$ } from '../../../remote-data.utils' ;
68import { mockData } from '../../../testing/browse-definition-data-service.stub' ;
9+ import { PlainTextMetadataListElementComponent } from './plain-text-metadata-list-element.component' ;
710
811// Render the mock representation with the default mock author browse definition so it is also rendered as a link
912// without affecting other tests
1013const mockMetadataRepresentation = Object . assign ( new MetadatumRepresentation ( 'type' , mockData [ 1 ] ) , {
1114 key : 'dc.contributor.author' ,
12- value : 'Test Author'
15+ value : 'Test Author' ,
1316} ) ;
1417
18+ const mockOrcidRepresentation = Object . assign ( new MetadatumRepresentation ( 'type' ) , {
19+ key : 'dc.contributor.author' ,
20+ value : 'Doe, John' ,
21+ authority : '1234-5678-9012-3456' ,
22+ } ) ;
23+
24+ const mockNonOrcidAuthorityRepresentation = Object . assign ( new MetadatumRepresentation ( 'type' ) , {
25+ key : 'dc.contributor.author' ,
26+ value : 'Smith, Jane' ,
27+ authority : 'some-non-orcid-authority-key' ,
28+ } ) ;
29+
30+ const mockOrcidWithWhitespaceRepresentation = Object . assign ( new MetadatumRepresentation ( 'type' ) , {
31+ key : 'dc.contributor.author' ,
32+ value : 'Doe, Jane' ,
33+ authority : ' 1234-5678-9012-3456 ' ,
34+ } ) ;
35+
36+ const mockConfigurationDataService = {
37+ findByPropertyName : jasmine . createSpy ( 'findByPropertyName' ) . and . returnValue (
38+ createSuccessfulRemoteDataObject$ ( { values : [ 'https://orcid.org' ] } ) ,
39+ ) ,
40+ } ;
41+
1542describe ( 'PlainTextMetadataListElementComponent' , ( ) => {
1643 let comp : PlainTextMetadataListElementComponent ;
1744 let fixture : ComponentFixture < PlainTextMetadataListElementComponent > ;
@@ -20,9 +47,12 @@ describe('PlainTextMetadataListElementComponent', () => {
2047 TestBed . configureTestingModule ( {
2148 imports : [ ] ,
2249 declarations : [ PlainTextMetadataListElementComponent ] ,
23- schemas : [ NO_ERRORS_SCHEMA ]
50+ providers : [
51+ { provide : ConfigurationDataService , useValue : mockConfigurationDataService } ,
52+ ] ,
53+ schemas : [ NO_ERRORS_SCHEMA ] ,
2454 } ) . overrideComponent ( PlainTextMetadataListElementComponent , {
25- set : { changeDetection : ChangeDetectionStrategy . Default }
55+ set : { changeDetection : ChangeDetectionStrategy . Default } ,
2656 } ) . compileComponents ( ) ;
2757 } ) ) ;
2858
@@ -41,4 +71,117 @@ describe('PlainTextMetadataListElementComponent', () => {
4171 expect ( fixture . debugElement . query ( By . css ( 'a.ds-browse-link' ) ) . nativeElement . innerHTML ) . toContain ( mockMetadataRepresentation . value ) ;
4272 } ) ;
4373
74+ describe ( 'when metadata has ORCID authority' , ( ) => {
75+ beforeEach ( ( ) => {
76+ comp . mdRepresentation = mockOrcidRepresentation ;
77+ fixture . detectChanges ( ) ;
78+ } ) ;
79+
80+ it ( 'should render an ORCID link' , ( ) => {
81+ const link = fixture . debugElement . query ( By . css ( 'a.orcid-author-link' ) ) ;
82+ expect ( link ) . toBeTruthy ( ) ;
83+ expect ( link . nativeElement . getAttribute ( 'href' ) ) . toBe ( 'https://orcid.org/1234-5678-9012-3456' ) ;
84+ expect ( link . nativeElement . textContent ) . toContain ( 'Doe, John' ) ;
85+ } ) ;
86+
87+ it ( 'should render an ORCID icon' , ( ) => {
88+ const icon = fixture . debugElement . query ( By . css ( 'a.orcid-author-link i.fa-orcid' ) ) ;
89+ expect ( icon ) . toBeTruthy ( ) ;
90+ } ) ;
91+
92+ it ( 'isOrcidAuthority should return true' , ( ) => {
93+ expect ( comp . isOrcidAuthority ( comp . orcidDomainUrl$ . value ) ) . toBeTrue ( ) ;
94+ } ) ;
95+
96+ it ( 'getOrcidUrl should return full ORCID URL' , ( ) => {
97+ expect ( comp . getOrcidUrl ( comp . orcidDomainUrl$ . value ) ) . toBe ( 'https://orcid.org/1234-5678-9012-3456' ) ;
98+ } ) ;
99+ } ) ;
100+
101+ describe ( 'when metadata has non-ORCID authority' , ( ) => {
102+ beforeEach ( ( ) => {
103+ comp . mdRepresentation = mockNonOrcidAuthorityRepresentation ;
104+ fixture . detectChanges ( ) ;
105+ } ) ;
106+
107+ it ( 'should render as plain text (no ORCID link)' , ( ) => {
108+ const link = fixture . debugElement . query ( By . css ( 'a.orcid-author-link' ) ) ;
109+ expect ( link ) . toBeFalsy ( ) ;
110+ } ) ;
111+
112+ it ( 'should render the value as a span' , ( ) => {
113+ const span = fixture . debugElement . query ( By . css ( 'span.dont-break-out' ) ) ;
114+ expect ( span ) . toBeTruthy ( ) ;
115+ expect ( span . nativeElement . textContent ) . toContain ( 'Smith, Jane' ) ;
116+ } ) ;
117+
118+ it ( 'isOrcidAuthority should return false' , ( ) => {
119+ expect ( comp . isOrcidAuthority ( comp . orcidDomainUrl$ . value ) ) . toBeFalse ( ) ;
120+ } ) ;
121+ } ) ;
122+
123+ describe ( 'getOrcidUrl with trailing slash handling' , ( ) => {
124+ it ( 'should not double-slash when domain URL ends with /' , ( ) => {
125+ comp . orcidDomainUrl$ . next ( 'https://orcid.org/' ) ;
126+ comp . mdRepresentation = mockOrcidRepresentation ;
127+ expect ( comp . getOrcidUrl ( 'https://orcid.org/' ) ) . toBe ( 'https://orcid.org/1234-5678-9012-3456' ) ;
128+ } ) ;
129+
130+ it ( 'should add slash when domain URL does not end with /' , ( ) => {
131+ comp . orcidDomainUrl$ . next ( 'https://sandbox.orcid.org' ) ;
132+ comp . mdRepresentation = mockOrcidRepresentation ;
133+ expect ( comp . getOrcidUrl ( 'https://sandbox.orcid.org' ) ) . toBe ( 'https://sandbox.orcid.org/1234-5678-9012-3456' ) ;
134+ } ) ;
135+ } ) ;
136+
137+ describe ( 'when backend config is not available' , ( ) => {
138+ beforeEach ( ( ) => {
139+ comp . orcidDomainUrl$ . next ( null ) ;
140+ comp . mdRepresentation = mockOrcidRepresentation ;
141+ fixture . detectChanges ( ) ;
142+ } ) ;
143+
144+ it ( 'should not render ORCID link even if authority is ORCID' , ( ) => {
145+ const link = fixture . debugElement . query ( By . css ( 'a.orcid-author-link' ) ) ;
146+ expect ( link ) . toBeFalsy ( ) ;
147+ } ) ;
148+
149+ it ( 'isOrcidAuthority should return false' , ( ) => {
150+ expect ( comp . isOrcidAuthority ( comp . orcidDomainUrl$ . value ) ) . toBeFalse ( ) ;
151+ } ) ;
152+
153+ it ( 'getOrcidUrl should return empty string' , ( ) => {
154+ expect ( comp . getOrcidUrl ( comp . orcidDomainUrl$ . value ) ) . toBe ( '' ) ;
155+ } ) ;
156+ } ) ;
157+
158+ describe ( 'getOrcidUrl defensive behavior' , ( ) => {
159+ it ( 'should return empty string when orcidDomainUrl is null' , ( ) => {
160+ comp . orcidDomainUrl$ . next ( null ) ;
161+ comp . mdRepresentation = mockOrcidRepresentation ;
162+ expect ( comp . getOrcidUrl ( null ) ) . toBe ( '' ) ;
163+ } ) ;
164+
165+ it ( 'should return empty string when mdRepresentation has no authority' , ( ) => {
166+ comp . orcidDomainUrl$ . next ( 'https://orcid.org' ) ;
167+ comp . mdRepresentation = mockMetadataRepresentation ;
168+ expect ( comp . getOrcidUrl ( 'https://orcid.org' ) ) . toBe ( '' ) ;
169+ } ) ;
170+ } ) ;
171+
172+ describe ( 'when authority has leading/trailing whitespace' , ( ) => {
173+ beforeEach ( ( ) => {
174+ comp . orcidDomainUrl$ . next ( 'https://orcid.org' ) ;
175+ comp . mdRepresentation = mockOrcidWithWhitespaceRepresentation ;
176+ fixture . detectChanges ( ) ;
177+ } ) ;
178+
179+ it ( 'isOrcidAuthority should return true after trimming' , ( ) => {
180+ expect ( comp . isOrcidAuthority ( comp . orcidDomainUrl$ . value ) ) . toBeTrue ( ) ;
181+ } ) ;
182+
183+ it ( 'getOrcidUrl should return trimmed ORCID URL' , ( ) => {
184+ expect ( comp . getOrcidUrl ( comp . orcidDomainUrl$ . value ) ) . toBe ( 'https://orcid.org/1234-5678-9012-3456' ) ;
185+ } ) ;
186+ } ) ;
44187} ) ;
0 commit comments