|
|
@@ -118,6 +118,12 @@ class CfGrowthPathwayEarnServiceTest {
|
|
|
"{\"source\":\"challenge_task.reward_cf\"}", null, null, "challenge_sub_task"));
|
|
|
when(cfEarnRuleService.getByCode("F18")).thenReturn(rule("F18", "consume", "formula", null, "floor(amt)",
|
|
|
"{\"cf_per_yuan\":100,\"amt_unit\":\"cent\"}", 1, 1, "health_start_plan"));
|
|
|
+ when(cfEarnRuleService.getByCode("F25")).thenReturn(rule("F25", "behavior", "fixed", 1, null,
|
|
|
+ "{\"daily_limit_by_tier\":\"cf_earn_daily_limit\",\"levels\":{\"NONE\":1,\"FAMILY\":2,\"PREMIUM\":5}}",
|
|
|
+ null, null, "checkin_micro"));
|
|
|
+ when(cfEarnRuleService.getByCode("F26")).thenReturn(rule("F26", "behavior", "fixed", 1, null,
|
|
|
+ "{\"daily_limit_by_tier\":\"cf_earn_daily_limit\",\"levels\":{\"NONE\":1,\"FAMILY\":2,\"PREMIUM\":5}}",
|
|
|
+ null, null, "checkin_emotion"));
|
|
|
|
|
|
ReflectionTestUtils.setField(cfBalanceService, "cfBalanceMapper", cfBalanceMapper);
|
|
|
ReflectionTestUtils.setField(cfBalanceService, "cfBalanceLogMapper", cfBalanceLogMapper);
|
|
|
@@ -258,6 +264,104 @@ class CfGrowthPathwayEarnServiceTest {
|
|
|
assertEquals(10, cfBalanceService.getBalance(MEMBER_ID).getAvailable());
|
|
|
}
|
|
|
|
|
|
+ // ---------- F25 微小行动打卡 ----------
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void F25_微小行动打卡_数量取规则固定1_refType为checkin_micro() {
|
|
|
+ CfEarnResult r = service.earnMicroCheckinCf(MEMBER_ID, 4001L);
|
|
|
+
|
|
|
+ assertTrue(r.getEarned());
|
|
|
+ assertEquals("F25", r.getRuleCode());
|
|
|
+ assertEquals("checkin_micro", r.getRefType());
|
|
|
+ assertEquals(4001L, r.getRefId());
|
|
|
+ // 1 来自 cf_earn_rule F25(fixed),代码不写死
|
|
|
+ assertEquals(1, r.getAmount());
|
|
|
+ assertEquals(1, cfBalanceService.getBalance(MEMBER_ID).getAvailable());
|
|
|
+
|
|
|
+ CfBalanceLog log = insertedLogs.get(0);
|
|
|
+ assertEquals("earn", log.getType());
|
|
|
+ assertEquals("checkin_micro", log.getRefType());
|
|
|
+ assertEquals(4001L, log.getRefId());
|
|
|
+ assertEquals(1, log.getAmount());
|
|
|
+ assertEquals(MEMBER_ID, log.getMemberId());
|
|
|
+ assertEquals("微小行动打卡", log.getRemark());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void F25_同一打卡记录重复提交_幂等只发一次() {
|
|
|
+ service.earnMicroCheckinCf(MEMBER_ID, 4002L);
|
|
|
+ CfEarnResult second = service.earnMicroCheckinCf(MEMBER_ID, 4002L);
|
|
|
+
|
|
|
+ assertTrue(second.getDuplicated());
|
|
|
+ assertEquals(1, insertedLogs.size());
|
|
|
+ assertEquals(1, cfBalanceService.getBalance(MEMBER_ID).getAvailable());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void F25_会员等级日限达上限_跳过发放() {
|
|
|
+ CfEarnDailyLimit limit = new CfEarnDailyLimit();
|
|
|
+ limit.setRuleCode("F25");
|
|
|
+ limit.setLevelCode("BASIC");
|
|
|
+ limit.setDailyLimit(3);
|
|
|
+ when(cfEarnDailyLimitMapper.selectOne(any())).thenReturn(limit);
|
|
|
+ when(cfBalanceLogMapper.selectCount(any())).thenReturn(3L);
|
|
|
+
|
|
|
+ CfEarnResult r = service.earnMicroCheckinCf(MEMBER_ID, 4003L);
|
|
|
+
|
|
|
+ assertFalse(r.getEarned());
|
|
|
+ assertTrue(r.getReason().contains("日限"));
|
|
|
+ assertTrue(earnLogs().isEmpty(), "日限命中不得入账");
|
|
|
+ }
|
|
|
+
|
|
|
+ // ---------- F26 情绪打卡 ----------
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void F26_情绪打卡_数量取规则固定1_refType为checkin_emotion() {
|
|
|
+ CfEarnResult r = service.earnEmotionCheckinCf(MEMBER_ID, 5001L);
|
|
|
+
|
|
|
+ assertTrue(r.getEarned());
|
|
|
+ assertEquals("F26", r.getRuleCode());
|
|
|
+ assertEquals("checkin_emotion", r.getRefType());
|
|
|
+ assertEquals(5001L, r.getRefId());
|
|
|
+ // 1 来自 cf_earn_rule F26(fixed),代码不写死
|
|
|
+ assertEquals(1, r.getAmount());
|
|
|
+ assertEquals(1, cfBalanceService.getBalance(MEMBER_ID).getAvailable());
|
|
|
+
|
|
|
+ CfBalanceLog log = insertedLogs.get(0);
|
|
|
+ assertEquals("earn", log.getType());
|
|
|
+ assertEquals("checkin_emotion", log.getRefType());
|
|
|
+ assertEquals(5001L, log.getRefId());
|
|
|
+ assertEquals(1, log.getAmount());
|
|
|
+ assertEquals(MEMBER_ID, log.getMemberId());
|
|
|
+ assertEquals("情绪打卡", log.getRemark());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void F26_同一打卡记录重复提交_幂等只发一次() {
|
|
|
+ service.earnEmotionCheckinCf(MEMBER_ID, 5002L);
|
|
|
+ CfEarnResult second = service.earnEmotionCheckinCf(MEMBER_ID, 5002L);
|
|
|
+
|
|
|
+ assertTrue(second.getDuplicated());
|
|
|
+ assertEquals(1, insertedLogs.size());
|
|
|
+ assertEquals(1, cfBalanceService.getBalance(MEMBER_ID).getAvailable());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void F26_会员等级日限达上限_跳过发放() {
|
|
|
+ CfEarnDailyLimit limit = new CfEarnDailyLimit();
|
|
|
+ limit.setRuleCode("F26");
|
|
|
+ limit.setLevelCode("BASIC");
|
|
|
+ limit.setDailyLimit(3);
|
|
|
+ when(cfEarnDailyLimitMapper.selectOne(any())).thenReturn(limit);
|
|
|
+ when(cfBalanceLogMapper.selectCount(any())).thenReturn(3L);
|
|
|
+
|
|
|
+ CfEarnResult r = service.earnEmotionCheckinCf(MEMBER_ID, 5003L);
|
|
|
+
|
|
|
+ assertFalse(r.getEarned());
|
|
|
+ assertTrue(r.getReason().contains("日限"));
|
|
|
+ assertTrue(earnLogs().isEmpty(), "日限命中不得入账");
|
|
|
+ }
|
|
|
+
|
|
|
// ---------- F17 挑战赛子任务完成 ----------
|
|
|
|
|
|
@Test
|
|
|
@@ -352,7 +456,7 @@ class CfGrowthPathwayEarnServiceTest {
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- void F14_F15_F16_ctx不携带数量_数量全由规则决定() {
|
|
|
+ void F14_F15_F16_F25_F26_ctx不携带数量_数量全由规则决定() {
|
|
|
CfGrowthPathwayEarnService s = new CfGrowthPathwayEarnService();
|
|
|
|
|
|
Map<String, Object> ctxF14 = captureCtx(s, MEMBER_ID, "F14", 11L,
|
|
|
@@ -373,6 +477,18 @@ class CfGrowthPathwayEarnServiceTest {
|
|
|
assertNull(ctxF16.get("amount"), "固定规则 F16 的数量必须来自 cf_earn_rule,代码不得传 amount");
|
|
|
assertEquals(33L, ctxF16.get("checkin_id"));
|
|
|
assertEquals("每日健康打卡", ctxF16.get("remark"));
|
|
|
+
|
|
|
+ Map<String, Object> ctxF25 = captureCtx(s, MEMBER_ID, "F25", 44L,
|
|
|
+ () -> s.earnMicroCheckinCf(MEMBER_ID, 44L));
|
|
|
+ assertNull(ctxF25.get("amount"), "固定规则 F25 的数量必须来自 cf_earn_rule,代码不得传 amount");
|
|
|
+ assertEquals(44L, ctxF25.get("checkin_id"));
|
|
|
+ assertEquals("微小行动打卡", ctxF25.get("remark"));
|
|
|
+
|
|
|
+ Map<String, Object> ctxF26 = captureCtx(s, MEMBER_ID, "F26", 55L,
|
|
|
+ () -> s.earnEmotionCheckinCf(MEMBER_ID, 55L));
|
|
|
+ assertNull(ctxF26.get("amount"), "固定规则 F26 的数量必须来自 cf_earn_rule,代码不得传 amount");
|
|
|
+ assertEquals(55L, ctxF26.get("checkin_id"));
|
|
|
+ assertEquals("情绪打卡", ctxF26.get("remark"));
|
|
|
}
|
|
|
|
|
|
@Test
|