Now that we have an edit form, let's test that validation works.
Again, first, the working code.
php artisan make:request UpdateProductRequest
app/Http/Requests/UpdateProductRequest.php:
use Illuminate\Foundation\Http\FormRequest; class UpdateProductRequest extends FormRequest{ public function authorize(): bool { return true; } public function rules(): array { return [ 'name' => 'required', 'price' => 'required', ]; }}
app/Http/Controllers/ProductController.php:
use Illuminate\Http\RedirectResponse;use App\Http\Requests\UpdateProductRequest; class ProductController extends Controller{ // ... public function update(UpdateProductRequest $request, Product $product): RedirectResponse { $product->update($request->validated()); return redirect()->route('products.index'); }}
The PUT request is used for updating, so in the test, again acting as an admin, we send a PUT request with empty values.
tests/Feature/ProductsTest.php:
class ProductsTest extends TestCase{ // ... public function test_product_update_validation_error_redirects_back_to_form() { $product = Product::factory()->create(); $response = $this->actingAs($this->admin)->put('products/' . $product->id, [ 'name' => '', 'price' => '' ]); } private function createUser(bool $isAdmin = false): User { return User::factory()->create([ 'is_admin' => $isAdmin, ]); }}
And now, we need to assert. We can first assert that the response is a redirect. And then Laravel has an assertion just for validatiing errors assertInvalid
.
tests/Feature/ProductsTest.php:
class ProductsTest extends TestCase{ // ... public function test_product_update_validation_error_redirects_back_to_form() { $product = Product::factory()->create(); $response = $this->actingAs($this->admin)->put('products/' . $product->id, [ 'name' => '', 'price' => '' ]); } private function createUser(bool $isAdmin = false): User { return User::factory()->create([ 'is_admin' => $isAdmin, ]); $response->assertStatus(302); $response->assertInvalid(['name', 'price']); }}
Another assertion to assert validation can be used is assertSessionHasErrors
. In the same way as in assertInvalid
, we need to provide keys.
tests/Feature/ProductsTest.php:
class ProductsTest extends TestCase{ // ... public function test_product_update_validation_error_redirects_back_to_form() { $product = Product::factory()->create(); $response = $this->actingAs($this->admin)->put('products/' . $product->id, [ 'name' => '', 'price' => '' ]); } private function createUser(bool $isAdmin = false): User { return User::factory()->create([ 'is_admin' => $isAdmin, ]); $response->assertStatus(302); $response->assertInvalid(['name', 'price']); $response->assertSessionHasErrors(['name', 'price']); }}