2012-03-26 6 views
5

Sto cercando un modo per preservare la sessione quando uso la funzione fakeRequest di Play 2.0 nei miei test Java, ma i miei tentativi falliscono durante il richiamo dei metodi in Scala JAR.Mantieni la sessione nelle chiamate Java successive a fakeRequest di Play 2.0

Sulla base di una richiesta di pull citato nell'interrogazione Scala Add values to Session during testing (FakeRequest, FakeApplication), ho pensato che il seguente potrebbe funzionare in Java:

public Session getSession(Result result) { 
    play.api.mvc.Cookies scalaCookies = 
     play.api.test.Helpers.cookies(result.getWrappedResult()); 
    play.api.mvc.Cookie scalaSessionCookie = 
     scalaCookies.get(play.api.mvc.Session.COOKIE_NAME()).get(); 
    scala.Option<play.api.mvc.Cookie> optionalCookie = 
     scala.Option.apply(scalaSessionCookie); 

    // Compiles fine, but fails with NoSuchMethodError: 
    play.api.mvc.Session scalaSession = 
     play.api.mvc.Session.decodeFromCookie(optionalCookie); 

    return new play.mvc.Http.Session(Scala.asJava(scalaSession.data())); 
} 

Questo compila bene, ma durante l'esecuzione dei test mi viene:

java.lang.NoSuchMethodError: 
    play.api.mvc.Session.decodeFromCookie(Lscala/Option;)Lplay/api/mvc/Session; 

Essendo una Scala completamente nuova, non ho davvero idea se sono nemmeno vicino. The Scala Session does expose (trait) that method through CookieBaker, I think.

Si noti che non sono necessariamente alla ricerca di un modo per eseguire il codice sopra riportato; quanto sopra è davvero solo il primo (possibile) passo per ottenere la sessione. Poi probabilmente proverei ad usare qualcosa come play.api.mvc.Session.encodeAsCookie(session) per passarlo alle richieste successive. Come per the ZenTasks demo:

@Test 
public void testLoginAndMore() { 
    Helpers.running(Helpers.fakeApplication(Helpers.inMemoryDatabase()), 
    new Runnable() { 
    public void run() { 
     Map<String, String> data = new HashMap<String, String>(); 
     data.put("email", "[email protected]"); 
     data.put("password", "secret"); 

     Result result = 
     callAction(controllers.routes.ref.Application.authenticate(), 
      fakeRequest().withFormUrlEncodedBody(data)); 
     assertThat(status(result)).isEqualTo(Status.SEE_OTHER); 
     assertThat(redirectLocation(result)).isEqualTo("/"); 

     // All fine; we're logged in. Now somehow preserve the cookie. This 
     // does NOT do the trick: 
     Session session = getSession(result); 
     // ...subsequent callAction(..)s, somehow passing the session cookie 
    } 
    }); 
} 

Per 1.x, Playframework Secure module: how do you “log in” to test a secured controller in a FunctionalTest? aiuta, ma le cose sembrano essere cambiate in 2.0, e non ho mai usato 1.x.

+0

(anche aggiunto a [un post correlato nel gioco Framework gruppo Google] (https://groups.google.com/forum/#!searchin/play-framework/session/play-framework/FuXaP7z9wz8) , in attesa di moderazione. Continuerà a mantenerlo sincronizzato con questo post, se applicabile.) – Arjan

+0

In Google Gruppi, Peter Hausel ha appena scritto: * Ciao, ho intenzione di applicare una correzione per questo oggi (insieme al supporto di cookie e flash). Grazie Peter * – Arjan

risposta

6

Non c'è bisogno di molta magia dopotutto. Il seguente semplicemente conserva l'header HTTP che imposta i cookie, e passa che nella prossima richiesta:.

Map<String, String> data = new HashMap<String, String>(); 
data.put("email", "[email protected]"); 
data.put("password", "secret"); 

Result result = callAction(controllers.routes.ref.Application.authenticate(), 
    fakeRequest().withFormUrlEncodedBody(data)); 

assertThat(status(result)).isEqualTo(Status.SEE_OTHER); 
assertThat(redirectLocation(result)).isEqualTo("/"); 
// All fine; we're logged in. Preserve the cookies: 
String cookies = header(HeaderNames.SET_COOKIE, result); 

// Fetch next page, passing the cookies 
result = routeAndCall(fakeRequest(GET, redirectLocation(result)) 
    .withHeader(HeaderNames.COOKIE, cookies)); 

assertThat(status(result)).isEqualTo(Status.OK); 
assertThat(contentAsString(result).contains("Guillaume Bort")); 

(Vedi the first version di questa stessa risposta per alcune informazioni su come ottenere solo il cookie PLAY_SESSION, e l'analisi che Non è certo tuttavia.)

+0

Grazie mille per questa risposta. – Mikesname

3

È facile con la versione corrente di Play utilizzare la sessione nei test. È possibile utilizzare il metodo di supporto statico cookies(Result result).

// Route that sets some session data to be used in subsequent requests 
Result result = callAction(...); 
Http.Cookie[] cookies = FluentIterable.from(cookies(result)).toArray(Http.Cookie.class); 

FakeRequest request = new FakeRequest(GET, "/someRoute").withCookies(cookies); 
callAction(controllers.routes.ref.Application.requestNeedingSession(), request);