diff --git a/src/app/app.spec.ts b/src/app/app.spec.ts index 47518b3..ce72eea 100644 --- a/src/app/app.spec.ts +++ b/src/app/app.spec.ts @@ -6,7 +6,6 @@ import { provideRouter } from '@angular/router'; import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest'; import { App } from './app'; -import { EventDateNoticeService } from './core/services/event-date-notice.service'; import { Tenant } from './core/services/tenant.interface'; import { TenantService } from './core/services/tenant.service'; @@ -117,48 +116,4 @@ describe('App', () => { ).toBe("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E"); }); - it('shows the date notices returned by the tenant bootstrap once', async () => { - const show = vi.fn(); - const dateNotices = [ - { - type: 'suspended' as const, - title: 'FECHA CANCELADA!', - message: [ - { text: 'La fecha del ', bold: false }, - { text: '09 de Octubre de 2026', bold: true }, - { text: ' ha sido cancelada.', bold: false }, - ], - }, - ]; - - await TestBed.configureTestingModule({ - imports: [App], - providers: [ - provideRouter([]), - { - provide: TenantService, - useValue: createTenantServiceStub('ready', { - ...tenant, - event: { - title: 'Festival', - location: 'Predio', - dates: [], - date_notices: dateNotices, - }, - }), - }, - { - provide: EventDateNoticeService, - useValue: { show }, - }, - ], - }).compileComponents(); - - const fixture = TestBed.createComponent(App); - fixture.detectChanges(); - fixture.detectChanges(); - - expect(show).toHaveBeenCalledOnce(); - expect(show).toHaveBeenCalledWith(dateNotices); - }); }); diff --git a/src/app/app.ts b/src/app/app.ts index b332a32..268c29d 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -1,9 +1,8 @@ -import { DOCUMENT, isPlatformBrowser } from '@angular/common'; -import { Component, PLATFORM_ID, computed, effect, inject } from '@angular/core'; +import { DOCUMENT } from '@angular/common'; +import { Component, computed, effect, inject } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { RouterOutlet } from '@angular/router'; -import { EventDateNoticeService } from './core/services/event-date-notice.service'; import { TenantService } from './core/services/tenant.service'; import { DEFAULT_TENANT_BRANDING } from './core/services/tenant-ssr-cache.store'; import { GlobalLoadingComponent } from './shared/components/global-loading/global-loading.component'; @@ -59,11 +58,8 @@ function hexToRgb(hex: string): string { }) export class App { private readonly tenantService = inject(TenantService); - private readonly eventDateNoticeService = inject(EventDateNoticeService); private readonly document = inject(DOCUMENT); private readonly title = inject(Title); - private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID)); - private notifiedTenantCode: string | null = null; constructor() { effect(() => { @@ -82,11 +78,6 @@ export class App { } favicon.setAttribute('href', faviconHref); - - if (this.isBrowser && tenant && this.notifiedTenantCode !== tenant.codigo) { - this.notifiedTenantCode = tenant.codigo; - this.eventDateNoticeService.show(tenant.event?.date_notices ?? []); - } }); } diff --git a/src/app/core/services/event-date-notice.service.spec.ts b/src/app/core/services/event-date-notice.service.spec.ts index 7e86d56..310ecfb 100644 --- a/src/app/core/services/event-date-notice.service.spec.ts +++ b/src/app/core/services/event-date-notice.service.spec.ts @@ -1,85 +1,59 @@ -import '@angular/compiler'; +import { provideHttpClient } from '@angular/common/http'; +import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { getTestBed } from '@angular/core/testing'; -import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing'; -import { Subject } from 'rxjs'; -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { EventDateNoticeModalComponent } from '../../shared/components/event-date-notice-modal/event-date-notice-modal.component'; -import { EventDateNoticeService } from './event-date-notice.service'; -import { ModalService } from './modal.service'; -import { TenantEventDateNotice } from './tenant.interface'; +import { environment } from '../../../environments/environment'; +import { EventDateNotice, EventDateNoticeService } from './event-date-notice.service'; +import { ApiResponse } from './api-response.interface'; +import { TenantService } from './tenant.service'; describe('EventDateNoticeService', () => { let service: EventDateNoticeService; - let open: ReturnType; - - beforeAll(() => { - try { - getTestBed().initTestEnvironment(BrowserTestingModule, platformBrowserTesting()); - } catch { - // Test environment may already be initialized by another setup entrypoint. - } - }); + let httpMock: HttpTestingController; beforeEach(() => { - open = vi.fn(); TestBed.configureTestingModule({ providers: [ EventDateNoticeService, + provideHttpClient(), + provideHttpClientTesting(), { - provide: ModalService, - useValue: { open }, + provide: TenantService, + useValue: { getTenant: () => ({ codigo: 'festival' }) }, }, ], }); + service = TestBed.inject(EventDateNoticeService); + httpMock = TestBed.inject(HttpTestingController); }); - afterEach(() => { - TestBed.resetTestingModule(); - }); + afterEach(() => httpMock.verify()); - it('shows backend notices sequentially', () => { - const firstClosed = new Subject(); - const secondClosed = new Subject(); - const notices: TenantEventDateNotice[] = [ - { - type: 'suspended', - title: 'FECHA CANCELADA!', - message: [{ text: 'La fecha fue cancelada.', bold: false }], - }, - { - type: 'rescheduled', - title: 'FECHA REPROGRAMADA!', - message: [{ text: 'La fecha fue reprogramada.', bold: false }], - }, - ]; + it('claims pending notices for the active tenant', () => { + const response = { + data: [ + { + type: 'suspended' as const, + change_ids: [10], + title: 'FECHA CANCELADA!', + message: [{ text: 'La fecha fue cancelada.', bold: false }], + }, + ], + }; + let result: ApiResponse | undefined; - open - .mockReturnValueOnce({ afterClosed$: firstClosed.asObservable() }) - .mockReturnValueOnce({ afterClosed$: secondClosed.asObservable() }); + service.claim().subscribe((value) => (result = value)); - service.show(notices); + const request = httpMock.expectOne( + `${environment.url}tenants/festival/event-date-notices/claim`, + ); + expect(request.request.method).toBe('POST'); + expect(request.request.body).toEqual({}); - expect(open).toHaveBeenCalledTimes(1); - expect(open).toHaveBeenNthCalledWith(1, EventDateNoticeModalComponent, { - size: 'sm', - data: notices[0], - }); + request.flush(response); - firstClosed.next(undefined); - - expect(open).toHaveBeenCalledTimes(2); - expect(open).toHaveBeenNthCalledWith(2, EventDateNoticeModalComponent, { - size: 'sm', - data: notices[1], - }); - }); - - it('does not open a modal without notices', () => { - service.show([]); - - expect(open).not.toHaveBeenCalled(); + expect(result).toEqual(response); }); }); diff --git a/src/app/core/services/tenant.interface.ts b/src/app/core/services/tenant.interface.ts index 6f8bff5..0792a45 100644 --- a/src/app/core/services/tenant.interface.ts +++ b/src/app/core/services/tenant.interface.ts @@ -73,34 +73,10 @@ export interface ActiveEventDate { isCanceled: boolean; } -export type TenantEventDateChangeType = 'rescheduled' | 'suspended'; - -export interface TenantEventDateChange { - type: TenantEventDateChangeType; - source_event_date_id: number | null; - destination_event_date_id: number | null; - previous_date: string; - new_date: string | null; - occurred_at: string; -} - -export interface TenantEventDateNoticeMessagePart { - text: string; - bold: boolean; -} - -export interface TenantEventDateNotice { - type: TenantEventDateChangeType; - title: string; - message: TenantEventDateNoticeMessagePart[]; -} - export interface TenantEvent { title: string; location: string; dates: ActiveEventDate[]; - date_changes?: TenantEventDateChange[]; - date_notices?: TenantEventDateNotice[]; } export interface WebsiteExtras { diff --git a/src/app/shared/components/event-date-notice-modal/event-date-notice-modal.component.spec.ts b/src/app/shared/components/event-date-notice-modal/event-date-notice-modal.component.spec.ts index 252f7dc..d565b47 100644 --- a/src/app/shared/components/event-date-notice-modal/event-date-notice-modal.component.spec.ts +++ b/src/app/shared/components/event-date-notice-modal/event-date-notice-modal.component.spec.ts @@ -3,8 +3,8 @@ import { TestBed, getTestBed } from '@angular/core/testing'; import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing'; import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest'; +import { EventDateNotice } from '../../../core/services/event-date-notice.service'; import { MODAL_DATA, ModalRef } from '../../../core/services/modal.service'; -import { TenantEventDateNotice } from '../../../core/services/tenant.interface'; import { EventDateNoticeModalComponent } from './event-date-notice-modal.component'; describe('EventDateNoticeModalComponent', () => { @@ -22,8 +22,9 @@ describe('EventDateNoticeModalComponent', () => { it('renders the precalculated message and emphasizes its marked parts', async () => { const close = vi.fn(); - const data: TenantEventDateNotice = { + const data: EventDateNotice = { type: 'rescheduled', + change_ids: [1, 2], title: 'FECHAS REPROGRAMADAS!', message: [ { text: 'Las fechas del ', bold: false }, @@ -48,7 +49,7 @@ describe('EventDateNoticeModalComponent', () => { expect(element.querySelector('h2')?.textContent).toContain(data.title); expect( - [...element.querySelectorAll('strong')].map((strong) => strong.textContent?.trim()), + [...element.querySelectorAll('b')].map((strong) => strong.textContent?.trim()), ).toEqual(['09 y 10 de Octubre de 2026', 'respectivamente']); element.querySelector('button')?.click();