init local code
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
package com.yunhai.cms.service.impl;
|
||||
|
||||
import com.yunhai.cms.model.dto.DeleteRequest;
|
||||
import com.yunhai.cms.model.dto.LinkSaveRequest;
|
||||
import com.yunhai.cms.model.vo.LinkVo;
|
||||
import com.yunhai.cms.support.CmsIntegrationTestBase;
|
||||
import com.yunhai.cms.support.TestUsers;
|
||||
import com.yunhai.platform.apistd.BizException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* 友情链接管理集成测试(方案 §5.1 表6 / §9.2)。
|
||||
*/
|
||||
@DisplayName("LinkService - 友情链接管理")
|
||||
@Transactional
|
||||
class LinkServiceIT extends CmsIntegrationTestBase {
|
||||
|
||||
@Autowired
|
||||
private LinkService linkService;
|
||||
|
||||
private Integer siteId;
|
||||
|
||||
@BeforeEach
|
||||
void seed() {
|
||||
siteId = persistSite("demo1", 1, "演示站点一").getId();
|
||||
}
|
||||
|
||||
private LinkSaveRequest req(String name, String url) {
|
||||
LinkSaveRequest r = new LinkSaveRequest();
|
||||
r.setSiteId(siteId);
|
||||
r.setName(name);
|
||||
r.setLinkUrl(url);
|
||||
return r;
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("保存友链:http/https/站内相对路径均接受;分组与默认值生效")
|
||||
void save_urlSchemesAndDefaults() {
|
||||
assertThat(linkService.save(TestUsers.superAdmin(), req("教育部", "http://www.moe.gov.cn")).getId())
|
||||
.isNotNull();
|
||||
assertThat(linkService.save(TestUsers.superAdmin(), req("兄弟院校", "https://www.pku.edu.cn")).getId())
|
||||
.isNotNull();
|
||||
|
||||
LinkVo relative = linkService.save(TestUsers.superAdmin(), req("站内页", "/cms/portal/demo1/"));
|
||||
assertThat(relative.getGroupName()).isEqualTo("default"); // 分组缺省
|
||||
assertThat(relative.getSortNo()).isZero();
|
||||
assertThat(relative.getStatus()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("保存友链:javascript: 等非法协议与空地址被拒")
|
||||
void save_invalidUrlRejected() {
|
||||
assertThatThrownBy(() -> linkService.save(
|
||||
TestUsers.superAdmin(), req("危险链", "javascript:alert(1)")))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("http");
|
||||
assertThatThrownBy(() -> linkService.save(TestUsers.superAdmin(), req("空链", "")))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("http");
|
||||
assertThatThrownBy(() -> linkService.save(
|
||||
TestUsers.superAdmin(), req("数据协议", "data:text/html,<script>")))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("http");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("列表按分组名+组内排序返回全量(含隐藏,供管理端)")
|
||||
void list_orderedByGroupAndSort() {
|
||||
LinkSaveRequest b = req("B链", "https://b.example.com");
|
||||
b.setGroupName("上级部门");
|
||||
b.setSortNo(2);
|
||||
linkService.save(TestUsers.superAdmin(), b);
|
||||
|
||||
LinkSaveRequest a = req("A链", "https://a.example.com");
|
||||
a.setGroupName("上级部门");
|
||||
a.setSortNo(1);
|
||||
linkService.save(TestUsers.superAdmin(), a);
|
||||
|
||||
LinkSaveRequest coop = req("合作单位链", "https://c.example.com");
|
||||
coop.setGroupName("合作单位");
|
||||
linkService.save(TestUsers.superAdmin(), coop);
|
||||
|
||||
LinkSaveRequest hidden = req("隐藏链", "https://h.example.com");
|
||||
hidden.setStatus(0);
|
||||
linkService.save(TestUsers.superAdmin(), hidden);
|
||||
|
||||
List<LinkVo> list = linkService.list(TestUsers.superAdmin(), siteId);
|
||||
// 分组名升序走 MySQL utf8mb4_general_ci:ASCII "default" < 中文(上 U+4E0A < 合 U+5408)
|
||||
assertThat(list).extracting(LinkVo::getName)
|
||||
.containsExactly("隐藏链", "A链", "B链", "合作单位链");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("修改/删除他站友链抛 FORBIDDEN;删除本站成功")
|
||||
void crossSiteAndDelete() {
|
||||
LinkVo own = linkService.save(TestUsers.superAdmin(), req("待删链", "https://x.example.com"));
|
||||
Integer otherSiteId = persistSite("demo2", 2, "演示站点二").getId();
|
||||
|
||||
LinkSaveRequest hijack = req("越权改链", "https://y.example.com");
|
||||
hijack.setId(own.getId());
|
||||
hijack.setSiteId(otherSiteId);
|
||||
assertThatThrownBy(() -> linkService.save(TestUsers.superAdmin(), hijack))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("无权");
|
||||
|
||||
DeleteRequest wrongSite = new DeleteRequest();
|
||||
wrongSite.setSiteId(otherSiteId);
|
||||
wrongSite.setId(own.getId());
|
||||
assertThatThrownBy(() -> linkService.delete(TestUsers.superAdmin(), wrongSite))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("无权");
|
||||
|
||||
DeleteRequest del = new DeleteRequest();
|
||||
del.setSiteId(siteId);
|
||||
del.setId(own.getId());
|
||||
linkService.delete(TestUsers.superAdmin(), del);
|
||||
assertThat(linkRepository.findById(own.getId())).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("删除不存在的友链报错(边界)")
|
||||
void delete_missingRejected() {
|
||||
DeleteRequest del = new DeleteRequest();
|
||||
del.setSiteId(siteId);
|
||||
del.setId(99999);
|
||||
assertThatThrownBy(() -> linkService.delete(TestUsers.superAdmin(), del))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("不存在");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user