@dpesch/mantisbt-mcp-server 1.8.3 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -1
- package/README.de.md +3 -3
- package/README.md +3 -3
- package/dist/date-filter.js +55 -0
- package/dist/search/highlight.js +63 -0
- package/dist/search/store.js +4 -0
- package/dist/search/tools.js +66 -4
- package/dist/tools/config.js +23 -8
- package/dist/tools/issues.js +135 -20
- package/dist/tools/notes.js +1 -1
- package/dist/tools/projects.js +3 -2
- package/dist/tools/version.js +2 -1
- package/docs/cookbook.de.md +64 -7
- package/docs/cookbook.md +64 -7
- package/docs/examples.de.md +12 -0
- package/docs/examples.md +12 -0
- package/package.json +1 -1
- package/server.json +2 -2
- package/tests/fixtures/get_issue.json +22 -0
- package/tests/helpers/search-mocks.ts +29 -6
- package/tests/search/highlight.test.ts +129 -0
- package/tests/search/tools.test.ts +286 -0
- package/tests/tools/issues.test.ts +446 -4
- package/tests/tools/string-coercion.test.ts +64 -0
- package/tests/utils/date-filter.test.ts +169 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { matchesDateFilter } from '../../src/date-filter.js';
|
|
3
|
+
|
|
4
|
+
describe('matchesDateFilter', () => {
|
|
5
|
+
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// No filter → always pass
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
it('returns true when no filter is set', () => {
|
|
11
|
+
expect(matchesDateFilter(
|
|
12
|
+
{ updated_at: '2026-03-20T10:00:00Z', created_at: '2026-03-01T00:00:00Z' },
|
|
13
|
+
{}
|
|
14
|
+
)).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('returns true for an item with no dates when no filter is set', () => {
|
|
18
|
+
expect(matchesDateFilter({}, {})).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// updated_after
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
it('updated_after: passes when updated_at is after the threshold', () => {
|
|
26
|
+
expect(matchesDateFilter(
|
|
27
|
+
{ updated_at: '2026-03-25T12:00:00Z' },
|
|
28
|
+
{ updated_after: '2026-03-24T00:00:00Z' }
|
|
29
|
+
)).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('updated_after: fails when updated_at is before the threshold', () => {
|
|
33
|
+
expect(matchesDateFilter(
|
|
34
|
+
{ updated_at: '2026-03-23T12:00:00Z' },
|
|
35
|
+
{ updated_after: '2026-03-24T00:00:00Z' }
|
|
36
|
+
)).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('updated_after: fails when updated_at equals the threshold (exclusive)', () => {
|
|
40
|
+
expect(matchesDateFilter(
|
|
41
|
+
{ updated_at: '2026-03-24T00:00:00Z' },
|
|
42
|
+
{ updated_after: '2026-03-24T00:00:00Z' }
|
|
43
|
+
)).toBe(false);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('updated_after: fails when updated_at is missing', () => {
|
|
47
|
+
expect(matchesDateFilter(
|
|
48
|
+
{ created_at: '2026-03-25T00:00:00Z' },
|
|
49
|
+
{ updated_after: '2026-03-24T00:00:00Z' }
|
|
50
|
+
)).toBe(false);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// updated_before
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
it('updated_before: passes when updated_at is before the threshold', () => {
|
|
58
|
+
expect(matchesDateFilter(
|
|
59
|
+
{ updated_at: '2026-03-20T00:00:00Z' },
|
|
60
|
+
{ updated_before: '2026-03-25T00:00:00Z' }
|
|
61
|
+
)).toBe(true);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('updated_before: fails when updated_at is after the threshold', () => {
|
|
65
|
+
expect(matchesDateFilter(
|
|
66
|
+
{ updated_at: '2026-03-26T00:00:00Z' },
|
|
67
|
+
{ updated_before: '2026-03-25T00:00:00Z' }
|
|
68
|
+
)).toBe(false);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('updated_before: fails when updated_at equals the threshold (exclusive)', () => {
|
|
72
|
+
expect(matchesDateFilter(
|
|
73
|
+
{ updated_at: '2026-03-25T00:00:00Z' },
|
|
74
|
+
{ updated_before: '2026-03-25T00:00:00Z' }
|
|
75
|
+
)).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('updated_before: fails when updated_at is missing', () => {
|
|
79
|
+
expect(matchesDateFilter(
|
|
80
|
+
{},
|
|
81
|
+
{ updated_before: '2026-03-25T00:00:00Z' }
|
|
82
|
+
)).toBe(false);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// created_after
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
|
|
89
|
+
it('created_after: passes when created_at is after the threshold', () => {
|
|
90
|
+
expect(matchesDateFilter(
|
|
91
|
+
{ created_at: '2026-03-25T12:00:00Z' },
|
|
92
|
+
{ created_after: '2026-03-24T00:00:00Z' }
|
|
93
|
+
)).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('created_after: fails when created_at is before the threshold', () => {
|
|
97
|
+
expect(matchesDateFilter(
|
|
98
|
+
{ created_at: '2026-03-23T00:00:00Z' },
|
|
99
|
+
{ created_after: '2026-03-24T00:00:00Z' }
|
|
100
|
+
)).toBe(false);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('created_after: fails when created_at is missing', () => {
|
|
104
|
+
expect(matchesDateFilter(
|
|
105
|
+
{ updated_at: '2026-03-25T00:00:00Z' },
|
|
106
|
+
{ created_after: '2026-03-24T00:00:00Z' }
|
|
107
|
+
)).toBe(false);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// created_before
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
it('created_before: passes when created_at is before the threshold', () => {
|
|
115
|
+
expect(matchesDateFilter(
|
|
116
|
+
{ created_at: '2026-03-20T00:00:00Z' },
|
|
117
|
+
{ created_before: '2026-03-25T00:00:00Z' }
|
|
118
|
+
)).toBe(true);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('created_before: fails when created_at is after the threshold', () => {
|
|
122
|
+
expect(matchesDateFilter(
|
|
123
|
+
{ created_at: '2026-03-26T00:00:00Z' },
|
|
124
|
+
{ created_before: '2026-03-25T00:00:00Z' }
|
|
125
|
+
)).toBe(false);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
// Combined filters (time window)
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
|
|
132
|
+
it('updated_after + updated_before: passes when updated_at is within window', () => {
|
|
133
|
+
expect(matchesDateFilter(
|
|
134
|
+
{ updated_at: '2026-03-22T00:00:00Z' },
|
|
135
|
+
{ updated_after: '2026-03-20T00:00:00Z', updated_before: '2026-03-25T00:00:00Z' }
|
|
136
|
+
)).toBe(true);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('updated_after + updated_before: fails when updated_at is outside window', () => {
|
|
140
|
+
expect(matchesDateFilter(
|
|
141
|
+
{ updated_at: '2026-03-26T00:00:00Z' },
|
|
142
|
+
{ updated_after: '2026-03-20T00:00:00Z', updated_before: '2026-03-25T00:00:00Z' }
|
|
143
|
+
)).toBe(false);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('all four filters: passes only when both dates are within their windows', () => {
|
|
147
|
+
expect(matchesDateFilter(
|
|
148
|
+
{ updated_at: '2026-03-22T00:00:00Z', created_at: '2026-03-10T00:00:00Z' },
|
|
149
|
+
{
|
|
150
|
+
updated_after: '2026-03-20T00:00:00Z',
|
|
151
|
+
updated_before: '2026-03-25T00:00:00Z',
|
|
152
|
+
created_after: '2026-03-05T00:00:00Z',
|
|
153
|
+
created_before: '2026-03-15T00:00:00Z',
|
|
154
|
+
}
|
|
155
|
+
)).toBe(true);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('all four filters: fails when one date is out of range', () => {
|
|
159
|
+
expect(matchesDateFilter(
|
|
160
|
+
{ updated_at: '2026-03-22T00:00:00Z', created_at: '2026-03-16T00:00:00Z' }, // created_at too late
|
|
161
|
+
{
|
|
162
|
+
updated_after: '2026-03-20T00:00:00Z',
|
|
163
|
+
updated_before: '2026-03-25T00:00:00Z',
|
|
164
|
+
created_after: '2026-03-05T00:00:00Z',
|
|
165
|
+
created_before: '2026-03-15T00:00:00Z',
|
|
166
|
+
}
|
|
167
|
+
)).toBe(false);
|
|
168
|
+
});
|
|
169
|
+
});
|