Skip to content

Commit

Permalink
HEY-15: question should be unique
Browse files Browse the repository at this point in the history
  • Loading branch information
rafael-pozzebon committed Nov 18, 2023
1 parent 8a356b9 commit c522047
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 41 deletions.
37 changes: 16 additions & 21 deletions app/Http/Controllers/QuestionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,41 @@
namespace App\Http\Controllers;

use App\Models\Question;
use App\Rules\SameQuestionRule;
use Closure;

class QuestionController extends Controller
{
public function index()
{
$questions = Question::query()
->where('created_by', auth()->id())
->latest()
->get();

$archivedQuestions = Question::query()
->where('created_by', auth()->id())
->onlyTrashed()
->latest()
->get();

return view('question.index', compact('questions', 'archivedQuestions'));
return view('question.index', [
'questions' => user()->questions,
'archivedQuestions' => user()->questions()->onlyTrashed()->get(),
]);
}

public function store()
{
$this->validate(request(), [
request()->validate([
'question' => [
'required',
'min:10',
function (string $attribute, mixed $value, \Closure $fail) {
function (string $attribute, mixed $value, Closure $fail) {
if ($value[strlen($value) - 1] != '?') {
$fail(__('The question must end with a question mark?.'));
$fail('Are you sure that is a question? It is missing the question mark in the end.');
}
},
new SameQuestionRule(),
],
]);

Question::query()->create([
'question' => request('question'),
'created_by' => auth()->id(),
'draft' => true,
]);
user()->questions()
->create([
'question' => request()->question,
'draft' => true,
]);

return redirect()->back();
return back();
}

public function edit(Question $question)
Expand Down
5 changes: 5 additions & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public function votes(): HasMany
return $this->hasMany(Vote::class);
}

public function questions(): HasMany
{
return $this->hasMany(Question::class, 'created_by');
}

public function like(Question $question): void
{
$this->votes()->updateOrCreate(
Expand Down
27 changes: 27 additions & 0 deletions app/Rules/SameQuestionRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace App\Rules;

use App\Models\Question;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class SameQuestionRule implements ValidationRule
{
/**
* Run the validation rule.
*
* @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if ($this->validationRule($value)) {
$fail('Pergunta já existe!');
}
}

private function validationRule(string $value): bool
{
return Question::whereQuestion($value)->exists();
}
}
66 changes: 46 additions & 20 deletions tests/Feature/Question/CreateTest.php
Original file line number Diff line number Diff line change
@@ -1,61 +1,87 @@
<?php

use App\Models\User;
use App\Models\{Question, User};

use function Pest\Laravel\{actingAs, assertDatabaseCount, assertDatabaseHas, post};
use function Pest\Laravel\{actingAs, assertDatabaseCount, assertDatabaseHas, post, postJson};

it('should be able to create a new question bigger than 255 characters', function () {
// Arrange
// Arrange :: preparar
$user = User::factory()->create();
actingAs($user);

//Act
// Act :: agir
$request = post(route('question.store'), [
'question' => str_repeat('a', 260) . '?',
'question' => str_repeat('*', 260) . '?',
]);

// Assert
// Assert :: verificar
$request->assertRedirect();
assertDatabaseCount('questions', 1);
assertDatabaseHas('questions', ['question' => str_repeat('*', 260) . '?']);
});

it('should create as a draft all the time', function () {
// Arrange :: preparar
$user = User::factory()->create();
actingAs($user);

// Act :: agir
post(route('question.store'), [
'question' => str_repeat('*', 260) . '?',
]);

// Assert :: verificar
assertDatabaseHas('questions', [
'question' => str_repeat('a', 260) . '?',
'question' => str_repeat('*', 260) . '?',
'draft' => true,
]);
});

it('should check if ends with a question mark ?', function () {
// Arrange
it('should check if ends with question mark ?', function () {
// Arrange :: preparar
$user = User::factory()->create();
actingAs($user);

//Act
// Act :: agir
$request = post(route('question.store'), [
'question' => str_repeat('?', 9) . ".",
'question' => str_repeat('*', 10),
]);

// Assert
// Assert :: verificar
$request->assertSessionHasErrors([
'question' => 'The question must end with a question mark?.',
'question' => 'Are you sure that is a question? It is missing the question mark in the end.',
]);
assertDatabaseCount('questions', 0);
});

it('should have at least 10 characters', function () {
// Arrange
// Arrange :: preparar
$user = User::factory()->create();
actingAs($user);

//Act
// Act :: agir
$request = post(route('question.store'), [
'question' => 'a',
'question' => str_repeat('*', 8) . '?',
]);

// Assert
$request->assertSessionHasErrors(['question' => __('validation.min.string', ['attribute' => 'question', 'min' => 10])]);
// Assert :: verificar
$request->assertSessionHasErrors(['question' => __('validation.min.string', ['min' => 10, 'attribute' => 'question'])]);
assertDatabaseCount('questions', 0);
});

test('only authenticated user can create a new question', function () {
test('only authenticated users can create a new question', function () {
post(route('question.store'), [
'question' => str_repeat('a', 260) . '?',
'question' => str_repeat('*', 8) . '?',
])->assertRedirect(route('login'));
});

test('question should be unique', function () {
$user = User::factory()->create();
actingAs($user);

Question::factory()->create(['question' => 'Alguma Pergunta?']);

post(route('question.store'), [
'question' => 'Alguma Pergunta?',
])->assertSessionHasErrors(['question' => 'Pergunta já existe!']);
});

0 comments on commit c522047

Please sign in to comment.