Skip to content

Commit

Permalink
feat: add view count to journal entry (monicahq/chandler#269)
Browse files Browse the repository at this point in the history
  • Loading branch information
djaiss authored Oct 31, 2022
1 parent aa7f2be commit 4753165
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 2 deletions.
2 changes: 1 addition & 1 deletion app/Helpers/PostHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ class PostHelper
public static function statistics(Post $post): array
{
$wordCount = 0;
$duration = 0;

$postSections = $post->postSections()
->whereNotNull('content')
Expand All @@ -33,6 +32,7 @@ public static function statistics(Post $post): array
return [
'word_count' => $wordCount,
'time_to_read_in_minute' => $duration,
'view_count' => $post->view_count,
];
}
}
1 change: 1 addition & 0 deletions app/Models/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Post extends Model
protected $fillable = [
'journal_id',
'title',
'view_count',
'published',
'written_at',
'updated_at',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

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

return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('posts', function (Blueprint $table) {
$table->integer('view_count')->after('title')->default(0);
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('posts', function (Blueprint $table) {
$table->dropColumn('view_count');
});
}
};
77 changes: 77 additions & 0 deletions domains/Vault/ManageJournals/Services/IncrementPostReadCounter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace App\Vault\ManageJournals\Services;

use App\Interfaces\ServiceInterface;
use App\Models\Journal;
use App\Models\Post;
use App\Services\BaseService;

class IncrementPostReadCounter extends BaseService implements ServiceInterface
{
private array $data;

private Post $post;

/**
* Get the validation rules that apply to the service.
*
* @return array
*/
public function rules(): array
{
return [
'account_id' => 'required|integer|exists:accounts,id',
'vault_id' => 'required|integer|exists:vaults,id',
'author_id' => 'required|integer|exists:users,id',
'journal_id' => 'required|integer|exists:journals,id',
'post_id' => 'required|integer|exists:posts,id',
];
}

/**
* Get the permissions that apply to the user calling the service.
*
* @return array
*/
public function permissions(): array
{
return [
'author_must_belong_to_account',
'vault_must_belong_to_account',
'author_must_be_vault_editor',
];
}

/**
* Increment the read counter of a post.
*
* @param array $data
* @return Post
*/
public function execute(array $data): Post
{
$this->data = $data;

$this->validate();
$this->increment();

return $this->post;
}

private function validate(): void
{
$this->validateRules($this->data);

Journal::where('vault_id', $this->data['vault_id'])
->findOrFail($this->data['journal_id']);

$this->post = Post::where('journal_id', $this->data['journal_id'])
->findOrFail($this->data['post_id']);
}

private function increment(): void
{
$this->post->increment('view_count');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use App\Models\Vault;
use App\Vault\ManageJournals\Services\CreatePost;
use App\Vault\ManageJournals\Services\DestroyPost;
use App\Vault\ManageJournals\Services\IncrementPostReadCounter;
use App\Vault\ManageJournals\Services\UpdatePost;
use App\Vault\ManageJournals\Web\ViewHelpers\PostCreateViewHelper;
use App\Vault\ManageJournals\Web\ViewHelpers\PostEditViewHelper;
Expand Down Expand Up @@ -83,6 +84,14 @@ public function show(Request $request, int $vaultId, int $journalId, int $postId
$vault = Vault::findOrFail($vaultId);
$post = Post::findOrFail($postId);

(new IncrementPostReadCounter())->execute([
'account_id' => Auth::user()->account_id,
'author_id' => Auth::user()->id,
'vault_id' => $vaultId,
'journal_id' => $journalId,
'post_id' => $postId,
]);

return Inertia::render('Vault/Journal/Post/Show', [
'layoutData' => VaultIndexViewHelper::layoutData($vault),
'data' => PostShowViewHelper::data($post, Auth::user()),
Expand Down
2 changes: 1 addition & 1 deletion resources/js/Pages/Vault/Journal/Post/Edit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ const destroy = () => {
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>

<span>Read 21 times</span>
<span>Read {{ statistics.view_count }} times</span>
</li>
</ul>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php

namespace Tests\Unit\Domains\Vault\ManageJournals\Services;

use App\Exceptions\NotEnoughPermissionException;
use App\Models\Account;
use App\Models\Journal;
use App\Models\Post;
use App\Models\User;
use App\Models\Vault;
use App\Vault\ManageJournals\Services\IncrementPostReadCounter;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Validation\ValidationException;
use Tests\TestCase;

class IncrementPostReadCounterTest extends TestCase
{
use DatabaseTransactions;

/** @test */
public function it_increments_a_post_counter(): void
{
$regis = $this->createUser();
$vault = $this->createVault($regis->account);
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
$journal = Journal::factory()->create([
'vault_id' => $vault->id,
]);
$post = Post::factory()->create([
'journal_id' => $journal->id,
]);

$this->executeService($regis, $regis->account, $vault, $journal, $post);
}

/** @test */
public function it_fails_if_wrong_parameters_are_given(): void
{
$request = [
'title' => 'Ross',
];

$this->expectException(ValidationException::class);
(new IncrementPostReadCounter())->execute($request);
}

/** @test */
public function it_fails_if_user_doesnt_belong_to_account(): void
{
$this->expectException(ModelNotFoundException::class);

$regis = $this->createUser();
$account = Account::factory()->create();
$vault = $this->createVault($regis->account);
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
$journal = Journal::factory()->create([
'vault_id' => $vault->id,
]);
$post = Post::factory()->create([
'journal_id' => $journal->id,
]);

$this->executeService($regis, $account, $vault, $journal, $post);
}

/** @test */
public function it_fails_if_journal_doesnt_belong_to_vault(): void
{
$this->expectException(ModelNotFoundException::class);

$regis = $this->createUser();
$vault = $this->createVault($regis->account);
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
$journal = Journal::factory()->create();
$post = Post::factory()->create([
'journal_id' => $journal->id,
]);

$this->executeService($regis, $regis->account, $vault, $journal, $post);
}

/** @test */
public function it_fails_if_post_doesnt_belong_to_journal(): void
{
$this->expectException(ModelNotFoundException::class);

$regis = $this->createUser();
$vault = $this->createVault($regis->account);
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
$journal = Journal::factory()->create([
'vault_id' => $vault->id,
]);
$post = Post::factory()->create();

$this->executeService($regis, $regis->account, $vault, $journal, $post);
}

/** @test */
public function it_fails_if_user_doesnt_have_right_permission_in_vault(): void
{
$this->expectException(NotEnoughPermissionException::class);

$regis = $this->createUser();
$vault = $this->createVault($regis->account);
$vault = $this->setPermissionInVault($regis, Vault::PERMISSION_VIEW, $vault);
$journal = Journal::factory()->create([
'vault_id' => $vault->id,
]);
$post = Post::factory()->create([
'journal_id' => $journal->id,
]);

$this->executeService($regis, $regis->account, $vault, $journal, $post);
}

private function executeService(User $author, Account $account, Vault $vault, Journal $journal, Post $post): void
{
$request = [
'account_id' => $account->id,
'vault_id' => $vault->id,
'author_id' => $author->id,
'journal_id' => $journal->id,
'post_id' => $post->id,
];

$post = (new IncrementPostReadCounter())->execute($request);

$this->assertDatabaseHas('posts', [
'id' => $post->id,
'journal_id' => $journal->id,
'view_count' => 1,
]);
}
}
1 change: 1 addition & 0 deletions tests/Unit/Helpers/PostHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public function it_gets_the_statistics(): void
[
'word_count' => 24,
'time_to_read_in_minute' => 1,
'view_count' => 0,
],
PostHelper::statistics($post)
);
Expand Down

0 comments on commit 4753165

Please sign in to comment.