add test case

This commit is contained in:
zhouhao
2018-10-10 18:16:20 +08:00
parent 4006e1b18b
commit 3fd5b7b32d
6 changed files with 304 additions and 0 deletions

View File

@@ -0,0 +1,137 @@
package org.hswebframework.web.authorization.full
import com.alibaba.fastjson.JSON
import org.hswebframework.web.authorization.AuthenticationManager
import org.hswebframework.web.authorization.TestApplication
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.http.MediaType
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.setup.MockMvcBuilders
import spock.lang.Shared
import spock.lang.Specification
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
/**
* 完整功能测试
* @author zhouhao
* @since 3.0.2
*/
@WebAppConfiguration
@ContextConfiguration
@SpringBootTest(classes = [TestApplication.class], properties = ["classpath:application.yml"])
class FullFunctionTest extends Specification {
@Autowired
private ConfigurableApplicationContext context;
@Shared
private MockMvc mockMvc;
@Autowired
private AuthenticationManager authenticationManager;
void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
def doLogin(String username, String password) {
return JSON.parseObject(mockMvc.perform(post("/authorize/login")
.contentType(MediaType.APPLICATION_JSON)
.content("""{"token_type":"test-token","username":"${username}","password":"${password}"}"""))
.andExpect(status().is(200))
.andReturn()
.getResponse()
.getContentAsString())
.getJSONObject("result").getString("token")
}
def "测试查询"() {
given: "登录"
def token = doLogin("admin", "admin")
when: "登录成功"
token != null
then: "进行查询"
def resp = mockMvc.perform(get("/test")
.header("token", token)//登录返回的token
.param("terms[0].column", "name")
.param("terms[0].value", "test"))
.andExpect(status().is(200))
.andReturn()
.getResponse()
.getContentAsString()
def result = JSON.parseObject(resp).getJSONObject("result");
expect: "权限控制成功"
result.getJSONArray("excludes") != null
//与application.yml中配置的数据权限一致
result.getJSONArray("excludes").getString(0) == "password"
result.getJSONArray("terms") != null
!result.getJSONArray("terms").isEmpty()
}
def "测试修改"() {
given: "登录"
def token = doLogin("admin", "admin")
when: "登录成功"
token != null
then: "进行修改数据"
def resp = mockMvc.perform(put("/test")
.header("token", token)//登录返回的token
.contentType(MediaType.APPLICATION_JSON)
.content("""{"id":"test","name":"testName"}"""))
.andExpect(status().is(200))
.andReturn()
.getResponse()
.getContentAsString()
def result = JSON.parseObject(resp).getJSONObject("result");
println result
expect: "权限控制成功,name属性被修改为null"
//与application.yml中配置的数据权限一致
result.getString("name") == null
result.getString("id") != null
}
def "测试新增"() {
given: "登录"
def token = doLogin("admin", "admin")
when: "登录成功"
token != null
then: "进行新增数据"
def resp = mockMvc.perform(post("/test")
.header("token", token)//登录返回的token
.contentType(MediaType.APPLICATION_JSON)
.content("""{"id":"test","name":"testName"}"""))
.andExpect(status().is(200))
.andReturn()
.getResponse()
.getContentAsString()
def result = JSON.parseObject(resp).getJSONObject("result");
expect: "权限控制成功,id不能进行insert操作"
//与application.yml中配置的数据权限一致
result.getString("id") == null
result.getString("name") != null
}
def "测试删除"() {
given: "登录"
def token = doLogin("admin", "admin")
when: "登录成功"
token != null
then: "进行新增数据"
def resp = mockMvc.perform(delete("/test/{id}", "test")
.header("token", token))//登录返回的token
.andReturn()
.getResponse()
.getContentAsString()
def status = JSON.parseObject(resp).getInteger("status");
expect:
"权限控制成功,不能进行delete操作"
//与application.yml中配置的数据权限一致
status == 403
}
}

View File

@@ -0,0 +1,39 @@
package org.hswebframework.web.authorization.full.controller;
import org.hswebframework.web.authorization.Permission;
import org.hswebframework.web.authorization.annotation.Authorize;
import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
import org.hswebframework.web.commons.entity.param.QueryParamEntity;
import org.hswebframework.web.controller.message.ResponseMessage;
import org.springframework.web.bind.annotation.*;
/**
* @author zhouhao
* @since 3.0.2
*/
public interface CrudController<T> {
@GetMapping
@Authorize(action = Permission.ACTION_QUERY, dataAccess = @RequiresDataAccess)
default ResponseMessage<QueryParamEntity> query(QueryParamEntity param) {
return ResponseMessage.ok(param);
}
@PutMapping
@Authorize(action = Permission.ACTION_UPDATE, dataAccess = @RequiresDataAccess)
default ResponseMessage<T> update(@RequestBody T entity) {
return ResponseMessage.ok(entity);
}
@PostMapping
@Authorize(action = Permission.ACTION_ADD, dataAccess = @RequiresDataAccess)
default ResponseMessage<T> insert(@RequestBody T entity) {
return ResponseMessage.ok(entity);
}
@DeleteMapping("/{id}")
@Authorize(action = Permission.ACTION_DELETE, dataAccess = @RequiresDataAccess)
ResponseMessage<T> delete(@PathVariable String id);
}

View File

@@ -0,0 +1,24 @@
package org.hswebframework.web.authorization.full.controller;
import org.hswebframework.web.authorization.annotation.Authorize;
import org.hswebframework.web.authorization.full.controller.model.TestModel;
import org.hswebframework.web.controller.message.ResponseMessage;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author zhouhao
* @since 3.0.2
*/
@RequestMapping("/test")
@RestController
@Authorize(permission = "test")
public class TestCrudController implements CrudController<TestModel> {
@Override
public ResponseMessage<TestModel> delete(@PathVariable String id) {
return ResponseMessage.ok();
}
}

View File

@@ -0,0 +1,21 @@
package org.hswebframework.web.authorization.full.controller.model;
import lombok.Data;
import org.hswebframework.web.commons.model.Model;
/**
* @author zhouhao
* @since 3.0.2
*/
@Data
public class TestModel implements Model {
private String id;
private String name;
private int age;
private String orgId;
private String password;
}

View File

@@ -0,0 +1,68 @@
package org.hswebframework.web.authorization.full.token;
import org.hswebframework.web.authorization.Authentication;
import org.hswebframework.web.authorization.basic.web.GeneratedToken;
import org.hswebframework.web.authorization.basic.web.ParsedToken;
import org.hswebframework.web.authorization.basic.web.UserTokenGenerator;
import org.hswebframework.web.authorization.basic.web.UserTokenParser;
import org.hswebframework.web.id.IDGenerator;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
/**
* @author zhouhao
* @since 3.0.2
*/
@Component
public class TestTokenGeneratorAndParser implements UserTokenGenerator, UserTokenParser {
@Override
public String getSupportTokenType() {
return "test-token";
}
@Override
public GeneratedToken generate(Authentication authentication) {
String token = IDGenerator.MD5.generate();
return new GeneratedToken() {
@Override
public Map<String, Object> getResponse() {
return Collections.singletonMap("token", token);
}
@Override
public String getToken() {
return token;
}
@Override
public String getType() {
return getSupportTokenType();
}
@Override
public int getTimeout() {
return -1;
}
};
}
@Override
public ParsedToken parseToken(HttpServletRequest request) {
return Optional.ofNullable(request.getHeader("token"))
.map(token -> new ParsedToken() {
@Override
public String getToken() {
return token;
}
@Override
public String getType() {
return getSupportTokenType();
}
}).orElse(null);
}
}

View File

@@ -40,5 +40,20 @@ hsweb:
fields:
- password
- salt
- id: test
actions: query,add,update
dataAccesses:
- action: query
type: DENY_FIELDS
fields:
- password
- action: update
type: DENY_FIELDS
fields:
- name
- action: add
type: DENY_FIELDS
fields:
- id
server:
port: 8808