1

我想爲我的使用Play 2.1.4和Socialsecure的web應用程序進行一些功能測試。在使用securesocial之前,這些測試非常簡單,但現在我有麻煩了,我可以對安全操作進行測試。用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: [email protected] 
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(); 
} 

}

由於我的理解,我就要讓用戶通過使用.withsession方法上fakerequest登錄,也許還設置一些好歹設置會話在服務器端的價值。

嘗試使用securesocial和play搜索網絡示例,但根本沒有發現任何測試。

我如何在我的用戶登錄,所以我可以preform測試?

問候 拉瓦

+1

看看http://stackoverflow.com/questions/17735636/testing-a-play2-application-with-securesocial-using-dependency-injection/18690179#18690179。它是Scala,但你應該可以在Java中做同樣的事情。 –

+0

謝謝,這幫助我解決了這個問題! – Rawa

回答

2

感謝David溫伯格評論我能有些線索和錯誤後,解決這個問題。 (:

我從這個答覆開始了我的LocalUser實現: https://stackoverflow.com/a/18589402/1724097

這是我如何解決它:

爲了使單元測試,我創建數據庫的本地用戶,使用測試 - data.yml文件:

- !!models.LocalUser 
    id: 1234567890 
    username: Username 
    provider: userpass 
    firstName: firstName 
    lastName: lastName 
    email: [email protected] 
    #hash for "password" 
    password: $2a$10$.VE.rwJFMblRv2HIqhZM5.CiqzYOhhJyLYrKpMmwXar6Vp58U7flW 

然後我做了我創建一個fakeCookie測試utils的類

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; 
    } 
} 

然後,我只是用我的cookie來在fakeRequest這樣的IM登錄:

Cookie cookie = Utils.fakeCookie("[email protected]"); 

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

希望這會幫助別人!

+0

您的解決方案已幫助我使用cookie,但出於興趣,您可以從您的ctx()中獲取當前用戶的安全操作? –