Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f375def613 | ||
|
|
af43657b5b | ||
|
|
526b73b4f8 | ||
|
|
d9db98849a | ||
|
|
6c3645ba15 | ||
|
|
43a5e2ab2f | ||
|
|
739256424f | ||
|
|
3c839ad8ca | ||
|
|
efbd5b3d72 | ||
|
|
5ba7e684fa | ||
|
|
f7c1726d51 | ||
|
|
5504abe3e0 | ||
|
|
5aeec0cfe4 | ||
|
|
e2fe41c2e0 | ||
|
|
48f485b378 | ||
|
|
6ee8fb65c3 | ||
|
|
2106bf4d94 | ||
|
|
72cef158a1 |
@@ -1,7 +1,7 @@
|
||||
# This workflow will build a package using Maven and then publish it to GitHub packages when a release is created
|
||||
# For more information see: https://github.com/actions/setup-java#apache-maven-with-a-settings-path
|
||||
|
||||
name: Blog backEnd CI
|
||||
name: Deplay
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
java-version: 1.8
|
||||
|
||||
- name: Build jar file
|
||||
run: echo $APPLICATION_PROPERTIES_TEST|base64 -d > src/main/resources/application-test.properties && echo $APPLICATION_PROPERTIES_PROD|base64 -d> src/main/resources/application-prod.properties && mvn -B package --file pom.xml
|
||||
run: echo $APPLICATION_PROPERTIES_PROD|base64 -d> src/main/resources/application-prod.properties && mvn -B package --file pom.xml
|
||||
|
||||
- name: SCP
|
||||
uses: appleboy/scp-action@master
|
||||
29
.github/workflows/test.yml
vendored
Normal file
29
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# This workflow will build a package using Maven and then publish it to GitHub packages when a release is created
|
||||
# For more information see: https://github.com/actions/setup-java#apache-maven-with-a-settings-path
|
||||
|
||||
name: pr Test
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
APPLICATION_PROPERTIES_TEST: ${{ secrets.APPLICATION_PROPERTIES_TEST }}
|
||||
APPLICATION_PROPERTIES_PROD: ${{ secrets.APPLICATION_PROPERTIES_PROD }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
|
||||
- name: Test
|
||||
run: echo $APPLICATION_PROPERTIES_TEST|base64 -d > src/main/resources/application-test.properties && mvn -B test --file pom.xml
|
||||
|
||||
|
||||
76
blog.sql
76
blog.sql
@@ -1,6 +1,30 @@
|
||||
CREATE DATABASE `t_blog`;
|
||||
CREATE DATABASE if not exists `blog`;
|
||||
|
||||
USE t_blog;
|
||||
USE blog;
|
||||
|
||||
CREATE TABLE `user`
|
||||
(
|
||||
`u_id` int not null primary key auto_increment,
|
||||
`u_email` varchar(50) not null,
|
||||
`u_pwd` varchar(40) not null comment '密码',
|
||||
`u_email_status` boolean default false comment '邮箱验证状态',
|
||||
`u_avatar` varchar(255) default null comment '用户头像',
|
||||
`u_desc` tinytext COLLATE utf8mb4_unicode_ci default null comment '用户的描述',
|
||||
`u_recently_landed_time` datetime default null comment '最近的登录时间',
|
||||
`u_display_name` varchar(30) COLLATE utf8mb4_unicode_ci default null comment '展示的昵称',
|
||||
`u_role` varchar(40) not null default 'user' comment '权限组',
|
||||
`status` tinyint(1) not null default 0 comment '账户状态',
|
||||
unique key `uni_user_id` (`u_id`),
|
||||
unique key `uni_user_email` (`u_email`)
|
||||
) comment '用户表';
|
||||
|
||||
CREATE TABLE `tag_category`
|
||||
(
|
||||
`t_id` bigint(20) primary key auto_increment,
|
||||
`t_name` varchar(255) not null,
|
||||
`is_category` boolean not null default true,
|
||||
`is_delete` boolean not null default false comment '该数据是否被删除'
|
||||
) comment '标签和分类表';
|
||||
|
||||
CREATE TABLE `article`
|
||||
(
|
||||
@@ -14,30 +38,25 @@ CREATE TABLE `article`
|
||||
`a_reading_number` int default 0 comment '文章阅读数',
|
||||
`a_like` int default 0 comment '文章点赞数',
|
||||
`a_dislike` int default 0 comment '文章不喜欢数',
|
||||
`a_category_id` int not null comment '文章分类id',
|
||||
`a_category_id` bigint not null comment '文章分类id',
|
||||
`a_publish_date` datetime default CURRENT_TIMESTAMP comment '文章发布时间',
|
||||
`a_update_date` datetime default null comment '文章的更新时间',
|
||||
`a_is_open` boolean default true comment '文章是否可见',
|
||||
`is_delete` boolean not null default false comment '该数据是否被删除'
|
||||
`is_delete` boolean not null default false comment '该数据是否被删除',
|
||||
foreign key (a_category_id) references tag_category (t_id),
|
||||
foreign key (a_author_id) references user (u_id)
|
||||
) DEFAULT CHARSET = utf8mb4
|
||||
COLLATE utf8mb4_general_ci,comment '文章表';
|
||||
|
||||
CREATE TABLE `article_tag`
|
||||
(
|
||||
`at_id` bigint(20) primary key auto_increment,
|
||||
`a_id` bigint(20) not null comment '文章id',
|
||||
`t_id` bigint not null comment 'tag/category 的id',
|
||||
`is_delete` boolean not null default false comment '该数据是否被删除'
|
||||
`at_id` bigint(20) primary key auto_increment,
|
||||
`a_id` bigint(20) not null comment '文章id',
|
||||
`t_id` bigint not null comment 'tag/category 的id',
|
||||
foreign key (a_id) references article (a_id),
|
||||
foreign key (t_id) references tag_category (t_id)
|
||||
) comment '文章标签表';
|
||||
|
||||
CREATE TABLE `tag_category`
|
||||
(
|
||||
`t_id` bigint(20) primary key auto_increment,
|
||||
`t_name` varchar(255) not null,
|
||||
`is_category` boolean not null default true,
|
||||
`is_delete` boolean not null default false comment '该数据是否被删除'
|
||||
) comment '标签和分类表';
|
||||
|
||||
CREATE TABLE `comment`
|
||||
(
|
||||
`co_id` bigint(20) primary key auto_increment,
|
||||
@@ -79,23 +98,6 @@ CREATE TABLE `web_update`
|
||||
`is_delete` boolean not null default false comment '该数据是否被删除'
|
||||
) comment '更新内容表';
|
||||
|
||||
CREATE TABLE `user`
|
||||
(
|
||||
`u_id` int not null primary key auto_increment,
|
||||
`u_email` varchar(50) not null,
|
||||
`u_pwd` varchar(40) not null comment '密码',
|
||||
`u_email_status` boolean default false comment '邮箱验证状态',
|
||||
`u_avatar` varchar(255) default null comment '用户头像',
|
||||
`u_desc` tinytext COLLATE utf8mb4_unicode_ci default null comment '用户的描述',
|
||||
`u_recently_landed_time` datetime default null comment '最近的登录时间',
|
||||
`u_display_name` varchar(30) COLLATE utf8mb4_unicode_ci default null comment '展示的昵称',
|
||||
`u_role` varchar(40) not null default 'user' comment '权限组',
|
||||
`status` tinyint(1) not null default 0 comment '账户状态',
|
||||
unique key `uni_user_id` (`u_id`),
|
||||
unique key `uni_user_email` (`u_email`)
|
||||
) comment '用户表';
|
||||
|
||||
|
||||
CREATE VIEW articleView
|
||||
(articleId, title, summary, mdContent, url, isOriginal, readingCount, likeCount, dislikeCount,
|
||||
publishDate, updateDate, isOpen,
|
||||
@@ -139,7 +141,7 @@ where article.a_id = article_tag.a_id
|
||||
CREATE VIEW commentView
|
||||
(commentId, pagePath, content, date, status, pid, toAuthorId, toAuthorEmail, toAuthorDisplayName,
|
||||
toAuthorAvatar, fromAuthorId, fromAuthorEmail, fromAuthorDisplayName,
|
||||
fromAuthorAvatar, isDelete)
|
||||
fromAuthorAvatar)
|
||||
as
|
||||
select cuT.co_id as commentId,
|
||||
cuT.co_page_path as pagePath,
|
||||
@@ -154,8 +156,7 @@ select cuT.co_id as commentId,
|
||||
userFrom.u_id as fromAuthorId,
|
||||
userFrom.u_email as fromAuthorEmail,
|
||||
userFrom.u_display_name as fromAuthorDisplayName,
|
||||
userFrom.u_avatar as fromAuthorAvatar,
|
||||
cuT.is_delete as isDelete
|
||||
userFrom.u_avatar as fromAuthorAvatar
|
||||
from (select comment.co_id,
|
||||
comment.co_page_path,
|
||||
comment.co_content,
|
||||
@@ -166,8 +167,7 @@ from (select comment.co_id,
|
||||
comment.co_to_author_id,
|
||||
userTo.u_email as toEmail,
|
||||
userTo.u_display_name as toDisplayName,
|
||||
userTo.u_avatar as toAvatar,
|
||||
comment.is_delete
|
||||
userTo.u_avatar as toAvatar
|
||||
from comment
|
||||
left join user userTo on (comment.co_to_author_id = userTo.u_id)
|
||||
) as cuT,
|
||||
|
||||
8
pom.xml
8
pom.xml
@@ -55,12 +55,12 @@
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>2.6.1</version>
|
||||
<version>2.9.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>2.6.1</version>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>swagger-bootstrap-ui</artifactId>
|
||||
<version>1.9.6</version>
|
||||
</dependency>
|
||||
|
||||
<!--MarkDown 2 html -->
|
||||
|
||||
@@ -26,7 +26,7 @@ public class CorsConfig {
|
||||
config.addAllowedOrigin("https://celess.cn");
|
||||
config.addAllowedOrigin("https://www.celess.cn");
|
||||
// 本地调试时的跨域
|
||||
if ("dev".equals(activeModel)) {
|
||||
if (!"prod".equals(activeModel)) {
|
||||
config.addAllowedOrigin("http://localhost:4200");
|
||||
config.addAllowedOrigin("http://127.0.0.1:4200");
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
@@ -25,7 +26,7 @@ public class SwaggerConfig {
|
||||
@Bean
|
||||
public Docket createRestApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.enable("dev".equals(environment))
|
||||
.enable(!"prod".equals(environment))
|
||||
.apiInfo(apiInfo())
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("cn.celess.blog"))
|
||||
@@ -37,7 +38,7 @@ public class SwaggerConfig {
|
||||
return new ApiInfoBuilder()
|
||||
.title("小海博客的APi")
|
||||
.description("小海博客的APi")
|
||||
.contact("小海")
|
||||
.contact(new Contact("小海", "https://www.celess.cn", "a@celess.cn"))
|
||||
.version("1.0")
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -56,10 +56,13 @@ public class AuthenticationFilter implements HandlerInterceptor {
|
||||
return writeResponse(ResponseEnum.LOGIN_EXPIRED, response, request);
|
||||
}
|
||||
String email = jwtUtil.getUsernameFromToken(jwtStr);
|
||||
if (!redisUtil.hasKey(email + "-login") || jwtUtil.isTokenExpired(jwtStr)) {
|
||||
if (jwtUtil.isTokenExpired(jwtStr)) {
|
||||
// 登陆过期
|
||||
return writeResponse(ResponseEnum.LOGIN_EXPIRED, response, request);
|
||||
}
|
||||
if (!redisUtil.hasKey(email + "-login")) {
|
||||
return writeResponse(ResponseEnum.LOGOUT, response, request);
|
||||
}
|
||||
String role = userService.getUserRoleByEmail(email);
|
||||
if (role.equals(ROLE_USER) || role.equals(ROLE_ADMIN)) {
|
||||
// 更新token
|
||||
|
||||
@@ -3,6 +3,7 @@ package cn.celess.blog.controller;
|
||||
import cn.celess.blog.enmu.ResponseEnum;
|
||||
import cn.celess.blog.entity.Response;
|
||||
import cn.celess.blog.entity.model.ArticleModel;
|
||||
import cn.celess.blog.entity.model.PageData;
|
||||
import cn.celess.blog.entity.request.ArticleReq;
|
||||
import cn.celess.blog.service.ArticleService;
|
||||
import cn.celess.blog.util.RedisUserUtil;
|
||||
@@ -11,6 +12,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
@@ -110,8 +113,9 @@ public class ArticleController {
|
||||
*/
|
||||
@GetMapping("/admin/articles")
|
||||
public Response adminArticles(@RequestParam(name = "page", defaultValue = "1") int page,
|
||||
@RequestParam(name = "count", defaultValue = "10") int count) {
|
||||
return Response.success(articleService.adminArticles(count, page));
|
||||
@RequestParam(name = "count", defaultValue = "10") int count,
|
||||
@RequestParam(name = "deleted", defaultValue = "false") boolean deleted) {
|
||||
return Response.success(articleService.adminArticles(count, page, deleted));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,7 +37,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* @date : 2019/04/02 22:03
|
||||
*/
|
||||
@RestController
|
||||
public class Other {
|
||||
public class CommonController {
|
||||
public static final Logger logger = LoggerFactory.getLogger(Object.class);
|
||||
|
||||
@Autowired
|
||||
@@ -33,6 +33,7 @@ public enum ResponseEnum {
|
||||
PWD_SAME(3601, "新密码与原密码相同"),
|
||||
PWD_NOT_SAME(3602, "新密码与原密码不相同"),
|
||||
LOGIN_EXPIRED(3700, "登陆过期"),
|
||||
LOGOUT(3710, "账户已注销"),
|
||||
PWD_WRONG(3800, "密码不正确"),
|
||||
|
||||
JWT_EXPIRED(3810, "Token过期"),
|
||||
|
||||
@@ -11,15 +11,15 @@ import java.io.Serializable;
|
||||
* @date : 2019/03/28 15:24
|
||||
*/
|
||||
@Data
|
||||
public class Response implements Serializable {
|
||||
public class Response<T> implements Serializable {
|
||||
private int code;
|
||||
private String msg;
|
||||
private Object result;
|
||||
private T result;
|
||||
|
||||
public Response() {
|
||||
}
|
||||
|
||||
public Response(int code, String msg, Object result) {
|
||||
public Response(int code, String msg, T result) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.result = result;
|
||||
|
||||
@@ -82,4 +82,6 @@ public class ArticleModel {
|
||||
* 文章的状态 true:公开 false:不公开
|
||||
*/
|
||||
private Boolean open;
|
||||
|
||||
private boolean deleted;
|
||||
}
|
||||
|
||||
@@ -20,4 +20,5 @@ public class CategoryModel {
|
||||
private String name;
|
||||
|
||||
private List<ArticleModel> articles;
|
||||
private boolean deleted;
|
||||
}
|
||||
|
||||
@@ -21,4 +21,5 @@ public class TagModel {
|
||||
|
||||
private List<ArticleModel> articles;
|
||||
|
||||
private boolean deleted;
|
||||
}
|
||||
|
||||
@@ -37,4 +37,6 @@ public class UserModel {
|
||||
private String role = "user";
|
||||
|
||||
private String token;
|
||||
|
||||
private int status;
|
||||
}
|
||||
|
||||
@@ -21,4 +21,6 @@ public class WebUpdateModel {
|
||||
this.info = info;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
private boolean deleted;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public interface ArticleService {
|
||||
* @param page 数据页
|
||||
* @return 分页数据
|
||||
*/
|
||||
PageData<ArticleModel> adminArticles(int count, int page);
|
||||
PageData<ArticleModel> adminArticles(int count, int page, boolean deleted);
|
||||
|
||||
/**
|
||||
* 获取文章状态为开放的文章
|
||||
|
||||
@@ -22,10 +22,12 @@ import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import sun.security.krb5.internal.PAData;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
@@ -145,7 +147,7 @@ public class ArticleServiceImpl implements ArticleService {
|
||||
//删除指定文章
|
||||
articleMapper.delete(articleId);
|
||||
|
||||
articleTagMapper.deleteByArticleId(articleId);
|
||||
//articleTagMapper.deleteByArticleId(articleId);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -273,21 +275,24 @@ public class ArticleServiceImpl implements ArticleService {
|
||||
|
||||
/**
|
||||
* @param count 数目
|
||||
* @param page 页面 默认减1
|
||||
* @param page 页面
|
||||
* @return PageInfo
|
||||
*/
|
||||
@Override
|
||||
public PageData<ArticleModel> adminArticles(int count, int page) {
|
||||
PageHelper.startPage(page, count, "articleId desc");
|
||||
public PageData<ArticleModel> adminArticles(int count, int page, boolean deleted) {
|
||||
List<Article> articleList = articleMapper.findAll();
|
||||
PageData<ArticleModel> pageData = new PageData<ArticleModel>(new PageInfo<Article>(articleList));
|
||||
List<ArticleModel> articleModelList = new ArrayList<>();
|
||||
articleList.forEach(article -> {
|
||||
ArticleModel articleModel = ModalTrans.article(article);
|
||||
articleModel.setMdContent(null);
|
||||
articleModelList.add(articleModel);
|
||||
});
|
||||
pageData.setList(articleModelList);
|
||||
|
||||
PageData<ArticleModel> pageData = new PageData<>(null, 0, count, page);
|
||||
List<Article> collect = articleList.stream().filter(article -> article.isDeleted() == deleted).collect(Collectors.toList());
|
||||
pageData.setTotal(collect.size());
|
||||
List<ArticleModel> articleModels = collect.stream()
|
||||
.peek(article -> article.setMdContent(null))
|
||||
.map(ModalTrans::article)
|
||||
.skip((page - 1) * count)
|
||||
.limit(count)
|
||||
.collect(Collectors.toList());
|
||||
pageData.setList(articleModels);
|
||||
|
||||
return pageData;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,12 @@ public class PartnerSiteServiceImpl implements PartnerSiteService {
|
||||
reqBody.setUrl("http://" + reqBody.getUrl());
|
||||
}
|
||||
BeanUtils.copyProperties(reqBody, partnerSite);
|
||||
if (reqBody.getIconPath() == null) {
|
||||
partnerSite.setIconPath("");
|
||||
}
|
||||
if (reqBody.getDesc() == null) {
|
||||
partnerSite.setDesc("");
|
||||
}
|
||||
partnerMapper.insert(partnerSite);
|
||||
return partnerSite;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author: 小海
|
||||
@@ -99,7 +100,7 @@ public class SitemapGenerateUtil {
|
||||
urlList.put("https://www.celess.cn", DateFormatUtil.getForXmlDate(new Date()));
|
||||
urlList.put("https://www.celess.cn/links", DateFormatUtil.getForXmlDate(new Date()));
|
||||
urlList.put("https://www.celess.cn/leaveMsg", DateFormatUtil.getForXmlDate(new Date()));
|
||||
List<Article> articles = articleMapper.findAll();
|
||||
List<Article> articles = articleMapper.findAll().stream().filter(article -> article.getOpen()&&!article.isDeleted()).collect(Collectors.toList());
|
||||
articles.forEach(article -> {
|
||||
urlList.put("https://www.celess.cn/article/" + article.getId(), DateFormatUtil.getForXmlDate(
|
||||
article.getUpdateDate() == null ? article.getPublishDate() : article.getUpdateDate()));
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
|
||||
|
||||
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into comment (co_page_path, co_content, co_date, co_pid, co_from_author_id, co_to_author_id, is_delete)
|
||||
VALUES (#{pagePath}, #{content}, now(), #{pid}, #{fromUser.id}, #{toUser.id}, false)
|
||||
insert into comment (co_page_path, co_content, co_date, co_pid, co_from_author_id, co_to_author_id, co_status)
|
||||
VALUES (#{pagePath}, #{content}, now(), #{pid}, #{fromUser.id}, #{toUser.id}, 0)
|
||||
</insert>
|
||||
|
||||
<update id="updateContent">
|
||||
@@ -84,7 +84,6 @@
|
||||
<select id="findAllByPagePath" resultMap="commentViewResultMap" parameterType="string">
|
||||
select *
|
||||
from commentView
|
||||
# 无奈之举
|
||||
<if test="toString() != null ">
|
||||
where pagePath = #{pagePath}
|
||||
</if>
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
<select id="findAll" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where isDelete = false
|
||||
order by articleId desc
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
@@ -1,30 +1,37 @@
|
||||
package cn.celess.blog;
|
||||
|
||||
|
||||
import cn.celess.blog.entity.Response;
|
||||
import cn.celess.blog.entity.model.UserModel;
|
||||
import cn.celess.blog.entity.request.LoginReq;
|
||||
import net.sf.json.JSONObject;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.After;
|
||||
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.context.SpringBootTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.ResultHandler;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static cn.celess.blog.enmu.ResponseEnum.SUCCESS;
|
||||
import static org.junit.Assert.*;
|
||||
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.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @Author: 小海
|
||||
@@ -40,6 +47,12 @@ public class BaseTest {
|
||||
protected MockMvc mockMvc;
|
||||
protected final static String Code = "code";
|
||||
protected final static String Result = "result";
|
||||
private static String userToken = null;
|
||||
private static String adminToken = null;
|
||||
/**
|
||||
* jackson 序列化/反序列化Json
|
||||
*/
|
||||
protected final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext wac;
|
||||
@@ -57,51 +70,125 @@ public class BaseTest {
|
||||
System.out.println("==========> 测试结束 <=========");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* admin 权限用户登录
|
||||
*
|
||||
* @return token
|
||||
*/
|
||||
protected String adminLogin() {
|
||||
try {
|
||||
LoginReq req = new LoginReq();
|
||||
req.setEmail("a@celess.cn");
|
||||
req.setPassword("123456789");
|
||||
req.setIsRememberMe(false);
|
||||
JSONObject loginReq = JSONObject.fromObject(req);
|
||||
String str = mockMvc.perform(MockMvcRequestBuilders.post("/login").content(loginReq.toString()).contentType("application/json"))
|
||||
// .andDo(MockMvcResultHandlers.print())
|
||||
.andReturn().getResponse().getContentAsString();
|
||||
String token = JSONObject.fromObject(str).getJSONObject(Result).getString("token");
|
||||
assertNotNull(token);
|
||||
return token;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
if (adminToken != null) return adminToken;
|
||||
LoginReq req = new LoginReq();
|
||||
req.setEmail("a@celess.cn");
|
||||
req.setPassword("123456789");
|
||||
req.setIsRememberMe(false);
|
||||
adminToken = login(req);
|
||||
assertNotNull(adminToken);
|
||||
return adminToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* user 权限用户登录
|
||||
*
|
||||
* @return token
|
||||
*/
|
||||
protected String userLogin() {
|
||||
if (userToken != null) return userToken;
|
||||
LoginReq req = new LoginReq();
|
||||
req.setEmail("zh56462271@qq.com");
|
||||
req.setPassword("123456789");
|
||||
req.setIsRememberMe(false);
|
||||
userToken = login(req);
|
||||
assertNotNull(userToken);
|
||||
return userToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录逻辑
|
||||
*
|
||||
* @param req 用户信息
|
||||
* @return token | null
|
||||
*/
|
||||
private String login(LoginReq req) {
|
||||
String str = null;
|
||||
try {
|
||||
LoginReq req = new LoginReq();
|
||||
req.setEmail("zh56462271@qq.com");
|
||||
req.setPassword("123456789");
|
||||
req.setIsRememberMe(false);
|
||||
JSONObject loginReq = JSONObject.fromObject(req);
|
||||
String str = mockMvc.perform(MockMvcRequestBuilders.post("/login").content(loginReq.toString()).contentType("application/json"))
|
||||
// .andDo(MockMvcResultHandlers.print())
|
||||
str = getMockData(post("/login"), null, req)
|
||||
.andReturn().getResponse().getContentAsString();
|
||||
String token = JSONObject.fromObject(str).getJSONObject(Result).getString("token");
|
||||
Response<UserModel> response = mapper.readValue(str, new TypeReference<Response<UserModel>>() {
|
||||
});
|
||||
assertEquals(SUCCESS.getCode(), response.getCode());
|
||||
String token = response.getResult().getToken();
|
||||
assertNotNull(token);
|
||||
return token;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
// 测试登录
|
||||
assertNotNull(userLogin());
|
||||
assertNotNull(adminLogin());
|
||||
try {
|
||||
// 测试getMockData方法
|
||||
assertNotNull(getMockData(get("/headerInfo")));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 产生指定长度的随机字符
|
||||
*
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
protected String randomStr(int len) {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, len);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 抽离的mock请求方法
|
||||
*
|
||||
* @param builder MockHttpServletRequestBuilder :get(...) post(...) ....
|
||||
* @return 返回 ResultActions
|
||||
* @throws Exception exc
|
||||
*/
|
||||
protected ResultActions getMockData(MockHttpServletRequestBuilder builder) throws Exception {
|
||||
return getMockData(builder, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 抽离的mock请求方法 重载
|
||||
*
|
||||
* @param builder ..
|
||||
* @param token 用户登录的token
|
||||
* @return ..
|
||||
* @throws Exception ..
|
||||
*/
|
||||
protected ResultActions getMockData(MockHttpServletRequestBuilder builder, String token) throws Exception {
|
||||
return getMockData(builder, token, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 抽离的mock请求方法 重载
|
||||
*
|
||||
* @param builder ..
|
||||
* @param token ..
|
||||
* @param content http中发送的APPLICATION_JSON的json数据
|
||||
* @return ..
|
||||
* @throws Exception ..
|
||||
*/
|
||||
protected ResultActions getMockData(MockHttpServletRequestBuilder builder, String token, Object content) throws Exception {
|
||||
// MockHttpServletRequestBuilder mockHttpServletRequestBuilder = get(url);
|
||||
if (token != null) {
|
||||
builder.header("Authorization", token);
|
||||
}
|
||||
if (content != null) {
|
||||
builder.content(mapper.writeValueAsString(content)).contentType(MediaType.APPLICATION_JSON);
|
||||
}
|
||||
return mockMvc.perform(builder).andExpect(status().isOk());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import cn.celess.blog.entity.model.ArticleModel;
|
||||
import cn.celess.blog.entity.model.PageData;
|
||||
import cn.celess.blog.entity.request.ArticleReq;
|
||||
import cn.celess.blog.mapper.ArticleMapper;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import net.sf.json.JSONObject;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -260,55 +262,43 @@ public class ArticleControllerTest extends BaseTest {
|
||||
|
||||
@Test
|
||||
public void adminArticles() {
|
||||
String token;
|
||||
try {
|
||||
// 未登录
|
||||
mockMvc.perform(get("/admin/articles?page=1&count=10"))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(result -> {
|
||||
assertEquals(HAVE_NOT_LOG_IN.getCode(),
|
||||
JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code)
|
||||
);
|
||||
});
|
||||
getMockData(get("/admin/articles?page=1&count=10")).andExpect(result ->
|
||||
assertEquals(HAVE_NOT_LOG_IN.getCode(), mapper.readValue(result.getResponse().getContentAsString(), Response.class).getCode())
|
||||
);
|
||||
|
||||
// User权限登陆
|
||||
token = userLogin();
|
||||
mockMvc.perform(get("/admin/articles?page=1&count=10")
|
||||
.header("Authorization", token))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(result -> {
|
||||
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
|
||||
assertEquals(PERMISSION_ERROR.getCode(), object.getInt(Code));
|
||||
});
|
||||
|
||||
token = adminLogin();
|
||||
// admin权限登陆
|
||||
mockMvc.perform(get("/admin/articles?page=1&count=10")
|
||||
.header("Authorization", token))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(result -> {
|
||||
JSONObject adminLogin = JSONObject.fromObject(result.getResponse().getContentAsString());
|
||||
assertEquals(SUCCESS.getCode(), adminLogin.getInt(Code));
|
||||
assertNotNull(adminLogin.getString(Result));
|
||||
// 判断pageInfo是否包装完全
|
||||
PageData<ArticleModel> pageData = (PageData<ArticleModel>) JSONObject.toBean(adminLogin.getJSONObject(Result), PageData.class);
|
||||
assertNotEquals(0, pageData.getTotal());
|
||||
assertEquals(1, pageData.getPageNum());
|
||||
assertEquals(10, pageData.getPageSize());
|
||||
// 内容完整
|
||||
for (Object arc : pageData.getList()) {
|
||||
ArticleModel a = (ArticleModel) JSONObject.toBean(JSONObject.fromObject(arc), ArticleModel.class);
|
||||
assertNotNull(a.getTitle());
|
||||
assertNotNull(a.getId());
|
||||
assertNotNull(a.getOriginal());
|
||||
assertNotNull(a.getPublishDateFormat());
|
||||
assertNotNull(a.getOpen());
|
||||
assertNotNull(a.getReadingNumber());
|
||||
assertNotNull(a.getLikeCount());
|
||||
assertNotNull(a.getDislikeCount());
|
||||
assertNull(a.getMdContent());
|
||||
}
|
||||
getMockData(get("/admin/articles?page=1&count=10"), userLogin()).andDo(result ->
|
||||
assertEquals(PERMISSION_ERROR.getCode(), mapper.readValue(result.getResponse().getContentAsString(), Response.class).getCode())
|
||||
);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// admin权限登陆
|
||||
int finalI = i;
|
||||
getMockData(get("/admin/articles?page=1&count=10&deleted=" + (i == 1)), adminLogin()).andDo(result -> {
|
||||
Response<PageData<ArticleModel>> response = mapper.readValue(result.getResponse().getContentAsString(), new TypeReference<Response<PageData<ArticleModel>>>() {
|
||||
});
|
||||
assertEquals(SUCCESS.getCode(), response.getCode());
|
||||
assertNotNull(response.getResult());
|
||||
// 判断pageInfo是否包装完全
|
||||
PageData<ArticleModel> pageData = response.getResult();
|
||||
assertNotEquals(0, pageData.getTotal());
|
||||
assertEquals(1, pageData.getPageNum());
|
||||
assertEquals(10, pageData.getPageSize());
|
||||
// 内容完整
|
||||
for (ArticleModel a : pageData.getList()) {
|
||||
assertNotNull(a.getTitle());
|
||||
assertNotNull(a.getId());
|
||||
assertNotNull(a.getOriginal());
|
||||
assertNotNull(a.getPublishDateFormat());
|
||||
assertNotNull(a.getOpen());
|
||||
assertNotNull(a.getReadingNumber());
|
||||
assertNotNull(a.getLikeCount());
|
||||
assertNotNull(a.getDislikeCount());
|
||||
assertEquals((finalI == 1), a.isDeleted());
|
||||
assertNull(a.getMdContent());
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -75,10 +75,8 @@ public class ArticleTagMapperTest extends BaseTest {
|
||||
@Test
|
||||
public void deleteMultiById() {
|
||||
ArticleTag articleTag = new ArticleTag();
|
||||
Article article = new Article();
|
||||
article.setId(-1L);
|
||||
Tag tag = new Tag();
|
||||
tag.setId(1L);
|
||||
Article article = articleMapper.getLastestArticle();
|
||||
Tag tag = tagMapper.getLastestTag();
|
||||
articleTag.setArticle(article);
|
||||
articleTag.setTag(tag);
|
||||
|
||||
@@ -89,7 +87,7 @@ public class ArticleTagMapperTest extends BaseTest {
|
||||
articleTagMapper.insert(articleTag);
|
||||
articleTagMapper.insert(articleTag);
|
||||
|
||||
List<ArticleTag> allByArticleId = articleTagMapper.findAllByArticleId(-1L);
|
||||
List<ArticleTag> allByArticleId = articleTagMapper.findAllByArticleId(article.getId());
|
||||
assertTrue(allByArticleId.size() >= 6);
|
||||
int lines = articleTagMapper.deleteMultiById(allByArticleId);
|
||||
assertTrue(lines >= 6);
|
||||
|
||||
Reference in New Issue
Block a user