2012-03-14 55 views
1

我想測試我的Controller - Secure.java。我使用play的Fixtures類來設置數據庫。不幸的是,當POST調用發出並且控件的方法被調用時,數據庫變成空的。但是,在測試方法中,我可以按預期檢索數據。如何在playframework中爲功能測試設置數據庫/燈具

路由

POST /login          user.Secure.authenticate 

控制器Secure.java

package controllers.user; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.PrintStream; 
import java.lang.reflect.InvocationTargetException; 
import java.text.DateFormat; 
import java.text.SimpleDateFormat; 
import java.util.List; 
import java.util.Date; 
import java.util.TimeZone; 

import models.User; 
import play.Logger; 
import play.Play; 
import play.data.validation.Required; 
import play.libs.Crypto; 
import play.mvc.Controller; 
import play.mvc.Http; 
import play.mvc.Util; 
import play.utils.Java; 
import mashpan.crawl.dropbox.DropboxCrawler; 
import mashpan.security.Check; 
import mashpan.utilities.*; 

import controllers.Application; 

/** 
* a more or less exact copy of the secure implementation of play. 
* - enhanced with a transport guarantee. 
* - support for user authentification 
* 
* @author ra and Philip De Smedt 
* @version 0.1 
* @date 20/11/2011 
* 
*/ 
public class Secure extends TransportUriGuaranteeController { 

    public static void authenticate(@Required String username, String password, boolean remember) throws Throwable { 
     Logger.debug("[Secure] authenticate: " 
       + "[username=" + (username == null ? "null" : username.toString()) + "]" 
       + "[password=" + (password == null ? "null" : password.toString()) + "]" 
       + "[remember=" + remember + "]" 
       ); 

     // Check tokens 
     Boolean allowed = false; 
     User user = User.find("byEmail", username).first(); 
     Logger.debug("[Secure.authenticate] "+"[user=" + (user == null ? "null" : user.toString()) + "]"); 
//  try { 
//   // This is the deprecated method name 
//   allowed = (Boolean)Security.invoke("authentify", username, password); 
//  } 
//  catch (UnsupportedOperationException e) 
//  { 
//   // This is the official method name 
//   allowed = (Boolean)Security.invoke("authenticate", username, password); 
//  } 

     allowed = Security.authenticate(username, password); 


     if(validation.hasErrors() || !allowed) { 
      Logger.debug("[Secure] Authentication failed" 
        + ", validationhasErrors()=" + validation.hasErrors() 
        + ", allowed="+allowed 
        ); 
      if(validation.hasErrors()) { 
       Logger.debug("[Secure] validation has errors!"); 
       for(play.data.validation.Error e : validation.errors()) { 
        Logger.debug("[Secure] Error: "+"[e=" + (e == null ? "null" : e.toString()) + "]"); 
       } 
      } 
      flash.keep("url"); 
      flash.error("secure.error"); 
      params.flash(); 
      Application.index(); 
     } 

     // Mark user as connected 
     session.put("email", username); 

     // Remember if needed 
     if (remember) 
     { 
      response.setCookie("rememberme", Crypto.sign(username) + "-" + username, "30d"); 
     } 

     // Save last login time and redirect to the original URL (or /) 
     User u = User.find("byEmail", username).first(); 
     u.lastLogin = new Date(); 
     u.save(); 

     Logger.debug("[Secure] Successfully authenticated user. Redirecting..."); 
     redirectToOriginalURL(); 
    } 


    public static class Security extends Controller { 

     /** 
     * Extend Play!s security mechanism to authenticate against 
     * the User object. 
     */ 
     public static boolean authenticate(String email, String password) { 
      Logger.debug("[Secure.Security.authenticate] " 
        + "[email=" + (email == null ? "null" : email.toString()) + "]" 
        + "[password=" + (password == null ? "null" : password.toString()) + "]"); 

      User user = User.find("byEmail", email).first(); 
      List<User> users = User.<User>findAll(); 
      Logger.debug("[Secure.Security] # of users found="+users.size()); 
      for(User u : users) { 
       Logger.debug("[Secure.Security] "+"[u=" + (u == null ? "null" : u.toString()) + "]"); 
      } 

      if (user == null) { 
       Logger.debug("[Secure.Security] Could not find user, authentication failed!"); 
       return false; 
      } 

      if (user.confirmationCode.length() != 0) { //user not confirmed yet 
       Logger.debug("[Secure.Security] User not confirmed yet, authentication failed!"); 
       return false; 
      } 
      return user.isThisCorrectUserPassword(password); 
     } 

     public static boolean check(String check) { 
      if ("isConnected".equals(check)) { 
       return Security.isConnected();     
      } 
      return false; 
     } 

     /** 
     * This method returns the current connected username 
     * @return 
     */ 
     public static String connected() { 
      return session.get("email"); 
     } 

     /** 
     * Indicate if a user is currently connected 
     * @return true if the user is connected 
     */ 
     public static boolean isConnected() { 
      return session.contains("email"); 
     } 

     /** 
     * This method is called after a successful authentication. 
     * You need to override this method if you with to perform specific actions (eg. Record the time the user signed in) 
     */ 
     static void onAuthenticated() { } 

     /** 
     * This method is called before a user tries to sign off. 
     * You need to override this method if you wish to perform specific actions (eg. Record the name of the user who signed off) 
     */ 
     static void onDisconnect() { } 

     /** 
     * This method is called after a successful sign off. 
     * You need to override this method if you wish to perform specific actions (eg. Record the time the user signed off) 
     */ 
     static void onDisconnected() { } 

     /** 
     * This method is called if a check does not succeed. By default it shows the not allowed page (the controller forbidden method). 
     * @param profile 
     */ 
     static void onCheckFailed(String profile) { 
      forbidden(); 
     } 
    } 
} 

測試類SecureTest.java

package controller.user; 

import java.util.*; 

import mashpan.utilities.*; 
import models.*; 

import org.junit.*; 

import play.*; 
import play.cache.*; 
import play.db.jpa.GenericModel.JPAQuery; 
import play.mvc.Http.Response; 
import play.test.*; 

public class FunctionalSecureTests extends FunctionalTest { 
    @Before 
    public void setUp() { 
     Fixtures.deleteDatabase(); 
     Fixtures.loadModels("testusers.yaml"); 
     Cache.clear(); 
    } 


    @Test 
    public void postLogin_shouldHaveStatus200() { 
     User user = User.find("byEmail", UserUtility.EMAIL).first(); 
     Logger.debug("[FunctionalSecureTests] "+"[user=" + (user == null ? "null" : user.toString()) + "]"); //prints out 


     Map<String, String> parameters = new HashMap<String, String>(); 
     parameters.put("username", UserUtility.EMAIL); 
     parameters.put("password", UserUtility.PASSWORD); 

     Response response = POST("/login", parameters); 

     assertIsOk(response); 
     assertStatus(200, response); 
    } 

} 

的conf/testusers.yaml

User(mashpan): 
    first_name: "Mash" 
    last_name: "Pan" 
    email: "[email protected]" 
    signupDate: 2012-03-08 
    passwordHash: "NOTFORYOU" 
    isAdmin: No 
    confirmationCode: "" 
    activationSent: Yes 
    recoverPasswordCode: !!null 
    lastLogin: !!null 
    referralCode: !!null 

堆棧跟蹤

DEBUG 232 :play#debug - [FunctionalSecureTests] [user=User [first_name=Mash, last_name=Pan, [email protected], signupDate=2012-03-08 01:00:00.0, passwordHash=$2a$10$L6IdeDhMGe1T7IbtSDd.6uLOvhHk7IoAzRzGzNlk8Cm4WWyWCbIp., isAdmin=false, confirmationCode=, activationSent=true, recoverPasswordCode=null, lastLogin=null, referralCode=null, [id=1]]] 
    DEBUG 232 :play#debug - [Secure] authenticate: [[email protected]][password=chickenrunfasteriffedup][remember=false] 
    DEBUG 232 :play#debug - [Secure.authenticate] [user=null] 
    DEBUG 232 :play#debug - [Secure.Security.authenticate] [[email protected]][password=chickenrunfasteriffedup] 
    DEBUG 232 :play#debug - [Secure.Security] # of users found=0 
    DEBUG 232 :play#debug - [Secure.Security] Could not find user, authentication failed! 
    DEBUG 232 :play#debug - [Secure] Authentication failed, validationhasErrors()=false, allowed=false 

回答

4

你的功能測試運行中,將在測試結束時結束事務。因此,在測試完成之前,您在此事務中執行的所有操作都不會提交給數據庫。因此,在這種情況下,您可以使用作業創建僅用於設置的新交易

@Before 
public void setUp() throws Exception { 
    new Job() { 
     @Override 
     public void doJob() throws Exception { 
      Fixtures.deleteDatabase(); 
      Fixtures.loadModels("testusers.yaml"); 
      Cache.clear(); 
     } 
    }.now().get(); 
} 
+0

如預期的那樣出色,非常感謝! – forste 2012-03-14 22:27:42

相關問題