2012-03-26 23 views
5

Estoy buscando una forma de preservar la sesión cuando uso la prueba de reproducción de Play 2.0 en mis pruebas de Java, pero mis intentos fallan al invocar métodos basados ​​en Scala Paso.Mantener la sesión en llamadas posteriores de Java a la solicitud de Play 2.0.

Sobre la base de una solicitud de extracción mencionado en la pregunta Scala Add values to Session during testing (FakeRequest, FakeApplication), pensé que la siguiente podría trabajar en 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())); 
} 

Esto compila bien, pero durante la ejecución de las pruebas que me obtiene:

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

Al ser un Scala newby total, realmente no tengo idea si estoy cerca. La sesión de Scala does expose (trait) that method through CookieBaker, I piensa.

Tenga en cuenta que no necesariamente estoy buscando una forma de ejecutar el código anterior; lo anterior es realmente solo el primer paso (posible) para obtener la sesión. A continuación, probablemente intente utilizar algo como play.api.mvc.Session.encodeAsCookie(session) para pasarlo a las solicitudes posteriores. Al igual que para 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 
    } 
    }); 
} 

Para 1.x, Playframework Secure module: how do you “log in” to test a secured controller in a FunctionalTest? ayuda, pero las cosas parecen haber cambiado en 2.0, y nunca he usado 1.x.

+0

(también añadió a [una entrada relacionada en el grupo framework Play Google] (https://groups.google.com/forum/#!searchin/play-framework/session/play-framework/FuXaP7z9wz8) ; en espera de moderación: mantendrá eso sincronizado con esta publicación, si corresponde.) – Arjan

+0

En Grupos de Google, Peter Hausel acaba de escribir: * Hola, voy a presentar una solución para esto hoy (junto con el soporte de cookies y flash). Gracias peter * – Arjan

Respuesta

6

No se necesita mucha magia después de todo. La siguiente simplemente conserva la cabecera HTTP que define las cookies, y pasa que en la siguiente solicitud:.

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")); 

(Ver the first version de esta misma respuesta para alguna información sobre cómo obtener solamente la cookie PLAY_SESSION y análisis que Eso no es necesario sin embargo.)

+0

Muchas gracias por esta respuesta. – Mikesname

3

Es realmente fácil con la versión actual de Play utilizar la sesión en sus pruebas. Puede usar el método de ayuda estático 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); 
Cuestiones relacionadas