diff --git a/etc/databases/mooc.sql b/etc/databases/mooc.sql index a999ef78..1a094f82 100644 --- a/etc/databases/mooc.sql +++ b/etc/databases/mooc.sql @@ -4,35 +4,35 @@ -- Generic tables -CREATE TABLE `mutations` ( - `id` BIGINT AUTO_INCREMENT PRIMARY KEY, - `table_name` VARCHAR(255) NOT NULL, - `operation` ENUM ('INSERT', 'UPDATE', 'DELETE') NOT NULL, - `old_value` JSON NULL, - `new_value` JSON NULL, - `mutation_timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP +CREATE TABLE mutations ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + table_name VARCHAR(255) NOT NULL, + operation ENUM ('INSERT', 'UPDATE', 'DELETE') NOT NULL, + old_value JSON NULL, + new_value JSON NULL, + mutation_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; -CREATE TABLE `domain_events` ( - `id` CHAR(36) NOT NULL, - `aggregate_id` CHAR(36) NOT NULL, - `name` VARCHAR(255) NOT NULL, - `body` JSON NOT NULL, - `occurred_on` TIMESTAMP NOT NULL, - PRIMARY KEY (`id`) +CREATE TABLE domain_events ( + id CHAR(36) NOT NULL, + aggregate_id CHAR(36) NOT NULL, + name VARCHAR(255) NOT NULL, + body JSON NOT NULL, + occurred_on TIMESTAMP NOT NULL, + PRIMARY KEY (id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; -- Aggregates tables -CREATE TABLE `courses` ( - `id` CHAR(36) NOT NULL, - `name` VARCHAR(255) NOT NULL, - `duration` VARCHAR(255) NOT NULL, - PRIMARY KEY (`id`) +CREATE TABLE courses ( + id CHAR(36) NOT NULL, + name VARCHAR(255) NOT NULL, + duration VARCHAR(255) NOT NULL, + PRIMARY KEY (id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; @@ -68,28 +68,62 @@ BEGIN VALUES ('courses', 'DELETE', JSON_OBJECT('id', old.id, 'name', old.name, 'duration', old.duration), NOW()); END; -CREATE TABLE `courses_counter` ( - `id` CHAR(36) NOT NULL, - `total` INT NOT NULL, - `existing_courses` JSON NOT NULL, - PRIMARY KEY (`id`) +CREATE TABLE courses_counter ( + id CHAR(36) NOT NULL, + total INT NOT NULL, + existing_courses JSON NOT NULL, + PRIMARY KEY (id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; -INSERT INTO `courses_counter` +INSERT INTO courses_counter (id, total, existing_courses) VALUES ("cdf26d7d-3deb-4e8c-9f73-4ac085a8d6f3", 0, "[]"); +CREATE TABLE steps ( + id CHAR(36) NOT NULL, + title VARCHAR(255) NOT NULL, + duration INT NOT NULL, + type VARCHAR(255) NOT NULL, + PRIMARY KEY (id) +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_unicode_ci; + +CREATE TABLE steps_video ( + id CHAR(36) NOT NULL, + url VARCHAR(255) NOT NULL, + FOREIGN KEY (id) REFERENCES steps(id) ON DELETE CASCADE +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_unicode_ci; + +CREATE TABLE steps_exercise ( + id CHAR(36) NOT NULL, + content VARCHAR(255) NOT NULL, + FOREIGN KEY (id) REFERENCES steps(id) ON DELETE CASCADE +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_unicode_ci; + +CREATE TABLE steps_quiz ( + id CHAR(36) NOT NULL, + questions TEXT NOT NULL, + FOREIGN KEY (id) REFERENCES steps(id) ON DELETE CASCADE +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_unicode_ci; + /* ------------------------- BACKOFFICE CONTEXT ---------------------------- */ -CREATE TABLE `backoffice_courses` ( - `id` CHAR(36) NOT NULL, - `name` VARCHAR(255) NOT NULL, - `duration` VARCHAR(255) NOT NULL, - PRIMARY KEY (`id`) +CREATE TABLE backoffice_courses ( + id CHAR(36) NOT NULL, + name VARCHAR(255) NOT NULL, + duration VARCHAR(255) NOT NULL, + PRIMARY KEY (id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci; diff --git a/src/Mooc/Steps/Application/Create/CreateVideoStepCommandHandler.php b/src/Mooc/Steps/Application/Create/CreateVideoStepCommandHandler.php new file mode 100644 index 00000000..34c30189 --- /dev/null +++ b/src/Mooc/Steps/Application/Create/CreateVideoStepCommandHandler.php @@ -0,0 +1,14 @@ +questions = $questions; + } +} diff --git a/src/Mooc/Steps/Domain/Quiz/QuizStepQuestion.php b/src/Mooc/Steps/Domain/Quiz/QuizStepQuestion.php new file mode 100644 index 00000000..15717259 --- /dev/null +++ b/src/Mooc/Steps/Domain/Quiz/QuizStepQuestion.php @@ -0,0 +1,22 @@ +question . '----' . implode('****', $this->answers); + } +} diff --git a/src/Mooc/Steps/Domain/Step.php b/src/Mooc/Steps/Domain/Step.php new file mode 100644 index 00000000..b59277cd --- /dev/null +++ b/src/Mooc/Steps/Domain/Step.php @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Exercise.ExerciseStepContent.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Exercise.ExerciseStepContent.orm.xml new file mode 100644 index 00000000..09e493da --- /dev/null +++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Exercise.ExerciseStepContent.orm.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Quiz.QuizStep.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Quiz.QuizStep.orm.xml new file mode 100644 index 00000000..4b116a56 --- /dev/null +++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Quiz.QuizStep.orm.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/QuizStepQuestionsType.php b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/QuizStepQuestionsType.php new file mode 100644 index 00000000..677fee74 --- /dev/null +++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/QuizStepQuestionsType.php @@ -0,0 +1,40 @@ + $question->toString(), $value), + $platform + ); + } + + public function convertToPHPValue($value, AbstractPlatform $platform): array + { + $scalars = parent::convertToPHPValue($value, $platform); + + return map(fn (string $value): QuizStepQuestion => QuizStepQuestion::fromString($value), $scalars); + } +} diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Step.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Step.orm.xml new file mode 100644 index 00000000..229add0c --- /dev/null +++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Step.orm.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepDuration.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepDuration.orm.xml new file mode 100644 index 00000000..c1307953 --- /dev/null +++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepDuration.orm.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepIdType.php b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepIdType.php new file mode 100644 index 00000000..47b97966 --- /dev/null +++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepIdType.php @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStep.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStep.orm.xml new file mode 100644 index 00000000..5302800f --- /dev/null +++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStep.orm.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStepUrl.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStepUrl.orm.xml new file mode 100644 index 00000000..a4141ba8 --- /dev/null +++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStepUrl.orm.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/src/Mooc/Steps/Infrastructure/Persistence/MySqlStepRepository.php b/src/Mooc/Steps/Infrastructure/Persistence/MySqlStepRepository.php new file mode 100644 index 00000000..45a1151d --- /dev/null +++ b/src/Mooc/Steps/Infrastructure/Persistence/MySqlStepRepository.php @@ -0,0 +1,28 @@ +persist($step); + } + + public function search(StepId $id): ?Step + { + return $this->repository(Step::class)->find($id); + } + + public function delete(Step $step): void + { + $this->remove($step); + } +} diff --git a/tests/Mooc/Steps/Domain/Exercise/ExerciseStepContentMother.php b/tests/Mooc/Steps/Domain/Exercise/ExerciseStepContentMother.php new file mode 100644 index 00000000..eac56c22 --- /dev/null +++ b/tests/Mooc/Steps/Domain/Exercise/ExerciseStepContentMother.php @@ -0,0 +1,16 @@ + QuizStepQuestionMother::create() + ) : $questions; + + return new QuizStep( + $id ?? StepIdMother::create(), + $title ?? StepTitleMother::create(), + $duration ?? StepDurationMother::create(), + ...$stepQuestions + ); + } +} diff --git a/tests/Mooc/Steps/Domain/Quiz/QuizStepQuestionMother.php b/tests/Mooc/Steps/Domain/Quiz/QuizStepQuestionMother.php new file mode 100644 index 00000000..04fcd800 --- /dev/null +++ b/tests/Mooc/Steps/Domain/Quiz/QuizStepQuestionMother.php @@ -0,0 +1,20 @@ + WordMother::create()) + ); + } +} diff --git a/tests/Mooc/Steps/Domain/StepDurationMother.php b/tests/Mooc/Steps/Domain/StepDurationMother.php new file mode 100644 index 00000000..73ce6842 --- /dev/null +++ b/tests/Mooc/Steps/Domain/StepDurationMother.php @@ -0,0 +1,16 @@ +repository()->save($step); + } + + /** + * @test + * @dataProvider steps + */ + public function it_should_search_an_existing_step(Step $step): void + { + $this->repository()->save($step); + + $this->assertEquals($step, $this->repository()->search($step->id)); + } + + /** + * @test + * @dataProvider steps + */ + public function it_should_delete_an_existing_step(Step $step): void + { + $this->repository()->save($step); + $this->repository()->delete($step); + + $this->assertNull($this->repository()->search($step->id)); + } + + public function steps(): array + { + return [ + 'video' => [VideoStepMother::create()], + 'exercise' => [ExerciseStepMother::create()], + 'quiz' => [QuizStepMother::create()], + ]; + } +} diff --git a/tests/Mooc/Steps/StepsModuleInfrastructureTestCase.php b/tests/Mooc/Steps/StepsModuleInfrastructureTestCase.php new file mode 100644 index 00000000..8d0eb52c --- /dev/null +++ b/tests/Mooc/Steps/StepsModuleInfrastructureTestCase.php @@ -0,0 +1,16 @@ +service(StepRepository::class); + } +}