161 lines
5.9 KiB
TypeScript
161 lines
5.9 KiB
TypeScript
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
|
|
import { ProjectPictureFormComponent } from './project-picture-form.component';
|
|
import { mockProjects } from '@app/testing/project.mock';
|
|
import { mockFileManagerSvc } from '@app/testing/file-manager.service.mock';
|
|
import { mockProjectFac } from '@app/testing/adapters/projects/project.facade.mock';
|
|
import { ProjectViewModel } from '@app/adapters/projects/project.presenter.model';
|
|
import { ProjectFacade } from '@app/adapters/projects/project.facade';
|
|
import { FileManagerService } from '@app/adapters/shared/services/file-manager.service';
|
|
import { ActionType } from '@app/domain/action-type.util';
|
|
|
|
describe('ProjectPictureFormComponent', () => {
|
|
let component: ProjectPictureFormComponent;
|
|
let fixture: ComponentFixture<ProjectPictureFormComponent>;
|
|
|
|
// 1. Mocks des services
|
|
const mockFileManagerService = mockFileManagerSvc;
|
|
|
|
const mockProjectFacade = mockProjectFac;
|
|
|
|
// Données de test
|
|
const mockProject: ProjectViewModel = mockProjects[0];
|
|
|
|
beforeEach(async () => {
|
|
// Reset des mocks
|
|
mockFileManagerService.file.set(null);
|
|
mockFileManagerService.imagePreviewUrl.set(null);
|
|
mockFileManagerService.fileError.set(null);
|
|
mockFileManagerService.resetFile.mockClear();
|
|
|
|
mockProjectFacade.update.mockClear();
|
|
mockProjectFacade.loading.set({ isLoading: false, action: ActionType.NONE });
|
|
mockProjectFacade.error.set({ hasError: false, message: null });
|
|
|
|
await TestBed.configureTestingModule({
|
|
imports: [ProjectPictureFormComponent],
|
|
providers: [
|
|
{ provide: ProjectFacade, useValue: mockProjectFacade },
|
|
{ provide: FileManagerService, useValue: mockFileManagerService },
|
|
],
|
|
}).compileComponents();
|
|
|
|
fixture = TestBed.createComponent(ProjectPictureFormComponent);
|
|
component = fixture.componentInstance;
|
|
|
|
// Initialisation de l'input requis
|
|
fixture.componentRef.setInput('project', mockProject);
|
|
fixture.detectChanges();
|
|
});
|
|
|
|
it('devrait créer le composant', () => {
|
|
expect(component).toBeTruthy();
|
|
});
|
|
|
|
describe("Affichage de l'image (currentImageUrl)", () => {
|
|
it('devrait prioriser la prévisualisation locale (upload en cours)', () => {
|
|
mockFileManagerService.imagePreviewUrl.set('data:image/png;base64,preview');
|
|
fixture.detectChanges();
|
|
|
|
expect(component.currentImageUrl).toBe('data:image/png;base64,preview');
|
|
});
|
|
|
|
it("devrait afficher l'image du serveur si pas de preview", () => {
|
|
// mockProject a 'image-serveur.jpg'
|
|
expect(component.currentImageUrl).toContain('portfolio-preview.png');
|
|
});
|
|
|
|
/*it('devrait générer une image Dicebear avec le nom du projet si aucune image', () => {
|
|
const projectNoImg = { ...mockProject, fichier: undefined };
|
|
fixture.componentRef.setInput('project', projectNoImg);
|
|
fixture.detectChanges();
|
|
|
|
expect(component.currentImageUrl).toContain('api.dicebear.com');
|
|
expect(component.currentImageUrl).toContain('Web 3D');
|
|
});*/
|
|
|
|
/*it("devrait générer une image par défaut si le projet n'a ni image ni nom", () => {
|
|
const emptyProject = { ...mockProject, fichier: undefined, nom: undefined };
|
|
fixture.componentRef.setInput('project', emptyProject);
|
|
fixture.detectChanges();
|
|
|
|
expect(component.currentImageUrl).toContain(undefined);
|
|
});*/
|
|
});
|
|
|
|
describe('Validation (canSubmit)', () => {
|
|
it('devrait être true si un fichier est prêt et valide', () => {
|
|
mockFileManagerService.file.set(new File([''], 'img.jpg'));
|
|
mockFileManagerService.fileError.set(null);
|
|
mockProjectFacade.loading.set({ isLoading: false, action: ActionType.NONE });
|
|
|
|
expect(component.canSubmit).toBe(true);
|
|
});
|
|
|
|
it('devrait être false si une erreur de fichier existe', () => {
|
|
mockFileManagerService.file.set(new File([''], 'img.jpg'));
|
|
mockFileManagerService.fileError.set('Trop lourd');
|
|
|
|
expect(component.canSubmit).toBe(false);
|
|
});
|
|
|
|
it('devrait être false si pas de fichier ni de preview', () => {
|
|
mockFileManagerService.file.set(null);
|
|
mockFileManagerService.imagePreviewUrl.set(null);
|
|
|
|
expect(component.canSubmit).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('Soumission (onSubmit)', () => {
|
|
it('devrait envoyer un FormData à la façade', () => {
|
|
const file = new File(['blob'], 'test.png');
|
|
mockFileManagerService.file.set(file);
|
|
|
|
component.onSubmit();
|
|
|
|
expect(mockProjectFacade.update).toHaveBeenCalledTimes(1);
|
|
|
|
const args = mockProjectFacade.update.mock.calls[0];
|
|
expect(args[0]).toBe('1'); // ID projet
|
|
expect(args[1]).toBeInstanceOf(FormData);
|
|
expect(args[1].get('fichier')).toBe(file);
|
|
});
|
|
|
|
it('ne devrait rien faire si pas de fichier', () => {
|
|
mockFileManagerService.file.set(null);
|
|
component.onSubmit();
|
|
expect(mockProjectFacade.update).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('Effets (Réinitialisation après succès)', () => {
|
|
it("devrait émettre onFormSubmitted et reset le fichier quand l'update réussit", () => {
|
|
// 1. Espionner l'output
|
|
let emitted = false;
|
|
component.onFormSubmitted.subscribe(() => (emitted = true));
|
|
|
|
// 2. Déclencher la soumission
|
|
mockFileManagerService.file.set(new File([''], 'test.jpg'));
|
|
component.onSubmit(); // onSubmitted -> true
|
|
|
|
// 3. Simuler la fin du chargement succès
|
|
mockProjectFacade.loading.set({ isLoading: false, action: ActionType.UPDATE });
|
|
|
|
fixture.detectChanges(); // Déclenche l'effect
|
|
|
|
expect(emitted).toBe(true);
|
|
expect(mockFileManagerService.resetFile).toHaveBeenCalled();
|
|
});
|
|
|
|
it("ne devrait rien faire si l'action n'est pas UPDATE", () => {
|
|
component.onSubmit();
|
|
|
|
mockProjectFacade.loading.set({ isLoading: false, action: ActionType.CREATE });
|
|
fixture.detectChanges();
|
|
|
|
expect(mockFileManagerService.resetFile).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
});
|