Introduce pluggable email and image upload

This commit is contained in:
Tim
2025-07-01 09:58:40 +08:00
parent 9db69ba714
commit aa64ef5ee1
16 changed files with 266 additions and 9 deletions

View File

@@ -1,7 +1,7 @@
package com.openisle.controller;
import com.openisle.model.User;
import com.openisle.service.EmailService;
import com.openisle.service.EmailSender;
import com.openisle.service.JwtService;
import com.openisle.service.UserService;
import org.junit.jupiter.api.Test;
@@ -33,7 +33,7 @@ class AuthControllerTest {
@MockBean
private JwtService jwtService;
@MockBean
private EmailService emailService;
private EmailSender emailService;
@Test
void registerSendsEmail() throws Exception {

View File

@@ -0,0 +1,59 @@
package com.openisle.controller;
import com.openisle.model.Category;
import com.openisle.service.CategoryService;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
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.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import java.util.List;
import static org.mockito.ArgumentMatchers.eq;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@WebMvcTest(CategoryController.class)
@AutoConfigureMockMvc(addFilters = false)
class CategoryControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private CategoryService categoryService;
@Test
void createAndGetCategory() throws Exception {
Category c = new Category();
c.setId(1L);
c.setName("tech");
Mockito.when(categoryService.createCategory(eq("tech"))).thenReturn(c);
Mockito.when(categoryService.getCategory(1L)).thenReturn(c);
mockMvc.perform(post("/api/categories")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"name\":\"tech\"}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("tech"));
mockMvc.perform(get("/api/categories/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(1));
}
@Test
void listCategories() throws Exception {
Category c = new Category();
c.setId(2L);
c.setName("life");
Mockito.when(categoryService.listCategories()).thenReturn(List.of(c));
mockMvc.perform(get("/api/categories"))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].name").value("life"));
}
}

View File

@@ -0,0 +1,60 @@
package com.openisle.controller;
import com.openisle.model.User;
import com.openisle.service.ImageUploader;
import com.openisle.service.UserService;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
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.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Optional;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@WebMvcTest(UserController.class)
@AutoConfigureMockMvc(addFilters = false)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@MockBean
private ImageUploader imageUploader;
@Test
void getCurrentUser() throws Exception {
User u = new User();
u.setId(1L);
u.setUsername("alice");
u.setEmail("a@b.com");
u.setAvatar("http://x/avatar.png");
Mockito.when(userService.findByUsername("alice")).thenReturn(Optional.of(u));
mockMvc.perform(get("/api/users/me").principal(new UsernamePasswordAuthenticationToken("alice","p")))
.andExpect(status().isOk())
.andExpect(jsonPath("$.avatar").value("http://x/avatar.png"));
}
@Test
void uploadAvatar() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "a.png", MediaType.IMAGE_PNG_VALUE, "img".getBytes());
Mockito.when(imageUploader.upload(any(), eq("a.png"))).thenReturn("http://img/a.png");
mockMvc.perform(multipart("/api/users/me/avatar").file(file).principal(new UsernamePasswordAuthenticationToken("alice","p")))
.andExpect(status().isOk())
.andExpect(jsonPath("$.url").value("http://img/a.png"));
Mockito.verify(userService).updateAvatar("alice", "http://img/a.png");
}
}

View File

@@ -3,7 +3,7 @@ package com.openisle.integration;
import com.openisle.model.User;
import com.openisle.model.Role;
import com.openisle.repository.UserRepository;
import com.openisle.service.EmailService;
import com.openisle.service.EmailSender;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -26,7 +26,7 @@ class ComplexFlowIntegrationTest {
private UserRepository users;
@MockBean
private EmailService emailService;
private EmailSender emailService;
private String registerAndLogin(String username, String email) {
HttpHeaders h = new HttpHeaders();

View File

@@ -0,0 +1,14 @@
package com.openisle.service;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CosImageUploaderTest {
@Test
void uploadReturnsUrl() {
CosImageUploader uploader = new CosImageUploader("http://cos.example.com");
String url = uploader.upload("data".getBytes(), "img.png");
assertEquals("http://cos.example.com/img.png", url);
}
}