我正在尝试为使用Play 2.1.4和Socialsecure的web应用程序进行一些功能测试。在使用securesocial之前,这些测试非常直接,但现在我遇到了麻烦,想象一下我如何对安全行为进行测试。
@Test
public void createNewNote() {
Result result;
// Should return bad request if no data is given
result = callAction(
controllers.routes.ref.Notes.newNote(),
fakeRequest().withFormUrlEncodedBody(
ImmutableMap.of("title", "", "text",
"")));
assertThat(status(result)).isEqualTo(BAD_REQUEST);
result = callAction(
controllers.routes.ref.Notes.newNote(),
fakeRequest().withFormUrlEncodedBody(
ImmutableMap.of("title", "My note title", "text",
"My note content")));
// Should return redirect status if successful
assertThat(status(result)).isEqualTo(SEE_OTHER);
assertThat(redirectLocation(result)).isEqualTo("/notes");
Note newNote = Note.find.where().eq("title", "My note title")
.findUnique();
// Should be saved to DB
assertNotNull(newNote);
assertEquals("My note title", newNote.title);
assertEquals("My note content", newNote.text);
}
截至目前,我在测试yml文件中有一个用户:
- !!models.User
id: 1234567890
username: Pingu
provider: Twitter
firstName: Pingu
lastName: Pingusson
email: pingu@note.com
password: password
我的用户很直接......:
@Table(
uniqueConstraints=
@UniqueConstraint(columnNames={"username"}))
@Entity
public class User extends Model {
private static final long serialVersionUID = 1L;
@Id
public String id;
public String provider;
public String firstName;
public String lastName;
public String email;
public String password;
@MinLength(5)
@MaxLength(20)
public String username;
public static Finder<String, User> find = new Finder<String, User>(
String.class, User.class);
public static User findById(String id) {
return find.where().eq("id", id).findUnique();
}
public static User findByEmail(String email) {
return find.where().eq("email", email).findUnique();
}
@Override
public String toString() {
return this.id + " - " + this.firstName;
}
}
和UserService:
公共类UserService扩展了BaseUserService {
public UserService(Application application) {
super(application);
}
@Override
public void doDeleteExpiredTokens() {
if (Logger.isDebugEnabled()) {
Logger.debug("deleteExpiredTokens...");
}
List<LocalToken> list = LocalToken.find.where().lt("expireAt", new DateTime().toString()).findList();
for(LocalToken localToken : list) {
localToken.delete();
}
}
@Override
public void doDeleteToken(String uuid) {
if (Logger.isDebugEnabled()) {
Logger.debug("deleteToken...");
Logger.debug(String.format("uuid = %s", uuid));
}
LocalToken localToken = LocalToken.find.byId(uuid);
if(localToken != null) {
localToken.delete();
}
}
@Override
//public Identity doFind(UserId userId) {
public Identity doFind(IdentityId identityId){
if (Logger.isDebugEnabled()) {
Logger.debug(String.format("finding by Id = %s", identityId.userId()));
}
User localUser = User.find.byId(identityId.userId());
Logger.debug(String.format("localUser = " + localUser));
if(localUser == null) return null;
SocialUser socialUser = new SocialUser(new IdentityId(localUser.id, localUser.provider),
localUser.firstName,
localUser.lastName,
String.format("%s %s", localUser.firstName, localUser.lastName),
Option.apply(localUser.email),
null,
new AuthenticationMethod("userPassword"),
null,
null,
Some.apply(new PasswordInfo("bcrypt", localUser.password, null))
);
if (Logger.isDebugEnabled()) {
Logger.debug(String.format("socialUser = %s", socialUser));
}
return socialUser;
}
@Override
public Identity doFindByEmailAndProvider(String email, String providerId) {
List<User> list = User.find.where().eq("email", email).eq("provider", providerId).findList();
if(list.size() != 1){
Logger.debug("found a null in findByEmailAndProvider...");
return null;
}
User localUser = list.get(0);
SocialUser socialUser =
new SocialUser(new IdentityId(localUser.email, localUser.provider),
localUser.firstName,
localUser.lastName,
String.format("%s %s", localUser.firstName, localUser.lastName),
Option.apply(localUser.email),
null,
new AuthenticationMethod("userPassword"),
null,
null,
Some.apply(new PasswordInfo("bcrypt", localUser.password, null))
);
return socialUser;
}
@Override
public Token doFindToken(String token) {
if (Logger.isDebugEnabled()) {
Logger.debug("findToken...");
Logger.debug(String.format("token = %s", token));
}
LocalToken localToken = LocalToken.find.byId(token);
if(localToken == null) return null;
Token result = new Token();
result.uuid = localToken.uuid;
result.creationTime = new DateTime(localToken.createdAt);
result.email = localToken.email;
result.expirationTime = new DateTime(localToken.expireAt);
result.isSignUp = localToken.isSignUp;
if (Logger.isDebugEnabled()) {
Logger.debug(String.format("foundToken = %s", result));
}
return result;
}
@Override
public Identity doSave(Identity user) {
if (Logger.isDebugEnabled()) {
Logger.debug("save...!_!");
Logger.debug(String.format("user = %s", user));
}
User localUser = null;
localUser = User.find.byId(user.identityId().userId());
Logger.debug("id = " + user.identityId().userId());
Logger.debug("provider = " + user.identityId().providerId());
Logger.debug("firstName = " + user.firstName());
Logger.debug("lastName = " + user.lastName());
Logger.debug(user.fullName() + "");
Logger.debug("email = " + user.email());
Logger.debug(user.email().getClass() + "");
if (localUser == null) {
Logger.debug("adding new...");
localUser = new User();
localUser.id = user.identityId().userId();
localUser.provider = user.identityId().providerId();
localUser.firstName = user.firstName();
localUser.lastName = user.lastName();
//Temporary solution for twitter which does not have email in OAuth answer
if(!(user.email().toString()).equals("None")){
localUser.email = user.email().get();
}
if(!(user.passwordInfo() + "").equals("None")){
localUser.password = user.passwordInfo().get().password();
}
localUser.save();
} else {
Logger.debug("existing one...");
localUser.id = user.identityId().userId();
localUser.provider = user.identityId().providerId();
localUser.firstName = user.firstName();
localUser.lastName = user.lastName();
//Temporary solution for twitter which does not have email in OAuth answer
if(!(user.email().toString()).equals("None")){
localUser.email = user.email().get();
}
if(!(user.passwordInfo() + "").equals("None")){
localUser.password = user.passwordInfo().get().password();
}
localUser.update();
}
return user;
}
@Override
public void doSave(Token token) {
LocalToken localToken = new LocalToken();
localToken.uuid = token.uuid;
localToken.email = token.email;
try {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
localToken.createdAt = df.parse(token.creationTime.toString("yyyy-MM-dd HH:mm:ss"));
localToken.expireAt = df.parse(token.expirationTime.toString("yyyy-MM-dd HH:mm:ss"));
} catch (ParseException e) {
Logger.error("UserService.doSave(): ", e);
}
localToken.isSignUp = token.isSignUp;
localToken.save();
}
}
根据我的理解,我应该在某种程度上设置会话,以便用户通过在fakerequest上使用.withsession方法登录,也可以在服务器端设置一些值。
尝试使用securesocial和play在网上搜索示例,但根本没有找到任何测试。
如何登录我的用户以便我可以预先测试?
祝你好运 拉瓦
答案 0 :(得分:2)
感谢David Weinbergs评论我能够在一些跟踪和错误之后解决这个问题。 (:
我从这个回复中开始了我的LocalUser实现: https://stackoverflow.com/a/18589402/1724097
这就是我解决它的方法:
要进行单元测试,我使用test-data.yml文件在数据库中创建了一个本地用户:
- !!models.LocalUser
id: 1234567890
username: Username
provider: userpass
firstName: firstName
lastName: lastName
email: user@example.com
#hash for "password"
password: $2a$10$.VE.rwJFMblRv2HIqhZM5.CiqzYOhhJyLYrKpMmwXar6Vp58U7flW
然后我创建了一个测试utils类来创建我的fakeCookie。
import models.LocalUser;
import play.Logger;
import securesocial.core.Authenticator;
import securesocial.core.IdentityId;
import securesocial.core.SocialUser;
import securesocial.core.PasswordInfo;
import scala.Some;
import securesocial.core.AuthenticationMethod;
import scala.Option;
import scala.util.Right;
import scala.util.Either;
import play.mvc.Http.Cookie;
public class Utils {
public static Cookie fakeCookie(String user){
LocalUser localUser = LocalUser.findByEmail(user);
Logger.debug("Username: " + localUser.username +" - ID: " + localUser.id);
SocialUser socialUser = new SocialUser(new IdentityId(localUser.id, localUser.provider),
localUser.firstName,
localUser.lastName,
String.format("%s %s", localUser.firstName, localUser.lastName),
Option.apply(localUser.email),
null,
new AuthenticationMethod("userPassword"),
null,
null,
Some.apply(new PasswordInfo("bcrypt", localUser.password, null))
);
Either either = Authenticator.create(socialUser);
Authenticator auth = (Authenticator) either.right().get();
play.api.mvc.Cookie scalaCookie = auth.toCookie();
//debug loggig
Logger.debug("Cookie data:");
Logger.debug("Name: " + "Value: " + auth.cookieName() + " | Class: " + auth.cookieName().getClass() + " | Should be type: " + "java.lang.String");
Logger.debug("Value: " + "Value: " + scalaCookie.value() + " | Class: " + scalaCookie.value().getClass() + " | Should be type: " + "java.lang.String");
Logger.debug("MaxAge: " + "Value: " + scalaCookie.maxAge() + " | Class: " + scalaCookie.maxAge().getClass() + " | Should be type: " + "int");
Logger.debug("Path: " + "Value: " + scalaCookie.path() + " | Class: " + scalaCookie.path().getClass() + " | Should be type: " + "java.lang.String");
Logger.debug("Domain: " + "Value: " + scalaCookie.domain() + " | Class: " + auth.cookieDomain().getClass() + " | Should be type: " + "java.lang.String");
Logger.debug("Secure: " + "Value: " + auth.cookieSecure() + " | Class: " + "Boolean" + " | Should be type: " + "boolean");
Logger.debug("HttpOnly: " + "Value: " + auth.cookieHttpOnly() + " | Class: " + "Boolean" + " | Should be type: " + "boolean");
// secureSocial doesnt seem to set a maxAge or Domain so i set them myself.
Cookie fakeCookie = new Cookie(auth.cookieName(), scalaCookie.value(), 120, scalaCookie.path(), "None", auth.cookieSecure(), auth.cookieHttpOnly());
return fakeCookie;
}
}
然后我只是在fakeRequest中使用我的cookie,所以我登录了:
Cookie cookie = Utils.fakeCookie("user@example.com");
Result result = callAction(
controllers.routes.ref.yourSampleClass.yourSecuredFucntion(),
fakeRequest().withFormUrlEncodedBody(
ImmutableMap.of("Value", "Some input value")).withCookies(cookie));
// Should return redirect status if successful
assertThat(status(result)).isEqualTo(SEE_OTHER);
assertThat(redirectLocation(result)).isEqualTo("/yourWantedResult");
希望这有助于其他人!