Skip to content

Commit

Permalink
feat(editor-content): add unit tests to file field store #30059 (#30184)
Browse files Browse the repository at this point in the history
### Parent Issue

#30059 

### Proposed Changes
* Add more unit tests
* Cases for Image field

### Checklist
- [x] Tests
- [x] Translations
- [x] Security Implications Contemplated (add notes if applicable)

### Screenshots


https://github.com/user-attachments/assets/b46c6f97-2dfa-4da2-9710-200ce3396600
  • Loading branch information
nicobytes authored Sep 30, 2024
1 parent 6cb8473 commit ec4a905
Show file tree
Hide file tree
Showing 5 changed files with 461 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import { Spectator, byTestId, createComponentFactory, mockProvider } from '@ngneat/spectator/jest';
import {
Spectator,
SpyObject,
byTestId,
createComponentFactory,
mockProvider
} from '@ngneat/spectator/jest';
import { of } from 'rxjs';

import { provideHttpClient } from '@angular/common/http';
import { ControlContainer } from '@angular/forms';

import { DotMessageService } from '@dotcms/data-access';
import { DotDropZoneComponent } from '@dotcms/ui';
import { DotDropZoneComponent, DropZoneErrorType, DropZoneFileEvent } from '@dotcms/ui';

import { DotFileFieldPreviewComponent } from './components/dot-file-field-preview/dot-file-field-preview.component';
import { DotFileFieldUiMessageComponent } from './components/dot-file-field-ui-message/dot-file-field-ui-message.component';
import { DotEditContentFileFieldComponent } from './dot-edit-content-file-field.component';
import { DotFileFieldUploadService } from './services/upload-file/upload-file.service';
import { FileFieldStore } from './store/file-field.store';
Expand All @@ -14,11 +23,15 @@ import {
BINARY_FIELD_MOCK,
createFormGroupDirectiveMock,
FILE_FIELD_MOCK,
IMAGE_FIELD_MOCK
IMAGE_FIELD_MOCK,
NEW_FILE_MOCK
} from '../../utils/mocks';

describe('DotEditContentFileFieldComponent', () => {
let spectator: Spectator<DotEditContentFileFieldComponent>;
let store: InstanceType<typeof FileFieldStore>;
let uploadService: SpyObject<DotFileFieldUploadService>;

const createComponent = createComponentFactory({
component: DotEditContentFileFieldComponent,
detectChanges: false,
Expand All @@ -30,23 +43,25 @@ describe('DotEditContentFileFieldComponent', () => {
});

describe('FileField', () => {
beforeEach(
() =>
(spectator = createComponent({
props: {
field: FILE_FIELD_MOCK
} as unknown
}))
);
beforeEach(() => {
spectator = createComponent({
props: {
field: FILE_FIELD_MOCK
} as unknown
});
store = spectator.inject(FileFieldStore, true);
uploadService = spectator.inject(DotFileFieldUploadService, true);
});

it('should be created', () => {
expect(spectator.component).toBeTruthy();
});

it('should have a DotDropZoneComponent', () => {
it('should have a DotDropZoneComponent and DotFileFieldUiMessageComponent', () => {
spectator.detectChanges();

expect(spectator.query(DotDropZoneComponent)).toBeTruthy();
expect(spectator.query(DotFileFieldUiMessageComponent)).toBeTruthy();
});

it('should show the proper actions', () => {
Expand All @@ -57,6 +72,149 @@ describe('DotEditContentFileFieldComponent', () => {
expect(spectator.query(byTestId('action-new-file'))).toBeTruthy();
expect(spectator.query(byTestId('action-generate-with-ai'))).toBeFalsy();
});

it('should call initLoad with proper params', () => {
const spyInitLoad = jest.spyOn(store, 'initLoad');

spectator.detectChanges();

expect(spyInitLoad).toHaveBeenCalledTimes(1);
expect(spyInitLoad).toHaveBeenCalledWith({
fieldVariable: FILE_FIELD_MOCK.variable,
inputType: FILE_FIELD_MOCK.fieldType
});
});

it('should call getAssetData when an value is set', () => {
const mockContentlet = NEW_FILE_MOCK.entity;
uploadService.getContentById.mockReturnValue(of(mockContentlet));

const spyGetAssetData = jest.spyOn(store, 'getAssetData');

spectator.component.writeValue(mockContentlet.identifier);

expect(spyGetAssetData).toHaveBeenCalledTimes(1);
expect(spyGetAssetData).toHaveBeenCalledWith(mockContentlet.identifier);
});

it('should does not call getAssetData when an null value', () => {
const mockContentlet = NEW_FILE_MOCK.entity;
uploadService.getContentById.mockReturnValue(of(mockContentlet));

const spyGetAssetData = jest.spyOn(store, 'getAssetData');

spectator.component.writeValue(null);

expect(spyGetAssetData).not.toHaveBeenCalled();
});

it('should have a preview with a proper content', () => {
const mockContentlet = NEW_FILE_MOCK.entity;
uploadService.getContentById.mockReturnValue(of(mockContentlet));

spectator.component.writeValue(mockContentlet.identifier);

spectator.detectChanges();

expect(spectator.query(DotFileFieldPreviewComponent)).toBeTruthy();
});

describe('fileDropped event', () => {
it('should call to handleUploadFile when and proper file', () => {
const mockContentlet = NEW_FILE_MOCK.entity;
uploadService.uploadDotAsset.mockReturnValue(of(mockContentlet));

const spyHandleUploadFile = jest.spyOn(store, 'handleUploadFile');

const mockEvent: DropZoneFileEvent = {
file: new File([''], 'filename', { type: 'text/html' }),
validity: {
fileTypeMismatch: false,
maxFileSizeExceeded: false,
multipleFilesDropped: false,
errorsType: [],
valid: true
}
};
spectator.detectChanges();

spectator.triggerEventHandler(DotDropZoneComponent, 'fileDropped', mockEvent);

expect(spyHandleUploadFile).toHaveBeenCalledTimes(1);
expect(spyHandleUploadFile).toHaveBeenCalledWith(mockEvent.file);
});

it('should not call to handleUploadFile when a null file', () => {
const mockContentlet = NEW_FILE_MOCK.entity;
uploadService.uploadDotAsset.mockReturnValue(of(mockContentlet));

const spyHandleUploadFile = jest.spyOn(store, 'handleUploadFile');

const mockEvent: DropZoneFileEvent = {
file: null,
validity: {
fileTypeMismatch: false,
maxFileSizeExceeded: false,
multipleFilesDropped: false,
errorsType: [],
valid: true
}
};
spectator.detectChanges();

spectator.triggerEventHandler(DotDropZoneComponent, 'fileDropped', mockEvent);

expect(spyHandleUploadFile).not.toHaveBeenCalled();
});

it('should set a proper error message with a invalid file', () => {
const mockContentlet = NEW_FILE_MOCK.entity;
uploadService.uploadDotAsset.mockReturnValue(of(mockContentlet));

const spySetUIMessage = jest.spyOn(store, 'setUIMessage');

const mockEvent: DropZoneFileEvent = {
file: new File([''], 'filename', { type: 'text/html' }),
validity: {
fileTypeMismatch: true,
maxFileSizeExceeded: false,
multipleFilesDropped: false,
errorsType: [DropZoneErrorType.MAX_FILE_SIZE_EXCEEDED],
valid: false
}
};
spectator.detectChanges();

spectator.triggerEventHandler(DotDropZoneComponent, 'fileDropped', mockEvent);

expect(spySetUIMessage).toHaveBeenCalled();
});
});

describe('fileSelected event', () => {
it('should call to fileSelected with proper file', () => {
const mockContentlet = NEW_FILE_MOCK.entity;
uploadService.uploadDotAsset.mockReturnValue(of(mockContentlet));

const spyHandleUploadFile = jest.spyOn(store, 'handleUploadFile');

const file = new File([''], 'filename', { type: 'text/html' });
spectator.component.fileSelected([file] as unknown as FileList);

expect(spyHandleUploadFile).toHaveBeenCalledTimes(1);
expect(spyHandleUploadFile).toHaveBeenCalledWith(file);
});

it('should not call to fileSelected when a null file', () => {
const mockContentlet = NEW_FILE_MOCK.entity;
uploadService.uploadDotAsset.mockReturnValue(of(mockContentlet));

const spyHandleUploadFile = jest.spyOn(store, 'handleUploadFile');
spectator.component.fileSelected([] as unknown as FileList);

expect(spyHandleUploadFile).not.toHaveBeenCalled();
});
});
});

describe('ImageField', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export class DotEditContentFileFieldComponent implements ControlValueAccessor, O

constructor() {
effect(() => {
if (!this.onChange && !this.onTouched) {
return;
}

const value = this.store.value();
this.onChange(value);
this.onTouched();
Expand Down
Loading

0 comments on commit ec4a905

Please sign in to comment.