diff --git a/includes/class-sensei-utils.php b/includes/class-sensei-utils.php index 0af5ab7438..486c98b300 100644 --- a/includes/class-sensei-utils.php +++ b/includes/class-sensei-utils.php @@ -1,7 +1,6 @@ lesson_progress_repository->get( $lesson_id, $student_id ); - if ( ! $lesson_progress || ! in_array( $lesson_progress->get_status(), [ Lesson_Progress::STATUS_COMPLETE, Quiz_Progress::STATUS_PASSED ], true ) ) { + if ( ! $lesson_progress || ! $lesson_progress->is_complete() ) { return; } diff --git a/includes/internal/migration/migrations/class-student-progress-migration.php b/includes/internal/migration/migrations/class-student-progress-migration.php index d096c34d77..9848ea1de0 100644 --- a/includes/internal/migration/migrations/class-student-progress-migration.php +++ b/includes/internal/migration/migrations/class-student-progress-migration.php @@ -12,9 +12,9 @@ } use Sensei\Internal\Migration\Migration_Abstract; -use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress; -use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress; -use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress_Interface; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress_Interface; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress_Interface; /** * Class Student_Progress_Migration. @@ -248,11 +248,11 @@ private function prepare_progress_to_insert( $progress_comments, $mapped_meta ): */ private function prepare_course_progress_to_insert( $comment, $meta ): void { $course_status = 'in-progress'; - if ( Course_Progress::STATUS_COMPLETE === $comment->comment_approved ) { + if ( Course_Progress_Interface::STATUS_COMPLETE === $comment->comment_approved ) { $course_status = 'complete'; } - if ( Course_Progress::STATUS_COMPLETE === $comment->comment_approved ) { + if ( Course_Progress_Interface::STATUS_COMPLETE === $comment->comment_approved ) { $completed_at = $comment->comment_date_gmt; } else { $completed_at = null; @@ -334,23 +334,23 @@ private function prepare_lesson_progress_to_insert( $comment, $meta ): void { if ( isset( $meta['_lesson_quiz'] ) ) { $quiz_id = $meta['_lesson_quiz']; $supported_statuses = [ - Quiz_Progress::STATUS_IN_PROGRESS, - Quiz_Progress::STATUS_FAILED, - Quiz_Progress::STATUS_GRADED, - Quiz_Progress::STATUS_PASSED, - Quiz_Progress::STATUS_UNGRADED, + Quiz_Progress_Interface::STATUS_IN_PROGRESS, + Quiz_Progress_Interface::STATUS_FAILED, + Quiz_Progress_Interface::STATUS_GRADED, + Quiz_Progress_Interface::STATUS_PASSED, + Quiz_Progress_Interface::STATUS_UNGRADED, // We need to map lesson statuses to quiz' passed status. - Lesson_Progress::STATUS_COMPLETE, + Lesson_Progress_Interface::STATUS_COMPLETE, ]; $quiz_status = in_array( $comment->comment_approved, $supported_statuses, true ) ? $comment->comment_approved - : Quiz_Progress::STATUS_IN_PROGRESS; + : Quiz_Progress_Interface::STATUS_IN_PROGRESS; $quiz_completed_at = $completed_at; - if ( Quiz_Progress::STATUS_IN_PROGRESS === $quiz_status ) { + if ( Quiz_Progress_Interface::STATUS_IN_PROGRESS === $quiz_status ) { $quiz_completed_at = null; } - if ( Lesson_Progress::STATUS_COMPLETE === $quiz_status ) { - $quiz_status = Quiz_Progress::STATUS_PASSED; + if ( Lesson_Progress_Interface::STATUS_COMPLETE === $quiz_status ) { + $quiz_status = Quiz_Progress_Interface::STATUS_PASSED; } $this->progress_inserts[] = [ diff --git a/includes/internal/student-progress/course-progress/models/class-comments-based-course-progress.php b/includes/internal/student-progress/course-progress/models/class-comments-based-course-progress.php new file mode 100644 index 0000000000..1613787903 --- /dev/null +++ b/includes/internal/student-progress/course-progress/models/class-comments-based-course-progress.php @@ -0,0 +1,22 @@ +status = self::STATUS_IN_PROGRESS; + $this->status = Course_Progress_Interface::STATUS_IN_PROGRESS; $this->started_at = $started_at ?? current_datetime(); } @@ -136,7 +126,7 @@ public function start( DateTimeInterface $started_at = null ): void { * @param DateTimeInterface|null $completed_at Course completion date. */ public function complete( DateTimeInterface $completed_at = null ): void { - $this->status = self::STATUS_COMPLETE; + $this->status = Course_Progress_Interface::STATUS_COMPLETE; $this->completed_at = $completed_at ?? current_datetime(); } diff --git a/includes/internal/student-progress/course-progress/models/class-course-progress-interface.php b/includes/internal/student-progress/course-progress/models/class-course-progress-interface.php new file mode 100644 index 0000000000..05e6bcac7f --- /dev/null +++ b/includes/internal/student-progress/course-progress/models/class-course-progress-interface.php @@ -0,0 +1,136 @@ +comments_based_repository->create( $course_id, $user_id ); $this->tables_based_repository->create( $course_id, $user_id ); return $progress; @@ -72,9 +73,9 @@ public function create( int $course_id, int $user_id ): Course_Progress { * * @param int $course_id The course ID. * @param int $user_id The user ID. - * @return Course_Progress|null The course progress or null if it does not exist. + * @return Course_Progress_Interface|null The course progress or null if it does not exist. */ - public function get( int $course_id, int $user_id ): ?Course_Progress { + public function get( int $course_id, int $user_id ): ?Course_Progress_Interface { return $this->comments_based_repository->get( $course_id, $user_id ); } @@ -96,9 +97,9 @@ public function has( int $course_id, int $user_id ): bool { * * @internal * - * @param Course_Progress $course_progress The course progress. + * @param Course_Progress_Interface $course_progress The course progress. */ - public function save( Course_Progress $course_progress ): void { + public function save( Course_Progress_Interface $course_progress ): void { $this->comments_based_repository->save( $course_progress ); $tables_based_progress = $this->tables_based_repository->get( $course_progress->get_course_id(), $course_progress->get_user_id() ); @@ -119,7 +120,7 @@ public function save( Course_Progress $course_progress ): void { $completed_at = new \DateTimeImmutable( '@' . $course_progress->get_completed_at()->getTimestamp() ); } - $progress_to_save = new Course_Progress( + $progress_to_save = new Tables_Based_Course_Progress( $tables_based_progress->get_id(), $tables_based_progress->get_course_id(), $tables_based_progress->get_user_id(), @@ -137,9 +138,9 @@ public function save( Course_Progress $course_progress ): void { * * @internal * - * @param Course_Progress $course_progress The course progress. + * @param Course_Progress_Interface $course_progress The course progress. */ - public function delete( Course_Progress $course_progress ): void { + public function delete( Course_Progress_Interface $course_progress ): void { $this->comments_based_repository->delete( $course_progress ); $this->tables_based_repository->delete( $course_progress ); } diff --git a/includes/internal/student-progress/course-progress/repositories/class-comments-based-course-progress-repository.php b/includes/internal/student-progress/course-progress/repositories/class-comments-based-course-progress-repository.php index 95d544ef4a..566fc949c3 100644 --- a/includes/internal/student-progress/course-progress/repositories/class-comments-based-course-progress-repository.php +++ b/includes/internal/student-progress/course-progress/repositories/class-comments-based-course-progress-repository.php @@ -8,7 +8,8 @@ namespace Sensei\Internal\Student_Progress\Course_Progress\Repositories; use DateTime; -use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Comments_Based_Course_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress_Interface; use Sensei_Utils; if ( ! defined( 'ABSPATH' ) ) { @@ -30,21 +31,26 @@ class Comments_Based_Course_Progress_Repository implements Course_Progress_Repos * * @param int $course_id The course ID. * @param int $user_id The user ID. - * @return Course_Progress The course progress. + * @return Course_Progress_Interface The course progress. * @throws \RuntimeException If the course progress could not be created. */ - public function create( int $course_id, int $user_id ): Course_Progress { + public function create( int $course_id, int $user_id ): Course_Progress_Interface { $metadata = [ 'start' => current_time( 'mysql' ), 'percent' => 0, 'complete' => 0, ]; - $comment_id = Sensei_Utils::update_course_status( $user_id, $course_id, Course_Progress::STATUS_IN_PROGRESS, $metadata ); + $comment_id = Sensei_Utils::update_course_status( $user_id, $course_id, Course_Progress_Interface::STATUS_IN_PROGRESS, $metadata ); if ( ! $comment_id ) { throw new \RuntimeException( "Can't create a course progress" ); } - return $this->get( $course_id, $user_id ); + $progress = $this->get( $course_id, $user_id ); + if ( ! $progress ) { + throw new \RuntimeException( 'Created course progress not found' ); + } + + return $progress; } /** @@ -55,9 +61,9 @@ public function create( int $course_id, int $user_id ): Course_Progress { * @param int $course_id The course ID. * @param int $user_id The user ID. * - * @return Course_Progress|null The course progress. + * @return Comments_Based_Course_Progress|null The course progress. */ - public function get( int $course_id, int $user_id ): ?Course_Progress { + public function get( int $course_id, int $user_id ): ?Course_Progress_Interface { $activity_args = [ 'post_id' => $course_id, 'user_id' => $user_id, @@ -80,13 +86,13 @@ public function get( int $course_id, int $user_id ): ?Course_Progress { $started_at = $meta_start ? new DateTime( $meta_start, wp_timezone() ) : current_datetime(); $comment_date = new DateTime( $comment->comment_date, wp_timezone() ); - if ( Course_Progress::STATUS_COMPLETE === $comment->comment_approved ) { + if ( Course_Progress_Interface::STATUS_COMPLETE === $comment->comment_approved ) { $completed_at = $comment_date; } else { $completed_at = null; } - return new Course_Progress( (int) $comment->comment_ID, $course_id, $user_id, $comment->comment_approved, $started_at, $completed_at, $comment_date, $comment_date ); + return new Comments_Based_Course_Progress( (int) $comment->comment_ID, $course_id, $user_id, $comment->comment_approved, $started_at, $completed_at, $comment_date, $comment_date ); } /** @@ -130,9 +136,10 @@ public function has( int $course_id, int $user_id ): bool { * * @internal * - * @param Course_Progress $course_progress The course progress. + * @param Course_Progress_Interface $course_progress The course progress. */ - public function save( Course_Progress $course_progress ): void { + public function save( Course_Progress_Interface $course_progress ): void { + $this->assert_comments_based_course_progress( $course_progress ); $metadata = []; if ( $course_progress->get_started_at() ) { $metadata['start'] = $course_progress->get_started_at()->format( 'Y-m-d H:i:s' ); @@ -145,9 +152,9 @@ public function save( Course_Progress $course_progress ): void { * * @internal * - * @param Course_Progress $course_progress The course progress. + * @param Course_Progress_Interface $course_progress The course progress. */ - public function delete( Course_Progress $course_progress ): void { + public function delete( Course_Progress_Interface $course_progress ): void { $args = array( 'post_id' => $course_progress->get_course_id(), 'type' => 'sensei_course_status', @@ -216,4 +223,17 @@ private function delete_activities( array $args ): void { Sensei()->flush_comment_counts_cache( $post_id ); } } + + /** + * Assert that the course progress is a Comments_Based_Course_Progress. + * + * @param Course_Progress_Interface $course_progress The course progress. + * @throws \InvalidArgumentException If the course progress is not a Comments_Based_Course_Progress. + */ + private function assert_comments_based_course_progress( Course_Progress_Interface $course_progress ): void { + if ( ! $course_progress instanceof Comments_Based_Course_Progress ) { + $actual_type = get_class( $course_progress ); + throw new \InvalidArgumentException( "Expected Comments_Based_Course_Progress, got {$actual_type}." ); + } + } } diff --git a/includes/internal/student-progress/course-progress/repositories/class-course-progress-repository-interface.php b/includes/internal/student-progress/course-progress/repositories/class-course-progress-repository-interface.php index 3c91388efb..81cbfb6389 100644 --- a/includes/internal/student-progress/course-progress/repositories/class-course-progress-repository-interface.php +++ b/includes/internal/student-progress/course-progress/repositories/class-course-progress-repository-interface.php @@ -7,7 +7,7 @@ namespace Sensei\Internal\Student_Progress\Course_Progress\Repositories; -use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress_Interface; if ( ! defined( 'ABSPATH' ) ) { exit; @@ -28,9 +28,9 @@ interface Course_Progress_Repository_Interface { * * @param int $course_id The course ID. * @param int $user_id The user ID. - * @return Course_Progress The course progress. + * @return Course_Progress_Interface The course progress. */ - public function create( int $course_id, int $user_id ): Course_Progress; + public function create( int $course_id, int $user_id ): Course_Progress_Interface; /** * Gets a course progress. @@ -39,9 +39,9 @@ public function create( int $course_id, int $user_id ): Course_Progress; * * @param int $course_id The course ID. * @param int $user_id The user ID. - * @return Course_Progress|null The course progress. + * @return Course_Progress_Interface|null The course progress. */ - public function get( int $course_id, int $user_id ): ?Course_Progress; + public function get( int $course_id, int $user_id ): ?Course_Progress_Interface; /** * Checks if a course progress exists. @@ -59,18 +59,18 @@ public function has( int $course_id, int $user_id ): bool; * * @internal * - * @param Course_Progress $course_progress The course progress. + * @param Course_Progress_Interface $course_progress The course progress. */ - public function save( Course_Progress $course_progress ): void; + public function save( Course_Progress_Interface $course_progress ): void; /** * Delete course progress. * * @internal * - * @param Course_Progress $course_progress The course progress. + * @param Course_Progress_Interface $course_progress The course progress. */ - public function delete( Course_Progress $course_progress ): void; + public function delete( Course_Progress_Interface $course_progress ): void; /** * Delete course progress for a given course. diff --git a/includes/internal/student-progress/course-progress/repositories/class-table-reading-aggregate-course-progress-repository.php b/includes/internal/student-progress/course-progress/repositories/class-table-reading-aggregate-course-progress-repository.php index f2cc0d0d8c..ea00429267 100644 --- a/includes/internal/student-progress/course-progress/repositories/class-table-reading-aggregate-course-progress-repository.php +++ b/includes/internal/student-progress/course-progress/repositories/class-table-reading-aggregate-course-progress-repository.php @@ -7,7 +7,8 @@ namespace Sensei\Internal\Student_Progress\Course_Progress\Repositories; -use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Comments_Based_Course_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress_Interface; if ( ! defined( 'ABSPATH' ) ) { exit; @@ -54,9 +55,9 @@ public function __construct( * * @param int $course_id The course ID. * @param int $user_id The user ID. - * @return Course_Progress The course progress. + * @return Course_Progress_Interface The course progress. */ - public function create( int $course_id, int $user_id ): Course_Progress { + public function create( int $course_id, int $user_id ): Course_Progress_Interface { $this->comments_based_repository->create( $course_id, $user_id ); return $this->tables_based_repository->create( $course_id, $user_id ); } @@ -66,9 +67,9 @@ public function create( int $course_id, int $user_id ): Course_Progress { * * @param int $course_id The course ID. * @param int $user_id The user ID. - * @return Course_Progress|null The course progress, or null if it doesn't exist. + * @return Course_Progress_Interface|null The course progress, or null if it doesn't exist. */ - public function get( int $course_id, int $user_id ): ?Course_Progress { + public function get( int $course_id, int $user_id ): ?Course_Progress_Interface { return $this->tables_based_repository->get( $course_id, $user_id ); } @@ -86,15 +87,15 @@ public function has( int $course_id, int $user_id ): bool { /** * Save course progress. * - * @param Course_Progress $course_progress The course progress. + * @param Course_Progress_Interface $course_progress The course progress. */ - public function save( Course_Progress $course_progress ): void { + public function save( Course_Progress_Interface $course_progress ): void { $this->tables_based_repository->save( $course_progress ); $comments_based_progress = $this->comments_based_repository->get( $course_progress->get_course_id(), $course_progress->get_user_id() ); if ( ! $comments_based_progress ) { $comments_based_progress = $this->comments_based_repository->create( $course_progress->get_course_id(), $course_progress->get_user_id() ); } - $updated_comments_based_progress = new Course_Progress( + $updated_comments_based_progress = new Comments_Based_Course_Progress( $comments_based_progress->get_id(), $comments_based_progress->get_course_id(), $comments_based_progress->get_user_id(), @@ -110,9 +111,9 @@ public function save( Course_Progress $course_progress ): void { /** * Deletes a course progress. * - * @param Course_Progress $course_progress The course progress. + * @param Course_Progress_Interface $course_progress The course progress. */ - public function delete( Course_Progress $course_progress ): void { + public function delete( Course_Progress_Interface $course_progress ): void { $this->tables_based_repository->delete( $course_progress ); $comments_based_progress = $this->comments_based_repository->get( $course_progress->get_course_id(), $course_progress->get_user_id() ); if ( $comments_based_progress ) { diff --git a/includes/internal/student-progress/course-progress/repositories/class-tables-based-course-progress-repository.php b/includes/internal/student-progress/course-progress/repositories/class-tables-based-course-progress-repository.php index c1bd7b2f85..ca5f1ea6f4 100644 --- a/includes/internal/student-progress/course-progress/repositories/class-tables-based-course-progress-repository.php +++ b/includes/internal/student-progress/course-progress/repositories/class-tables-based-course-progress-repository.php @@ -9,7 +9,8 @@ use DateTimeImmutable; use DateTimeZone; -use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress_Interface; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Tables_Based_Course_Progress; use wpdb; if ( ! defined( 'ABSPATH' ) ) { @@ -49,9 +50,9 @@ public function __construct( wpdb $wpdb ) { * * @param int $course_id The course ID. * @param int $user_id The user ID. - * @return Course_Progress The course progress. + * @return Course_Progress_Interface The course progress. */ - public function create( int $course_id, int $user_id ): Course_Progress { + public function create( int $course_id, int $user_id ): Course_Progress_Interface { $current_datetime = new DateTimeImmutable( 'now', new DateTimeZone( 'UTC' ) ); $date_format = 'Y-m-d H:i:s'; $this->wpdb->insert( @@ -61,7 +62,7 @@ public function create( int $course_id, int $user_id ): Course_Progress { 'user_id' => $user_id, 'parent_post_id' => null, 'type' => 'course', - 'status' => Course_Progress::STATUS_IN_PROGRESS, + 'status' => Course_Progress_Interface::STATUS_IN_PROGRESS, 'started_at' => $current_datetime->format( $date_format ), 'completed_at' => null, 'created_at' => $current_datetime->format( $date_format ), @@ -81,11 +82,11 @@ public function create( int $course_id, int $user_id ): Course_Progress { ); $id = (int) $this->wpdb->insert_id; - return new Course_Progress( + return new Tables_Based_Course_Progress( $id, $course_id, $user_id, - Course_Progress::STATUS_IN_PROGRESS, + Course_Progress_Interface::STATUS_IN_PROGRESS, $current_datetime, null, $current_datetime, @@ -100,9 +101,9 @@ public function create( int $course_id, int $user_id ): Course_Progress { * * @param int $course_id The course ID. * @param int $user_id The user ID. - * @return Course_Progress|null The course progress or null if it does not exist. + * @return Course_Progress_Interface|null The course progress or null if it does not exist. */ - public function get( int $course_id, int $user_id ): ?Course_Progress { + public function get( int $course_id, int $user_id ): ?Course_Progress_Interface { $table_name = $this->wpdb->prefix . 'sensei_lms_progress'; $query = $this->wpdb->prepare( // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared @@ -120,7 +121,7 @@ public function get( int $course_id, int $user_id ): ?Course_Progress { $timezone = new DateTimeZone( 'UTC' ); - return new Course_Progress( + return new Tables_Based_Course_Progress( (int) $row->id, (int) $row->post_id, (int) $row->user_id, @@ -162,9 +163,11 @@ public function has( int $course_id, int $user_id ): bool { * * @internal * - * @param Course_Progress $course_progress The course progress. + * @param Course_Progress_Interface $course_progress The course progress. */ - public function save( Course_Progress $course_progress ): void { + public function save( Course_Progress_Interface $course_progress ): void { + $this->assert_tables_based_course_progress( $course_progress ); + $date_format = 'Y-m-d H:i:s'; $updated_at = new DateTimeImmutable( 'now', new DateTimeZone( 'UTC' ) ); @@ -198,9 +201,9 @@ public function save( Course_Progress $course_progress ): void { * * @internal * - * @param Course_Progress $course_progress The course progress. + * @param Course_Progress_Interface $course_progress The course progress. */ - public function delete( Course_Progress $course_progress ): void { + public function delete( Course_Progress_Interface $course_progress ): void { $this->wpdb->delete( $this->wpdb->prefix . 'sensei_lms_progress', [ @@ -257,4 +260,17 @@ public function delete_for_user( int $user_id ): void { ] ); } + + /** + * Assert that the course progress is a Tables_Based_Course_Progress. + * + * @param Course_Progress_Interface $course_progress The course progress. + * @throws \InvalidArgumentException If the course progress is not a Tables_Based_Course_Progress. + */ + private function assert_tables_based_course_progress( Course_Progress_Interface $course_progress ): void { + if ( ! $course_progress instanceof Tables_Based_Course_Progress ) { + $actual_type = get_class( $course_progress ); + throw new \InvalidArgumentException( "Expected Tables_Based_Course_Progress, got {$actual_type}." ); + } + } } diff --git a/includes/internal/student-progress/lesson-progress/models/class-comments-based-lesson-progress.php b/includes/internal/student-progress/lesson-progress/models/class-comments-based-lesson-progress.php new file mode 100644 index 0000000000..b4bd6b2c84 --- /dev/null +++ b/includes/internal/student-progress/lesson-progress/models/class-comments-based-lesson-progress.php @@ -0,0 +1,71 @@ +completed_at = $completed_at ?? current_datetime(); + $has_questions = Sensei_Lesson::lesson_quiz_has_questions( $this->lesson_id ); + $this->status = $has_questions ? Quiz_Progress_Interface::STATUS_PASSED : self::STATUS_COMPLETE; + } + + /** + * Returns the lesson progress status. + * + * @internal + * + * @return string|null + */ + public function get_status(): ?string { + switch ( $this->status ) { + case 'complete': + case 'graded': + case 'passed': + return self::STATUS_COMPLETE; + + case 'failed': + // This may be 'completed' depending on... + // Get Quiz ID, this won't be needed once all Quiz meta fields are stored on the Lesson. + $lesson_quiz_id = Sensei()->lesson->lesson_quizzes( $this->lesson_id ); + if ( $lesson_quiz_id ) { + // ...the quiz pass setting. + $pass_required = get_post_meta( $lesson_quiz_id, '_pass_required', true ); + if ( empty( $pass_required ) ) { + // We just require the user to have done the quiz, not to have passed. + return self::STATUS_COMPLETE; + } + } + return self::STATUS_IN_PROGRESS; + + default: + return self::STATUS_IN_PROGRESS; + } + } +} diff --git a/includes/internal/student-progress/lesson-progress/models/class-lesson-progress.php b/includes/internal/student-progress/lesson-progress/models/class-lesson-progress-abstract.php similarity index 84% rename from includes/internal/student-progress/lesson-progress/models/class-lesson-progress.php rename to includes/internal/student-progress/lesson-progress/models/class-lesson-progress-abstract.php index cd6f4abbf0..7087a92226 100644 --- a/includes/internal/student-progress/lesson-progress/models/class-lesson-progress.php +++ b/includes/internal/student-progress/lesson-progress/models/class-lesson-progress-abstract.php @@ -1,6 +1,6 @@ completed_at = $completed_at ?? current_datetime(); - $has_questions = Sensei_Lesson::lesson_quiz_has_questions( $this->lesson_id ); - $this->status = $has_questions ? Quiz_Progress::STATUS_PASSED : self::STATUS_COMPLETE; + $this->status = self::STATUS_COMPLETE; } /** @@ -217,13 +201,7 @@ public function get_completed_at(): ?DateTimeInterface { * @return bool */ public function is_complete(): bool { - $completed_statuses = [ - self::STATUS_COMPLETE, - Quiz_Progress::STATUS_PASSED, - Quiz_Progress::STATUS_GRADED, - ]; - - return in_array( $this->status, $completed_statuses, true ); + return $this->get_status() === self::STATUS_COMPLETE; } /** diff --git a/includes/internal/student-progress/lesson-progress/models/class-lesson-progress-interface.php b/includes/internal/student-progress/lesson-progress/models/class-lesson-progress-interface.php new file mode 100644 index 0000000000..403df940f3 --- /dev/null +++ b/includes/internal/student-progress/lesson-progress/models/class-lesson-progress-interface.php @@ -0,0 +1,145 @@ +comments_based_repository->create( $lesson_id, $user_id ); $this->tables_based_repository->create( $lesson_id, $user_id ); return $progress; @@ -72,9 +73,9 @@ public function create( int $lesson_id, int $user_id ): Lesson_Progress { * * @param int $lesson_id The lesson ID. * @param int $user_id The user ID. - * @return Lesson_Progress|null The lesson progress or null if it does not exist. + * @return Lesson_Progress_Interface|null The lesson progress or null if it does not exist. */ - public function get( int $lesson_id, int $user_id ): ?Lesson_Progress { + public function get( int $lesson_id, int $user_id ): ?Lesson_Progress_Interface { return $this->comments_based_repository->get( $lesson_id, $user_id ); } @@ -96,10 +97,11 @@ public function has( int $lesson_id, int $user_id ): bool { * * @internal * - * @param Lesson_Progress $lesson_progress The lesson progress. + * @param Lesson_Progress_Interface $lesson_progress The lesson progress. */ - public function save( Lesson_Progress $lesson_progress ): void { + public function save( Lesson_Progress_Interface $lesson_progress ): void { $this->comments_based_repository->save( $lesson_progress ); + $tables_based_progress = $this->tables_based_repository->get( $lesson_progress->get_lesson_id(), $lesson_progress->get_user_id() ); if ( ! $tables_based_progress ) { $tables_based_progress = $this->tables_based_repository->create( @@ -118,7 +120,7 @@ public function save( Lesson_Progress $lesson_progress ): void { $completed_at = new \DateTimeImmutable( '@' . $lesson_progress->get_completed_at()->getTimestamp() ); } - $progress_to_save = new Lesson_Progress( + $progress_to_save = new Tables_Based_Lesson_Progress( $tables_based_progress->get_id(), $tables_based_progress->get_lesson_id(), $tables_based_progress->get_user_id(), @@ -136,9 +138,9 @@ public function save( Lesson_Progress $lesson_progress ): void { * * @intenal * - * @param Lesson_Progress $lesson_progress The lesson progress. + * @param Lesson_Progress_Interface $lesson_progress The lesson progress. */ - public function delete( Lesson_Progress $lesson_progress ): void { + public function delete( Lesson_Progress_Interface $lesson_progress ): void { $this->comments_based_repository->delete( $lesson_progress ); $this->tables_based_repository->delete( $lesson_progress ); } diff --git a/includes/internal/student-progress/lesson-progress/repositories/class-comments-based-lesson-progress-repository.php b/includes/internal/student-progress/lesson-progress/repositories/class-comments-based-lesson-progress-repository.php index 57c9ba2eb4..620096ad63 100644 --- a/includes/internal/student-progress/lesson-progress/repositories/class-comments-based-lesson-progress-repository.php +++ b/includes/internal/student-progress/lesson-progress/repositories/class-comments-based-lesson-progress-repository.php @@ -8,8 +8,11 @@ namespace Sensei\Internal\Student_Progress\Lesson_Progress\Repositories; use DateTime; -use SebastianBergmann\Timer\RuntimeException; -use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress; +use InvalidArgumentException; +use ReflectionClass; +use RuntimeException; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Comments_Based_Lesson_Progress; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress_Interface; use Sensei_Utils; if ( ! defined( 'ABSPATH' ) ) { @@ -32,19 +35,24 @@ class Comments_Based_Lesson_Progress_Repository implements Lesson_Progress_Repos * @param int $lesson_id The lesson ID. * @param int $user_id The user ID. * - * @return Lesson_Progress The lesson progress. + * @return Lesson_Progress_Interface The lesson progress. * @throws RuntimeException When the lesson progress could not be created. */ - public function create( int $lesson_id, int $user_id ): Lesson_Progress { + public function create( int $lesson_id, int $user_id ): Lesson_Progress_Interface { $metadata = [ 'start' => current_time( 'mysql' ), ]; - $comment_id = Sensei_Utils::update_lesson_status( $user_id, $lesson_id, Lesson_Progress::STATUS_IN_PROGRESS, $metadata ); + $comment_id = Sensei_Utils::update_lesson_status( $user_id, $lesson_id, Lesson_Progress_Interface::STATUS_IN_PROGRESS, $metadata ); if ( ! $comment_id ) { throw new RuntimeException( "Can't create a lesson progress" ); } - return $this->get( $lesson_id, $user_id ); + $progress = $this->get( $lesson_id, $user_id ); + if ( ! $progress ) { + throw new RuntimeException( 'Created lesson progress not found' ); + } + + return $progress; } /** @@ -55,9 +63,9 @@ public function create( int $lesson_id, int $user_id ): Lesson_Progress { * @param int $lesson_id The lesson ID. * @param int $user_id The user ID. * - * @return Lesson_Progress|null The lesson progress or null if not found. + * @return Lesson_Progress_Interface|null The lesson progress or null if not found. */ - public function get( int $lesson_id, int $user_id ): ?Lesson_Progress { + public function get( int $lesson_id, int $user_id ): ?Lesson_Progress_Interface { $activity_args = [ 'post_id' => $lesson_id, 'user_id' => $user_id, @@ -78,7 +86,7 @@ public function get( int $lesson_id, int $user_id ): ?Lesson_Progress { $completed_at = null; } - return new Lesson_Progress( (int) $comment->comment_ID, $lesson_id, $user_id, $comment->comment_approved, $started_at, $completed_at, $comment_date, $comment_date ); + return new Comments_Based_Lesson_Progress( (int) $comment->comment_ID, $lesson_id, $user_id, $comment->comment_approved, $started_at, $completed_at, $comment_date, $comment_date ); } /** @@ -105,14 +113,29 @@ public function has( int $lesson_id, int $user_id ): bool { * * @internal * - * @param Lesson_Progress $lesson_progress The lesson progress. + * @param Lesson_Progress_Interface $lesson_progress The lesson progress. */ - public function save( Lesson_Progress $lesson_progress ): void { + public function save( Lesson_Progress_Interface $lesson_progress ): void { + $this->assert_comments_based_lesson_progress( $lesson_progress ); + $metadata = []; if ( $lesson_progress->get_started_at() ) { $metadata['start'] = $lesson_progress->get_started_at()->format( 'Y-m-d H:i:s' ); } - $comment_id = Sensei_Utils::update_lesson_status( $lesson_progress->get_user_id(), $lesson_progress->get_lesson_id(), $lesson_progress->get_status(), $metadata ); + + // We need to use internal value for status, not the one returned by the getter. + // Comments_Based_Lesson_Progress::get_status() returns a normalized status, but we need the internal one. + $reflection_class = new ReflectionClass( Comments_Based_Lesson_Progress::class ); + $status_property = $reflection_class->getProperty( 'status' ); + $status_property->setAccessible( true ); + $status = $status_property->getValue( $lesson_progress ); + + $comment_id = Sensei_Utils::update_lesson_status( + $lesson_progress->get_user_id(), + $lesson_progress->get_lesson_id(), + $status, + $metadata + ); if ( $lesson_progress->is_complete() && $comment_id ) { $comment = [ @@ -129,9 +152,9 @@ public function save( Lesson_Progress $lesson_progress ): void { * * @internal * - * @param Lesson_Progress $lesson_progress The lesson progress. + * @param Lesson_Progress_Interface $lesson_progress The lesson progress. */ - public function delete( Lesson_Progress $lesson_progress ): void { + public function delete( Lesson_Progress_Interface $lesson_progress ): void { $args = array( 'post_id' => $lesson_progress->get_lesson_id(), 'type' => 'sensei_lesson_status', @@ -229,5 +252,17 @@ private function delete_activities( array $args ): void { Sensei()->flush_comment_counts_cache( $post_id ); } } -} + /** + * Asserts that the lesson progress is a Comments_Based_Lesson_Progress. + * + * @param Lesson_Progress_Interface $lesson_progress The lesson progress. + * @throws InvalidArgumentException When the lesson progress is not a Comments_Based_Lesson_Progress. + */ + private function assert_comments_based_lesson_progress( Lesson_Progress_Interface $lesson_progress ): void { + if ( ! $lesson_progress instanceof Comments_Based_Lesson_Progress ) { + $actual_type = get_class( $lesson_progress ); + throw new InvalidArgumentException( "Expected Comments_Based_Lesson_Progress, got {$actual_type}." ); + } + } +} diff --git a/includes/internal/student-progress/lesson-progress/repositories/class-lesson-progress-repository-interface.php b/includes/internal/student-progress/lesson-progress/repositories/class-lesson-progress-repository-interface.php index 15a9750f36..7683ff6e0f 100644 --- a/includes/internal/student-progress/lesson-progress/repositories/class-lesson-progress-repository-interface.php +++ b/includes/internal/student-progress/lesson-progress/repositories/class-lesson-progress-repository-interface.php @@ -7,7 +7,7 @@ namespace Sensei\Internal\Student_Progress\Lesson_Progress\Repositories; -use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress_Interface; if ( ! defined( 'ABSPATH' ) ) { exit; @@ -28,9 +28,9 @@ interface Lesson_Progress_Repository_Interface { * * @param int $lesson_id The lesson ID. * @param int $user_id The user ID. - * @return Lesson_Progress The lesson progress. + * @return Lesson_Progress_Interface The lesson progress. */ - public function create( int $lesson_id, int $user_id ): Lesson_Progress; + public function create( int $lesson_id, int $user_id ): Lesson_Progress_Interface; /** * Finds a lesson progress by lesson and user. @@ -39,9 +39,9 @@ public function create( int $lesson_id, int $user_id ): Lesson_Progress; * * @param int $lesson_id The lesson ID. * @param int $user_id The user ID. - * @return Lesson_Progress|null The lesson progress or null if not found. + * @return Lesson_Progress_Interface|null The lesson progress or null if not found. */ - public function get( int $lesson_id, int $user_id ): ?Lesson_Progress; + public function get( int $lesson_id, int $user_id ): ?Lesson_Progress_Interface; /** * Check if a lesson progress exists. @@ -59,18 +59,18 @@ public function has( int $lesson_id, int $user_id ): bool; * * @internal * - * @param Lesson_Progress $lesson_progress The lesson progress. + * @param Lesson_Progress_Interface $lesson_progress The lesson progress. */ - public function save( Lesson_Progress $lesson_progress ): void; + public function save( Lesson_Progress_Interface $lesson_progress ): void; /** * Delete the lesson progress. * * @internal * - * @param Lesson_Progress $lesson_progress The lesson progress. + * @param Lesson_Progress_Interface $lesson_progress The lesson progress. */ - public function delete( Lesson_Progress $lesson_progress ): void; + public function delete( Lesson_Progress_Interface $lesson_progress ): void; /** * Delete all lesson progress for a lesson. diff --git a/includes/internal/student-progress/lesson-progress/repositories/class-table-reading-aggregate-lesson-progress-repository.php b/includes/internal/student-progress/lesson-progress/repositories/class-table-reading-aggregate-lesson-progress-repository.php index 7c102006d4..d409881784 100644 --- a/includes/internal/student-progress/lesson-progress/repositories/class-table-reading-aggregate-lesson-progress-repository.php +++ b/includes/internal/student-progress/lesson-progress/repositories/class-table-reading-aggregate-lesson-progress-repository.php @@ -7,7 +7,8 @@ namespace Sensei\Internal\Student_Progress\Lesson_Progress\Repositories; -use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Comments_Based_Lesson_Progress; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress_Interface; if ( ! defined( 'ABSPATH' ) ) { exit; @@ -49,9 +50,9 @@ public function __construct( Comments_Based_Lesson_Progress_Repository $comments * * @param int $lesson_id The lesson ID. * @param int $user_id The user ID. - * @return Lesson_Progress The lesson progress. + * @return Lesson_Progress_Interface The lesson progress. */ - public function create( int $lesson_id, int $user_id ): Lesson_Progress { + public function create( int $lesson_id, int $user_id ): Lesson_Progress_Interface { $this->comments_based_repository->create( $lesson_id, $user_id ); return $this->tables_based_repository->create( $lesson_id, $user_id ); } @@ -61,9 +62,9 @@ public function create( int $lesson_id, int $user_id ): Lesson_Progress { * * @param int $lesson_id The lesson ID. * @param int $user_id The user ID. - * @return Lesson_Progress|null The lesson progress. + * @return Lesson_Progress_Interface|null The lesson progress. */ - public function get( int $lesson_id, int $user_id ): ?Lesson_Progress { + public function get( int $lesson_id, int $user_id ): ?Lesson_Progress_Interface { return $this->tables_based_repository->get( $lesson_id, $user_id ); } @@ -81,9 +82,9 @@ public function has( int $lesson_id, int $user_id ): bool { /** * Save a lesson progress. * - * @param Lesson_Progress $lesson_progress The lesson progress. + * @param Lesson_Progress_Interface $lesson_progress The lesson progress. */ - public function save( Lesson_Progress $lesson_progress ): void { + public function save( Lesson_Progress_Interface $lesson_progress ): void { $this->tables_based_repository->save( $lesson_progress ); $comments_based_progress = $this->comments_based_repository->get( $lesson_progress->get_lesson_id(), @@ -95,7 +96,7 @@ public function save( Lesson_Progress $lesson_progress ): void { $lesson_progress->get_user_id() ); } - $updated_comments_based_progress = new Lesson_Progress( + $updated_comments_based_progress = new Comments_Based_Lesson_Progress( $comments_based_progress->get_id(), $lesson_progress->get_lesson_id(), $lesson_progress->get_user_id(), @@ -111,9 +112,9 @@ public function save( Lesson_Progress $lesson_progress ): void { /** * Deletes a lesson progress. * - * @param Lesson_Progress $lesson_progress The lesson progress. + * @param Lesson_Progress_Interface $lesson_progress The lesson progress. */ - public function delete( Lesson_Progress $lesson_progress ): void { + public function delete( Lesson_Progress_Interface $lesson_progress ): void { $this->tables_based_repository->delete( $lesson_progress ); $comments_based_progress = $this->comments_based_repository->get( $lesson_progress->get_lesson_id(), diff --git a/includes/internal/student-progress/lesson-progress/repositories/class-tables-based-lesson-progress-repository.php b/includes/internal/student-progress/lesson-progress/repositories/class-tables-based-lesson-progress-repository.php index e1b74044a5..f608e3edc6 100644 --- a/includes/internal/student-progress/lesson-progress/repositories/class-tables-based-lesson-progress-repository.php +++ b/includes/internal/student-progress/lesson-progress/repositories/class-tables-based-lesson-progress-repository.php @@ -9,7 +9,10 @@ use DateTimeImmutable; use DateTimeZone; -use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress; +use InvalidArgumentException; +use RuntimeException; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress_Interface; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Tables_Based_Lesson_Progress; use wpdb; if ( ! defined( 'ABSPATH' ) ) { @@ -50,9 +53,9 @@ public function __construct( wpdb $wpdb ) { * @param int $lesson_id The lesson ID. * @param int $user_id The user ID. * - * @return Lesson_Progress The lesson progress. + * @return Lesson_Progress_Interface The lesson progress. */ - public function create( int $lesson_id, int $user_id ): Lesson_Progress { + public function create( int $lesson_id, int $user_id ): Lesson_Progress_Interface { $current_datetime = new DateTimeImmutable( 'now', new DateTimeZone( 'UTC' ) ); $date_format = 'Y-m-d H:i:s'; $this->wpdb->insert( @@ -62,7 +65,7 @@ public function create( int $lesson_id, int $user_id ): Lesson_Progress { 'user_id' => $user_id, 'parent_post_id' => null, 'type' => 'lesson', - 'status' => Lesson_Progress::STATUS_IN_PROGRESS, + 'status' => Lesson_Progress_Interface::STATUS_IN_PROGRESS, 'started_at' => $current_datetime->format( $date_format ), 'completed_at' => null, 'created_at' => $current_datetime->format( $date_format ), @@ -82,11 +85,11 @@ public function create( int $lesson_id, int $user_id ): Lesson_Progress { ); $id = (int) $this->wpdb->insert_id; - return new Lesson_Progress( + return new Tables_Based_Lesson_Progress( $id, $lesson_id, $user_id, - Lesson_Progress::STATUS_IN_PROGRESS, + Lesson_Progress_Interface::STATUS_IN_PROGRESS, $current_datetime, null, $current_datetime, @@ -102,9 +105,9 @@ public function create( int $lesson_id, int $user_id ): Lesson_Progress { * @param int $lesson_id The lesson ID. * @param int $user_id The user ID. * - * @return Lesson_Progress|null The lesson progress or null if not found. + * @return Lesson_Progress_Interface|null The lesson progress or null if not found. */ - public function get( int $lesson_id, int $user_id ): ?Lesson_Progress { + public function get( int $lesson_id, int $user_id ): ?Lesson_Progress_Interface { $table_name = $this->wpdb->prefix . 'sensei_lms_progress'; $query = $this->wpdb->prepare( // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared @@ -122,7 +125,7 @@ public function get( int $lesson_id, int $user_id ): ?Lesson_Progress { $timezone = new DateTimeZone( 'UTC' ); - return new Lesson_Progress( + return new Tables_Based_Lesson_Progress( (int) $row->id, (int) $row->post_id, (int) $row->user_id, @@ -164,9 +167,11 @@ public function has( int $lesson_id, int $user_id ): bool { * * @internal * - * @param Lesson_Progress $lesson_progress The lesson progress. + * @param Lesson_Progress_Interface $lesson_progress The lesson progress. */ - public function save( Lesson_Progress $lesson_progress ): void { + public function save( Lesson_Progress_Interface $lesson_progress ): void { + $this->assert_tables_based_lesson_progress( $lesson_progress ); + $updated_at = new DateTimeImmutable( 'now', new DateTimeZone( 'UTC' ) ); $lesson_progress->set_updated_at( $updated_at ); @@ -199,9 +204,9 @@ public function save( Lesson_Progress $lesson_progress ): void { * * @internal * - * @param Lesson_Progress $lesson_progress The lesson progress. + * @param Lesson_Progress_Interface $lesson_progress The lesson progress. */ - public function delete( Lesson_Progress $lesson_progress ): void { + public function delete( Lesson_Progress_Interface $lesson_progress ): void { $this->wpdb->delete( $this->wpdb->prefix . 'sensei_lms_progress', [ @@ -291,4 +296,17 @@ public function count( int $course_id, int $user_id ): int { return (int) $count; } + + /** + * Asserts that the lesson progress is a Tables_Based_Lesson_Progress. + * + * @param Lesson_Progress_Interface $lesson_progress The lesson progress. + * @throws InvalidArgumentException If the lesson progress is not a Tables_Based_Lesson_Progress. + */ + private function assert_tables_based_lesson_progress( Lesson_Progress_Interface $lesson_progress ): void { + if ( ! $lesson_progress instanceof Tables_Based_Lesson_Progress ) { + $actual_type = get_class( $lesson_progress ); + throw new InvalidArgumentException( "Expected Tables_Based_Lesson_Progress, got {$actual_type}." ); + } + } } diff --git a/includes/internal/student-progress/quiz-progress/models/class-comments-based-quiz-progress.php b/includes/internal/student-progress/quiz-progress/models/class-comments-based-quiz-progress.php new file mode 100644 index 0000000000..efeda24778 --- /dev/null +++ b/includes/internal/student-progress/quiz-progress/models/class-comments-based-quiz-progress.php @@ -0,0 +1,46 @@ +status, $supported_statuses, true ) + ? $this->status + : self::STATUS_IN_PROGRESS; + + return $status; + } +} diff --git a/includes/internal/student-progress/quiz-progress/models/class-quiz-progress.php b/includes/internal/student-progress/quiz-progress/models/class-quiz-progress-abstract.php similarity index 89% rename from includes/internal/student-progress/quiz-progress/models/class-quiz-progress.php rename to includes/internal/student-progress/quiz-progress/models/class-quiz-progress-abstract.php index 7cb0de3cba..c49b98d40f 100644 --- a/includes/internal/student-progress/quiz-progress/models/class-quiz-progress.php +++ b/includes/internal/student-progress/quiz-progress/models/class-quiz-progress-abstract.php @@ -1,6 +1,6 @@ tables_based_repository->create( $quiz_id, $user_id ); return $this->comments_based_repository->create( $quiz_id, $user_id ); } @@ -71,9 +72,9 @@ public function create( int $quiz_id, int $user_id ): Quiz_Progress { * * @param int $quiz_id The quiz ID. * @param int $user_id The user ID. - * @return Quiz_Progress|null The quiz progress or null if it does not exist. + * @return Quiz_Progress_Interface|null The quiz progress or null if it does not exist. */ - public function get( int $quiz_id, int $user_id ): ?Quiz_Progress { + public function get( int $quiz_id, int $user_id ): ?Quiz_Progress_Interface { return $this->comments_based_repository->get( $quiz_id, $user_id ); } @@ -95,9 +96,9 @@ public function has( int $quiz_id, int $user_id ): bool { * * @internal * - * @param Quiz_Progress $quiz_progress The quiz progress. + * @param Quiz_Progress_Interface $quiz_progress The quiz progress. */ - public function save( Quiz_Progress $quiz_progress ): void { + public function save( Quiz_Progress_Interface $quiz_progress ): void { $this->comments_based_repository->save( $quiz_progress ); $tables_based_progress = $this->tables_based_repository->get( $quiz_progress->get_quiz_id(), $quiz_progress->get_user_id() ); @@ -118,7 +119,7 @@ public function save( Quiz_Progress $quiz_progress ): void { $completed_at = new \DateTimeImmutable( '@' . $quiz_progress->get_completed_at()->getTimestamp() ); } - $progress_to_save = new Quiz_Progress( + $progress_to_save = new Tables_Based_Quiz_Progress( $tables_based_progress->get_id(), $tables_based_progress->get_quiz_id(), $tables_based_progress->get_user_id(), @@ -136,9 +137,9 @@ public function save( Quiz_Progress $quiz_progress ): void { * * @internal * - * @param Quiz_Progress $quiz_progress The quiz progress. + * @param Quiz_Progress_Interface $quiz_progress The quiz progress. */ - public function delete( Quiz_Progress $quiz_progress ): void { + public function delete( Quiz_Progress_Interface $quiz_progress ): void { $this->comments_based_repository->delete( $quiz_progress ); $this->tables_based_repository->delete( $quiz_progress ); } diff --git a/includes/internal/student-progress/quiz-progress/repositories/class-comments-based-quiz-progress-repository.php b/includes/internal/student-progress/quiz-progress/repositories/class-comments-based-quiz-progress-repository.php index 0dfbbceabc..3353653468 100644 --- a/includes/internal/student-progress/quiz-progress/repositories/class-comments-based-quiz-progress-repository.php +++ b/includes/internal/student-progress/quiz-progress/repositories/class-comments-based-quiz-progress-repository.php @@ -8,7 +8,8 @@ namespace Sensei\Internal\Student_Progress\Quiz_Progress\Repositories; use DateTime; -use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Comments_Based_Quiz_Progress; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress_Interface; use Sensei_Utils; if ( ! defined( 'ABSPATH' ) ) { @@ -31,10 +32,10 @@ class Comments_Based_Quiz_Progress_Repository implements Quiz_Progress_Repositor * * @param int $quiz_id Quiz identifier. * @param int $user_id User identifier. - * @return Quiz_Progress + * @return Quiz_Progress_Interface * @throws \RuntimeException When the quiz progress doesn't exist. In this implementation we re-use lesson progress. */ - public function create( int $quiz_id, int $user_id ): Quiz_Progress { + public function create( int $quiz_id, int $user_id ): Quiz_Progress_Interface { $progress = $this->get( $quiz_id, $user_id ); if ( ! $progress ) { /** @@ -54,9 +55,9 @@ public function create( int $quiz_id, int $user_id ): Quiz_Progress { * * @param int $quiz_id Quiz identifier. * @param int $user_id User identifier. - * @return Quiz_Progress + * @return Quiz_Progress_Interface */ - public function get( int $quiz_id, int $user_id ): ?Quiz_Progress { + public function get( int $quiz_id, int $user_id ): ?Quiz_Progress_Interface { $lesson_id = Sensei()->quiz->get_lesson_id( $quiz_id ); if ( ! $lesson_id ) { return null; @@ -72,20 +73,9 @@ public function get( int $quiz_id, int $user_id ): ?Quiz_Progress { return null; } - $supported_statuses = [ - Quiz_Progress::STATUS_IN_PROGRESS, - Quiz_Progress::STATUS_FAILED, - Quiz_Progress::STATUS_GRADED, - Quiz_Progress::STATUS_PASSED, - Quiz_Progress::STATUS_UNGRADED, - ]; - $comment_date = new DateTime( $comment->comment_date, wp_timezone() ); $meta_start = get_comment_meta( $comment->comment_ID, 'start', true ); $started_at = ! empty( $meta_start ) ? new DateTime( $meta_start, wp_timezone() ) : current_datetime(); - $status = in_array( $comment->comment_approved, $supported_statuses, true ) - ? $comment->comment_approved - : Quiz_Progress::STATUS_IN_PROGRESS; if ( in_array( $comment->comment_approved, [ 'complete', 'passed', 'graded' ], true ) ) { $completed_at = $comment_date; @@ -93,7 +83,7 @@ public function get( int $quiz_id, int $user_id ): ?Quiz_Progress { $completed_at = null; } - return new Quiz_Progress( (int) $comment->comment_ID, $quiz_id, $user_id, $status, $started_at, $completed_at, $comment_date, $comment_date ); + return new Comments_Based_Quiz_Progress( (int) $comment->comment_ID, $quiz_id, $user_id, $comment->comment_approved, $started_at, $completed_at, $comment_date, $comment_date ); } /** @@ -122,15 +112,25 @@ public function has( int $quiz_id, int $user_id ): bool { * * @internal * - * @param Quiz_Progress $quiz_progress Quiz progress. + * @param Quiz_Progress_Interface $quiz_progress Quiz progress. */ - public function save( Quiz_Progress $quiz_progress ): void { + public function save( Quiz_Progress_Interface $quiz_progress ): void { + $this->assert_comments_based_quiz_progress( $quiz_progress ); + $lesson_id = Sensei()->quiz->get_lesson_id( $quiz_progress->get_quiz_id() ); $metadata = []; if ( $quiz_progress->get_started_at() ) { $metadata['start'] = $quiz_progress->get_started_at()->format( 'Y-m-d H:i:s' ); } - Sensei_Utils::update_lesson_status( $quiz_progress->get_user_id(), $lesson_id, $quiz_progress->get_status(), $metadata ); + + // We need to use internal value for status, not the one returned by the getter. + // Commets-based `get_status` method excludes lesson-progress `complete` status, that we still need while saving. + $reflection_class = new \ReflectionClass( Comments_Based_Quiz_Progress::class ); + $status_property = $reflection_class->getProperty( 'status' ); + $status_property->setAccessible( true ); + $status = $status_property->getValue( $quiz_progress ); + + Sensei_Utils::update_lesson_status( $quiz_progress->get_user_id(), $lesson_id, $status, $metadata ); } /** @@ -138,9 +138,9 @@ public function save( Quiz_Progress $quiz_progress ): void { * * @internal * - * @param Quiz_Progress $quiz_progress Quiz progress. + * @param Quiz_Progress_Interface $quiz_progress Quiz progress. */ - public function delete( Quiz_Progress $quiz_progress ): void { + public function delete( Quiz_Progress_Interface $quiz_progress ): void { Sensei_Utils::sensei_delete_quiz_answers( $quiz_progress->get_quiz_id(), $quiz_progress->get_user_id() ); } @@ -192,4 +192,17 @@ private function delete_grade_and_answers( $comment_id ): void { delete_comment_meta( $comment_id, 'quiz_answers' ); delete_comment_meta( $comment_id, 'grade' ); } + + /** + * Assert that the quiz progress is a Comments_Based_Quiz_Progress. + * + * @param Quiz_Progress_Interface $quiz_progress Quiz progress. + * @throws \InvalidArgumentException When the quiz progress is not a Comments_Based_Quiz_Progress. + */ + private function assert_comments_based_quiz_progress( Quiz_Progress_Interface $quiz_progress ): void { + if ( ! $quiz_progress instanceof Comments_Based_Quiz_Progress ) { + $actual_type = get_class( $quiz_progress ); + throw new \InvalidArgumentException( "Expected Comments_Based_Quiz_Progress, got {$actual_type}." ); + } + } } diff --git a/includes/internal/student-progress/quiz-progress/repositories/class-quiz-progress-repository-interface.php b/includes/internal/student-progress/quiz-progress/repositories/class-quiz-progress-repository-interface.php index c22ac39c73..b85c3de771 100644 --- a/includes/internal/student-progress/quiz-progress/repositories/class-quiz-progress-repository-interface.php +++ b/includes/internal/student-progress/quiz-progress/repositories/class-quiz-progress-repository-interface.php @@ -7,7 +7,7 @@ namespace Sensei\Internal\Student_Progress\Quiz_Progress\Repositories; -use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress_Interface; if ( ! defined( 'ABSPATH' ) ) { exit; @@ -28,9 +28,9 @@ interface Quiz_Progress_Repository_Interface { * * @param int $quiz_id Quiz identifier. * @param int $user_id User identifier. - * @return Quiz_Progress + * @return Quiz_Progress_Interface */ - public function create( int $quiz_id, int $user_id ): Quiz_Progress; + public function create( int $quiz_id, int $user_id ): Quiz_Progress_Interface; /** * Find a quiz progress by quiz and user identifiers. @@ -39,9 +39,9 @@ public function create( int $quiz_id, int $user_id ): Quiz_Progress; * * @param int $quiz_id Quiz identifier. * @param int $user_id User identifier. - * @return Quiz_Progress + * @return Quiz_Progress_Interface|null */ - public function get( int $quiz_id, int $user_id ): ?Quiz_Progress; + public function get( int $quiz_id, int $user_id ): ?Quiz_Progress_Interface; /** * Check if a quiz progress exists. @@ -59,18 +59,18 @@ public function has( int $quiz_id, int $user_id ): bool; * * @internal * - * @param Quiz_Progress $quiz_progress Quiz progress. + * @param Quiz_Progress_Interface $quiz_progress Quiz progress. */ - public function save( Quiz_Progress $quiz_progress ): void; + public function save( Quiz_Progress_Interface $quiz_progress ): void; /** * Delete the quiz progress. * * @internal * - * @param Quiz_Progress $quiz_progress The quiz progress. + * @param Quiz_Progress_Interface $quiz_progress The quiz progress. */ - public function delete( Quiz_Progress $quiz_progress ): void; + public function delete( Quiz_Progress_Interface $quiz_progress ): void; /** * Delete all quiz progress for a quiz. diff --git a/includes/internal/student-progress/quiz-progress/repositories/class-table-reading-aggregate-quiz-progress-repository.php b/includes/internal/student-progress/quiz-progress/repositories/class-table-reading-aggregate-quiz-progress-repository.php index 3e92e03f8d..f85ed18d48 100644 --- a/includes/internal/student-progress/quiz-progress/repositories/class-table-reading-aggregate-quiz-progress-repository.php +++ b/includes/internal/student-progress/quiz-progress/repositories/class-table-reading-aggregate-quiz-progress-repository.php @@ -7,7 +7,8 @@ namespace Sensei\Internal\Student_Progress\Quiz_Progress\Repositories; -use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Comments_Based_Quiz_Progress; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress_Interface; if ( ! defined( 'ABSPATH' ) ) { exit; @@ -54,9 +55,9 @@ public function __construct( * * @param int $quiz_id The quiz ID. * @param int $user_id The user ID. - * @return Quiz_Progress The quiz progress. + * @return Quiz_Progress_Interface The quiz progress. */ - public function create( int $quiz_id, int $user_id ): Quiz_Progress { + public function create( int $quiz_id, int $user_id ): Quiz_Progress_Interface { $this->comments_based_repository->create( $quiz_id, $user_id ); return $this->tables_based_repository->create( $quiz_id, $user_id ); } @@ -66,9 +67,9 @@ public function create( int $quiz_id, int $user_id ): Quiz_Progress { * * @param int $quiz_id The quiz ID. * @param int $user_id The user ID. - * @return Quiz_Progress|null The quiz progress or null if it does not exist. + * @return Quiz_Progress_Interface|null The quiz progress or null if it does not exist. */ - public function get( int $quiz_id, int $user_id ): ?Quiz_Progress { + public function get( int $quiz_id, int $user_id ): ?Quiz_Progress_Interface { return $this->tables_based_repository->get( $quiz_id, $user_id ); } @@ -86,9 +87,9 @@ public function has( int $quiz_id, int $user_id ): bool { /** * Save quiz progress. * - * @param Quiz_Progress $quiz_progress The quiz progress. + * @param Quiz_Progress_Interface $quiz_progress The quiz progress. */ - public function save( Quiz_Progress $quiz_progress ): void { + public function save( Quiz_Progress_Interface $quiz_progress ): void { $this->tables_based_repository->save( $quiz_progress ); $comments_based_quiz_progress = $this->comments_based_repository->get( $quiz_progress->get_quiz_id(), $quiz_progress->get_user_id() ); if ( ! $comments_based_quiz_progress ) { @@ -97,7 +98,7 @@ public function save( Quiz_Progress $quiz_progress ): void { $quiz_progress->get_user_id() ); } - $updated_comments_based_quiz_progress = new Quiz_Progress( + $updated_comments_based_quiz_progress = new Comments_Based_Quiz_Progress( $comments_based_quiz_progress->get_id(), $quiz_progress->get_quiz_id(), $quiz_progress->get_user_id(), @@ -113,9 +114,9 @@ public function save( Quiz_Progress $quiz_progress ): void { /** * Deletes a quiz progress. * - * @param Quiz_Progress $quiz_progress The quiz progress. + * @param Quiz_Progress_Interface $quiz_progress The quiz progress. */ - public function delete( Quiz_Progress $quiz_progress ): void { + public function delete( Quiz_Progress_Interface $quiz_progress ): void { $this->tables_based_repository->delete( $quiz_progress ); $coments_based_quiz_progress = $this->comments_based_repository->get( $quiz_progress->get_quiz_id(), $quiz_progress->get_user_id() ); if ( $coments_based_quiz_progress ) { @@ -142,5 +143,4 @@ public function delete_for_user( int $user_id ): void { $this->comments_based_repository->delete_for_user( $user_id ); $this->tables_based_repository->delete_for_user( $user_id ); } - } diff --git a/includes/internal/student-progress/quiz-progress/repositories/class-tables-based-quiz-progress-repository.php b/includes/internal/student-progress/quiz-progress/repositories/class-tables-based-quiz-progress-repository.php index 25c72de1b1..b137ea73ee 100644 --- a/includes/internal/student-progress/quiz-progress/repositories/class-tables-based-quiz-progress-repository.php +++ b/includes/internal/student-progress/quiz-progress/repositories/class-tables-based-quiz-progress-repository.php @@ -9,7 +9,8 @@ use DateTimeImmutable; use DateTimeZone; -use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress_Interface; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Tables_Based_Quiz_Progress; use wpdb; if ( ! defined( 'ABSPATH' ) ) { @@ -49,9 +50,9 @@ public function __construct( wpdb $wpdb ) { * * @param int $quiz_id Quiz identifier. * @param int $user_id User identifier. - * @return Quiz_Progress + * @return Quiz_Progress_Interface */ - public function create( int $quiz_id, int $user_id ): Quiz_Progress { + public function create( int $quiz_id, int $user_id ): Quiz_Progress_Interface { $current_datetime = new DateTimeImmutable( 'now', new DateTimeZone( 'UTC' ) ); $date_format = 'Y-m-d H:i:s'; $this->wpdb->insert( @@ -61,7 +62,7 @@ public function create( int $quiz_id, int $user_id ): Quiz_Progress { 'user_id' => $user_id, 'parent_post_id' => null, 'type' => 'quiz', - 'status' => Quiz_Progress::STATUS_IN_PROGRESS, + 'status' => Quiz_Progress_Interface::STATUS_IN_PROGRESS, 'started_at' => $current_datetime->format( $date_format ), 'completed_at' => null, 'created_at' => $current_datetime->format( $date_format ), @@ -81,11 +82,11 @@ public function create( int $quiz_id, int $user_id ): Quiz_Progress { ); $id = (int) $this->wpdb->insert_id; - return new Quiz_Progress( + return new Tables_Based_Quiz_Progress( $id, $quiz_id, $user_id, - Quiz_Progress::STATUS_IN_PROGRESS, + Quiz_Progress_Interface::STATUS_IN_PROGRESS, $current_datetime, null, $current_datetime, @@ -100,9 +101,9 @@ public function create( int $quiz_id, int $user_id ): Quiz_Progress { * * @param int $quiz_id Quiz identifier. * @param int $user_id User identifier. - * @return Quiz_Progress + * @return Quiz_Progress_Interface|null */ - public function get( int $quiz_id, int $user_id ): ?Quiz_Progress { + public function get( int $quiz_id, int $user_id ): ?Quiz_Progress_Interface { $table_name = $this->wpdb->prefix . 'sensei_lms_progress'; $query = $this->wpdb->prepare( // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared @@ -120,7 +121,7 @@ public function get( int $quiz_id, int $user_id ): ?Quiz_Progress { $timezone = new DateTimeZone( 'UTC' ); - return new Quiz_Progress( + return new Tables_Based_Quiz_Progress( (int) $row->id, (int) $row->post_id, (int) $row->user_id, @@ -162,9 +163,11 @@ public function has( int $quiz_id, int $user_id ): bool { * * @internal * - * @param Quiz_Progress $quiz_progress Quiz progress. + * @param Quiz_Progress_Interface $quiz_progress Quiz progress. */ - public function save( Quiz_Progress $quiz_progress ): void { + public function save( Quiz_Progress_Interface $quiz_progress ): void { + $this->assert_tables_based_quiz_progress( $quiz_progress ); + $updated_at = new DateTimeImmutable( 'now', new DateTimeZone( 'UTC' ) ); $quiz_progress->set_updated_at( $updated_at ); @@ -197,9 +200,9 @@ public function save( Quiz_Progress $quiz_progress ): void { * * @internal * - * @param Quiz_Progress $quiz_progress Quiz progress. + * @param Quiz_Progress_Interface $quiz_progress Quiz progress. */ - public function delete( Quiz_Progress $quiz_progress ): void { + public function delete( Quiz_Progress_Interface $quiz_progress ): void { $this->wpdb->delete( $this->wpdb->prefix . 'sensei_lms_progress', [ @@ -256,4 +259,17 @@ public function delete_for_user( int $user_id ): void { ] ); } + + /** + * Assert that the quiz progress is a Tables_Based_Quiz_Progress. + * + * @param Quiz_Progress_Interface $quiz_progress Quiz progress. + * @throws \InvalidArgumentException If the quiz progress is not a Tables_Based_Quiz_Progress. + */ + private function assert_tables_based_quiz_progress( Quiz_Progress_Interface $quiz_progress ): void { + if ( ! $quiz_progress instanceof Tables_Based_Quiz_Progress ) { + $actual_type = get_class( $quiz_progress ); + throw new \InvalidArgumentException( "Expected Tables_Based_Quiz_Progress, got {$actual_type}." ); + } + } } diff --git a/includes/rest-api/class-sensei-rest-api-extensions-controller.php b/includes/rest-api/class-sensei-rest-api-extensions-controller.php index 6191be836f..cef35f9862 100644 --- a/includes/rest-api/class-sensei-rest-api-extensions-controller.php +++ b/includes/rest-api/class-sensei-rest-api-extensions-controller.php @@ -379,7 +379,7 @@ function ( $plugin ) { $plugins ); - $response_json = []; + $response_json = []; $response_json[ $extensions_key ] = array_values( $mapped_plugins ); $response = new WP_REST_Response(); diff --git a/tests/unit-tests/internal/emails/generators/test-class-student-completes-lesson.php b/tests/unit-tests/internal/emails/generators/test-class-student-completes-lesson.php index 58cfbb8fd1..861cb351cf 100644 --- a/tests/unit-tests/internal/emails/generators/test-class-student-completes-lesson.php +++ b/tests/unit-tests/internal/emails/generators/test-class-student-completes-lesson.php @@ -5,6 +5,7 @@ use Sensei\Internal\Emails\Email_Repository; use Sensei\Internal\Emails\Generators\Student_Completes_Lesson; use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress_Interface; use Sensei\Internal\Student_Progress\Lesson_Progress\Repositories\Lesson_Progress_Repository_Interface; use Sensei_Lesson; @@ -109,8 +110,8 @@ public function testStudentCompletedLessonMailToTeacher_LessonNotCompleted_Doesn /* Arrange. */ $email_repository = $this->createMock( Email_Repository::class ); - $lesson_progress = $this->createMock( Lesson_Progress::class ); - $lesson_progress->method( 'get_status' )->willReturn( 'in-progress' ); + $lesson_progress = $this->createMock( Lesson_Progress_Interface::class ); + $lesson_progress->method( 'is_complete' )->willReturn( false ); $lesson_progress_repository = $this->createMock( Lesson_Progress_Repository_Interface::class ); $lesson_progress_repository->method( 'get' )->with( 2, 1 )->willReturn( $lesson_progress ); @@ -162,8 +163,8 @@ public function testStudentCompletedLessonMailToTeacher_LessonCompleted_CallsSen ); $email_repository = $this->createMock( Email_Repository::class ); - $lesson_progress = $this->createMock( Lesson_Progress::class ); - $lesson_progress->method( 'get_status' )->willReturn( 'complete' ); + $lesson_progress = $this->createMock( Lesson_Progress_Interface::class ); + $lesson_progress->method( 'is_complete' )->willReturn( true ); $lesson_progress_repository = $this->createMock( Lesson_Progress_Repository_Interface::class ); $lesson_progress_repository->method( 'get' )->with( $lesson_id, $student_id )->willReturn( $lesson_progress ); @@ -240,8 +241,8 @@ public function testStudentCompletedLessonMailToTeacher_LessonCompletedAndTeache ); $email_repository = $this->createMock( Email_Repository::class ); - $lesson_progress = $this->createMock( Lesson_Progress::class ); - $lesson_progress->method( 'get_status' )->willReturn( 'complete' ); + $lesson_progress = $this->createMock( Lesson_Progress_Interface::class ); + $lesson_progress->method( 'is_complete' )->willReturn( true ); $lesson_progress_repository = $this->createMock( Lesson_Progress_Repository_Interface::class ); $lesson_progress_repository->method( 'get' )->with( $lesson_id, $student_id )->willReturn( $lesson_progress ); diff --git a/tests/unit-tests/internal/student-progress/course-progress/models/test-class-comments-based-course-progress.php b/tests/unit-tests/internal/student-progress/course-progress/models/test-class-comments-based-course-progress.php new file mode 100644 index 0000000000..326a2f8558 --- /dev/null +++ b/tests/unit-tests/internal/student-progress/course-progress/models/test-class-comments-based-course-progress.php @@ -0,0 +1,76 @@ +create_progress(); + + /* Act. */ + $progress->start( $started_at ); + + /* Assert. */ + self::assertSame( $started_at, $progress->get_started_at() ); + } + + public function testGetStatus_WhenStartCalled_ReturnsMatchingStatus(): void { + /* Arrange. */ + $progress = $this->create_progress(); + + /* Act. */ + $progress->start(); + + /* Assert. */ + self::assertSame( 'in-progress', $progress->get_status() ); + } + + public function testGetCompletedAt_WhenCompleteWithCompletedAtCalled_ReturnsSameCompletedAt(): void { + /* Arrange. */ + $completed_at = new \DateTimeImmutable(); + $progress = $this->create_progress(); + + /* Act. */ + $progress->complete( $completed_at ); + + /* Assert. */ + self::assertSame( $completed_at, $progress->get_completed_at() ); + } + + public function testGetStatus_WhenCompleteCalled_ReturnsMatchingStatus(): void { + /* Arrange. */ + $progress = $this->create_progress(); + + /* Act. */ + $progress->complete(); + + /* Assert. */ + self::assertSame( 'complete', $progress->get_status() ); + } + + private function create_progress(): Comments_Based_Course_Progress { + return new Comments_Based_Course_Progress( + 1, + 2, + 3, + 'complete', + new \DateTime( '2020-01-01 00:00:01' ), + new \DateTime( '2020-01-01 00:00:02' ), + new \DateTime( '2020-01-01 00:00:00' ), + new \DateTime( '2020-01-01 00:00:03' ) + ); + } +} diff --git a/tests/unit-tests/internal/student-progress/course-progress/models/test-class-course-progress.php b/tests/unit-tests/internal/student-progress/course-progress/models/test-class-tables-based-course-progress.php similarity index 71% rename from tests/unit-tests/internal/student-progress/course-progress/models/test-class-course-progress.php rename to tests/unit-tests/internal/student-progress/course-progress/models/test-class-tables-based-course-progress.php index 0db61037fd..4c490b8853 100644 --- a/tests/unit-tests/internal/student-progress/course-progress/models/test-class-course-progress.php +++ b/tests/unit-tests/internal/student-progress/course-progress/models/test-class-tables-based-course-progress.php @@ -1,24 +1,24 @@ createProgress(); + $progress = $this->create_progress(); /* Act. */ $progress->start( $started_at ); @@ -29,7 +29,7 @@ public function testGetStartedAt_WhenStartWithStartedAtCalled_ReturnsSameStarted public function testGetStatus_WhenStartCalled_ReturnsMatchingStatus(): void { /* Arrange. */ - $progress = $this->createProgress(); + $progress = $this->create_progress(); /* Act. */ $progress->start(); @@ -41,7 +41,7 @@ public function testGetStatus_WhenStartCalled_ReturnsMatchingStatus(): void { public function testGetCompletedAt_WhenCompleteWithCompletedAtCalled_ReturnsSameCompletedAt(): void { /* Arrange. */ $completed_at = new \DateTimeImmutable(); - $progress = $this->createProgress(); + $progress = $this->create_progress(); /* Act. */ $progress->complete( $completed_at ); @@ -52,7 +52,7 @@ public function testGetCompletedAt_WhenCompleteWithCompletedAtCalled_ReturnsSame public function testGetStatus_WhenCompleteCalled_ReturnsMatchingStatus(): void { /* Arrange. */ - $progress = $this->createProgress(); + $progress = $this->create_progress(); /* Act. */ $progress->complete(); @@ -61,8 +61,8 @@ public function testGetStatus_WhenCompleteCalled_ReturnsMatchingStatus(): void { self::assertSame( 'complete', $progress->get_status() ); } - private function createProgress(): Course_Progress { - return new Course_Progress( + private function create_progress(): Tables_Based_Course_Progress { + return new Tables_Based_Course_Progress( 1, 2, 3, diff --git a/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-comment-reading-aggregate-course-progress-repository.php b/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-comment-reading-aggregate-course-progress-repository.php index 423f23d1cf..133976a39f 100644 --- a/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-comment-reading-aggregate-course-progress-repository.php +++ b/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-comment-reading-aggregate-course-progress-repository.php @@ -2,7 +2,9 @@ namespace SenseiTest\Internal\Student_Progress\Course_Progress\Repositories; -use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Comments_Based_Course_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress_Interface; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Tables_Based_Course_Progress; use Sensei\Internal\Student_Progress\Course_Progress\Repositories\Comment_Reading_Aggregate_Course_Progress_Repository; use Sensei\Internal\Student_Progress\Course_Progress\Repositories\Comments_Based_Course_Progress_Repository; use Sensei\Internal\Student_Progress\Course_Progress\Repositories\Tables_Based_Course_Progress_Repository; @@ -66,11 +68,12 @@ public function testHas_Always_CallsCommentsBasedRepository(): void { public function testSave_Always_CallsCommentsBasedRepository(): void { /* Arrange. */ - $progress = $this->create_course_progress(); + $progress = $this->create_comments_based_course_progress(); $comments_based = $this->createMock( Comments_Based_Course_Progress_Repository::class ); - $tables_based = $this->createMock( Tables_Based_Course_Progress_Repository::class ); - $tables_based->method( 'get' )->willReturn( $progress ); + $tables_based_progress = $this->create_tables_based_course_progress(); + $tables_based = $this->createMock( Tables_Based_Course_Progress_Repository::class ); + $tables_based->method( 'get' )->willReturn( $tables_based_progress ); $repository = new Comment_Reading_Aggregate_Course_Progress_Repository( $comments_based, $tables_based ); @@ -84,8 +87,8 @@ public function testSave_Always_CallsCommentsBasedRepository(): void { public function testSave_TablesBasedProgressFound_CallsTablesBasedRepository(): void { /* Arrange. */ - $progress = $this->create_course_progress(); - $found_progress = $this->create_course_progress(); + $progress = $this->create_comments_based_course_progress(); + $found_progress = $this->create_tables_based_course_progress(); $comments_based = $this->createMock( Comments_Based_Course_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Course_Progress_Repository::class ); @@ -102,7 +105,7 @@ public function testSave_TablesBasedProgressFound_CallsTablesBasedRepository(): ->method( 'save' ) ->with( $this->callback( - function ( Course_Progress $progress_to_save ) use ( $progress, $found_progress ) { + function ( Tables_Based_Course_Progress $progress_to_save ) use ( $progress, $found_progress ) { self::assertNotSame( $progress, $progress_to_save, 'We should create a new progress based on a found one: not using passed for saving.' ); self::assertNotSame( $found_progress, $progress_to_save, 'We should create a new progress based on a found one: not the found one itself.' ); return true; @@ -114,9 +117,9 @@ function ( Course_Progress $progress_to_save ) use ( $progress, $found_progress public function testSave_TablesBasedProgressFound_ConvertsTimeToUtc(): void { /* Arrange. */ - $progress = $this->create_course_progress( new \DateTimeImmutable( '2020-01-01 03:00:00', new \DateTimeZone( 'GMT+03:00' ) ) ); + $progress = $this->create_comments_based_course_progress( new \DateTimeImmutable( '2020-01-01 03:00:00', new \DateTimeZone( 'GMT+03:00' ) ) ); - $found_progress = $this->create_course_progress(); + $found_progress = $this->create_tables_based_course_progress(); $comments_based = $this->createMock( Comments_Based_Course_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Course_Progress_Repository::class ); @@ -133,7 +136,7 @@ public function testSave_TablesBasedProgressFound_ConvertsTimeToUtc(): void { ->method( 'save' ) ->with( $this->callback( - function ( Course_Progress $progress_to_save ) { + function ( Course_Progress_Interface $progress_to_save ) { return '2020-01-01 00:00:00' === $progress_to_save->get_started_at()->format( 'Y-m-d H:i:s' ); } ) @@ -143,8 +146,8 @@ function ( Course_Progress $progress_to_save ) { public function testSave_TablesBasedProgressNotFound_CreatesTablesBasedProgress(): void { /* Arrange. */ - $progress = $this->create_course_progress(); - $created_progress = $this->create_course_progress(); + $progress = $this->create_comments_based_course_progress(); + $created_progress = $this->create_tables_based_course_progress(); $comments_based = $this->createMock( Comments_Based_Course_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Course_Progress_Repository::class ); @@ -166,7 +169,7 @@ public function testSave_TablesBasedProgressNotFound_CreatesTablesBasedProgress( public function testDelete_Always_CallsTablesBasedRepository(): void { /* Arrange. */ - $progress = $this->create_course_progress(); + $progress = $this->create_comments_based_course_progress(); $comments_based = $this->createMock( Comments_Based_Course_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Course_Progress_Repository::class ); @@ -183,7 +186,7 @@ public function testDelete_Always_CallsTablesBasedRepository(): void { public function testDelete_Always_CallsCommentsBasedRepository(): void { /* Arrange. */ - $progress = $this->create_course_progress(); + $progress = $this->create_comments_based_course_progress(); $comments_based = $this->createMock( Comments_Based_Course_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Course_Progress_Repository::class ); @@ -264,13 +267,32 @@ public function testDeleteForUser_Always_CallsCommentsBasedRepository(): void { } /** - * Creates a course progress object. + * Creates a comments-based course progress object. * * @param \DateTimeInterface|null $started_at Started at date. - * @return Course_Progress + * @return Comments_Based_Course_Progress */ - public function create_course_progress( $started_at = null ): Course_Progress { - return new Course_Progress( + public function create_comments_based_course_progress( $started_at = null ): Comments_Based_Course_Progress { + return new Comments_Based_Course_Progress( + 1, + 2, + 3, + 'in-progress', + $started_at ?? new \DateTimeImmutable(), + new \DateTimeImmutable(), + new \DateTimeImmutable(), + new \DateTimeImmutable() + ); + } + + /** + * Creates a tables-based course progress object. + * + * @param \DateTimeInterface|null $started_at Started at date. + * @return Tables_Based_Course_Progress + */ + public function create_tables_based_course_progress( $started_at = null ): Tables_Based_Course_Progress { + return new Tables_Based_Course_Progress( 1, 2, 3, diff --git a/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-comments-based-course-progress-repository.php b/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-comments-based-course-progress-repository.php index 663933e515..73e0ab7baf 100644 --- a/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-comments-based-course-progress-repository.php +++ b/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-comments-based-course-progress-repository.php @@ -2,7 +2,7 @@ namespace SenseiTest\Internal\Student_Progress\Course_Progress\Repositories; -use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress_Interface; use Sensei\Internal\Student_Progress\Course_Progress\Repositories\Comments_Based_Course_Progress_Repository; /** @@ -197,7 +197,18 @@ public function testDeleteForUser_WhenUserGiven_DeletesProgressForUser(): void { self::assertTrue( $repository->has( $course_id, $user_id ) ); } - private function export_progress( Course_Progress $progress ): array { + public function testSave_CommentsBasedProgressGiven_ThrowsException(): void { + /* Arrange. */ + $progress = $this->createMock( Course_Progress_Interface::class ); + $repository = new Comments_Based_Course_Progress_Repository(); + + /* Expect & Act. */ + $this->expectException( \InvalidArgumentException::class ); + $this->expectExceptionMessage( 'Expected Comments_Based_Course_Progress, got ' . get_class( $progress ) . '.' ); + $repository->save( $progress ); + } + + private function export_progress( Course_Progress_Interface $progress ): array { return [ 'user_id' => $progress->get_user_id(), 'course_id' => $progress->get_course_id(), diff --git a/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-table-reading-aggregate-course-progress-repository.php b/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-table-reading-aggregate-course-progress-repository.php index 5ca91ffeaf..31c70bbdba 100644 --- a/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-table-reading-aggregate-course-progress-repository.php +++ b/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-table-reading-aggregate-course-progress-repository.php @@ -2,7 +2,8 @@ namespace SenseiTest\Internal\Student_Progress\Course_Progress\Repositories; -use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Comments_Based_Course_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Tables_Based_Course_Progress; use Sensei\Internal\Student_Progress\Course_Progress\Repositories\Table_Reading_Aggregate_Course_Progress_Repository; use Sensei\Internal\Student_Progress\Course_Progress\Repositories\Tables_Based_Course_Progress_Repository; use Sensei\Internal\Student_Progress\Course_Progress\Repositories\Comments_Based_Course_Progress_Repository; @@ -12,7 +13,7 @@ public function testCreate_Always_ReturnsTablesBasedVersion(): void { /* Arrange. */ $comments_based_repository = $this->createMock( Comments_Based_Course_Progress_Repository::class ); - $created_progress = $this->createMock( \Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress::class ); + $created_progress = $this->createMock( Tables_Based_Course_Progress::class ); $tables_based_repository = $this->createMock( Tables_Based_Course_Progress_Repository::class ); $tables_based_repository->method( 'create' )->willReturn( $created_progress ); @@ -44,7 +45,7 @@ public function testGet_Always_ReturnsTablesBasedProgress(): void { /* Arrange. */ $comments_based_repository = $this->createMock( Comments_Based_Course_Progress_Repository::class ); - $created_progress = $this->createMock( \Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress::class ); + $created_progress = $this->createMock( Tables_Based_Course_Progress::class ); $tables_based_repository = $this->createMock( Tables_Based_Course_Progress_Repository::class ); $tables_based_repository ->method( 'get' ) @@ -109,7 +110,7 @@ public function testHas_Never_CallsCommentsBasedRepository(): void { public function testDelete_Always_CallsTablesBasedRepository(): void { /* Arrange. */ - $progress = $this->createMock( Course_Progress::class ); + $progress = $this->createMock( Tables_Based_Course_Progress::class ); $progress->method( 'get_course_id' )->willReturn( 1 ); $progress->method( 'get_user_id' )->willReturn( 2 ); @@ -128,7 +129,7 @@ public function testDelete_Always_CallsTablesBasedRepository(): void { public function testDelete_CommentsBasedProgressNotFound_DoesntDeleteCommentsBasedProgress(): void { /* Arrange. */ - $progress = $this->createMock( Course_Progress::class ); + $progress = $this->createMock( Tables_Based_Course_Progress::class ); $progress->method( 'get_course_id' )->willReturn( 1 ); $progress->method( 'get_user_id' )->willReturn( 2 ); @@ -151,26 +152,26 @@ public function testDelete_CommentsBasedProgressNotFound_DoesntDeleteCommentsBas public function testDelete_CommentsBasedProgressFound_DeletesCommentsBasedProgress(): void { /* Arrange. */ - $progress = $this->createMock( Course_Progress::class ); + $progress = $this->createMock( Tables_Based_Course_Progress::class ); $progress->method( 'get_course_id' )->willReturn( 1 ); $progress->method( 'get_user_id' )->willReturn( 2 ); - $commets_based_progress = $this->createMock( Course_Progress::class ); + $comments_based_progress = $this->createMock( Comments_Based_Course_Progress::class ); $comments_based_repository = $this->createMock( Comments_Based_Course_Progress_Repository::class ); $comments_based_repository ->method( 'get' ) ->with( 1, 2 ) - ->willReturn( $commets_based_progress ); + ->willReturn( $comments_based_progress ); $tables_based_repository = $this->createMock( Tables_Based_Course_Progress_Repository::class ); $repository = new Table_Reading_Aggregate_Course_Progress_Repository( $comments_based_repository, $tables_based_repository ); /* Expect & Act. */ - $tables_based_repository + $comments_based_repository ->expects( $this->once() ) ->method( 'delete' ) - ->with( $commets_based_progress ); + ->with( $comments_based_progress ); $repository->delete( $progress ); } @@ -237,8 +238,8 @@ public function testDeleteForUser_Always_CallsCommentsBasedRepository(): void { public function testSave_Always_CallsTablesBasedRepository(): void { /* Arrange. */ $date_mock = new \DateTimeImmutable( '2020-01-01' ); - $tables_based_progress = new Course_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); - $comments_based_progress = new Course_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $tables_based_progress = new Tables_Based_Course_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $comments_based_progress = new Comments_Based_Course_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); $comments_based_repository = $this->createMock( Comments_Based_Course_Progress_Repository::class ); $comments_based_repository @@ -261,8 +262,8 @@ public function testSave_Always_CallsTablesBasedRepository(): void { public function testSave_CommentsBasedProgressNotFound_CreatesCommentsBasedProgress(): void { /* Arrange. */ $date_mock = new \DateTimeImmutable( '2020-01-01' ); - $tables_based_progress = new Course_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); - $comments_based_progress = new Course_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $tables_based_progress = new Tables_Based_Course_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $comments_based_progress = new Comments_Based_Course_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); $comments_based_repository = $this->createMock( Comments_Based_Course_Progress_Repository::class ); $comments_based_repository @@ -287,8 +288,8 @@ public function testSave_CommentsBasedProgressNotFound_CreatesCommentsBasedProgr public function testSave_CommentsBasedProgressFound_DoesntCreateCommentsBasedProgress(): void { /* Arrange. */ $date_mock = new \DateTimeImmutable( '2020-01-01' ); - $tables_based_progress = new Course_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); - $comments_based_progress = new Course_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $tables_based_progress = new Tables_Based_Course_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $comments_based_progress = new Comments_Based_Course_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); $comments_based_repository = $this->createMock( Comments_Based_Course_Progress_Repository::class ); $comments_based_repository @@ -312,8 +313,8 @@ public function testSave_CommentsBasedProgressFound_DoesntCreateCommentsBasedPro public function testSave_Always_SavesToCommentsBasedRepository(): void { /* Arrange. */ $date_mock = new \DateTimeImmutable( '2020-01-01' ); - $tables_based_progress = new Course_Progress( 3, 1, 2, 'complete', $date_mock, $date_mock, $date_mock, $date_mock ); - $comments_based_progress = new Course_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $tables_based_progress = new Tables_Based_Course_Progress( 3, 1, 2, 'complete', $date_mock, $date_mock, $date_mock, $date_mock ); + $comments_based_progress = new Comments_Based_Course_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); $comments_based_repository = $this->createMock( Comments_Based_Course_Progress_Repository::class ); $comments_based_repository @@ -331,7 +332,7 @@ public function testSave_Always_SavesToCommentsBasedRepository(): void { ->method( 'save' ) ->with( $this->callback( - function ( Course_Progress $progress ) { + function ( Comments_Based_Course_Progress $progress ) { return 'complete' === $progress->get_status(); } ) diff --git a/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-tables-based-course-progress-repository.php b/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-tables-based-course-progress-repository.php index 7aad0aa94a..fa66b0efe2 100644 --- a/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-tables-based-course-progress-repository.php +++ b/tests/unit-tests/internal/student-progress/course-progress/repositories/test-class-tables-based-course-progress-repository.php @@ -3,7 +3,8 @@ namespace SenseiTest\Internal\Student_Progress\Course_Progress\Repositories; use DateTimeImmutable; -use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Course_Progress_Interface; +use Sensei\Internal\Student_Progress\Course_Progress\Models\Tables_Based_Course_Progress; use Sensei\Internal\Student_Progress\Course_Progress\Repositories\Tables_Based_Course_Progress_Repository; use wpdb; @@ -242,10 +243,21 @@ public function testHas_WithRealDbAndProgressFound_ReturnsFalse(): void { self::assertTrue( $has ); } + public function testSave_NonTablesBasedProgressGiven_TrowsException(): void { + /* Arrange. */ + $progress = $this->createMock( Course_Progress_Interface::class ); + $repository = new Tables_Based_Course_Progress_Repository( $this->createMock( wpdb::class ) ); + + /* Expect & Act. */ + $this->expectException( \InvalidArgumentException::class ); + $this->expectExceptionMessage( 'Expected Tables_Based_Course_Progress, got ' . get_class( $progress ) . '.' ); + $repository->save( $progress ); + } + public function testSave_ProgressGiven_CallsWpdbUpdate(): void { /* Arrange. */ $wpdb = $this->createMock( wpdb::class ); - $progress = new Course_Progress( + $progress = new Tables_Based_Course_Progress( 1, 2, 3, @@ -290,7 +302,7 @@ function ( $data ) { public function testDelete_ProgressGiven_CallsWpdbDelete(): void { /* Arrange. */ $wpdb = $this->createMock( wpdb::class ); - $progress = new Course_Progress( + $progress = new Tables_Based_Course_Progress( 1, 2, 3, @@ -368,7 +380,7 @@ public function testDeleteForUser_UserIdGiven_CallsWpdbDelete(): void { $repository->delete_for_user( 2 ); } - private function export_progress( Course_Progress $progress ): array { + private function export_progress( Course_Progress_Interface $progress ): array { return [ 'id' => $progress->get_id(), 'course_id' => $progress->get_course_id(), @@ -377,7 +389,7 @@ private function export_progress( Course_Progress $progress ): array { ]; } - private function export_progress_with_dates( ?Course_Progress $progress ): array { + private function export_progress_with_dates( ?Course_Progress_Interface $progress ): array { return [ 'id' => $progress->get_id(), 'course_id' => $progress->get_course_id(), diff --git a/tests/unit-tests/internal/student-progress/lesson-progress/models/test-class-comments-based-lesson-progress.php b/tests/unit-tests/internal/student-progress/lesson-progress/models/test-class-comments-based-lesson-progress.php new file mode 100644 index 0000000000..fa36b512a6 --- /dev/null +++ b/tests/unit-tests/internal/student-progress/lesson-progress/models/test-class-comments-based-lesson-progress.php @@ -0,0 +1,363 @@ +factory = new \Sensei_Factory(); + } + + public function tearDown(): void { + parent::tearDown(); + $this->factory->tearDown(); + } + + public function testGetId_ConstructedWithId_ReturnsSameId(): void { + /* Arrange. */ + $lesson_progress = $this->create_progress(); + + /* Act. */ + $actual = $lesson_progress->get_id(); + + /* Assert. */ + self::assertSame( 1, $actual ); + } + + public function testGetLessonId_ConstructedWithLessonId_ReturnsSameLessonId(): void { + /* Arrange. */ + $lesson_progress = $this->create_progress(); + + /* Act. */ + $actual = $lesson_progress->get_lesson_id(); + + /* Assert. */ + self::assertSame( 2, $actual ); + } + + public function testGetUserId_ConstructedWithUserId_ReturnsSameUserId(): void { + /* Arrange. */ + $lesson_progress = $this->create_progress(); + + /* Act. */ + $actual = $lesson_progress->get_user_id(); + + /* Assert. */ + self::assertSame( 3, $actual ); + } + + /** + * Test that get status returns the expected value. + * + * @dataProvider providerGetStatus_ConstructedWithNonFaildedStatus_ReturnsMatchingStatus + */ + public function testGetStatus_ConstructedWithNonFaildedStatus_ReturnsMatchingStatus( $internal_status, $expected_status ): void { + /* Arrange. */ + $lesson_progress = $this->create_progress( $internal_status ); + + /* Act. */ + $actual = $lesson_progress->get_status(); + + /* Assert. */ + self::assertSame( $expected_status, $actual ); + } + + public function providerGetStatus_ConstructedWithNonFaildedStatus_ReturnsMatchingStatus(): array { + return array( + 'internal in-progress' => array( 'in-progress', 'in-progress' ), + 'internal complete' => array( 'complete', 'complete' ), + // The following values come from quiz progress: + 'internal passed' => array( 'passed', 'complete' ), + 'internal graded' => array( 'graded', 'complete' ), + 'internal ungraded' => array( 'ungraded', 'in-progress' ), + ); + } + + public function testGetStatus_ConstructedWithFaildedStatusAndPassNotRequired_ReturnsComplete(): void { + /* Arrange. */ + $lesson_id = $this->factory->lesson->create(); + $quiz_id = $this->factory->quiz->create( + array( + 'post_parent' => $lesson_id, + 'meta_input' => array( + '_pass_required' => 0, + ), + ) + ); + + $progress = new Comments_Based_Lesson_Progress( + 1, + $lesson_id, + 3, + 'failed', + new \DateTime( '2020-01-01 00:00:00' ), + new \DateTime( '2020-01-01 00:00:01' ), + new \DateTime( '2020-01-01 00:00:02' ), + new \DateTime( '2020-01-01 00:00:03' ) + ); + + /* Act. */ + $actual = $progress->get_status(); + + /* Assert. */ + self::assertSame( 'complete', $actual ); + } + + public function testGetStatus_ConstructedWithFaildedStatusAndPassRequired_ReturnsInProgress(): void { + /* Arrange. */ + $lesson_id = $this->factory->lesson->create(); + $quiz_id = $this->factory->quiz->create( + array( + 'post_parent' => $lesson_id, + 'meta_input' => array( + '_pass_required' => 1, + ), + ) + ); + + $progress = new Comments_Based_Lesson_Progress( + 1, + $lesson_id, + 3, + 'failed', + new \DateTime( '2020-01-01 00:00:00' ), + new \DateTime( '2020-01-01 00:00:01' ), + new \DateTime( '2020-01-01 00:00:02' ), + new \DateTime( '2020-01-01 00:00:03' ) + ); + + /* Act. */ + $actual = $progress->get_status(); + + /* Assert. */ + self::assertSame( 'in-progress', $actual ); + } + + public function testGetStartedAt_ConstructedWithStartedAt_ReturnsSameStartedAt(): void { + /* Arrange. */ + $lesson_progress = $this->create_progress(); + + /* Act. */ + $actual = $lesson_progress->get_started_at()->format( 'Y-m-d H:i:s' ); + + /* Assert. */ + self::assertSame( '2020-01-01 00:00:00', $actual ); + } + + public function testGetCompletedAt_ConstructedWithCompletedAt_ReturnsSameCompletedAt(): void { + /* Arrange. */ + $lesson_progress = $this->create_progress(); + + /* Act. */ + $actual = $lesson_progress->get_completed_at()->format( 'Y-m-d H:i:s' ); + + /* Assert. */ + self::assertSame( '2020-01-01 00:00:01', $actual ); + } + + public function testGetCreatedAt_ConstructedWithCreatedAt_ReturnsSameCreatedAt(): void { + /* Arrange. */ + $lesson_progress = $this->create_progress(); + + /* Act. */ + $actual = $lesson_progress->get_created_at()->format( 'Y-m-d H:i:s' ); + + /* Assert. */ + self::assertSame( '2020-01-01 00:00:02', $actual ); + } + + public function testGetUpdatedAt_ConstructedWithUpdatedAt_ReturnsSameUpdatedAt(): void { + /* Arrange. */ + $lesson_progress = $this->create_progress(); + + /* Act. */ + $actual = $lesson_progress->get_updated_at()->format( 'Y-m-d H:i:s' ); + + /* Assert. */ + self::assertSame( '2020-01-01 00:00:03', $actual ); + } + + public function testGetUpdatedAt_WhenUpdatedAtSet_ReturnsSameUpdatedAt(): void { + /* Arrange. */ + $lesson_progress = $this->create_progress(); + $lesson_progress->set_updated_at( new \DateTime( '2020-01-01 00:00:04' ) ); + + /* Act. */ + $actual = $lesson_progress->get_updated_at()->format( 'Y-m-d H:i:s' ); + + /* Assert. */ + self::assertSame( '2020-01-01 00:00:04', $actual ); + } + + public function testGetStartedAt_WhenStartWithStartedAtCalled_ReturnsSameStartedAt(): void { + /* Arrange. */ + $started_at = new \DateTimeImmutable(); + $progress = $this->create_progress(); + + /* Act. */ + $progress->start( $started_at ); + + /* Assert. */ + self::assertSame( $started_at, $progress->get_started_at() ); + } + + public function testIsComplete_WhenConstructedInProgressAndCompleteCalled_ReturnsTrue(): void { + /* Arrange. */ + $progress = $this->create_progress( 'in-progress' ); + $progress->complete(); + + /* Act. */ + $actual = $progress->is_complete(); + + /* Assert. */ + self::assertTrue( $actual ); + } + + public function testIsComplete_WhenConstructedCompleteAndStartCalled_ReturnsFalse(): void { + /* Arrange. */ + $progress = $this->create_progress( 'complete' ); + $progress->start(); + + /* Act. */ + $actual = $progress->is_complete(); + + /* Assert. */ + self::assertFalse( $actual ); + } + + /** + * Test that the progress is complete when the completed_at is set. + * + * @dataProvider providerIsComplete_WhenConstructedWithStatus_ReturnsMatchingValue + * @param string $status The status to set. + * @param bool $expected The expected value. + */ + public function testIsComplete_WhenConstructedWithStatus_ReturnsMatchingValue( string $status, bool $expected ): void { + /* Arrange. */ + $progress = $this->create_progress( $status ); + + /* Act. */ + $actual = $progress->is_complete(); + + /* Assert. */ + self::assertSame( $expected, $actual ); + } + + public function providerIsComplete_WhenConstructedWithStatus_ReturnsMatchingValue(): array { + return [ + [ 'in-progress', false ], + [ 'complete', true ], + // The following values come from quiz progress: + [ 'passed', true ], + [ 'failed', false ], + [ 'graded', true ], + [ 'ungraded', false ], + ]; + } + + public function testIsComplete_ConstructedWithFaildedStatusAndPassNotRequired_ReturnsTrue(): void { + /* Arrange. */ + $lesson_id = $this->factory->lesson->create(); + $quiz_id = $this->factory->quiz->create( + array( + 'post_parent' => $lesson_id, + 'meta_input' => array( + '_pass_required' => 0, + ), + ) + ); + + $progress = new Comments_Based_Lesson_Progress( + 1, + $lesson_id, + 3, + 'failed', + new \DateTime( '2020-01-01 00:00:00' ), + new \DateTime( '2020-01-01 00:00:01' ), + new \DateTime( '2020-01-01 00:00:02' ), + new \DateTime( '2020-01-01 00:00:03' ) + ); + + /* Act. */ + $actual = $progress->is_complete(); + + /* Assert. */ + self::assertTrue( $actual ); + } + + public function testIsComplete_ConstructedWithFaildedStatusAndPassRequired_ReturnsFalse(): void { + /* Arrange. */ + $lesson_id = $this->factory->lesson->create(); + $quiz_id = $this->factory->quiz->create( + array( + 'post_parent' => $lesson_id, + 'meta_input' => array( + '_pass_required' => 1, + ), + ) + ); + + $progress = new Comments_Based_Lesson_Progress( + 1, + $lesson_id, + 3, + 'failed', + new \DateTime( '2020-01-01 00:00:00' ), + new \DateTime( '2020-01-01 00:00:01' ), + new \DateTime( '2020-01-01 00:00:02' ), + new \DateTime( '2020-01-01 00:00:03' ) + ); + + /* Act. */ + $actual = $progress->is_complete(); + + /* Assert. */ + self::assertFalse( $actual ); + } + + public function testGetCompletedAt_WhenCompleteWithCompletedAtCalled_ReturnsSameCompletedAt(): void { + /* Arrange. */ + $completed_at = new \DateTimeImmutable(); + $progress = $this->create_progress(); + + /* Act. */ + $progress->complete( $completed_at ); + + /* Assert. */ + self::assertSame( $completed_at, $progress->get_completed_at() ); + } + + private function create_progress( string $status = null ): Comments_Based_Lesson_Progress { + return new Comments_Based_Lesson_Progress( + 1, + 2, + 3, + $status ?? 'in-progress', + new \DateTime( '2020-01-01 00:00:00' ), + new \DateTime( '2020-01-01 00:00:01' ), + new \DateTime( '2020-01-01 00:00:02' ), + new \DateTime( '2020-01-01 00:00:03' ) + ); + } +} diff --git a/tests/unit-tests/internal/student-progress/lesson-progress/models/test-class-lesson-progress.php b/tests/unit-tests/internal/student-progress/lesson-progress/models/test-class-tables-based-lesson-progress.php similarity index 59% rename from tests/unit-tests/internal/student-progress/lesson-progress/models/test-class-lesson-progress.php rename to tests/unit-tests/internal/student-progress/lesson-progress/models/test-class-tables-based-lesson-progress.php index 433c4af0c7..f1154a4505 100644 --- a/tests/unit-tests/internal/student-progress/lesson-progress/models/test-class-lesson-progress.php +++ b/tests/unit-tests/internal/student-progress/lesson-progress/models/test-class-tables-based-lesson-progress.php @@ -1,29 +1,45 @@ factory = new \Sensei_Factory(); + } + + public function tearDown(): void { + parent::tearDown(); + $this->factory->tearDown(); + } public function testGetId_ConstructedWithId_ReturnsSameId(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $lesson_progress = $this->create_progress(); /* Act. */ - $actual = $course_progress->get_id(); + $actual = $lesson_progress->get_id(); /* Assert. */ self::assertSame( 1, $actual ); @@ -31,10 +47,10 @@ public function testGetId_ConstructedWithId_ReturnsSameId(): void { public function testGetLessonId_ConstructedWithLessonId_ReturnsSameLessonId(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $lesson_progress = $this->create_progress(); /* Act. */ - $actual = $course_progress->get_lesson_id(); + $actual = $lesson_progress->get_lesson_id(); /* Assert. */ self::assertSame( 2, $actual ); @@ -42,32 +58,44 @@ public function testGetLessonId_ConstructedWithLessonId_ReturnsSameLessonId(): v public function testGetUserId_ConstructedWithUserId_ReturnsSameUserId(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $lesson_progress = $this->create_progress(); /* Act. */ - $actual = $course_progress->get_user_id(); + $actual = $lesson_progress->get_user_id(); /* Assert. */ self::assertSame( 3, $actual ); } - public function testGetStatus_ConstructedWithStatus_ReturnsSameStatus(): void { + /** + * Test that get status returns the expected value. + * + * @dataProvider providerGetStatus_ConstructedWithStatus_ReturnsMatchingStatus + */ + public function testGetStatus_ConstructedWithStatus_ReturnsMatchingStatus( $internal_status, $expected_status ): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $lesson_progress = $this->create_progress( $internal_status ); /* Act. */ - $actual = $course_progress->get_status(); + $actual = $lesson_progress->get_status(); /* Assert. */ - self::assertSame( 'in-progress', $actual ); + self::assertSame( $expected_status, $actual ); + } + + public function providerGetStatus_ConstructedWithStatus_ReturnsMatchingStatus(): array { + return array( + 'in-progress' => array( 'in-progress', 'in-progress' ), + 'complete' => array( 'complete', 'complete' ), + ); } public function testGetStartedAt_ConstructedWithStartedAt_ReturnsSameStartedAt(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $lesson_progress = $this->create_progress(); /* Act. */ - $actual = $course_progress->get_started_at()->format( 'Y-m-d H:i:s' ); + $actual = $lesson_progress->get_started_at()->format( 'Y-m-d H:i:s' ); /* Assert. */ self::assertSame( '2020-01-01 00:00:00', $actual ); @@ -75,10 +103,10 @@ public function testGetStartedAt_ConstructedWithStartedAt_ReturnsSameStartedAt() public function testGetCompletedAt_ConstructedWithCompletedAt_ReturnsSameCompletedAt(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $lesson_progress = $this->create_progress(); /* Act. */ - $actual = $course_progress->get_completed_at()->format( 'Y-m-d H:i:s' ); + $actual = $lesson_progress->get_completed_at()->format( 'Y-m-d H:i:s' ); /* Assert. */ self::assertSame( '2020-01-01 00:00:01', $actual ); @@ -86,10 +114,10 @@ public function testGetCompletedAt_ConstructedWithCompletedAt_ReturnsSameComplet public function testGetCreatedAt_ConstructedWithCreatedAt_ReturnsSameCreatedAt(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $lesson_progress = $this->create_progress(); /* Act. */ - $actual = $course_progress->get_created_at()->format( 'Y-m-d H:i:s' ); + $actual = $lesson_progress->get_created_at()->format( 'Y-m-d H:i:s' ); /* Assert. */ self::assertSame( '2020-01-01 00:00:02', $actual ); @@ -97,10 +125,10 @@ public function testGetCreatedAt_ConstructedWithCreatedAt_ReturnsSameCreatedAt() public function testGetUpdatedAt_ConstructedWithUpdatedAt_ReturnsSameUpdatedAt(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $lesson_progress = $this->create_progress(); /* Act. */ - $actual = $course_progress->get_updated_at()->format( 'Y-m-d H:i:s' ); + $actual = $lesson_progress->get_updated_at()->format( 'Y-m-d H:i:s' ); /* Assert. */ self::assertSame( '2020-01-01 00:00:03', $actual ); @@ -108,11 +136,11 @@ public function testGetUpdatedAt_ConstructedWithUpdatedAt_ReturnsSameUpdatedAt() public function testGetUpdatedAt_WhenUpdatedAtSet_ReturnsSameUpdatedAt(): void { /* Arrange. */ - $course_progress = $this->createProgress(); - $course_progress->set_updated_at( new \DateTime( '2020-01-01 00:00:04' ) ); + $lesson_progress = $this->create_progress(); + $lesson_progress->set_updated_at( new \DateTime( '2020-01-01 00:00:04' ) ); /* Act. */ - $actual = $course_progress->get_updated_at()->format( 'Y-m-d H:i:s' ); + $actual = $lesson_progress->get_updated_at()->format( 'Y-m-d H:i:s' ); /* Assert. */ self::assertSame( '2020-01-01 00:00:04', $actual ); @@ -121,7 +149,7 @@ public function testGetUpdatedAt_WhenUpdatedAtSet_ReturnsSameUpdatedAt(): void { public function testGetStartedAt_WhenStartWithStartedAtCalled_ReturnsSameStartedAt(): void { /* Arrange. */ $started_at = new \DateTimeImmutable(); - $progress = $this->createProgress(); + $progress = $this->create_progress(); /* Act. */ $progress->start( $started_at ); @@ -132,7 +160,7 @@ public function testGetStartedAt_WhenStartWithStartedAtCalled_ReturnsSameStarted public function testIsComplete_WhenConstructedInProgressAndCompleteCalled_ReturnsTrue(): void { /* Arrange. */ - $progress = $this->createProgress( 'in-progress' ); + $progress = $this->create_progress( 'in-progress' ); $progress->complete(); /* Act. */ @@ -144,7 +172,7 @@ public function testIsComplete_WhenConstructedInProgressAndCompleteCalled_Return public function testIsComplete_WhenConstructedCompleteAndStartCalled_ReturnsFalse(): void { /* Arrange. */ - $progress = $this->createProgress( 'complete' ); + $progress = $this->create_progress( 'complete' ); $progress->start(); /* Act. */ @@ -155,7 +183,7 @@ public function testIsComplete_WhenConstructedCompleteAndStartCalled_ReturnsFals } /** - * Test that the progress is complete when the completed_at is set. + * Test that the progress is complete when the status is set. * * @dataProvider providerIsComplete_WhenConstructedWithStatus_ReturnsMatchingValue * @param string $status The status to set. @@ -163,7 +191,7 @@ public function testIsComplete_WhenConstructedCompleteAndStartCalled_ReturnsFals */ public function testIsComplete_WhenConstructedWithStatus_ReturnsMatchingValue( string $status, bool $expected ): void { /* Arrange. */ - $progress = $this->createProgress( $status ); + $progress = $this->create_progress( $status ); /* Act. */ $actual = $progress->is_complete(); @@ -176,18 +204,13 @@ public function providerIsComplete_WhenConstructedWithStatus_ReturnsMatchingValu return [ [ 'in-progress', false ], [ 'complete', true ], - // The following values come from quiz progress: - [ 'passed', true ], - [ 'failed', false ], - [ 'graded', true ], - [ 'ungraded', false ], ]; } public function testGetCompletedAt_WhenCompleteWithCompletedAtCalled_ReturnsSameCompletedAt(): void { /* Arrange. */ $completed_at = new \DateTimeImmutable(); - $progress = $this->createProgress(); + $progress = $this->create_progress(); /* Act. */ $progress->complete( $completed_at ); @@ -196,8 +219,8 @@ public function testGetCompletedAt_WhenCompleteWithCompletedAtCalled_ReturnsSame self::assertSame( $completed_at, $progress->get_completed_at() ); } - private function createProgress( string $status = null ): Lesson_Progress { - return new Lesson_Progress( + private function create_progress( string $status = null ): Tables_Based_Lesson_Progress { + return new Tables_Based_Lesson_Progress( 1, 2, 3, diff --git a/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-comment-reading-aggregate-lesson-progress-repository.php b/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-comment-reading-aggregate-lesson-progress-repository.php index 261e039e83..57cd7fdace 100644 --- a/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-comment-reading-aggregate-lesson-progress-repository.php +++ b/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-comment-reading-aggregate-lesson-progress-repository.php @@ -2,7 +2,9 @@ namespace SenseiTest\Internal\Student_Progress\Lesson_Progress\Repositories; -use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Comments_Based_Lesson_Progress; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress_Interface; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Tables_Based_Lesson_Progress; use Sensei\Internal\Student_Progress\Lesson_Progress\Repositories\Comment_Reading_Aggregate_Lesson_Progress_Repository; use Sensei\Internal\Student_Progress\Lesson_Progress\Repositories\Comments_Based_Lesson_Progress_Repository; use Sensei\Internal\Student_Progress\Lesson_Progress\Repositories\Tables_Based_Lesson_Progress_Repository; @@ -71,13 +73,14 @@ public function testHas_Always_CallsCommentsBasedRepository(): void { public function testSave_WhenUsedTables_CallsCommentsBasedRepository(): void { /* Arrange. */ - $progress = $this->create_lesson_progress(); + $progress = $this->create_comments_based_lesson_progress(); + $found_progress = $this->create_tables_based_lesson_progress(); $comments_based = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Lesson_Progress_Repository::class ); $tables_based ->method( 'get' ) - ->willReturn( $progress ); + ->willReturn( $found_progress ); $repository = new Comment_Reading_Aggregate_Lesson_Progress_Repository( $comments_based, $tables_based ); @@ -91,17 +94,8 @@ public function testSave_WhenUsedTables_CallsCommentsBasedRepository(): void { public function testSave_TablesBasedProgressFound_CallsTablesBasedRepository(): void { /* Arrange. */ - $progress = $this->create_lesson_progress(); - $found_progress = new Lesson_Progress( - 2, - 3, - 4, - 'a', - new \DateTimeImmutable(), - new \DateTimeImmutable(), - new \DateTimeImmutable(), - new \DateTimeImmutable() - ); + $progress = $this->create_comments_based_lesson_progress(); + $found_progress = $this->create_tables_based_lesson_progress(); $comments_based = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Lesson_Progress_Repository::class ); @@ -118,7 +112,7 @@ public function testSave_TablesBasedProgressFound_CallsTablesBasedRepository(): ->method( 'save' ) ->with( $this->callback( - function ( Lesson_Progress $progress_to_save ) use ( $progress, $found_progress ) { + function ( Lesson_Progress_Interface $progress_to_save ) use ( $progress, $found_progress ) { self::assertNotSame( $progress, $progress_to_save, 'We should create a new progress based on a found one: not using passed for saving.' ); self::assertNotSame( $found_progress, $progress_to_save, 'We should create a new progress based on a found one: not the found one itself.' ); return true; @@ -130,9 +124,9 @@ function ( Lesson_Progress $progress_to_save ) use ( $progress, $found_progress public function testSave_TablesBasedProgressFound_ConvertsTimeToUtc(): void { /* Arrange. */ - $progress = $this->create_lesson_progress( new \DateTimeImmutable( '2020-01-01 03:00:00', new \DateTimeZone( 'GMT+03:00' ) ) ); + $progress = $this->create_comments_based_lesson_progress( new \DateTimeImmutable( '2020-01-01 03:00:00', new \DateTimeZone( 'GMT+03:00' ) ) ); - $found_progress = $this->create_lesson_progress(); + $found_progress = $this->create_tables_based_lesson_progress(); $comments_based = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Lesson_Progress_Repository::class ); @@ -149,7 +143,7 @@ public function testSave_TablesBasedProgressFound_ConvertsTimeToUtc(): void { ->method( 'save' ) ->with( $this->callback( - function ( Lesson_Progress $progress_to_save ) { + function ( Lesson_Progress_Interface $progress_to_save ) { return '2020-01-01 00:00:00' === $progress_to_save->get_started_at()->format( 'Y-m-d H:i:s' ); } ) @@ -158,8 +152,8 @@ function ( Lesson_Progress $progress_to_save ) { } public function testSave_TablesBasedProgressNotFound_CreatesTablesBasedProgress(): void { /* Arrange. */ - $progress = $this->create_lesson_progress(); - $created_progress = $this->create_lesson_progress(); + $progress = $this->create_comments_based_lesson_progress(); + $created_progress = $this->create_tables_based_lesson_progress(); $comments_based = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Lesson_Progress_Repository::class ); @@ -181,7 +175,7 @@ public function testSave_TablesBasedProgressNotFound_CreatesTablesBasedProgress( public function testDelete_Always_CallsTablesBasedRepository(): void { /* Arrange. */ - $progress = $this->create_lesson_progress(); + $progress = $this->create_comments_based_lesson_progress(); $comments_based = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Lesson_Progress_Repository::class ); @@ -198,7 +192,7 @@ public function testDelete_Always_CallsTablesBasedRepository(): void { public function testDelete_Always_CallsCommentsBasedRepository(): void { /* Arrange. */ - $progress = $this->create_lesson_progress(); + $progress = $this->create_comments_based_lesson_progress(); $comments_based = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Lesson_Progress_Repository::class ); @@ -300,13 +294,13 @@ public function testCount_Always_CallsCommentsBasedRepository(): void { } /** - * Create a lesson progress. + * Create a comments-baesd lesson progress. * * @param \DateTimeInterface|null $started_at The started at date. - * @return Lesson_Progress + * @return Comments_Based_Lesson_Progress */ - public function create_lesson_progress( $started_at = null ): Lesson_Progress { - return new Lesson_Progress( + public function create_comments_based_lesson_progress( $started_at = null ): Comments_Based_Lesson_Progress { + return new Comments_Based_Lesson_Progress( 1, 2, 3, @@ -317,4 +311,23 @@ public function create_lesson_progress( $started_at = null ): Lesson_Progress { new \DateTimeImmutable() ); } + + /** + * Create a tables-baesd lesson progress. + * + * @param \DateTimeInterface|null $started_at The started at date. + * @return Lesson_Progress + */ + public function create_tables_based_lesson_progress( $started_at = null ): Tables_Based_Lesson_Progress { + return new Tables_Based_Lesson_Progress( + 4, + 2, + 3, + 'b', + $started_at ?? new \DateTimeImmutable(), + new \DateTimeImmutable(), + new \DateTimeImmutable(), + new \DateTimeImmutable() + ); + } } diff --git a/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-comments-based-lesson-progress-repository.php b/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-comments-based-lesson-progress-repository.php index a3efe2fd7c..082dae581e 100644 --- a/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-comments-based-lesson-progress-repository.php +++ b/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-comments-based-lesson-progress-repository.php @@ -2,7 +2,7 @@ namespace SenseiTest\Internal\Student_Progress\Lesson_Progress\Repositories; -use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress_Interface; use Sensei\Internal\Student_Progress\Lesson_Progress\Repositories\Comments_Based_Lesson_Progress_Repository; /** @@ -112,6 +112,17 @@ public function testGet_WhenProgressChangedAndSaved_ReturnsUpdatedProgress(): vo self::assertSame( $this->export_progress( $progress ), $this->export_progress( $actual ) ); } + public function testSave_WhenNonCommentsBasedProgressGiven_ThrowsException(): void { + /* Arrange. */ + $progress = $this->createMock( Lesson_Progress_Interface::class ); + $repository = new Comments_Based_Lesson_Progress_Repository(); + + /* Expect&Act. */ + $this->expectException( \InvalidArgumentException::class ); + $this->expectExceptionMessage( 'Expected Comments_Based_Lesson_Progress, got ' . get_class( $progress ) . '.' ); + $repository->save( $progress ); + } + public function testCount_WhenNoProgress_ReturnsZero(): void { /* Arrange. */ $course_id = $this->factory->course->create(); @@ -188,7 +199,7 @@ public function testDeleteForUser_WhenUserGiven_DeletesProgressForUser(): void { self::assertTrue( $repository->has( $lesson_id, $user_id ) ); } - private function export_progress( Lesson_Progress $progress ): array { + private function export_progress( Lesson_Progress_Interface $progress ): array { return [ 'user_id' => $progress->get_user_id(), 'lesson_id' => $progress->get_lesson_id(), diff --git a/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-table-reading-aggregate-lesson-progress-repository.php b/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-table-reading-aggregate-lesson-progress-repository.php index eac53c2040..d692dd7f6b 100644 --- a/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-table-reading-aggregate-lesson-progress-repository.php +++ b/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-table-reading-aggregate-lesson-progress-repository.php @@ -2,7 +2,9 @@ namespace SenseiTest\Internal\Student_Progress\Lesson_Progress\Repositories; -use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Comments_Based_Lesson_Progress; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress_Interface; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Tables_Based_Lesson_Progress; use Sensei\Internal\Student_Progress\Lesson_Progress\Repositories\Table_Reading_Aggregate_Lesson_Progress_Repository; use Sensei\Internal\Student_Progress\Lesson_Progress\Repositories\Tables_Based_Lesson_Progress_Repository; use Sensei\Internal\Student_Progress\Lesson_Progress\Repositories\Comments_Based_Lesson_Progress_Repository; @@ -12,7 +14,7 @@ public function testCreate_Always_ReturnsTablesBasedVersion(): void { /* Arrange. */ $comments_based_repository = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); - $created_progress = $this->createMock( \Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress::class ); + $created_progress = $this->createMock( Tables_Based_Lesson_Progress::class ); $tables_based_repository = $this->createMock( Tables_Based_Lesson_Progress_Repository::class ); $tables_based_repository->method( 'create' )->willReturn( $created_progress ); @@ -44,7 +46,7 @@ public function testGet_Always_ReturnsTablesBasedProgress(): void { /* Arrange. */ $comments_based_repository = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); - $created_progress = $this->createMock( \Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress::class ); + $created_progress = $this->createMock( Tables_Based_Lesson_Progress::class ); $tables_based_repository = $this->createMock( Tables_Based_Lesson_Progress_Repository::class ); $tables_based_repository ->method( 'get' ) @@ -109,7 +111,7 @@ public function testHas_Never_CallsCommentsBasedRepository(): void { public function testDelete_Always_CallsTablesBasedRepository(): void { /* Arrange. */ - $progress = $this->createMock( Lesson_Progress::class ); + $progress = $this->createMock( Lesson_Progress_Interface::class ); $progress->method( 'get_lesson_id' )->willReturn( 1 ); $progress->method( 'get_user_id' )->willReturn( 2 ); @@ -128,7 +130,7 @@ public function testDelete_Always_CallsTablesBasedRepository(): void { public function testDelete_CommentsBasedProgressNotFound_DoesntDeleteCommentsBasedProgress(): void { /* Arrange. */ - $progress = $this->createMock( Lesson_Progress::class ); + $progress = $this->createMock( Lesson_Progress_Interface::class ); $progress->method( 'get_lesson_id' )->willReturn( 1 ); $progress->method( 'get_user_id' )->willReturn( 2 ); @@ -151,11 +153,11 @@ public function testDelete_CommentsBasedProgressNotFound_DoesntDeleteCommentsBas public function testDelete_CommentsBasedProgressFound_DeletesCommentsBasedProgress(): void { /* Arrange. */ - $progress = $this->createMock( Lesson_Progress::class ); + $progress = $this->createMock( Lesson_Progress_Interface::class ); $progress->method( 'get_lesson_id' )->willReturn( 1 ); $progress->method( 'get_user_id' )->willReturn( 2 ); - $commets_based_progress = $this->createMock( Lesson_Progress::class ); + $commets_based_progress = $this->createMock( Comments_Based_Lesson_Progress::class ); $comments_based_repository = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); $comments_based_repository ->method( 'get' ) @@ -167,7 +169,7 @@ public function testDelete_CommentsBasedProgressFound_DeletesCommentsBasedProgre $repository = new Table_Reading_Aggregate_Lesson_Progress_Repository( $comments_based_repository, $tables_based_repository ); /* Expect & Act. */ - $tables_based_repository + $comments_based_repository ->expects( $this->once() ) ->method( 'delete' ) ->with( $commets_based_progress ); @@ -237,8 +239,8 @@ public function testDeleteForUser_Always_CallsCommentsBasedRepository(): void { public function testSave_Always_CallsTablesBasedRepository(): void { /* Arrange. */ $date_mock = new \DateTimeImmutable( '2020-01-01' ); - $tables_based_progress = new Lesson_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); - $comments_based_progress = new Lesson_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $tables_based_progress = new Tables_Based_Lesson_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $comments_based_progress = new Comments_Based_Lesson_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); $comments_based_repository = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); $comments_based_repository @@ -261,8 +263,8 @@ public function testSave_Always_CallsTablesBasedRepository(): void { public function testSave_CommentsBasedProgressNotFound_CreatesCommentsBasedProgress(): void { /* Arrange. */ $date_mock = new \DateTimeImmutable( '2020-01-01' ); - $tables_based_progress = new Lesson_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); - $comments_based_progress = new Lesson_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $tables_based_progress = new Tables_Based_Lesson_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $comments_based_progress = new Comments_Based_Lesson_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); $comments_based_repository = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); $comments_based_repository @@ -287,8 +289,8 @@ public function testSave_CommentsBasedProgressNotFound_CreatesCommentsBasedProgr public function testSave_CommentsBasedProgressFound_DoesntCreateCommentsBasedProgress(): void { /* Arrange. */ $date_mock = new \DateTimeImmutable( '2020-01-01' ); - $tables_based_progress = new Lesson_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); - $comments_based_progress = new Lesson_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $tables_based_progress = new Tables_Based_Lesson_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $comments_based_progress = new Comments_Based_Lesson_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); $comments_based_repository = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); $comments_based_repository @@ -312,8 +314,8 @@ public function testSave_CommentsBasedProgressFound_DoesntCreateCommentsBasedPro public function testSave_Always_SavesToCommentsBasedRepository(): void { /* Arrange. */ $date_mock = new \DateTimeImmutable( '2020-01-01' ); - $tables_based_progress = new Lesson_Progress( 3, 1, 2, 'complete', $date_mock, $date_mock, $date_mock, $date_mock ); - $comments_based_progress = new Lesson_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $tables_based_progress = new Tables_Based_Lesson_Progress( 3, 1, 2, 'complete', $date_mock, $date_mock, $date_mock, $date_mock ); + $comments_based_progress = new Comments_Based_Lesson_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); $comments_based_repository = $this->createMock( Comments_Based_Lesson_Progress_Repository::class ); $comments_based_repository @@ -331,7 +333,7 @@ public function testSave_Always_SavesToCommentsBasedRepository(): void { ->method( 'save' ) ->with( $this->callback( - function ( Lesson_Progress $progress ) { + function ( Lesson_Progress_Interface $progress ) { return 'complete' === $progress->get_status(); } ) diff --git a/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-tables-based-lesson-progress-repository.php b/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-tables-based-lesson-progress-repository.php index 5ffc32f0a3..71cb6c6b57 100644 --- a/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-tables-based-lesson-progress-repository.php +++ b/tests/unit-tests/internal/student-progress/lesson-progress/repositories/test-class-tables-based-lesson-progress-repository.php @@ -3,7 +3,8 @@ namespace SenseiTest\Internal\Student_Progress\Lesson_Progress\Repositories; use DateTimeImmutable; -use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Lesson_Progress_Interface; +use Sensei\Internal\Student_Progress\Lesson_Progress\Models\Tables_Based_Lesson_Progress; use Sensei\Internal\Student_Progress\Lesson_Progress\Repositories\Tables_Based_Lesson_Progress_Repository; use Sensei_Course; use wpdb; @@ -244,7 +245,7 @@ public function testHas_WithRealDbAndProgressFound_ReturnsFalse(): void { public function testSave_ProgressGiven_CallsWpdbUpdate(): void { /* Arrange. */ $wpdb = $this->createMock( wpdb::class ); - $progress = new Lesson_Progress( + $progress = new Tables_Based_Lesson_Progress( 1, 2, 3, @@ -286,10 +287,21 @@ function ( $data ) { $repository->save( $progress ); } + public function testSave_NonTablesBasedProgressGiven_ThrowsException(): void { + /* Arrange. */ + $progress = $this->createMock( Lesson_Progress_Interface::class ); + $repository = new Tables_Based_Lesson_Progress_Repository( $this->createMock( wpdb::class ) ); + + /* Expect & Act. */ + $this->expectException( \InvalidArgumentException::class ); + $this->expectExceptionMessage( 'Expected Tables_Based_Lesson_Progress, got ' . get_class( $progress ) . '.' ); + $repository->save( $progress ); + } + public function testDelete_ProgressGiven_CallsWpdbDelete(): void { /* Arrange. */ $wpdb = $this->createMock( wpdb::class ); - $progress = new Lesson_Progress( + $progress = new Tables_Based_Lesson_Progress( 1, 2, 3, @@ -400,7 +412,7 @@ public function testCount_ParamsGiven_ReturnsMatchingValue(): void { Sensei()->course = $initial_course; } - private function export_progress( Lesson_Progress $progress ): array { + private function export_progress( Lesson_Progress_Interface $progress ): array { return [ 'id' => $progress->get_id(), 'lesson_id' => $progress->get_lesson_id(), @@ -409,7 +421,7 @@ private function export_progress( Lesson_Progress $progress ): array { ]; } - private function export_progress_with_dates( ?Lesson_Progress $progress ): array { + private function export_progress_with_dates( ?Lesson_Progress_Interface $progress ): array { return [ 'id' => $progress->get_id(), 'lesson_id' => $progress->get_lesson_id(), diff --git a/tests/unit-tests/internal/student-progress/quiz-progress/models/test-class-comments-based-quiz-progress.php b/tests/unit-tests/internal/student-progress/quiz-progress/models/test-class-comments-based-quiz-progress.php new file mode 100644 index 0000000000..af65810f28 --- /dev/null +++ b/tests/unit-tests/internal/student-progress/quiz-progress/models/test-class-comments-based-quiz-progress.php @@ -0,0 +1,173 @@ +create_progress(); + + /* Act. */ + $actual = $course_progress->get_id(); + + /* Assert. */ + self::assertSame( 1, $actual ); + } + + public function testGetQuizId_ConstructedWithQuizId_ReturnsSameQuizId(): void { + /* Arrange. */ + $course_progress = $this->create_progress(); + + /* Act. */ + $actual = $course_progress->get_quiz_id(); + + /* Assert. */ + self::assertSame( 2, $actual ); + } + + public function testGetUserId_ConstructedWithUserId_ReturnsSameUserId(): void { + /* Arrange. */ + $course_progress = $this->create_progress(); + + /* Act. */ + $actual = $course_progress->get_user_id(); + + /* Assert. */ + self::assertSame( 3, $actual ); + } + + public function testGetStatus_ConstructedWithStatus_ReturnsSameStatus(): void { + /* Arrange. */ + $course_progress = $this->create_progress(); + + /* Act. */ + $actual = $course_progress->get_status(); + + /* Assert. */ + self::assertSame( 'in-progress', $actual ); + } + + public function testGetStartedAt_ConstructedWithStartedAt_ReturnsSameStartedAt(): void { + /* Arrange. */ + $course_progress = $this->create_progress(); + + /* Act. */ + $actual = $course_progress->get_started_at()->format( 'Y-m-d H:i:s' ); + + /* Assert. */ + self::assertSame( '2020-01-01 00:00:00', $actual ); + } + + public function testGetCompletedAt_ConstructedWithCompletedAt_ReturnsSameCompletedAt(): void { + /* Arrange. */ + $course_progress = $this->create_progress(); + + /* Act. */ + $actual = $course_progress->get_completed_at()->format( 'Y-m-d H:i:s' ); + + /* Assert. */ + self::assertSame( '2020-01-01 00:00:01', $actual ); + } + + public function testGetCreatedAt_ConstructedWithCreatedAt_ReturnsSameCreatedAt(): void { + /* Arrange. */ + $course_progress = $this->create_progress(); + + /* Act. */ + $actual = $course_progress->get_created_at()->format( 'Y-m-d H:i:s' ); + + /* Assert. */ + self::assertSame( '2020-01-01 00:00:02', $actual ); + } + + public function testGetUpdatedAt_ConstructedWithUpdatedAt_ReturnsSameUpdatedAt(): void { + /* Arrange. */ + $course_progress = $this->create_progress(); + + /* Act. */ + $actual = $course_progress->get_updated_at()->format( 'Y-m-d H:i:s' ); + + /* Assert. */ + self::assertSame( '2020-01-01 00:00:03', $actual ); + } + + public function testGetUpdatedAt_WhenUpdatedAtSet_ReturnsSameUpdatedAt(): void { + /* Arrange. */ + $course_progress = $this->create_progress(); + $course_progress->set_updated_at( new \DateTime( '2020-01-01 00:00:04' ) ); + + /* Act. */ + $actual = $course_progress->get_updated_at()->format( 'Y-m-d H:i:s' ); + + /* Assert. */ + self::assertSame( '2020-01-01 00:00:04', $actual ); + } + + public function testGetStatus_WhenGradeCalled_ReturnsGradedStatus(): void { + /* Arrange. */ + $course_progress = $this->create_progress(); + $course_progress->grade(); + + /* Act. */ + $actual = $course_progress->get_status(); + + /* Assert. */ + self::assertSame( 'graded', $actual ); + } + + public function testGetStatus_WhenFailCalled_ReturnsFailedStatus(): void { + /* Arrange. */ + $course_progress = $this->create_progress(); + $course_progress->fail(); + + /* Act. */ + $actual = $course_progress->get_status(); + + /* Assert. */ + self::assertSame( 'failed', $actual ); + } + + public function testGetStatus_WhenPassCalled_ReturnsPassedStatus(): void { + /* Arrange. */ + $course_progress = $this->create_progress(); + $course_progress->pass(); + + /* Act. */ + $actual = $course_progress->get_status(); + + /* Assert. */ + self::assertSame( 'passed', $actual ); + } + + public function testGetStatus_WhenUngradeCalled_ReturnsUngradedStatus(): void { + /* Arrange. */ + $course_progress = $this->create_progress(); + $course_progress->ungrade(); + + /* Act. */ + $actual = $course_progress->get_status(); + + /* Assert. */ + self::assertSame( 'ungraded', $actual ); + } + + private function create_progress( string $status = null ): Comments_Based_Quiz_Progress { + return new Comments_Based_Quiz_Progress( + 1, + 2, + 3, + $status ?? 'in-progress', + new \DateTime( '2020-01-01 00:00:00' ), + new \DateTime( '2020-01-01 00:00:01' ), + new \DateTime( '2020-01-01 00:00:02' ), + new \DateTime( '2020-01-01 00:00:03' ) + ); + }} diff --git a/tests/unit-tests/internal/student-progress/quiz-progress/models/test-class-quiz-progress.php b/tests/unit-tests/internal/student-progress/quiz-progress/models/test-class-tables-based-quiz-progress.php similarity index 79% rename from tests/unit-tests/internal/student-progress/quiz-progress/models/test-class-quiz-progress.php rename to tests/unit-tests/internal/student-progress/quiz-progress/models/test-class-tables-based-quiz-progress.php index 955affa8ba..85f92c1add 100644 --- a/tests/unit-tests/internal/student-progress/quiz-progress/models/test-class-quiz-progress.php +++ b/tests/unit-tests/internal/student-progress/quiz-progress/models/test-class-tables-based-quiz-progress.php @@ -2,19 +2,18 @@ namespace SenseiTest\Internal\Student_Progress\Quiz_Progress\Models; -use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress; - +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Tables_Based_Quiz_Progress; /** - * Class Quiz_Progress_Test. + * Class Tables_Based_Quiz_Progress_Test. * - * @covers \Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress + * @covers \Sensei\Internal\Student_Progress\Quiz_Progress\Models\Tables_Based_Quiz_Progress */ -class Quiz_Progress_Test extends \WP_UnitTestCase { +class Tables_Based_Quiz_Progress_Test extends \WP_UnitTestCase { public function testGetId_ConstructedWithId_ReturnsSameId(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); /* Act. */ $actual = $course_progress->get_id(); @@ -25,7 +24,7 @@ public function testGetId_ConstructedWithId_ReturnsSameId(): void { public function testGetQuizId_ConstructedWithQuizId_ReturnsSameQuizId(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); /* Act. */ $actual = $course_progress->get_quiz_id(); @@ -36,7 +35,7 @@ public function testGetQuizId_ConstructedWithQuizId_ReturnsSameQuizId(): void { public function testGetUserId_ConstructedWithUserId_ReturnsSameUserId(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); /* Act. */ $actual = $course_progress->get_user_id(); @@ -47,7 +46,7 @@ public function testGetUserId_ConstructedWithUserId_ReturnsSameUserId(): void { public function testGetStatus_ConstructedWithStatus_ReturnsSameStatus(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); /* Act. */ $actual = $course_progress->get_status(); @@ -58,7 +57,7 @@ public function testGetStatus_ConstructedWithStatus_ReturnsSameStatus(): void { public function testGetStartedAt_ConstructedWithStartedAt_ReturnsSameStartedAt(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); /* Act. */ $actual = $course_progress->get_started_at()->format( 'Y-m-d H:i:s' ); @@ -69,7 +68,7 @@ public function testGetStartedAt_ConstructedWithStartedAt_ReturnsSameStartedAt() public function testGetCompletedAt_ConstructedWithCompletedAt_ReturnsSameCompletedAt(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); /* Act. */ $actual = $course_progress->get_completed_at()->format( 'Y-m-d H:i:s' ); @@ -80,7 +79,7 @@ public function testGetCompletedAt_ConstructedWithCompletedAt_ReturnsSameComplet public function testGetCreatedAt_ConstructedWithCreatedAt_ReturnsSameCreatedAt(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); /* Act. */ $actual = $course_progress->get_created_at()->format( 'Y-m-d H:i:s' ); @@ -91,7 +90,7 @@ public function testGetCreatedAt_ConstructedWithCreatedAt_ReturnsSameCreatedAt() public function testGetUpdatedAt_ConstructedWithUpdatedAt_ReturnsSameUpdatedAt(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); /* Act. */ $actual = $course_progress->get_updated_at()->format( 'Y-m-d H:i:s' ); @@ -102,7 +101,7 @@ public function testGetUpdatedAt_ConstructedWithUpdatedAt_ReturnsSameUpdatedAt() public function testGetUpdatedAt_WhenUpdatedAtSet_ReturnsSameUpdatedAt(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); $course_progress->set_updated_at( new \DateTime( '2020-01-01 00:00:04' ) ); /* Act. */ @@ -114,7 +113,7 @@ public function testGetUpdatedAt_WhenUpdatedAtSet_ReturnsSameUpdatedAt(): void { public function testGetStatus_WhenGradeCalled_ReturnsGradedStatus(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); $course_progress->grade(); /* Act. */ @@ -126,7 +125,7 @@ public function testGetStatus_WhenGradeCalled_ReturnsGradedStatus(): void { public function testGetStatus_WhenFailCalled_ReturnsFailedStatus(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); $course_progress->fail(); /* Act. */ @@ -138,7 +137,7 @@ public function testGetStatus_WhenFailCalled_ReturnsFailedStatus(): void { public function testGetStatus_WhenPassCalled_ReturnsPassedStatus(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); $course_progress->pass(); /* Act. */ @@ -150,7 +149,7 @@ public function testGetStatus_WhenPassCalled_ReturnsPassedStatus(): void { public function testGetStatus_WhenUngradeCalled_ReturnsUngradedStatus(): void { /* Arrange. */ - $course_progress = $this->createProgress(); + $course_progress = $this->create_progress(); $course_progress->ungrade(); /* Act. */ @@ -160,8 +159,8 @@ public function testGetStatus_WhenUngradeCalled_ReturnsUngradedStatus(): void { self::assertSame( 'ungraded', $actual ); } - private function createProgress( string $status = null ): Quiz_Progress { - return new Quiz_Progress( + private function create_progress( string $status = null ): Tables_Based_Quiz_Progress { + return new Tables_Based_Quiz_Progress( 1, 2, 3, diff --git a/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-comment-reading-aggregate-quiz-progress-repository.php b/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-comment-reading-aggregate-quiz-progress-repository.php index 2904aa8726..49c17956c9 100644 --- a/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-comment-reading-aggregate-quiz-progress-repository.php +++ b/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-comment-reading-aggregate-quiz-progress-repository.php @@ -2,7 +2,8 @@ namespace SenseiTest\Internal\Student_Progress\Quiz_Progress\Repositories; -use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Comments_Based_Quiz_Progress; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Tables_Based_Quiz_Progress; use Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Comment_Reading_Aggregate_Quiz_Progress_Repository; use Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Comments_Based_Quiz_Progress_Repository; use Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Tables_Based_Quiz_Progress_Repository; @@ -71,11 +72,12 @@ public function testHas_Always_CallsCommentsBasedRepository(): void { public function testSave_Always_CallsCommentsBasedRepository(): void { /* Arrange. */ - $progress = $this->create_quiz_progress(); + $progress = $this->create_comments_based_quiz_progress(); $comments_based = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); - $tables_based = $this->createMock( Tables_Based_Quiz_Progress_Repository::class ); - $tables_based->method( 'get' )->willReturn( $progress ); + $tables_based_progress = $this->create_tables_based_quiz_progress(); + $tables_based = $this->createMock( Tables_Based_Quiz_Progress_Repository::class ); + $tables_based->method( 'get' )->willReturn( $tables_based_progress ); $repository = new Comment_Reading_Aggregate_Quiz_Progress_Repository( $comments_based, $tables_based ); @@ -89,17 +91,8 @@ public function testSave_Always_CallsCommentsBasedRepository(): void { public function testSave_TablesBasedProgressFound_CallsTablesBasedRepository(): void { /* Arrange. */ - $progress = $this->create_quiz_progress(); - $found_progress = new Quiz_Progress( - 2, - 3, - 4, - 'a', - new \DateTimeImmutable(), - new \DateTimeImmutable(), - new \DateTimeImmutable(), - new \DateTimeImmutable() - ); + $progress = $this->create_comments_based_quiz_progress(); + $found_progress = $this->create_tables_based_quiz_progress(); $comments_based = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Quiz_Progress_Repository::class ); @@ -116,7 +109,7 @@ public function testSave_TablesBasedProgressFound_CallsTablesBasedRepository(): ->method( 'save' ) ->with( $this->callback( - function ( Quiz_Progress $progress_to_save ) use ( $progress, $found_progress ) { + function ( Tables_Based_Quiz_Progress $progress_to_save ) use ( $progress, $found_progress ) { self::assertNotSame( $progress, $progress_to_save, 'We should create a new progress based on a found one: not using passed for saving.' ); self::assertNotSame( $found_progress, $progress_to_save, 'We should create a new progress based on a found one: not the found one itself.' ); return true; @@ -128,9 +121,9 @@ function ( Quiz_Progress $progress_to_save ) use ( $progress, $found_progress ) public function testSave_TablesProgressProgressFound_ConvertsTimeToUtc(): void { /* Arrange. */ - $progress = $this->create_quiz_progress( new \DateTimeImmutable( '2020-01-01 03:00:00', new \DateTimeZone( 'GMT+03:00' ) ) ); + $progress = $this->create_comments_based_quiz_progress( new \DateTimeImmutable( '2020-01-01 03:00:00', new \DateTimeZone( 'GMT+03:00' ) ) ); - $found_progress = $this->create_quiz_progress(); + $found_progress = $this->create_tables_based_quiz_progress(); $comments_based = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Quiz_Progress_Repository::class ); @@ -147,7 +140,7 @@ public function testSave_TablesProgressProgressFound_ConvertsTimeToUtc(): void { ->method( 'save' ) ->with( $this->callback( - function ( Quiz_Progress $progress_to_save ) { + function ( Tables_Based_Quiz_Progress $progress_to_save ) { return '2020-01-01 00:00:00' === $progress_to_save->get_started_at()->format( 'Y-m-d H:i:s' ); } ) @@ -157,8 +150,8 @@ function ( Quiz_Progress $progress_to_save ) { public function testSave_TablesBasedProgressNotFound_CaertesQuizProgress(): void { /* Arrange. */ - $progress = $this->create_quiz_progress(); - $created_progress = $this->create_quiz_progress(); + $progress = $this->create_comments_based_quiz_progress(); + $created_progress = $this->create_tables_based_quiz_progress(); $comments_based = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Quiz_Progress_Repository::class ); @@ -180,7 +173,7 @@ public function testSave_TablesBasedProgressNotFound_CaertesQuizProgress(): void public function testDelete_Always_CallsTablesBasedRepository(): void { /* Arrange. */ - $progress = $this->create_quiz_progress(); + $progress = $this->create_comments_based_quiz_progress(); $comments_based = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Quiz_Progress_Repository::class ); @@ -197,7 +190,7 @@ public function testDelete_Always_CallsTablesBasedRepository(): void { public function testDelete_Always_CallsCommentsBasedRepository(): void { /* Arrange. */ - $progress = $this->create_quiz_progress(); + $progress = $this->create_comments_based_quiz_progress(); $comments_based = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); $tables_based = $this->createMock( Tables_Based_Quiz_Progress_Repository::class ); @@ -278,13 +271,13 @@ public function testDeleteForUser_Always_CallsCommentsBasedRepository(): void { } /** - * Create a quiz progress. + * Create a comments-based quiz progress. * * @param \DateTimeInterface|null $started_at Started at. - * @return Quiz_Progress + * @return Comments_Based_Quiz_Progress */ - public function create_quiz_progress( $started_at = null ): Quiz_Progress { - return new Quiz_Progress( + public function create_comments_based_quiz_progress( $started_at = null ): Comments_Based_Quiz_Progress { + return new Comments_Based_Quiz_Progress( 1, 2, 3, @@ -295,4 +288,23 @@ public function create_quiz_progress( $started_at = null ): Quiz_Progress { new \DateTimeImmutable() ); } + + /** + * Create a tables-based quiz progress. + * + * @param \DateTimeInterface|null $started_at Started at. + * @return Tables_Based_Quiz_Progress + */ + public function create_tables_based_quiz_progress( $started_at = null ): Tables_Based_Quiz_Progress { + return new Tables_Based_Quiz_Progress( + 4, + 2, + 3, + 'b', + $started_at ?? new \DateTimeImmutable(), + new \DateTimeImmutable(), + new \DateTimeImmutable(), + new \DateTimeImmutable() + ); + } } diff --git a/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-comments-based-quiz-progress-repository.php b/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-comments-based-quiz-progress-repository.php index e716ab0685..b139ddd341 100644 --- a/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-comments-based-quiz-progress-repository.php +++ b/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-comments-based-quiz-progress-repository.php @@ -2,7 +2,7 @@ namespace SenseiTest\Internal\Student_Progress\Repositories; -use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress_Interface; use Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Comments_Based_Quiz_Progress_Repository; /** @@ -114,7 +114,7 @@ public function testHas_WhenStatusNotFound_ReturnsFalse(): void { $lesson_id = $this->factory->lesson->create(); $user_id = $this->factory->user->create(); $quiz_id = $this->factory->quiz->create( [ 'post_parent' => $lesson_id ] ); - $repository = new \Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Comments_Based_Quiz_Progress_Repository(); + $repository = new Comments_Based_Quiz_Progress_Repository(); /* Act. */ $actual = $repository->has( $quiz_id, $user_id ); @@ -148,6 +148,17 @@ public function testGet_WhenProgressUpdatedAndSaved_ReturnsMatchingProgress(): v self::assertSame( $expected, $this->export_progress( $actual ) ); } + public function testSave_NonCommentsBasedProgressGiven_ThrowsException(): void { + /* Arrange. */ + $progress = $this->createMock( Quiz_Progress_Interface::class ); + $repository = new Comments_Based_Quiz_Progress_Repository(); + + /* Expect & Act. */ + $this->expectException( \InvalidArgumentException::class ); + $this->expectExceptionMessage( 'Expected Comments_Based_Quiz_Progress, got ' . get_class( $progress ) . '.' ); + $repository->save( $progress ); + } + public function testDelete_ProgressGiven_DeletesAllUserAnswers(): void { /* Arrange. */ $lesson_id = $this->factory->lesson->create(); @@ -290,7 +301,7 @@ public function testDeleteForUser_WhenUserGiven_DeletesGradesForThisUser(): void self::assertSame( $expected, $actual ); } - private function export_progress( Quiz_Progress $progress ): array { + private function export_progress( Quiz_Progress_Interface $progress ): array { return [ 'user_id' => $progress->get_user_id(), 'quiz_id' => $progress->get_quiz_id(), diff --git a/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-table-reading-aggregate-quiz-progress-repository.php b/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-table-reading-aggregate-quiz-progress-repository.php index 6a5a88079b..ba0f53b25b 100644 --- a/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-table-reading-aggregate-quiz-progress-repository.php +++ b/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-table-reading-aggregate-quiz-progress-repository.php @@ -2,7 +2,8 @@ namespace SenseiTest\Internal\Student_Progress\Quiz_Progress\Repositories; -use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Comments_Based_Quiz_Progress; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Tables_Based_Quiz_Progress; use Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Table_Reading_Aggregate_Quiz_Progress_Repository; use Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Tables_Based_Quiz_Progress_Repository; use Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Comments_Based_Quiz_Progress_Repository; @@ -12,7 +13,7 @@ public function testCreate_Always_ReturnsTablesBasedVersion(): void { /* Arrange. */ $comments_based_repository = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); - $created_progress = $this->createMock( \Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress::class ); + $created_progress = $this->createMock( Tables_Based_Quiz_Progress::class ); $tables_based_repository = $this->createMock( Tables_Based_Quiz_Progress_Repository::class ); $tables_based_repository->method( 'create' )->willReturn( $created_progress ); @@ -44,7 +45,7 @@ public function testGet_Always_ReturnsTablesBasedProgress(): void { /* Arrange. */ $comments_based_repository = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); - $created_progress = $this->createMock( \Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress::class ); + $created_progress = $this->createMock( Tables_Based_Quiz_Progress::class ); $tables_based_repository = $this->createMock( Tables_Based_Quiz_Progress_Repository::class ); $tables_based_repository ->method( 'get' ) @@ -109,7 +110,7 @@ public function testHas_Never_CallsCommentsBasedRepository(): void { public function testDelete_Always_CallsTablesBasedRepository(): void { /* Arrange. */ - $progress = $this->createMock( Quiz_Progress::class ); + $progress = $this->createMock( Tables_Based_Quiz_Progress::class ); $progress->method( 'get_quiz_id' )->willReturn( 1 ); $progress->method( 'get_user_id' )->willReturn( 2 ); @@ -128,7 +129,7 @@ public function testDelete_Always_CallsTablesBasedRepository(): void { public function testDelete_CommentsBasedProgressNotFound_DoesntDeleteCommentsBasedProgress(): void { /* Arrange. */ - $progress = $this->createMock( Quiz_Progress::class ); + $progress = $this->createMock( Tables_Based_Quiz_Progress::class ); $progress->method( 'get_quiz_id' )->willReturn( 1 ); $progress->method( 'get_user_id' )->willReturn( 2 ); @@ -151,11 +152,11 @@ public function testDelete_CommentsBasedProgressNotFound_DoesntDeleteCommentsBas public function testDelete_CommentsBasedProgressFound_DeletesCommentsBasedProgress(): void { /* Arrange. */ - $progress = $this->createMock( Quiz_Progress::class ); + $progress = $this->createMock( Tables_Based_Quiz_Progress::class ); $progress->method( 'get_quiz_id' )->willReturn( 1 ); $progress->method( 'get_user_id' )->willReturn( 2 ); - $commets_based_progress = $this->createMock( Quiz_Progress::class ); + $commets_based_progress = $this->createMock( Comments_Based_Quiz_Progress::class ); $comments_based_repository = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); $comments_based_repository ->method( 'get' ) @@ -167,7 +168,7 @@ public function testDelete_CommentsBasedProgressFound_DeletesCommentsBasedProgre $repository = new Table_Reading_Aggregate_Quiz_Progress_Repository( $comments_based_repository, $tables_based_repository ); /* Expect & Act. */ - $tables_based_repository + $comments_based_repository ->expects( $this->once() ) ->method( 'delete' ) ->with( $commets_based_progress ); @@ -237,8 +238,8 @@ public function testDeleteForUser_Always_CallsCommentsBasedRepository(): void { public function testSave_Always_CallsTablesBasedRepository(): void { /* Arrange. */ $date_mock = new \DateTimeImmutable( '2020-01-01' ); - $tables_based_progress = new Quiz_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); - $comments_based_progress = new Quiz_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $tables_based_progress = new Tables_Based_Quiz_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $comments_based_progress = new Comments_Based_Quiz_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); $comments_based_repository = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); $comments_based_repository @@ -261,8 +262,8 @@ public function testSave_Always_CallsTablesBasedRepository(): void { public function testSave_CommentsBasedProgressNotFound_CreatesCommentsBasedProgress(): void { /* Arrange. */ $date_mock = new \DateTimeImmutable( '2020-01-01' ); - $tables_based_progress = new Quiz_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); - $comments_based_progress = new Quiz_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $tables_based_progress = new Tables_Based_Quiz_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $comments_based_progress = new Comments_Based_Quiz_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); $comments_based_repository = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); $comments_based_repository @@ -287,8 +288,8 @@ public function testSave_CommentsBasedProgressNotFound_CreatesCommentsBasedProgr public function testSave_CommentsBasedProgressFound_DoesntCreateCommentsBasedProgress(): void { /* Arrange. */ $date_mock = new \DateTimeImmutable( '2020-01-01' ); - $tables_based_progress = new Quiz_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); - $comments_based_progress = new Quiz_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $tables_based_progress = new Tables_Based_Quiz_Progress( 3, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $comments_based_progress = new Comments_Based_Quiz_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); $comments_based_repository = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); $comments_based_repository @@ -312,8 +313,8 @@ public function testSave_CommentsBasedProgressFound_DoesntCreateCommentsBasedPro public function testSave_Always_SavesToCommentsBasedRepository(): void { /* Arrange. */ $date_mock = new \DateTimeImmutable( '2020-01-01' ); - $tables_based_progress = new Quiz_Progress( 3, 1, 2, 'complete', $date_mock, $date_mock, $date_mock, $date_mock ); - $comments_based_progress = new Quiz_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); + $tables_based_progress = new Tables_Based_Quiz_Progress( 3, 1, 2, 'passed', $date_mock, $date_mock, $date_mock, $date_mock ); + $comments_based_progress = new Comments_Based_Quiz_Progress( 4, 1, 2, 'in-progress', $date_mock, $date_mock, $date_mock, $date_mock ); $comments_based_repository = $this->createMock( Comments_Based_Quiz_Progress_Repository::class ); $comments_based_repository @@ -331,8 +332,8 @@ public function testSave_Always_SavesToCommentsBasedRepository(): void { ->method( 'save' ) ->with( $this->callback( - function ( Quiz_Progress $progress ) { - return 'complete' === $progress->get_status(); + function ( Comments_Based_Quiz_Progress $progress ) { + return 'passed' === $progress->get_status(); } ) ); diff --git a/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-tables-based-quiz-progress-repository.php b/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-tables-based-quiz-progress-repository.php index d4d80ba51b..c1d4bea98b 100644 --- a/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-tables-based-quiz-progress-repository.php +++ b/tests/unit-tests/internal/student-progress/quiz-progress/repositories/test-class-tables-based-quiz-progress-repository.php @@ -3,7 +3,8 @@ namespace SenseiTest\Internal\Student_Progress\Quiz_Progress\Repositories; use DateTimeImmutable; -use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Quiz_Progress_Interface; +use Sensei\Internal\Student_Progress\Quiz_Progress\Models\Tables_Based_Quiz_Progress; use Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Tables_Based_Quiz_Progress_Repository; use wpdb; @@ -243,7 +244,7 @@ public function testHas_WithRealDbAndProgressFound_ReturnsFalse(): void { public function testSave_ProgressGiven_CallsWpdbUpdate(): void { /* Arrange. */ $wpdb = $this->createMock( wpdb::class ); - $progress = new Quiz_Progress( + $progress = new Tables_Based_Quiz_Progress( 1, 2, 3, @@ -285,10 +286,21 @@ function ( $data ) { $repository->save( $progress ); } + public function testSave_NonTablesBasedProgressGiven_ThrowsException(): void { + /* Arrange. */ + $progress = $this->createMock( Quiz_Progress_Interface::class ); + $repository = new Tables_Based_Quiz_Progress_Repository( $this->createMock( wpdb::class ) ); + + /* Expect& Act. */ + $this->expectException( \InvalidArgumentException::class ); + $this->expectExceptionMessage( 'Expected Tables_Based_Quiz_Progress, got ' . get_class( $progress ) . '.' ); + $repository->save( $progress ); + } + public function testDelete_ProgressGiven_CallsWpdbDelete(): void { /* Arrange. */ $wpdb = $this->createMock( wpdb::class ); - $progress = new Quiz_Progress( + $progress = new Tables_Based_Quiz_Progress( 1, 2, 3, @@ -366,7 +378,7 @@ public function testDeleteForUser_UserIdGiven_CallsWpdbDelete(): void { $repository->delete_for_user( 2 ); } - private function export_progress( Quiz_Progress $progress ): array { + private function export_progress( Quiz_Progress_Interface $progress ): array { return [ 'id' => $progress->get_id(), 'quiz_id' => $progress->get_quiz_id(), @@ -375,7 +387,7 @@ private function export_progress( Quiz_Progress $progress ): array { ]; } - private function export_progress_with_dates( ?Quiz_Progress $progress ): array { + private function export_progress_with_dates( ?Quiz_Progress_Interface $progress ): array { return [ 'id' => $progress->get_id(), 'quiz_id' => $progress->get_quiz_id(), diff --git a/tests/unit-tests/internal/student-progress/services/test-class-quiz-deleted-handler.php b/tests/unit-tests/internal/student-progress/services/test-class-quiz-deleted-handler.php index 0194afcc03..d3903a032e 100644 --- a/tests/unit-tests/internal/student-progress/services/test-class-quiz-deleted-handler.php +++ b/tests/unit-tests/internal/student-progress/services/test-class-quiz-deleted-handler.php @@ -2,12 +2,13 @@ namespace SenseiTest\Internal\Student_Progress\Services; +use Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Quiz_Progress_Repository_Interface; use Sensei\Internal\Student_Progress\Services\Quiz_Deleted_Handler; class Quiz_Deleted_Handler_Test extends \WP_UnitTestCase { public function testInit_WhenCalled_AddsAction(): void { /* Arrange. */ - $quiz_progress_repository = $this->createMock( \Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Quiz_Progress_Repository_Interface::class ); + $quiz_progress_repository = $this->createMock( Quiz_Progress_Repository_Interface::class ); $handler = new Quiz_Deleted_Handler( $quiz_progress_repository ); /* Act. */ @@ -21,7 +22,7 @@ public function testInit_WhenCalled_AddsAction(): void { public function testHandle_NonQuizPostGiven_DoesntCallDeleteMethod(): void { /* Arrange. */ $deleted_post = new \WP_Post( (object) [ 'post_type' => 'post' ] ); - $quiz_progress_repository = $this->createMock( \Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Quiz_Progress_Repository_Interface::class ); + $quiz_progress_repository = $this->createMock( Quiz_Progress_Repository_Interface::class ); $handler = new Quiz_Deleted_Handler( $quiz_progress_repository ); /* Expect & Act. */ @@ -34,7 +35,7 @@ public function testHandle_NonQuizPostGiven_DoesntCallDeleteMethod(): void { public function testHandle_QuizGiven_CallsDeleteMethod(): void { /* Arrange. */ $deleted_post = new \WP_Post( (object) [ 'post_type' => 'quiz' ] ); - $quiz_progress_repository = $this->createMock( \Sensei\Internal\Student_Progress\Quiz_Progress\Repositories\Quiz_Progress_Repository_Interface::class ); + $quiz_progress_repository = $this->createMock( Quiz_Progress_Repository_Interface::class ); $handler = new Quiz_Deleted_Handler( $quiz_progress_repository ); /* Expect & Act. */ diff --git a/tests/unit-tests/test-class-quiz.php b/tests/unit-tests/test-class-quiz.php index 349438acc5..c6927e3b23 100644 --- a/tests/unit-tests/test-class-quiz.php +++ b/tests/unit-tests/test-class-quiz.php @@ -1,6 +1,6 @@ createMock( Course_Progress::class ); + $course_progress_mock = $this->createMock( Course_Progress_Interface::class ); $course_progress_mock->method( 'get_started_at' ) ->willReturn( new DateTime( 'now' ) );