Skip to content

Commit 07759e1

Browse files
authored
Merge pull request #1000 from Vlad0n20/feat/ENG-9827
[ENG-9827] - Revert metadata creation workflow
2 parents ab21476 + 7a6dad9 commit 07759e1

25 files changed

Lines changed: 957 additions & 980 deletions

src/app/features/collections/components/add-to-collection/add-to-collection-confirmation-dialog/add-to-collection-confirmation-dialog.component.spec.ts

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ import { of, throwError } from 'rxjs';
99
import { ComponentFixture, TestBed } from '@angular/core/testing';
1010

1111
import { CreateCollectionSubmission } from '@osf/features/collections/store/add-to-collection/add-to-collection.actions';
12+
import { CedarMetadataAttributes, CedarRecordDataBinding } from '@osf/features/metadata/models';
13+
import { CreateCedarMetadataRecord } from '@osf/features/metadata/store';
1214
import { UpdateProjectPublicStatus } from '@osf/features/project/overview/store';
15+
import { ResourceType } from '@osf/shared/enums/resource-type.enum';
16+
import { CollectionSubmissionPayload } from '@osf/shared/models/collections/collection-submission-payload.model';
1317
import { ToastService } from '@osf/shared/services/toast.service';
1418

1519
import { provideOSFCore } from '@testing/osf.testing.provider';
@@ -19,20 +23,39 @@ import { ToastServiceMock, ToastServiceMockType } from '@testing/providers/toast
1923

2024
import { AddToCollectionConfirmationDialogComponent } from './add-to-collection-confirmation-dialog.component';
2125

26+
const MOCK_CEDAR_DATA: CedarRecordDataBinding = {
27+
data: { '@context': {} } as CedarMetadataAttributes,
28+
id: 'template-1',
29+
isPublished: true,
30+
};
31+
2232
describe('AddToCollectionConfirmationDialogComponent', () => {
2333
let component: AddToCollectionConfirmationDialogComponent;
2434
let fixture: ComponentFixture<AddToCollectionConfirmationDialogComponent>;
2535
let store: Store;
2636
let dialogRef: DynamicDialogRef;
2737
let toastService: ToastServiceMockType;
28-
let dialogConfig: { data: { payload?: unknown; project?: { id: string; isPublic: boolean } } };
38+
let dialogConfig: {
39+
data: {
40+
payload?: CollectionSubmissionPayload;
41+
project?: { id: string; isPublic: boolean };
42+
cedarData?: CedarRecordDataBinding | null;
43+
};
44+
};
45+
46+
const MOCK_PAYLOAD: CollectionSubmissionPayload = {
47+
collectionId: 'collection-1',
48+
projectId: 'project-1',
49+
userId: 'user-1',
50+
};
2951

3052
beforeEach(() => {
3153
toastService = ToastServiceMock.simple();
3254
dialogConfig = {
3355
data: {
34-
payload: { title: 'Submission' },
56+
payload: MOCK_PAYLOAD,
3557
project: { id: 'project-1', isPublic: false },
58+
cedarData: null,
3659
},
3760
};
3861

@@ -69,13 +92,14 @@ describe('AddToCollectionConfirmationDialogComponent', () => {
6992
expect(toastService.showSuccess).not.toHaveBeenCalled();
7093
});
7194

72-
it('should update project public status and create submission when project is private', () => {
95+
it('should update project public status then create submission when project is private and no Cedar data', () => {
7396
vi.spyOn(store, 'dispatch').mockReturnValue(of(void 0));
7497

7598
component.handleAddToCollectionConfirm();
7699

77100
expect(store.dispatch).toHaveBeenCalledWith(new UpdateProjectPublicStatus([{ id: 'project-1', public: true }]));
78-
expect(store.dispatch).toHaveBeenCalledWith(new CreateCollectionSubmission({ title: 'Submission' } as any));
101+
expect(store.dispatch).toHaveBeenCalledWith(new CreateCollectionSubmission(MOCK_PAYLOAD));
102+
expect(store.dispatch).not.toHaveBeenCalledWith(expect.any(CreateCedarMetadataRecord));
79103
expect(dialogRef.close).toHaveBeenCalledWith(true);
80104
expect(toastService.showSuccess).toHaveBeenCalledWith('collections.addToCollection.confirmationDialogToastMessage');
81105
expect(component.isSubmitting()).toBe(false);
@@ -87,11 +111,34 @@ describe('AddToCollectionConfirmationDialogComponent', () => {
87111

88112
component.handleAddToCollectionConfirm();
89113

90-
expect(store.dispatch).toHaveBeenCalledWith(new CreateCollectionSubmission({ title: 'Submission' } as any));
114+
expect(store.dispatch).toHaveBeenCalledWith(new CreateCollectionSubmission(MOCK_PAYLOAD));
91115
expect(store.dispatch).not.toHaveBeenCalledWith(expect.any(UpdateProjectPublicStatus));
92116
expect(dialogRef.close).toHaveBeenCalledWith(true);
93117
});
94118

119+
it('should create Cedar record before submission when cedarData is present', () => {
120+
dialogConfig.data.cedarData = MOCK_CEDAR_DATA;
121+
vi.spyOn(store, 'dispatch').mockReturnValue(of(void 0));
122+
123+
component.handleAddToCollectionConfirm();
124+
125+
expect(store.dispatch).toHaveBeenCalledWith(
126+
new CreateCedarMetadataRecord(MOCK_CEDAR_DATA, 'project-1', ResourceType.Project)
127+
);
128+
expect(store.dispatch).toHaveBeenCalledWith(new CreateCollectionSubmission(MOCK_PAYLOAD));
129+
expect(dialogRef.close).toHaveBeenCalledWith(true);
130+
});
131+
132+
it('should not create Cedar record when cedarData is null', () => {
133+
dialogConfig.data.cedarData = null;
134+
vi.spyOn(store, 'dispatch').mockReturnValue(of(void 0));
135+
136+
component.handleAddToCollectionConfirm();
137+
138+
expect(store.dispatch).not.toHaveBeenCalledWith(expect.any(CreateCedarMetadataRecord));
139+
expect(store.dispatch).toHaveBeenCalledWith(new CreateCollectionSubmission(MOCK_PAYLOAD));
140+
});
141+
95142
it('should reset submitting state on error', () => {
96143
vi.spyOn(store, 'dispatch').mockImplementation((action) => {
97144
if (action instanceof CreateCollectionSubmission) {
@@ -106,4 +153,20 @@ describe('AddToCollectionConfirmationDialogComponent', () => {
106153
expect(dialogRef.close).not.toHaveBeenCalled();
107154
expect(toastService.showSuccess).not.toHaveBeenCalled();
108155
});
156+
157+
it('should reset submitting state on Cedar record creation error', () => {
158+
dialogConfig.data.cedarData = MOCK_CEDAR_DATA;
159+
vi.spyOn(store, 'dispatch').mockImplementation((action) => {
160+
if (action instanceof CreateCedarMetadataRecord) {
161+
return throwError(() => new Error('cedar fail'));
162+
}
163+
return of(void 0);
164+
});
165+
166+
component.handleAddToCollectionConfirm();
167+
168+
expect(component.isSubmitting()).toBe(false);
169+
expect(dialogRef.close).not.toHaveBeenCalled();
170+
expect(toastService.showSuccess).not.toHaveBeenCalled();
171+
});
109172
});

src/app/features/collections/components/add-to-collection/add-to-collection-confirmation-dialog/add-to-collection-confirmation-dialog.component.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import { TranslatePipe } from '@ngx-translate/core';
55
import { Button } from 'primeng/button';
66
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
77

8-
import { forkJoin, of } from 'rxjs';
8+
import { Observable, of, switchMap } from 'rxjs';
99

1010
import { ChangeDetectionStrategy, Component, DestroyRef, inject, signal } from '@angular/core';
1111
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
1212

1313
import { CreateCollectionSubmission } from '@osf/features/collections/store/add-to-collection/add-to-collection.actions';
14+
import { CedarRecordDataBinding } from '@osf/features/metadata/models';
15+
import { CreateCedarMetadataRecord } from '@osf/features/metadata/store';
1416
import { UpdateProjectPublicStatus } from '@osf/features/project/overview/store';
17+
import { ResourceType } from '@osf/shared/enums/resource-type.enum';
1518
import { ToastService } from '@osf/shared/services/toast.service';
1619

1720
@Component({
@@ -30,26 +33,33 @@ export class AddToCollectionConfirmationDialogComponent {
3033
actions = createDispatchMap({
3134
createCollectionSubmission: CreateCollectionSubmission,
3235
updateProjectPublicStatus: UpdateProjectPublicStatus,
36+
createCedarRecord: CreateCedarMetadataRecord,
3337
});
3438

3539
handleAddToCollectionConfirm(): void {
3640
const payload = this.config.data.payload;
3741
const project = this.config.data.project;
42+
const cedarData = this.config.data.cedarData as CedarRecordDataBinding | null | undefined;
3843

3944
if (!payload || !project) return;
4045

4146
this.isSubmitting.set(true);
4247
const projectPayload = [{ id: project.id as string, public: true }];
4348

44-
const updatePublicStatus$ = project.isPublic ? of(null) : this.actions.updateProjectPublicStatus(projectPayload);
49+
const updatePublicStatus$: Observable<unknown> = project.isPublic
50+
? of(null)
51+
: this.actions.updateProjectPublicStatus(projectPayload);
4552

46-
const createSubmission$ = this.actions.createCollectionSubmission(payload);
53+
const createCedar$: Observable<unknown> = cedarData
54+
? this.actions.createCedarRecord(cedarData, project.id as string, ResourceType.Project)
55+
: of(null);
4756

48-
forkJoin({
49-
publicStatusUpdate: updatePublicStatus$,
50-
collectionSubmission: createSubmission$,
51-
})
52-
.pipe(takeUntilDestroyed(this.destroyRef))
57+
updatePublicStatus$
58+
.pipe(
59+
switchMap(() => createCedar$),
60+
switchMap(() => this.actions.createCollectionSubmission(payload)),
61+
takeUntilDestroyed(this.destroyRef)
62+
)
5363
.subscribe({
5464
next: () => {
5565
this.isSubmitting.set(false);

src/app/features/collections/components/add-to-collection/add-to-collection.component.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ <h1 class="collections-heading flex align-items-center">{{ collectionProvider()?
4848
[targetStepValue]="AddToCollectionSteps.CollectionMetadata"
4949
[isDisabled]="isCollectionMetadataDisabled()"
5050
[primaryCollectionId]="primaryCollectionId()"
51+
[isCedarMode]="isCedarMode()"
52+
[cedarTemplate]="requiredMetadataTemplate()"
53+
[existingCedarRecord]="existingCedarRecord()"
5154
(metadataSaved)="handleCollectionMetadataSaved($event)"
55+
(cedarDataSaved)="handleCedarDataSaved($event)"
5256
(stepChange)="handleChangeStep($event)"
5357
/>
5458
</p-stepper>

0 commit comments

Comments
 (0)