org.osiam.client.connector.OsiamConnectorTest.java Source code

Java tutorial

Introduction

Here is the source code for org.osiam.client.connector.OsiamConnectorTest.java

Source

package org.osiam.client.connector;
/*
 * for licensing see the file license.txt.
 */

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import static org.apache.http.HttpStatus.SC_OK;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpStatus;
import org.apache.http.entity.ContentType;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.osiam.client.AccessTokenMockProvider;
import org.osiam.client.exception.InvalidAttributeException;
import org.osiam.client.oauth.AccessToken;
import org.osiam.client.oauth.GrantType;
import org.osiam.client.oauth.Scope;
import org.osiam.client.query.Query;
import org.osiam.client.query.QueryResult;
import org.osiam.client.query.metamodel.User_;
import org.osiam.resources.scim.Address;
import org.osiam.resources.scim.Group;
import org.osiam.resources.scim.Meta;
import org.osiam.resources.scim.MultiValuedAttribute;
import org.osiam.resources.scim.Name;
import org.osiam.resources.scim.User;

import com.github.tomakehurst.wiremock.client.MappingBuilder;
import com.github.tomakehurst.wiremock.junit.WireMockRule;

public class OsiamConnectorTest {

    private final static String ENDPOINT = "http://localhost:9090/";
    static final String AUTH_ENDPOINT_ADDRESS = "http://localhost:9090/osiam-auth-server/";
    private static final String URL_BASE_USERS = "/osiam-resource-server//Users";
    private static final String URL_BASE_ME = "/osiam-server//me";
    private static final String URL_BASE_GROUPS = "/osiam-resource-server//Groups";
    private final static String userIdString = "94bbe688-4b1e-4e4e-80e7-e5ba5c4d6db4";
    private static final String GROUP_ID_STRING = "55bbe688-4b1e-4e4e-80e7-e5ba5c4d6db4";
    private final static String COUNTRY = "Germany";
    private static final String IRRELEVANT = "irrelevant";
    private final static String SIMPLE_USER_QUERY_STRING = "filter=displayName+eq+BarbaraJ.";
    private final static String SIMPLE_GROUP_QUERY_STRING = "filter=displayName+eq+test_group01";
    private final static int NUMBER_OF_EXPECTED_GROUPS = 7;
    private final static String VALID_CLIENT_ID = "valid-client";
    private final static String VALID_CLIENT_SECRET = "valid_secret";
    private final static String VALID_USERNAME = "valid-username";
    private final static String VALID_PASSWORD = "valid-password";
    private final static String TOKEN_PATH = "/oauth/token";

    private AccessToken accessToken;
    private User singleUserResult;
    private String searchedUserID;
    private String searchedGroupId;
    private AccessTokenMockProvider tokenProvider;
    private QueryResult<User> userQueryResult;
    private QueryResult<Group> groupQueryResult;
    private List<User> allUsers;
    private List<Group> allGroups;
    private Query query;

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(9090); // No-args constructor defaults to port 8080
    private OsiamConnector oConnector;

    @Before
    public void setUp() throws Exception {
        oConnector = new OsiamConnector.Builder().setEndpoint(ENDPOINT)
                .setGrantType(GrantType.RESOURCE_OWNER_PASSWORD_CREDENTIALS).setClientId(IRRELEVANT)
                .setClientSecret(IRRELEVANT).setUserName(IRRELEVANT).setPassword(IRRELEVANT).build();
        tokenProvider = new AccessTokenMockProvider("/__files/valid_accesstoken.json");

        givenAnUserID();
        givenAGroupID();
        givenAnAccessToken();
    }

    @Test
    public void getUser_is_transferred_correctly() throws Exception {
        givenUserIDcanBeFound();
        whenSingleIDisLookedUp();
        thenReturnedUserHasID(searchedUserID);
        thenMetaDataWasDeserializedCorrectly();
        thenAddressIsDeserializedCorrectly();
        thenPhoneNumbersAreDeserializedCorrectly();
        thenBasicValuesAreDeserializedCorrectly();
    }

    @Test
    public void getAllUsers_is_transferred_correctly() {
        givenAllUsersAreLookedUpSuccessfully();
        whenAllUsersAreLookedUp();
        thenNumberOfAllUsersIs(1);
    }

    @Test
    public void searchUsers_by_string_is_transferred_correctly() {
        givenASingleUserCanBeSearchedByQuery();
        whenSearchIsUsedByString(SIMPLE_USER_QUERY_STRING);
        thenUserQueryWasValid();
        thenNumberOfReturnedUsersIs(1);
        thenReturnedListOfSearchedUsersIsAsExpected();
    }

    @Test
    public void searchUsers_by_query_is_transferred_correctly() throws UnsupportedEncodingException {
        givenAQueryContainingDifficultCharacters();
        givenAUserCanBeSearchedByQuery();
        whenSearchIsUsedByQuery();
        thenQueryStringIsSplitCorrectly();
    }

    @Test
    public void getMe_is_transferred_correctly() throws Exception {
        givenAccessTokenForMeIsValid();
        whenMeIsLookedUp();
        thenReturnedUserMatchesExpectations();
    }

    @Test
    public void getGroup_is_transferred_correctly() throws IOException {
        givenGroupIDcanBeFound();
        whenSingleGroupIsLookedUp();
        thenReturnedGroupHasID(searchedGroupId);
    }

    @Test
    public void getAllGroups_is_transferred_correctly() throws Exception {
        givenAllGroupsAreLookedUpSuccessfully();
        whenAllGroupsAreLookedUp();
        thenReturnedListOfAllGroupsIsAsExpected();
    }

    @Test
    public void searchGroups_by_string_is_transferred_correctly() {
        givenASingleGroupCanBeLookedUpByQuery();
        whenSingleGroupIsSearchedByQueryString(SIMPLE_GROUP_QUERY_STRING);
        thenGroupQueryWasValid();
        thenReturnedListOfSearchedGroupsIsAsExpected();
    }

    @Test
    public void retrieveAccessToken_is_transferred_correctly() throws Exception {
        given_a_correctly_configured_auth_service();
        given_oauth_server_issues_access_token();
        when_token_is_requested();
        then_access_token_is_valid();
    }

    @Test(expected = InvalidAttributeException.class)
    public void request_access_token_without_setting_endpoint_raises_exception() {
        givenAConfiguredServiceWithoutEndpoint();
        when_token_is_requested();
    }

    @Test(expected = InvalidAttributeException.class)
    public void request_me_user_without_setting_endpint_raises_exception() {
        givenAConfiguredServiceWithoutResourceEndpoint();
        given_oauth_server_issues_access_token();
        when_token_is_requested();
        when_me_user_is_requested();
    }

    private void givenUserIDcanBeFound() {
        stubFor(givenUserIDisLookedUp(userIdString, accessToken).willReturn(
                aResponse().withStatus(SC_OK).withHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
                        .withBodyFile("user_" + userIdString + ".json")));
    }

    private void givenGroupIDcanBeFound() {
        stubFor(givenGroupIDisLookedUp(GROUP_ID_STRING, accessToken).willReturn(
                aResponse().withStatus(SC_OK).withHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
                        .withBodyFile("group_" + GROUP_ID_STRING + ".json")));
    }

    private MappingBuilder givenUserIDisLookedUp(String id, AccessToken accessToken) {
        return get(urlEqualTo(URL_BASE_USERS + "/" + id))
                .withHeader("Content-Type", equalTo(ContentType.APPLICATION_JSON.getMimeType()))
                .withHeader("Authorization", equalTo("Bearer " + accessToken.getToken()));
    }

    private MappingBuilder givenGroupIDisLookedUp(String id, AccessToken accessToken) {
        return get(urlEqualTo(URL_BASE_GROUPS + "/" + id))
                .withHeader("Content-Type", equalTo(ContentType.APPLICATION_JSON.getMimeType()))
                .withHeader("Authorization", equalTo("Bearer " + accessToken.getToken()));
    }

    private void whenSingleIDisLookedUp() {
        singleUserResult = oConnector.getUser(searchedUserID, accessToken);
    }

    private void thenReturnedUserHasID(String id) {
        assertEquals(id.toString(), singleUserResult.getId());
    }

    private void thenMetaDataWasDeserializedCorrectly() throws ParseException {
        Meta deserializedMeta = singleUserResult.getMeta();
        Date expectedCreated = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2011-08-01 20:29:49");

        assertEquals(expectedCreated, deserializedMeta.getCreated());
        assertEquals(expectedCreated, deserializedMeta.getLastModified());
        assertEquals("https://example.com/v1/Users/2819c223...", deserializedMeta.getLocation());
        assertEquals(null, deserializedMeta.getVersion());
        assertEquals("User", deserializedMeta.getResourceType());
    }

    public void thenAddressIsDeserializedCorrectly() throws Exception {
        List<Address> addresses = singleUserResult.getAddresses();
        assertEquals(1, addresses.size());
        Address address = addresses.get(0);

        assertEquals("example street 42", address.getStreetAddress());
        assertEquals("11111", address.getPostalCode());
        assertEquals(COUNTRY, address.getCountry());
        assertEquals(COUNTRY, address.getRegion());
        assertEquals(COUNTRY, address.getLocality());
    }

    public void thenPhoneNumbersAreDeserializedCorrectly() {
        List<MultiValuedAttribute> phonenumbers = singleUserResult.getPhoneNumbers();
        assertEquals(1, phonenumbers.size());
        MultiValuedAttribute phonenumber = phonenumbers.get(0);

        assertEquals("555-555-8377", phonenumber.getValue().toString());
        assertEquals("work", phonenumber.getType());
    }

    public void thenBasicValuesAreDeserializedCorrectly() throws Exception {
        assertEquals("bjensen", singleUserResult.getExternalId());
        assertEquals(null, singleUserResult.isActive());
        assertEquals("BarbaraJ.", singleUserResult.getDisplayName());
        assertEquals("de", singleUserResult.getLocale());
        assertEquals("Barbara", singleUserResult.getNickName());
        assertEquals("Dr.", singleUserResult.getTitle());
        assertEquals("bjensen", singleUserResult.getUserName());
    }

    private void givenAnAccessToken() throws IOException {
        this.accessToken = tokenProvider.valid_access_token();
    }

    private void givenAnUserID() {
        this.searchedUserID = userIdString;
    }

    private void givenAllUsersAreLookedUpSuccessfully() {
        stubFor(get(urlEqualTo(URL_BASE_USERS + "?count=" + Integer.MAX_VALUE))
                .withHeader("Content-Type", equalTo(ContentType.APPLICATION_JSON.getMimeType()))
                .withHeader("Authorization", equalTo("Bearer " + accessToken.getToken()))
                .willReturn(aResponse().withStatus(SC_OK)
                        .withHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
                        .withBodyFile("query_all_users.json")));
    }

    private void whenAllUsersAreLookedUp() {
        allUsers = oConnector.getAllUsers(accessToken);
    }

    private void thenNumberOfReturnedUsersIs(int numberOfUsers) {
        assertEquals(numberOfUsers, userQueryResult.getTotalResults());
        assertEquals(numberOfUsers, userQueryResult.getResources().size());
    }

    private void thenNumberOfAllUsersIs(int numberOfUsers) {
        assertEquals(numberOfUsers, allUsers.size());
    }

    private void givenASingleUserCanBeSearchedByQuery() {
        stubFor(get(urlEqualTo(URL_BASE_USERS + "?filter=displayName+eq+BarbaraJ."))
                .withHeader("Content-Type", equalTo(ContentType.APPLICATION_JSON.getMimeType()))
                .willReturn(aResponse().withStatus(SC_OK)
                        .withHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
                        .withBodyFile("query_user_by_name.json")));
    }

    private void whenSearchIsUsedByString(String queryString) {
        userQueryResult = oConnector.searchUsers(queryString, accessToken);
    }

    private void thenUserQueryWasValid() {
        verify(getRequestedFor(urlEqualTo(URL_BASE_USERS + "?filter=displayName+eq+BarbaraJ."))
                .withHeader("Content-Type", equalTo(ContentType.APPLICATION_JSON.getMimeType())));
    }

    private void thenReturnedListOfSearchedUsersIsAsExpected() {
        assertEquals(1, userQueryResult.getTotalResults());
        assertEquals("BarbaraJ.", userQueryResult.getResources().iterator().next().getDisplayName());
    }

    private void givenAQueryContainingDifficultCharacters() throws UnsupportedEncodingException {
        Query.Filter filter = new Query.Filter(User.class,
                User_.Name.formatted.contains("Schulz & Schulz Industries"));
        query = new Query.Builder(User.class).setFilter(filter).build();
    }

    private void givenAUserCanBeSearchedByQuery() {
        stubFor(get(urlMatching(URL_BASE_USERS + "\\?filter=.+"))
                .withHeader("Content-Type", equalTo(ContentType.APPLICATION_JSON.getMimeType()))
                .willReturn(aResponse().withStatus(SC_OK)
                        .withHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
                        .withBodyFile("query_user_by_name.json")));
    }

    private void whenSearchIsUsedByQuery() {
        userQueryResult = oConnector.searchUsers(query, accessToken);
    }

    private void thenQueryStringIsSplitCorrectly() {
        verify(getRequestedFor(
                urlEqualTo(URL_BASE_USERS + "?filter=name.formatted+co+%22Schulz+%26+Schulz+Industries%22"))
                        .withHeader("Content-Type", equalTo(ContentType.APPLICATION_JSON.getMimeType())));
    }

    private void givenAccessTokenForMeIsValid() {
        stubFor(givenMeIsLookedUp(accessToken).willReturn(
                aResponse().withStatus(SC_OK).withHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
                        .withBodyFile("user_" + userIdString + ".json")));
    }

    private MappingBuilder givenMeIsLookedUp(AccessToken accessToken) {
        return get(urlEqualTo(URL_BASE_USERS + "/me"))
                .withHeader("Content-Type", equalTo(ContentType.APPLICATION_JSON.getMimeType()))
                .withHeader("Authorization", equalTo("Bearer " + accessToken.getToken()));
    }

    private void whenMeIsLookedUp() {
        singleUserResult = oConnector.getMe(accessToken);
    }

    private void thenReturnedUserMatchesExpectations() throws Exception {

        User expectedUser = get_expected_user();

        assertEquals(expectedUser.getDisplayName(), singleUserResult.getDisplayName());
        assertEqualsEmailList(expectedUser.getEmails(), singleUserResult.getEmails());
        assertEquals(expectedUser.getExternalId(), singleUserResult.getExternalId());
        assertEquals(expectedUser.getLocale(), singleUserResult.getLocale());
        assertEqualsName(expectedUser.getName(), singleUserResult.getName());
        assertEquals(expectedUser.getNickName(), singleUserResult.getNickName());
        assertEquals(expectedUser.getPassword(), singleUserResult.getPassword());
        assertEquals(expectedUser.getPhotos(), singleUserResult.getPhotos());
        assertEquals(expectedUser.getPreferredLanguage(), singleUserResult.getPreferredLanguage());
        assertEquals(expectedUser.getProfileUrl(), singleUserResult.getProfileUrl());
        assertEquals(expectedUser.getTimezone(), singleUserResult.getTimezone());
        assertEquals(expectedUser.getTitle(), singleUserResult.getTitle());
        assertEquals(expectedUser.getUserName(), singleUserResult.getUserName());
        assertEquals(expectedUser.getUserType(), singleUserResult.getUserType());
        assertEquals(expectedUser.isActive(), singleUserResult.isActive());
    }

    private User get_expected_user() throws Exception {
        Reader reader = null;
        StringBuilder jsonUser = null;
        User expectedUser;
        try {
            reader = new FileReader("src/test/resources/__files/user_" + userIdString + ".json");
            jsonUser = new StringBuilder();
            for (int c; (c = reader.read()) != -1;)
                jsonUser.append((char) c);
        } finally {
            try {
                reader.close();
            } catch (Exception e) {
            }
        }

        expectedUser = new ObjectMapper().readValue(jsonUser.toString(), User.class);
        return expectedUser;
    }

    private void assertEqualsEmailList(List<MultiValuedAttribute> expected, List<MultiValuedAttribute> actual) {
        if (expected == null && actual == null) {
            return;
        }
        if (expected.size() != actual.size()) {
            fail("The expected List has not the same number of values like the actual list");
        }
        for (int count = 0; count < expected.size(); count++) {
            MultiValuedAttribute expectedAttribute = expected.get(count);
            MultiValuedAttribute actualAttribute = actual.get(count);
            assertEquals(expectedAttribute.getValue().toString(), actualAttribute.getValue().toString());
        }
    }

    private void assertEqualsName(Name expected, Name actual) {
        if (expected == null && actual == null) {
            return;
        }
        assertEquals(expected.getFamilyName(), actual.getFamilyName());
        assertEquals(expected.getGivenName(), actual.getGivenName());
        assertEquals(expected.getMiddleName(), actual.getMiddleName());
        assertEquals(expected.getHonorificPrefix(), actual.getHonorificPrefix());
        assertEquals(expected.getHonorificSuffix(), actual.getHonorificSuffix());
    }

    private void whenSingleGroupIsLookedUp() {
        oConnector.getGroup(searchedGroupId, accessToken);
    }

    private void givenAGroupID() {
        this.searchedGroupId = GROUP_ID_STRING;
    }

    private void thenReturnedGroupHasID(String id) {
        Group result = oConnector.getGroup(id, accessToken);
        assertEquals(id.toString(), result.getId());
    }

    private void givenAllGroupsAreLookedUpSuccessfully() {
        stubFor(get(urlEqualTo(URL_BASE_GROUPS + "?count=" + Integer.MAX_VALUE))
                .withHeader("Content-Type", equalTo(ContentType.APPLICATION_JSON.getMimeType()))
                .withHeader("Authorization", equalTo("Bearer " + accessToken.getToken()))
                .willReturn(aResponse().withStatus(SC_OK)
                        .withHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
                        .withBodyFile("query_all_groups.json")));
    }

    private void whenAllGroupsAreLookedUp() {
        allGroups = oConnector.getAllGroups(accessToken);
    }

    private void thenReturnedListOfAllGroupsIsAsExpected() {
        assertEquals(NUMBER_OF_EXPECTED_GROUPS, allGroups.size());
        for (Group currentGroup : allGroups) {
            if (currentGroup.getId().equals(GROUP_ID_STRING)) {
                assertEquals(1, currentGroup.getMembers().size());
                for (MultiValuedAttribute actValue : currentGroup.getMembers()) {
                    assertEquals(userIdString, actValue.getValue().toString());
                }
                break;
            }
        }
    }

    private void givenASingleGroupCanBeLookedUpByQuery() {
        stubFor(get(urlEqualTo(URL_BASE_GROUPS + "?filter=displayName+eq+test_group01"))
                .withHeader("Content-Type", equalTo(ContentType.APPLICATION_JSON.getMimeType()))
                .willReturn(aResponse().withStatus(SC_OK)
                        .withHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
                        .withBodyFile("query_group_by_name.json")));
    }

    private void thenGroupQueryWasValid() {
        verify(getRequestedFor(urlEqualTo(URL_BASE_GROUPS + "?filter=displayName+eq+test_group01"))
                .withHeader("Content-Type", equalTo(ContentType.APPLICATION_JSON.getMimeType())));
    }

    private void whenSingleGroupIsSearchedByQueryString(String queryString) {
        groupQueryResult = oConnector.searchGroups(queryString, accessToken);
    }

    private void thenReturnedListOfSearchedGroupsIsAsExpected() {
        assertEquals(1, groupQueryResult.getTotalResults());
        assertEquals(1, groupQueryResult.getResources().size());
        assertEquals("test_group01", groupQueryResult.getResources().iterator().next().getDisplayName());
    }

    private void given_a_correctly_configured_auth_service() {
        oConnector = new OsiamConnector.Builder().setEndpoint(ENDPOINT)
                .setGrantType(GrantType.RESOURCE_OWNER_PASSWORD_CREDENTIALS).setClientId(VALID_CLIENT_ID)
                .setClientSecret(VALID_CLIENT_SECRET).setUserName(VALID_USERNAME).setPassword(VALID_PASSWORD)
                .setScope(Scope.GET).build();
    }

    private void givenAConfiguredServiceWithoutEndpoint() {
        oConnector = new OsiamConnector.Builder().setGrantType(GrantType.RESOURCE_OWNER_PASSWORD_CREDENTIALS)
                .setClientId(VALID_CLIENT_ID).setClientSecret(VALID_CLIENT_SECRET).setUserName(VALID_USERNAME)
                .setPassword(VALID_PASSWORD).setScope(Scope.GET).build();
    }

    private void givenAConfiguredServiceWithoutResourceEndpoint() {
        oConnector = new OsiamConnector.Builder().setGrantType(GrantType.RESOURCE_OWNER_PASSWORD_CREDENTIALS)
                .setAuthServiceEndpoint(AUTH_ENDPOINT_ADDRESS).setClientId(VALID_CLIENT_ID)
                .setClientSecret(VALID_CLIENT_SECRET).setUserName(VALID_USERNAME).setPassword(VALID_PASSWORD)
                .setScope(Scope.GET).build();
    }

    private void given_oauth_server_issues_access_token() {
        stubFor(post(urlEqualTo("/osiam-auth-server/" + TOKEN_PATH))
                .willReturn(aResponse().withStatus(HttpStatus.SC_OK).withBodyFile("valid_accesstoken.json")));
    }

    private void when_token_is_requested() {
        accessToken = oConnector.retrieveAccessToken();
    }

    private void when_me_user_is_requested() {
        oConnector.getMe(accessToken);
    }

    private void then_access_token_is_valid() throws Exception {
        assertFalse(accessToken.isExpired());
    }
}