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
如預期的那樣出色,非常感謝! – forste 2012-03-14 22:27:42