From f74d15713c2db3640b38acd18aef7d74f38d9670 Mon Sep 17 00:00:00 2001 From: Gabriel De Los Rios Date: Sun, 14 Dec 2025 20:40:50 -0300 Subject: [PATCH] feat: add contact service --- src/app/pages/main/contact.service.spec.ts | 75 ++++++++++++++++++++++ src/app/pages/main/contact.service.ts | 35 ++++++++++ 2 files changed, 110 insertions(+) create mode 100644 src/app/pages/main/contact.service.spec.ts create mode 100644 src/app/pages/main/contact.service.ts diff --git a/src/app/pages/main/contact.service.spec.ts b/src/app/pages/main/contact.service.spec.ts new file mode 100644 index 0000000..5c98655 --- /dev/null +++ b/src/app/pages/main/contact.service.spec.ts @@ -0,0 +1,75 @@ +import { TestBed } from '@angular/core/testing'; +import { Response } from '../../models/Response'; +import { ContactService } from './contact.service'; +import { provideHttpClient } from '@angular/common/http'; +import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; +import { environment } from '../../../environments/environment'; +import { ContactDTO } from '../../models/ContactDTO'; + +describe('ContactService', () => { + let service: ContactService; + let httpTestingController: HttpTestingController; + + let RES_MOCK: Response; + + let endpointURL = environment.apiUrl + '/contacts'; + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [], + providers: [provideHttpClient(), provideHttpClientTesting()], + }); + service = TestBed.inject(ContactService); + httpTestingController = TestBed.inject(HttpTestingController); + + RES_MOCK = { + data: null, + errors: [], + message: '', + success: true, + }; + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should GET contacts from the contacts ep', () => { + const CONTACTS_MOCK = [new ContactDTO(1, 'mock1'), new ContactDTO(2, 'mock2')]; + service.getAll().subscribe(); + const req = httpTestingController.expectOne(endpointURL); + expect(req.request.method).toEqual('GET'); + RES_MOCK.data = CONTACTS_MOCK; + req.flush(RES_MOCK); + httpTestingController.verify(); + }); + + it('should POST contact to the contacts ep', () => { + const CONTACT_MOCK = new ContactDTO(undefined, 'mock'); + service.save(CONTACT_MOCK).subscribe(); + const postReq = httpTestingController.expectOne(endpointURL); + expect(postReq.request.method).toEqual('POST'); + expect(postReq.request.body).toEqual(CONTACT_MOCK); + CONTACT_MOCK.id = 1; + RES_MOCK.data = CONTACT_MOCK + postReq.flush(RES_MOCK); + const getReq = httpTestingController.expectOne(endpointURL); + expect(getReq.request.method).toEqual('GET'); + RES_MOCK.data = [CONTACT_MOCK]; + getReq.flush(RES_MOCK); + httpTestingController.verify(); + }); + + it('should DELETE with the given ID to the contacts ep', () => { + const ID_MOCK = 1; + service.delete(ID_MOCK).subscribe(); + const deleteReq = httpTestingController.expectOne(`${endpointURL}/${ID_MOCK}`); + expect(deleteReq.request.method).toEqual('DELETE'); + RES_MOCK.message = "Contact deleted successfully"; + deleteReq.flush(RES_MOCK); + const getReq = httpTestingController.expectOne(endpointURL); + expect(getReq.request.method).toEqual('GET'); + RES_MOCK.data = []; + RES_MOCK.message = ''; + getReq.flush(RES_MOCK); + }); +}); diff --git a/src/app/pages/main/contact.service.ts b/src/app/pages/main/contact.service.ts new file mode 100644 index 0000000..e4ef8fc --- /dev/null +++ b/src/app/pages/main/contact.service.ts @@ -0,0 +1,35 @@ +import { HttpClient } from '@angular/common/http'; +import { inject, Injectable } from '@angular/core'; +import { environment } from '../../../environments/environment'; +import { ContactDTO } from '../../models/ContactDTO'; +import { Response } from '../../models/Response'; +import { BehaviorSubject, map, switchMap, tap } from 'rxjs'; + +@Injectable({ + providedIn: 'root', +}) +export class ContactService { + + private readonly httpClient = inject(HttpClient); + private readonly contacts = new BehaviorSubject([]); + readonly contacts$ = this.contacts.asObservable(); + + delete(id: number){ + return this.httpClient.delete>(`${environment.apiUrl}/contacts/${id}`) + .pipe(switchMap(() => this.getAll())) + } + + getAll() { + return this.httpClient.get>(environment.apiUrl+'/contacts') + .pipe( + map( response => response.data ?? []), + tap( contacts => this.contacts.next(contacts)) + ) + } + + save(contact: ContactDTO) { + return this.httpClient.post>(environment.apiUrl+'/contacts', contact) + .pipe(switchMap(() => this.getAll())) + } + +}