Skip to content

Commit

Permalink
Test(Class, Enrollment, Course): Mark course as completed use case
Browse files Browse the repository at this point in the history
  • Loading branch information
Artur-Poffo committed Feb 8, 2024
1 parent fa82858 commit 2921373
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
- [ ] Return information about a course with student progress in your modules and classes.
- [x] Students can mark classes as completed.
- [x] Mark modules as completed after the student views all its classes.
- [ ] After completing all modules of a course, that course for a student should be marked as completed.
- [x] After completing all modules of a course, that course for a student should be marked as completed.
- [ ] Return information about a student with the courses they are enrolled in.
- [ ] After completing a course, the student can issue a certificate.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { type UseCaseError } from '@/core/errors/use-case-error'

export class AllModulesInTheCourseMustBeMarkedAsCompleted extends Error implements UseCaseError {
constructor(courseName: string) {
super(`All modules in the course: ${courseName}, must be marked as completed`)
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { NotAllowedError } from '@/core/errors/errors/not-allowed-error'
import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
import { makeClass } from '../../../../../test/factories/make-class'
import { makeCourse } from '../../../../../test/factories/make-course'
import { makeEnrollment } from '../../../../../test/factories/make-enrollment'
Expand All @@ -10,6 +12,7 @@ import { InMemoryEnrollmentsRepository } from '../../../../../test/repositories/
import { InMemoryStudentsRepository } from '../../../../../test/repositories/in-memory-students-repository'
import { InMemoryInstructorRepository } from './../../../../../test/repositories/in-memory-instructors-repository'
import { InMemoryModulesRepository } from './../../../../../test/repositories/in-memory-modules-repository'
import { AllModulesInTheCourseMustBeMarkedAsCompleted } from './errors/all-modules-in-the-course-must-be-marked-as-completed'
import { MarkCourseAsCompletedUseCase } from './mark-course-as-completed'

let inMemoryEnrollmentsRepository: InMemoryEnrollmentsRepository
Expand Down Expand Up @@ -40,7 +43,7 @@ describe('Mark course as completed use case', () => {
)
})

it('should be able to mark a enrollment of a course as completed', async () => {
it('should be able to mark a enrollment of a student as completed', async () => {
const instructor = makeInstructor()
await inMemoryInstructorsRepository.create(instructor)

Expand Down Expand Up @@ -71,5 +74,106 @@ describe('Mark course as completed use case', () => {
})

expect(result.isRight()).toBe(true)
expect(inMemoryEnrollmentsRepository.items[0].completedAt).not.toBe(null)
})

it('should not be able to mark a inexistent enrollment of a student as completed', async () => {
const instructor = makeInstructor()
await inMemoryInstructorsRepository.create(instructor)

const course = makeCourse({ instructorId: instructor.id })
await inMemoryCoursesRepository.create(course)

const module = makeModule({
courseId: course.id,
moduleNumber: 1
})
await inMemoryModulesRepository.create(module)

const classToMarkAsCompleted = makeClass({ name: 'John Doe Class', moduleId: module.id, classNumber: 1 })
await inMemoryClassesRepository.create(classToMarkAsCompleted)

const student = makeStudent()
await inMemoryStudentsRepository.create(student)

const result = await sut.exec({
enrollmentId: 'inexistentEnrollmentId',
studentId: student.id.toString()
})

expect(result.isLeft()).toBe(true)
expect(result.value).toBeInstanceOf(ResourceNotFoundError)
})

it('should not be able to mark a enrollment of a student as completed if the student not is the owner of the enrollment', async () => {
const instructor = makeInstructor()
await inMemoryInstructorsRepository.create(instructor)

const course = makeCourse({ instructorId: instructor.id })
await inMemoryCoursesRepository.create(course)

const module = makeModule({
name: 'John Doe Module',
courseId: course.id,
moduleNumber: 1
})
await inMemoryModulesRepository.create(module)

const classToAdd = makeClass({ name: 'John Doe Class', moduleId: module.id, classNumber: 1 })
await inMemoryClassesRepository.create(classToAdd)

const correctStudent = makeStudent()
const wrongStudent = makeStudent()

await Promise.all([
inMemoryStudentsRepository.create(correctStudent),
inMemoryStudentsRepository.create(wrongStudent)
])

const enrollment = makeEnrollment({ studentId: correctStudent.id, courseId: course.id })
await inMemoryEnrollmentsRepository.create(enrollment)

await inMemoryEnrollmentsRepository.markClassAsCompleted(classToAdd.id.toString(), enrollment)

const result = await sut.exec({
enrollmentId: enrollment.id.toString(),
studentId: wrongStudent.id.toString()
})

expect(result.isLeft()).toBe(true)
expect(result.value).toBeInstanceOf(NotAllowedError)
})

it('should not be able to mark a enrollment of a student as completed if any module within it is not completed', async () => {
const instructor = makeInstructor()
await inMemoryInstructorsRepository.create(instructor)

const course = makeCourse({ instructorId: instructor.id })
await inMemoryCoursesRepository.create(course)

const notCompletedModule = makeModule({
courseId: course.id,
moduleNumber: 1
})
await inMemoryModulesRepository.create(notCompletedModule)

const classToMarkAsCompleted = makeClass({ name: 'John Doe Class', moduleId: notCompletedModule.id, classNumber: 1 })
await inMemoryClassesRepository.create(classToMarkAsCompleted)

const student = makeStudent()
await inMemoryStudentsRepository.create(student)

const enrollment = makeEnrollment({ studentId: student.id, courseId: course.id })
await inMemoryEnrollmentsRepository.create(enrollment)

// Not mark module as completed

const result = await sut.exec({
enrollmentId: enrollment.id.toString(),
studentId: student.id.toString()
})

expect(result.isLeft()).toBe(true)
expect(result.value).toBeInstanceOf(AllModulesInTheCourseMustBeMarkedAsCompleted)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { type CoursesRepository } from '../repositories/courses-repository'
import { type EnrollmentsRepository } from '../repositories/enrollments-repository'
import { type StudentsRepository } from '../repositories/students-repository'
import { type ModulesRepository } from './../repositories/modules-repository'
import { AllModulesInTheCourseMustBeMarkedAsCompleted } from './errors/all-modules-in-the-course-must-be-marked-as-completed'

interface MarkCourseAsCompletedUseCaseRequest {
enrollmentId: string
Expand Down Expand Up @@ -60,7 +61,7 @@ export class MarkCourseAsCompletedUseCase implements UseCase<MarkCourseAsComplet
})

if (!allModulesOfThisCourseIsCompleted) {
return left(new ResourceNotFoundError())
return left(new AllModulesInTheCourseMustBeMarkedAsCompleted(completeCourse.course.name))
}

await this.enrollmentsRepository.markAsCompleted(enrollment)
Expand Down

0 comments on commit 2921373

Please sign in to comment.