Search code examples
javaplayframework-1.xjunit3

Play Framework 1.x Functional Test with @AllowFeature Controller Method


I do want to write some functional tests for our project. Techstack: Play Framework 1.5, Java 16, Junit 3.

I found following documentation: test - 1.5.x security - 1.5.x

So the Controller looks something like this.

@AllowFeature(Feature.SEARCH_BOX)
public static void search(String term) {
    //implementation omitted

    TablePage<MyAwesomeType> page = search(term);

    render(..., page, term);
}

And my test looks like this

public class SearchTest extends FunctionalTest {

    @Test
    public void search_withResults() {
        String term = "ABC";
        Http.Response response = GET("/foo/search?term=" + term);

        assertStatus(302, response);

        assertThat(renderArgs("page"), is(notNullValue()));
        TablePage<MyAwesomeType> page = (TablePage<MyAwesomeType>) renderArgs("page");

        assertTrue(page.getTotalRecords() >= 1);
    }

}

However, the TablePage<MyAwesomeType> page is null when it really should not be, and i am unable to step into the controller method with the debugger. So it looks like the controller method search(...) is not called at all.

The response Code is 302 - Found but I think this might be play suggestion it found the path /foo/search

My guess is that i need to setup some UserContext or send a authenticityToken along with the request. So play can check the required feature @AllowFeature(Feature.A_SEARCH_BOX).

Does anybody know how I would setup such a functional test?

Any help is appreciated. Thanks!


Solution

  • I was able to figure this out.

    I need to log into the application and then the play FunctionalTest.class takes care of the cookie.

    1. Add @NoAuthenticityto the login method
    @NoAuthenticity // <-- This enables execution without authenticityToken
    public static void login(@Required String username, @Required String password) {
        ... 
    }
    
    1. Post a request to login before the test.
    @Test
    public void search_withResults() {
        // 1. login
        Map<String, String> credentials = Map.of("username", "MyUsername", "password", "MyPassword");
        POST("/login", credentials); 
        // Note: session info / authenticityToken is stored in a cookie
        // FunctionalTest.class makes sure to use this cookie for subsequent requests
    
        // This request now works like a charm
        String term = "ABC";
        Http.Response response = GET("/foo/search?term=" + term);
    
        assertStatus(302, response);
    
        assertThat(renderArgs("page"), is(notNullValue()));
        TablePage<MyAwesomeType> page = (TablePage<MyAwesomeType>) renderArgs("page");
    
        assertTrue(page.getTotalRecords() >= 1);
    }
    

    Note: One can use the JUnit @Before Annotation to simplify the test class.

    @Before
    public void login(){
        Map<String, String> credentials = Map.of("username", "MyUsername", "password", "MyPassword");
        POST("/login", credentials);
    }
    
    @Test
    public void search_withResults() {
        String term = "ABC";
        Http.Response response = GET("/foo/search?term=" + term);
    
        assertStatus(302, response);
    
        assertThat(renderArgs("page"), is(notNullValue()));
        TablePage<MyAwesomeType> page = (TablePage<MyAwesomeType>) renderArgs("page");
    
        assertTrue(page.getTotalRecords() >= 1);
    }
    
    @Test
    public void anotherTest() { ... }
    
    @Test
    public void yetAnotherTest() { ... }