DEV Community

Elanor
Elanor

Posted on

Testing DataTables JSON response in Laravel without using Dusk

Recently, I needed to quickly test Datatables-as-a-service implementation but I didn't want to use Laravel Dusk for just one test. An easy workaround is to check that the JSON response contains the data that you're looking for. But because this is encoded I ran into a caveat with the random test data.

For example, I was filtering the datatable so that administrator users can see all the entries, but normal users can only see their own entries. We expect the JSON response to only have the data related to the specific user viewing the results.

Test That Users Can Only See Their Entries

public function testUserCanOnlySeeTheirEntries() {
    $user = factory('App\User')->create();
    // Create one that belongs to me
    $user_entry = factory('App\Entry')->create(['user_id' => $user->id]);
    // Create one that is random
    $other = factory('App\Entry')->create();

    $this->actingAs($user)
       ->getJson(route('entries.index'), ['HTTP_X-Requested-With' => 'XMLHttpRequest'])
       // See the users' results as expected
       ->assertJsonFragment(['end' => $user_entry->end->format('m/d/Y h:i A')])
       ->assertSeeText($user->name)
      // Don't see results that do not belong to me
       ->assertJsonMissing(['end' => $other->end->format('m/d/Y h:i A')])
       ->assertDontSeeText($other->user->name);
    }
Enter fullscreen mode Exit fullscreen mode

This test worked great, until it didn't. If Faker happened to generate a user's name with special characters, like Ellie O'Neil the test would fail due to encoding. Ellie O'Neil could not be found in string: Ellie O'Neil

Technically the application was working fine -- since this data will be passed to the browser for display it doesn't matter if it's encoded or not. But we want our CI pipelines to succeed no matter what the randomly generated data might be.

Quick fix for this is to use htmlspecialchars to encode the search string so that it will match the JSON results no matter what.

// Change
->assertSeeText($user->name)
// to
->assertSeeText(htmlspecialchars($user->name, ENT_QUOTES))
Enter fullscreen mode Exit fullscreen mode

Make sure to use the ENT_QUOTES flag so that apostraphes are encoded as well as everything else.

Top comments (0)