Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
pawelmysior committed Jul 30, 2017
0 parents commit 5c67158
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/vendor
composer.lock
29 changes: 29 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "pawelmysior/publishable",
"authors": [
{
"name": "Pawel Mysior",
"email": "[email protected]"
}
],
"require": {
"php": ">=5.6.4",
"illuminate/database": "^5.4",
"nesbot/carbon": "^1.22"
},
"require-dev": {
"orchestra/database": "~3.4",
"orchestra/testbench": "~3.4",
"phpunit/phpunit": "~5.7"
},
"autoload": {
"psr-4": {
"PawelMysior\\Publishable\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"PawelMysior\\Publishable\\Tests\\": "tests/"
}
}
}
24 changes: 24 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./src</directory>
</whitelist>
</filter>
<php>
<env name="APP_ENV" value="testing"/>
</php>
</phpunit>
71 changes: 71 additions & 0 deletions src/Publishable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace PawelMysior\Publishable;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;

trait Publishable
{
/**
* Scope a query to only include published models.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopePublished(Builder $query)
{
return $query->where('published_at', '<=', Carbon::now())->whereNotNull('published_at');
}

/**
* Scope a query to only include unpublished models.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeUnpublished(Builder $query)
{
return $query->where('published_at', '>', Carbon::now())->orWhereNull('published_at');
}

/**
* @return bool
*/
public function isPublished()
{
if (is_null($this->published_at)) {
return false;
}

return $this->published_at->lte(Carbon::now());
}

/**
* @return bool
*/
public function isUnpublished()
{
return !$this->isPublished();
}

/**
* @return bool
*/
public function publish()
{
return $this->update([
'published_at' => Carbon::now()->toDateTimeString(),
]);
}

/**
* @return bool
*/
public function unpublish()
{
return $this->update([
'published_at' => null,
]);
}
}
13 changes: 13 additions & 0 deletions tests/Post.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace PawelMysior\Publishable\Tests;

use Illuminate\Database\Eloquent\Model;
use PawelMysior\Publishable\Publishable;

class Post extends Model
{
use Publishable;

protected $guarded = [];
}
126 changes: 126 additions & 0 deletions tests/PublishableTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?php

namespace PawelMysior\Publishable\Tests;

use Carbon\Carbon;

class PublishableTest extends TestCase
{
/** @test */
public function posts_with_published_at_date_in_the_past_are_published()
{
$post = Post::create([
'published_at' => Carbon::yesterday(),
]);

$this->assertTrue($post->isPublished());
$this->assertFalse($post->isUnpublished());
}

/** @test */
public function posts_with_published_at_date_set_as_now_are_published()
{
$post = Post::create([
'published_at' => Carbon::now(),
]);

$this->assertTrue($post->isPublished());
$this->assertFalse($post->isUnpublished());
}

/** @test */
public function posts_with_published_at_date_in_the_future_are_not_published()
{
$post = Post::create([
'published_at' => Carbon::tomorrow(),
]);

$this->assertFalse($post->isPublished());
$this->assertTrue($post->isUnpublished());
}

/** @test */
public function posts_with_published_at_set_as_null_are_not_published()
{
$post = Post::create([
'published_at' => null,
]);

$this->assertFalse($post->isPublished());
$this->assertTrue($post->isUnpublished());
}

/** @test */
public function publishing_post_sets_the_published_at_date_as_now()
{
$post = Post::create([
'published_at' => null,
]);

$post->publish();

$this->assertEquals(Carbon::now(), $post->published_at);
}

/** @test */
public function unpublishing_post_sets_the_published_at_date_as_null()
{
$post = Post::create([
'published_at' => Carbon::now(),
]);

$post->unpublish();

$this->assertNull($post->published_at);
}

/** @test */
public function test_published_scope()
{
$firstPublishedPost = Post::create([
'published_at' => Carbon::yesterday(),
]);
$secondPublishedPost = Post::create([
'published_at' => Carbon::now(),
]);

$firstUnpublishedPost = Post::create([
'published_at' => null,
]);
$secondUnpublishedPost = Post::create([
'published_at' => Carbon::tomorrow(),
]);

$posts = Post::published()->get();

$this->assertTrue($posts->contains($firstPublishedPost));
$this->assertTrue($posts->contains($secondPublishedPost));
$this->assertFalse($posts->contains($firstUnpublishedPost));
$this->assertFalse($posts->contains($secondUnpublishedPost));
}

/** @test */
public function test_unpublished_scope()
{
$firstPublishedPost = Post::create([
'published_at' => Carbon::yesterday(),
]);
$secondPublishedPost = Post::create([
'published_at' => Carbon::now(),
]);

$firstUnpublishedPost = Post::create([
'published_at' => null,
]);
$secondUnpublishedPost = Post::create([
'published_at' => Carbon::tomorrow(),
]);

$posts = Post::unpublished()->get();

$this->assertFalse($posts->contains($firstPublishedPost));
$this->assertFalse($posts->contains($secondPublishedPost));
$this->assertTrue($posts->contains($firstUnpublishedPost));
$this->assertTrue($posts->contains($secondUnpublishedPost));
}
}
27 changes: 27 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace PawelMysior\Publishable\Tests;

use Orchestra\Testbench\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
public function setUp()
{
parent::setUp();

$this->loadMigrationsFrom(realpath(__DIR__.'/migrations'));
}

protected function getEnvironmentSetUp($app)
{
$app['config']->set('database.default', 'testing');
}

protected function getPackageProviders($app)
{
return [
\Orchestra\Database\ConsoleServiceProvider::class,
];
}
}
32 changes: 32 additions & 0 deletions tests/migrations/2017_07_29_163922_create_posts_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->timestamp('published_at')->nullable();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}

0 comments on commit 5c67158

Please sign in to comment.