Repository: mohamednagy/Laravel-rating Branch: master Commit: febd673ab877 Files: 37 Total size: 40.1 KB Directory structure: gitextract_thniymky/ ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── CONTRIBUTING.md │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ └── config.yml │ ├── SECURITY.md │ └── workflows/ │ ├── php-cs-fixer.yml │ ├── psalm.yml │ └── run-tests.yml ├── .gitignore ├── .php_cs.dist ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json ├── database/ │ └── migrations/ │ ├── add_type_column_to_ratings_table.php.stub │ └── create_ratings_table.php.stub ├── phpunit.xml.dist ├── psalm.xml.dist ├── src/ │ ├── LaravelRating.php │ ├── LaravelRatingFacade.php │ ├── LaravelRatingServiceProvider.php │ ├── Models/ │ │ └── Rating.php │ └── Traits/ │ ├── Like/ │ │ ├── CanLike.php │ │ └── Likeable.php │ ├── Rate/ │ │ ├── CanRate.php │ │ └── Rateable.php │ └── Vote/ │ ├── CanVote.php │ └── Votable.php └── tests/ ├── LikeTest.php ├── Models/ │ ├── Post.php │ └── User.php ├── RatingTest.php ├── TestCase.php ├── VotingTest.php └── database/ └── migrations/ ├── create_posts_table.php └── create_users_table.php ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] charset = utf-8 indent_size = 4 indent_style = space end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false [*.{yml,yaml}] indent_size = 2 ================================================ FILE: .gitattributes ================================================ # Path-based git attributes # https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html # Ignore all test and documentation with "export-ignore". /.github export-ignore /.gitattributes export-ignore /.gitignore export-ignore /phpunit.xml.dist export-ignore /tests export-ignore /.editorconfig export-ignore /.php_cs.dist export-ignore /psalm.xml export-ignore /psalm.xml.dist export-ignore ================================================ FILE: .github/CONTRIBUTING.md ================================================ # Contributing Contributions are **welcome** and will be fully **credited**. Please read and understand the contribution guide before creating an issue or pull request. ## Etiquette This project is open source, and as such, the maintainers give their free time to build and maintain the source code held within. They make the code freely available in the hope that it will be of use to other developers. It would be extremely unfair for them to suffer abuse or anger for their hard work. Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the world that developers are civilized and selfless people. It's the duty of the maintainer to ensure that all submissions to the project are of sufficient quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used. ## Viability When requesting or submitting new features, first consider whether it might be useful to others. Open source projects are used by many developers, who may have entirely different needs to your own. Think about whether or not your feature is likely to be used by other users of the project. ## Procedure Before filing an issue: - Attempt to replicate the problem, to ensure that it wasn't a coincidental incident. - Check to make sure your feature suggestion isn't already present within the project. - Check the pull requests tab to ensure that the bug doesn't have a fix in progress. - Check the pull requests tab to ensure that the feature isn't already in progress. Before submitting a pull request: - Check the codebase to ensure that your feature doesn't already exist. - Check the pull requests to ensure that another person hasn't already submitted the feature or fix. ## Requirements If the project maintainer has any additional requirements, you will find them listed here. - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](https://pear.php.net/package/PHP_CodeSniffer). - **Add tests!** - Your patch won't be accepted if it doesn't have tests. - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. - **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option. - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. **Happy coding**! ================================================ FILE: .github/FUNDING.yml ================================================ github: nagy ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false contact_links: - name: Report a bug url: https://github.com/mohamednagy/laravel-rating/issues/new about: Report a reproducable bug ================================================ FILE: .github/SECURITY.md ================================================ # Security Policy If you discover any security related issues, please email mohamed.n.haleem@gmail.com instead of using the issue tracker. ================================================ FILE: .github/workflows/php-cs-fixer.yml ================================================ name: Check & fix styling on: [push] jobs: php-cs-fixer: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 with: ref: ${{ github.head_ref }} - name: Run PHP CS Fixer uses: docker://oskarstark/php-cs-fixer-ga with: args: --config=.php_cs.dist --allow-risky=yes - name: Commit changes uses: stefanzweifel/git-auto-commit-action@v4 with: commit_message: Fix styling ================================================ FILE: .github/workflows/psalm.yml ================================================ name: Psalm on: push: paths: - '**.php' - 'psalm.xml.dist' jobs: psalm: name: psalm runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: '7.4' extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick coverage: none - name: Cache composer dependencies uses: actions/cache@v2 with: path: vendor key: composer-${{ hashFiles('composer.lock') }} - name: Run composer install run: composer install -n --prefer-dist - name: Run psalm run: ./vendor/bin/psalm --output-format=github ================================================ FILE: .github/workflows/run-tests.yml ================================================ name: run-tests on: [push, pull_request] jobs: test: runs-on: ${{ matrix.os }} strategy: fail-fast: true matrix: os: [ubuntu-latest, windows-latest] php: [8.0, 7.4, 7.3] laravel: ["^8.0", "^7.0", "^6.0"] stability: [prefer-stable] include: - laravel: ^8.0 os: ubuntu-latest testbench: ^6.0 - laravel: ^7.0 os: ubuntu-latest testbench: ^5.0 - laravel: ^6.0 os: ubuntu-latest testbench: ^4.0 name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} steps: - name: Checkout code uses: actions/checkout@v2 - 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: none - 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: Execute tests run: vendor/bin/phpunit ================================================ FILE: .gitignore ================================================ .idea .php_cs .php_cs.cache .phpunit.result.cache build composer.lock coverage docs phpunit.xml psalm.xml vendor ================================================ FILE: .php_cs.dist ================================================ notPath('bootstrap/*') ->notPath('storage/*') ->notPath('resources/view/mail/*') ->in([ __DIR__ . '/src', __DIR__ . '/tests', ]) ->name('*.php') ->notName('*.blade.php') ->ignoreDotFiles(true) ->ignoreVCS(true); return PhpCsFixer\Config::create() ->setRules([ '@PSR2' => true, 'array_syntax' => ['syntax' => 'short'], 'ordered_imports' => ['sortAlgorithm' => 'alpha'], 'no_unused_imports' => true, 'not_operator_with_successor_space' => true, 'trailing_comma_in_multiline_array' => true, 'phpdoc_scalar' => true, 'unary_operator_spaces' => true, 'binary_operator_spaces' => true, 'blank_line_before_statement' => [ 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'], ], 'phpdoc_single_line_var_spacing' => true, 'phpdoc_var_without_name' => true, 'class_attributes_separation' => [ 'elements' => [ 'method', ], ], 'method_argument_space' => [ 'on_multiline' => 'ensure_fully_multiline', 'keep_multiple_spaces_after_comma' => true, ], 'single_trait_insert_per_statement' => true, ]) ->setFinder($finder); ================================================ FILE: CHANGELOG.md ================================================ # Changelog All notable changes to `laravel-rating` will be documented in this file. ## 1.0.0 - 202X-XX-XX - initial release ================================================ FILE: LICENSE.md ================================================ The MIT License (MIT) Copyright (c) nagy Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================

               

# New Maintainer This package now maintined by [Ahmed Nagi](https://twitter.com/nagiworks) # Laravel-Ratings Laravel package that allows you to **rate, like & dislike or vote up & down** your models with a simple and clear way.
*If you see this packge can help, Don't skimp on me with a star :)* * [Install](https://github.com/mohamednagy/Laravel-rating#install) * [Rating](https://github.com/mohamednagy/Laravel-rating#rating) * [Like & Dislike](https://github.com/mohamednagy/Laravel-rating#like--dislike) * [Voting](https://github.com/mohamednagy/Laravel-rating#voting) ## Rating include `CanRate` trait into your user model to apply rating functions ```php use Nagy\LaravelRating\Traits\Rate\CanRate; class User extends Model { use CanRate; ``` include `Rateable` trait to your model that will be rateable ```php use Nagy\LaravelRating\Traits\Rate\Rateable; class Post extends Model { use Rateable; ``` now you can rate your models as the following: ```php $user->rate($postModel, 5); ``` also you can unrate your models as the following: ```php $user->unrate($postModel); // alternatively $user->rate($postModel, -1); // or $user->rate($postModel, false); // or $user->rate($postModel, null); ``` get the average ratings of a model ```php $post->ratingsAvg(); ``` get the total count of ratings of a model ```php $post->ratingsCount(); ``` get the rated models by a user ```php $user->rated(); // returns a collection of rated models ``` ## Voting include `CanVote` trait into your user model to apply rating functionalties ```php use Nagy\LaravelRating\Traits\Vote\CanVote; class User extends Model { use CanVote; ``` include `Votable` trait to your model that will be votable ```php use Nagy\LaravelRating\Traits\Vote\Votable; class Post extends Model { use Votable; ``` now you can vote your model as the following: ```php // up vote or +1 your model $user->upVote($postModel); // down vote or -1 your model $user->downVote($postModel); ``` get total votes count ```php $postModel->votesCount(); ``` get total up votes count ```php $postModel->upVotesCount(); ``` get total down votes count ```php $postModel->downVotesCount(); ``` get the up voted models by a user ```php $user->upVoted(); // returns a collection of up voted models ``` get the down voted models by a user ```php $user->downVoted(); // returns a collection of down voted models ``` get the total voted models by a user ```php $user->voted(); // returns a collection of total voted models; ``` ## Like & Dislike include `CanLike` trait into your user model to apply like and dislike functionalties ```php use Nagy\LaravelRating\Traits\Like\CanLike; class User extends Model { use CanLike; ``` include `Likeable` trait to your model that will be likeable ```php use Nagy\LaravelRating\Traits\Like\Likeable; class Post extends Model { use Likeable; ``` now you can like your model as the following: ```php // like $user->like($postModel); // dislike $user->dislike($postModel); ``` get total likes count ```php $postModel->likesCount(); ``` get total dislikes count ```php $postModel->dislikesCount(); ``` get total likes and dislikes count ```php $postModel->likesDislikesCount(); ``` get the liked models by a user ```php $user->liked(); // return a collection of liked models; ``` get the disliked models by a user ```php $user->disliked(); // return a collection of disliked models; ``` get the total liked and disliked models by a user ```php $user->likedDisliked(); // return a collection of liked and disliked models; ``` # Install for laravel 8.* , 7.* , 6.* ```bash composer require nagy/laravel-rating ``` for laravel 5.* ```bash composer require nagy/laravel-rating:^1.2 ``` in your config/app.php ```php 'providers' => [ ... Nagy\LaravelRating\LaravelRatingServiceProvider::class ], 'aliases' => [ ... "LaravelRating" => \Nagy\LaravelRating\LaravelRatingFacade::class, ] ``` > You don't need this step in laravel5.5 `package:discover` will do the job :) publish the migrations ```bash php artisan vendor:publish --tag=laravelRatings ``` run the migrations ```bash php artisan migrate ``` ================================================ FILE: composer.json ================================================ { "name": "nagy/laravel-rating", "description": "manage rating column for elqouent models", "keywords": [ "nagy", "laravel-rating" ], "homepage": "https://github.com/nagy/laravel-rating", "license": "MIT", "authors": [ { "name": "Ahmed Nagi", "email": "info@ahmednagi.com", "role": "Developer" }, { "name": "Mohamed Nagy", "email": "mohamed.n.haleem@gmail.com", "role": "Developer" } ], "require": { "php": "^8.0|^7.3", "illuminate/contracts": "^8.0|^7.0|^6.0" }, "require-dev": { "orchestra/testbench": "^6.0|^5.0|^4.0", "phpunit/phpunit": "^9.3|^8.0", "vimeo/psalm": "^4.4" }, "autoload": { "psr-4": { "Nagy\\LaravelRating\\": "src", "Nagy\\LaravelRating\\Database\\Factories\\": "database/factories" } }, "autoload-dev": { "psr-4": { "Nagy\\LaravelRating\\Tests\\": "tests" } }, "scripts": { "psalm": "vendor/bin/psalm", "test": "vendor/bin/phpunit --colors=always", "test-coverage": "vendor/bin/phpunit --coverage-html coverage" }, "config": { "sort-packages": true }, "extra": { "laravel": { "providers": [ "Nagy\\LaravelRating\\LaravelRatingServiceProvider" ], "aliases": { "LaravelRatingFacade": "Nagy\\LaravelRating\\LaravelRatingFacade" } } }, "minimum-stability": "dev", "prefer-stable": true } ================================================ FILE: database/migrations/add_type_column_to_ratings_table.php.stub ================================================ string('type')->nullable(); }); } public function down() { Schema::dropColumns('ratings', ['type']); } } ================================================ FILE: database/migrations/create_ratings_table.php.stub ================================================ bigIncrements('id'); $table->morphs('model'); $table->morphs('rateable'); $table->decimal('value', 2, 1); $table->timestamps(); }); } public function down() { Schema::dropIfExists('ratings'); } } ================================================ FILE: phpunit.xml.dist ================================================ tests ./src ================================================ FILE: psalm.xml.dist ================================================ ================================================ FILE: src/LaravelRating.php ================================================ isRated($user, $rateable, $type)) { return $user->{$this->resolveTypeRelation($type)}() ->where('rateable_id', $rateable->id) ->where('type', $type) ->where('rateable_type', $this->getRateableByClass($rateable)) ->update(['value' => $value]); } return $user->{$this->resolveTypeRelation($type)}()->create([ 'rateable_id' => $rateable->id, 'rateable_type' => $this->getRateableByClass($rateable), 'value' => $value, 'type' => $type, ]); } public function unRate($user, $rateable, $type) { if ($this->isRated($user, $rateable, $type)) { return $user->{$this->resolveTypeRelation($type)}() ->where('rateable_id', $rateable->id) ->where('type', $type) ->where('rateable_type', $this->getRateableByClass($rateable)) ->delete(); } return false; } public function isRated($user, $rateable, $type) { $rating = $user->{$this->resolveTypeRelation($type)}() ->where('rateable_id', $rateable->id) ->where('rateable_type', $this->getRateableByClass($rateable)) ->where('type', $type) ->first(); return $rating != null; } public function getRatingValue($user, $rateable, $type) { $rating = $user->{$this->resolveTypeRelation($type)}() ->where('rateable_id', $rateable->id) ->where('rateable_type', $this->getRateableByClass($rateable)) ->where('type', $type) ->first(); return $rating != null ? $rating->value : null; } private function resolveTypeRelation($type) { $lookup = [ static::TYPE_LIKE => 'likes', static::TYPE_RATE => 'ratings', static::TYPE_VOTE => 'votes', ]; return $lookup[$type]; } public function resolveRatedItems($items) { $collection = collect(); foreach ($items as $item) { $rateableClass = $this->getRateableByKey($item->rateable_type); $collection->push((new $rateableClass)->find($item->rateable_id)); } return $collection; } private function getRateableByClass($rateable) { $rateable = get_class($rateable); if (in_array($rateable, Relation::$morphMap)) { $rateable = array_search($rateable, Relation::$morphMap); } return $rateable; } private function getRateableByKey($rateable) { if (array_key_exists($rateable, Relation::$morphMap)) { $rateable = Relation::$morphMap[$rateable]; } return $rateable; } } ================================================ FILE: src/LaravelRatingFacade.php ================================================ publishes([ __DIR__.'/../database/migrations/create_ratings_table.php.stub' => app()->basePath().'/database/migrations/'.date('Y_m_d_His', time() + 1).'_create_ratings_table.php', __DIR__.'/../database/migrations/add_type_column_to_ratings_table.php.stub' => app()->basePath().'/database/migrations/'.date('Y_m_d_His', time() + 2).'_add_type_column_to_ratings_table.php', ], 'laravelRatings'); } /** * * @return void */ public function register() { $this->app->bind('laravelRating', function () { return new LaravelRating(); }); } } ================================================ FILE: src/Models/Rating.php ================================================ morphTo(); } public function rateable() { return $this->morphTo(); } } ================================================ FILE: src/Traits/Like/CanLike.php ================================================ morphMany(Rating::class, 'model')->where('type', LaravelRating::TYPE_LIKE); } public function like($model) { return LaravelRatingFacade::rate($this, $model, 1, LaravelRating::TYPE_LIKE); } public function dislike($model) { return LaravelRatingFacade::rate($this, $model, 0, LaravelRating::TYPE_LIKE); } public function isLiked($model) { return LaravelRatingFacade::isRated($this, $model, LaravelRating::TYPE_LIKE); } public function liked() { $liked = $this->likes()->where('value', 1)->get(); return LaravelRatingFacade::resolveRatedItems($liked); } public function disliked() { $disliked = $this->likes()->where('value', 0)->get(); return LaravelRatingFacade::resolveRatedItems($disliked); } public function likedDisliked() { return LaravelRatingFacade::resolveRatedItems($this->likes); } } ================================================ FILE: src/Traits/Like/Likeable.php ================================================ morphMany(Rating::class, 'rateable'); } public function likesDislikesCount() { return $this->likes()->count(); } public function likesCount() { return $this->likes()->where('value', 1)->count(); } public function dislikesCount() { return $this->likes()->where('value', 0)->count(); } } ================================================ FILE: src/Traits/Rate/CanRate.php ================================================ morphMany(Rating::class, 'model')->where('type', LaravelRating::TYPE_RATE); } public function rate($model, $value) { if ($value === null || $value === false || $value === -1) { return $this->unRate($model); } return LaravelRatingFacade::rate($this, $model, $value, LaravelRating::TYPE_RATE); } public function unRate($model) { return LaravelRatingFacade::unRate($this, $model, LaravelRating::TYPE_RATE); } public function getRatingValue($model) { return LaravelRatingFacade::getRatingValue($this, $model, LaravelRating::TYPE_RATE); } public function isRated($model) { return LaravelRatingFacade::isRated($this, $model, LaravelRating::TYPE_RATE); } public function rated() { return LaravelRatingFacade::resolveRatedItems($this->ratings); } } ================================================ FILE: src/Traits/Rate/Rateable.php ================================================ morphMany(Rating::class, 'rateable'); } public function ratingsAvg() { return $this->ratings()->avg('value'); } public function ratingsCount() { return $this->ratings()->count(); } } ================================================ FILE: src/Traits/Vote/CanVote.php ================================================ morphMany(Rating::class, 'model')->where('type', LaravelRating::TYPE_VOTE); } public function upVote($model) { return LaravelRatingFacade::rate($this, $model, 1, LaravelRating::TYPE_VOTE); } public function downVote($model) { return LaravelRatingFacade::rate($this, $model, 0, LaravelRating::TYPE_VOTE); } public function isVoted($model) { return LaravelRatingFacade::isRated($this, $model, LaravelRating::TYPE_VOTE); } public function getVotingValue($model) { return LaravelRatingFacade::getRatingValue($this, $model, LaravelRating::TYPE_VOTE); } public function upVoted() { $upVoted = $this->votes()->where('value', 1)->get(); return LaravelRatingFacade::resolveRatedItems($upVoted); } public function downVoted() { $downVoted = $this->votes()->where('value', 0)->get(); return LaravelRatingFacade::resolveRatedItems($downVoted); } public function voted() { return LaravelRatingFacade::resolveRatedItems($this->votes); } } ================================================ FILE: src/Traits/Vote/Votable.php ================================================ morphMany(Rating::class, 'rateable'); } public function totalVotesCount() { return $this->votes()->count(); } public function upVotesCount() { return $this->votes()->where('value', 1)->count(); } public function downVotesCount() { return $this->votes()->where('value', 0)->count(); } public function votesDiff() { return $this->upVotesCount() - $this->downVotesCount(); } } ================================================ FILE: tests/LikeTest.php ================================================ 'test']); $post = Post::create(['name' => 'test post']); $user->like($post); $this->assertCount(1, $user->likes); } /** @test */ public function user_can_dislike_likable_model() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $user->dislike($post); $this->assertCount(1, $user->likes); } /** @test */ public function user_can_return_total_likes_count() { $user = User::create(['name' => 'test']); $user2 = User::create(['name' => 'test2']); $post = Post::create(['name' => 'test post']); $user->like($post); $user2->like($post); $this->assertTrue($post->likesCount() == 2); } /** @test */ public function it_can_return_liked_items_for_a_user() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $post2 = Post::create(['name' => 'test post2']); $user->like($post); $user->dislike($post2); $this->assertEquals('test post', $user->liked()->first()->name); } /** @test */ public function it_can_return_disliked_items_for_a_user() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $post2 = Post::create(['name' => 'test post2']); $user->like($post); $user->dislike($post2); $this->assertEquals('test post2', $user->disliked()->first()->name); } /** @test */ public function it_can_return_all_liked_disliked_items_for_a_user() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $post2 = Post::create(['name' => 'test post2']); $user->like($post); $user->dislike($post2); $this->assertCount(2, $user->likedDisliked()); } } ================================================ FILE: tests/Models/Post.php ================================================ 'test']); $post = Post::create(['name' => 'test post']); $user->rate($post, 5); $this->assertCount(1, $user->ratings); } /** @test */ public function user_can_unrate_rateable_model() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $user->rate($post, 5); $user->unRate($post); $this->assertCount(0, $user->ratings); } /** @test */ public function ratable_model_can_be_unrated_if_passed_false_or_null_to_rate_method() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $user->rate($post, 5); $user->rate($post, -1); $user->rate($post, 5); $user->rate($post, null); $user->rate($post, 5); $user->rate($post, false); $user->rate($post, 5); $user->rate($post, 10); $this->assertEquals(10, $user->getRatingValue($post)); $this->assertCount(1, $user->ratings); } /** @test */ public function it_can_return_rating_value_for_user_for_rateable_model() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $user->rate($post, 5); $this->assertTrue($user->getRatingValue($post) == 5); } /** @test */ public function it_can_update_user_rating_if_already_rated() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $user->rate($post, 5); $this->assertTrue($user->getRatingValue($post) == 5); $user->rate($post, 10); $this->assertTrue($user->getRatingValue($post) == 10); } /** @test */ public function it_can_return_avg_for_rateable_model() { $user = User::create(['name' => 'test']); $user2 = User::create(['name' => 'test2']); $post = Post::create(['name' => 'test post']); $user->rate($post, 5); $user2->rate($post, 10); $this->assertTrue($post->ratingsAvg() == 7.5); } /** @test */ public function it_can_return_count_for_rateable_model() { $user = User::create(['name' => 'test']); $user2 = User::create(['name' => 'test2']); $post = Post::create(['name' => 'test post']); $user->rate($post, 5); $user2->rate($post, 10); $this->assertTrue($post->ratingsCount() == 2); } /** @test */ public function it_can_return_rated_items_for_a_user() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $post2 = Post::create(['name' => 'test post2']); $user->rate($post, 5); $user->rate($post2, 10); $this->assertCount(2, $user->rated()); } /** @test */ public function it_can_work_with_morph_maps() { Relation::$morphMap = [ 'post' => Post::class, 'user' => User::class, ]; $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $user->rate($post, 5); $this->assertCount(1, $user->rated()); } } ================================================ FILE: tests/TestCase.php ================================================ set('database.default', 'sqlite'); $app['config']->set('database.connections.sqlite', [ 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', ]); include_once __DIR__.'/../database/migrations/create_ratings_table.php.stub'; include_once __DIR__.'/../database/migrations/add_type_column_to_ratings_table.php.stub'; include_once __DIR__.'/database/migrations/create_posts_table.php'; include_once __DIR__.'/database/migrations/create_users_table.php'; (new \CreateRatingsTable())->up(); (new \AddTypeColumnToRatingsTable())->up(); (new \CreatePostsTable())->up(); (new \CreateUsersTable())->up(); } } ================================================ FILE: tests/VotingTest.php ================================================ 'test']); $post = Post::create(['name' => 'test post']); $user->upVote($post); $this->assertCount(1, $user->votes); $this->assertTrue($user->getVotingValue($post) == 1); } /** @test */ public function user_can_down_vote_votable_model() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $user->downVote($post); $this->assertCount(1, $user->votes); $this->assertTrue($user->getVotingValue($post) == 0); } /** @test */ public function it_returns_total_up_voting_count() { $user = User::create(['name' => 'test']); $user2 = User::create(['name' => 'test2']); $post = Post::create(['name' => 'test post']); $user->upVote($post); $user2->upVote($post); $this->assertTrue($post->upVotesCount() == 2); } /** @test */ public function it_returns_total_down_voting_count() { $user = User::create(['name' => 'test']); $user2 = User::create(['name' => 'test2']); $post = Post::create(['name' => 'test post']); $user->downVote($post); $user2->downVote($post); $this->assertTrue($post->downVotesCount() == 2); } /** @test */ public function it_returns_total_votes_count() { $user = User::create(['name' => 'test']); $user2 = User::create(['name' => 'test2']); $post = Post::create(['name' => 'test post']); $user->upVote($post); $user2->downVote($post); $this->assertTrue($post->totalVotesCount() == 2); } /** @test */ public function it_returns_votes_diff() { $user = User::create(['name' => 'test']); $user2 = User::create(['name' => 'test2']); $post = Post::create(['name' => 'test post']); $user->upVote($post); $user2->downVote($post); $this->assertTrue($post->votesDiff() == 0); } /** @test */ public function it_can_return_up_voted_items_for_a_user() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $post2 = Post::create(['name' => 'test post2']); $user->upVote($post); $user->downVote($post2); $this->assertEquals('test post', $user->upVoted()->first()->name); } /** @test */ public function it_can_return_downvoted_items_for_a_user() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $post2 = Post::create(['name' => 'test post2']); $user->upVote($post); $user->downVote($post2); $this->assertEquals('test post2', $user->downVoted()->first()->name); } /** @test */ public function it_can_return_all_voted_items_for_a_user() { $user = User::create(['name' => 'test']); $post = Post::create(['name' => 'test post']); $post2 = Post::create(['name' => 'test post2']); $user->upVote($post); $user->downVote($post2); $this->assertCount(2, $user->voted()); } } ================================================ FILE: tests/database/migrations/create_posts_table.php ================================================ bigIncrements('id'); $table->string('name'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('posts'); } } ================================================ FILE: tests/database/migrations/create_users_table.php ================================================ bigIncrements('id'); $table->string('name'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } }