1

Я пытаюсь выполнить некоторые функциональные тесты для своего веб-приложения, использующего Play 2.1.4 и Socialsecure. Прежде чем использовать 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 и играть, но не обнаружил никаких тестов вообще.

Как я могу войти в систему для своего пользователя, чтобы я мог подготовить тесты?

С наилучшими пожеланиями Рава

+1

Взгляните на http://stackoverflow.com/questions/17735636/testing-a-play2-application-with-securesocial-using-dependency-injection/18690179#18690179. Это Scala, но вы должны иметь возможность делать то же самое на Java. –

+0

Спасибо, это помогло мне решить эту проблему! – Rawa

ответ

2

Благодаря David Weinbergs комментарий я смог решить эту проблему после того, как какой-то след и ошибок. (:

Я начал свою реализацию Локальный_пользователя из этого ответа: https://stackoverflow.com/a/18589402/1724097

Это, как я ее решил:

Для модульных тестов я создал локальный пользователь в базе данных, с помощью Test- 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 

Тогда я сделал тестовый 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 = 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() в ваших защищенных действиях? –