package de.asideas.crowdsource.testsupport.util; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import de.asideas.crowdsource.domain.shared.ProjectStatus; import de.asideas.crowdsource.presentation.Comment; import de.asideas.crowdsource.presentation.FinancingRound; import de.asideas.crowdsource.presentation.Pledge; import de.asideas.crowdsource.presentation.project.Attachment; import de.asideas.crowdsource.presentation.project.Project; import de.asideas.crowdsource.presentation.project.ProjectStatusUpdate; import de.asideas.crowdsource.presentation.user.UserActivation; import de.asideas.crowdsource.presentation.user.UserRegistration; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; import java.util.Arrays; import java.util.List; import static org.junit.Assert.assertEquals; @Component public class CrowdSourceClient { private static final RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory()); public static final String DEFAULT_USER_EMAIL = "crowdsource@crowd.source.de"; public static final String DEFAULT_USER_PASS = "einEselGehtZumBaecker!"; public static final String DEFAULT_ADMIN_EMAIL = "cs_admin@crowd.source.de"; public static final String DEFAULT_ADMIN_PASS = "einAdminGehtZumBaecker!"; @Autowired private UrlProvider urlProvider; @Value("${de.asideas.crowdsource.content.allowed.email.domain}") private String allowedEmailDomain; public AuthToken authorizeWithDefaultUser() { return authorize(DEFAULT_USER_EMAIL, DEFAULT_USER_PASS); } public AuthToken authorizeWithAdminUser() { return authorize(DEFAULT_ADMIN_EMAIL, DEFAULT_ADMIN_PASS); } public AuthToken authorize(String email, String password) { MultiValueMap<String, String> tokenRequest = new LinkedMultiValueMap<>(); tokenRequest.put("username", Arrays.asList(email)); tokenRequest.put("password", Arrays.asList(password)); tokenRequest.put("client_id", Arrays.asList("web")); tokenRequest.put("grant_type", Arrays.asList("password")); return restTemplate.postForObject(urlProvider.applicationUrl() + "/oauth/token", tokenRequest, AuthToken.class); } public void registerUser(String emailName) { // create a user via the REST API UserRegistration userRegistration = new UserRegistration(); userRegistration.setEmail(emailName + "@" + allowedEmailDomain); userRegistration.setTermsOfServiceAccepted(true); restTemplate.postForObject(urlProvider.applicationUrl() + "/user", userRegistration, Void.class); } public void activateUser(String emailName, UserActivation userActivation) { restTemplate.postForObject(urlProvider.applicationUrl() + "/user/{email}/activation", userActivation, Void.class, emailName + "@" + allowedEmailDomain); } public void recoverPassword(String userEmail) { restTemplate.getForObject(urlProvider.applicationUrl() + "/user/{email}/password-recovery", Void.class, userEmail); } public ResponseEntity<Project> createProject(Project project, AuthToken authToken) { HttpEntity<Project> requestEntity = createRequestEntity(project, authToken); return restTemplate.exchange(urlProvider.applicationUrl() + "/project", HttpMethod.POST, requestEntity, Project.class); } public Attachment uploadFileAttachmentForProject(Project project, ClassPathResource fileResource) { LinkedMultiValueMap<String, Object> body = new LinkedMultiValueMap<>(); body.add("file", fileResource); HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = createRequestEntity(body, authorizeWithDefaultUser()); ResponseEntity<Attachment> result = restTemplate.exchange( urlProvider.applicationUrl() + "/projects/" + project.getId() + "/attachments/", HttpMethod.POST, requestEntity, Attachment.class); return result.getBody(); } public ResponseEntity<FinancingRound> startFinancingRound(FinancingRound financingRound, AuthToken authToken) { HttpEntity<FinancingRound> requestEntity = createRequestEntity(financingRound, authToken); return restTemplate.exchange(urlProvider.applicationUrl() + "/financingrounds", HttpMethod.POST, requestEntity, FinancingRound.class); } public FinancingRound getActiveFinanceRound() { try { return restTemplate.getForObject(urlProvider.applicationUrl() + "/financingrounds/active", FinancingRound.class); } catch (HttpClientErrorException e) { if (e.getStatusCode() == HttpStatus.NOT_FOUND) { return null; } throw e; } } public ResponseEntity<FinancingRound> stopFinancingRound(String id, AuthToken authToken) { HttpEntity requestEntity = createRequestEntity(authToken); return restTemplate.exchange(urlProvider.applicationUrl() + "/financingrounds/{id}/cancel", HttpMethod.PUT, requestEntity, FinancingRound.class, id); } public ResponseEntity<Void> pledgeProject(Project project, Pledge pledge, AuthToken authToken) { HttpEntity<Pledge> requestEntity = createRequestEntity(pledge, authToken); return restTemplate.exchange(urlProvider.applicationUrl() + "/project/{id}/pledges", HttpMethod.POST, requestEntity, Void.class, project.getId()); } public void comment(Project project, String comment, AuthToken token) { final String commentUrl = urlProvider.applicationUrl() + "/project/{id}/comment"; restTemplate.exchange(commentUrl, HttpMethod.POST, createRequestEntity(new Comment(null, null, comment), token), Void.class, project.getId()); } private <T> HttpEntity<T> createRequestEntity(T body, AuthToken authToken) { MultiValueMap<String, String> headers = new LinkedMultiValueMap<>(); headers.put("Authorization", Arrays.asList("Bearer " + authToken.accessToken)); return new HttpEntity<>(body, headers); } private HttpEntity createRequestEntity(AuthToken authToken) { return createRequestEntity(null, authToken); } public RestTemplate getUnderlyingClient() { return restTemplate; } public void publish(Project project, AuthToken token) { modifyProjectStatus(project.getId(), ProjectStatus.PUBLISHED, token); project.setStatus(ProjectStatus.PUBLISHED); } public void reject(Project project, AuthToken token) { modifyProjectStatus(project.getId(), ProjectStatus.REJECTED, token); project.setStatus(ProjectStatus.REJECTED); } public void defer(Project project, AuthToken token) { modifyProjectStatus(project.getId(), ProjectStatus.DEFERRED, token); project.setStatus(ProjectStatus.DEFERRED); } public void likeProject(Project project, AuthToken token) { final ResponseEntity<Project> exchange = restTemplate.exchange( urlProvider.applicationUrl() + "/projects/" + project.getId() + "/likes", HttpMethod.POST, createRequestEntity(token), Project.class); assertEquals(HttpStatus.OK, exchange.getStatusCode()); } public void unlikeProject(Project project, AuthToken token) { final ResponseEntity<Project> exchange = restTemplate.exchange( urlProvider.applicationUrl() + "/projects/" + project.getId() + "/likes", HttpMethod.DELETE, createRequestEntity(token), Project.class); assertEquals(HttpStatus.OK, exchange.getStatusCode()); } private void modifyProjectStatus(String projectId, ProjectStatus status, AuthToken token) { final ResponseEntity<Project> exchange = restTemplate.exchange( urlProvider.applicationUrl() + "/project/" + projectId + "/status", HttpMethod.PATCH, createRequestEntity(new ProjectStatusUpdate(status), token), Project.class); assertEquals(HttpStatus.OK, exchange.getStatusCode()); } public List<Project> listProjects(AuthToken authToken) { ResponseEntity<Project[]> responseEntity = restTemplate.exchange( urlProvider.applicationUrl() + "/projects", HttpMethod.GET, createRequestEntity(authToken), Project[].class); assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); return Arrays.asList(responseEntity.getBody()); } @JsonIgnoreProperties(ignoreUnknown = true) public static class AuthToken { @JsonProperty("access_token") private String accessToken; public AuthToken() { } public String getAccessToken() { return this.accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } @Override public boolean equals(Object o) { return EqualsBuilder.reflectionEquals(this, o); } @Override public int hashCode() { return HashCodeBuilder.reflectionHashCode(this); } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } } }