From 719da391d6de8c942ab76cebed4bbfd54d1ffd84 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 20:52:12 +0800 Subject: [PATCH 01/17] Add github workflow (wip) --- .github/workflows/run-tests.yml | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/workflows/run-tests.yml diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000..6c94465 --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,56 @@ +name: Tests + +on: [push, pull_request] + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: true + matrix: + os: [ubuntu-latest, windows-latest] + php: [8.0, 8.1, 8.2] + laravel: [^9.51.0, ^8.83.27, ^10.0.0] + stability: [prefer-lowest, prefer-stable] + include: + - laravel: ^10.0.0 + testbench: ^8.0.0 + - laravel: ^9.51.0 + testbench: ^7.22.0 + - laravel: ^8.83.27 + testbench: ^6.25.1 + exclude: + - php: 8.0 + laravel: ^10.0.0 + - php: 8.1 + laravel: ^8.83.27 + + + name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo + coverage: xdebug + + - name: Setup problem matchers + run: | + echo "::add-matcher::${{ runner.tool_cache }}/php.json" + echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Install dependencies + run: | + composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update + composer update --${{ matrix.stability }} --prefer-dist --no-interaction + + - name: List Installed Dependencies + run: composer show -D + + - name: Execute test + run: vendor/bin/phpunit From a01d4f872025ac8403a3571ef37bf318f566f455 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 21:21:58 +0800 Subject: [PATCH 02/17] Add `composer require nesbot/carbon:^2.68.1 --dev` --- .github/workflows/run-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 6c94465..100231c 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -48,6 +48,7 @@ jobs: run: | composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update composer update --${{ matrix.stability }} --prefer-dist --no-interaction + composer require nesbot/carbon:^2.68.1 --dev - name: List Installed Dependencies run: composer show -D From 09122403a3f5ad514ed23f74f1482c6be628bf81 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 21:26:25 +0800 Subject: [PATCH 03/17] wip --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 100231c..35e10c2 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -10,7 +10,7 @@ jobs: matrix: os: [ubuntu-latest, windows-latest] php: [8.0, 8.1, 8.2] - laravel: [^9.51.0, ^8.83.27, ^10.0.0] + laravel: [^8.83.27, ^9.51.0, ^10.0.0] stability: [prefer-lowest, prefer-stable] include: - laravel: ^10.0.0 From bb9c3854f21ff2921c285a1327f2cf60ec7aab7e Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 21:31:34 +0800 Subject: [PATCH 04/17] Drop PHP 7.3 and laravel below v8 --- .github/workflows/run-tests.yml | 2 +- composer.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 35e10c2..4ef9cbc 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -48,7 +48,7 @@ jobs: run: | composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update composer update --${{ matrix.stability }} --prefer-dist --no-interaction - composer require nesbot/carbon:^2.68.1 --dev + composer require nesbot/carbon:^2.68.1 - name: List Installed Dependencies run: composer show -D diff --git a/composer.json b/composer.json index 0743c66..f8714d4 100644 --- a/composer.json +++ b/composer.json @@ -22,13 +22,13 @@ } ], "require": { - "php": "^7.3|^8.0", - "laravel/framework": "~5.4.0|~5.5.0|~5.6.0|~5.7.0|~5.8.0|^6.0|^7.0|^8.0|^9.0|^10.0" + "php": "^8.0", + "illuminate/contracts": "^8.83.27|^9.51.0|^10.0.0" }, "require-dev": { - "orchestra/testbench": "~3.8|^4.0|^5.0|^7.0|^8.0", + "orchestra/testbench": "^6.25.1|^7.22.0|^8.0.0", "mockery/mockery": "^0.9.4 || ~1.0", - "phpunit/phpunit": "~8.5|^9.0" + "phpunit/phpunit": "^9.0" }, "autoload": { "psr-4": { From 4080d44f7c448d88e21706dc2075cb2f2204d8ed Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 21:44:53 +0800 Subject: [PATCH 05/17] Manage test files Signed-off-by: Lloric Mayuga Garcia --- phpunit.xml | 4 ++-- tests/{ => Feature}/BadgeTest.php | 4 +++- tests/{ => Feature}/PointTest.php | 7 ++++--- tests/{ => Feature}/ReputationTest.php | 9 +++++---- .../Badges/FirstContribution.php | 4 ++-- .../Badges/FirstThousandPoints.php | 4 ++-- tests/{ => Fixtures}/Models/Post.php | 2 +- tests/{ => Fixtures}/Models/Reply.php | 2 +- tests/{ => Fixtures}/Models/User.php | 4 ++-- ...18_09_10_104820_create_test_posts_table.php | 0 ...18_09_17_104820_create_test_users_table.php | 0 ...06_045032_create_test_reputations_table.php | 0 ...8_11_06_205032_create_test_badges_table.php | 0 tests/TestCase.php | 18 ++++++++++-------- 14 files changed, 32 insertions(+), 26 deletions(-) rename tests/{ => Feature}/BadgeTest.php (96%) rename tests/{ => Feature}/PointTest.php (98%) rename tests/{ => Feature}/ReputationTest.php (98%) rename tests/{ => Fixtures}/Badges/FirstContribution.php (82%) rename tests/{ => Fixtures}/Badges/FirstThousandPoints.php (82%) rename tests/{ => Fixtures}/Models/Post.php (92%) rename tests/{ => Fixtures}/Models/Reply.php (87%) rename tests/{ => Fixtures}/Models/User.php (87%) rename tests/{ => Fixtures}/database/migrations/2018_09_10_104820_create_test_posts_table.php (100%) rename tests/{ => Fixtures}/database/migrations/2018_09_17_104820_create_test_users_table.php (100%) rename tests/{ => Fixtures}/database/migrations/2018_11_06_045032_create_test_reputations_table.php (100%) rename tests/{ => Fixtures}/database/migrations/2018_11_06_205032_create_test_badges_table.php (100%) diff --git a/phpunit.xml b/phpunit.xml index 9024953..8f5014e 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -10,8 +10,8 @@ stopOnFailure="false" > - - ./tests/ + + ./tests/Feature diff --git a/tests/BadgeTest.php b/tests/Feature/BadgeTest.php similarity index 96% rename from tests/BadgeTest.php rename to tests/Feature/BadgeTest.php index 5df4071..d2f5f86 100644 --- a/tests/BadgeTest.php +++ b/tests/Feature/BadgeTest.php @@ -1,6 +1,8 @@ loadMigrationsFrom(__DIR__ . '/database/migrations'); + $this->loadMigrationsFrom(__DIR__ . '/Fixtures/database/migrations'); } /** @@ -31,13 +33,13 @@ protected function getEnvironmentSetUp($app) 'prefix' => '', ]); - $app['config']->set('gamify.payee_model', '\QCod\Gamify\Tests\Models\User'); + $app['config']->set('gamify.payee_model', '\QCod\Gamify\Tests\Fixtures\Models\User'); // test badges $app->singleton('badges', function () { - return collect(['FirstContribution', 'FirstThousandPoints']) - ->map(function ($badge) { - return app("QCod\\Gamify\\Tests\Badges\\".$badge); + return collect([FirstContribution::class, FirstThousandPoints::class]) + ->map(function (string $badge) { + return app($badge); }); }); } From 0878fb8159ae93e7f2c5a57d4335bcd4410be475 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 21:51:15 +0800 Subject: [PATCH 06/17] Use pestphp Signed-off-by: Lloric Mayuga Garcia --- composer.json | 8 +++++++- phpunit.xml | 27 +++++++++++++-------------- tests/Pest.php | 6 ++++++ 3 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 tests/Pest.php diff --git a/composer.json b/composer.json index f8714d4..920952e 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,8 @@ "require-dev": { "orchestra/testbench": "^6.25.1|^7.22.0|^8.0.0", "mockery/mockery": "^0.9.4 || ~1.0", - "phpunit/phpunit": "^9.0" + "pestphp/pest": "^2.11", + "pestphp/pest-plugin-laravel": "^2.1" }, "autoload": { "psr-4": { @@ -52,5 +53,10 @@ }, "scripts": { "test": "vendor/bin/phpunit" + }, + "config": { + "allow-plugins": { + "pestphp/pest-plugin": true + } } } diff --git a/phpunit.xml b/phpunit.xml index 8f5014e..48dda83 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,21 +1,20 @@ - - - - ./tests/Feature - - - - - - + + + ./tests/Feature + + + + + diff --git a/tests/Pest.php b/tests/Pest.php new file mode 100644 index 0000000..316daa8 --- /dev/null +++ b/tests/Pest.php @@ -0,0 +1,6 @@ +in('Feature'); From 2f09d86d14cef6d6784a69dc764ebe8be98e4dbe Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 21:56:16 +0800 Subject: [PATCH 07/17] Allow using pest v1 for a lower laravel version Signed-off-by: Lloric Mayuga Garcia --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 920952e..579987d 100644 --- a/composer.json +++ b/composer.json @@ -28,8 +28,8 @@ "require-dev": { "orchestra/testbench": "^6.25.1|^7.22.0|^8.0.0", "mockery/mockery": "^0.9.4 || ~1.0", - "pestphp/pest": "^2.11", - "pestphp/pest-plugin-laravel": "^2.1" + "pestphp/pest": "^1.23.1|^2.11", + "pestphp/pest-plugin-laravel": "^1.4|^2.1" }, "autoload": { "psr-4": { From b3fea69e1bd846ae231f63f89881f64e8bc71f21 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 22:02:29 +0800 Subject: [PATCH 08/17] wip Signed-off-by: Lloric Mayuga Garcia --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 4ef9cbc..aed9e47 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -54,4 +54,4 @@ jobs: run: composer show -D - name: Execute test - run: vendor/bin/phpunit + run: vendor/bin/pest --ci --coverage From bb31920bdb99370c02e510b4a73a1c26da96e52a Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 22:07:00 +0800 Subject: [PATCH 09/17] Install laravel/pint, then run it on test folder Signed-off-by: Lloric Mayuga Garcia --- .github/workflows/run-tests.yml | 2 +- composer.json | 7 +- pint.json | 92 +++++++++++++++++++ tests/Feature/BadgeTest.php | 2 + tests/Feature/PointTest.php | 8 +- tests/Feature/ReputationTest.php | 6 +- tests/Fixtures/Badges/FirstContribution.php | 2 + tests/Fixtures/Badges/FirstThousandPoints.php | 2 + tests/Fixtures/Models/Post.php | 2 + tests/Fixtures/Models/Reply.php | 2 + tests/Fixtures/Models/User.php | 2 + ...8_09_10_104820_create_test_posts_table.php | 2 + ...8_09_17_104820_create_test_users_table.php | 2 + ...6_045032_create_test_reputations_table.php | 2 + ..._11_06_205032_create_test_badges_table.php | 2 + tests/Pest.php | 4 +- tests/TestCase.php | 14 ++- 17 files changed, 135 insertions(+), 18 deletions(-) create mode 100644 pint.json diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index aed9e47..855d8cb 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -54,4 +54,4 @@ jobs: run: composer show -D - name: Execute test - run: vendor/bin/pest --ci --coverage + run: composer test -- --ci diff --git a/composer.json b/composer.json index 579987d..0652fa6 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,8 @@ "orchestra/testbench": "^6.25.1|^7.22.0|^8.0.0", "mockery/mockery": "^0.9.4 || ~1.0", "pestphp/pest": "^1.23.1|^2.11", - "pestphp/pest-plugin-laravel": "^1.4|^2.1" + "pestphp/pest-plugin-laravel": "^1.4|^2.1", + "laravel/pint": "^1.10" }, "autoload": { "psr-4": { @@ -52,7 +53,9 @@ } }, "scripts": { - "test": "vendor/bin/phpunit" + "test": "vendor/bin/pest", + "format": "vendor/bin/pint", + "format-dryrun": "vendor/bin/pint --test" }, "config": { "allow-plugins": { diff --git a/pint.json b/pint.json new file mode 100644 index 0000000..ed80727 --- /dev/null +++ b/pint.json @@ -0,0 +1,92 @@ +{ + "preset": "psr12", + "exclude": [ + "src" + ], + "notPath": [ + ".phpunit.result.cache" + ], + "rules": { + "align_multiline_comment": true, + "array_indentation": true, + "array_syntax": true, + "assign_null_coalescing_to_coalesce_equal": true, + "binary_operator_spaces": true, + "blank_line_before_statement": { + "statements": [ + "break", + "continue", + "declare", + "return", + "throw", + "try" + ] + }, + "cast_spaces": true, + "class_attributes_separation": { + "elements": { + "method": "one" + } + }, + "clean_namespace": true, + "combine_consecutive_issets": true, + "combine_consecutive_unsets": true, + "declare_strict_types": true, + "doctrine_annotation_indentation": true, + "doctrine_annotation_spaces": true, + "fully_qualified_strict_types": true, + "function_typehint_space": true, + "global_namespace_import": true, + "heredoc_indentation": true, + "include": true, + "lambda_not_used_import": true, + "linebreak_after_opening_tag": true, + "list_syntax": true, + "magic_constant_casing": true, + "magic_method_casing": true, + "method_argument_space": { + "on_multiline": "ensure_fully_multiline", + "keep_multiple_spaces_after_comma": true + }, + "method_chaining_indentation": true, + "multiline_comment_opening_closing": true, + "multiline_whitespace_before_semicolons": true, + "native_function_casing": true, + "native_function_type_declaration_casing": true, + "no_alias_language_construct_call": true, + "no_alternative_syntax": true, + "no_empty_comment": true, + "no_empty_statement": true, + "no_extra_blank_lines": true, + "no_leading_namespace_whitespace": true, + "no_mixed_echo_print": true, + "no_multiline_whitespace_around_double_arrow": true, + "no_multiple_statements_per_line": true, + "no_singleline_whitespace_before_semicolons": true, + "no_spaces_around_offset": true, + "no_unneeded_import_alias": true, + "no_unused_imports": true, + "no_whitespace_before_comma_in_array": true, + "no_whitespace_in_blank_line": true, + "not_operator_with_space": true, + "not_operator_with_successor_space": true, + "php_unit_fqcn_annotation": true, + "phpdoc_line_span": { + "const": "single", + "method": "single", + "property": "single" + }, + "phpdoc_scalar": true, + "phpdoc_single_line_var_spacing": true, + "phpdoc_var_without_name": true, + "simple_to_complex_string_variable": true, + "simplified_if_return": true, + "single_quote": true, + "standardize_not_equals": true, + "trailing_comma_in_multiline": true, + "trim_array_spaces": true, + "types_spaces": true, + "unary_operator_spaces": true, + "whitespace_after_comma_in_array": true + } +} diff --git a/tests/Feature/BadgeTest.php b/tests/Feature/BadgeTest.php index d2f5f86..0841cb7 100644 --- a/tests/Feature/BadgeTest.php +++ b/tests/Feature/BadgeTest.php @@ -1,5 +1,7 @@ $post->getMorphClass(), 'subject_id' => $post->id, 'point' => 10, - 'name' => 'FakeCreatePostPoint' + 'name' => 'FakeCreatePostPoint', ]); } @@ -345,8 +347,6 @@ public function __construct($subject) $this->subject = $subject; } - /** - * @var string payee model relation on subject - */ + /** @var string payee model relation on subject */ protected $payee = 'user'; } diff --git a/tests/Feature/ReputationTest.php b/tests/Feature/ReputationTest.php index 5997219..752f787 100644 --- a/tests/Feature/ReputationTest.php +++ b/tests/Feature/ReputationTest.php @@ -1,5 +1,7 @@ reducePoint(3); Event::assertDispatched(ReputationChanged::class, function ($event) use ($user) { - return ($event->point === 3 && $user->id == $event->user->id && !$event->increment); + return ($event->point === 3 && $user->id == $event->user->id && ! $event->increment); }); $this->assertEquals(7, $user->fresh()->getPoints()); @@ -158,7 +160,7 @@ public function __construct($model) */ public function qualifier() { - return !is_null($this->getSubject()->best_reply_id); + return ! is_null($this->getSubject()->best_reply_id); } /** diff --git a/tests/Fixtures/Badges/FirstContribution.php b/tests/Fixtures/Badges/FirstContribution.php index 8abd161..367324e 100644 --- a/tests/Fixtures/Badges/FirstContribution.php +++ b/tests/Fixtures/Badges/FirstContribution.php @@ -1,5 +1,7 @@ in('Feature'); + ->in('Feature'); diff --git a/tests/TestCase.php b/tests/TestCase.php index c22e421..bc8b182 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,5 +1,7 @@ loadMigrationsFrom(__DIR__ . '/Fixtures/database/migrations'); } - /** - * @param \Illuminate\Foundation\Application $app - */ + /** @param \Illuminate\Foundation\Application $app */ protected function getEnvironmentSetUp($app) { $app['config']->set('database.default', 'testbench'); @@ -66,7 +64,7 @@ public function createUser($attrs = []) $user->forceFill(array_merge($attrs, [ 'name' => 'Saqueib', 'email' => 'me@example.com', - 'password' => 'secret' + 'password' => 'secret', ]))->save(); return $user->fresh(); @@ -85,7 +83,7 @@ public function createPost($attrs = []) $post->forceFill(array_merge($attrs, [ 'title' => 'Dummy post title', 'body' => 'I am the content on dummy post', - 'user_id' => 1 + 'user_id' => 1, ]))->save(); return $post->fresh(); From 6e47613efe9deeceba00e7e202284081ea6c3c0a Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 22:13:23 +0800 Subject: [PATCH 10/17] Use laravel/pint:^1.5 Signed-off-by: Lloric Mayuga Garcia --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 0652fa6..5109c95 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,7 @@ "mockery/mockery": "^0.9.4 || ~1.0", "pestphp/pest": "^1.23.1|^2.11", "pestphp/pest-plugin-laravel": "^1.4|^2.1", - "laravel/pint": "^1.10" + "laravel/pint": "^1.5" }, "autoload": { "psr-4": { From 93be447a276d87e39d883ba2f2745b18d55342ec Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 22:56:36 +0800 Subject: [PATCH 11/17] Convert test to pest Signed-off-by: Lloric Mayuga Garcia --- tests/Feature/BadgeTest.php | 104 ++-- tests/Feature/PointTest.php | 512 ++++++------------ tests/Feature/ReputationTest.php | 234 +++----- .../Fake/PointTypes/FakeCreatePostPoint.php | 24 + .../Fake/PointTypes/FakePayeeFieldPoint.php | 20 + .../PointTypes/FakePointTypeWithoutPayee.php | 16 + .../FakePointTypeWithoutSubject.php | 18 + .../Fake/PointTypes/FakePointWithoutPoint.php | 17 + .../FakeWelcomeUserWithFalseQualifier.php | 27 + .../FakeWelcomeUserWithNamePoint.php | 24 + tests/Helpers.php | 46 ++ tests/Pest.php | 4 +- tests/TestCase.php | 77 +-- 13 files changed, 474 insertions(+), 649 deletions(-) create mode 100644 tests/Fixtures/Fake/PointTypes/FakeCreatePostPoint.php create mode 100644 tests/Fixtures/Fake/PointTypes/FakePayeeFieldPoint.php create mode 100644 tests/Fixtures/Fake/PointTypes/FakePointTypeWithoutPayee.php create mode 100644 tests/Fixtures/Fake/PointTypes/FakePointTypeWithoutSubject.php create mode 100644 tests/Fixtures/Fake/PointTypes/FakePointWithoutPoint.php create mode 100644 tests/Fixtures/Fake/PointTypes/FakeWelcomeUserWithFalseQualifier.php create mode 100644 tests/Fixtures/Fake/PointTypes/FakeWelcomeUserWithNamePoint.php create mode 100644 tests/Helpers.php diff --git a/tests/Feature/BadgeTest.php b/tests/Feature/BadgeTest.php index 0841cb7..626e586 100644 --- a/tests/Feature/BadgeTest.php +++ b/tests/Feature/BadgeTest.php @@ -2,80 +2,56 @@ declare(strict_types=1); -namespace QCod\Gamify\Tests\Feature; - -use QCod\Gamify\Tests\TestCase; - -class BadgeTest extends TestCase -{ - /** - * a badge can be given to a user - * - * @test - */ - public function a_badge_can_be_given_to_a_user() - { - $user = $this->createUser(); - $badge = $this->createBadge(); - - $badge->awardTo($user); - - $this->assertCount(1, $user->badges); - $this->assertTrue($user->badges->first()->is($badge)); - } +use function PHPUnit\Framework\assertCount; +use function PHPUnit\Framework\assertEquals; +use function PHPUnit\Framework\assertTrue; - /** - * a badge can be remove from a user - * - * @test - */ - public function a_badge_can_be_remove_from_a_user() - { - $user = $this->createUser(); - $badge = $this->createBadge(); - $badge->awardTo($user); - $this->assertCount(1, $user->badges); - - $badge->removeFrom($user); - - $this->assertCount(0, $user->fresh()->badges); - } +test('a badge can be given to a user', function () { + $user = createUser(); + $badge = createBadge(); + + $badge->awardTo($user); + + assertCount(1, $user->badges); + assertTrue($user->badges->first()->is($badge)); +}); - /** - * a badge is awarded if user point reached 1000 - * - * @test - */ - public function a_badge_is_awarded_if_user_point_reached_1000() - { - $user = $this->createUser(); - $this->assertCount(0, $user->badges); +test('a badge can be remove from a user', function () { + $user = createUser(); + $badge = createBadge(); + $badge->awardTo($user); + assertCount(1, $user->badges); + + $badge->removeFrom($user); + + assertCount(0, $user->fresh()->badges); +}); + +test( + 'a badge is awarded if user point reached 1000', + function () { + $user = createUser(); + assertCount(0, $user->badges); $user->addPoint(1001); - $this->assertCount(1, $user->fresh()->badges); + assertCount(1, $user->fresh()->badges); $user->reducePoint(10); - $this->assertCount(0, $user->fresh()->badges); + assertCount(0, $user->fresh()->badges); } +); - /** - * a badge is given when user first creats a post - * - * @test - */ - public function a_badge_is_given_when_user_first_creats_a_post() - { - $user = $this->createUser(); - $this->assertCount(0, $user->badges); +test('a badge is given when user first creat a post', function () { + $user = createUser(); + assertCount(0, $user->badges); - $this->createPost(['user_id' => $user->id]); - $this->assertCount(0, $user->fresh()->badges); + createPost(['user_id' => $user->id]); + assertCount(0, $user->fresh()->badges); - $user->addPoint(20); - $this->assertCount(1, $user->fresh()->badges); + $user->addPoint(20); + assertCount(1, $user->fresh()->badges); - $this->assertEquals('First Contribution', $user->fresh()->badges->first()->name); - } -} + assertEquals('First Contribution', $user->fresh()->badges->first()->name); +}); diff --git a/tests/Feature/PointTest.php b/tests/Feature/PointTest.php index d0c397f..4bb2aec 100644 --- a/tests/Feature/PointTest.php +++ b/tests/Feature/PointTest.php @@ -2,351 +2,173 @@ declare(strict_types=1); -namespace QCod\Gamify\Tests\Feature; - use QCod\Gamify\Exceptions\InvalidPayeeModel; use QCod\Gamify\Exceptions\PointsNotDefined; use QCod\Gamify\Exceptions\PointSubjectNotSet; -use QCod\Gamify\PointType; -use QCod\Gamify\Tests\Fixtures\Models\User; -use QCod\Gamify\Tests\TestCase; - -class PointTest extends TestCase -{ - /** - * it_sets_point_type_name_from_class_name - * - * @test - */ - public function it_sets_point_type_name_from_class_name() - { - $point = new FakeCreatePostPoint(1); - - $this->assertEquals('FakeCreatePostPoint', $point->getName()); - } - - /** - * it uses name property for point name if provided - * - * @test - */ - public function it_uses_name_property_for_point_name_if_provided() - { - $point = new FakeWelcomeUserWithNamePoint(1); - - $this->assertEquals('FakeName', $point->getName()); - } - - /** - * it can get points for a point type - * - * @test - */ - public function it_can_get_points_for_a_point_type() - { - $point = new FakeCreatePostPoint(1); - - $this->assertEquals(10, $point->getPoints()); - } - - /** - * it gives point to a user - * - * @test - */ - public function it_gives_point_to_a_user() - { - $user = $this->createUser(); - $post = $this->createPost(['user_id' => $user->id]); - - $user->givePoint(new FakeCreatePostPoint($post)); - - $this->assertEquals(10, $user->fresh()->getPoints()); - $this->assertCount(1, $user->reputations); - $this->assertDatabaseHas('reputations', [ - 'payee_id' => $user->id, - 'subject_type' => $post->getMorphClass(), - 'subject_id' => $post->id, - 'point' => 10, - 'name' => 'FakeCreatePostPoint', - ]); - } - - /** - * it can access a reputation payee and subject - * - * @test - */ - public function it_can_access_a_reputation_payee_and_subject() - { - $user = $this->createUser(); - $post = $this->createPost(['user_id' => $user->id]); - - $user->givePoint(new FakeCreatePostPoint($post)); - - $point = $user->reputations()->first(); - - $this->assertEquals($user->id, $point->payee->id); - $this->assertEquals($post->id, $point->subject->id); - - $this->assertEquals('FakeCreatePostPoint', $post->reputations->first()->name); - } - - /** - * it only adds unique point reward if property is set on point type - * - * @test - */ - public function it_only_adds_unique_point_reward_if_property_is_set_on_point_type() - { - $user = $this->createUser(); - $post = $this->createPost(['user_id' => $user->id]); - - $user->givePoint(new FakeCreatePostPoint($post)); - $user->givePoint(new FakeCreatePostPoint($post)); - - $this->assertEquals(10, $user->fresh()->getPoints()); - $this->assertCount(1, $user->reputations); - } - - /** - * it can store duplicate reputations if no property set - * - * @test - */ - public function it_can_store_duplicate_reputations_if_no_property_set() - { - $user = $this->createUser(); - $post = $this->createPost(['user_id' => $user->id]); - - $user->givePoint(new FakeWelcomeUserWithNamePoint($post)); - $user->givePoint(new FakeWelcomeUserWithNamePoint($post)); - - $this->assertEquals(60, $user->fresh()->getPoints()); - $this->assertCount(2, $user->reputations); - } - - /** - * it do not give point if qualifier returns false - * - * @test - */ - public function it_do_not_give_point_if_qualifier_returns_false() - { - $user = $this->createUser(); - $post = $this->createPost(['user_id' => $user->id]); - - $user->givePoint(new FakeWelcomeUserWithFalseQualifier($post)); - - $this->assertEquals(0, $user->fresh()->getPoints()); - $this->assertCount(0, $user->reputations); - } - - /** - * it uses payee field on point as relation if no payee method override - * - * @test - */ - public function it_uses_payee_field_on_point_as_relation_if_no_payee_method_override() - { - $user = $this->createUser(); - $post = $this->createPost(['user_id' => $user->id]); - - $user->givePoint(new FakePayeeFieldPoint($post)); - - $this->assertEquals(10, $user->fresh()->getPoints()); - $this->assertCount(1, $user->reputations); - } - - /** - * it can undo a reward by given model - * - * @test - */ - public function it_can_undo_a_reward_by_given_model() - { - $user = $this->createUser(); - $post = $this->createPost(['user_id' => $user->id]); - $user->givePoint(new FakeWelcomeUserWithNamePoint($post)); - $user->givePoint(new FakeWelcomeUserWithNamePoint($post)); - $this->assertEquals(60, $user->fresh()->getPoints()); - $this->assertCount(2, $user->reputations); - - $user->undoPoint(new FakeWelcomeUserWithNamePoint($post)); - - $this->assertEquals(30, $user->fresh()->getPoints()); - $this->assertCount(1, $user->fresh()->reputations); - - $user->undoPoint(new FakeWelcomeUserWithNamePoint($post)); - - $this->assertEquals(0, $user->fresh()->getPoints()); - $this->assertCount(0, $user->fresh()->reputations); - } - - /** - * it throws exception if no payee is returned - * - * @test - */ - public function it_throws_exception_if_no_payee_is_returned() - { - $user = $this->createUser(); - $this->expectException(InvalidPayeeModel::class); - - $user->givePoint(new FakePointTypeWithoutPayee()); - - $this->assertEquals(0, $user->fresh()->getPoints()); - $this->assertCount(0, $user->reputations); - } - - /** - * it throws exception if no subject is set - * - * @test - */ - public function it_throws_exception_if_no_subject_is_set() - { - $user = $this->createUser(); - $this->expectException(PointSubjectNotSet::class); - - $user->givePoint(new FakePointTypeWithoutSubject()); - - $this->assertEquals(0, $user->fresh()->getPoints()); - $this->assertCount(0, $user->reputations); - } - - /** - * it throws exception if no points field or method is defined - * - * @test - */ - public function it_throws_exception_if_no_points_field_or_method_is_defined() - { - $user = $this->createUser(); - $post = $this->createPost(['user_id' => $user->id]); - $this->expectException(PointsNotDefined::class); - - $user->givePoint(new FakePointWithoutPoint($post)); - - $this->assertEquals(0, $user->fresh()->getPoints()); - $this->assertCount(0, $user->reputations); - } - - /** - * it gives and undo point via helper functions - * - * @test - */ - public function it_gives_and_undo_point_via_helper_functions() - { - $user = $this->createUser(); - $post = $this->createPost(['user_id' => $user->id]); - - givePoint(new FakePayeeFieldPoint($post), $user); - - $this->assertEquals(10, $user->fresh()->getPoints()); - $this->assertCount(1, $user->reputations); - - undoPoint(new FakePayeeFieldPoint($post), $user); - - $user = $user->fresh(); - $this->assertEquals(0, $user->getPoints()); - $this->assertCount(0, $user->reputations); - } -} - -class FakeCreatePostPoint extends PointType -{ - protected $points = 10; - - public $allowDuplicates = false; - - public function __construct($subject) - { - $this->subject = $subject; - } - - public function payee() - { - return $this->getSubject()->user; - } -} - -class FakeWelcomeUserWithNamePoint extends PointType -{ - protected $name = 'FakeName'; - - protected $points = 30; - - public function __construct($subject) - { - $this->subject = $subject; - } - - public function payee() - { - return $this->getSubject()->user; - } -} - -class FakeWelcomeUserWithFalseQualifier extends PointType -{ - protected $points = 10; - - public function __construct($subject) - { - $this->subject = $subject; - } - - public function qualifier() - { - return false; - } - - public function payee() - { - return $this->getSubject()->user; - } -} - -class FakePointTypeWithoutPayee extends PointType -{ - protected $point = 24; - - public function payee() - { - } -} - -class FakePointTypeWithoutSubject extends PointType -{ - protected $point = 12; - - public function payee() - { - return new User(); - } -} - -class FakePointWithoutPoint extends PointType -{ - protected $payee = 'user'; - - public function __construct($subject) - { - $this->subject = $subject; - } -} - -class FakePayeeFieldPoint extends PointType -{ - protected $points = 10; - - public function __construct($subject) - { - $this->subject = $subject; - } - - /** @var string payee model relation on subject */ - protected $payee = 'user'; -} +use QCod\Gamify\Tests\Fixtures\Fake\PointTypes\FakeCreatePostPoint; +use QCod\Gamify\Tests\Fixtures\Fake\PointTypes\FakePayeeFieldPoint; +use QCod\Gamify\Tests\Fixtures\Fake\PointTypes\FakePointTypeWithoutPayee; +use QCod\Gamify\Tests\Fixtures\Fake\PointTypes\FakePointTypeWithoutSubject; +use QCod\Gamify\Tests\Fixtures\Fake\PointTypes\FakePointWithoutPoint; +use QCod\Gamify\Tests\Fixtures\Fake\PointTypes\FakeWelcomeUserWithFalseQualifier; +use QCod\Gamify\Tests\Fixtures\Fake\PointTypes\FakeWelcomeUserWithNamePoint; + +use function Pest\Laravel\assertDatabaseHas; +use function PHPUnit\Framework\assertCount; +use function PHPUnit\Framework\assertEquals; + +it('sets point type name from class name', function () { + $point = new FakeCreatePostPoint(1); + + assertEquals('FakeCreatePostPoint', $point->getName()); +}); + +it('uses name property for point name if provided', function () { + $point = new FakeWelcomeUserWithNamePoint(1); + + assertEquals('FakeName', $point->getName()); +}); + +it('can get points for a point type', function () { + $point = new FakeCreatePostPoint(1); + + assertEquals(10, $point->getPoints()); +}); + +it('gives point to a user', function () { + $user = createUser(); + $post = createPost(['user_id' => $user->id]); + + $user->givePoint(new FakeCreatePostPoint($post)); + + assertEquals(10, $user->fresh()->getPoints()); + assertCount(1, $user->reputations); + assertDatabaseHas('reputations', [ + 'payee_id' => $user->id, + 'subject_type' => $post->getMorphClass(), + 'subject_id' => $post->id, + 'point' => 10, + 'name' => 'FakeCreatePostPoint', + ]); +}); + +it('can access a reputation payee and subject', function () { + $user = createUser(); + $post = createPost(['user_id' => $user->id]); + + $user->givePoint(new FakeCreatePostPoint($post)); + + $point = $user->reputations()->first(); + + assertEquals($user->id, $point->payee->id); + assertEquals($post->id, $point->subject->id); + + assertEquals('FakeCreatePostPoint', $post->reputations->first()->name); +}); + +it('only adds unique point reward if property is set on point type', function () { + $user = createUser(); + $post = createPost(['user_id' => $user->id]); + + $user->givePoint(new FakeCreatePostPoint($post)); + $user->givePoint(new FakeCreatePostPoint($post)); + + assertEquals(10, $user->fresh()->getPoints()); + assertCount(1, $user->reputations); +}); + +it('can store duplicate reputations if no property set', function () { + $user = createUser(); + $post = createPost(['user_id' => $user->id]); + + $user->givePoint(new FakeWelcomeUserWithNamePoint($post)); + $user->givePoint(new FakeWelcomeUserWithNamePoint($post)); + + assertEquals(60, $user->fresh()->getPoints()); + assertCount(2, $user->reputations); +}); + +it('do not give point if qualifier returns false', function () { + $user = createUser(); + $post = createPost(['user_id' => $user->id]); + + $user->givePoint(new FakeWelcomeUserWithFalseQualifier($post)); + + assertEquals(0, $user->fresh()->getPoints()); + assertCount(0, $user->reputations); +}); + +it('uses payee field on point as relation if no payee method override', function () { + $user = createUser(); + $post = createPost(['user_id' => $user->id]); + + $user->givePoint(new FakePayeeFieldPoint($post)); + + assertEquals(10, $user->fresh()->getPoints()); + assertCount(1, $user->reputations); +}); + +it('can undo a reward by given model', function () { + $user = createUser(); + $post = createPost(['user_id' => $user->id]); + $user->givePoint(new FakeWelcomeUserWithNamePoint($post)); + $user->givePoint(new FakeWelcomeUserWithNamePoint($post)); + assertEquals(60, $user->fresh()->getPoints()); + assertCount(2, $user->reputations); + + $user->undoPoint(new FakeWelcomeUserWithNamePoint($post)); + + assertEquals(30, $user->fresh()->getPoints()); + assertCount(1, $user->fresh()->reputations); + + $user->undoPoint(new FakeWelcomeUserWithNamePoint($post)); + + assertEquals(0, $user->fresh()->getPoints()); + assertCount(0, $user->fresh()->reputations); +}); + +it('throws exception if no payee is returned', function () { + $user = createUser(); + $user->givePoint(new FakePointTypeWithoutPayee()); + + assertEquals(0, $user->fresh()->getPoints()); + assertCount(0, $user->reputations); +}) + ->throws(InvalidPayeeModel::class); + +it('throws exception if no subject is set', function () { + $user = createUser(); + + $user->givePoint(new FakePointTypeWithoutSubject()); + + assertEquals(0, $user->fresh()->getPoints()); + assertCount(0, $user->reputations); +}) + ->throws(PointSubjectNotSet::class); + +it('throws exception if no points field or method is defined', function () { + $user = createUser(); + $post = createPost(['user_id' => $user->id]); + + $user->givePoint(new FakePointWithoutPoint($post)); + + assertEquals(0, $user->fresh()->getPoints()); + assertCount(0, $user->reputations); +}) + ->throws(PointsNotDefined::class); + +it('gives and undo point via helper functions', function () { + $user = createUser(); + $post = createPost(['user_id' => $user->id]); + + givePoint(new FakePayeeFieldPoint($post), $user); + + assertEquals(10, $user->fresh()->getPoints()); + assertCount(1, $user->reputations); + + undoPoint(new FakePayeeFieldPoint($post), $user); + + $user = $user->fresh(); + assertEquals(0, $user->getPoints()); + assertCount(0, $user->reputations); +}); diff --git a/tests/Feature/ReputationTest.php b/tests/Feature/ReputationTest.php index 752f787..4a9109d 100644 --- a/tests/Feature/ReputationTest.php +++ b/tests/Feature/ReputationTest.php @@ -2,174 +2,72 @@ declare(strict_types=1); -namespace QCod\Gamify\Tests\Feature; - -use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Event; use QCod\Gamify\Events\ReputationChanged; -use QCod\Gamify\PointType; -use QCod\Gamify\Tests\TestCase; - -class ReputationTest extends TestCase -{ - use RefreshDatabase; - - /** - * it gets user points - * - * @test - */ - public function it_gets_user_points() - { - $user = $this->createUser(['reputation' => 10]); - - $this->assertEquals(10, $user->getPoints()); - } - - /** - * it gives reputation point to a user - * - * @test - */ - public function it_gives_reputation_point_to_a_user() - { - $user = $this->createUser(); - $this->assertEquals(0, $user->getPoints()); - - $user->addPoint(10); - - $this->assertEquals(10, $user->fresh()->getPoints()); - } - - /** - * it reduces reputation point for a user - * - * @test - */ - public function it_reduces_reputation_point_for_a_user() - { - $user = $this->createUser(['reputation' => 20]); - $this->assertEquals(20, $user->reputation); - - $user->reducePoint(5); - - $this->assertEquals(15, $user->fresh()->getPoints()); - } - - /** - * it zeros reputation point of a user - * - * @test - */ - public function it_zeros_reputation_point_of_a_user() - { - $user = $this->createUser(['reputation' => 50]); - $this->assertEquals(50, $user->getPoints()); - - $user->resetPoint(); - - $this->assertEquals(0, $user->fresh()->getPoints()); - } - - /** - * it fires event on reputation change - * - * @test - */ - public function it_fires_event_on_reputation_change() - { - Event::fake(); - - $user = $this->createUser(); - $this->assertEquals(0, $user->getPoints()); - - $user->addPoint(10); - - Event::assertDispatched(ReputationChanged::class, function ($event) use ($user) { - return ($event->point === 10 && $user->id == $event->user->id && $event->increment); - }); - - $this->assertEquals(10, $user->fresh()->getPoints()); - } - - /** - * it fires event on reputation reduced - * - * @test - */ - public function it_fires_event_on_reputation_reduced() - { - Event::fake(); - - $user = $this->createUser(['reputation' => 10]); - - $user->reducePoint(3); - - Event::assertDispatched(ReputationChanged::class, function ($event) use ($user) { - return ($event->point === 3 && $user->id == $event->user->id && ! $event->increment); - }); - - $this->assertEquals(7, $user->fresh()->getPoints()); - } -} - -class FakePostCreated extends PointType -{ - protected $points = 10; - - public function __construct($model) - { - $this->setSubject($model); - } - - /** - * Check qualification for this point - * - * @return bool - */ - public function qualifier() - { - return true; - } - - /** - * User who will be recieving point - * - * @return Model - */ - public function payee() - { - return $this->getSubject()->user; - } -} - -class FakeBestReply extends PointType -{ - protected $points = 50; - - public function __construct($model) - { - $this->setSubject($model); - } - - /** - * Check qualification for this point - * - * @return bool - */ - public function qualifier() - { - return ! is_null($this->getSubject()->best_reply_id); - } - - /** - * User who will be recieving point - * - * @return Model - */ - public function payee() - { - return $this->getSubject()->bestReply->user; - } -} + +use function PHPUnit\Framework\assertEquals; + +uses(RefreshDatabase::class); + +it('gets user points', function () { + $user = createUser(['reputation' => 10]); + + assertEquals(10, $user->getPoints()); +}); + +it('gives reputation point to a user', function () { + $user = createUser(); + assertEquals(0, $user->getPoints()); + + $user->addPoint(10); + + assertEquals(10, $user->fresh()->getPoints()); +}); + +it('reduces reputation point for a user', function () { + $user = createUser(['reputation' => 20]); + assertEquals(20, $user->reputation); + + $user->reducePoint(5); + + assertEquals(15, $user->fresh()->getPoints()); +}); + +it('zeros reputation point of a user', function () { + $user = createUser(['reputation' => 50]); + assertEquals(50, $user->getPoints()); + + $user->resetPoint(); + + assertEquals(0, $user->fresh()->getPoints()); +}); + +it('fires event on reputation change', function () { + Event::fake(); + + $user = createUser(); + assertEquals(0, $user->getPoints()); + + $user->addPoint(10); + + Event::assertDispatched(ReputationChanged::class, function ($event) use ($user) { + return ($event->point === 10 && $user->id == $event->user->id && $event->increment); + }); + + assertEquals(10, $user->fresh()->getPoints()); +}); + +it('fires event on reputation reduced', function () { + Event::fake(); + + $user = createUser(['reputation' => 10]); + + $user->reducePoint(3); + + Event::assertDispatched(ReputationChanged::class, function ($event) use ($user) { + return ($event->point === 3 && $user->id == $event->user->id && ! $event->increment); + }); + + assertEquals(7, $user->fresh()->getPoints()); +}); diff --git a/tests/Fixtures/Fake/PointTypes/FakeCreatePostPoint.php b/tests/Fixtures/Fake/PointTypes/FakeCreatePostPoint.php new file mode 100644 index 0000000..1a1f185 --- /dev/null +++ b/tests/Fixtures/Fake/PointTypes/FakeCreatePostPoint.php @@ -0,0 +1,24 @@ +subject = $subject; + } + + public function payee() + { + return $this->getSubject()->user; + } +} diff --git a/tests/Fixtures/Fake/PointTypes/FakePayeeFieldPoint.php b/tests/Fixtures/Fake/PointTypes/FakePayeeFieldPoint.php new file mode 100644 index 0000000..a12e1a9 --- /dev/null +++ b/tests/Fixtures/Fake/PointTypes/FakePayeeFieldPoint.php @@ -0,0 +1,20 @@ +subject = $subject; + } + + /** @var string payee model relation on subject */ + protected $payee = 'user'; +} diff --git a/tests/Fixtures/Fake/PointTypes/FakePointTypeWithoutPayee.php b/tests/Fixtures/Fake/PointTypes/FakePointTypeWithoutPayee.php new file mode 100644 index 0000000..7b9c5b2 --- /dev/null +++ b/tests/Fixtures/Fake/PointTypes/FakePointTypeWithoutPayee.php @@ -0,0 +1,16 @@ +subject = $subject; + } +} diff --git a/tests/Fixtures/Fake/PointTypes/FakeWelcomeUserWithFalseQualifier.php b/tests/Fixtures/Fake/PointTypes/FakeWelcomeUserWithFalseQualifier.php new file mode 100644 index 0000000..3002bd6 --- /dev/null +++ b/tests/Fixtures/Fake/PointTypes/FakeWelcomeUserWithFalseQualifier.php @@ -0,0 +1,27 @@ +subject = $subject; + } + + public function qualifier() + { + return false; + } + + public function payee() + { + return $this->getSubject()->user; + } +} diff --git a/tests/Fixtures/Fake/PointTypes/FakeWelcomeUserWithNamePoint.php b/tests/Fixtures/Fake/PointTypes/FakeWelcomeUserWithNamePoint.php new file mode 100644 index 0000000..a0295fe --- /dev/null +++ b/tests/Fixtures/Fake/PointTypes/FakeWelcomeUserWithNamePoint.php @@ -0,0 +1,24 @@ +subject = $subject; + } + + public function payee() + { + return $this->getSubject()->user; + } +} diff --git a/tests/Helpers.php b/tests/Helpers.php new file mode 100644 index 0000000..797b1bc --- /dev/null +++ b/tests/Helpers.php @@ -0,0 +1,46 @@ +forceFill(array_merge($attributes, [ + 'name' => 'Saqueib', + 'email' => 'me@example.com', + 'password' => 'secret', + ]))->save(); + + return $user->fresh(); +} + +function createPost($attributes = []): Post +{ + $post = new Post(); + + $post->forceFill(array_merge($attributes, [ + 'title' => 'Dummy post title', + 'body' => 'I am the content on dummy post', + 'user_id' => 1, + ]))->save(); + + return $post->fresh(); +} + +function createBadge($attributes = []): Badge +{ + $badge = new Badge(); + + $badge->forceFill(array_merge($attributes, [ + 'name' => 'New Member', + 'description' => 'Welcome new user', + 'icon' => 'images/new-member-icon.svg', + ]))->save(); + + return $badge->fresh(); +} diff --git a/tests/Pest.php b/tests/Pest.php index 0d24a91..c582fef 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -4,5 +4,7 @@ use QCod\Gamify\Tests\TestCase; -uses(TestCase::class) +uses( + TestCase::class, +) ->in('Feature'); diff --git a/tests/TestCase.php b/tests/TestCase.php index bc8b182..70a8d8f 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,10 +5,9 @@ namespace QCod\Gamify\Tests; use Orchestra\Testbench\TestCase as OrchestraTestCase; -use QCod\Gamify\Badge; +use QCod\Gamify\GamifyServiceProvider; use QCod\Gamify\Tests\Fixtures\Badges\FirstContribution; use QCod\Gamify\Tests\Fixtures\Badges\FirstThousandPoints; -use QCod\Gamify\Tests\Fixtures\Models\Post; use QCod\Gamify\Tests\Fixtures\Models\User; abstract class TestCase extends OrchestraTestCase @@ -22,7 +21,7 @@ protected function setUp(): void } /** @param \Illuminate\Foundation\Application $app */ - protected function getEnvironmentSetUp($app) + protected function getEnvironmentSetUp($app): void { $app['config']->set('database.default', 'testbench'); $app['config']->set('database.connections.testbench', [ @@ -31,80 +30,16 @@ protected function getEnvironmentSetUp($app) 'prefix' => '', ]); - $app['config']->set('gamify.payee_model', '\QCod\Gamify\Tests\Fixtures\Models\User'); + $app['config']->set('gamify.payee_model', User::class); - // test badges $app->singleton('badges', function () { return collect([FirstContribution::class, FirstThousandPoints::class]) - ->map(function (string $badge) { - return app($badge); - }); + ->map(fn (string $badge) => app($badge)); }); } - /** - * @param \Illuminate\Foundation\Application $app - * @return array - */ - protected function getPackageProviders($app) + protected function getPackageProviders($app): array { - return ['QCod\Gamify\GamifyServiceProvider']; - } - - /** - * Create a user - * - * @param array $attrs - * @return User - */ - public function createUser($attrs = []) - { - $user = new User(); - - $user->forceFill(array_merge($attrs, [ - 'name' => 'Saqueib', - 'email' => 'me@example.com', - 'password' => 'secret', - ]))->save(); - - return $user->fresh(); - } - - /** - * Create a post - * - * @param array $attrs - * @return Post - */ - public function createPost($attrs = []) - { - $post = new Post(); - - $post->forceFill(array_merge($attrs, [ - 'title' => 'Dummy post title', - 'body' => 'I am the content on dummy post', - 'user_id' => 1, - ]))->save(); - - return $post->fresh(); - } - - /** - * Create a badge - * - * @param array $attrs - * @return Badge - */ - public function createBadge($attrs = []) - { - $badge = new Badge(); - - $badge->forceFill(array_merge($attrs, [ - 'name' => 'New Member', - 'description' => 'Welcome new user', - 'icon' => 'images/new-member-icon.svg', - ]))->save(); - - return $badge->fresh(); + return [GamifyServiceProvider::class]; } } From 2c12817f9aa3e526f65a7f0daf655c333007f4ce Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 22:57:20 +0800 Subject: [PATCH 12/17] wip Signed-off-by: Lloric Mayuga Garcia --- tests/Helpers.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Helpers.php b/tests/Helpers.php index 797b1bc..3363032 100644 --- a/tests/Helpers.php +++ b/tests/Helpers.php @@ -19,7 +19,7 @@ function createUser(array $attributes = []): User return $user->fresh(); } -function createPost($attributes = []): Post +function createPost(array $attributes = []): Post { $post = new Post(); @@ -32,7 +32,7 @@ function createPost($attributes = []): Post return $post->fresh(); } -function createBadge($attributes = []): Badge +function createBadge(array $attributes = []): Badge { $badge = new Badge(); From 5b5fa14531988270d72d6fe9aae87ea6ccd6286e Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 23:01:21 +0800 Subject: [PATCH 13/17] Use defineDatabaseMigrations() Signed-off-by: Lloric Mayuga Garcia --- tests/TestCase.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/TestCase.php b/tests/TestCase.php index 70a8d8f..9f81117 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -12,11 +12,8 @@ abstract class TestCase extends OrchestraTestCase { - /** @inheritdoc */ - protected function setUp(): void + protected function defineDatabaseMigrations(): void { - parent::setUp(); - $this->loadMigrationsFrom(__DIR__ . '/Fixtures/database/migrations'); } From 0561e81bed00ee4cfae8c24eb693b50d2d0c8f73 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 23:34:33 +0800 Subject: [PATCH 14/17] Make database test migration realtime Signed-off-by: Lloric Mayuga Garcia --- composer.json | 3 +- {src/config => config}/gamify.php | 4 +- .../add_reputation_on_user_table.php.stub | 16 ++--- .../migrations/create_gamify_tables.php.stub | 19 ++---- src/GamifyServiceProvider.php | 58 ++++++------------- ...8_09_10_104820_create_test_posts_table.php | 46 --------------- ...8_09_17_104820_create_test_users_table.php | 39 ------------- ...6_045032_create_test_reputations_table.php | 39 ------------- ..._11_06_205032_create_test_badges_table.php | 45 -------------- tests/TestCase.php | 44 +++++++++++++- 10 files changed, 74 insertions(+), 239 deletions(-) rename {src/config => config}/gamify.php (93%) rename {src => database}/migrations/add_reputation_on_user_table.php.stub (71%) rename {src => database}/migrations/create_gamify_tables.php.stub (83%) delete mode 100644 tests/Fixtures/database/migrations/2018_09_10_104820_create_test_posts_table.php delete mode 100644 tests/Fixtures/database/migrations/2018_09_17_104820_create_test_users_table.php delete mode 100644 tests/Fixtures/database/migrations/2018_11_06_045032_create_test_reputations_table.php delete mode 100644 tests/Fixtures/database/migrations/2018_11_06_205032_create_test_badges_table.php diff --git a/composer.json b/composer.json index 5109c95..0c8eb1d 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ ], "require": { "php": "^8.0", - "illuminate/contracts": "^8.83.27|^9.51.0|^10.0.0" + "illuminate/contracts": "^8.83.27|^9.51.0|^10.0.0", + "spatie/laravel-package-tools": "^1.12" }, "require-dev": { "orchestra/testbench": "^6.25.1|^7.22.0|^8.0.0", diff --git a/src/config/gamify.php b/config/gamify.php similarity index 93% rename from src/config/gamify.php rename to config/gamify.php index b40050a..0fb8f48 100644 --- a/src/config/gamify.php +++ b/config/gamify.php @@ -1,5 +1,7 @@ '\App\User', @@ -33,5 +35,5 @@ ], // Default level - 'badge_default_level' => 1 + 'badge_default_level' => 1, ]; diff --git a/src/migrations/add_reputation_on_user_table.php.stub b/database/migrations/add_reputation_on_user_table.php.stub similarity index 71% rename from src/migrations/add_reputation_on_user_table.php.stub rename to database/migrations/add_reputation_on_user_table.php.stub index 25213db..2c2d852 100644 --- a/src/migrations/add_reputation_on_user_table.php.stub +++ b/database/migrations/add_reputation_on_user_table.php.stub @@ -1,29 +1,21 @@ unsignedInteger('reputation')->default(0)->after('remember_token'); }); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() + public function down(): void { Schema::table('users', function (Blueprint $table) { $table->dropColumn('reputation'); diff --git a/src/migrations/create_gamify_tables.php.stub b/database/migrations/create_gamify_tables.php.stub similarity index 83% rename from src/migrations/create_gamify_tables.php.stub rename to database/migrations/create_gamify_tables.php.stub index d1f05af..2b8da5f 100644 --- a/src/migrations/create_gamify_tables.php.stub +++ b/database/migrations/create_gamify_tables.php.stub @@ -1,19 +1,15 @@ increments('id'); $table->string('name'); @@ -25,7 +21,6 @@ class CreateGamifyTables extends Migration $table->timestamps(); }); - // badges table Schema::create('badges', function (Blueprint $table) { $table->increments('id'); $table->string('name'); @@ -35,7 +30,6 @@ class CreateGamifyTables extends Migration $table->timestamps(); }); - // user_badges pivot Schema::create('user_badges', function (Blueprint $table) { $table->primary(['user_id', 'badge_id']); $table->unsignedInteger('user_id'); @@ -44,12 +38,7 @@ class CreateGamifyTables extends Migration }); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() + public function down(): void { Schema::dropIfExists('user_badges'); Schema::dropIfExists('badges'); diff --git a/src/GamifyServiceProvider.php b/src/GamifyServiceProvider.php index af2335a..7e4e177 100644 --- a/src/GamifyServiceProvider.php +++ b/src/GamifyServiceProvider.php @@ -9,56 +9,36 @@ use QCod\Gamify\Console\MakeBadgeCommand; use QCod\Gamify\Console\MakePointCommand; use QCod\Gamify\Events\ReputationChanged; +use Spatie\LaravelPackageTools\Package; +use Spatie\LaravelPackageTools\PackageServiceProvider; -class GamifyServiceProvider extends ServiceProvider +class GamifyServiceProvider extends PackageServiceProvider { - /** - * Perform post-registration booting of services. - * - * @return void - */ - public function boot() - { - // publish config - $this->publishes([ - __DIR__ . '/config/gamify.php' => config_path('gamify.php'), - ], 'config'); - - $this->mergeConfigFrom(__DIR__ . '/config/gamify.php', 'gamify'); - - // publish migration - if (!class_exists('CreateGamifyTables')) { - $timestamp = date('Y_m_d_His', time()); - $this->publishes([ - __DIR__ . '/migrations/create_gamify_tables.php.stub' => database_path("/migrations/{$timestamp}_create_gamify_tables.php"), - __DIR__ . '/migrations/add_reputation_on_user_table.php.stub' => database_path("/migrations/{$timestamp}_add_reputation_field_on_user_table.php"), - ], 'migrations'); - } - // register commands - if ($this->app->runningInConsole()) { - $this->commands([ + public function configurePackage(Package $package): void + { + $package->name('gamify') + ->hasConfigFile() + ->hasMigrations([ + 'add_reputation_on_user_table', + 'create_gamify_tables', + ]) + ->hasCommands([ MakePointCommand::class, MakeBadgeCommand::class, ]); - } + } - // register event listener + public function packageBooted(): void + { Event::listen(ReputationChanged::class, SyncBadges::class); } - /** - * Register bindings in the container. - * - * @return void - */ - public function register() + public function packageRegistered(): void { $this->app->singleton('badges', function () { return cache()->rememberForever('gamify.badges.all', function () { - return $this->getBadges()->map(function ($badge) { - return new $badge; - }); + return $this->getBadges()->map(fn($badge) => new $badge); }); }); } @@ -66,9 +46,9 @@ public function register() /** * Get all the badge inside app/Gamify/Badges folder * - * @return Collection + * @return Collection */ - protected function getBadges() + protected function getBadges(): Collection { $badgeRootNamespace = config( 'gamify.badge_namespace', diff --git a/tests/Fixtures/database/migrations/2018_09_10_104820_create_test_posts_table.php b/tests/Fixtures/database/migrations/2018_09_10_104820_create_test_posts_table.php deleted file mode 100644 index 514a389..0000000 --- a/tests/Fixtures/database/migrations/2018_09_10_104820_create_test_posts_table.php +++ /dev/null @@ -1,46 +0,0 @@ -increments('id'); - $table->string('title'); - $table->text('body'); - $table->unsignedInteger('best_reply_id')->nullable(); - $table->unsignedInteger('user_id'); - $table->timestamps(); - }); - - Schema::create('replies', function (Blueprint $table) { - $table->increments('id'); - $table->text('body'); - $table->unsignedInteger('user_id'); - $table->unsignedInteger('post_id'); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::dropIfExists('posts'); - Schema::dropIfExists('replies'); - } -} diff --git a/tests/Fixtures/database/migrations/2018_09_17_104820_create_test_users_table.php b/tests/Fixtures/database/migrations/2018_09_17_104820_create_test_users_table.php deleted file mode 100644 index d2ba4e2..0000000 --- a/tests/Fixtures/database/migrations/2018_09_17_104820_create_test_users_table.php +++ /dev/null @@ -1,39 +0,0 @@ -increments('id'); - $table->string('name'); - $table->string('email')->unique(); - $table->timestamp('email_verified_at')->nullable(); - $table->string('password'); - $table->rememberToken(); - $table->unsignedInteger('reputation')->default(0); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::dropIfExists('users'); - } -} diff --git a/tests/Fixtures/database/migrations/2018_11_06_045032_create_test_reputations_table.php b/tests/Fixtures/database/migrations/2018_11_06_045032_create_test_reputations_table.php deleted file mode 100644 index 72e5d77..0000000 --- a/tests/Fixtures/database/migrations/2018_11_06_045032_create_test_reputations_table.php +++ /dev/null @@ -1,39 +0,0 @@ -increments('id'); - $table->string('name'); - $table->mediumInteger('point', false)->default(0); - $table->integer('subject_id')->nullable(); - $table->string('subject_type')->nullable(); - $table->unsignedInteger('payee_id')->nullable(); - $table->text('meta')->nullable(); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::dropIfExists('reputations'); - } -} diff --git a/tests/Fixtures/database/migrations/2018_11_06_205032_create_test_badges_table.php b/tests/Fixtures/database/migrations/2018_11_06_205032_create_test_badges_table.php deleted file mode 100644 index daf1871..0000000 --- a/tests/Fixtures/database/migrations/2018_11_06_205032_create_test_badges_table.php +++ /dev/null @@ -1,45 +0,0 @@ -increments('id'); - $table->string('name'); - $table->string('description')->nullable(); - $table->string('icon')->nullable(); - $table->tinyInteger('level')->default(config('gamify.badge_default_level', 1)); - $table->timestamps(); - }); - - Schema::create('user_badges', function (Blueprint $table) { - $table->primary(['user_id', 'badge_id']); - $table->unsignedInteger('user_id'); - $table->unsignedInteger('badge_id'); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::dropIfExists('user_badges'); - Schema::dropIfExists('badges'); - } -} diff --git a/tests/TestCase.php b/tests/TestCase.php index 9f81117..44fe726 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -4,17 +4,57 @@ namespace QCod\Gamify\Tests; +use Illuminate\Database\Schema\Blueprint; use Orchestra\Testbench\TestCase as OrchestraTestCase; use QCod\Gamify\GamifyServiceProvider; use QCod\Gamify\Tests\Fixtures\Badges\FirstContribution; use QCod\Gamify\Tests\Fixtures\Badges\FirstThousandPoints; use QCod\Gamify\Tests\Fixtures\Models\User; +use AddReputationFieldOnUserTable; +use CreateGamifyTables; abstract class TestCase extends OrchestraTestCase { - protected function defineDatabaseMigrations(): void + protected function setUp(): void { - $this->loadMigrationsFrom(__DIR__ . '/Fixtures/database/migrations'); + parent::setUp(); + $this->setUpDatabase($this->app); + } + + protected function setUpDatabase($app): void + { + $schema = $app['db']->connection()->getSchemaBuilder(); + + $schema->create('posts', function (Blueprint $table) { + $table->increments('id'); + $table->string('title'); + $table->text('body'); + $table->unsignedInteger('best_reply_id')->nullable(); + $table->unsignedInteger('user_id'); + $table->timestamps(); + }); + $schema->create('replies', function (Blueprint $table) { + $table->increments('id'); + $table->text('body'); + $table->unsignedInteger('user_id'); + $table->unsignedInteger('post_id'); + $table->timestamps(); + }); + $schema->create('users', function (Blueprint $table) { + $table->increments('id'); + $table->string('name'); + $table->string('email')->unique(); + $table->timestamp('email_verified_at')->nullable(); + $table->string('password'); + $table->rememberToken(); + $table->timestamps(); + }); + + include_once __DIR__.'/../database/migrations/add_reputation_on_user_table.php.stub'; + (new AddReputationFieldOnUserTable())->up(); + + include_once __DIR__.'/../database/migrations/create_gamify_tables.php.stub'; + (new CreateGamifyTables())->up(); } /** @param \Illuminate\Foundation\Application $app */ From f8db65851b5cc5bcce9a073f55ddc11842c193e3 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Wed, 2 Aug 2023 23:40:23 +0800 Subject: [PATCH 15/17] Make model dynamic Signed-off-by: Lloric Mayuga Garcia --- database/migrations/add_reputation_on_user_table.php.stub | 4 ++-- tests/Fixtures/Models/Post.php | 3 +-- tests/Fixtures/Models/Reply.php | 3 ++- tests/Fixtures/Models/User.php | 5 +++-- tests/TestCase.php | 8 +++++--- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/database/migrations/add_reputation_on_user_table.php.stub b/database/migrations/add_reputation_on_user_table.php.stub index 2c2d852..39cd41c 100644 --- a/database/migrations/add_reputation_on_user_table.php.stub +++ b/database/migrations/add_reputation_on_user_table.php.stub @@ -10,14 +10,14 @@ class AddReputationFieldOnUserTable extends Migration { public function up(): void { - Schema::table('users', function (Blueprint $table) { + Schema::table(app(config('gamify.payee_model'))->getTable(), function (Blueprint $table) { $table->unsignedInteger('reputation')->default(0)->after('remember_token'); }); } public function down(): void { - Schema::table('users', function (Blueprint $table) { + Schema::table(app(config('gamify.payee_model'))->getTable(), function (Blueprint $table) { $table->dropColumn('reputation'); }); } diff --git a/tests/Fixtures/Models/Post.php b/tests/Fixtures/Models/Post.php index a74fb43..e8ce3a3 100644 --- a/tests/Fixtures/Models/Post.php +++ b/tests/Fixtures/Models/Post.php @@ -8,10 +8,9 @@ class Post extends Model { - public $table = 'posts'; + public $table = 'test_posts'; protected $guarded = []; - protected $connection = 'testbench'; public function replies() { diff --git a/tests/Fixtures/Models/Reply.php b/tests/Fixtures/Models/Reply.php index 9165310..c933430 100644 --- a/tests/Fixtures/Models/Reply.php +++ b/tests/Fixtures/Models/Reply.php @@ -8,8 +8,9 @@ class Reply extends Model { + public $table = 'test_replies'; + protected $guarded = []; - protected $connection = 'testbench'; public function user() { diff --git a/tests/Fixtures/Models/User.php b/tests/Fixtures/Models/User.php index 832dbf6..29d67a4 100644 --- a/tests/Fixtures/Models/User.php +++ b/tests/Fixtures/Models/User.php @@ -11,9 +11,10 @@ class User extends Model { use Gamify; + // used in config to alter a project level model + public $table = 'test_users'; + protected $guarded = []; - protected $connection = 'testbench'; - public $table = 'users'; public function posts() { diff --git a/tests/TestCase.php b/tests/TestCase.php index 44fe726..ea41459 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -9,6 +9,8 @@ use QCod\Gamify\GamifyServiceProvider; use QCod\Gamify\Tests\Fixtures\Badges\FirstContribution; use QCod\Gamify\Tests\Fixtures\Badges\FirstThousandPoints; +use QCod\Gamify\Tests\Fixtures\Models\Post; +use QCod\Gamify\Tests\Fixtures\Models\Reply; use QCod\Gamify\Tests\Fixtures\Models\User; use AddReputationFieldOnUserTable; use CreateGamifyTables; @@ -25,7 +27,7 @@ protected function setUpDatabase($app): void { $schema = $app['db']->connection()->getSchemaBuilder(); - $schema->create('posts', function (Blueprint $table) { + $schema->create((new Post())->getTable(), function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->text('body'); @@ -33,14 +35,14 @@ protected function setUpDatabase($app): void $table->unsignedInteger('user_id'); $table->timestamps(); }); - $schema->create('replies', function (Blueprint $table) { + $schema->create((new Reply())->getTable(), function (Blueprint $table) { $table->increments('id'); $table->text('body'); $table->unsignedInteger('user_id'); $table->unsignedInteger('post_id'); $table->timestamps(); }); - $schema->create('users', function (Blueprint $table) { + $schema->create((new User())->getTable(), function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); From 3c967d3c615998ae5863ba3c6aa2b35495458b1e Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Thu, 3 Aug 2023 08:44:29 +0800 Subject: [PATCH 16/17] ide helper Signed-off-by: Lloric Mayuga Garcia --- tests/Fixtures/Models/Post.php | 24 ++++++++++++++++++------ tests/Fixtures/Models/Reply.php | 10 ++++++++-- tests/Fixtures/Models/User.php | 10 ++++++++-- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/tests/Fixtures/Models/Post.php b/tests/Fixtures/Models/Post.php index e8ce3a3..95ed0d8 100644 --- a/tests/Fixtures/Models/Post.php +++ b/tests/Fixtures/Models/Post.php @@ -5,30 +5,42 @@ namespace QCod\Gamify\Tests\Fixtures\Models; use Illuminate\Database\Eloquent\Model; - +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\HasOne; +use Illuminate\Database\Eloquent\Relations\MorphMany; +use QCod\Gamify\Reputation; + +/** + * @property int $id + * @property-read \Illuminate\Database\Eloquent\Collection|\QCod\Gamify\Tests\Fixtures\Models\Reply[] $replies + * @property-read \QCod\Gamify\Tests\Fixtures\Models\User $user + * @property-read \QCod\Gamify\Tests\Fixtures\Models\Reply|null $bestReply + * @property-read \Illuminate\Database\Eloquent\Collection $reputations + */ class Post extends Model { public $table = 'test_posts'; protected $guarded = []; - public function replies() + public function replies(): HasMany { return $this->hasMany(Reply::class)->latest(); } - public function user() + public function user(): BelongsTo { return $this->belongsTo(User::class); } - public function bestReply() + public function bestReply(): HasOne { return $this->hasOne(Reply::class, 'id', 'best_reply_id'); } - public function reputations() + public function reputations(): MorphMany { - return $this->morphMany('QCod\Gamify\Reputation', 'subject'); + return $this->morphMany(Reputation::class, 'subject'); } } diff --git a/tests/Fixtures/Models/Reply.php b/tests/Fixtures/Models/Reply.php index c933430..0a824af 100644 --- a/tests/Fixtures/Models/Reply.php +++ b/tests/Fixtures/Models/Reply.php @@ -5,19 +5,25 @@ namespace QCod\Gamify\Tests\Fixtures\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +/** + * @property int $id + * @property-read \QCod\Gamify\Tests\Fixtures\Models\User $user + * @property-read \QCod\Gamify\Tests\Fixtures\Models\Post $post + */ class Reply extends Model { public $table = 'test_replies'; protected $guarded = []; - public function user() + public function user(): BelongsTo { return $this->belongsTo(User::class); } - public function post() + public function post(): BelongsTo { return $this->belongsTo(Post::class); } diff --git a/tests/Fixtures/Models/User.php b/tests/Fixtures/Models/User.php index 29d67a4..c6189b2 100644 --- a/tests/Fixtures/Models/User.php +++ b/tests/Fixtures/Models/User.php @@ -5,18 +5,24 @@ namespace QCod\Gamify\Tests\Fixtures\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\HasMany; use QCod\Gamify\Gamify; +/** + * @property int $id + * @property-read \Illuminate\Database\Eloquent\Collection $badges + * @property-read \Illuminate\Database\Eloquent\Collection $reputations + * @property-read \Illuminate\Database\Eloquent\Collection $posts + */ class User extends Model { use Gamify; - // used in config to alter a project level model public $table = 'test_users'; protected $guarded = []; - public function posts() + public function posts(): HasMany { return $this->hasMany(Post::class); } From 7e176243ebd57aea32bc1a07902af0d2d737b825 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Thu, 3 Aug 2023 08:48:15 +0800 Subject: [PATCH 17/17] ide helper Signed-off-by: Lloric Mayuga Garcia --- src/HasBadges.php | 4 ++++ src/HasReputations.php | 4 ++++ tests/Fixtures/Models/User.php | 2 -- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/HasBadges.php b/src/HasBadges.php index 6cdd50f..0f9e7f6 100644 --- a/src/HasBadges.php +++ b/src/HasBadges.php @@ -2,6 +2,10 @@ namespace QCod\Gamify; +/** + * @property-read \Illuminate\Database\Eloquent\Collection $badges + * @property-read int|null $badges_count + */ trait HasBadges { /** diff --git a/src/HasReputations.php b/src/HasReputations.php index 8b46717..b0410cf 100644 --- a/src/HasReputations.php +++ b/src/HasReputations.php @@ -4,6 +4,10 @@ use QCod\Gamify\Events\ReputationChanged; +/** + * @property-read \Illuminate\Database\Eloquent\Collection $reputations + * @property-read int|null $reputations_count + */ trait HasReputations { /** diff --git a/tests/Fixtures/Models/User.php b/tests/Fixtures/Models/User.php index c6189b2..1b03076 100644 --- a/tests/Fixtures/Models/User.php +++ b/tests/Fixtures/Models/User.php @@ -10,8 +10,6 @@ /** * @property int $id - * @property-read \Illuminate\Database\Eloquent\Collection $badges - * @property-read \Illuminate\Database\Eloquent\Collection $reputations * @property-read \Illuminate\Database\Eloquent\Collection $posts */ class User extends Model