From cdc67812781809fdad836fc1ad44a5cc562dbc52 Mon Sep 17 00:00:00 2001 From: Caio Nascimento Date: Sun, 28 Jan 2024 23:00:46 -0300 Subject: [PATCH] feat: uncomplete habit regardless time --- .../MemoryHabitCompletionDateRepository.ts | 35 ++++++++++++++----- .../postgres/PgHabitCompDateRepository.ts | 6 ++-- .../tests/HabitCompletionDateUseCase.test.ts | 10 ++++++ src/domain/entities/HabitCompletionDate.ts | 2 +- .../routes/e2e/habitCompDate.routes.test.ts | 10 ++++++ 5 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/adapters/database/inMemory/MemoryHabitCompletionDateRepository.ts b/src/adapters/database/inMemory/MemoryHabitCompletionDateRepository.ts index 81a0f24..41414c4 100644 --- a/src/adapters/database/inMemory/MemoryHabitCompletionDateRepository.ts +++ b/src/adapters/database/inMemory/MemoryHabitCompletionDateRepository.ts @@ -14,10 +14,20 @@ export class MemoryHabitCompletionDateRepository } async findByHabitIdAndDate(habitId: string, completedDate: string) { - return this.habitCompletionDates.find( - habit => - habit.habitId === habitId && habit.completedDate === completedDate, - ); + const completeDateWithoutHour = new Date(completedDate) + .toISOString() + .substring(0, 10); + + return this.habitCompletionDates.find(habit => { + const storeCompletedDateWithoutHour = new Date(habit.completedDate) + .toISOString() + .substring(0, 10); + + return ( + habit.habitId === habitId && + completeDateWithoutHour === storeCompletedDateWithoutHour + ); + }); } async list() { @@ -25,9 +35,18 @@ export class MemoryHabitCompletionDateRepository } async delete(habitId: string, completedDate: string) { - this.habitCompletionDates = this.habitCompletionDates.filter( - habit => - !(habit.habitId === habitId && habit.completedDate === completedDate), - ); + const completedDateWithoutHour = new Date(completedDate) + .toISOString() + .substring(0, 10); + + this.habitCompletionDates = this.habitCompletionDates.filter(habit => { + const storedCompletedDateWithouHour = new Date(habit.completedDate) + .toISOString() + .substring(0, 10); + return !( + habit.habitId === habitId && + storedCompletedDateWithouHour === completedDateWithoutHour + ); + }); } } diff --git a/src/adapters/database/postgres/PgHabitCompDateRepository.ts b/src/adapters/database/postgres/PgHabitCompDateRepository.ts index 57bf72e..bb64dc5 100644 --- a/src/adapters/database/postgres/PgHabitCompDateRepository.ts +++ b/src/adapters/database/postgres/PgHabitCompDateRepository.ts @@ -36,8 +36,8 @@ export class PgHabitCompDateRepository async findByHabitIdAndDate(habitId: string, completedDate: string) { const [habit] = ( await pool.query( - `SELECT * FROM habit_completion_dates - WHERE habit_id = $1 AND completed_date = $2`, + `SELECT *, completed_date AT TIME ZONE 'UTC' as completed_date FROM habit_completion_dates + WHERE habit_id = $1 AND DATE(completed_date) = $2`, [habitId, completedDate], ) ).rows; @@ -51,7 +51,7 @@ export class PgHabitCompDateRepository async delete(habitId: string, completedDate: string) { await pool.query( `DELETE FROM habit_completion_dates - WHERE habit_id = $1 AND completed_date = $2`, + WHERE habit_id = $1 AND DATE(completed_date) = $2`, [habitId, completedDate], ); } diff --git a/src/application/tests/HabitCompletionDateUseCase.test.ts b/src/application/tests/HabitCompletionDateUseCase.test.ts index 4567a87..9ac8170 100644 --- a/src/application/tests/HabitCompletionDateUseCase.test.ts +++ b/src/application/tests/HabitCompletionDateUseCase.test.ts @@ -69,4 +69,14 @@ describe('Complete a Habit', () => { habitCompletionDateUseCase.execute(habitId, completedDate), ).rejects.toEqual({ statusCode: 400, message: 'habit not found' }); }); + + it('should be possible to uncomplete a habit regardless of the time.', async () => { + const createdHabit = await createHabitUseCase.execute('run'); + const habitCompletionDate = await habitCompletionDateUseCase.execute( + createdHabit.id, + completedDate, + ); + expect(habitCompletionDate?.habitId).toBe(createdHabit.id); + expect(habitCompletionDate?.completedDate).toBe(completedDate); + }); }); diff --git a/src/domain/entities/HabitCompletionDate.ts b/src/domain/entities/HabitCompletionDate.ts index 308f250..768b09b 100644 --- a/src/domain/entities/HabitCompletionDate.ts +++ b/src/domain/entities/HabitCompletionDate.ts @@ -1,5 +1,5 @@ export interface HabitCompletionDate { id: string; habitId: string; - completedDate?: string; + completedDate: string; } diff --git a/src/infra/web/routes/e2e/habitCompDate.routes.test.ts b/src/infra/web/routes/e2e/habitCompDate.routes.test.ts index 0df2e70..e6fa2cd 100644 --- a/src/infra/web/routes/e2e/habitCompDate.routes.test.ts +++ b/src/infra/web/routes/e2e/habitCompDate.routes.test.ts @@ -85,4 +85,14 @@ describe('Habit Complete Date Controllers', () => { expect(response.status).toBe(400); expect(response.body).toBe('habit not found'); }); + + it('POST (should be able to uncomplete a habit regardless of the time)', async () => { + const response = await request(app).post('/').send({ + habitId: '4567', + completedDate: '2000-02-03T23:59:59.000Z', + }); + const completedHabits = await memoryHabitCompDateRepository.list(); + expect(completedHabits).toHaveLength(1); + expect(response.status).toBe(200); + }); });