Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: ->toMatchSnapshot() will not work with @csrf #946

Closed
alexmanase opened this issue Aug 31, 2023 · 11 comments
Closed

[Bug]: ->toMatchSnapshot() will not work with @csrf #946

alexmanase opened this issue Aug 31, 2023 · 11 comments

Comments

@alexmanase
Copy link
Contributor

What Happened

When I use expect($response)->toMatchSnapshot() and I use the @csrf directory the test will fail because the csrf is changed on every request.`

I think there should be a way to ignore the @csrf directive on snapshot testing.

How to Reproduce

  1. Create a Laravel Project with Pest
  2. Create a view that contains @csrf
  3. Use the Pest API for testing the snapshot: expect($response)->toMatchSnapshot().
  4. Run tests.

Sample Repository

https://github.com/alexmanase/pest-snapshost-csrf-issue

Pest Version

2.16.1

PHP Version

8.2.8

Operation System

macOS

Notes

No response

@alexmanase alexmanase added the bug label Aug 31, 2023
@nunomaduro
Copy link
Member

cc @freekmurze

@freekmurze
Copy link
Collaborator

In our projects we add a function to strip out the token of a value before snapshotting that value.

It would be nice if there were some helper methods on the Pest snapshot methods for this. Or maybe let the toMatchSnapshot() method accept a canonicalising callable.

expect($response)->toMatchSnapshot($callableThatWillCanonicaliseResponse)

@gehrisandro
Copy link
Contributor

There is a similar problem with wire:id="<random-string>" when trying to take a snapshot of a Livewire component.

I think it would be nice if the most common "problems" would be handled automatically by Pest. But the idea with the callable sounds nice for custom use cases. 👍

@owenvoke
Copy link
Member

owenvoke commented Sep 4, 2023

I think the callable makes the most sense. Perhaps for Livewire, it could be a hook or something via the Pest Livewire plugin, and @csrf output could be part of the Pest Laravel plugin. I think it seems a bit weird maybe to handle a bunch of Laravel-specific cases in Pest core. As people might ask us to add (and maintain) a bunch of other common cases, such as for Symfony and other frameworks. 🤷🏻

For example, we could have a method like Snapshot::macro('laravel.csrf', function () { ... });, and then in plugins they can register bits to strip out in snapshots. 🤷🏻 And then have like Snapshot::disableMacro('laravel.csrf'); if you don't want to include a plugins macro.

@gehrisandro
Copy link
Contributor

@owenvoke Sounds amazing 🎉

@nunomaduro
Copy link
Member

@gehrisandro I like the idea of nice if the most common "problems" would be handled automatically by Pest.

@gehrisandro
Copy link
Contributor

Here my current quick and dirty fix for Livewire:

expect(str($component->html(stripInitialData: true))->replaceMatches('/wire:id="[0-9a-zA-Z]*"/', ''))
        ->toMatchSnapshot();

If we all agree on the suggestion by @owenvoke I can help here. I should find some time by the end of this week.

@alexmanase
Copy link
Contributor Author

And here is my fix for the @csrf issue:

$response = get($url);
$content = $response->content();

$newContent = collect(
    str($content)->explode("\n")
)
    ->reject(fn (string $line) => str($line)->contains('_token'))
    ->reject(fn (string $line) => str($line)->contains('link rel="preload" as="style"'))
    ->implode("\n");

$response->setContent($newContent);

expect($response)->toMatchSnapshot();

@gehrisandro
Copy link
Contributor

Here my PR

@jellisii
Copy link

CSRF tokens can possibly be more easily stripped by using
$response->setContent(preg_replace('/' . csrf_token() . '/', '', $response->getContent()));

@nunomaduro
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants