software.coolstuff.springframework.owncloud.service.impl.AbstractOwncloudServiceTest.java Source code

Java tutorial

Introduction

Here is the source code for software.coolstuff.springframework.owncloud.service.impl.AbstractOwncloudServiceTest.java

Source

/*-
 * #%L
 * owncloud-spring-boot-starter
 * %%
 * Copyright (C) 2016 - 2017 by the original Authors
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */
package software.coolstuff.springframework.owncloud.service.impl;

import lombok.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.test.web.client.RequestMatcher;
import org.springframework.test.web.client.ResponseActions;
import org.springframework.util.MultiValueMap;
import software.coolstuff.springframework.owncloud.config.AuthorityAppenderConfiguration;
import software.coolstuff.springframework.owncloud.config.AuthorityMapperConfiguration;
import software.coolstuff.springframework.owncloud.config.IgnoreOnComponentScan;
import software.coolstuff.springframework.owncloud.config.VelocityConfiguration;
import software.coolstuff.springframework.owncloud.service.api.OwncloudGrantedAuthoritiesMapper;
import software.coolstuff.springframework.owncloud.service.impl.local.OwncloudLocalFileTestExecutionListener;
import software.coolstuff.springframework.owncloud.service.impl.rest.OwncloudRestService;
import software.coolstuff.springframework.owncloud.service.impl.rest.OwncloudRestServiceTest;

import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.Format;
import java.util.*;

import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.*;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.NONE, properties = "debug=true", classes = {
        VelocityConfiguration.class, AuthorityAppenderConfiguration.class, AuthorityMapperConfiguration.class })
@TestExecutionListeners({ SpringBootDependencyInjectionTestExecutionListener.class,
        WithSecurityContextTestExecutionListener.class, OwncloudLocalFileTestExecutionListener.class })
@ComponentScan(excludeFilters = { @Filter(IgnoreOnComponentScan.class) })
public abstract class AbstractOwncloudServiceTest {

    private final static String DEFAULT_PATH = "/ocs/v1.php";
    private final static String VELOCITY_PATH_PREFIX = "/velocity/";

    private final static Format LONG_FORMAT = new DecimalFormat("###########0",
            DecimalFormatSymbols.getInstance(Locale.ENGLISH));

    @Autowired(required = false)
    private OwncloudGrantedAuthoritiesMapper owncloudGrantedAuthoritiesMapper;

    @Autowired(required = false)
    private GrantedAuthoritiesMapper grantedAuthoritiesMapper;

    @Autowired
    private OwncloudProperties properties;

    @Autowired
    private VelocityEngine velocityEngine;

    private MockRestServiceServer server;

    @Before
    public final void setUp() throws Exception {
        if (this instanceof OwncloudRestServiceTest) {
            server = createServer(((OwncloudRestServiceTest) this).owncloudService());
        }
    }

    protected Format getQuotaFormat() {
        return LONG_FORMAT;
    }

    protected final MockRestServiceServer createServer(OwncloudRestService owncloudService) {
        return MockRestServiceServer.createServer(owncloudService.getRestTemplate());
    }

    protected void verifyServer() {
        if (server != null) {
            server.verify();
        }
    }

    protected final MockRestServiceServer getServer() {
        return server;
    }

    protected void respondUsers(RestRequest request, String... users) throws IOException {
        if (isNoRestTestClass()) {
            return;
        }
        ResponseActions preparedRequest = prepareRestRequest(request);

        Context context = new VelocityContext();
        setSuccessMetaInformation(context);
        context.put("users", Arrays.asList(users));

        preparedRequest.andRespond(withSuccess(merge("users.vm", context), MediaType.TEXT_XML));
    }

    private boolean isNoRestTestClass() {
        return !(this instanceof OwncloudRestServiceTest);
    }

    private ResponseActions prepareRestRequest(RestRequest request) throws MalformedURLException {
        MockRestServiceServer server = this.server;
        if (request.getServer() != null) {
            server = request.getServer();
        }
        ResponseActions responseActions = server.expect(requestToWithPrefix(request.getUrl()))
                .andExpect(method(request.getMethod()));
        if (StringUtils.isNotBlank(request.getBasicAuthentication())) {
            responseActions.andExpect(header(HttpHeaders.AUTHORIZATION, request.getBasicAuthentication()));
        } else {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            responseActions
                    .andExpect(header(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString(
                            (authentication.getName() + ":" + authentication.getCredentials()).getBytes())));
        }
        return responseActions;
    }

    private RequestMatcher requestToWithPrefix(String uri) throws MalformedURLException {
        String rootURI = null;
        if (isNoResourceLocation()) {
            URL url = new URL(properties.getLocation());
            rootURI = properties.getLocation();
            if (StringUtils.isBlank(url.getPath()) || "/".equals(url.getPath())) {
                rootURI = URI.create(url.toString() + DEFAULT_PATH).toString();
            }
        }
        return requestTo(rootURI + uri);
    }

    private boolean isNoResourceLocation() {
        return !StringUtils.startsWith(properties.getLocation(), "file:")
                && !StringUtils.startsWith(properties.getLocation(), "classpath:");
    }

    private void setSuccessMetaInformation(Context context) {
        context.put("status", "ok");
        context.put("statuscode", 100);
    }

    private String merge(String templateName, Context context) throws IOException {
        String prefixedTemplateName = templateName;
        if (!StringUtils.startsWith(templateName, VELOCITY_PATH_PREFIX)) {
            prefixedTemplateName = VELOCITY_PATH_PREFIX + templateName;
            if (StringUtils.startsWith(templateName, "/")) {
                prefixedTemplateName = VELOCITY_PATH_PREFIX + StringUtils.substring(templateName, 1);
            }
        }
        Template template = velocityEngine.getTemplate(prefixedTemplateName);
        try (Writer writer = new StringWriter()) {
            template.merge(context, writer);
            writer.flush();
            return writer.toString();
        }
    }

    protected void respondGroups(RestRequest request, String... groups) throws IOException {
        if (isNoRestTestClass()) {
            return;
        }
        ResponseActions preparedRequest = prepareRestRequest(request);

        Context context = new VelocityContext();
        setSuccessMetaInformation(context);
        context.put("groups", Arrays.asList(groups));

        preparedRequest.andRespond(withSuccess(merge("groups.vm", context), request.getResponseType()));
    }

    protected void respondFailure(RestRequest request, int statuscode) throws IOException {
        respondFailure(request, statuscode, null);
    }

    protected void respondFailure(RestRequest request, int statuscode, String message) throws IOException {
        if (isNoRestTestClass()) {
            return;
        }
        ResponseActions preparedRequest = prepareRestRequest(request);

        Context context = new VelocityContext();
        setFailureMetaInformation(context, statuscode, message);

        preparedRequest.andRespond(withSuccess(merge("void.vm", context), request.getResponseType()));
    }

    protected void respondHttpStatus(RestRequest request, HttpStatus httpStatus) throws MalformedURLException {
        if (isNoRestTestClass()) {
            return;
        }
        prepareRestRequest(request).andRespond(withStatus(httpStatus));
    }

    protected void respondSuccess(RestRequest request) throws IOException {
        respondSuccess(request, null);
    }

    protected void respondSuccess(RestRequest request, MultiValueMap<String, String> requestBody)
            throws IOException {
        if (isNoRestTestClass()) {
            return;
        }
        ResponseActions preparedRequest = prepareRestRequest(request);

        Context context = new VelocityContext();
        setSuccessMetaInformation(context);

        if (requestBody != null) {
            preparedRequest = preparedRequest.andExpect(content().formData(requestBody));
        }
        preparedRequest.andRespond(withSuccess(merge("void.vm", context), MediaType.TEXT_XML));
    }

    private void setFailureMetaInformation(Context context, int statuscode, String message) {
        context.put("status", "failure");
        context.put("statuscode", statuscode);
        context.put("message", message != null ? message : "");
    }

    protected void respondUser(RestRequest request, UserResponse userResponse) throws IOException {
        if (isNoRestTestClass()) {
            return;
        }
        ResponseActions preparedRequest = prepareRestRequest(request);

        Context context = new VelocityContext();
        setSuccessMetaInformation(context);
        userResponse.fillContext(context);

        preparedRequest.andRespond(withSuccess(merge("user.vm", context), MediaType.TEXT_XML));
    }

    @Setter
    @Builder
    public static class UserResponse {
        private final static String ENABLED = "enabled";
        private final static String EMAIL = "email";
        private final static String DISPLAY_NAME = "displayname";
        private final static String QUOTA = "quota";
        private final static String USED = "used";
        private final static String FREE = "free";
        private final static String RELATIVE = "relative";

        private final static Format FLOAT_FORMAT = new DecimalFormat("###########0.00",
                DecimalFormatSymbols.getInstance(Locale.ENGLISH));

        @Builder.Default
        private boolean enabled = true;
        private String email;
        private String displayname;
        private Long quota;
        @Builder.Default
        private Long used = 817_928_385L;
        @Builder.Default
        private Long free = 255_813_439L;
        @Builder.Default
        private Float relative = 23.82F;

        public void fillContext(Context context) {
            context.put(ENABLED, Boolean.toString(enabled));
            context.put(EMAIL, email);
            context.put(DISPLAY_NAME, displayname);
            context.put(QUOTA, quota != null ? LONG_FORMAT.format(quota) : null);
            context.put(USED, used != null ? LONG_FORMAT.format(used) : null);
            context.put(FREE, free != null ? LONG_FORMAT.format(free) : null);
            context.put(RELATIVE, relative != null ? FLOAT_FORMAT.format(relative) : null);
        }
    }

    protected void checkAuthorities(String username, Collection<? extends GrantedAuthority> actual,
            String... expected) {
        assertThat(actual == null ? 0 : actual.size()).isEqualTo(expected.length);
        List<GrantedAuthority> authorities = new ArrayList<>();
        if (ArrayUtils.isNotEmpty(expected)) {
            for (String authority : expected) {
                authorities.add(new SimpleGrantedAuthority(authority));
            }
        }
        if (owncloudGrantedAuthoritiesMapper != null) {
            assertThat(CollectionUtils.isEqualCollection(actual,
                    owncloudGrantedAuthoritiesMapper.mapAuthorities(username, authorities))).isTrue();
        } else if (grantedAuthoritiesMapper != null) {
            assertThat(
                    CollectionUtils.isEqualCollection(actual, grantedAuthoritiesMapper.mapAuthorities(authorities)))
                            .isTrue();
        } else {
            assertThat(CollectionUtils.isEqualCollection(actual, authorities)).isTrue();
        }
    }

    protected final String getSecurityContextBasicAuthorizationHeader() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return "Basic " + Base64.getEncoder()
                .encodeToString((authentication.getName() + ":" + authentication.getCredentials()).getBytes());
    }

    @Data
    @AllArgsConstructor(access = AccessLevel.PRIVATE)
    @Builder
    protected static class RestRequest {

        private MockRestServiceServer server;
        @NotNull
        private final HttpMethod method;
        @NotNull
        private final String url;
        private String basicAuthentication;
        @Builder.Default
        private MediaType responseType = MediaType.TEXT_XML;
    }
}