Skip to content

Commit 37fad7b

Browse files
committed
refactor(settings): Implement CR suggestions; Update tests
1 parent 394a13c commit 37fad7b

File tree

7 files changed

+55
-32
lines changed

7 files changed

+55
-32
lines changed

src/app/features/profile/components/profile-information/profile-information.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { toSignal } from '@angular/core/rxjs-interop';
99
import { EducationHistoryComponent } from '@osf/shared/components/education-history/education-history.component';
1010
import { EmploymentHistoryComponent } from '@osf/shared/components/employment-history/employment-history.component';
1111
import { SOCIAL_LINKS } from '@osf/shared/constants/social-links.const';
12+
import { ExternalIdentityStatus } from '@osf/shared/enums/external-identity-status.enum';
1213
import { IS_MEDIUM } from '@osf/shared/helpers/breakpoints.tokens';
1314
import { UserModel } from '@osf/shared/models/user/user.models';
1415
import { SortByDatePipe } from '@osf/shared/pipes/sort-by-date.pipe';
@@ -45,7 +46,7 @@ export class ProfileInformationComponent {
4546

4647
orcidId = computed(() => {
4748
const orcid = this.currentUser()?.external_identity?.ORCID;
48-
return orcid?.status?.toUpperCase() === 'VERIFIED' ? orcid.id : undefined;
49+
return orcid?.status?.toUpperCase() === ExternalIdentityStatus.VERIFIED ? orcid.id : undefined;
4950
});
5051

5152
toProfileSettings() {

src/app/features/settings/profile-settings/components/authenticated-identity/authenticated-identity.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ <h2>
66
</div>
77
<div class="flex flex-column row-gap-4 w-full md:flex-row md:align-items-end md:column-gap-3">
88
<div class="w-full md:w-12">
9-
@if (existingOrcid) {
9+
@if (existingOrcid()) {
1010
<div class="flex flex-row align-items-center gap-2">
1111
<img ngSrc="assets/icons/colored/orcid.svg" width="16" height="16" alt="orcid" />
1212
<a class="font-bold" [href]="orcidUrl()"> {{ orcidUrl() }} </a>

src/app/features/settings/profile-settings/components/authenticated-identity/authenticated-identity.component.spec.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
2+
import { MockPipe, MockProvider } from 'ng-mocks';
3+
4+
import { signal } from '@angular/core';
15
import { ComponentFixture, TestBed } from '@angular/core/testing';
26

37
import { AccountSettingsSelectors } from '@osf/features/settings/account-settings/store/account-settings.selectors';
48
import { CustomConfirmationService } from '@osf/shared/services/custom-confirmation.service';
9+
import { LoaderService } from '@osf/shared/services/loader.service';
10+
import { ToastService } from '@osf/shared/services/toast.service';
511

612
import { AuthenticatedIdentityComponent } from './authenticated-identity.component';
713

@@ -12,22 +18,27 @@ describe('AuthenticatedIdentityComponent', () => {
1218
let component: AuthenticatedIdentityComponent;
1319
let fixture: ComponentFixture<AuthenticatedIdentityComponent>;
1420

21+
const mockExternalIdentities = signal([
22+
{
23+
id: 'ORCID',
24+
externalId: '0001-0002-0003-0004',
25+
status: 'VERIFIED',
26+
},
27+
]);
28+
1529
beforeEach(async () => {
1630
await TestBed.configureTestingModule({
17-
imports: [AuthenticatedIdentityComponent],
31+
imports: [AuthenticatedIdentityComponent, MockPipe(TranslatePipe)],
1832
providers: [
33+
MockProvider(ToastService),
34+
MockProvider(LoaderService),
35+
MockProvider(TranslateService),
1936
{ provide: CustomConfirmationService, useValue: MockCustomConfirmationServiceProvider.useValue },
2037
provideMockStore({
2138
signals: [
2239
{
2340
selector: AccountSettingsSelectors.getExternalIdentities,
24-
value: [
25-
{
26-
id: 'ORCID',
27-
externalId: '0001-0002-0003-0004',
28-
status: 'VERIFIED',
29-
},
30-
],
41+
value: mockExternalIdentities,
3142
},
3243
],
3344
}),
@@ -44,17 +55,17 @@ describe('AuthenticatedIdentityComponent', () => {
4455
});
4556

4657
it('should show existing user ORCID when present in external identities', () => {
47-
expect(component.existingOrcid).toEqual('0001-0002-0003-0004');
58+
expect(component.existingOrcid()).toEqual('0001-0002-0003-0004');
4859
expect(component.orcidUrl()).toEqual('https://orcid.org/0001-0002-0003-0004');
4960
component.disconnectOrcid();
5061
expect(MockCustomConfirmationServiceProvider.useValue.confirmDelete).toHaveBeenCalled();
5162
});
5263

5364
it('should show connect button when no existing ORCID is present in external identities', () => {
54-
TestBed.inject(provideMockStore).overrideSelector(AccountSettingsSelectors.getExternalIdentities, []);
65+
mockExternalIdentities.set([]);
5566
fixture.detectChanges();
5667

57-
expect(component.existingOrcid).toBeUndefined();
68+
expect(component.existingOrcid()).toBeUndefined();
5869
expect(component.orcidUrl()).toBeNull();
5970
});
6071
});

src/app/features/settings/profile-settings/components/authenticated-identity/authenticated-identity.component.ts

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import { Tooltip } from 'primeng/tooltip';
88
import { finalize } from 'rxjs';
99

1010
import { NgOptimizedImage } from '@angular/common';
11-
import { ChangeDetectionStrategy, Component, computed, effect, inject } from '@angular/core';
11+
import { ChangeDetectionStrategy, Component, computed, inject, OnInit } from '@angular/core';
1212

13+
import { ExternalIdentityStatus } from '@osf/shared/enums/external-identity-status.enum';
1314
import { CustomConfirmationService } from '@osf/shared/services/custom-confirmation.service';
1415
import { LoaderService } from '@osf/shared/services/loader.service';
1516
import { ToastService } from '@osf/shared/services/toast.service';
@@ -27,15 +28,15 @@ import {
2728
styleUrl: './authenticated-identity.component.scss',
2829
changeDetection: ChangeDetectionStrategy.OnPush,
2930
})
30-
export class AuthenticatedIdentityComponent {
31+
export class AuthenticatedIdentityComponent implements OnInit {
3132
private readonly customConfirmationService = inject(CustomConfirmationService);
3233
private readonly toastService = inject(ToastService);
3334
private readonly loaderService = inject(LoaderService);
3435

35-
constructor() {
36-
effect(() => {
37-
this.actions.getExternalIdentities();
38-
});
36+
private readonly ORCID_PROVIDER = 'ORCID';
37+
38+
ngOnInit() {
39+
this.actions.getExternalIdentities();
3940
}
4041

4142
readonly actions = createDispatchMap({
@@ -46,27 +47,24 @@ export class AuthenticatedIdentityComponent {
4647
readonly externalIdentities = select(AccountSettingsSelectors.getExternalIdentities);
4748

4849
readonly orcidUrl = computed(() => {
49-
return this.existingOrcid ? `https://orcid.org/${this.existingOrcid}` : null;
50+
return this.existingOrcid() ? `https://orcid.org/${this.existingOrcid()}` : null;
5051
});
5152

52-
get existingOrcid(): string | undefined {
53-
const externalIdentities = this.externalIdentities();
54-
const existingOrcid = externalIdentities?.find((identity) => identity.id === 'ORCID');
55-
if (existingOrcid && existingOrcid.status === 'VERIFIED') {
56-
return existingOrcid.externalId;
57-
}
58-
return undefined;
59-
}
53+
readonly existingOrcid = computed(
54+
(): string | undefined =>
55+
this.externalIdentities()?.find((i) => i.id === 'ORCID' && i.status === ExternalIdentityStatus.VERIFIED)
56+
?.externalId
57+
);
6058

6159
disconnectOrcid(): void {
6260
this.customConfirmationService.confirmDelete({
6361
headerKey: 'settings.accountSettings.connectedIdentities.deleteDialog.header',
64-
messageParams: { name: 'ORCID' },
62+
messageParams: { name: this.ORCID_PROVIDER },
6563
messageKey: 'settings.accountSettings.connectedIdentities.deleteDialog.message',
6664
onConfirm: () => {
6765
this.loaderService.show();
6866
this.actions
69-
.deleteExternalIdentity('ORCID')
67+
.deleteExternalIdentity(this.ORCID_PROVIDER)
7068
.pipe(finalize(() => this.loaderService.hide()))
7169
.subscribe(() => this.toastService.showSuccess('settings.accountSettings.connectedIdentities.successDelete'));
7270
},

src/app/features/settings/profile-settings/components/social/social.component.spec.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { CustomConfirmationService } from '@osf/shared/services/custom-confirmat
88
import { LoaderService } from '@osf/shared/services/loader.service';
99
import { ToastService } from '@osf/shared/services/toast.service';
1010

11+
import { AuthenticatedIdentityComponent } from '../authenticated-identity/authenticated-identity.component';
1112
import { SocialFormComponent } from '../social-form/social-form.component';
1213

1314
import { SocialComponent } from './social.component';
@@ -24,7 +25,12 @@ describe('SocialComponent', () => {
2425
jest.clearAllMocks();
2526

2627
await TestBed.configureTestingModule({
27-
imports: [SocialComponent, MockComponent(SocialFormComponent), MockPipe(TranslatePipe)],
28+
imports: [
29+
SocialComponent,
30+
MockComponent(SocialFormComponent),
31+
MockComponent(AuthenticatedIdentityComponent),
32+
MockPipe(TranslatePipe),
33+
],
2834
providers: [
2935
provideMockStore({
3036
signals: [{ selector: UserSelectors.getSocialLinks, value: MOCK_USER.social }],
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export enum ExternalIdentityStatus {
2+
VERIFIED = 'VERIFIED',
3+
LINK = 'LINK',
4+
CREATE = 'CREATE',
5+
}

src/app/shared/models/user/external-identity.model.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import { ExternalIdentityStatus } from '@osf/shared/enums/external-identity-status.enum';
2+
13
export interface OrcidInfo {
24
id: string;
3-
status: string;
5+
status: ExternalIdentityStatus;
46
}
57

68
export interface ExternalIdentityModel {

0 commit comments

Comments
 (0)