Test cleanup
This commit is contained in:
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* AuthApiTestSupport.java
|
||||||
|
*
|
||||||
|
* Shared MockMvc helpers for authentication API integration tests.
|
||||||
|
*/
|
||||||
|
package com.seanstarkey.notesvault.auth;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.seanstarkey.notesvault.repository.UserRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
|
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides common fixtures and request helpers used by focused auth controller
|
||||||
|
* test classes.
|
||||||
|
*/
|
||||||
|
abstract class AuthApiTestSupport {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected UserRepository userRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected JwtUtil jwtUtil;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
protected ResultActions register(String username, String password) throws Exception {
|
||||||
|
return mockMvc.perform(post("/auth/register")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content("""
|
||||||
|
{
|
||||||
|
"username": "%s",
|
||||||
|
"password": "%s"
|
||||||
|
}
|
||||||
|
""".formatted(username, password)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
/**
|
|
||||||
* AuthControllerTest.java
|
|
||||||
*/
|
|
||||||
package com.seanstarkey.notesvault.auth;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.seanstarkey.notesvault.repository.UserRepository;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
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.http.MediaType;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
||||||
|
|
||||||
@SpringBootTest
|
|
||||||
@AutoConfigureMockMvc
|
|
||||||
@Transactional
|
|
||||||
class AuthControllerTest {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MockMvc mockMvc;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserRepository userRepository;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PasswordEncoder passwordEncoder;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private JwtUtil jwtUtil;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void registerCreatesUserAndReturnsPublicProfile() throws Exception {
|
|
||||||
mockMvc.perform(post("/auth/register")
|
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
|
||||||
.content("""
|
|
||||||
{
|
|
||||||
"username": "starkey",
|
|
||||||
"password": "secret123"
|
|
||||||
}
|
|
||||||
"""))
|
|
||||||
.andExpect(status().isCreated())
|
|
||||||
.andExpect(jsonPath("$.id").isNotEmpty())
|
|
||||||
.andExpect(jsonPath("$.username").value("starkey"))
|
|
||||||
.andExpect(jsonPath("$.createdAt").isNotEmpty())
|
|
||||||
.andExpect(jsonPath("$.password").doesNotExist())
|
|
||||||
.andExpect(jsonPath("$.passwordHash").doesNotExist());
|
|
||||||
|
|
||||||
var savedUser = userRepository.findByUsername("starkey").orElseThrow();
|
|
||||||
assertThat(savedUser.getPasswordHash()).isNotEqualTo("secret123");
|
|
||||||
assertThat(passwordEncoder.matches("secret123", savedUser.getPasswordHash())).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test: duplicate usernames are rejected.
|
|
||||||
* Verifies that the unique account invariant is enforced at the API boundary
|
|
||||||
* with HTTP 409 instead of silently overwriting or exposing database details.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
void registerRejectsDuplicateUsername() throws Exception {
|
|
||||||
register("starkey", "secret123").andExpect(status().isCreated());
|
|
||||||
|
|
||||||
register("starkey", "another123")
|
|
||||||
.andExpect(status().isConflict())
|
|
||||||
.andExpect(jsonPath("$.error").value("Username is already registered"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test: registered users can log in and receive a bearer token.
|
|
||||||
* Verifies that POST /auth/login authenticates stored BCrypt credentials,
|
|
||||||
* returns token metadata, and issues a JWT whose subject is the username.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
void loginAuthenticatesUserAndReturnsBearerToken() throws Exception {
|
|
||||||
register("starkey", "secret123").andExpect(status().isCreated());
|
|
||||||
|
|
||||||
String responseBody = mockMvc.perform(post("/auth/login")
|
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
|
||||||
.content("""
|
|
||||||
{
|
|
||||||
"username": "starkey",
|
|
||||||
"password": "secret123"
|
|
||||||
}
|
|
||||||
"""))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.token").isNotEmpty())
|
|
||||||
.andExpect(jsonPath("$.tokenType").value("Bearer"))
|
|
||||||
.andExpect(jsonPath("$.expiresInSeconds").value(86400))
|
|
||||||
.andExpect(jsonPath("$.expiresAt").isNotEmpty())
|
|
||||||
.andReturn()
|
|
||||||
.getResponse()
|
|
||||||
.getContentAsString();
|
|
||||||
|
|
||||||
String token = objectMapper.readTree(responseBody).get("token").asText();
|
|
||||||
|
|
||||||
assertThat(jwtUtil.getUsernameFromToken(token)).isEqualTo("starkey");
|
|
||||||
assertThat(jwtUtil.isTokenValid(token, "starkey")).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
private org.springframework.test.web.servlet.ResultActions register(String username, String password) throws Exception {
|
|
||||||
return mockMvc.perform(post("/auth/register")
|
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
|
||||||
.content("""
|
|
||||||
{
|
|
||||||
"username": "%s",
|
|
||||||
"password": "%s"
|
|
||||||
}
|
|
||||||
""".formatted(username, password)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/**
|
||||||
|
* AuthRegistrationControllerTest.java
|
||||||
|
*
|
||||||
|
* API-level tests for public user registration behavior.
|
||||||
|
*/
|
||||||
|
package com.seanstarkey.notesvault.auth;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies registration behavior through the real Spring MVC, Security, JPA,
|
||||||
|
* validation, and Flyway-backed H2 application stack.
|
||||||
|
*/
|
||||||
|
@SpringBootTest
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
@Transactional
|
||||||
|
class AuthRegistrationControllerTest extends AuthApiTestSupport {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test: registering a new user returns public account details.
|
||||||
|
* Verifies that POST /auth/register creates a user, hashes the password,
|
||||||
|
* returns HTTP 201, and never exposes credential material in the response.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
void registerCreatesUserAndReturnsPublicProfile() throws Exception {
|
||||||
|
mockMvc.perform(post("/auth/register")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content("""
|
||||||
|
{
|
||||||
|
"username": "alice",
|
||||||
|
"password": "secret123"
|
||||||
|
}
|
||||||
|
"""))
|
||||||
|
.andExpect(status().isCreated())
|
||||||
|
.andExpect(jsonPath("$.id").isNotEmpty())
|
||||||
|
.andExpect(jsonPath("$.username").value("alice"))
|
||||||
|
.andExpect(jsonPath("$.createdAt").isNotEmpty())
|
||||||
|
.andExpect(jsonPath("$.password").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$.passwordHash").doesNotExist());
|
||||||
|
|
||||||
|
var savedUser = userRepository.findByUsername("alice").orElseThrow();
|
||||||
|
assertThat(savedUser.getPasswordHash()).isNotEqualTo("secret123");
|
||||||
|
assertThat(passwordEncoder.matches("secret123", savedUser.getPasswordHash())).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test: duplicate usernames are rejected.
|
||||||
|
* Verifies that the unique account invariant is enforced at the API boundary
|
||||||
|
* with HTTP 409 instead of silently overwriting or exposing database details.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
void registerRejectsDuplicateUsername() throws Exception {
|
||||||
|
register("alice", "secret123").andExpect(status().isCreated());
|
||||||
|
|
||||||
|
register("alice", "another123")
|
||||||
|
.andExpect(status().isConflict())
|
||||||
|
.andExpect(jsonPath("$.error").value("Username is already registered"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test: invalid registration payloads return field-level validation details.
|
||||||
|
* Verifies that username and password constraints are enforced before
|
||||||
|
* persistence and reported with the documented HTTP 422 response shape.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
void registerRejectsInvalidPayload() throws Exception {
|
||||||
|
mockMvc.perform(post("/auth/register")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content("""
|
||||||
|
{
|
||||||
|
"username": "al",
|
||||||
|
"password": "short"
|
||||||
|
}
|
||||||
|
"""))
|
||||||
|
.andExpect(status().isUnprocessableEntity())
|
||||||
|
.andExpect(jsonPath("$.error").value("Validation failed"))
|
||||||
|
.andExpect(jsonPath("$.fields.username").exists())
|
||||||
|
.andExpect(jsonPath("$.fields.password").exists());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/**
|
||||||
|
* ControllerApiTestSupport.java
|
||||||
|
*
|
||||||
|
* Shared MockMvc helpers for note and sharing API integration tests.
|
||||||
|
*/
|
||||||
|
package com.seanstarkey.notesvault.controller;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.seanstarkey.notesvault.auth.JwtUtil;
|
||||||
|
import com.seanstarkey.notesvault.entity.Note;
|
||||||
|
import com.seanstarkey.notesvault.entity.NoteShare;
|
||||||
|
import com.seanstarkey.notesvault.entity.User;
|
||||||
|
import com.seanstarkey.notesvault.repository.NoteRepository;
|
||||||
|
import com.seanstarkey.notesvault.repository.NoteShareRepository;
|
||||||
|
import com.seanstarkey.notesvault.repository.UserRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides common authenticated request setup for focused note controller test
|
||||||
|
* classes.
|
||||||
|
*/
|
||||||
|
abstract class ControllerApiTestSupport {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected JwtUtil jwtUtil;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected NoteRepository noteRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected NoteShareRepository noteShareRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected UserRepository userRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
protected void register(String username, String password) throws Exception {
|
||||||
|
mockMvc.perform(post("/auth/register")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content("""
|
||||||
|
{
|
||||||
|
"username": "%s",
|
||||||
|
"password": "%s"
|
||||||
|
}
|
||||||
|
""".formatted(username, password)))
|
||||||
|
.andExpect(status().isCreated());
|
||||||
|
|
||||||
|
assertThat(userRepository.findByUsername(username)).isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected UUID createNote(String token, String title, String content) throws Exception {
|
||||||
|
String responseBody = mockMvc.perform(post("/notes")
|
||||||
|
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content("""
|
||||||
|
{
|
||||||
|
"title": "%s",
|
||||||
|
"content": "%s"
|
||||||
|
}
|
||||||
|
""".formatted(title, content)))
|
||||||
|
.andExpect(status().isCreated())
|
||||||
|
.andReturn()
|
||||||
|
.getResponse()
|
||||||
|
.getContentAsString();
|
||||||
|
|
||||||
|
return UUID.fromString(objectMapper.readTree(responseBody).get("id").asText());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ResultActions shareNote(String token, UUID noteId, String targetUsername) throws Exception {
|
||||||
|
return mockMvc.perform(post("/notes/{id}/share", noteId)
|
||||||
|
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content("""
|
||||||
|
{
|
||||||
|
"username": "%s"
|
||||||
|
}
|
||||||
|
""".formatted(targetUsername)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void shareWith(UUID noteId, String username) {
|
||||||
|
Note note = noteRepository.findById(noteId).orElseThrow();
|
||||||
|
User sharedWith = userRepository.findByUsername(username).orElseThrow();
|
||||||
|
|
||||||
|
NoteShare share = new NoteShare();
|
||||||
|
share.setNote(note);
|
||||||
|
share.setSharedWith(sharedWith);
|
||||||
|
noteShareRepository.saveAndFlush(share);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,65 +1,34 @@
|
|||||||
/**
|
/**
|
||||||
* NoteControllerTest.java
|
* NoteCreationControllerTest.java
|
||||||
*
|
*
|
||||||
* API-level tests for authenticated note endpoints exposed by NoteController.
|
* API-level tests for authenticated note creation behavior.
|
||||||
*/
|
*/
|
||||||
package com.seanstarkey.notesvault.controller;
|
package com.seanstarkey.notesvault.controller;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.seanstarkey.notesvault.auth.JwtUtil;
|
|
||||||
import com.seanstarkey.notesvault.entity.Note;
|
import com.seanstarkey.notesvault.entity.Note;
|
||||||
import com.seanstarkey.notesvault.entity.NoteShare;
|
|
||||||
import com.seanstarkey.notesvault.entity.User;
|
|
||||||
import com.seanstarkey.notesvault.repository.NoteRepository;
|
|
||||||
import com.seanstarkey.notesvault.repository.NoteShareRepository;
|
|
||||||
import com.seanstarkey.notesvault.repository.UserRepository;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies note CRUD, sharing, authentication, authorization, and validation
|
* Verifies POST /notes through the real Spring MVC, Security, JPA, validation,
|
||||||
* behavior through the real Spring MVC, Security, JPA, validation, and
|
* and Flyway-backed H2 application stack.
|
||||||
* Flyway-backed H2 application stack.
|
|
||||||
*/
|
*/
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@AutoConfigureMockMvc
|
@AutoConfigureMockMvc
|
||||||
@Transactional
|
@Transactional
|
||||||
class NoteControllerTest {
|
class NoteCreationControllerTest extends ControllerApiTestSupport {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MockMvc mockMvc;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private JwtUtil jwtUtil;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private NoteRepository noteRepository;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private NoteShareRepository noteShareRepository;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserRepository userRepository;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test: authenticated users can create notes.
|
* Test: authenticated users can create notes.
|
||||||
@@ -119,45 +88,29 @@ class NoteControllerTest {
|
|||||||
.andExpect(jsonPath("$.error").value("Unauthorized"));
|
.andExpect(jsonPath("$.error").value("Unauthorized"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void register(String username, String password) throws Exception {
|
/*
|
||||||
mockMvc.perform(post("/auth/register")
|
* Test: invalid note creation payloads return field-level validation details.
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
* Verifies that POST /notes rejects blank content before persistence and
|
||||||
.content("""
|
* reports the documented HTTP 422 response shape.
|
||||||
{
|
*/
|
||||||
"username": "%s",
|
@Test
|
||||||
"password": "%s"
|
void createNoteRejectsInvalidPayload() throws Exception {
|
||||||
}
|
register("alice", "secret123");
|
||||||
""".formatted(username, password)))
|
String token = jwtUtil.generateToken("alice");
|
||||||
.andExpect(status().isCreated());
|
|
||||||
|
|
||||||
assertThat(userRepository.findByUsername(username)).isPresent();
|
mockMvc.perform(post("/notes")
|
||||||
}
|
|
||||||
|
|
||||||
private UUID createNote(String token, String title, String content) throws Exception {
|
|
||||||
String responseBody = mockMvc.perform(post("/notes")
|
|
||||||
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
|
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
"title": "%s",
|
"title": "My Note",
|
||||||
"content": "%s"
|
"content": ""
|
||||||
}
|
}
|
||||||
""".formatted(title, content)))
|
"""))
|
||||||
.andExpect(status().isCreated())
|
.andExpect(status().isUnprocessableEntity())
|
||||||
.andReturn()
|
.andExpect(jsonPath("$.error").value("Validation failed"))
|
||||||
.getResponse()
|
.andExpect(jsonPath("$.fields.content").exists());
|
||||||
.getContentAsString();
|
|
||||||
|
|
||||||
return UUID.fromString(objectMapper.readTree(responseBody).get("id").asText());
|
assertThat(noteRepository.findAll()).isEmpty();
|
||||||
}
|
|
||||||
|
|
||||||
private void shareWith(UUID noteId, String username) {
|
|
||||||
Note note = noteRepository.findById(noteId).orElseThrow();
|
|
||||||
User sharedWith = userRepository.findByUsername(username).orElseThrow();
|
|
||||||
|
|
||||||
NoteShare share = new NoteShare();
|
|
||||||
share.setNote(note);
|
|
||||||
share.setSharedWith(sharedWith);
|
|
||||||
noteShareRepository.saveAndFlush(share);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user