feat(profile): 新增C端个人资料与设备相册功能

- 新增个人资料模块,支持获取、修改昵称和个性签名
- 实现头像上传与校验,支持JPEG/PNG格式及尺寸限制
- 添加app_user表signature字段的可重复执行SQL脚本
- 新增设备相册控制器,支持读取、收藏和删除相册图片
- 编写AppProfileService和DeviceAlbumController单元测试
This commit is contained in:
tongtong committed 2026-11-09 09:23:43 +08:00
1 parent 8d61c63c8b
commit 4dd7d98ce9
9 files changed
+382

No files matched your search

@@ -0,0 +1,54 @@
package com.youlai.boot.device;
import com.youlai.boot.common.result.ResultCode;
import com.youlai.boot.device.controller.DeviceAlbumController;
import com.youlai.boot.device.model.vo.DevicePictureVO;
import com.youlai.boot.device.service.DevicePictureService;
import jakarta.validation.Validation;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
class DeviceAlbumControllerTest {
private final DevicePictureService pictures = mock(DevicePictureService.class);
private final DeviceAlbumController controller = new DeviceAlbumController(pictures);
@Test
void listUsesAuthenticatedDeviceAndRetainsFavoriteState() {
DevicePictureVO photo = new DevicePictureVO();
photo.setUrl("https://example.com/photo.jpg");
photo.setFavorite(1);
when(pictures.listPictures("device-a")).thenReturn(List.of(photo));
assertThat(controller.list("device-a").getData()).containsExactly(photo);
verify(pictures).listPictures("device-a");
verifyNoMoreInteractions(pictures);
}
@Test
void favoriteAndDeleteUseAuthenticatedDeviceAndExactUrl() {
String url = "https://example.com/photo.jpg?key=a%2Bb";
when(pictures.updateFavorite("device-a", url, true)).thenReturn(true);
assertThat(controller.favorite("device-a", url, 1).getCode()).isEqualTo(ResultCode.SUCCESS.getCode());
controller.delete("device-a", url);
verify(pictures).updateFavorite("device-a", url, true);
verify(pictures).deletePicture("device-a", url);
verifyNoMoreInteractions(pictures);
}
@Test
void missingPictureDoesNotReportFavoriteSuccess() {
assertThat(controller.favorite("device-a", "missing", 0).getCode()).isNotEqualTo(ResultCode.SUCCESS.getCode());
}
@Test
void mutationRejectsBlankIdentityAndInvalidFavorite() throws Exception {
try (var factory = Validation.buildDefaultValidatorFactory()) {
var validator = factory.getValidator().forExecutables();
var method = DeviceAlbumController.class.getMethod("favorite", String.class, String.class, Integer.class);
assertThat(validator.validateParameters(controller, method, new Object[]{"device-a", "url", 2})).isNotEmpty();
assertThat(validator.validateParameters(controller, method, new Object[]{"", " ", 1})).hasSize(2);
assertThat(validator.validateParameters(controller, method, new Object[]{"device-a", "url", 0})).isEmpty();
}
}
}