60 lines
2.4 KiB
JavaScript
60 lines
2.4 KiB
JavaScript
// P2-7(audit):app:open-config-dir 高频调用检测。
|
||
//
|
||
// 设计:main/audit-rate.js 提供 createAuditRateTracker({ windowMs, threshold, now })
|
||
// 返回 hit(key) → { count, exceeded }。滑动窗口按 key 计数:
|
||
// - 窗口内 count ≤ threshold → exceeded=false
|
||
// - 窗口内 count > threshold → exceeded=true(调用方据此 console.warn)
|
||
// - 超过 windowMs 的旧记录自动过期
|
||
//
|
||
// now 可注入(Date.now 默认),方便单测推进时间。
|
||
|
||
import { describe, it, expect } from 'vitest';
|
||
const { createAuditRateTracker } = require('../../main/audit-rate.js');
|
||
|
||
describe('createAuditRateTracker —— P2-7 高频调用检测', () => {
|
||
it('首次调用 count=1,不 exceeded', () => {
|
||
const t = createAuditRateTracker({ windowMs: 60_000, threshold: 5 });
|
||
expect(t.hit('k')).toEqual({ count: 1, exceeded: false });
|
||
});
|
||
|
||
it('窗口内累计到 threshold 不 exceeded,超过则 exceeded', () => {
|
||
let now = 1000;
|
||
const t = createAuditRateTracker({ windowMs: 60_000, threshold: 3, now: () => now });
|
||
expect(t.hit('k').exceeded).toBe(false); // 1
|
||
expect(t.hit('k').exceeded).toBe(false); // 2
|
||
expect(t.hit('k').exceeded).toBe(false); // 3
|
||
const fourth = t.hit('k'); // 4 > 3
|
||
expect(fourth.count).toBe(4);
|
||
expect(fourth.exceeded).toBe(true);
|
||
});
|
||
|
||
it('不同 key 独立计数', () => {
|
||
const t = createAuditRateTracker({ windowMs: 60_000, threshold: 1 });
|
||
t.hit('a');
|
||
expect(t.hit('b')).toEqual({ count: 1, exceeded: false });
|
||
});
|
||
|
||
it('超过 windowMs 的旧记录过期,重新计数', () => {
|
||
let now = 0;
|
||
const t = createAuditRateTracker({ windowMs: 1000, threshold: 2, now: () => now });
|
||
t.hit('k'); // t=0
|
||
t.hit('k'); // t=0, count=2
|
||
expect(t.hit('k').exceeded).toBe(true); // t=0, count=3
|
||
now = 1500; // 滑出窗口
|
||
expect(t.hit('k')).toEqual({ count: 1, exceeded: false });
|
||
});
|
||
|
||
it('边界:恰好 windowMs 的时间点视为过期([now-window, now) 语义)', () => {
|
||
let now = 0;
|
||
const t = createAuditRateTracker({ windowMs: 1000, threshold: 1, now: () => now });
|
||
t.hit('k'); // t=0
|
||
now = 1000; // 恰好 1000ms 后
|
||
expect(t.hit('k')).toEqual({ count: 1, exceeded: false });
|
||
});
|
||
|
||
it('默认 now=Date.now,不抛错', () => {
|
||
const t = createAuditRateTracker({ windowMs: 1000, threshold: 1 });
|
||
expect(() => t.hit('k')).not.toThrow();
|
||
});
|
||
});
|