Skip to content
This repository was archived by the owner on Jun 29, 2021. It is now read-only.
Merged
44 changes: 44 additions & 0 deletions domains/Discussions/Controllers/QuestionsGetAnswersController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Domains\Discussions\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Domains\Discussions\Models\Question;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Contracts\Auth\Factory as Auth;
use Illuminate\Contracts\Pagination\Paginator;

class QuestionsGetAnswersController extends Controller
{
private Question $question;

public function __construct(Auth $auth, Question $question)
{
if ($auth->guest()) {
$this->middleware('throttle:30,1');
}

$this->question = $question;
}

public function __invoke(int $id, Request $request): Paginator
{
$this->validate($request, [
'author' => 'sometimes|integer|exists:users,id',
'created' => 'sometimes|array|size:2',
'created.from' => 'required_with:created|date',
'created.to' => 'required_with:created|date|afterOrEqual:created.from'
]);

return $this->question
->findOrFail($id)
->answers()
->when($authorId = $request->input('author'),
static fn(Builder $answers, int $authorId) => $answers->whereAuthorId($authorId))
->when($created = $request->input('created'),
static fn(Builder $answers, array $created) => $answers->whereBetween('created_at', [$created['from'], $created['to']]))
->latest()
->simplePaginate(15);
}
}
6 changes: 6 additions & 0 deletions domains/Discussions/Models/Question.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;

class Question extends Model
Expand All @@ -22,6 +23,11 @@ public function author(): BelongsTo
->withTrashed();
}

public function answers(): HasMany
{
return $this->hasMany(Answer::class);
}

public function scopeFindByAuthorId(Builder $query, int $term): Builder
{
return $query->where('author_id', $term);
Expand Down
115 changes: 115 additions & 0 deletions domains/Discussions/Tests/Feature/QuestionsGetAnswersTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

namespace Domains\Discussions\Tests\Feature;

use Carbon\Carbon;
use Faker\Factory;
use Tests\TestCase;
use Faker\Generator;
use Illuminate\Http\Response;
use Domains\Accounts\Models\User;
use Domains\Discussions\Models\Answer;
use Domains\Discussions\Models\Question;
use Laravel\Lumen\Testing\DatabaseMigrations;
use Domains\Accounts\Database\Factories\UserFactory;
use Domains\Discussions\Database\Factories\AnswerFactory;
use Domains\Discussions\Database\Factories\QuestionFactory;

class QuestionsGetAnswersTest extends TestCase
{
use DatabaseMigrations;

private User $user;
private User $secondUser;
private Question $question;
private Answer $answer;
private Answer $secondAnswer;
private Answer $thirdAnswer;

protected function setUp(): void
{
parent::setUp();

$this->user = UserFactory::new()->create();
$this->secondUser = UserFactory::new()->create();

$this->question = QuestionFactory::new([
'author_id' => $this->user->id
])->create();

$this->answer = AnswerFactory::new([
'question_id' => $this->question->id,
'author_id' => $this->user->id,
'created_at' => Carbon::now()->subWeek()->toDateTimeString()
])->create();

$this->secondAnswer = AnswerFactory::new([
'question_id' => $this->question->id,
'author_id' => $this->secondUser->id,
'created_at' => Carbon::now()->toDateTimeString()
])->create();

$this->thirdAnswer = AnswerFactory::new([
'question_id' => $this->question->id,
'author_id' => $this->user->id,
'created_at' => Carbon::now()->subWeek()->toDateTimeString()
])->create();
}

/** @test */
public function it_gets_paginated_answers_for_a_question(): void
{
$this->get(route('discussions.questions.answersList', ['id' => $this->question->id]))
->seeJson([
"id" => $this->answer->id,
"question_id" => '' . $this->question->id
])
->seeJson([
"id" => $this->secondAnswer->id,
"question_id" => '' . $this->question->id
]);
}

/** @test */
public function it_gets_paginated_answers_for_a_question_from_a_particular_author(): void
{
$this->get(route('discussions.questions.answersList', ['id' => $this->question->id, 'author' => $this->user->id]))
->seeJson(['id' => $this->answer->id])
->dontSeeJson(['id' => $this->secondAnswer->id]);
}

/** @test */
public function it_gets_paginated_answers_for_a_question_from_a_particular_time_frame(): void
{
$aWeekAgo = Carbon::now()->subDays(8);
$yesterday = Carbon::yesterday();

$this->get(route('discussions.questions.answersList', ['id' => $this->question->id]) . '?created[from]=' . $aWeekAgo->format('Y-m-d') . '&created[to]=' . $yesterday->format('Y-m-d'))
->seeJson([
"id" => $this->answer->id,
"question_id" => '' . $this->question->id
])
->dontSeeJson([
"id" => $this->secondAnswer->id
]);
}

/** @test */
public function it_gets_paginated_answers_for_a_question_from_a_particular_time_frame_and_user(): void
{
$aWeekAgo = Carbon::now()->subDays(8);
$yesterday = Carbon::yesterday();

$this->get(route('discussions.questions.answersList', ['id' => $this->question->id]) . '?created[from]=' . $aWeekAgo->format('Y-m-d') . '&created[to]=' . $yesterday->format('Y-m-d') . '&author=1')
->seeJson([
"id" => $this->answer->id,
"question_id" => '' . $this->question->id
])
->seeJson([
"id" => $this->thirdAnswer->id,
])
->dontSeeJson([
"id" => $this->secondAnswer->id
]);
}
}
6 changes: 6 additions & 0 deletions domains/Discussions/routes.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use Domains\Discussions\Controllers\AnswersStoreController;
use Domains\Discussions\Controllers\QuestionsGetAnswersController;
use Domains\Discussions\Controllers\QuestionsDeleteController;
use Domains\Discussions\Controllers\QuestionsIndexController;
use Domains\Discussions\Controllers\QuestionsStoreController;
Expand Down Expand Up @@ -39,3 +40,8 @@
'as' => 'questions.view',
'uses' => QuestionsViewController::class,
]);

Route::get('/questions/{id}/answers', [
'as' => 'questions.answersList',
'uses' => QuestionsGetAnswersController::class
]);