Integrity constraint violation when testing using Pest php
test('admin cannot delete a category that is in use by an idea', function () {
$admin = User::factory()->create(['role' => 'admin']);
$category = Category::factory()->create();
Idea::factory()->for($category)->pending()->create(); // Idea uses this category
$response = $this->actingAs($admin)->delete(route('categories.destroy', $category));
$response->assertRedirect(); // Redirects back
$response->assertSessionHas('status', 'error');
$this->assertDatabaseHas('categories', ['id' => $category->id]); // Category still exists
});
I wrote this function to test Category Management feature. But when i run php artisan test, it return error value with Integrity constraint violation message. Can anyone help me to solve this?
You're creating an idea that reference a category. Deleting that category would cause a constraint violation, and you'll get an exception.
If you want to handle those errors gracefully, you'll need to catch query exceptions in your controller method. But I'm not a fan of that because query exceptions can be caused by other things too. I'd rather check if there are any associated ideas before deletion, and block the action with an error message if needed.
@newbie360 This isn't about the UI. The original poster is writing a feature test.
Hiding the button isn't sufficient. What if the user has added an idea on another browser tab? Or what if they're part of a team, and another user just added an idea?
An authorization error (403) is wrong and would mislead the user. The correct error would be 409 Conflict with a proper error message, so that the user understands what's going on.
@newbie360 There of course needs to be a policy, and I assume it's there already. But that's for authorization, and this isn't an authorization issue.
It's really bad practice to return incorrect status codes. Which one of those do you use when validation fails? Or when rate limit is exceeded, XSRF token is rejected, or a JS asset has been updated?
As for your testing suggestion, that's exactly what OP tried. It doesn't work because it triggers a 500 error, and there's no good programmatic way to differentiate it from unexpected query exceptions, which should be reported to developers.
And if an action fails, the user must see why it fails. Otherwise you'll frustrate them and clog up customer support. Just do the right thing.