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
8 changes: 8 additions & 0 deletions setup-jest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,11 @@ jest.mock('@newrelic/browser-agent/loaders/browser-agent', () => ({
stop: jest.fn(),
})),
}));

if (!globalThis.structuredClone) {
Object.defineProperty(globalThis, 'structuredClone', {
value: <T>(value: T): T => JSON.parse(JSON.stringify(value)) as T,
writable: true,
configurable: true,
});
}
10 changes: 0 additions & 10 deletions src/app/features/contributors/contributors.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,6 @@ describe('Component: Contributors', () => {

const mockContributors: ContributorModel[] = [MOCK_CONTRIBUTOR, MOCK_CONTRIBUTOR_WITHOUT_HISTORY];

beforeAll(() => {
if (typeof (globalThis as any).structuredClone !== 'function') {
Object.defineProperty(globalThis as any, 'structuredClone', {
configurable: true,
writable: true,
value: (o: unknown) => JSON.parse(JSON.stringify(o)),
});
}
});

beforeEach(async () => {
jest.useFakeTimers();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,6 @@ describe('ContributorsDialogComponent', () => {

const mockContributors: ContributorModel[] = [MOCK_CONTRIBUTOR];

beforeAll(() => {
if (typeof (globalThis as any).structuredClone !== 'function') {
Object.defineProperty(globalThis as any, 'structuredClone', {
configurable: true,
writable: true,
value: (o: unknown) => JSON.parse(JSON.stringify(o)),
});
}
});

beforeEach(async () => {
mockCustomDialogService = CustomDialogServiceMockBuilder.create().build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,6 @@ describe('ModeratorsListComponent', () => {

const mockModerators: ModeratorModel[] = MOCK_MODERATORS;

beforeAll(() => {
if (typeof (globalThis as any).structuredClone !== 'function') {
Object.defineProperty(globalThis as any, 'structuredClone', {
configurable: true,
writable: true,
value: (o: unknown) => JSON.parse(JSON.stringify(o)),
});
}
});

beforeEach(async () => {
mockActivatedRoute = ActivatedRouteMockBuilder.create()
.withParams({ providerId: mockProviderId })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
</div>

<section class="mt-4 flex flex-row justify-content-end">
<p-button [label]="'common.buttons.addOneMore' | translate" severity="secondary" (click)="add()" />
<p-button [label]="'common.buttons.addOneMore' | translate" severity="secondary" (onClick)="add()" />
</section>
</section>
Original file line number Diff line number Diff line change
Expand Up @@ -12,52 +12,49 @@ import { OSFTestingModule } from '@testing/osf.testing.module';
describe('ArrayInputComponent', () => {
let component: ArrayInputComponent;
let fixture: ComponentFixture<ArrayInputComponent>;
let formArray: FormArray<FormControl>;
let formArray: FormArray<FormControl<string>>;

beforeEach(async () => {
await TestBed.configureTestingModule({
function setup(overrides?: { withValidators?: boolean; formArray?: FormArray<FormControl<string>> }) {
TestBed.configureTestingModule({
imports: [ArrayInputComponent, MockComponent(TextInputComponent), OSFTestingModule],
}).compileComponents();
});

fixture = TestBed.createComponent(ArrayInputComponent);
component = fixture.componentInstance;

formArray = new FormArray<FormControl>([new FormControl('test')]);
fixture.componentRef.setInput('formArray', formArray);
formArray =
overrides?.formArray ?? new FormArray<FormControl<string>>([new FormControl('test', { nonNullable: true })]);
fixture.componentRef.setInput('formArray', formArray as FormArray<FormControl>);
fixture.componentRef.setInput('inputPlaceholder', 'Enter value');
fixture.componentRef.setInput('validators', [Validators.required]);
if (overrides?.withValidators ?? true) {
fixture.componentRef.setInput('validators', [Validators.required]);
}

fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});

it('should have correct input values', () => {
expect(component.formArray()).toBe(formArray);
expect(component.inputPlaceholder()).toBe('Enter value');
expect(component.validators()).toEqual([Validators.required]);
});
}

it('should add new control to form array', () => {
setup();
const initialLength = formArray.length;

component.add();

expect(formArray.length).toBe(initialLength + 1);
expect(formArray.at(formArray.length - 1)).toBeInstanceOf(FormControl);
const newControl = formArray.at(formArray.length - 1);
expect(newControl.value).toBe('');
expect(newControl.hasError('required')).toBe(true);
});

it('should add control with correct validators', () => {
it('should add control without validators when validators input is not set', () => {
setup({ withValidators: false });
component.add();

const newControl = formArray.at(formArray.length - 1);
expect(newControl.hasError('required')).toBe(true);
expect(newControl.errors).toBeNull();
});

it('should remove control at specified index', () => {
component.add();
setup();
component.add();
const initialLength = formArray.length;

Expand All @@ -67,37 +64,13 @@ describe('ArrayInputComponent', () => {
});

it('should not remove control if only one control exists', () => {
const singleControlArray = new FormArray<FormControl>([new FormControl('only')]);
fixture.componentRef.setInput('formArray', singleControlArray);
fixture.detectChanges();
const singleControlArray = new FormArray<FormControl<string>>([new FormControl('only', { nonNullable: true })]);
setup({ formArray: singleControlArray });

const initialLength = singleControlArray.length;

component.remove(0);

expect(singleControlArray.length).toBe(initialLength);
});

it('should handle multiple add and remove operations', () => {
const initialLength = formArray.length;

component.add();
component.add();
component.add();

expect(formArray.length).toBe(initialLength + 3);

component.remove(1);
component.remove(2);

expect(formArray.length).toBe(initialLength + 1);
});

it('should create controls with nonNullable true', () => {
component.add();

const newControl = formArray.at(formArray.length - 1);
expect(newControl.value).toBe('');
expect(newControl.hasError('required')).toBe(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import { TextInputComponent } from '@osf/shared/components/text-input/text-input
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ArrayInputComponent {
formArray = input.required<FormArray<FormControl>>();
inputPlaceholder = input.required<string>();
validators = input.required<ValidatorFn[]>();
readonly formArray = input.required<FormArray<FormControl>>();
readonly inputPlaceholder = input.required<string>();
readonly validators = input<ValidatorFn[]>([]);

add() {
add(): void {
this.formArray().push(
new FormControl('', {
nonNullable: true,
Expand All @@ -28,9 +28,11 @@ export class ArrayInputComponent {
);
}

remove(index: number) {
if (this.formArray().length > 1) {
this.formArray().removeAt(index);
remove(index: number): void {
const formArray = this.formArray();

if (formArray.length > 1) {
formArray.removeAt(index);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ <h2>{{ 'preprints.preprintStepper.authorAssertions.publicPreregistration.title'
styleClass="w-full"
[label]="'common.buttons.back' | translate"
severity="info"
(click)="backButtonClicked()"
(onClick)="backButtonClicked()"
/>
<p-button
class="w-6 md:w-9rem"
Expand All @@ -236,6 +236,6 @@ <h2>{{ 'preprints.preprintStepper.authorAssertions.publicPreregistration.title'
tooltipPosition="top"
[disabled]="authorAssertionsForm.invalid"
[loading]="isUpdatingPreprint()"
(click)="nextButtonClicked()"
(onClick)="nextButtonClicked()"
/>
</section>
Loading
Loading