diff --git a/.env b/.env index 8099dcd3..696afa31 100644 --- a/.env +++ b/.env @@ -8,8 +8,8 @@ APP_SECRET=29ac4a5187930cd4b689aa0f3ee7cbc0 #--------------------------------# # MySql MOOC_DATABASE_DRIVER=pdo_mysql -MOOC_DATABASE_HOST=codely-php_ddd_skeleton-mooc-mysql -MOOC_DATABASE_PORT=3306 +MOOC_DATABASE_HOST=127.0.0.1 +MOOC_DATABASE_PORT=3360 MOOC_DATABASE_NAME=mooc MOOC_DATABASE_USER=root MOOC_DATABASE_PASSWORD= diff --git a/etc/databases/mooc.sql b/etc/databases/mooc.sql index a999ef78..999103fe 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; @@ -43,7 +43,7 @@ CREATE TRIGGER after_courses_insert FOR EACH ROW BEGIN INSERT INTO mutations (table_name, operation, new_value, mutation_timestamp) - VALUES ('courses', 'INSERT', JSON_OBJECT('id', new.id, 'name', new.name, 'duration', new.duration), NOW()); + VALUES ('courses', 'INSERT', json_object('id', new.id, 'name', new.name, 'duration', new.duration), now()); END; CREATE TRIGGER after_courses_update @@ -54,9 +54,9 @@ BEGIN INSERT INTO mutations (table_name, operation, old_value, new_value, mutation_timestamp) VALUES ('courses', 'UPDATE', - JSON_OBJECT('id', old.id, 'name', old.name, 'duration', old.duration), - JSON_OBJECT('id', new.id, 'name', new.name, 'duration', new.duration), - NOW()); + json_object('id', old.id, 'name', old.name, 'duration', old.duration), + json_object('id', new.id, 'name', new.name, 'duration', new.duration), + now()); END; CREATE TRIGGER after_courses_delete @@ -65,31 +65,61 @@ CREATE TRIGGER after_courses_delete FOR EACH ROW BEGIN INSERT INTO mutations (table_name, operation, old_value, mutation_timestamp) - VALUES ('courses', 'DELETE', JSON_OBJECT('id', old.id, 'name', old.name, 'duration', old.duration), NOW()); + 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 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 +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_unicode_ci; + +CREATE TABLE steps_video ( + id CHAR(36) NOT NULL, + url VARCHAR(255) NOT NULL +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_unicode_ci; + +CREATE TABLE steps_exercise ( + id CHAR(36) NOT NULL, + content VARCHAR(255) NOT NULL +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_unicode_ci; + +CREATE TABLE steps_quiz ( + id CHAR(36) NOT NULL, + questions TEXT NOT NULL +) 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..06e08645 --- /dev/null +++ b/src/Mooc/Steps/Application/Create/CreateVideoStepCommandHandler.php @@ -0,0 +1,12 @@ +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..349ebb57 --- /dev/null +++ b/src/Mooc/Steps/Infrastructure/Persistence/MySqlStepRepository.php @@ -0,0 +1,23 @@ +persist($step); + } + + public function search(StepId $id): ?Step + { + return $this->repository(Step::class)->find($id); + } +} 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 @@ + WordMother::create()); + + 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..4685bd5a --- /dev/null +++ b/tests/Mooc/Steps/Domain/Quiz/QuizStepQuestionMother.php @@ -0,0 +1,21 @@ + 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)); + } + + 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); + } +}