bug-tracker.test.js
3.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
* bugTracker 单测
*/
const fs = require('fs');
const pathResolver = require('../../services/devloop/path-resolver');
const bugTracker = require('../../services/devloop/bug-tracker');
describe('bugTracker', () => {
let pid, root;
beforeEach(() => {
pathResolver._resetForTesting();
const r = pathResolver.allocateProjectRoot({ company_id: 'c-test', mode: 'sandbox' });
pid = r.pid;
root = r.root_path;
});
afterEach(() => {
fs.rmSync(root, { recursive: true, force: true });
});
describe('open + dedup', () => {
it('open new bug returns id', () => {
const b = bugTracker.open(pid, {
source: 'unit_test', unit_id: 'auth-be',
test_name: 'login.invalid-pwd', severity: 'high',
title: 'expected 401 got 500',
});
expect(b.id).toMatch(/^bug-/);
expect(b.status).toBe('open');
});
it('same unit + test → dedup returns existing id', () => {
const b1 = bugTracker.open(pid, {
unit_id: 'auth-be', test_name: 'login.invalid-pwd', title: 'T1',
});
const b2 = bugTracker.open(pid, {
unit_id: 'auth-be', test_name: 'login.invalid-pwd', title: 'T2',
});
expect(b2.id).toBe(b1.id);
});
});
describe('transition', () => {
it('open → fixing → fixed → verified', () => {
const b = bugTracker.open(pid, {
unit_id: 'auth-be', test_name: 'x', title: 'T',
});
bugTracker.transition(pid, b.id, { to: 'fixing', by: 'coder' });
expect(bugTracker.get(pid, b.id).status).toBe('fixing');
bugTracker.transition(pid, b.id, { to: 'fixed', by: 'tester' });
expect(bugTracker.get(pid, b.id).status).toBe('fixed');
bugTracker.transition(pid, b.id, { to: 'verified', by: 'integrator' });
expect(bugTracker.get(pid, b.id).status).toBe('verified');
});
it('open → verified (skip) throws', () => {
const b = bugTracker.open(pid, { unit_id: 'x-be', test_name: 'y', title: 'T' });
expect(() => bugTracker.transition(pid, b.id, { to: 'verified', by: 'system' }))
.toThrow(bugTracker.InvalidBugTransitionError);
});
it('verified → open (reopen) ok', () => {
const b = bugTracker.open(pid, { unit_id: 'x-be', test_name: 'y', title: 'T' });
bugTracker.transition(pid, b.id, { to: 'fixing', by: 'coder' });
bugTracker.transition(pid, b.id, { to: 'fixed', by: 'tester' });
bugTracker.transition(pid, b.id, { to: 'verified', by: 'integrator' });
bugTracker.transition(pid, b.id, { to: 'open', by: 'system' });
expect(bugTracker.get(pid, b.id).status).toBe('open');
});
});
describe('list + stats', () => {
it('filter by status', () => {
const b1 = bugTracker.open(pid, { unit_id: 'a-be', test_name: 't1', title: 'T1' });
const b2 = bugTracker.open(pid, { unit_id: 'b-be', test_name: 't2', title: 'T2' });
bugTracker.transition(pid, b2.id, { to: 'fixing', by: 'coder' });
const open = bugTracker.list(pid, { status: ['open'] });
const fixing = bugTracker.list(pid, { status: ['fixing'] });
expect(open.map(b => b.id)).toContain(b1.id);
expect(fixing.map(b => b.id)).toContain(b2.id);
});
it('stats counts by status', () => {
bugTracker.open(pid, { unit_id: 'a-be', test_name: 't1', title: 'T', severity: 'high' });
bugTracker.open(pid, { unit_id: 'b-be', test_name: 't2', title: 'T', severity: 'low' });
const s = bugTracker.stats(pid);
expect(s.open).toBe(2);
expect(s.by_severity.high).toBe(1);
expect(s.by_severity.low).toBe(1);
});
});
describe('history', () => {
it('tracks all transitions', () => {
const b = bugTracker.open(pid, { unit_id: 'a-be', test_name: 't', title: 'T' });
bugTracker.transition(pid, b.id, { to: 'fixing', by: 'coder' });
bugTracker.transition(pid, b.id, { to: 'fixed', by: 'tester' });
const h = bugTracker.history(pid, b.id);
// 含 open 时的 history (1) + 2 次 transition = 3 条
expect(h.length).toBeGreaterThanOrEqual(3);
});
});
});