sector => clean archi et test vert
This commit is contained in:
@@ -15,6 +15,8 @@ import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-r
|
||||
import { PbProfileRepository } from '@app/infrastructure/profiles/pb-profile.repository';
|
||||
import { PROJECT_REPOSITORY_TOKEN } from '@app/infrastructure/projects/project-repository.token';
|
||||
import { PbProjectRepository } from '@app/infrastructure/projects/pb-project.repository';
|
||||
import { SECTOR_REPOSITORY_TOKEN } from '@app/infrastructure/sectors/sector-repository.token';
|
||||
import { PbSectorRepository } from '@app/infrastructure/sectors/pb-sector.repository';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
@@ -31,6 +33,7 @@ export const appConfig: ApplicationConfig = {
|
||||
provideHttpClient(withFetch()),
|
||||
{ provide: PROFILE_REPOSITORY_TOKEN, useExisting: PbProfileRepository },
|
||||
{ provide: PROJECT_REPOSITORY_TOKEN, useExisting: PbProjectRepository },
|
||||
{ provide: SECTOR_REPOSITORY_TOKEN, useExisting: PbSectorRepository },
|
||||
provideToastr({
|
||||
timeOut: 10000,
|
||||
positionClass: 'toast-top-right',
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SectorService } from './sector.service';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
describe('SectorService', () => {
|
||||
let service: SectorService;
|
||||
|
||||
const routerSpy = {
|
||||
navigate: jest.fn(),
|
||||
navigateByUrl: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
{ provide: Router, useValue: routerSpy }, // <<— spy: neutralise la navigation
|
||||
],
|
||||
imports: [],
|
||||
});
|
||||
service = TestBed.inject(SectorService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,24 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import PocketBase from 'pocketbase';
|
||||
import { environment } from '@env/environment.development';
|
||||
import { from } from 'rxjs';
|
||||
import { Sector } from '@app/shared/models/sector';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class SectorService {
|
||||
get sectors() {
|
||||
const pb = new PocketBase(environment.baseUrl);
|
||||
return from(
|
||||
pb.collection<Sector>('secteur').getFullList({
|
||||
sort: 'nom',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getSectorById(id: string) {
|
||||
const pb = new PocketBase(environment.baseUrl);
|
||||
return from(pb.collection<Sector>('secteur').getOne<Sector>(id));
|
||||
}
|
||||
}
|
||||
6
src/app/domain/sectors/dto/create-sector.dto.ts
Normal file
6
src/app/domain/sectors/dto/create-sector.dto.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export interface CreateSectorDto {
|
||||
id: string;
|
||||
created: string;
|
||||
updated: string;
|
||||
nom: string;
|
||||
}
|
||||
7
src/app/domain/sectors/sector.repository.ts
Normal file
7
src/app/domain/sectors/sector.repository.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { Sector } from '@app/domain/sectors/sector.model';
|
||||
|
||||
export interface SectorRepository {
|
||||
list(): Observable<Sector[]>;
|
||||
getOne(sectorId: string): Observable<Sector>;
|
||||
}
|
||||
25
src/app/infrastructure/sectors/pb-sector.repository.ts
Normal file
25
src/app/infrastructure/sectors/pb-sector.repository.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { SectorRepository } from '@app/domain/sectors/sector.repository';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import { environment } from '@env/environment';
|
||||
import { Sector } from '@app/domain/sectors/sector.model';
|
||||
import PocketBase from 'pocketbase';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class PbSectorRepository implements SectorRepository {
|
||||
private pb = new PocketBase(environment.baseUrl);
|
||||
|
||||
getOne(sectorId: string): Observable<Sector> {
|
||||
return from(this.pb.collection<Sector>('secteur').getOne<Sector>(sectorId));
|
||||
}
|
||||
|
||||
list(): Observable<Sector[]> {
|
||||
return from(
|
||||
this.pb.collection<Sector>('secteur').getFullList({
|
||||
sort: 'nom',
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { InjectionToken } from '@angular/core';
|
||||
import { SectorRepository } from '@app/domain/sectors/sector.repository';
|
||||
|
||||
export const SECTOR_REPOSITORY_TOKEN = new InjectionToken<SectorRepository>('SectorRepository');
|
||||
@@ -2,17 +2,19 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ProfileDetailComponent } from './profile-detail.component';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { AuthService } from '@app/core/services/authentication/auth.service';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { PROJECT_REPOSITORY_TOKEN } from '@app/infrastructure/projects/project-repository.token';
|
||||
import { ProjectRepository } from '@app/domain/projects/project.repository';
|
||||
import { of } from 'rxjs';
|
||||
import { Project } from '@app/domain/projects/project.model';
|
||||
import { Sector } from '@app/domain/sectors/sector.model';
|
||||
import { SectorRepository } from '@app/domain/sectors/sector.repository';
|
||||
import { SECTOR_REPOSITORY_TOKEN } from '@app/infrastructure/sectors/sector-repository.token';
|
||||
|
||||
describe('ProfileDetailComponent', () => {
|
||||
let component: ProfileDetailComponent;
|
||||
let fixture: ComponentFixture<ProfileDetailComponent>;
|
||||
let mockProjectRepository: jest.Mocked<ProjectRepository>;
|
||||
let mockSectorRepo: SectorRepository;
|
||||
|
||||
beforeEach(async () => {
|
||||
mockProjectRepository = {
|
||||
@@ -22,11 +24,17 @@ describe('ProfileDetailComponent', () => {
|
||||
update: jest.fn().mockReturnValue(of({} as Project)),
|
||||
};
|
||||
|
||||
mockSectorRepo = {
|
||||
list: jest.fn(),
|
||||
getOne: jest.fn().mockReturnValue(of({} as Sector)),
|
||||
};
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ProfileDetailComponent],
|
||||
providers: [
|
||||
provideRouter([]),
|
||||
{ provide: PROJECT_REPOSITORY_TOKEN, useValue: mockProjectRepository },
|
||||
{ provide: SECTOR_REPOSITORY_TOKEN, useValue: mockSectorRepo },
|
||||
],
|
||||
}).compileComponents();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@if (sector != undefined) {
|
||||
@if (sector() != undefined) {
|
||||
<div class="flex flex-wrap space-x-2 items-center space-y-1">
|
||||
@for (chip of sector.nom.split('-'); track chip) {
|
||||
@for (chip of sector().noms; track chip) {
|
||||
<small
|
||||
class="rounded-full bg-indigo-400 hover:bg-indigo-700 text-xs text-white py-1.5 px-3 font-semibold"
|
||||
>{{ chip | titlecase }}</small
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ChipsComponent } from './chips.component';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { SECTOR_REPOSITORY_TOKEN } from '@app/infrastructure/sectors/sector-repository.token';
|
||||
import { of } from 'rxjs';
|
||||
import { Sector } from '@app/domain/sectors/sector.model';
|
||||
import { SectorRepository } from '@app/domain/sectors/sector.repository';
|
||||
|
||||
describe('ChipsComponent', () => {
|
||||
let component: ChipsComponent;
|
||||
let fixture: ComponentFixture<ChipsComponent>;
|
||||
|
||||
let mockSectorRepo: SectorRepository;
|
||||
|
||||
beforeEach(async () => {
|
||||
mockSectorRepo = {
|
||||
list: jest.fn(),
|
||||
getOne: jest.fn().mockReturnValue(of({} as Sector)),
|
||||
};
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ChipsComponent],
|
||||
providers: [
|
||||
provideRouter([]),
|
||||
{ provide: SECTOR_REPOSITORY_TOKEN, useValue: mockSectorRepo },
|
||||
],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ChipsComponent);
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Component, inject, Input, OnInit } from '@angular/core';
|
||||
import { Sector } from '@app/shared/models/sector';
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { TitleCasePipe } from '@angular/common';
|
||||
import { SectorService } from '@app/core/services/sector/sector.service';
|
||||
import { UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { SectorFacade } from '@app/ui/sectors/sector.facade';
|
||||
|
||||
@Component({
|
||||
selector: 'app-chips',
|
||||
@@ -15,12 +14,12 @@ import { UntilDestroy } from '@ngneat/until-destroy';
|
||||
export class ChipsComponent implements OnInit {
|
||||
@Input({ required: true }) sectorId: string | null = null;
|
||||
|
||||
protected sectorService = inject(SectorService);
|
||||
|
||||
protected sector: Sector | undefined = undefined;
|
||||
private readonly sectorFacade = new SectorFacade();
|
||||
protected sector = this.sectorFacade.sector;
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.sectorId)
|
||||
this.sectorService.getSectorById(this.sectorId).subscribe((value) => (this.sector = value));
|
||||
if (this.sectorId) {
|
||||
this.sectorFacade.loadOne(this.sectorId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
@if (user != undefined) {
|
||||
<a
|
||||
[routerLink]="[user.username ? user.username : user.id]"
|
||||
[state]="{ user, profile }"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
<div
|
||||
class="items-center bg-gray-50 rounded-lg shadow sm:flex dark:bg-gray-800 dark:border-gray-700 cursor-pointer"
|
||||
>
|
||||
<div class="sm:w-max w-full flex items-center justify-center">
|
||||
@if (user.avatar) {
|
||||
<img
|
||||
class="max-w-xl rounded-lg max-h-64 object-cover sm:rounded-none sm:rounded-l-lg"
|
||||
src="{{ environment.baseUrl }}/api/files/users/{{ user.id }}/{{ user.avatar }}"
|
||||
alt="{{ user.username }}"
|
||||
loading="lazy"
|
||||
/>
|
||||
} @else {
|
||||
<img
|
||||
class="max-w-xl rounded-lg max-h-64 sm:rounded-none sm:rounded-l-lg"
|
||||
src="https://api.dicebear.com/9.x/adventurer/svg?seed={{ user.username }}"
|
||||
alt="{{ user.username }}"
|
||||
loading="lazy"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="p-5 flex flex-col items-center space-y-2">
|
||||
@if (profile.estVerifier) {
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="size-6 text-purple-800"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M8.603 3.799A4.49 4.49 0 0 1 12 2.25c1.357 0 2.573.6 3.397 1.549a4.49 4.49 0 0 1 3.498 1.307 4.491 4.491 0 0 1 1.307 3.497A4.49 4.49 0 0 1 21.75 12a4.49 4.49 0 0 1-1.549 3.397 4.491 4.491 0 0 1-1.307 3.497 4.491 4.491 0 0 1-3.497 1.307A4.49 4.49 0 0 1 12 21.75a4.49 4.49 0 0 1-3.397-1.549 4.49 4.49 0 0 1-3.498-1.306 4.491 4.491 0 0 1-1.307-3.498A4.49 4.49 0 0 1 2.25 12c0-1.357.6-2.573 1.549-3.397a4.49 4.49 0 0 1 1.307-3.497 4.49 4.49 0 0 1 3.497-1.307Zm7.007 6.387a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
}
|
||||
|
||||
@if (user.name) {
|
||||
<h3 class="text-xl font-bold tracking-tight text-gray-900 dark:text-white">
|
||||
{{ user.name }}
|
||||
</h3>
|
||||
} @else if (user.username) {
|
||||
<h3 class="text-xl font-bold tracking-tight text-gray-900 dark:text-white">
|
||||
{{ user.username }}
|
||||
</h3>
|
||||
} @else {
|
||||
<h3 class="text-xl font-bold tracking-tight text-gray-900 dark:text-white">
|
||||
Non mentionné
|
||||
</h3>
|
||||
}
|
||||
<span class="text-gray-500 dark:text-gray-400">{{ profile.profession }}</span>
|
||||
|
||||
<app-chips [sectorId]="profile.secteur" />
|
||||
|
||||
<app-reseaux [reseaux]="profile.reseaux" />
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HorizentalProfileItemComponent } from './horizental-profile-item.component';
|
||||
|
||||
describe('HorizentalProfileItemComponent', () => {
|
||||
let component: HorizentalProfileItemComponent;
|
||||
let fixture: ComponentFixture<HorizentalProfileItemComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [HorizentalProfileItemComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(HorizentalProfileItemComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,31 +0,0 @@
|
||||
import { Component, inject, Input, OnInit } from '@angular/core';
|
||||
import { Router, RouterLink } from '@angular/router';
|
||||
import { UserService } from '@app/core/services/user/user.service';
|
||||
import { User } from '@app/shared/models/user';
|
||||
import { ChipsComponent } from '@app/shared/components/chips/chips.component';
|
||||
import { ReseauxComponent } from '@app/shared/components/reseaux/reseaux.component';
|
||||
import { environment } from '@env/environment';
|
||||
import { ProfileViewModel } from '@app/ui/profiles/profile.presenter.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-horizental-profile-item',
|
||||
standalone: true,
|
||||
imports: [RouterLink, ChipsComponent, ReseauxComponent],
|
||||
templateUrl: './horizental-profile-item.component.html',
|
||||
styleUrl: './horizental-profile-item.component.scss',
|
||||
})
|
||||
export class HorizentalProfileItemComponent implements OnInit {
|
||||
@Input({ required: true }) profile: ProfileViewModel = {} as ProfileViewModel;
|
||||
protected router = inject(Router);
|
||||
protected userService = inject(UserService);
|
||||
|
||||
protected user: User | undefined = undefined;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.userService
|
||||
.getUserById(this.profile.utilisateur)
|
||||
.subscribe((value) => (this.user = value));
|
||||
}
|
||||
|
||||
protected readonly environment = environment;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<section class="bg-white dark:bg-gray-900">
|
||||
<div class="py-8 px-4 mx-auto max-w-screen-xl text-center lg:py-16 lg:px-6">
|
||||
<div class="grid gap-8 mb-6 lg:mb-16 md:grid-cols-2">
|
||||
@for (profile of profiles; track profile.id) {
|
||||
<app-horizental-profile-item [profile]="profile" />
|
||||
} @empty {
|
||||
<p>Aucun profile trouvée</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,22 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HorizentalProfileListComponent } from './horizental-profile-list.component';
|
||||
|
||||
describe('HorizentalProfileListComponent', () => {
|
||||
let component: HorizentalProfileListComponent;
|
||||
let fixture: ComponentFixture<HorizentalProfileListComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [HorizentalProfileListComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(HorizentalProfileListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,14 +0,0 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { HorizentalProfileItemComponent } from '@app/shared/components/horizental-profile-item/horizental-profile-item.component';
|
||||
import { ProfileViewModel } from '@app/ui/profiles/profile.presenter.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-horizental-profile-list',
|
||||
standalone: true,
|
||||
imports: [HorizentalProfileItemComponent],
|
||||
templateUrl: './horizental-profile-list.component.html',
|
||||
styleUrl: './horizental-profile-list.component.scss',
|
||||
})
|
||||
export class HorizentalProfileListComponent {
|
||||
@Input({ required: true }) profiles: ProfileViewModel[] = [];
|
||||
}
|
||||
@@ -8,6 +8,9 @@ import { PROFILE_REPOSITORY_TOKEN } from '@app/infrastructure/profiles/profile-r
|
||||
import { ProfileRepository } from '@app/domain/profiles/profile.repository';
|
||||
import { of } from 'rxjs';
|
||||
import { Profile } from '@app/domain/profiles/profile.model';
|
||||
import { SectorRepository } from '@app/domain/sectors/sector.repository';
|
||||
import { Sector } from '@app/domain/sectors/sector.model';
|
||||
import { SECTOR_REPOSITORY_TOKEN } from '@app/infrastructure/sectors/sector-repository.token';
|
||||
|
||||
describe('MyProfileUpdateFormComponent', () => {
|
||||
let component: MyProfileUpdateFormComponent;
|
||||
@@ -15,6 +18,7 @@ describe('MyProfileUpdateFormComponent', () => {
|
||||
|
||||
let mockToastrService: Partial<ToastrService>;
|
||||
let mockProfileRepo: ProfileRepository;
|
||||
let mockSectorRepo: SectorRepository;
|
||||
|
||||
const mockProfileData = {
|
||||
profession: '',
|
||||
@@ -38,6 +42,11 @@ describe('MyProfileUpdateFormComponent', () => {
|
||||
getByUserId: jest.fn().mockReturnValue(of({} as Profile)),
|
||||
};
|
||||
|
||||
mockSectorRepo = {
|
||||
list: jest.fn().mockReturnValue(of([])),
|
||||
getOne: jest.fn().mockReturnValue(of({} as Sector)),
|
||||
};
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [MyProfileUpdateFormComponent],
|
||||
providers: [
|
||||
@@ -45,6 +54,7 @@ describe('MyProfileUpdateFormComponent', () => {
|
||||
provideRouter([]),
|
||||
{ provide: ToastrService, useValue: mockToastrService },
|
||||
{ provide: PROFILE_REPOSITORY_TOKEN, useValue: mockProfileRepo },
|
||||
{ provide: SECTOR_REPOSITORY_TOKEN, useValue: mockSectorRepo },
|
||||
],
|
||||
}).compileComponents();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, effect, inject, Input, OnInit, signal } from '@angular/core';
|
||||
import { Component, effect, inject, Input, OnInit } from '@angular/core';
|
||||
import {
|
||||
FormBuilder,
|
||||
FormControl,
|
||||
@@ -8,8 +8,6 @@ import {
|
||||
} from '@angular/forms';
|
||||
import { UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { NgClass } from '@angular/common';
|
||||
import { SectorService } from '@app/core/services/sector/sector.service';
|
||||
import { Sector } from '@app/shared/models/sector';
|
||||
import { AuthService } from '@app/core/services/authentication/auth.service';
|
||||
import { MyProfileUpdateCvFormComponent } from '@app/shared/components/my-profile-update-cv-form/my-profile-update-cv-form.component';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
@@ -17,6 +15,7 @@ import { ProfileViewModel } from '@app/ui/profiles/profile.presenter.model';
|
||||
import { ProfileFacade } from '@app/ui/profiles/profile.facade';
|
||||
import { ActionType } from '@app/domain/action-type.util';
|
||||
import { Profile } from '@app/domain/profiles/profile.model';
|
||||
import { SectorFacade } from '@app/ui/sectors/sector.facade';
|
||||
|
||||
@Component({
|
||||
selector: 'app-my-profile-update-form',
|
||||
@@ -31,15 +30,19 @@ export class MyProfileUpdateFormComponent implements OnInit {
|
||||
|
||||
@Input({ required: true }) profile: ProfileViewModel = {} as ProfileViewModel;
|
||||
private readonly formBuilder = inject(FormBuilder);
|
||||
protected readonly sectorService = inject(SectorService);
|
||||
protected readonly authService = inject(AuthService);
|
||||
profileForm!: FormGroup;
|
||||
protected sectors = signal<Sector[]>([]);
|
||||
|
||||
private readonly profileFacade = new ProfileFacade();
|
||||
protected readonly loading = this.profileFacade.loading;
|
||||
protected readonly error = this.profileFacade.error;
|
||||
|
||||
private readonly sectorFacade = new SectorFacade();
|
||||
protected sectors = this.sectorFacade.sectors;
|
||||
protected sector = this.sectorFacade.sector;
|
||||
protected readonly sectorLoading = this.sectorFacade.loading;
|
||||
protected readonly sectorError = this.sectorFacade.error;
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
switch (this.loading().action) {
|
||||
@@ -58,6 +61,12 @@ export class MyProfileUpdateFormComponent implements OnInit {
|
||||
);
|
||||
}
|
||||
}
|
||||
switch (this.sectorLoading().action) {
|
||||
case ActionType.READ:
|
||||
if (!this.sectorLoading() && !this.sectorError().hasError) {
|
||||
this.profileForm.get('secteur')!.setValue(this.sector().id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -95,12 +104,10 @@ export class MyProfileUpdateFormComponent implements OnInit {
|
||||
});
|
||||
|
||||
if (this.profile.secteur) {
|
||||
this.sectorService
|
||||
.getSectorById(this.profile.secteur)
|
||||
.subscribe((value) => this.profileForm.get('secteur')!.setValue(value.id));
|
||||
this.sectorFacade.loadOne(this.profile.secteur);
|
||||
}
|
||||
|
||||
this.sectorService.sectors.subscribe((value) => this.sectors.set(value));
|
||||
this.sectorFacade.load();
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { VerticalProfileListComponent } from './vertical-profile-list.component';
|
||||
import { Router } from '@angular/router';
|
||||
import { provideRouter } from '@angular/router';
|
||||
|
||||
describe('VerticalProfileListComponent', () => {
|
||||
let component: VerticalProfileListComponent;
|
||||
let fixture: ComponentFixture<VerticalProfileListComponent>;
|
||||
|
||||
const routerSpy = {
|
||||
navigate: jest.fn(),
|
||||
navigateByUrl: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [VerticalProfileListComponent],
|
||||
providers: [{ provide: Router, useValue: routerSpy }],
|
||||
providers: [provideRouter([])],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(VerticalProfileListComponent);
|
||||
|
||||
15
src/app/testing/domain/sectors/fake-sector.repository.ts
Normal file
15
src/app/testing/domain/sectors/fake-sector.repository.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { SectorRepository } from '@app/domain/sectors/sector.repository';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { Sector } from '@app/domain/sectors/sector.model';
|
||||
import { fakeSectors } from '@app/testing/sector.mock';
|
||||
|
||||
export class FakeSectorRepository implements SectorRepository {
|
||||
getOne(sectorId: string): Observable<Sector> {
|
||||
const sector = fakeSectors.find((s) => s.id === sectorId) ?? ({} as Sector);
|
||||
return of(sector);
|
||||
}
|
||||
|
||||
list(): Observable<Sector[]> {
|
||||
return of(fakeSectors);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { PbProfileRepository } from '@app/infrastructure/profiles/pb-profile.rep
|
||||
import { Profile } from '@app/domain/profiles/profile.model';
|
||||
import { ProfileDTO } from '@app/domain/profiles/dto/create-profile.dto';
|
||||
import PocketBase from 'pocketbase';
|
||||
import { mockProfiles } from '@app/testing/profile.mock';
|
||||
|
||||
jest.mock('pocketbase'); // on mock le module PocketBase
|
||||
|
||||
@@ -36,29 +37,12 @@ describe('PbProfileRepository', () => {
|
||||
// 🔹 TEST : list()
|
||||
// ------------------------------------------
|
||||
it('devrait appeler pb.collection("profiles").getFullList() avec un tri par profession', (done) => {
|
||||
const fakeProfiles: Profile[] = [
|
||||
{
|
||||
id: '1',
|
||||
created: '',
|
||||
updated: '',
|
||||
profession: 'Développeur',
|
||||
utilisateur: 'u001',
|
||||
estVerifier: false,
|
||||
secteur: 'Informatique',
|
||||
reseaux: {} as JSON,
|
||||
bio: 'Bio test',
|
||||
cv: '',
|
||||
projets: [],
|
||||
apropos: 'À propos...',
|
||||
},
|
||||
];
|
||||
|
||||
mockCollection.getFullList.mockResolvedValue(fakeProfiles);
|
||||
mockCollection.getFullList.mockResolvedValue(mockProfiles);
|
||||
|
||||
repo.list().subscribe((result) => {
|
||||
expect(mockPocketBase.collection).toHaveBeenCalledWith('profiles');
|
||||
expect(mockCollection.getFullList).toHaveBeenCalledWith({ sort: 'profession' });
|
||||
expect(result).toEqual(fakeProfiles);
|
||||
expect(result).toEqual(mockProfiles);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -66,29 +50,14 @@ describe('PbProfileRepository', () => {
|
||||
// ------------------------------------------
|
||||
// 🔹 TEST : getByUserId()
|
||||
// ------------------------------------------
|
||||
it('devrait appeler pb.collection("profiles").getFirstListItem() avec le bon filtre utilisateur', (done) => {
|
||||
const userId = 'user_001';
|
||||
const fakeProfile: Profile = {
|
||||
id: 'p001',
|
||||
created: '',
|
||||
updated: '',
|
||||
profession: 'Designer',
|
||||
utilisateur: userId,
|
||||
estVerifier: true,
|
||||
secteur: 'Création',
|
||||
reseaux: {} as JSON,
|
||||
bio: 'Bio',
|
||||
cv: '',
|
||||
projets: [],
|
||||
apropos: 'À propos...',
|
||||
};
|
||||
it('devrait appeler pb.collection("profiles").getFirstListItem() avec le bon filtre utilisateur', () => {
|
||||
const userId = '1';
|
||||
|
||||
mockCollection.getFirstListItem.mockResolvedValue(fakeProfile);
|
||||
mockCollection.getFirstListItem.mockResolvedValue(mockProfiles);
|
||||
|
||||
repo.getByUserId(userId).subscribe((result) => {
|
||||
expect(mockCollection.getFirstListItem).toHaveBeenCalledWith(`utilisateur="${userId}"`);
|
||||
expect(result).toEqual(fakeProfile);
|
||||
done();
|
||||
expect(result).toEqual(mockProfiles[0]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -128,7 +97,7 @@ describe('PbProfileRepository', () => {
|
||||
// 🔹 TEST : update()
|
||||
// ------------------------------------------
|
||||
it('devrait appeler pb.collection("profiles").update() avec ID et données partielle', (done) => {
|
||||
const id = 'p002';
|
||||
const id = '1';
|
||||
const data = { bio: 'Bio mise à jour' };
|
||||
const updatedProfile: Profile = {
|
||||
id,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { PbProjectRepository } from '@app/infrastructure/projects/pb-project.rep
|
||||
import { CreateProjectDto } from '@app/domain/projects/dto/create-project.dto';
|
||||
import { Project } from '@app/domain/projects/project.model';
|
||||
import PocketBase from 'pocketbase';
|
||||
import { fakeProjects } from '@app/testing/project.mock';
|
||||
|
||||
jest.mock('pocketbase'); // on mock le module entier
|
||||
|
||||
@@ -63,19 +64,7 @@ describe('PbProjectRepository', () => {
|
||||
// 🔹 TEST : list()
|
||||
// ------------------------------------------
|
||||
it('devrait appeler pb.collection("projets").getFullList() avec le filtre utilisateur', (done) => {
|
||||
const userId = 'user_001';
|
||||
const fakeProjects: Project[] = [
|
||||
{
|
||||
id: '1',
|
||||
created: '',
|
||||
updated: '',
|
||||
nom: 'P1',
|
||||
lien: '',
|
||||
description: '',
|
||||
fichier: [],
|
||||
utilisateur: userId,
|
||||
},
|
||||
];
|
||||
const userId = '1';
|
||||
|
||||
mockCollection.getFullList.mockResolvedValue(fakeProjects);
|
||||
|
||||
@@ -92,7 +81,7 @@ describe('PbProjectRepository', () => {
|
||||
// 🔹 TEST : get()
|
||||
// ------------------------------------------
|
||||
it('devrait appeler pb.collection("projets").getOne() avec le bon ID', (done) => {
|
||||
const id = 'p123';
|
||||
const id = '1';
|
||||
const fakeProject: Project = {
|
||||
id,
|
||||
created: '',
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import { FakeSectorRepository } from '@app/testing/domain/sectors/fake-sector.repository';
|
||||
import { PbSectorRepository } from '@app/infrastructure/sectors/pb-sector.repository';
|
||||
import { fakeSectors } from '@app/testing/sector.mock';
|
||||
import PocketBase from 'pocketbase';
|
||||
|
||||
jest.mock('pocketbase'); // on mock le module entier
|
||||
|
||||
describe('SectorRepository', () => {
|
||||
let sectorRepo: FakeSectorRepository;
|
||||
let mockCollection: any;
|
||||
let mockPocketBase: any;
|
||||
|
||||
beforeEach(() => {
|
||||
// Création d’un faux client PocketBase avec des méthodes mockées
|
||||
mockPocketBase = {
|
||||
collection: jest.fn().mockReturnValue({
|
||||
getFullList: jest.fn(),
|
||||
getOne: jest.fn(),
|
||||
}),
|
||||
};
|
||||
|
||||
// 👇 On remplace la classe importée par notre version mockée
|
||||
(PocketBase as jest.Mock).mockImplementation(() => mockPocketBase);
|
||||
|
||||
// on récupère une "collection" simulée
|
||||
mockCollection = mockPocketBase.collection('sectors');
|
||||
|
||||
// on instancie le repository à tester
|
||||
sectorRepo = new PbSectorRepository();
|
||||
});
|
||||
|
||||
// ------------------------------------------
|
||||
// 🔹 TEST : list()
|
||||
// ------------------------------------------
|
||||
it('devrait appeler pb.collection("sectors").getFullList() ', () => {
|
||||
mockCollection.getFullList.mockResolvedValue(fakeSectors);
|
||||
|
||||
sectorRepo.list().subscribe((result) => {
|
||||
expect(mockPocketBase.collection).toHaveBeenCalledWith('sectors');
|
||||
expect(result).toEqual(fakeSectors);
|
||||
});
|
||||
});
|
||||
|
||||
// ------------------------------------------
|
||||
// 🔹 TEST : getOne()
|
||||
// ------------------------------------------
|
||||
it('devrait appeler pb.collection("sectors").getFirstListItem() ', () => {
|
||||
const sectorId = 'sector_001';
|
||||
|
||||
mockCollection.getOne.mockResolvedValue(fakeSectors.find((s) => s.id === sectorId));
|
||||
|
||||
sectorRepo.getOne(sectorId).subscribe((result) => {
|
||||
expect(mockCollection.getFirstListItem).toHaveBeenCalledWith(`sectors="${sectorId}"`);
|
||||
expect(result).toEqual(fakeSectors[0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
34
src/app/testing/sector.mock.ts
Normal file
34
src/app/testing/sector.mock.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Sector } from '@app/domain/sectors/sector.model';
|
||||
|
||||
export const fakeSectors: Sector[] = [
|
||||
{
|
||||
id: 'sector_001',
|
||||
created: '2025-01-01T10:00:00Z',
|
||||
updated: '2025-01-05T14:00:00Z',
|
||||
nom: 'Informatique',
|
||||
},
|
||||
{
|
||||
id: 'sector_002',
|
||||
created: '2025-01-02T11:00:00Z',
|
||||
updated: '2025-01-06T15:00:00Z',
|
||||
nom: 'Design graphique',
|
||||
},
|
||||
{
|
||||
id: 'sector_003',
|
||||
created: '2025-01-03T12:00:00Z',
|
||||
updated: '2025-01-07T16:00:00Z',
|
||||
nom: 'Marketing digital',
|
||||
},
|
||||
{
|
||||
id: 'sector_004',
|
||||
created: '2025-01-04T13:00:00Z',
|
||||
updated: '2025-01-08T17:00:00Z',
|
||||
nom: 'Finance et comptabilité',
|
||||
},
|
||||
{
|
||||
id: 'sector_005',
|
||||
created: '2025-01-05T14:00:00Z',
|
||||
updated: '2025-01-09T18:00:00Z',
|
||||
nom: 'Ressources humaines',
|
||||
},
|
||||
];
|
||||
46
src/app/testing/ui/sectors/sector.facade.spec.ts
Normal file
46
src/app/testing/ui/sectors/sector.facade.spec.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { SectorFacade } from '@app/ui/sectors/sector.facade';
|
||||
import { SECTOR_REPOSITORY_TOKEN } from '@app/infrastructure/sectors/sector-repository.token';
|
||||
import { FakeSectorRepository } from '@app/testing/domain/sectors/fake-sector.repository';
|
||||
import { fakeSectors } from '@app/testing/sector.mock';
|
||||
|
||||
describe('SectorFacade', () => {
|
||||
let sectorFacade: SectorFacade;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
SectorFacade,
|
||||
{ provide: SECTOR_REPOSITORY_TOKEN, useClass: FakeSectorRepository },
|
||||
],
|
||||
});
|
||||
|
||||
sectorFacade = TestBed.inject(SectorFacade);
|
||||
});
|
||||
|
||||
// ------------------------------------------
|
||||
// 🔹 TEST : Chargement des secteurs (load)
|
||||
// ------------------------------------------
|
||||
it("devrait charger les secteurs d'activité ", () => {
|
||||
sectorFacade.load();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(sectorFacade.sectors().length).toBe(fakeSectors.length);
|
||||
expect(sectorFacade.loading().isLoading).toBe(false);
|
||||
expect(sectorFacade.error().hasError).toBe(false);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
// ------------------------------------------
|
||||
// 🔹 TEST : Chargement d’un secteur unique
|
||||
// ------------------------------------------
|
||||
it('devrait charger un secteur par son ID', () => {
|
||||
const sectorId = '1';
|
||||
sectorFacade.loadOne(sectorId);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(sectorFacade.sector()).toBe(fakeSectors.find((s) => s.id === sectorId));
|
||||
expect(sectorFacade.error().hasError).toBe(false);
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
30
src/app/testing/ui/sectors/sector.presenter.spec.ts
Normal file
30
src/app/testing/ui/sectors/sector.presenter.spec.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { SectorPresenter } from '@app/ui/sectors/sector.presenter';
|
||||
import { Sector } from '@app/domain/sectors/sector.model';
|
||||
import { fakeSectors } from '@app/testing/sector.mock';
|
||||
|
||||
describe('SectorPresenter', () => {
|
||||
let presenter: SectorPresenter;
|
||||
|
||||
beforeEach(() => {
|
||||
presenter = new SectorPresenter();
|
||||
});
|
||||
|
||||
it('devrait transformer un Sector en SectorPresenterModel', () => {
|
||||
const sector: Sector = fakeSectors[0];
|
||||
|
||||
const viewModel = presenter.toViewModel(sector);
|
||||
|
||||
expect(viewModel).toEqual({
|
||||
id: sector.id,
|
||||
nom: sector.nom,
|
||||
noms: ['Informatique'],
|
||||
});
|
||||
});
|
||||
|
||||
it('devrait transformer un tableau complet', () => {
|
||||
const result = presenter.toViewModels(fakeSectors);
|
||||
|
||||
expect(result.length).toBe(5);
|
||||
expect(result[0].nom).toBe(fakeSectors[0].nom);
|
||||
});
|
||||
});
|
||||
20
src/app/testing/usecase/sectors/get-sector.usecase.spec.ts
Normal file
20
src/app/testing/usecase/sectors/get-sector.usecase.spec.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { FakeSectorRepository } from '@app/testing/domain/sectors/fake-sector.repository';
|
||||
import { fakeSectors } from '@app/testing/sector.mock';
|
||||
import { GetSectorUseCase } from '@app/usecase/sectors/get-sector.usecase';
|
||||
|
||||
describe('ListSectorUsecase', () => {
|
||||
let useCase: GetSectorUseCase;
|
||||
let repo: FakeSectorRepository;
|
||||
|
||||
beforeEach(() => {
|
||||
repo = new FakeSectorRepository();
|
||||
useCase = new GetSectorUseCase(repo);
|
||||
});
|
||||
|
||||
it('doit retourne la liste des secteurs ', () => {
|
||||
const sectorId = '1';
|
||||
useCase.execute(sectorId).subscribe((sector) => {
|
||||
expect(sector).toBe(fakeSectors.find((s) => s.id === sectorId));
|
||||
});
|
||||
});
|
||||
});
|
||||
19
src/app/testing/usecase/sectors/list-sector.usecase.spec.ts
Normal file
19
src/app/testing/usecase/sectors/list-sector.usecase.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { ListSectorUsecase } from '@app/usecase/sectors/list-sector.usecase';
|
||||
import { FakeSectorRepository } from '@app/testing/domain/sectors/fake-sector.repository';
|
||||
import { fakeSectors } from '@app/testing/sector.mock';
|
||||
|
||||
describe('ListSectorUsecase', () => {
|
||||
let useCase: ListSectorUsecase;
|
||||
let repo: FakeSectorRepository;
|
||||
|
||||
beforeEach(() => {
|
||||
repo = new FakeSectorRepository();
|
||||
useCase = new ListSectorUsecase(repo);
|
||||
});
|
||||
|
||||
it('doit retourne la liste des secteurs ', () => {
|
||||
useCase.execute().subscribe((sectors) => {
|
||||
expect(sectors.length).toBe(fakeSectors.length);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -35,10 +35,7 @@ export class ProjectFacade {
|
||||
private readonly projectPresenter = new ProjectPresenter();
|
||||
|
||||
load(userId: string) {
|
||||
this.loading.set({
|
||||
action: ActionType.READ,
|
||||
isLoading: true,
|
||||
});
|
||||
this.handleError(ActionType.READ, false, null, true);
|
||||
|
||||
this.listUseCase.execute(userId).subscribe({
|
||||
next: (projects: Project[]) => {
|
||||
@@ -53,10 +50,7 @@ export class ProjectFacade {
|
||||
}
|
||||
|
||||
loadOne(projectId: string) {
|
||||
this.loading.set({
|
||||
action: ActionType.READ,
|
||||
isLoading: true,
|
||||
});
|
||||
this.handleError(ActionType.READ, false, null, true);
|
||||
|
||||
this.getUseCase.execute(projectId).subscribe({
|
||||
next: (project: Project) => {
|
||||
@@ -70,10 +64,7 @@ export class ProjectFacade {
|
||||
}
|
||||
|
||||
create(projectDto: CreateProjectDto) {
|
||||
this.loading.set({
|
||||
action: ActionType.CREATE,
|
||||
isLoading: true,
|
||||
});
|
||||
this.handleError(ActionType.CREATE, false, null, true);
|
||||
|
||||
this.createUseCase.execute(projectDto).subscribe({
|
||||
next: (project: Project) => {
|
||||
@@ -88,10 +79,7 @@ export class ProjectFacade {
|
||||
}
|
||||
|
||||
update(userId: string, data: any) {
|
||||
this.loading.set({
|
||||
action: ActionType.UPDATE,
|
||||
isLoading: true,
|
||||
});
|
||||
this.handleError(ActionType.UPDATE, false, null, true);
|
||||
|
||||
this.UpdateUseCase.execute(userId, data).subscribe({
|
||||
next: (project: Project) => {
|
||||
|
||||
65
src/app/ui/sectors/sector.facade.ts
Normal file
65
src/app/ui/sectors/sector.facade.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { inject, signal } from '@angular/core';
|
||||
import { SECTOR_REPOSITORY_TOKEN } from '@app/infrastructure/sectors/sector-repository.token';
|
||||
import { ListSectorUsecase } from '@app/usecase/sectors/list-sector.usecase';
|
||||
import { GetSectorUseCase } from '@app/usecase/sectors/get-sector.usecase';
|
||||
import { ActionType } from '@app/domain/action-type.util';
|
||||
import { LoaderAction } from '@app/domain/loader-action.util';
|
||||
import { ErrorResponse } from '@app/domain/error-response.util';
|
||||
import { SectorPresenterModel } from '@app/ui/sectors/sector.presenter.model';
|
||||
import { Sector } from '@app/domain/sectors/sector.model';
|
||||
import { SectorPresenter } from '@app/ui/sectors/sector.presenter';
|
||||
|
||||
export class SectorFacade {
|
||||
private readonly sectorRepo = inject(SECTOR_REPOSITORY_TOKEN);
|
||||
|
||||
private readonly listSectorUseCase = new ListSectorUsecase(this.sectorRepo);
|
||||
private readonly getSectorUseCase = new GetSectorUseCase(this.sectorRepo);
|
||||
|
||||
readonly sectors = signal<SectorPresenterModel[]>([]);
|
||||
readonly sector = signal<SectorPresenterModel>({} as SectorPresenterModel);
|
||||
|
||||
readonly loading = signal<LoaderAction>({ isLoading: false, action: ActionType.NONE });
|
||||
readonly error = signal<ErrorResponse>({
|
||||
action: ActionType.NONE,
|
||||
hasError: false,
|
||||
message: null,
|
||||
});
|
||||
|
||||
private readonly sectorPresenter = new SectorPresenter();
|
||||
|
||||
load() {
|
||||
this.handleError(ActionType.READ, false, null, true);
|
||||
this.listSectorUseCase.execute().subscribe({
|
||||
next: (sectors: Sector[]) => {
|
||||
this.sectors.set(this.sectorPresenter.toViewModels(sectors));
|
||||
this.handleError(ActionType.READ, false, null, false);
|
||||
},
|
||||
error: (err) => {
|
||||
this.handleError(ActionType.READ, false, err, false);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
loadOne(sectorId: string) {
|
||||
this.handleError(ActionType.READ, false, null, true);
|
||||
this.getSectorUseCase.execute(sectorId).subscribe({
|
||||
next: (sector: Sector) => {
|
||||
this.sector.set(this.sectorPresenter.toViewModel(sector));
|
||||
this.handleError(ActionType.READ, false, null, false);
|
||||
},
|
||||
error: (err) => {
|
||||
this.handleError(ActionType.READ, false, err, false);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private handleError(
|
||||
action: ActionType = ActionType.NONE,
|
||||
hasError: boolean,
|
||||
message: string | null = null,
|
||||
isLoading = false
|
||||
) {
|
||||
this.error.set({ action, hasError, message });
|
||||
this.loading.set({ action, isLoading });
|
||||
}
|
||||
}
|
||||
5
src/app/ui/sectors/sector.presenter.model.ts
Normal file
5
src/app/ui/sectors/sector.presenter.model.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface SectorPresenterModel {
|
||||
id: string;
|
||||
nom: string;
|
||||
noms?: string[];
|
||||
}
|
||||
17
src/app/ui/sectors/sector.presenter.ts
Normal file
17
src/app/ui/sectors/sector.presenter.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { SectorPresenterModel } from '@app/ui/sectors/sector.presenter.model';
|
||||
import { Sector } from '@app/domain/sectors/sector.model';
|
||||
|
||||
export class SectorPresenter {
|
||||
toViewModel(sector: Sector): SectorPresenterModel {
|
||||
const names = sector.nom ? sector.nom.split('-') : [];
|
||||
return {
|
||||
id: sector.id,
|
||||
nom: sector.nom,
|
||||
noms: names,
|
||||
};
|
||||
}
|
||||
|
||||
toViewModels(sectors: Sector[]): SectorPresenterModel[] {
|
||||
return sectors.map(this.toViewModel);
|
||||
}
|
||||
}
|
||||
11
src/app/usecase/sectors/get-sector.usecase.ts
Normal file
11
src/app/usecase/sectors/get-sector.usecase.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { SectorRepository } from '@app/domain/sectors/sector.repository';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Sector } from '@app/domain/sectors/sector.model';
|
||||
|
||||
export class GetSectorUseCase {
|
||||
constructor(private readonly sectorRepository: SectorRepository) {}
|
||||
|
||||
execute(sectorId: string): Observable<Sector> {
|
||||
return this.sectorRepository.getOne(sectorId);
|
||||
}
|
||||
}
|
||||
11
src/app/usecase/sectors/list-sector.usecase.ts
Normal file
11
src/app/usecase/sectors/list-sector.usecase.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { SectorRepository } from '@app/domain/sectors/sector.repository';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Sector } from '@app/domain/sectors/sector.model';
|
||||
|
||||
export class ListSectorUsecase {
|
||||
constructor(private readonly sectorRepository: SectorRepository) {}
|
||||
|
||||
execute(): Observable<Sector[]> {
|
||||
return this.sectorRepository.list();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user