package org.ff4j.spring.boot.web.api.resources;
/*
* #%L
* ff4j-spring-boot-web-api
* %%
* Copyright (C) 2013 - 2016 FF4J
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.apache.commons.lang3.StringUtils;
import org.ff4j.FF4j;
import org.ff4j.core.Feature;
import org.ff4j.property.*;
import org.ff4j.property.store.InMemoryPropertyStore;
import org.ff4j.property.util.PropertyFactory;
import org.ff4j.spring.boot.web.api.Application;
import org.ff4j.spring.boot.web.api.utils.HttpMethod;
import org.ff4j.store.InMemoryFeatureStore;
import org.json.JSONException;
import org.skyscreamer.jsonassert.JSONAssert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationContextLoader;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.web.context.WebApplicationContext;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author <a href="mailto:paul58914080@gmail.com">Paul Williams</a>
*/
@ContextConfiguration(classes = Application.class, loader = SpringApplicationContextLoader.class)
@WebAppConfiguration
public abstract class AbstractStepDef {
protected MockMvc mockMvc;
@Autowired
protected WebApplicationContext context;
protected MockHttpServletRequestBuilder requestBuilder;
protected MockHttpServletResponse response;
@Autowired
protected FF4j ff4j;
protected abstract void init();
protected void clearFeatureStore() {
ff4j.setFeatureStore(new InMemoryFeatureStore());
ff4j.setPropertiesStore(new InMemoryPropertyStore());
}
protected void clearPropertyStore() {
ff4j.setFeatureStore(new InMemoryFeatureStore());
ff4j.setPropertiesStore(new InMemoryPropertyStore());
}
protected void constructRequestBuilder(String path, String httpMethod, String contentType) {
switch (HttpMethod.getHttpMethod(httpMethod)) {
case GET:
requestBuilder = MockMvcRequestBuilders.get(path).contentType(MediaType.valueOf(contentType));
break;
case PUT:
requestBuilder = MockMvcRequestBuilders.put(path).contentType(MediaType.valueOf(contentType));
break;
case DELETE:
requestBuilder = MockMvcRequestBuilders.delete(path).contentType(MediaType.valueOf(contentType));
break;
case POST:
requestBuilder = MockMvcRequestBuilders.post(path).contentType(MediaType.valueOf(contentType));
break;
default:
throw new AssertionError("http method not found");
}
}
protected void createFeatures(List<FeaturePojo> features) {
for (FeaturePojo featurePojo : features) {
Feature feature = new Feature(featurePojo.getUid(), Boolean.valueOf(featurePojo.getEnable()),
featurePojo.getDescription(), featurePojo.getGroup(),
Arrays.asList(featurePojo.getPermissions().split(",")));
createFeature(feature);
}
}
protected void createProperties(List<PropertyPojo> properties) {
for (PropertyPojo propertyPojo : properties) {
Property<?> property = asProperty(propertyPojo.getName(), propertyPojo.getType(), propertyPojo.getValue(),
propertyPojo.getDescription(),
StringUtils.isNotBlank(propertyPojo.getFixedValueCSV()) ? new HashSet<String>(Arrays.asList(propertyPojo.getFixedValueCSV().split(","))) : null);
createProperty(property);
}
}
private void createProperty(Property<?> property) {
ff4j.createProperty(property);
}
protected void createFeature(Feature feature) {
ff4j.createFeature(feature);
}
protected void setRequestBody(String requestBody) {
requestBuilder.content(requestBody);
}
protected void assertErrorCodeAndMessage(int statusCode, String expectedErrorResponse) throws Exception {
response = mockMvc.perform(requestBuilder).andReturn().getResponse();
assertThat(response.getStatus()).isEqualTo(statusCode);
assertThat(response.getErrorMessage()).isEqualTo(expectedErrorResponse);
}
protected void assertStatus(int expectedStatusCode) throws Exception {
response = mockMvc.perform(requestBuilder).andReturn().getResponse();
assertThat(response.getStatus()).isEqualTo(expectedStatusCode);
}
protected void assertJsonResponse(String expectedResponse) throws UnsupportedEncodingException, JSONException {
JSONAssert.assertEquals(expectedResponse, response.getContentAsString(), false);
}
protected void assertContent(String expectedResponse) throws UnsupportedEncodingException {
assertThat(response.getContentAsString()).contains(expectedResponse);
}
protected Property<?> asProperty(String name, String type, String value, String description, Set<String> fixedValues) {
return PropertyFactory.createProperty(name, getType(type), value, description, fixedValues);
}
private String getType(String name) {
PropertyValueEnum propertyEnum = PropertyValueEnum.getEnum(name);
switch (propertyEnum) {
case INT:
case LONG:
case STRING:
case BOOLEAN:
return propertyEnum.getType();
default:
return null;
}
}
private enum PropertyValueEnum {
INT("int", PropertyInt.class.getName()),
LONG("long", PropertyLong.class.getName()),
STRING("string", PropertyString.class.getName()),
BOOLEAN("boolean", PropertyBoolean.class.getName());
private String name;
private String type;
public String getName() {
return name;
}
public String getType() {
return type;
}
PropertyValueEnum(String name, String type) {
this.name = name;
this.type = type;
}
public static PropertyValueEnum getEnum(String name) {
for (PropertyValueEnum propertyValueEnum : PropertyValueEnum.values()) {
if (StringUtils.isNotBlank(name) && name.equalsIgnoreCase(propertyValueEnum.getName())) {
return propertyValueEnum;
}
}
throw new UnsupportedOperationException("property " + name + " not found");
}
}
protected class FeaturePojo {
private String uid;
private String enable;
private String description;
private String group;
private String permissions;
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getEnable() {
return enable;
}
public void setEnable(String enable) {
this.enable = enable;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getPermissions() {
return permissions;
}
public void setPermissions(String permissions) {
this.permissions = permissions;
}
}
protected class PropertyPojo {
private String name;
private String description;
private String type;
private String value;
private String fixedValueCSV;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getFixedValueCSV() {
return fixedValueCSV;
}
public void setFixedValueCSV(String fixedValueCSV) {
this.fixedValueCSV = fixedValueCSV;
}
}
}