From ad37e2d7499da9b1e2c13149449a1020949c16e3 Mon Sep 17 00:00:00 2001 From: Collin Henderson Date: Sun, 10 Mar 2024 18:10:50 -0400 Subject: [PATCH] [WIP] Adds TagsController tests --- app/Http/Controllers/TagsController.php | 12 +--- .../Controllers/TagsController/StoreTest.php | 66 +++++++++++++++++++ .../Controllers/TagsController/UpdateTest.php | 56 ++++++++++++++++ tests/TestCase.php | 4 +- 4 files changed, 126 insertions(+), 12 deletions(-) create mode 100644 tests/Feature/Controllers/TagsController/StoreTest.php create mode 100644 tests/Feature/Controllers/TagsController/UpdateTest.php diff --git a/app/Http/Controllers/TagsController.php b/app/Http/Controllers/TagsController.php index a216a77a..92fc0129 100644 --- a/app/Http/Controllers/TagsController.php +++ b/app/Http/Controllers/TagsController.php @@ -10,16 +10,6 @@ class TagsController extends Controller { - /** - * Display a listing of the resource. - * - * @return \Illuminate\Http\Response - */ - public function index() - { - return auth()->user()->tags; - } - /** * Store a newly created resource in storage. * @@ -29,7 +19,7 @@ public function store(Request $request) { if (auth()->user()->cannot('create', Tag::class)) { return redirect()->back()->withErrors([ - 'sponsorship_required' => [Ability::CREATE_TAG], + 'sponsorship_required' => [Ability::CREATE_TAG->value], ]); } diff --git a/tests/Feature/Controllers/TagsController/StoreTest.php b/tests/Feature/Controllers/TagsController/StoreTest.php new file mode 100644 index 00000000..3f347139 --- /dev/null +++ b/tests/Feature/Controllers/TagsController/StoreTest.php @@ -0,0 +1,66 @@ +post('/tags') + ->assertRedirect('/login'); + +it('creates a new tag', function () { + $this->login(); + + $this->assertDatabaseMissing('tags', ['name' => 'Laravel']); + + $this + ->post(route('tags.store'), ['name' => 'Laravel']) + ->assertRedirect(RouteServiceProvider::HOME) + ->assertSessionHas('success', "The 'Laravel' tag was added"); + + $this->assertDatabaseHas('tags', ['name' => 'Laravel']); +}); + +it('requires a valid name', function (array $badData, array|string $errors) { + $this + ->login() + ->post(route('tags.store'), [...$badData]) + ->assertInvalid($errors); +})->with([ + [['name' => null], 'name'], + [['name' => true], 'name'], + [['name' => 12], 'name'], + [[], 'name'], +]); + +it('requires a unique name per user', function () { + Tag::factory()->create(['name' => 'VueJS']); + + $this + ->login() + ->post(route('tags.store'), ['name' => 'VueJS']) + ->assertValid() + ->assertRedirect(RouteServiceProvider::HOME); + + expect(auth()->user()->tags()->count())->toBe(1); + + $this + ->post(route('tags.store'), ['name' => 'VueJS']) + ->assertInvalid(['name' => 'You already have a tag with that name.']); + + expect(auth()->user()->tags()->count())->toBe(1); +}); + +it('flashes an error if the user is not a sponsor and is at their tag limit', function () { + $this->login(); + + Tag::factory()->count(5)->create(['user_id' => auth()->id()]); + + $this + ->post(route('tags.store'), ['name' => 'VueJS']) + ->assertRedirect(RouteServiceProvider::HOME) + ->assertSessionHasErrors(['sponsorship_required' => 'create_tag']); + + $this->assertDatabaseMissing('tags', ['user_id' => auth()->id(), 'name' => 'VueJS']); +}); diff --git a/tests/Feature/Controllers/TagsController/UpdateTest.php b/tests/Feature/Controllers/TagsController/UpdateTest.php new file mode 100644 index 00000000..efed8fdd --- /dev/null +++ b/tests/Feature/Controllers/TagsController/UpdateTest.php @@ -0,0 +1,56 @@ +put('/tags/1', ['name' => 'TypeScript']) + ->assertRedirect('/login'); + +it('updates a tag', function () { + $this->login(); + + $tag = Tag::factory()->create(['name' => 'SwypeScript', 'user_id' => auth()->id()]); + + $this + ->put(route('tags.update', $tag), ['name' => 'TypeScript']) + ->assertRedirect(route('dashboard.show')); + + $this->assertDatabaseHas('tags', ['id' => $tag->id, 'name' => 'TypeScript']); +}); + +it('requires a valid name', function (array $badData, array|string $errors) { + $this->login(); + + $tag = Tag::factory()->create(['user_id' => auth()->id()]); + + $this + ->put(route('tags.update', $tag), [...$badData]) + ->assertInvalid($errors); +})->with([ + [['name' => null], 'name'], + [['name' => true], 'name'], + [['name' => 12], 'name'], + [[], 'name'], +]); + +it('requires a unique name per user', function () { + // Create a tag called Laravel by someone else + Tag::factory()->create(['name' => 'Laravel']); + + $this->login(); + + $tag = Tag::factory()->create(['name' => 'Laaravell', 'user_id' => auth()->id()]); + $tagB = Tag::factory()->create(['user_id' => auth()->id()]); + + $this + ->put(route('tags.update', $tag), ['name' => 'Laravel']) + ->assertValid() + ->assertRedirect(RouteServiceProvider::HOME); + + $this + ->put(route('tags.update', $tagB), ['name' => 'Laravel']) + ->assertInvalid(['name' => 'You already have a tag with that name.']); +}); diff --git a/tests/TestCase.php b/tests/TestCase.php index ab9671c2..62f88fa0 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,6 +5,7 @@ namespace Tests; use App\Models\User; +use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Foundation\Testing\TestCase as BaseTestCase; use Illuminate\Support\Facades\Http; @@ -23,7 +24,8 @@ protected function setUp(): void protected function login(User $user = null) { - $user ??= User::factory()->create()->first(); + /** @var Authenticatable $user * */ + $user ??= User::factory()->create(); $this->actingAs($user);