fix(会员升级): 相等价差 / 点差也拒绝,堵住 0 元升级
- quote_runtime_profile_membership_upgrade 先把 target.price_cents / period_points 与 current 比较,<= 直接返回 InvalidQuoteInput(评审第 15 条) - 保留 rank 递增校验;旧实现用 checked_sub 只拦下溢,相等会算出 0 元升级 / 0 补点 - inverted_catalog_price_and_points_are_rejected 扩展相等分支,已验证去掉 <= 时该用例失败
This commit is contained in:
@@ -182,15 +182,13 @@ pub fn quote_runtime_profile_membership_upgrade(
|
||||
input.now_micros,
|
||||
);
|
||||
|
||||
// 目录价格 / 每期泥点必须严格随 rank 递增;倒挂时宁可报错,也不算出 0 元升级。
|
||||
let price_delta_cents = target
|
||||
.price_cents
|
||||
.checked_sub(current.price_cents)
|
||||
.ok_or(RuntimeProfileMembershipUpgradeRejection::InvalidQuoteInput)?;
|
||||
let points_delta = target
|
||||
.period_points
|
||||
.checked_sub(current.period_points)
|
||||
.ok_or(RuntimeProfileMembershipUpgradeRejection::InvalidQuoteInput)?;
|
||||
// 目录价格 / 每期泥点必须严格随 rank 递增;相等或倒挂都直接拒绝,
|
||||
// 否则 checked_sub 会把「相等」算成 0 元升级 / 0 补点,违背目录不变量。
|
||||
if target.price_cents <= current.price_cents || target.period_points <= current.period_points {
|
||||
return Err(RuntimeProfileMembershipUpgradeRejection::InvalidQuoteInput);
|
||||
}
|
||||
let price_delta_cents = target.price_cents - current.price_cents;
|
||||
let points_delta = target.period_points - current.period_points;
|
||||
|
||||
let (amount_cents, granted_points_delta) = match target.cycle_kind {
|
||||
RuntimeProfileMembershipCycleKind::Monthly => (price_delta_cents, points_delta),
|
||||
@@ -494,6 +492,19 @@ mod tests {
|
||||
|
||||
target.price_cents = current.price_cents + 1;
|
||||
target.period_points = current.period_points - 1;
|
||||
assert_eq!(
|
||||
quote_runtime_profile_membership_upgrade(RuntimeProfileMembershipUpgradeQuoteInput {
|
||||
current: current.clone(),
|
||||
target: target.clone(),
|
||||
..base_input()
|
||||
}),
|
||||
Err(RuntimeProfileMembershipUpgradeRejection::InvalidQuoteInput)
|
||||
);
|
||||
|
||||
// 中文注释:相等同样破坏「严格随 rank 递增」,必须拒绝;旧实现用 checked_sub
|
||||
// 会把相等的价差 / 点差算成 0,从而产出 0 元升级 / 0 补点。
|
||||
target.price_cents = current.price_cents;
|
||||
target.period_points = current.period_points;
|
||||
assert_eq!(
|
||||
quote_runtime_profile_membership_upgrade(RuntimeProfileMembershipUpgradeQuoteInput {
|
||||
current,
|
||||
|
||||
Reference in New Issue
Block a user