From 04a2bfb6db5efed02756980ebf5582617e7c3b45 Mon Sep 17 00:00:00 2001 From: Duncan Sterken Date: Mon, 17 Dec 2018 15:21:43 +0100 Subject: [PATCH] Add partial unit tests --- .env.example | 2 +- .gitignore | 1 + app/Http/Controllers/Api/StringController.php | 9 +- composer.json | 1 + database/factories/StringValueFactory.php | 43 ++++++ .../{ModelFactory.php => UserFactory.php} | 5 +- phpunit.xml | 2 + tests/StringTest.php | 133 ++++++++++++++++++ tests/TestCase.php | 26 +++- 9 files changed, 212 insertions(+), 10 deletions(-) create mode 100644 database/factories/StringValueFactory.php rename database/factories/{ModelFactory.php => UserFactory.php} (91%) create mode 100644 tests/StringTest.php diff --git a/.env.example b/.env.example index 5fd7ed0..39aaf18 100644 --- a/.env.example +++ b/.env.example @@ -2,7 +2,7 @@ APP_NAME=Straas APP_ENV=local APP_KEY= APP_DEBUG=true -APP_URL=http://straas.local +APP_URL=https://straas.local APP_TIMEZONE=GMT LOG_CHANNEL=stack diff --git a/.gitignore b/.gitignore index 059a517..e51a912 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ Homestead.json Homestead.yaml .env +database.sqlite diff --git a/app/Http/Controllers/Api/StringController.php b/app/Http/Controllers/Api/StringController.php index 7e7069a..7be77ee 100644 --- a/app/Http/Controllers/Api/StringController.php +++ b/app/Http/Controllers/Api/StringController.php @@ -28,19 +28,20 @@ use App\Http\Controllers\Controller; use App\Models\StringValue; +use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; use Illuminate\Validation\UnauthorizedException; class StringController extends Controller { - public function fromUser(Request $request) + public function fromUser(Request $request): array { return [ 'strings' => $request->user()->strings, ]; } - public function createString(Request $request) + public function createString(Request $request): Model { $validated = $this->validate($request, [ 'value' => 'required|string|max:50', @@ -53,7 +54,7 @@ public function createString(Request $request) return $string; } - public function updateString(Request $request, $id) + public function updateString(Request $request, $id): Model { $validated = $this->validate($request, [ 'value' => 'required|string|max:50', @@ -70,7 +71,7 @@ public function updateString(Request $request, $id) return $string; } - public function deleteString(Request $request, $id) + public function deleteString(Request $request, $id): array { $string = StringValue::query()->findOrFail($id); diff --git a/composer.json b/composer.json index e9fbf1a..d3ff5f7 100644 --- a/composer.json +++ b/composer.json @@ -6,6 +6,7 @@ "type": "project", "require": { "php": ">=7.1.3", + "ext-json": "*", "laravel/lumen-framework": "5.7.*", "vlucas/phpdotenv": "~2.2" }, diff --git a/database/factories/StringValueFactory.php b/database/factories/StringValueFactory.php new file mode 100644 index 0000000..31aeac7 --- /dev/null +++ b/database/factories/StringValueFactory.php @@ -0,0 +1,43 @@ +define(App\Models\StringValue::class, function (Faker\Generator $faker) { + return [ + 'user_id' => factory(\App\Models\User::class)->create()->id, + 'value' => $faker->unique()->word, + ]; +}); diff --git a/database/factories/ModelFactory.php b/database/factories/UserFactory.php similarity index 91% rename from database/factories/ModelFactory.php rename to database/factories/UserFactory.php index 7d8f38f..0483879 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/UserFactory.php @@ -35,9 +35,8 @@ | */ -$factory->define(App\User::class, function (Faker\Generator $faker) { +$factory->define(App\Models\User::class, function (Faker\Generator $faker) { return [ - 'name' => $faker->name, - 'email' => $faker->email, + 'token' => $faker->uuid, ]; }); diff --git a/phpunit.xml b/phpunit.xml index 4055d54..63700ff 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -45,6 +45,8 @@ + + diff --git a/tests/StringTest.php b/tests/StringTest.php new file mode 100644 index 0000000..7a9afc7 --- /dev/null +++ b/tests/StringTest.php @@ -0,0 +1,133 @@ +user = factory(User::class)->create(); + } + + public function testUserCanRetrieveStrings() + { + /** + * @var \Illuminate\Database\Eloquent\Collection $stringsCollection + */ + $stringsCollection = factory(StringValue::class, 5)->create(['user_id' => $this->user->id]); + + // Other users also have strings + factory(StringValue::class, 3)->create(); + + $strings = $stringsCollection->map(function (StringValue $s) { + return $s->toArray(); + })->toArray(); + + $response = $this->request('GET', 'strings', $this->user)->decodeResponseJson()->strings; + + $userStrings = collect($response)->map(function ($s) { + // Map the values to match the faker return + return [ + 'value' => $s->value, + 'updated_at' => $s->updated_at, + 'created_at' => $s->created_at, + 'id' => $s->id, + ]; + })->toArray(); + + $this->assertCount(5, $strings); + $this->assertSameSize($strings, $userStrings); + $this->assertSame($strings, $userStrings); + } + + public function testUserCanNotRetrieveStringsWhenNotLoggedIn() + { + $response = $this->request('GET', 'strings', 'bla', [], [ + 'Authorization' => 'Token InvalidToken', + ]); + + $response->assertResponseStatus(403); + } + + public function testStringCreationWithValidParameters() + { + $data = [ + 'value' => str_random(), + ]; + + $currentStrings = $this->user->strings()->get(); + + $response = $this->request('POST', 'strings', $this->user, $data); + + $newStrings = $this->user->strings()->get(); + + $response->assertResponseStatus(200); + $this->assertCount(0, $currentStrings); + $this->assertCount(1, $newStrings); + } + + public function testStringCreationFailsWhenStringIsTooLarge() + { + $data = [ + 'value' => str_random(51), + ]; + + $response = $this->request('POST', 'strings', $this->user, $data); + + $response->assertResponseStatus(422); + } + + public function testUserCanDeleteOwnString() + { + $string = factory(StringValue::class)->create(['user_id' => $this->user->id]); + + $response = $this->request('DELETE', "strings/{$string->id}", $this->user); + + $response->assertResponseOk(); + } + + public function testUserCanNotDeleteOtherStrings() + { + $string = factory(StringValue::class)->create(); + + $response = $this->request('DELETE', "strings/{$string->id}", $this->user); + + $response->assertResponseStatus(403); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index e97233f..d449372 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,4 +1,7 @@ 'application/json'], $headers); + + if ($user instanceof User) { + $headers['Authorization'] = 'Token ' . $user->token; + } + + $request = $this->json($method, "api/$uri", $data, $headers); + + return $request; + } + + protected function decodeResponseJson($assoc = false) + { + $this->assertResponseOk(); + + return json_decode($this->response->getContent(), $assoc); } }