Skip to content
Draft
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
@@ -1,24 +1,18 @@
import { MockComponents, MockProvider } from 'ng-mocks';
import { MockProvider } from 'ng-mocks';

import { DynamicDialogConfig } from 'primeng/dynamicdialog';

import { ComponentFixture, TestBed } from '@angular/core/testing';

import { FileSelectDestinationComponent } from '@osf/shared/components/file-select-destination/file-select-destination.component';
import { IconComponent } from '@osf/shared/components/icon/icon.component';
import { LoadingSpinnerComponent } from '@osf/shared/components/loading-spinner/loading-spinner.component';
import { CustomConfirmationService } from '@osf/shared/services/custom-confirmation.service';
import { FilesService } from '@osf/shared/services/files.service';
import { ToastService } from '@osf/shared/services/toast.service';

import { provideOSFCore } from '@testing/osf.testing.provider';
import { CustomConfirmationServiceMock } from '@testing/providers/custom-confirmation-provider.mock';
import { provideDynamicDialogRefMock } from '@testing/providers/dynamic-dialog-ref.mock';
import { provideMockStore } from '@testing/providers/store-provider.mock';
import { ToastServiceMock } from '@testing/providers/toast-provider.mock';

import { FilesSelectors } from '../../store';

import { ConfirmMoveFileDialogComponent } from './confirm-move-file-dialog.component';

describe('ConfirmConfirmMoveFileDialogComponent', () => {
Expand All @@ -31,23 +25,14 @@ describe('ConfirmConfirmMoveFileDialogComponent', () => {
};

TestBed.configureTestingModule({
imports: [
ConfirmMoveFileDialogComponent,
...MockComponents(IconComponent, LoadingSpinnerComponent, FileSelectDestinationComponent),
],
imports: [ConfirmMoveFileDialogComponent],
providers: [
provideOSFCore(),
provideDynamicDialogRefMock(),
MockProvider(DynamicDialogConfig, dialogConfigMock),
MockProvider(FilesService),
MockProvider(ToastService, ToastServiceMock.simple()),
MockProvider(CustomConfirmationService, CustomConfirmationServiceMock.simple()),
provideMockStore({
signals: [
{ selector: FilesSelectors.getMoveDialogFiles, value: [] },
{ selector: FilesSelectors.getProvider, value: null },
],
}),
],
});

Expand All @@ -63,10 +48,5 @@ describe('ConfirmConfirmMoveFileDialogComponent', () => {
it('should initialize with correct properties', () => {
expect(component.config).toBeDefined();
expect(component.dialogRef).toBeDefined();
expect(component.files).toBeDefined();
});

it('should get files from store', () => {
expect(component.files()).toEqual([]);
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { select } from '@ngxs/store';

import { TranslatePipe, TranslateService } from '@ngx-translate/core';

import { Button } from 'primeng/button';
Expand All @@ -11,7 +9,6 @@ import { catchError } from 'rxjs/operators';
import { ChangeDetectionStrategy, Component, DestroyRef, inject } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';

import { FilesSelectors } from '@osf/features/files/store';
import { CustomConfirmationService } from '@osf/shared/services/custom-confirmation.service';
import { FilesService } from '@osf/shared/services/files.service';
import { ToastService } from '@osf/shared/services/toast.service';
Expand All @@ -35,8 +32,6 @@ export class ConfirmMoveFileDialogComponent {
private readonly toastService = inject(ToastService);
private readonly customConfirmationService = inject(CustomConfirmationService);

readonly files = select(FilesSelectors.getMoveDialogFiles);

readonly provider = this.config.data.storageProvider;

private fileProjectId = this.config.data.resourceId;
Expand Down Expand Up @@ -112,9 +107,7 @@ export class ConfirmMoveFileDialogComponent {
this.customConfirmationService.confirmDelete({
headerKey: conflictFiles.length > 1 ? 'files.dialogs.replaceFile.multiple' : 'files.dialogs.replaceFile.single',
messageKey: 'files.dialogs.replaceFile.message',
messageParams: {
name: conflictFiles.map((c) => c.file.name).join(', '),
},
messageParams: { name: conflictFiles.map((c) => c.file.name).join(', ') },
acceptLabelKey: 'common.buttons.replace',
onConfirm: () => {
const replaceRequests$ = conflictFiles.map(({ link }) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<form [formGroup]="folderForm" (ngSubmit)="onSubmit()">
<div class="flex flex-column gap-4">
<osf-text-input
[control]="folderForm.controls['name']"
[control]="folderForm.controls.name"
[label]="'files.dialogs.createFolder.folderName'"
[placeholder]="'files.dialogs.createFolder.folderNamePlaceholder'"
[maxLength]="nameLimit"
[maxLength]="nameMaxLength"
[minLength]="nameMinLength"
>
</osf-text-input>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('CreateFolderDialogComponent', () => {
});

it('should expose name limits from shared input limits', () => {
expect(component.nameLimit).toBe(InputLimits.name.maxLength);
expect(component.nameMaxLength).toBe(InputLimits.name.maxLength);
expect(component.nameMinLength).toBe(InputLimits.name.minLength);
});

Expand All @@ -46,6 +46,14 @@ describe('CreateFolderDialogComponent', () => {
expect(dialogRef.close).not.toHaveBeenCalled();
});

it('should not close dialog when value is only whitespace', () => {
component.folderForm.controls.name.setValue(' ');

component.onSubmit();

expect(dialogRef.close).not.toHaveBeenCalled();
});

it('should close dialog with trimmed folder name when form is valid', () => {
component.folderForm.controls.name.setValue(' New Folder ');

Expand All @@ -69,4 +77,20 @@ describe('CreateFolderDialogComponent', () => {

expect(dialogRef.close).not.toHaveBeenCalled();
});

it('should not close dialog when value is shorter than minimum length', () => {
component.folderForm.controls.name.setValue('A'.repeat(InputLimits.name.minLength - 1));

component.onSubmit();

expect(dialogRef.close).not.toHaveBeenCalled();
});

it('should not close dialog when value exceeds maximum length', () => {
component.folderForm.controls.name.setValue('A'.repeat(InputLimits.name.maxLength + 1));

component.onSubmit();

expect(dialogRef.close).not.toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Button } from 'primeng/button';
import { DynamicDialogRef } from 'primeng/dynamicdialog';

import { Component, inject } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';

import { TextInputComponent } from '@osf/shared/components/text-input/text-input.component';
import { forbiddenFileNameCharacters, InputLimits } from '@osf/shared/constants/input-limits.const';
Expand All @@ -17,14 +17,17 @@ import { CustomValidators } from '@osf/shared/helpers/custom-form-validators.hel
})
export class CreateFolderDialogComponent {
readonly dialogRef = inject(DynamicDialogRef);
readonly nameLimit = InputLimits.name.maxLength;

readonly nameMaxLength = InputLimits.name.maxLength;
readonly nameMinLength = InputLimits.name.minLength;

readonly folderForm = new FormGroup({
name: new FormControl('', {
nonNullable: true,
validators: [
CustomValidators.requiredTrimmed(),
Validators.minLength(InputLimits.name.minLength),
Validators.maxLength(InputLimits.name.maxLength),
CustomValidators.forbiddenCharactersValidator(forbiddenFileNameCharacters),
CustomValidators.noPeriodAtEnd(),
],
Expand All @@ -37,9 +40,6 @@ export class CreateFolderDialogComponent {
}

const folderName = this.folderForm.getRawValue().name.trim();

if (folderName) {
this.dialogRef.close(folderName);
}
this.dialogRef.close(folderName);
}
}
Original file line number Diff line number Diff line change
@@ -1,50 +1,52 @@
<form [formGroup]="fileMetadataForm" (ngSubmit)="setFileMetadata()" class="flex flex-column gap-3">
<form class="flex flex-column gap-3" [formGroup]="fileMetadataForm" (ngSubmit)="setFileMetadata()">
<div class="flex flex-column gap-1">
<p>{{ 'common.labels.title' | translate }}</p>
<input pInputText id="title" [formControl]="titleControl" />
<label for="title">{{ 'common.labels.title' | translate }}</label>
<input pInputText id="title" [formControl]="fileMetadataForm.controls.title" />
</div>

<div class="flex flex-column gap-1">
<p>{{ 'common.labels.description' | translate }}</p>
<input pInputText id="description" [formControl]="descriptionControl" />
<label for="description">{{ 'common.labels.description' | translate }}</label>
<textarea pTextarea id="description" rows="3" [formControl]="fileMetadataForm.controls.description"></textarea>
</div>

<div class="flex flex-column gap-1">
<p>{{ 'files.detail.fileMetadata.fields.resourceType' | translate }}</p>
<label for="resourceType">{{ 'files.detail.fileMetadata.fields.resourceType' | translate }}</label>
<p-select
inputId="resourceType"
class="w-full"
appendTo="body"
[options]="resourceTypes"
optionValue="value"
optionLabel="value"
appendTo="body"
[formControl]="resourceTypeControl"
[formControl]="fileMetadataForm.controls.resourceType"
[showClear]="true"
></p-select>
</div>

<div class="flex flex-column gap-1">
<p>{{ 'files.detail.fileMetadata.fields.resourceLanguage' | translate }}</p>
<label for="resourceLanguage">{{ 'files.detail.fileMetadata.fields.resourceLanguage' | translate }}</label>
<p-select
inputId="resourceLanguage"
class="w-full"
appendTo="body"
[options]="languages"
optionValue="code"
optionLabel="name"
[formControl]="resourceLanguageControl"
[formControl]="fileMetadataForm.controls.resourceLanguage"
[filter]="true"
filterBy="name"
appendTo="body"
[showClear]="true"
[virtualScroll]="true"
[virtualScrollItemSize]="35"
></p-select>
</div>

<div class="flex btn-full-width gap-2 mt-4">
<p-button [label]="'common.buttons.cancel' | translate" severity="info" class="w-full" (onClick)="cancel()" />
<p-button class="w-full" [label]="'common.buttons.cancel' | translate" severity="info" (onClick)="cancel()" />
<p-button
[label]="'common.buttons.save' | translate"
class="w-full"
type="submit"
[label]="'common.buttons.save' | translate"
[disabled]="!fileMetadataForm.valid"
/>
</div>
Expand Down
Loading
Loading