package com.worktajm.repository;
import com.worktajm.Application;
import com.worktajm.domain.SocialUserConnection;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.social.connect.*;
import org.springframework.social.connect.support.ConnectionFactoryRegistry;
import org.springframework.social.connect.support.OAuth1ConnectionFactory;
import org.springframework.social.connect.support.OAuth2ConnectionFactory;
import org.springframework.social.oauth1.OAuth1Operations;
import org.springframework.social.oauth1.OAuth1ServiceProvider;
import org.springframework.social.oauth2.*;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import javax.inject.Inject;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.assertj.core.api.StrictAssertions.assertThat;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest
@Transactional
public class CustomSocialUsersConnectionRepositoryIntTest {
private ConnectionFactoryRegistry connectionFactoryRegistry;
private TestFacebookConnectionFactory connectionFactory;
private CustomSocialUsersConnectionRepository usersConnectionRepository;
private ConnectionRepository connectionRepository;
@Inject
private SocialUserConnectionRepository socialUserConnectionRepository;
@Before
public void setUp() {
socialUserConnectionRepository.deleteAll();
connectionFactoryRegistry = new ConnectionFactoryRegistry();
connectionFactory = new TestFacebookConnectionFactory();
connectionFactoryRegistry.addConnectionFactory(connectionFactory);
usersConnectionRepository = new CustomSocialUsersConnectionRepository(socialUserConnectionRepository, connectionFactoryRegistry);
connectionRepository = usersConnectionRepository.createConnectionRepository("1");
}
@Test
public void findUserIdWithConnection() {
insertFacebookConnection();
List<String> userIds = usersConnectionRepository.findUserIdsWithConnection(connectionRepository.getPrimaryConnection(TestFacebookApi.class));
assertEquals("1", userIds.get(0));
}
@Test
public void findUserIdWithConnectionNoSuchConnection() {
Connection<TestFacebookApi> connection = connectionFactory.createConnection(new AccessGrant("12345"));
assertEquals(0, usersConnectionRepository.findUserIdsWithConnection(connection).size());
}
@Test
public void findUserIdWithConnectionMultipleConnectionsToSameProviderUser() {
insertFacebookConnection();
insertFacebookConnectionSameFacebookUser();
List<String> localUserIds = usersConnectionRepository.findUserIdsWithConnection(connectionRepository.getPrimaryConnection(TestFacebookApi.class));
assertEquals(2, localUserIds.size());
assertEquals("1", localUserIds.get(0));
assertEquals("2", localUserIds.get(1));
}
@Test
public void findUserIdsConnectedTo() {
insertFacebookConnection();
insertFacebookConnection3();
Set<String> localUserIds = usersConnectionRepository.findUserIdsConnectedTo("facebook", new HashSet<>(Arrays.asList("9", "11")));
assertEquals(2, localUserIds.size());
assertTrue(localUserIds.contains("1"));
assertTrue(localUserIds.contains("2"));
}
@Test
@SuppressWarnings("unchecked")
public void findAllConnections() {
connectionFactoryRegistry.addConnectionFactory(new TestTwitterConnectionFactory());
insertTwitterConnection();
insertFacebookConnection();
MultiValueMap<String, Connection<?>> connections = connectionRepository.findAllConnections();
assertEquals(2, connections.size());
Connection<TestFacebookApi> facebook = (Connection<TestFacebookApi>) connections.getFirst("facebook");
assertFacebookConnection(facebook);
Connection<TestTwitterApi> twitter = (Connection<TestTwitterApi>) connections.getFirst("twitter");
assertTwitterConnection(twitter);
}
@Test
public void findAllConnectionsMultipleConnectionResults() {
connectionFactoryRegistry.addConnectionFactory(new TestTwitterConnectionFactory());
insertTwitterConnection();
insertFacebookConnection();
insertFacebookConnection2();
MultiValueMap<String, Connection<?>> connections = connectionRepository.findAllConnections();
assertEquals(2, connections.size());
assertEquals(2, connections.get("facebook").size());
assertEquals(1, connections.get("twitter").size());
}
@Test
public void findAllConnectionsEmptyResult() {
connectionFactoryRegistry.addConnectionFactory(new TestTwitterConnectionFactory());
MultiValueMap<String, Connection<?>> connections = connectionRepository.findAllConnections();
assertEquals(2, connections.size());
assertEquals(0, connections.get("facebook").size());
assertEquals(0, connections.get("twitter").size());
}
@Test(expected = IllegalArgumentException.class)
public void noSuchConnectionFactory() {
insertTwitterConnection();
connectionRepository.findAllConnections();
}
@Test
@SuppressWarnings("unchecked")
public void findConnectionsByProviderId() {
connectionFactoryRegistry.addConnectionFactory(new TestTwitterConnectionFactory());
insertTwitterConnection();
List<Connection<?>> connections = connectionRepository.findConnections("twitter");
assertEquals(1, connections.size());
assertTwitterConnection((Connection<TestTwitterApi>) connections.get(0));
}
@Test
public void findConnectionsByProviderIdEmptyResult() {
assertTrue(connectionRepository.findConnections("facebook").isEmpty());
}
@Test
public void findConnectionsByApi() {
insertFacebookConnection();
insertFacebookConnection2();
List<Connection<TestFacebookApi>> connections = connectionRepository.findConnections(TestFacebookApi.class);
assertEquals(2, connections.size());
assertFacebookConnection(connections.get(0));
}
@Test
public void findConnectionsByApiEmptyResult() {
assertTrue(connectionRepository.findConnections(TestFacebookApi.class).isEmpty());
}
@Test
@SuppressWarnings("unchecked")
public void findConnectionsToUsers() {
connectionFactoryRegistry.addConnectionFactory(new TestTwitterConnectionFactory());
insertTwitterConnection();
insertFacebookConnection();
insertFacebookConnection2();
MultiValueMap<String, String> providerUsers = new LinkedMultiValueMap<>();
providerUsers.add("facebook", "10");
providerUsers.add("facebook", "9");
providerUsers.add("twitter", "1");
MultiValueMap<String, Connection<?>> connectionsForUsers = connectionRepository.findConnectionsToUsers(providerUsers);
assertEquals(2, connectionsForUsers.size());
assertEquals("10", connectionsForUsers.getFirst("facebook").getKey().getProviderUserId());
assertFacebookConnection((Connection<TestFacebookApi>) connectionsForUsers.get("facebook").get(1));
assertTwitterConnection((Connection<TestTwitterApi>) connectionsForUsers.getFirst("twitter"));
}
@Test
public void findConnectionsToUsersEmptyResult() {
MultiValueMap<String, String> providerUsers = new LinkedMultiValueMap<>();
providerUsers.add("facebook", "1");
assertTrue(connectionRepository.findConnectionsToUsers(providerUsers).isEmpty());
}
@Test(expected = IllegalArgumentException.class)
public void findConnectionsToUsersEmptyInput() {
MultiValueMap<String, String> providerUsers = new LinkedMultiValueMap<>();
connectionRepository.findConnectionsToUsers(providerUsers);
}
@Test
@SuppressWarnings("unchecked")
public void findConnectionByKey() {
insertFacebookConnection();
assertFacebookConnection((Connection<TestFacebookApi>) connectionRepository.getConnection(new ConnectionKey("facebook", "9")));
}
@Test(expected = NoSuchConnectionException.class)
public void findConnectionByKeyNoSuchConnection() {
connectionRepository.getConnection(new ConnectionKey("facebook", "bogus"));
}
@Test
public void findConnectionByApiToUser() {
insertFacebookConnection();
insertFacebookConnection2();
assertFacebookConnection(connectionRepository.getConnection(TestFacebookApi.class, "9"));
assertEquals("10", connectionRepository.getConnection(TestFacebookApi.class, "10").getKey().getProviderUserId());
}
@Test(expected = NoSuchConnectionException.class)
public void findConnectionByApiToUserNoSuchConnection() {
assertFacebookConnection(connectionRepository.getConnection(TestFacebookApi.class, "9"));
}
@Test
public void findPrimaryConnection() {
insertFacebookConnection();
assertFacebookConnection(connectionRepository.getPrimaryConnection(TestFacebookApi.class));
}
@Test
public void findPrimaryConnectionSelectFromMultipleByRank() {
insertFacebookConnection2();
insertFacebookConnection();
assertFacebookConnection(connectionRepository.getPrimaryConnection(TestFacebookApi.class));
}
@Test(expected = NotConnectedException.class)
public void findPrimaryConnectionNotConnected() {
connectionRepository.getPrimaryConnection(TestFacebookApi.class);
}
@Test
public void removeConnections() {
SocialUserConnection facebookConnection = insertFacebookConnection();
insertFacebookConnection2();
assertThat(socialUserConnectionRepository.findOne(facebookConnection.getId())).isNotNull();
connectionRepository.removeConnections("facebook");
assertThat(socialUserConnectionRepository.findOne(facebookConnection.getId())).isNull();
}
@Test
public void removeConnectionsToProviderNoOp() {
connectionRepository.removeConnections("twitter");
}
@Test
public void removeConnection() {
SocialUserConnection facebookConnection = insertFacebookConnection();
assertThat(socialUserConnectionRepository.findOne(facebookConnection.getId())).isNotNull();
connectionRepository.removeConnection(new ConnectionKey("facebook", "9"));
assertThat(socialUserConnectionRepository.findOne(facebookConnection.getId())).isNull();
}
@Test
public void removeConnectionNoOp() {
connectionRepository.removeConnection(new ConnectionKey("facebook", "1"));
}
@Test
public void addConnection() {
Connection<TestFacebookApi> connection = connectionFactory.createConnection(new AccessGrant("123456789", null, "987654321", 3600L));
connectionRepository.addConnection(connection);
Connection<TestFacebookApi> restoredConnection = connectionRepository.getPrimaryConnection(TestFacebookApi.class);
assertEquals(connection, restoredConnection);
assertNewConnection(restoredConnection);
}
@Test(expected = DataIntegrityViolationException.class)
public void addConnectionDuplicate() {
Connection<TestFacebookApi> connection = connectionFactory.createConnection(new AccessGrant("123456789", null, "987654321", 3600L));
connectionRepository.addConnection(connection);
connectionRepository.addConnection(connection);
}
@Test
public void updateConnectionProfileFields() {
connectionFactoryRegistry.addConnectionFactory(new TestTwitterConnectionFactory());
insertTwitterConnection();
Connection<TestTwitterApi> twitter = connectionRepository.getPrimaryConnection(TestTwitterApi.class);
assertEquals("http://twitter.com/kdonald/picture", twitter.getImageUrl());
twitter.sync();
assertEquals("http://twitter.com/kdonald/a_new_picture", twitter.getImageUrl());
connectionRepository.updateConnection(twitter);
Connection<TestTwitterApi> twitter2 = connectionRepository.getPrimaryConnection(TestTwitterApi.class);
assertEquals("http://twitter.com/kdonald/a_new_picture", twitter2.getImageUrl());
}
@Test
public void updateConnectionAccessFields() {
insertFacebookConnection();
Connection<TestFacebookApi> facebook = connectionRepository.getPrimaryConnection(TestFacebookApi.class);
assertEquals("234567890", facebook.getApi().getAccessToken());
facebook.refresh();
connectionRepository.updateConnection(facebook);
Connection<TestFacebookApi> facebook2 = connectionRepository.getPrimaryConnection(TestFacebookApi.class);
assertEquals("765432109", facebook2.getApi().getAccessToken());
ConnectionData data = facebook.createData();
assertEquals("654321098", data.getRefreshToken());
}
@Test
public void findPrimaryConnection_afterRemove() {
insertFacebookConnection();
insertFacebookConnection2();
// 9 is the providerUserId of the first Facebook connection
connectionRepository.removeConnection(new ConnectionKey("facebook", "9"));
assertEquals(1, connectionRepository.findConnections(TestFacebookApi.class).size());
assertNotNull(connectionRepository.findPrimaryConnection(TestFacebookApi.class));
}
private SocialUserConnection insertTwitterConnection() {
return createExistingSocialUserConnection(
"1",
"twitter",
"1",
1L,
"@kdonald",
"http://twitter.com/kdonald",
"http://twitter.com/kdonald/picture",
"123456789",
"987654321",
null,
null
);
}
private SocialUserConnection insertFacebookConnection() {
return createExistingSocialUserConnection(
"1",
"facebook",
"9",
1L,
null,
null,
null,
"234567890",
null,
"345678901",
System.currentTimeMillis() + 3600000);
}
private SocialUserConnection insertFacebookConnection2() {
return createExistingSocialUserConnection(
"1",
"facebook",
"10",
2L,
null,
null,
null,
"456789012",
null,
"56789012",
System.currentTimeMillis() + 3600000);
}
private SocialUserConnection insertFacebookConnection3() {
return createExistingSocialUserConnection(
"2",
"facebook",
"11", 2L,
null,
null,
null,
"456789012",
null,
"56789012",
System.currentTimeMillis() + 3600000);
}
private SocialUserConnection insertFacebookConnectionSameFacebookUser() {
return createExistingSocialUserConnection(
"2",
"facebook",
"9",
1L,
null,
null,
null,
"234567890",
null,
"345678901",
System.currentTimeMillis() + 3600000);
}
private SocialUserConnection createExistingSocialUserConnection(String userId,
String providerId,
String providerUserId,
Long rank,
String displayName,
String profileURL,
String imageURL,
String accessToken,
String secret,
String refreshToken,
Long expireTime) {
SocialUserConnection socialUserConnectionToSabe = new SocialUserConnection(
userId,
providerId,
providerUserId,
rank,
displayName,
profileURL,
imageURL,
accessToken,
secret,
refreshToken,
expireTime);
return socialUserConnectionRepository.save(socialUserConnectionToSabe);
}
private void assertNewConnection(Connection<TestFacebookApi> connection) {
assertEquals("facebook", connection.getKey().getProviderId());
assertEquals("9", connection.getKey().getProviderUserId());
assertEquals("Keith Donald", connection.getDisplayName());
assertEquals("http://facebook.com/keith.donald", connection.getProfileUrl());
assertEquals("http://facebook.com/keith.donald/picture", connection.getImageUrl());
assertTrue(connection.test());
TestFacebookApi api = connection.getApi();
assertNotNull(api);
assertEquals("123456789", api.getAccessToken());
assertEquals("123456789", connection.createData().getAccessToken());
assertEquals("987654321", connection.createData().getRefreshToken());
}
private void assertTwitterConnection(Connection<TestTwitterApi> twitter) {
assertEquals(new ConnectionKey("twitter", "1"), twitter.getKey());
assertEquals("@kdonald", twitter.getDisplayName());
assertEquals("http://twitter.com/kdonald", twitter.getProfileUrl());
assertEquals("http://twitter.com/kdonald/picture", twitter.getImageUrl());
TestTwitterApi twitterApi = twitter.getApi();
assertEquals("123456789", twitterApi.getAccessToken());
assertEquals("987654321", twitterApi.getSecret());
twitter.sync();
assertEquals("http://twitter.com/kdonald/a_new_picture", twitter.getImageUrl());
}
private void assertFacebookConnection(Connection<TestFacebookApi> facebook) {
assertEquals(new ConnectionKey("facebook", "9"), facebook.getKey());
assertEquals(null, facebook.getDisplayName());
assertEquals(null, facebook.getProfileUrl());
assertEquals(null, facebook.getImageUrl());
TestFacebookApi facebookApi = facebook.getApi();
assertEquals("234567890", facebookApi.getAccessToken());
facebook.sync();
assertEquals("Keith Donald", facebook.getDisplayName());
assertEquals("http://facebook.com/keith.donald", facebook.getProfileUrl());
assertEquals("http://facebook.com/keith.donald/picture", facebook.getImageUrl());
}
// test facebook provider
private static class TestFacebookConnectionFactory extends OAuth2ConnectionFactory<TestFacebookApi> {
public TestFacebookConnectionFactory() {
super("facebook", new TestFacebookServiceProvider(), new TestFacebookApiAdapter());
}
}
private static class TestFacebookServiceProvider implements OAuth2ServiceProvider<TestFacebookApi> {
public OAuth2Operations getOAuthOperations() {
return new OAuth2Operations() {
public String buildAuthorizeUrl(GrantType grantType, OAuth2Parameters params) {
return null;
}
public String buildAuthenticateUrl(GrantType grantType, OAuth2Parameters params) {
return null;
}
public String buildAuthorizeUrl(OAuth2Parameters params) {
return null;
}
public String buildAuthenticateUrl(OAuth2Parameters params) {
return null;
}
public AccessGrant exchangeForAccess(String authorizationGrant, String redirectUri, MultiValueMap<String, String> additionalParameters) {
return null;
}
public AccessGrant exchangeCredentialsForAccess(String username, String password, MultiValueMap<String, String> additionalParameters) {
return null;
}
public AccessGrant refreshAccess(String refreshToken, MultiValueMap<String, String> additionalParameters) {
return new AccessGrant("765432109", "read", "654321098", 3600L);
}
@Deprecated
public AccessGrant refreshAccess(String refreshToken, String scope, MultiValueMap<String, String> additionalParameters) {
return new AccessGrant("765432109", "read", "654321098", 3600L);
}
public AccessGrant authenticateClient() {
return null;
}
public AccessGrant authenticateClient(String scope) {
return null;
}
};
}
public TestFacebookApi getApi(final String accessToken) {
return () -> accessToken;
}
}
public interface TestFacebookApi {
String getAccessToken();
}
private static class TestFacebookApiAdapter implements ApiAdapter<TestFacebookApi> {
private String accountId = "9";
private String name = "Keith Donald";
private String profileUrl = "http://facebook.com/keith.donald";
private String profilePictureUrl = "http://facebook.com/keith.donald/picture";
public boolean test(TestFacebookApi api) {
return true;
}
public void setConnectionValues(TestFacebookApi api, ConnectionValues values) {
values.setProviderUserId(accountId);
values.setDisplayName(name);
values.setProfileUrl(profileUrl);
values.setImageUrl(profilePictureUrl);
}
public UserProfile fetchUserProfile(TestFacebookApi api) {
return new UserProfileBuilder().setName(name).setEmail("keith@interface21.com").setUsername("Keith.Donald").build();
}
public void updateStatus(TestFacebookApi api, String message) {
}
}
// test twitter provider
private static class TestTwitterConnectionFactory extends OAuth1ConnectionFactory<TestTwitterApi> {
public TestTwitterConnectionFactory() {
super("twitter", new TestTwitterServiceProvider(), new TestTwitterApiAdapter());
}
}
private static class TestTwitterServiceProvider implements OAuth1ServiceProvider<TestTwitterApi> {
public OAuth1Operations getOAuthOperations() {
return null;
}
public TestTwitterApi getApi(final String accessToken, final String secret) {
return new TestTwitterApi() {
public String getAccessToken() {
return accessToken;
}
public String getSecret() {
return secret;
}
};
}
}
public interface TestTwitterApi {
String getAccessToken();
String getSecret();
}
private static class TestTwitterApiAdapter implements ApiAdapter<TestTwitterApi> {
private String accountId = "1";
private String name = "@kdonald";
private String profileUrl = "http://twitter.com/kdonald";
private String profilePictureUrl = "http://twitter.com/kdonald/a_new_picture";
public boolean test(TestTwitterApi api) {
return true;
}
public void setConnectionValues(TestTwitterApi api, ConnectionValues values) {
values.setProviderUserId(accountId);
values.setDisplayName(name);
values.setProfileUrl(profileUrl);
values.setImageUrl(profilePictureUrl);
}
public UserProfile fetchUserProfile(TestTwitterApi api) {
return new UserProfileBuilder().setName(name).setUsername("kdonald").build();
}
public void updateStatus(TestTwitterApi api, String message) {
}
}
}