Skip to content

Commit

Permalink
Feat(Course): Fetch recent courses use case
Browse files Browse the repository at this point in the history
  • Loading branch information
Artur-Poffo committed Feb 12, 2024
1 parent cbfb65f commit 6baf407
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 2 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,10 @@
### Courses
- [ ] GET /courses/:courseId - Get course details
- [ ] GET /courses/:courseId/instructor - Get course instructor details
- [ ] GET /courses/:courseId/evaluations - Get course evaluations - make use case
- [ ] GET /courses/:courseId/evaluation - Get course evaluation average
- [ ] GET /courses/:courseId/stats - Get course statistics, like duration and number of classes
- [ ] GET /courses/:courseId/metrics - Get course metrics for a dashboard
- [ ] GET /courses - Get recent courses with instructor and evaluations - make use case
- [ ] GET /courses - Get recent courses with instructor and evaluation average
- [ ] GET /courses/filter - Filter courses by name or tags
- [ ] GET /courses/:courseId/students - Get students enrolled in this course
- [ ] GET /courses/:courseId/modules - Get course modules
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { type StudentWithCoursesDTO } from './../../enterprise/entities/dtos/stu

export interface CoursesRepository {
findById: (id: string) => Promise<Course | null>
findAll: () => Promise<Course[]>
findManyByInstructorId: (instructorId: string) => Promise<Course[]>
queryByName: (name: string) => Promise<Course[]>
queryByTags: (tags: Tag[]) => Promise<Course[]>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { makeCourse } from '../../../../../test/factories/make-course'
import { InMemoryClassesRepository } from '../../../../../test/repositories/in-memory-classes-repository'
import { InMemoryCourseTagsRepository } from '../../../../../test/repositories/in-memory-course-tags-repository'
import { InMemoryCoursesRepository } from '../../../../../test/repositories/in-memory-courses-repository'
import { InMemoryEnrollmentsRepository } from '../../../../../test/repositories/in-memory-enrollments-repository'
import { InMemoryInstructorRepository } from '../../../../../test/repositories/in-memory-instructors-repository'
import { InMemoryModulesRepository } from '../../../../../test/repositories/in-memory-modules-repository'
import { InMemoryStudentsRepository } from '../../../../../test/repositories/in-memory-students-repository'
import { FetchRecentCoursesUseCase } from './fetch-recent-courses'

let inMemoryClassesRepository: InMemoryClassesRepository
let inMemoryCourseTagsRepository: InMemoryCourseTagsRepository
let inMemoryEnrollmentsRepository: InMemoryEnrollmentsRepository
let inMemoryStudentsRepository: InMemoryStudentsRepository
let inMemoryInstructorsRepository: InMemoryInstructorRepository
let inMemoryModulesRepository: InMemoryModulesRepository
let inMemoryCoursesRepository: InMemoryCoursesRepository
let sut: FetchRecentCoursesUseCase

describe('Fetch recent courses use case', () => {
beforeEach(() => {
inMemoryClassesRepository = new InMemoryClassesRepository()
inMemoryCourseTagsRepository = new InMemoryCourseTagsRepository()
inMemoryStudentsRepository = new InMemoryStudentsRepository()
inMemoryInstructorsRepository = new InMemoryInstructorRepository()

inMemoryModulesRepository = new InMemoryModulesRepository(inMemoryClassesRepository)

inMemoryEnrollmentsRepository = new InMemoryEnrollmentsRepository(
inMemoryClassesRepository, inMemoryModulesRepository, inMemoryStudentsRepository
)
inMemoryCoursesRepository = new InMemoryCoursesRepository(inMemoryModulesRepository, inMemoryInstructorsRepository, inMemoryEnrollmentsRepository, inMemoryStudentsRepository, inMemoryCourseTagsRepository)

sut = new FetchRecentCoursesUseCase(inMemoryCoursesRepository)
})

it('should be able to fetch recent courses correctly', async () => {
const firstCourse = makeCourse({ name: 'John Doe Course 1', createdAt: new Date('2023-01-01') })
const secondCourse = makeCourse({ name: 'John Doe Course 2', createdAt: new Date('2023-01-02') })

await Promise.all([
inMemoryCoursesRepository.create(firstCourse),
inMemoryCoursesRepository.create(secondCourse)
])

const result = await sut.exec()

console.log(result.value)

expect(result.isRight()).toBe(true)
expect(result.value).toMatchObject({
courses: [
expect.objectContaining({
name: 'John Doe Course 2'
}),
expect.objectContaining({
name: 'John Doe Course 1'
})
]
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { right, type Either } from '@/core/either'
import { type UseCase } from '@/core/use-cases/use-case'
import { type Course } from '../../enterprise/entities/course'
import { type CoursesRepository } from '../repositories/courses-repository'

type FetchRecentCoursesUseCaseResponse = Either<
null,
{
courses: Course[]
}
>

export class FetchRecentCoursesUseCase implements UseCase<null, FetchRecentCoursesUseCaseResponse> {
constructor(
private readonly coursesRepository: CoursesRepository
) { }

async exec(): Promise<FetchRecentCoursesUseCaseResponse> {
const courses = await this.coursesRepository.findAll()

return right({
courses
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { type CourseDTO } from './course'
import { type InstructorDTO } from './instructor'

export interface CourseWithInstructorAndEvaluation {
course: CourseDTO
instructor: InstructorDTO
evaluationAverage: number
}
6 changes: 6 additions & 0 deletions test/repositories/in-memory-courses-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ export class InMemoryCoursesRepository implements CoursesRepository {
return course
}

async findAll(): Promise<Course[]> {
const courses = [...this.items]

return courses.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
}

async findManyByInstructorId(instructorId: string): Promise<Course[]> {
return this.items.filter(courseToCompare => courseToCompare.instructorId.toString() === instructorId)
}
Expand Down

0 comments on commit 6baf407

Please sign in to comment.