package com.porterhead.rest.user.social;
import com.porterhead.rest.config.ApplicationConfig;
import com.porterhead.rest.user.UserService;
import com.porterhead.rest.user.UserServiceImpl;
import com.porterhead.rest.user.api.AuthenticatedUserToken;
import com.porterhead.rest.user.api.CreateUserRequest;
import com.porterhead.rest.user.api.ExternalUser;
import com.porterhead.rest.user.api.PasswordRequest;
import com.porterhead.rest.user.builder.ExternalUserBuilder;
import com.porterhead.rest.user.domain.Role;
import com.porterhead.rest.user.domain.SocialUser;
import com.porterhead.rest.user.domain.User;
import org.apache.commons.lang.RandomStringUtils;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.social.connect.UserProfile;
import org.springframework.social.connect.UserProfileBuilder;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.List;
import java.util.UUID;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
/**
* User: porter
* Date: 21/05/2012
* Time: 18:35
*/
public class JpaUsersConnectionRepositoryTest extends AbstractSocialTst {
private JpaUsersConnectionRepository usersConnectionRepository;
private Validator validator;
private ApplicationConfig applicationConfig;
public void setUpRepository() {
usersConnectionRepository = new JpaUsersConnectionRepository(
socialUserRepository, userRepository, connectionFactoryLocator, textEncryptor);
when(userRepository.save(any(User.class))).thenAnswer(new Answer<User>() {
public User answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
user.setUuid(((User) args[0]).getUuid().toString());
return (User) args[0];
}
});
validator = Validation.buildDefaultValidatorFactory().getValidator();
applicationConfig = mock(ApplicationConfig.class);
when(applicationConfig.getAuthorizationExpiryTimeInSeconds()).thenReturn(60 * 60);
}
@Test
public void firstTimeConnected() {
UserService userService = new UserServiceImpl(usersConnectionRepository, validator, applicationConfig);
((UserServiceImpl)userService).setUserRepository(userRepository);
List<String> userIds = usersConnectionRepository.findUserIdsWithConnection(connection);
assertThat(userIds.size(), is(1));
assertThat(userIds.get(0), is(user.getUuid().toString()));
verify(userRepository, times(2)).save(any(User.class));
verify(socialUserRepository).save(any(SocialUser.class));
}
@Test
public void alreadyRegistered() {
when(socialUserRepository.findByProviderIdAndProviderUserId(PROVIDER_ID, PROVIDER_USER_ID)).thenReturn(socialUsers);
List<String> userIds = usersConnectionRepository.findUserIdsWithConnection(connection);
assertThat(userIds.size(), is(1));
assertThat(userIds.get(0), is(user.getUuid().toString()));
verify(userRepository, never()).save(any(User.class));
verify(socialUserRepository, never()).save(any(SocialUser.class));
}
@Test
public void validSocialLogin() {
UserService userService = new UserServiceImpl(usersConnectionRepository, validator, applicationConfig);
((UserServiceImpl)userService).setUserRepository(userRepository);
UserProfileBuilder builder = new UserProfileBuilder();
UserProfile profile = builder.setFirstName("Tom").setLastName("Tucker").setEmail("tt@example.com").setUsername("ttucker").build();
when(connection.fetchUserProfile()).thenReturn(profile);
AuthenticatedUserToken token = userService.socialLogin(connection);
ExternalUser user = userService.getUser(new ExternalUser(token.getUserId()), token.getUserId());
assertThat(user, is(notNullValue()));
assertThat(user.getEmailAddress(), is("tt@example.com"));
assertThat(user.getFirstName(), is("Tom"));
assertThat(user.getLastName(), is("Tucker"));
assertThat(user.isVerified(), is(true));
assertThat(user.getRole().equalsIgnoreCase(Role.authenticated.toString()), is(true));
}
@Test
public void updateFromSocialLogin() {
UserService userService = new UserServiceImpl(usersConnectionRepository, validator, applicationConfig);
((UserServiceImpl)userService).setUserRepository(userRepository);
UserProfileBuilder builder = new UserProfileBuilder();
UserProfile profile = builder.setFirstName("Tom").setLastName("Tucker").setEmail("tt@example.com").setUsername("ttucker").build();
when(connection.fetchUserProfile()).thenReturn(profile);
userService.socialLogin(connection);
//login again and update
profile = builder.setFirstName("Foo").setLastName("Bar").setEmail("foobar@example.com").setUsername("foobar").build();
when(connection.fetchUserProfile()).thenReturn(profile);
AuthenticatedUserToken token = userService.socialLogin(connection);
ExternalUser user = userService.getUser(new ExternalUser(token.getUserId()), token.getUserId());
assertThat(user, is(notNullValue()));
assertThat(user.getEmailAddress(), is("foobar@example.com"));
assertThat(user.getFirstName(), is("Foo"));
assertThat(user.getLastName(), is("Bar"));
assertThat(user.isVerified(), is(true));
assertThat(user.getRole().equalsIgnoreCase(Role.authenticated.toString()), is(true));
}
/**
* Test to ensure that the social login is linked to the previously enrolled email address
*
*/
@Test
public void loginWithEmailAddressThenSocialLogin() {
//set up services
UserService userService = new UserServiceImpl(usersConnectionRepository, validator, applicationConfig);
((UserServiceImpl) userService).setUserRepository(userRepository);
//create email account
CreateUserRequest request = getCreateUserRequest(RandomStringUtils.randomAlphabetic(8) + "@example.com");
AuthenticatedUserToken token = userService.createUser(request, Role.authenticated);
UserProfileBuilder builder = new UserProfileBuilder();
UserProfile profile = builder.setFirstName(user.getFirstName()).setLastName(user.getLastName()).setEmail(user.getEmailAddress()).setUsername("jsmith.12").build();
when(connection.fetchUserProfile()).thenReturn(profile);
when(userRepository.findByEmailAddress(any(String.class))).thenReturn(new User(UUID.fromString(token.getUserId())));
when(userRepository.findByUuid(any(String.class))).thenReturn(new User(UUID.fromString(token.getUserId())));
AuthenticatedUserToken loginToken = userService.socialLogin(connection);
ExternalUser user = userService.getUser(new ExternalUser(token.getUserId()), token.getUserId());
assertThat(token.getUserId(), is(loginToken.getUserId()));
}
private CreateUserRequest getCreateUserRequest(String emailAddress) {
CreateUserRequest request = new CreateUserRequest();
ExternalUser user = ExternalUserBuilder.create().withFirstName("John")
.withLastName("Smith")
.withEmailAddress(emailAddress)
.build();
request.setUser(user);
request.setPassword(new PasswordRequest("password"));
return request;
}
}