I\'ve been having some problems testing controllers that use Play\'s CSRF protection. To demonstrate this, I\'ve created a very simple Play application that minimally exhibi
To those that are still interested: I managed to solve this problem globally by enabling CSRF protection in tests. The app will then create a token for every request that does not contain one. See my answer to this question
Bonus answer for those interested in Java: I got this to work in the Java version of Play Framework 2.2 by adding
.withSession(CSRF.TokenName(), CSRFFilter.apply$default$5().generateToken())
to fakeRequest()
Following on from @plade, I added a helper method to my base test class:
protected static FakeRequest csrfRequest(String method, String url) {
String token = CSRFFilter.apply$default$5().generateToken();
return fakeRequest(method, url + "?csrfToken=" + token)
.withSession(CSRF.TokenName(), token);
}
I use the following method in my base integration test class:
def csrfRequest(method: String, uri: String)(implicit app: Application): FakeRequest[AnyContentAsEmpty.type] = {
val tokenProvider: TokenProvider = app.injector.instanceOf[TokenProvider]
val csrfTags = Map(Token.NameRequestTag -> "csrfToken", Token.RequestTag -> tokenProvider.generateToken)
FakeRequest(method, uri, FakeHeaders(), AnyContentAsEmpty, tags = csrfTags)
}
Then you can use it in your tests where you would use FakeRequest
.
One solution is to test using a browser, eg Fluentlenium, as this will manage cookies etc, so the CSRF protection should all just work.
The other solution is to add a session to the FakeRequest so that it contains a token, eg:
FakeRequest().withSession("csrfToken" -> CSRF.SignedTokenProvider.generateToken)
Obviously if you're doing that a lot, you can create a help method to do that for you.
For those who might be interested, I created a trait for play 2.5.x : https://stackoverflow.com/a/40259536/3894835
You can then use it in your tests requests like the addToken{} of the controller :
val fakeRequest = addToken(FakeRequest(/* params */))