From eddb24aa5b948c3103d1d6f245f59449dd1ca64b Mon Sep 17 00:00:00 2001 From: dengqichen Date: Wed, 28 May 2025 11:08:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtest=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=B1=BB=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 16 +++ .../com/zeodao/reminder/util/HolidayUtil.java | 54 ++++---- .../service/TaskReminderServiceTest.java | 126 ++++++++++++------ .../zeodao/reminder/util/HolidayUtilTest.java | 103 ++++++++++++++ 4 files changed, 234 insertions(+), 65 deletions(-) create mode 100644 Dockerfile create mode 100644 src/test/java/com/zeodao/reminder/util/HolidayUtilTest.java diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7d3ebcf --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM eclipse-temurin:21-jre + +COPY ./target/*.jar /app.jar + +ENV TZ=Asia/Shanghai + +EXPOSE 8080 + +## 启动后端项目 +CMD java -Djava.security.egd=file:/dev/./urandom -jar app.jar + + +# docker -H tcp://172.22.222.6:2375 build -t 172.22.222.100:28082/task-reminder:1.0.0 . + +# docker -H tcp://172.22.222.6:2375 push 172.22.222.100:28082/task-reminder:1.0.0 + diff --git a/src/main/java/com/zeodao/reminder/util/HolidayUtil.java b/src/main/java/com/zeodao/reminder/util/HolidayUtil.java index 167968d..687a425 100644 --- a/src/main/java/com/zeodao/reminder/util/HolidayUtil.java +++ b/src/main/java/com/zeodao/reminder/util/HolidayUtil.java @@ -34,42 +34,48 @@ public class HolidayUtil { /** * 初始化2025年节假日 + * 根据国务院办公厅2024年11月12日发布的《关于2025年部分节假日安排的通知》 */ private static void initHolidays2025() { - // 元旦:1月1日 + // 元旦:1月1日(周三)放假1天,不调休 HOLIDAYS_2025.add(LocalDate.of(2025, Month.JANUARY, 1)); - // 春节:1月28日-2月3日(预估,实际以国务院公布为准) - HOLIDAYS_2025.add(LocalDate.of(2025, Month.JANUARY, 28)); - HOLIDAYS_2025.add(LocalDate.of(2025, Month.JANUARY, 29)); - HOLIDAYS_2025.add(LocalDate.of(2025, Month.JANUARY, 30)); - HOLIDAYS_2025.add(LocalDate.of(2025, Month.JANUARY, 31)); - HOLIDAYS_2025.add(LocalDate.of(2025, Month.FEBRUARY, 1)); - HOLIDAYS_2025.add(LocalDate.of(2025, Month.FEBRUARY, 2)); - HOLIDAYS_2025.add(LocalDate.of(2025, Month.FEBRUARY, 3)); + // 春节:1月28日(农历除夕、周二)至2月4日(农历正月初七、周二)放假调休,共8天 + HOLIDAYS_2025.add(LocalDate.of(2025, Month.JANUARY, 28)); // 除夕 + HOLIDAYS_2025.add(LocalDate.of(2025, Month.JANUARY, 29)); // 正月初一 + HOLIDAYS_2025.add(LocalDate.of(2025, Month.JANUARY, 30)); // 正月初二 + HOLIDAYS_2025.add(LocalDate.of(2025, Month.JANUARY, 31)); // 正月初三 + HOLIDAYS_2025.add(LocalDate.of(2025, Month.FEBRUARY, 1)); // 正月初四 + HOLIDAYS_2025.add(LocalDate.of(2025, Month.FEBRUARY, 2)); // 正月初五 + HOLIDAYS_2025.add(LocalDate.of(2025, Month.FEBRUARY, 3)); // 正月初六 + HOLIDAYS_2025.add(LocalDate.of(2025, Month.FEBRUARY, 4)); // 正月初七 - // 清明节:4月5日-7日(预估) - for (int day = 5; day <= 7; day++) { - HOLIDAYS_2025.add(LocalDate.of(2025, Month.APRIL, day)); - } + // 清明节:4月4日(周五)至6日(周日)放假,共3天 + HOLIDAYS_2025.add(LocalDate.of(2025, Month.APRIL, 4)); + HOLIDAYS_2025.add(LocalDate.of(2025, Month.APRIL, 5)); + HOLIDAYS_2025.add(LocalDate.of(2025, Month.APRIL, 6)); - // 劳动节:5月1日-5日(预估) - for (int day = 1; day <= 5; day++) { - HOLIDAYS_2025.add(LocalDate.of(2025, Month.MAY, day)); - } + // 劳动节:5月1日(周四)至5日(周一)放假调休,共5天 + HOLIDAYS_2025.add(LocalDate.of(2025, Month.MAY, 1)); + HOLIDAYS_2025.add(LocalDate.of(2025, Month.MAY, 2)); + HOLIDAYS_2025.add(LocalDate.of(2025, Month.MAY, 3)); + HOLIDAYS_2025.add(LocalDate.of(2025, Month.MAY, 4)); + HOLIDAYS_2025.add(LocalDate.of(2025, Month.MAY, 5)); - // 端午节:5月31日-6月2日(预估) + // 端午节:5月31日(周六)至6月2日(周一)放假,共3天 HOLIDAYS_2025.add(LocalDate.of(2025, Month.MAY, 31)); HOLIDAYS_2025.add(LocalDate.of(2025, Month.JUNE, 1)); HOLIDAYS_2025.add(LocalDate.of(2025, Month.JUNE, 2)); - // 中秋节:10月6日(预估) + // 国庆节、中秋节:10月1日(周三)至8日(周三)放假调休,共8天 + HOLIDAYS_2025.add(LocalDate.of(2025, Month.OCTOBER, 1)); + HOLIDAYS_2025.add(LocalDate.of(2025, Month.OCTOBER, 2)); + HOLIDAYS_2025.add(LocalDate.of(2025, Month.OCTOBER, 3)); + HOLIDAYS_2025.add(LocalDate.of(2025, Month.OCTOBER, 4)); + HOLIDAYS_2025.add(LocalDate.of(2025, Month.OCTOBER, 5)); HOLIDAYS_2025.add(LocalDate.of(2025, Month.OCTOBER, 6)); - - // 国庆节:10月1日-7日 - for (int day = 1; day <= 7; day++) { - HOLIDAYS_2025.add(LocalDate.of(2025, Month.OCTOBER, day)); - } + HOLIDAYS_2025.add(LocalDate.of(2025, Month.OCTOBER, 7)); + HOLIDAYS_2025.add(LocalDate.of(2025, Month.OCTOBER, 8)); } /** diff --git a/src/test/java/com/zeodao/reminder/service/TaskReminderServiceTest.java b/src/test/java/com/zeodao/reminder/service/TaskReminderServiceTest.java index 8b8c927..c11ece8 100644 --- a/src/test/java/com/zeodao/reminder/service/TaskReminderServiceTest.java +++ b/src/test/java/com/zeodao/reminder/service/TaskReminderServiceTest.java @@ -1,5 +1,6 @@ package com.zeodao.reminder.service; +import com.zeodao.reminder.config.TaskReminderConfig; import com.zeodao.reminder.util.HolidayUtil; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -7,19 +8,22 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.test.util.ReflectionTestUtils; import java.time.LocalDate; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; /** * 任务提醒服务测试类 * * @author Zeodao - * @version 1.0.0 + * @version 2.0.0 */ @ExtendWith(MockitoExtension.class) class TaskReminderServiceTest { @@ -30,101 +34,141 @@ class TaskReminderServiceTest { @Mock private HolidayUtil holidayUtil; + @Mock + private TaskReminderConfig taskReminderConfig; + @InjectMocks private TaskReminderService taskReminderService; + private TaskReminderConfig.Group testGroup; + @BeforeEach void setUp() { - // 设置测试用的消息内容 - ReflectionTestUtils.setField(taskReminderService, "morningMessage", "测试早上消息"); - ReflectionTestUtils.setField(taskReminderService, "eveningMessage", "测试晚上消息"); + // 创建测试群组配置 + testGroup = new TaskReminderConfig.Group(); + testGroup.setId("test-group"); + testGroup.setName("测试群组"); + testGroup.setEnabled(true); + + TaskReminderConfig.Webhook webhook = new TaskReminderConfig.Webhook(); + webhook.setUrl("https://test.webhook.url"); + testGroup.setWebhook(webhook); + + Map schedules = new HashMap<>(); + + TaskReminderConfig.Schedule morningSchedule = new TaskReminderConfig.Schedule(); + morningSchedule.setTime("0 0 9 * * MON-FRI"); + morningSchedule.setMessage("测试早上消息"); + schedules.put("morning", morningSchedule); + + TaskReminderConfig.Schedule eveningSchedule = new TaskReminderConfig.Schedule(); + eveningSchedule.setTime("0 30 17 * * MON-FRI"); + eveningSchedule.setMessage("测试晚上消息"); + schedules.put("evening", eveningSchedule); + + testGroup.setSchedules(schedules); } @Test - void testSendMorningReminderOnWorkday() { + void testSendReminderOnWorkday() { // 模拟工作日 when(holidayUtil.isWeekend(any(LocalDate.class))).thenReturn(false); when(holidayUtil.isHoliday(any(LocalDate.class))).thenReturn(false); - when(wechatWebhookService.createTaskReminderMessage(anyString(), anyString())).thenReturn("测试消息"); - when(wechatWebhookService.sendMarkdownMessage(anyString())).thenReturn(true); + when(taskReminderConfig.getGroupById("test-group")).thenReturn(testGroup); + when(wechatWebhookService.createTaskReminderMessage(anyString(), anyString(), anyString())).thenReturn("测试消息"); + when(wechatWebhookService.sendMarkdownMessage(anyString(), anyString())).thenReturn(true); // 执行测试 - taskReminderService.sendMorningReminder(); + taskReminderService.sendReminder("test-group", "morning"); // 验证 - verify(wechatWebhookService, times(1)).sendMarkdownMessage(anyString()); + verify(wechatWebhookService, times(1)).sendMarkdownMessage(eq("test-group"), anyString()); } @Test - void testSendMorningReminderOnWeekend() { + void testSendReminderOnWeekend() { // 模拟周末 when(holidayUtil.isWeekend(any(LocalDate.class))).thenReturn(true); - // 注意:当isWeekend返回true时,不会调用isHoliday方法,所以不需要mock // 执行测试 - taskReminderService.sendMorningReminder(); + taskReminderService.sendReminder("test-group", "morning"); // 验证不发送消息 - verify(wechatWebhookService, never()).sendMarkdownMessage(anyString()); + verify(wechatWebhookService, never()).sendMarkdownMessage(anyString(), anyString()); } @Test - void testSendMorningReminderOnHoliday() { + void testSendReminderOnHoliday() { // 模拟节假日(不是周末,但是节假日) when(holidayUtil.isWeekend(any(LocalDate.class))).thenReturn(false); when(holidayUtil.isHoliday(any(LocalDate.class))).thenReturn(true); // 执行测试 - taskReminderService.sendMorningReminder(); + taskReminderService.sendReminder("test-group", "morning"); // 验证不发送消息 - verify(wechatWebhookService, never()).sendMarkdownMessage(anyString()); + verify(wechatWebhookService, never()).sendMarkdownMessage(anyString(), anyString()); // 验证两个方法都被调用了 verify(holidayUtil, times(1)).isWeekend(any(LocalDate.class)); verify(holidayUtil, times(1)).isHoliday(any(LocalDate.class)); } @Test - void testSendEveningReminderOnWorkday() { + void testSendAllMorningReminders() { // 模拟工作日 when(holidayUtil.isWeekend(any(LocalDate.class))).thenReturn(false); when(holidayUtil.isHoliday(any(LocalDate.class))).thenReturn(false); - when(wechatWebhookService.createTaskReminderMessage(anyString(), anyString())).thenReturn("测试消息"); - when(wechatWebhookService.sendMarkdownMessage(anyString())).thenReturn(true); + when(taskReminderConfig.getEnabledGroups()).thenReturn(Arrays.asList(testGroup)); + when(taskReminderConfig.getGroupById("test-group")).thenReturn(testGroup); + when(wechatWebhookService.createTaskReminderMessage(anyString(), anyString(), anyString())).thenReturn("测试消息"); + when(wechatWebhookService.sendMarkdownMessage(anyString(), anyString())).thenReturn(true); // 执行测试 - taskReminderService.sendEveningReminder(); + taskReminderService.sendAllMorningReminders(); // 验证 - verify(wechatWebhookService, times(1)).sendMarkdownMessage(anyString()); + verify(wechatWebhookService, times(1)).sendMarkdownMessage(eq("test-group"), anyString()); } @Test - void testSendTestMessage() { - // 模拟成功发送 - when(wechatWebhookService.createTaskReminderMessage(anyString(), anyString())).thenReturn("测试消息"); - when(wechatWebhookService.sendMarkdownMessage(anyString())).thenReturn(true); - - // 执行测试 - boolean result = taskReminderService.sendTestMessage(); - - // 验证 - assert result; - verify(wechatWebhookService, times(1)).sendMarkdownMessage(anyString()); - } - - @Test - void testGetNextReminderInfo() { + void testSendAllEveningReminders() { // 模拟工作日 when(holidayUtil.isWeekend(any(LocalDate.class))).thenReturn(false); when(holidayUtil.isHoliday(any(LocalDate.class))).thenReturn(false); + when(taskReminderConfig.getEnabledGroups()).thenReturn(Arrays.asList(testGroup)); + when(taskReminderConfig.getGroupById("test-group")).thenReturn(testGroup); + when(wechatWebhookService.createTaskReminderMessage(anyString(), anyString(), anyString())).thenReturn("测试消息"); + when(wechatWebhookService.sendMarkdownMessage(anyString(), anyString())).thenReturn(true); // 执行测试 - String info = taskReminderService.getNextReminderInfo(); + taskReminderService.sendAllEveningReminders(); // 验证 - assert info != null; - assert info.contains("当前时间"); - assert info.contains("今天是否工作日:是"); + verify(wechatWebhookService, times(1)).sendMarkdownMessage(eq("test-group"), anyString()); + } + + @Test + void testSendReminderWithInvalidGroup() { + // 模拟群组不存在 + when(taskReminderConfig.getGroupById("invalid-group")).thenReturn(null); + + // 执行测试 + taskReminderService.sendReminder("invalid-group", "morning"); + + // 验证不发送消息 + verify(wechatWebhookService, never()).sendMarkdownMessage(anyString(), anyString()); + } + + @Test + void testSendReminderWithDisabledGroup() { + // 创建禁用的群组 + testGroup.setEnabled(false); + when(taskReminderConfig.getGroupById("test-group")).thenReturn(testGroup); + + // 执行测试 + taskReminderService.sendReminder("test-group", "morning"); + + // 验证不发送消息 + verify(wechatWebhookService, never()).sendMarkdownMessage(anyString(), anyString()); } } diff --git a/src/test/java/com/zeodao/reminder/util/HolidayUtilTest.java b/src/test/java/com/zeodao/reminder/util/HolidayUtilTest.java new file mode 100644 index 0000000..b721f4c --- /dev/null +++ b/src/test/java/com/zeodao/reminder/util/HolidayUtilTest.java @@ -0,0 +1,103 @@ +package com.zeodao.reminder.util; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.time.LocalDate; +import java.time.Month; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * 节假日工具类测试 + * + * @author Zeodao + * @version 2.0.0 + */ +@SpringBootTest +class HolidayUtilTest { + + @Autowired + private HolidayUtil holidayUtil; + + @Test + void testNewYearHoliday() { + // 元旦:1月1日 + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.JANUARY, 1))); + assertFalse(holidayUtil.isHoliday(LocalDate.of(2025, Month.JANUARY, 2))); + } + + @Test + void testSpringFestivalHolidays() { + // 春节:1月28日至2月4日,共8天 + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.JANUARY, 28))); // 除夕 + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.JANUARY, 29))); // 初一 + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.FEBRUARY, 4))); // 初七 + assertFalse(holidayUtil.isHoliday(LocalDate.of(2025, Month.FEBRUARY, 5))); // 初八,不是假期 + } + + @Test + void testQingmingHolidays() { + // 清明节:4月4日至6日,共3天 + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.APRIL, 4))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.APRIL, 5))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.APRIL, 6))); + assertFalse(holidayUtil.isHoliday(LocalDate.of(2025, Month.APRIL, 7))); + } + + @Test + void testLaborDayHolidays() { + // 劳动节:5月1日至5日,共5天 + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.MAY, 1))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.MAY, 2))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.MAY, 3))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.MAY, 4))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.MAY, 5))); + assertFalse(holidayUtil.isHoliday(LocalDate.of(2025, Month.MAY, 6))); + } + + @Test + void testDragonBoatFestivalHolidays() { + // 端午节:5月31日至6月2日,共3天 + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.MAY, 31))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.JUNE, 1))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.JUNE, 2))); + assertFalse(holidayUtil.isHoliday(LocalDate.of(2025, Month.JUNE, 3))); + } + + @Test + void testNationalDayAndMidAutumnHolidays() { + // 国庆节、中秋节:10月1日至8日,共8天 + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.OCTOBER, 1))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.OCTOBER, 2))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.OCTOBER, 3))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.OCTOBER, 4))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.OCTOBER, 5))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.OCTOBER, 6))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.OCTOBER, 7))); + assertTrue(holidayUtil.isHoliday(LocalDate.of(2025, Month.OCTOBER, 8))); + assertFalse(holidayUtil.isHoliday(LocalDate.of(2025, Month.OCTOBER, 9))); + } + + @Test + void testWorkdays() { + // 测试工作日 + LocalDate workday = LocalDate.of(2025, Month.JANUARY, 2); // 周四,工作日 + assertTrue(holidayUtil.isWorkday(workday)); + assertFalse(holidayUtil.isWeekend(workday)); + assertFalse(holidayUtil.isHoliday(workday)); + } + + @Test + void testWeekends() { + // 测试周末 + LocalDate saturday = LocalDate.of(2025, Month.JANUARY, 4); // 周六 + LocalDate sunday = LocalDate.of(2025, Month.JANUARY, 5); // 周日 + + assertTrue(holidayUtil.isWeekend(saturday)); + assertTrue(holidayUtil.isWeekend(sunday)); + assertFalse(holidayUtil.isWorkday(saturday)); + assertFalse(holidayUtil.isWorkday(sunday)); + } +}