diff --git a/server/src/controllers/housingController.test.ts b/server/src/controllers/housingController.test.ts index 953f4f032..feb671a2f 100644 --- a/server/src/controllers/housingController.test.ts +++ b/server/src/controllers/housingController.test.ts @@ -27,8 +27,9 @@ import { Owners, ownerTable } from '~/repositories/ownerRepository'; -import { HousingStatusApi } from '~/models/HousingStatusApi'; +import { HousingStatusApi, toHousingStatus } from '~/models/HousingStatusApi'; import { + EventRecordDBO, Events, eventsTable, HousingEvents, @@ -68,12 +69,17 @@ import { OCCUPANCY_VALUES } from '@zerologementvacant/models'; import { EstablishmentApi } from '~/models/EstablishmentApi'; +import { UserApi, UserRoles } from '~/models/UserApi'; describe('Housing API', () => { const { app } = createServer(); const establishment = genEstablishmentApi(); const user = genUserApi(establishment.id); + const visitor: UserApi = { + ...genUserApi(establishment.id), + role: UserRoles.Visitor + }; const anotherEstablishment = genEstablishmentApi(); const anotherUser = genUserApi(anotherEstablishment.id); @@ -81,7 +87,7 @@ describe('Housing API', () => { await Establishments().insert( [establishment, anotherEstablishment].map(formatEstablishmentApi) ); - await Users().insert([user, anotherUser].map(formatUserApi)); + await Users().insert([user, visitor, anotherUser].map(formatUserApi)); }); describe('GET /housing/{id}', () => { @@ -570,7 +576,15 @@ describe('Housing API', () => { expect(status).toBe(constants.HTTP_STATUS_NOT_FOUND); }); - it.todo('should throw if the user is a visitor'); + it('should throw if the user is a visitor', async () => { + const { status } = await request(app) + .put(testRoute(housing.id)) + .send(payload) + .type('json') + .use(tokenProvider(visitor)); + + expect(status).toBe(constants.HTTP_STATUS_UNAUTHORIZED); + }); it('should return the housing', async () => { const { body, status } = await request(app) @@ -610,6 +624,73 @@ describe('Housing API', () => { occupancy_intended: payload.occupancyIntended }); }); + + it('should not create events if there is no change', async () => { + const payload: HousingUpdatePayloadDTO = { + status: toHousingStatus(housing.status), + subStatus: housing.subStatus, + occupancy: housing.occupancy, + occupancyIntended: housing.occupancyIntended, + precisions: housing.precisions, + vacancyReasons: housing.vacancyReasons + }; + + const { status } = await request(app) + .put(testRoute(housing.id)) + .send(payload) + .type('json') + .use(tokenProvider(user)); + + expect(status).toBe(constants.HTTP_STATUS_OK); + const events = await HousingEvents().where({ + housing_geo_code: housing.geoCode, + housing_id: housing.id + }); + expect(events).toHaveLength(0); + }); + + it('should create an event related to the status change', async () => { + const { status } = await request(app) + .put(testRoute(housing.id)) + .send(payload) + .type('json') + .use(tokenProvider(user)); + + expect(status).toBe(constants.HTTP_STATUS_OK); + const event = await Events() + .join(housingEventsTable, 'event_id', 'id') + .where({ + housing_id: housing.id, + housing_geo_code: housing.geoCode, + name: 'Changement de statut de suivi' + }) + .first(); + expect(event).toMatchObject>>({ + name: 'Changement de statut de suivi', + created_by: user.id + }); + }); + + it('should create an event related to the occupancy change', async () => { + const { status } = await request(app) + .put(testRoute(housing.id)) + .send(payload) + .use(tokenProvider(user)); + + expect(status).toBe(constants.HTTP_STATUS_OK); + const event = await Events() + .join(housingEventsTable, 'event_id', 'id') + .where({ + housing_geo_code: housing.geoCode, + housing_id: housing.id, + name: "Modification du statut d'occupation" + }) + .first(); + expect(event).toMatchObject>>({ + name: "Modification du statut d'occupation", + created_by: user.id + }); + }); }); describe('POST /housing/list', () => { diff --git a/server/src/controllers/housingController.ts b/server/src/controllers/housingController.ts index 61006717a..1926b38a1 100644 --- a/server/src/controllers/housingController.ts +++ b/server/src/controllers/housingController.ts @@ -322,7 +322,7 @@ async function updateNext( request: Request, response: Response ): Promise { - const { body, establishment, params } = request as AuthenticatedRequest< + const { auth, body, establishment, params } = request as AuthenticatedRequest< HousingPathParams, HousingDTO, HousingUpdatePayloadDTO @@ -348,6 +348,22 @@ async function updateNext( }; await startTransaction(async () => { await housingRepository.update(updated); + await createHousingUpdateEvents( + housing, + { + statusUpdate: { + status: fromHousingStatus(body.status), + subStatus: body.subStatus, + precisions: body.precisions, + vacancyReasons: body.vacancyReasons + }, + occupancyUpdate: { + occupancy: body.occupancy, + occupancyIntended: body.occupancyIntended + } + }, + auth.userId + ); }); response.status(constants.HTTP_STATUS_OK).json(toHousingDTO(updated)); @@ -477,8 +493,14 @@ async function createHousingUpdateEvents( statusUpdate && (housingApi.status !== statusUpdate.status || housingApi.subStatus !== statusUpdate.subStatus || - !_.isEqual(housingApi.precisions, statusUpdate.precisions) || - !_.isEqual(housingApi.vacancyReasons, statusUpdate.vacancyReasons)) + !_.isEqual( + housingApi.precisions ?? null, + statusUpdate.precisions ?? null + ) || + !_.isEqual( + housingApi.vacancyReasons ?? null, + statusUpdate.vacancyReasons ?? null + )) ) { await eventRepository.insertHousingEvent({ id: uuidv4(),