Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ import { of, throwError } from 'rxjs';
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { CreateCollectionSubmission } from '@osf/features/collections/store/add-to-collection/add-to-collection.actions';
import { CedarMetadataAttributes, CedarRecordDataBinding } from '@osf/features/metadata/models';
import { CreateCedarMetadataRecord } from '@osf/features/metadata/store';
import {
CedarMetadataAttributes,
CedarMetadataRecordData,
CedarRecordDataBinding,
} from '@osf/features/metadata/models';
import { CreateCedarMetadataRecord, UpdateCedarMetadataRecord } from '@osf/features/metadata/store';
import { UpdateProjectPublicStatus } from '@osf/features/project/overview/store';
import { ResourceType } from '@osf/shared/enums/resource-type.enum';
import { CollectionSubmissionPayload } from '@osf/shared/models/collections/collection-submission-payload.model';
Expand All @@ -29,6 +33,15 @@ const MOCK_CEDAR_DATA: CedarRecordDataBinding = {
isPublished: true,
};

const MOCK_EXISTING_CEDAR_RECORD: CedarMetadataRecordData = {
id: 'cedar-record-1',
attributes: { metadata: {} as CedarMetadataAttributes, is_published: true },
relationships: {
template: { data: { type: 'cedar-metadata-templates', id: 'template-1' } },
target: { data: { type: 'nodes', id: 'project-1' } },
},
};

describe('AddToCollectionConfirmationDialogComponent', () => {
let component: AddToCollectionConfirmationDialogComponent;
let fixture: ComponentFixture<AddToCollectionConfirmationDialogComponent>;
Expand All @@ -40,6 +53,7 @@ describe('AddToCollectionConfirmationDialogComponent', () => {
payload?: CollectionSubmissionPayload;
project?: { id: string; isPublic: boolean };
cedarData?: CedarRecordDataBinding | null;
existingCedarRecord?: CedarMetadataRecordData | null;
};
};

Expand Down Expand Up @@ -116,7 +130,7 @@ describe('AddToCollectionConfirmationDialogComponent', () => {
expect(dialogRef.close).toHaveBeenCalledWith(true);
});

it('should create Cedar record before submission when cedarData is present', () => {
it('should create Cedar record before submission when cedarData is present and no existing record', () => {
dialogConfig.data.cedarData = MOCK_CEDAR_DATA;
vi.spyOn(store, 'dispatch').mockReturnValue(of(void 0));

Expand All @@ -125,6 +139,22 @@ describe('AddToCollectionConfirmationDialogComponent', () => {
expect(store.dispatch).toHaveBeenCalledWith(
new CreateCedarMetadataRecord(MOCK_CEDAR_DATA, 'project-1', ResourceType.Project)
);
expect(store.dispatch).not.toHaveBeenCalledWith(expect.any(UpdateCedarMetadataRecord));
expect(store.dispatch).toHaveBeenCalledWith(new CreateCollectionSubmission(MOCK_PAYLOAD));
expect(dialogRef.close).toHaveBeenCalledWith(true);
});

it('should update existing Cedar record instead of creating when existingCedarRecord is provided', () => {
dialogConfig.data.cedarData = MOCK_CEDAR_DATA;
dialogConfig.data.existingCedarRecord = MOCK_EXISTING_CEDAR_RECORD;
vi.spyOn(store, 'dispatch').mockReturnValue(of(void 0));

component.handleAddToCollectionConfirm();

expect(store.dispatch).toHaveBeenCalledWith(
new UpdateCedarMetadataRecord(MOCK_CEDAR_DATA, 'cedar-record-1', 'project-1', ResourceType.Project)
);
expect(store.dispatch).not.toHaveBeenCalledWith(expect.any(CreateCedarMetadataRecord));
expect(store.dispatch).toHaveBeenCalledWith(new CreateCollectionSubmission(MOCK_PAYLOAD));
expect(dialogRef.close).toHaveBeenCalledWith(true);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import { ChangeDetectionStrategy, Component, DestroyRef, inject, signal } from '
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';

import { CreateCollectionSubmission } from '@osf/features/collections/store/add-to-collection/add-to-collection.actions';
import { CedarRecordDataBinding } from '@osf/features/metadata/models';
import { CreateCedarMetadataRecord } from '@osf/features/metadata/store';
import { CedarMetadataRecordData, CedarRecordDataBinding } from '@osf/features/metadata/models';
import { CreateCedarMetadataRecord, UpdateCedarMetadataRecord } from '@osf/features/metadata/store';
import { UpdateProjectPublicStatus } from '@osf/features/project/overview/store';
import { ResourceType } from '@osf/shared/enums/resource-type.enum';
import { ProjectModel } from '@osf/shared/models/projects/projects.model';
import { ToastService } from '@osf/shared/services/toast.service';

@Component({
Expand All @@ -34,29 +35,33 @@ export class AddToCollectionConfirmationDialogComponent {
createCollectionSubmission: CreateCollectionSubmission,
updateProjectPublicStatus: UpdateProjectPublicStatus,
createCedarRecord: CreateCedarMetadataRecord,
updateCedarRecord: UpdateCedarMetadataRecord,
});

handleAddToCollectionConfirm(): void {
const payload = this.config.data.payload;
const project = this.config.data.project;
const project = this.config.data.project as ProjectModel | null | undefined;
const cedarData = this.config.data.cedarData as CedarRecordDataBinding | null | undefined;
const existingCedarRecord = this.config.data.existingCedarRecord as CedarMetadataRecordData | null | undefined;

if (!payload || !project) return;

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

const updatePublicStatus$: Observable<unknown> = project.isPublic
? of(null)
: this.actions.updateProjectPublicStatus(projectPayload);

const createCedar$: Observable<unknown> = cedarData
? this.actions.createCedarRecord(cedarData, project.id as string, ResourceType.Project)
const saveCedar$: Observable<unknown> = cedarData
? existingCedarRecord
? this.actions.updateCedarRecord(cedarData, existingCedarRecord.id!, project.id, ResourceType.Project)
: this.actions.createCedarRecord(cedarData, project.id, ResourceType.Project)
: of(null);

updatePublicStatus$
.pipe(
switchMap(() => createCedar$),
switchMap(() => saveCedar$),
switchMap(() => this.actions.createCollectionSubmission(payload)),
takeUntilDestroyed(this.destroyRef)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,13 +270,16 @@ describe('AddToCollectionComponent', () => {
expect(result).toBeUndefined();
});

it('should open confirmation dialog in new submission mode', () => {
it('should open confirmation dialog in new submission mode with existingCedarRecord in data', () => {
const { component, dialogService } = setup();
component.handleAddToCollection();

expect(dialogService.open).toHaveBeenCalledWith(
expect.any(Function),
expect.objectContaining({ header: 'collections.addToCollection.confirmationDialogHeader' })
expect.objectContaining({
header: 'collections.addToCollection.confirmationDialogHeader',
data: expect.objectContaining({ existingCedarRecord: null }),
})
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,21 +245,18 @@ export class AddToCollectionComponent implements CanDeactivateComponent {
payload,
project: this.selectedProject(),
cedarData: this.pendingCedarData(),
existingCedarRecord: this.existingCedarRecord(),
},
})
.onClose.pipe(
filter((res) => !!res),
switchMap(() => this.saveCedarRecordIfNeeded()),
takeUntilDestroyed(this.destroyRef)
)
.subscribe({
next: () => {
this.allowNavigation.set(true);
this.router.navigate([this.selectedProject()?.id, 'overview']);
},
error: () => {
this.toastService.showError('collections.addToCollection.updateError');
},
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export class CollectionMetadataStepComponent {
const template = this.cedarTemplate();
if (!editor || !template) return;

const currentMetadata = editor.currentMetadata;
const currentMetadata = editor.currentMetadata ?? this.cedarFormData();
const isValid = !!editor.dataQualityReport?.isValid;

if (currentMetadata) {
Expand Down
Loading