Skip to content

Commit 6ff10ff

Browse files
authored
[ENG-8624] feat(registries): add context to registration submission + rearrange title and description layout (#304)
* feat(registries): add context to registration submission + rearrange layout * feat(registries): CR followup * feat(registries): Add test for TagsComponent * feat(registries): Add moar tests * feat(registries): CR followup
1 parent 52c5896 commit 6ff10ff

File tree

10 files changed

+241
-21
lines changed

10 files changed

+241
-21
lines changed

jest.config.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,23 @@ module.exports = {
7676
'<rootDir>/src/app/features/project/settings',
7777
'<rootDir>/src/app/features/project/wiki',
7878
'<rootDir>/src/app/features/project/project.component.ts',
79-
'<rootDir>/src/app/features/registries/',
79+
'<rootDir>/src/app/features/registries/pages',
80+
'<rootDir>/src/app/features/registries/registries.component.spec.ts',
81+
'<rootDir>/src/app/features/registries/components/metadata/contributors',
82+
'<rootDir>/src/app/features/registries/components/metadata/registries-license',
83+
'<rootDir>/src/app/features/registries/components/metadata/registries-subjects',
84+
'<rootDir>/src/app/features/registries/components/confirm-continue-editing-dialog',
85+
'<rootDir>/src/app/features/registries/components/confirm-registration-dialog',
86+
'<rootDir>/src/app/features/registries/components/custom-step',
87+
'<rootDir>/src/app/features/registries/components/drafts',
88+
'<rootDir>/src/app/features/registries/components/files-control',
89+
'<rootDir>/src/app/features/registries/components/justification-review',
90+
'<rootDir>/src/app/features/registries/components/justification-step',
91+
'<rootDir>/src/app/features/registries/components/new-registration',
92+
'<rootDir>/src/app/features/registries/components/registry-provider-hero',
93+
'<rootDir>/src/app/features/registries/components/registry-services',
94+
'<rootDir>/src/app/features/registries/components/review',
95+
'<rootDir>/src/app/features/registries/components/select-components-dialog',
8096
'<rootDir>/src/app/features/settings/addons/',
8197
'<rootDir>/src/app/features/settings/tokens/mappers/',
8298
'<rootDir>/src/app/features/settings/tokens/store/',
@@ -90,7 +106,6 @@ module.exports = {
90106
'<rootDir>/src/app/shared/components/shared-metadata/dialogs/affiliated-institutions-dialog/',
91107
'<rootDir>/src/app/shared/components/shared-metadata/dialogs/contributors-dialog/',
92108
'<rootDir>/src/app/shared/components/shared-metadata/shared-metadata',
93-
'<rootDir>/src/app/shared/components/subjects/',
94109
'<rootDir>/src/app/shared/components/wiki/edit-section/',
95110
'<rootDir>/src/app/shared/components/wiki/wiki-list/',
96111
],

src/app/features/registries/components/metadata/metadata.component.html

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
11
<section class="flex flex-column bg-white flex-1 h-full p-5 gap-4 w-full">
2+
<div>
3+
<h2 class="mb-2">{{ 'registries.metadata.title' | translate }}</h2>
4+
<p class="mb-4">{{ 'registries.metadata.description' | translate }}</p>
5+
</div>
26
<form [formGroup]="metadataForm" (ngSubmit)="submitMetadata()" class="flex flex-column gap-4">
3-
<section>
4-
<h2 class="mb-2">{{ 'registries.metadata.title' | translate }}</h2>
5-
<p class="mb-4">{{ 'registries.metadata.description' | translate }}</p>
7+
<section data-test-registration-title-section>
68
<p-card class="w-full">
9+
<label for="registration-title-id">
10+
<h2 class="mb-2">{{ 'common.labels.title' | translate }}</h2>
11+
</label>
12+
<p class="mb-1">{{ 'shared.title.description' | translate }}</p>
713
<osf-text-input
8-
label="common.labels.title"
14+
id="registration-title-id"
915
[control]="metadataForm.controls['title']"
1016
[maxLength]="inputLimits.fullName.maxLength"
1117
>
1218
</osf-text-input>
19+
</p-card>
20+
</section>
21+
<section data-test-registration-description-section>
22+
<p-card>
1323
<div class="mt-2">
14-
<label for="project-description-id">{{ 'common.labels.description' | translate }}</label>
24+
<label for="registration-description-id" class="mb-2">
25+
<h2>{{ 'common.labels.description' | translate }}</h2>
26+
</label>
27+
<p class="mb-1">{{ 'shared.description.message' | translate }}</p>
1528
<textarea
16-
id="project-description-id"
29+
id="registration-description-id"
1730
formControlName="description"
1831
class="w-full"
1932
rows="5"
@@ -32,10 +45,19 @@ <h2 class="mb-2">{{ 'registries.metadata.title' | translate }}</h2>
3245
<div class="flex justify-content-end"></div>
3346
</p-card>
3447
</section>
35-
<osf-contributors [control]="metadataForm.controls['contributors']"></osf-contributors>
36-
<osf-registries-license [control]="metadataForm.controls['license']"></osf-registries-license>
37-
<osf-registries-subjects [control]="metadataForm.controls['subjects']"></osf-registries-subjects>
38-
<osf-registries-tags></osf-registries-tags>
48+
<osf-contributors
49+
data-test-registration-contributors-section
50+
[control]="metadataForm.controls['contributors']"
51+
></osf-contributors>
52+
<osf-registries-license
53+
data-test-registration-license-section
54+
[control]="metadataForm.controls['license']"
55+
></osf-registries-license>
56+
<osf-registries-subjects
57+
data-test-registration-subjects-section
58+
[control]="metadataForm.controls['subjects']"
59+
></osf-registries-subjects>
60+
<osf-registries-tags data-test-registration-tags-section></osf-registries-tags>
3961
<div class="flex justify-content-end">
4062
<p-button [label]="'registries.deleteDraft' | translate" severity="danger" (click)="deleteDraft()" class="mr-2">
4163
</p-button>

src/app/features/registries/components/metadata/metadata.component.spec.ts

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,71 @@
1+
import { Store } from '@ngxs/store';
2+
3+
import { MockComponent, MockProvider } from 'ng-mocks';
4+
5+
import { ConfirmationService, MessageService } from 'primeng/api';
6+
7+
import { of } from 'rxjs';
8+
19
import { ComponentFixture, TestBed } from '@angular/core/testing';
10+
import { ReactiveFormsModule } from '@angular/forms';
11+
import { ActivatedRoute } from '@angular/router';
12+
13+
import { TextInputComponent } from '@osf/shared/components';
14+
import { MOCK_STORE } from '@osf/shared/mocks';
15+
import { ContributorsSelectors, SubjectsSelectors } from '@osf/shared/stores';
216

17+
import { RegistriesSelectors } from '../../store';
18+
19+
import { ContributorsComponent } from './contributors/contributors.component';
20+
import { RegistriesLicenseComponent } from './registries-license/registries-license.component';
21+
import { RegistriesSubjectsComponent } from './registries-subjects/registries-subjects.component';
22+
import { RegistriesTagsComponent } from './registries-tags/registries-tags.component';
323
import { MetadataComponent } from './metadata.component';
424

25+
import { MOCK_DRAFT_REGISTRATION } from '@testing/mocks/draft-registration.mock';
26+
import { OSFTestingModule } from '@testing/osf.testing.module';
27+
528
describe('MetadataComponent', () => {
629
let component: MetadataComponent;
730
let fixture: ComponentFixture<MetadataComponent>;
31+
const mockRoute = {
32+
snapshot: {
33+
params: of({ id: 'someId' }),
34+
},
35+
params: of(''),
36+
};
837

938
beforeEach(async () => {
39+
MOCK_STORE.selectSignal.mockImplementation((selector) => {
40+
switch (selector) {
41+
case RegistriesSelectors.getDraftRegistration:
42+
return () => MOCK_DRAFT_REGISTRATION;
43+
case RegistriesSelectors.getStepsValidation:
44+
return () => [];
45+
case ContributorsSelectors.getContributors:
46+
return () => [];
47+
case SubjectsSelectors.getSelectedSubjects:
48+
return () => [];
49+
}
50+
return null;
51+
});
1052
await TestBed.configureTestingModule({
11-
imports: [MetadataComponent],
53+
imports: [
54+
OSFTestingModule,
55+
ReactiveFormsModule,
56+
MetadataComponent,
57+
MockComponent(ContributorsComponent),
58+
MockComponent(RegistriesLicenseComponent),
59+
MockComponent(RegistriesSubjectsComponent),
60+
MockComponent(RegistriesTagsComponent),
61+
MockComponent(TextInputComponent),
62+
],
63+
providers: [
64+
{ provide: ActivatedRoute, useValue: mockRoute },
65+
MockProvider(ConfirmationService),
66+
MockProvider(MessageService),
67+
MockProvider(Store, MOCK_STORE),
68+
],
1269
}).compileComponents();
1370

1471
fixture = TestBed.createComponent(MetadataComponent);
@@ -19,4 +76,25 @@ describe('MetadataComponent', () => {
1976
it('should create', () => {
2077
expect(component).toBeTruthy();
2178
});
79+
80+
it('should render with submission form', () => {
81+
const titleSection = fixture.nativeElement.querySelector('[data-test-registration-title-section]');
82+
const descriptionSection = fixture.nativeElement.querySelector('[data-test-registration-description-section]');
83+
const contributorsSection = fixture.nativeElement.querySelector('[data-test-registration-contributors-section]');
84+
const subjectsSection = fixture.nativeElement.querySelector('[data-test-registration-subjects-section]');
85+
const tagsSection = fixture.nativeElement.querySelector('[data-test-registration-tags-section]');
86+
expect(titleSection).toBeDefined();
87+
expect(descriptionSection).toBeDefined();
88+
expect(contributorsSection).toBeDefined();
89+
expect(subjectsSection).toBeDefined();
90+
expect(tagsSection).toBeDefined();
91+
const titleFieldLabel = titleSection.querySelector('h2');
92+
expect(titleFieldLabel.textContent).toEqual('common.labels.title');
93+
const titleFieldHelpText = titleSection.querySelector('p');
94+
expect(titleFieldHelpText.textContent).toEqual('shared.title.description');
95+
const descriptionFieldLabel = descriptionSection.querySelector('h2');
96+
expect(descriptionFieldLabel.textContent).toEqual('common.labels.description');
97+
const descriptionFieldHelpText = descriptionSection.querySelector('p');
98+
expect(descriptionFieldHelpText.textContent).toEqual('shared.description.message');
99+
});
22100
});

src/app/features/registries/components/metadata/metadata.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export class MetadataComponent implements OnDestroy {
8484
constructor() {
8585
effect(() => {
8686
const draft = this.draftRegistration();
87+
// TODO: This shouldn't be an effect()
8788
if (draft && !this.isFormUpdated) {
8889
this.updateFormValue(draft);
8990
this.isFormUpdated = true;
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
<p-card>
22
<div class="flex flex-column gap-3">
3-
<h2>{{ 'project.overview.metadata.tags' | translate }} ({{ 'common.labels.optional' | translate }})</h2>
4-
5-
<osf-tags-input (tagsChanged)="onTagsChanged($event)" [tags]="selectedTags()"></osf-tags-input>
3+
<label for="registration-tag-id">
4+
<h2>{{ 'project.overview.metadata.tags' | translate }} ({{ 'common.labels.optional' | translate }})</h2>
5+
</label>
6+
<p class="mb-1">{{ 'shared.tags.description' | translate }}</p>
7+
<osf-tags-input
8+
id="registration-tag-id"
9+
(tagsChanged)="onTagsChanged($event)"
10+
[tags]="selectedTags()"
11+
></osf-tags-input>
612
</div>
713
</p-card>

src/app/features/registries/components/metadata/registries-tags/registries-tags.component.spec.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,40 @@
1+
import { Store } from '@ngxs/store';
2+
3+
import { MockProvider } from 'ng-mocks';
4+
5+
import { of } from 'rxjs';
6+
17
import { ComponentFixture, TestBed } from '@angular/core/testing';
8+
import { ActivatedRoute } from '@angular/router';
9+
10+
import { RegistriesSelectors } from '@osf/features/registries/store';
11+
import { MOCK_STORE } from '@osf/shared/mocks';
212

313
import { RegistriesTagsComponent } from './registries-tags.component';
414

15+
import { OSFTestingStoreModule } from '@testing/osf.testing.module';
16+
517
describe('TagsComponent', () => {
618
let component: RegistriesTagsComponent;
719
let fixture: ComponentFixture<RegistriesTagsComponent>;
20+
const mockRoute = {
21+
snapshot: {
22+
params: of({ id: 'someId' }),
23+
},
24+
params: of(''),
25+
};
826

27+
MOCK_STORE.selectSignal.mockImplementation((selector) => {
28+
switch (selector) {
29+
case RegistriesSelectors.getSelectedTags:
30+
return () => [];
31+
}
32+
return null;
33+
});
934
beforeEach(async () => {
1035
await TestBed.configureTestingModule({
11-
imports: [RegistriesTagsComponent],
36+
imports: [OSFTestingStoreModule, RegistriesTagsComponent],
37+
providers: [{ provide: ActivatedRoute, useValue: mockRoute }, MockProvider(Store, MOCK_STORE)],
1238
}).compileComponents();
1339

1440
fixture = TestBed.createComponent(RegistriesTagsComponent);
@@ -19,4 +45,9 @@ describe('TagsComponent', () => {
1945
it('should create', () => {
2046
expect(component).toBeTruthy();
2147
});
48+
49+
it('should render with label', () => {
50+
const labelElement = fixture.nativeElement.querySelector('label');
51+
expect(labelElement.textContent).toEqual('project.overview.metadata.tags (common.labels.optional)');
52+
});
2253
});

src/app/shared/components/subjects/subjects.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<h2 class="mb-2">{{ 'shared.subjects.title' | translate }}</h2>
2-
2+
<p class="mb-1">{{ 'shared.subjects.description' | translate }}</p>
33
<p-card class="block text-base mb-3">
44
@if (!selected().length) {
55
<p class="text-500">{{ 'shared.subjects.noSelected' | translate }}</p>

src/app/shared/components/subjects/subjects.component.spec.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,37 @@
1+
import { Store } from '@ngxs/store';
2+
3+
import { MockProvider } from 'ng-mocks';
4+
15
import { ComponentFixture, TestBed } from '@angular/core/testing';
26

7+
import { MOCK_STORE } from '@osf/shared/mocks';
8+
import { SubjectsSelectors } from '@osf/shared/stores';
9+
310
import { SubjectsComponent } from './subjects.component';
411

12+
import { OSFTestingStoreModule } from '@testing/osf.testing.module';
13+
514
describe('SubjectsComponent', () => {
615
let component: SubjectsComponent;
716
let fixture: ComponentFixture<SubjectsComponent>;
817

918
beforeEach(async () => {
19+
MOCK_STORE.selectSignal.mockImplementation((selector) => {
20+
switch (selector) {
21+
case SubjectsSelectors.getSubjects:
22+
return () => [];
23+
case SubjectsSelectors.getSubjectsLoading:
24+
return () => false;
25+
case SubjectsSelectors.getSearchedSubjects:
26+
return () => [];
27+
case SubjectsSelectors.getSearchedSubjectsLoading:
28+
return () => false;
29+
}
30+
return null;
31+
});
1032
await TestBed.configureTestingModule({
11-
imports: [SubjectsComponent],
33+
imports: [SubjectsComponent, OSFTestingStoreModule],
34+
providers: [MockProvider(Store, MOCK_STORE)],
1235
}).compileComponents();
1336

1437
fixture = TestBed.createComponent(SubjectsComponent);
@@ -19,4 +42,11 @@ describe('SubjectsComponent', () => {
1942
it('should create', () => {
2043
expect(component).toBeTruthy();
2144
});
45+
46+
it('should render with label and description', () => {
47+
const headerElement = fixture.nativeElement.querySelector('h2');
48+
expect(headerElement.textContent).toEqual('shared.subjects.title');
49+
const descriptionElement = fixture.nativeElement.querySelector('p');
50+
expect(descriptionElement.textContent).toEqual('shared.subjects.description');
51+
});
2252
});

src/assets/i18n/en.json

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2447,6 +2447,15 @@
24472447
"copyright": "Copyright © 2011-2025"
24482448
},
24492449
"shared": {
2450+
"title": {
2451+
"description": "Provide a concise and descriptive title for your registration that accurately reflects the main focus of your research. A clear and specific title will help others quickly understand the essence of your study."
2452+
},
2453+
"description": {
2454+
"message": "Write a detailed description of your research project, including its purpose and any expected outcomes. This should give readers a comprehensive overview of your work."
2455+
},
2456+
"affiliatedInstitutions": {
2457+
"description": "This is a service provided by the OSF and is automatically applied to your registration. If you are not sure if your institution has signed up for this service, you can look for their name in this list."
2458+
},
24502459
"resources": {
24512460
"title": "Open resources",
24522461
"data": "Data",
@@ -2466,10 +2475,12 @@
24662475
"title": "Subjects",
24672476
"noSelected": "No subjects selected",
24682477
"searchSubjects": "Search subjects",
2469-
"noSubject": "No subjects found"
2478+
"noSubject": "No subjects found",
2479+
"description": "Identify the main subject areas that your research pertains to. This helps categorize your work and makes it easier for others in your field to find and reference it."
24702480
},
24712481
"tags": {
2472-
"title": "Tags"
2482+
"title": "Tags",
2483+
"description": "Enter specific keywords that describe the key elements and concepts of your research. These keywords will improve the discoverability of your registration in search results and databases."
24732484
},
24742485
"files": {
24752486
"limitText": "You may attach up to 5 file(s) to this question. Files cannot total over 5GB in size.",
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { DraftRegistrationModel } from '@shared/models';
2+
3+
export const MOCK_DRAFT_REGISTRATION: DraftRegistrationModel = {
4+
branchedFrom: {
5+
filesLink: 'someFilesLink',
6+
id: 'projectId',
7+
title: 'Project Title',
8+
type: 'nodes',
9+
},
10+
components: [],
11+
description: 'This is a description',
12+
hasProject: true,
13+
id: 'thisissupposedtobeauniqueid',
14+
license: {
15+
id: 'someLicenseId',
16+
options: null,
17+
},
18+
providerId: 'osf',
19+
registrationSchemaId: '6797c0dedee44d144a2943fc',
20+
stepsData: {
21+
summary: '',
22+
uploader: [],
23+
},
24+
tags: [],
25+
title: 'This is a title',
26+
};

0 commit comments

Comments
 (0)