Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ dependencies {
runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ protected void configure(HttpSecurity http) throws Exception {
.and()
.authorizeRequests() // 다음 리퀘스트에 대한 사용권한 체크
.antMatchers("/*/signin", "/*/signup").permitAll() // 가입 및 인증 주소는 누구나 접근가능
.antMatchers(HttpMethod.GET, "helloworld/**").permitAll() // hellowworld로 시작하는 GET요청 리소스는 누구나 접근가능
.antMatchers("/*/users").hasRole("ADMIN")
.antMatchers(HttpMethod.GET, "/helloworld/**").permitAll() // hellowworld로 시작하는 GET요청 리소스는 누구나 접근가능
.anyRequest().hasRole("USER") // 그외 나머지 요청은 모두 인증된 회원만 접근 가능
.and()
.exceptionHandling().accessDeniedHandler(new CustomAccessDeniedHandler())
Expand Down
11 changes: 4 additions & 7 deletions src/main/java/com/rest/api/controller/v1/SignController.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;

Expand All @@ -31,7 +28,7 @@ public class SignController {
private final PasswordEncoder passwordEncoder;

@ApiOperation(value = "로그인", notes = "이메일 회원 로그인을 한다.")
@GetMapping(value = "/signin")
@PostMapping(value = "/signin")
public SingleResult<String> signin(@ApiParam(value = "회원ID : 이메일", required = true) @RequestParam String id,
@ApiParam(value = "비밀번호", required = true) @RequestParam String password) {

Expand All @@ -43,8 +40,8 @@ public SingleResult<String> signin(@ApiParam(value = "회원ID : 이메일", req
}

@ApiOperation(value = "가입", notes = "회원가입을 한다.")
@GetMapping(value = "/signup")
public CommonResult signin(@ApiParam(value = "회원ID : 이메일", required = true) @RequestParam String id,
@PostMapping(value = "/signup")
public CommonResult signup(@ApiParam(value = "회원ID : 이메일", required = true) @RequestParam String id,
@ApiParam(value = "비밀번호", required = true) @RequestParam String password,
@ApiParam(value = "이름", required = true) @RequestParam String name) {

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/rest/api/controller/v1/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ public ListResult<User> findAllUser() {
}

@ApiImplicitParams({
@ApiImplicitParam(name = "X-AUTH-TOKEN", value = "로그인 성공 후 access_token", required = false, dataType = "String", paramType = "header")
@ApiImplicitParam(name = "X-AUTH-TOKEN", value = "로그인 성공 후 access_token", required = true, dataType = "String", paramType = "header")
})
@ApiOperation(value = "회원 단건 조회", notes = "회원번호(msrl)로 회원을 조회한다")
@GetMapping(value = "/user")
public SingleResult<User> findUserById(@ApiParam(value = "언어", defaultValue = "ko") @RequestParam String lang) {
public SingleResult<User> findUser() {
// SecurityContext에서 인증받은 회원의 정보를 얻어온다.
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String id = authentication.getName();
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/rest/api/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class User implements UserDetails {
@Id // pk
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long msrl;
@Column(nullable = false, unique = true, length = 30)
@Column(nullable = false, unique = true, length = 50)
private String uid;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@Column(nullable = false, length = 100)
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/rest/api/service/ResponseService.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class ResponseService {

// enum으로 api 요청 결과에 대한 code, message를 정의합니다.
public enum CommonResponse {
SUCCESS(0, "성공하였습니디.");
SUCCESS(0, "성공하였습니다.");

int code;
String msg;
Expand Down
16 changes: 0 additions & 16 deletions src/test/java/com/rest/api/SpringRestApiApplicationTests.java

This file was deleted.

52 changes: 52 additions & 0 deletions src/test/java/com/rest/api/controller/HelloControllerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.rest.api.controller;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
public class HelloControllerTest {

@Autowired
private MockMvc mockMvc;

@Test
public void helloworldString() throws Exception {
mockMvc.perform(get("/helloworld/string"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType("text/plain;charset=UTF-8"))
.andExpect(content().string("helloworld"));
}

@Test
public void helloworldJson() throws Exception {
mockMvc.perform(get("/helloworld/json"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=utf-8"))
.andExpect(jsonPath("$.message").value("helloworld"));
}

@Test
public void helloworldPage() throws Exception {
mockMvc.perform(get("/helloworld/page"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType("text/html;charset=UTF-8"))
.andExpect(view().name("helloworld"))
.andExpect(content().string("helloworld"));
}
}
89 changes: 89 additions & 0 deletions src/test/java/com/rest/api/controller/v1/SignControllerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.rest.api.controller.v1;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.context.WebApplicationContext;

import java.time.LocalDateTime;
import java.time.ZoneId;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
public class SignControllerTest {

@Autowired
private MockMvc mockMvc;

@Test
public void signin() throws Exception {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("id", "happydaddy@naver.com");
params.add("password", "1234");
mockMvc.perform(post("/v1/signin").params(params))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.code").value(0))
.andExpect(jsonPath("$.msg").exists())
.andExpect(jsonPath("$.data").exists());
}

@Test
public void signinFail() throws Exception {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("id", "happydaddy@naver.com");
params.add("password", "12345");
mockMvc.perform(post("/v1/signin").params(params))
.andDo(print())
.andExpect(status().is5xxServerError())
.andExpect(jsonPath("$.success").value(false))
.andExpect(jsonPath("$.code").value(-1001))
.andExpect(jsonPath("$.msg").exists());
}

@Test
public void signup() throws Exception {
long epochTime = LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond();
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("id", "happydaddy_" + epochTime + "@naver.com");
params.add("password", "12345");
params.add("name", "happydaddy_" + epochTime);
mockMvc.perform(post("/v1/signup").params(params))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.code").value(0))
.andExpect(jsonPath("$.msg").exists());
}

@Test
public void signupFail() throws Exception {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("id", "happydaddy@naver.com");
params.add("password", "12345");
params.add("name", "happydaddy");
mockMvc.perform(post("/v1/signup").params(params))
.andDo(print())
.andExpect(status().is5xxServerError())
.andExpect(jsonPath("$.success").value(false))
.andExpect(jsonPath("$.code").value(-9999));
}
}
119 changes: 119 additions & 0 deletions src/test/java/com/rest/api/controller/v1/UserControllerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package com.rest.api.controller.v1;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.json.JacksonJsonParser;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
public class UserControllerTest {

@Autowired
private MockMvc mockMvc;

private String token;

@Before
public void setUp() throws Exception {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("id", "happydaddy@naver.com");
params.add("password", "1234");
MvcResult result = mockMvc.perform(post("/v1/signin").params(params))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.code").value(0))
.andExpect(jsonPath("$.msg").exists())
.andExpect(jsonPath("$.data").exists())
.andReturn();

String resultString = result.getResponse().getContentAsString();
JacksonJsonParser jsonParser = new JacksonJsonParser();
token = jsonParser.parseMap(resultString).get("data").toString();
}

@Test
public void invalidToken() throws Exception {
mockMvc.perform(MockMvcRequestBuilders
.get("/v1/users")
.header("X-AUTH-TOKEN", "XXXXXXXXXX"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(forwardedUrl("/exception/entrypoint"));
}

@Test
@WithMockUser(username = "mockUser", roles = {"ADMIN"}) // 가상의 Mock 유저 대입
public void accessdenied() throws Exception {
mockMvc.perform(MockMvcRequestBuilders
.get("/v1/users"))
//.header("X-AUTH-TOKEN", token))
.andDo(print())
.andExpect(status().isOk())
.andExpect(forwardedUrl("/exception/accessdenied"));
}

@Test
public void findAllUser() throws Exception {
mockMvc.perform(MockMvcRequestBuilders
.get("/v1/users")
.header("X-AUTH-TOKEN", token))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.list").exists());
}

@Test
public void findUser() throws Exception {
mockMvc.perform(MockMvcRequestBuilders
.get("/v1/user")
.header("X-AUTH-TOKEN", token))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.data").exists());
}

@Test
public void modify() throws Exception {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("msrl", "1");
params.add("name", "행복전도사");
mockMvc.perform(MockMvcRequestBuilders
.put("/v1/user")
.header("X-AUTH-TOKEN", token)
.params(params))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true));
}

@Test
public void delete() throws Exception {
mockMvc.perform(MockMvcRequestBuilders
.delete("/v1/user/2")
.header("X-AUTH-TOKEN", token))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true));
}
}
Loading