github-issue-tower-defence-management 1.38.0 → 1.38.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 +7 -0
- package/bin/domain/usecases/SetNoStoryIssueToStoryUseCase.js +2 -2
- package/bin/domain/usecases/SetNoStoryIssueToStoryUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/domain/usecases/SetNoStoryIssueToStoryUseCase.test.ts +372 -0
- package/src/domain/usecases/SetNoStoryIssueToStoryUseCase.ts +4 -2
- package/types/domain/usecases/SetNoStoryIssueToStoryUseCase.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [1.38.1](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.38.0...v1.38.1) (2026-05-04)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **core:** skip issues with story: label in SetNoStoryIssueToStoryUseCase ([9e325a3](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/9e325a3eaccc1e2c3ea5ca3288b459ed12d4d08e))
|
|
7
|
+
|
|
1
8
|
# [1.38.0](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.37.1...v1.38.0) (2026-05-04)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -13,11 +13,11 @@ class SetNoStoryIssueToStoryUseCase {
|
|
|
13
13
|
}
|
|
14
14
|
const isTargetIssue = (issue) => {
|
|
15
15
|
return (issue.story === null &&
|
|
16
|
+
!issue.labels.some((label) => label.toLowerCase().startsWith('story:')) &&
|
|
16
17
|
(issue.nextActionDate === null ||
|
|
17
18
|
issue.nextActionDate.getTime() <= input.targetDates[0].getTime()) &&
|
|
18
19
|
issue.nextActionHour === null &&
|
|
19
|
-
issue.state === 'OPEN'
|
|
20
|
-
issue.story === null);
|
|
20
|
+
issue.state === 'OPEN');
|
|
21
21
|
};
|
|
22
22
|
const firstStory = input.project.story?.stories[0];
|
|
23
23
|
if (!firstStory) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SetNoStoryIssueToStoryUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/SetNoStoryIssueToStoryUseCase.ts"],"names":[],"mappings":";;;AAIA,MAAa,6BAA6B;IACxC,YAAqB,eAAqD;QAArD,oBAAe,GAAf,eAAe,CAAsC;QAE1E,QAAG,GAAG,KAAK,EAAE,KAKZ,EAAiB,EAAE;YAClB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAClC,IACE,CAAC,KAAK;gBACN,KAAK,CAAC,SAAS;gBACf,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,EACtE,CAAC;gBACD,OAAO;YACT,CAAC;YACD,MAAM,aAAa,GAAG,CAAC,KAAY,EAAW,EAAE;gBAC9C,OAAO,CACL,KAAK,CAAC,KAAK,KAAK,IAAI;oBACpB,CAAC,KAAK,CAAC,cAAc,KAAK,IAAI;wBAC5B,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;oBACnE,KAAK,CAAC,cAAc,KAAK,IAAI;oBAC7B,KAAK,CAAC,KAAK,KAAK,MAAM
|
|
1
|
+
{"version":3,"file":"SetNoStoryIssueToStoryUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/SetNoStoryIssueToStoryUseCase.ts"],"names":[],"mappings":";;;AAIA,MAAa,6BAA6B;IACxC,YAAqB,eAAqD;QAArD,oBAAe,GAAf,eAAe,CAAsC;QAE1E,QAAG,GAAG,KAAK,EAAE,KAKZ,EAAiB,EAAE;YAClB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAClC,IACE,CAAC,KAAK;gBACN,KAAK,CAAC,SAAS;gBACf,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,EACtE,CAAC;gBACD,OAAO;YACT,CAAC;YACD,MAAM,aAAa,GAAG,CAAC,KAAY,EAAW,EAAE;gBAC9C,OAAO,CACL,KAAK,CAAC,KAAK,KAAK,IAAI;oBACpB,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAC3B,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CACzC;oBACD,CAAC,KAAK,CAAC,cAAc,KAAK,IAAI;wBAC5B,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;oBACnE,KAAK,CAAC,cAAc,KAAK,IAAI;oBAC7B,KAAK,CAAC,KAAK,KAAK,MAAM,CACvB,CAAC;YACJ,CAAC,CAAC;YACF,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;YACnD,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO;YACT,CAAC;YACD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC1B,SAAS;gBACX,CAAC;gBACD,MAAM,IAAI,CAAC,eAAe,CAAC,WAAW,CACpC,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,EAC3B,KAAK,EACL,UAAU,CAAC,EAAE,CACd,CAAC;gBACF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC,CAAC;IA3C2E,CAAC;CA4C/E;AA7CD,sEA6CC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import { mock } from 'jest-mock-extended';
|
|
2
|
+
import { SetNoStoryIssueToStoryUseCase } from './SetNoStoryIssueToStoryUseCase';
|
|
3
|
+
import { IssueRepository } from './adapter-interfaces/IssueRepository';
|
|
4
|
+
import { Issue } from '../entities/Issue';
|
|
5
|
+
import { Project } from '../entities/Project';
|
|
6
|
+
|
|
7
|
+
describe('SetNoStoryIssueToStoryUseCase', () => {
|
|
8
|
+
const mockIssueRepository = mock<IssueRepository>();
|
|
9
|
+
|
|
10
|
+
const basicStory = {
|
|
11
|
+
name: 'Story Field',
|
|
12
|
+
fieldId: 'storyFieldId',
|
|
13
|
+
databaseId: 123,
|
|
14
|
+
stories: [
|
|
15
|
+
{
|
|
16
|
+
id: 'noStoryId',
|
|
17
|
+
name: 'regular / NO STORY',
|
|
18
|
+
color: 'GRAY' as const,
|
|
19
|
+
description: '',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 'highPriorityId',
|
|
23
|
+
name: 'regular / high priority',
|
|
24
|
+
color: 'RED' as const,
|
|
25
|
+
description: '',
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
workflowManagementStory: {
|
|
29
|
+
id: 'workflowManagementStoryId',
|
|
30
|
+
name: 'workflow management',
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const basicProject: Project = {
|
|
35
|
+
...mock<Project>(),
|
|
36
|
+
story: basicStory,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const targetDate = new Date('2000-01-01T01:00:00Z');
|
|
40
|
+
|
|
41
|
+
let useCase: SetNoStoryIssueToStoryUseCase;
|
|
42
|
+
|
|
43
|
+
beforeEach(() => {
|
|
44
|
+
jest.clearAllMocks();
|
|
45
|
+
jest.useFakeTimers();
|
|
46
|
+
useCase = new SetNoStoryIssueToStoryUseCase(mockIssueRepository);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
afterEach(() => {
|
|
50
|
+
jest.useRealTimers();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('run', () => {
|
|
54
|
+
it('should do nothing when project has no story field', async () => {
|
|
55
|
+
const projectWithoutStory: Project = { ...basicProject, story: null };
|
|
56
|
+
|
|
57
|
+
await useCase.run({
|
|
58
|
+
targetDates: [targetDate],
|
|
59
|
+
project: projectWithoutStory,
|
|
60
|
+
issues: [
|
|
61
|
+
{
|
|
62
|
+
...mock<Issue>(),
|
|
63
|
+
labels: [],
|
|
64
|
+
story: null,
|
|
65
|
+
state: 'OPEN',
|
|
66
|
+
nextActionDate: null,
|
|
67
|
+
nextActionHour: null,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
cacheUsed: false,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalled();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should do nothing when cacheUsed is true', async () => {
|
|
77
|
+
await useCase.run({
|
|
78
|
+
targetDates: [targetDate],
|
|
79
|
+
project: basicProject,
|
|
80
|
+
issues: [
|
|
81
|
+
{
|
|
82
|
+
...mock<Issue>(),
|
|
83
|
+
labels: [],
|
|
84
|
+
story: null,
|
|
85
|
+
state: 'OPEN',
|
|
86
|
+
nextActionDate: null,
|
|
87
|
+
nextActionHour: null,
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
cacheUsed: true,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalled();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should do nothing when no target date has minutes === 0', async () => {
|
|
97
|
+
const nonHourDate = new Date('2000-01-01T01:30:00Z');
|
|
98
|
+
|
|
99
|
+
await useCase.run({
|
|
100
|
+
targetDates: [nonHourDate],
|
|
101
|
+
project: basicProject,
|
|
102
|
+
issues: [
|
|
103
|
+
{
|
|
104
|
+
...mock<Issue>(),
|
|
105
|
+
labels: [],
|
|
106
|
+
story: null,
|
|
107
|
+
state: 'OPEN',
|
|
108
|
+
nextActionDate: null,
|
|
109
|
+
nextActionHour: null,
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
cacheUsed: false,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalled();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should do nothing when project story has no stories', async () => {
|
|
119
|
+
const projectWithEmptyStories: Project = {
|
|
120
|
+
...basicProject,
|
|
121
|
+
story: {
|
|
122
|
+
...basicStory,
|
|
123
|
+
stories: [],
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
await useCase.run({
|
|
128
|
+
targetDates: [targetDate],
|
|
129
|
+
project: projectWithEmptyStories,
|
|
130
|
+
issues: [
|
|
131
|
+
{
|
|
132
|
+
...mock<Issue>(),
|
|
133
|
+
labels: [],
|
|
134
|
+
story: null,
|
|
135
|
+
state: 'OPEN',
|
|
136
|
+
nextActionDate: null,
|
|
137
|
+
nextActionHour: null,
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
cacheUsed: false,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalled();
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should assign first story to eligible issue with no story and no story: labels', async () => {
|
|
147
|
+
const issue: Issue = {
|
|
148
|
+
...mock<Issue>(),
|
|
149
|
+
labels: [],
|
|
150
|
+
story: null,
|
|
151
|
+
state: 'OPEN',
|
|
152
|
+
nextActionDate: null,
|
|
153
|
+
nextActionHour: null,
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const promise = useCase.run({
|
|
157
|
+
targetDates: [targetDate],
|
|
158
|
+
project: basicProject,
|
|
159
|
+
issues: [issue],
|
|
160
|
+
cacheUsed: false,
|
|
161
|
+
});
|
|
162
|
+
await jest.runAllTimersAsync();
|
|
163
|
+
await promise;
|
|
164
|
+
|
|
165
|
+
expect(mockIssueRepository.updateStory.mock.calls).toEqual([
|
|
166
|
+
[{ ...basicProject, story: basicProject.story }, issue, 'noStoryId'],
|
|
167
|
+
]);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('should skip issue that has a story: label', async () => {
|
|
171
|
+
const issue: Issue = {
|
|
172
|
+
...mock<Issue>(),
|
|
173
|
+
labels: ['story:high-priority'],
|
|
174
|
+
story: null,
|
|
175
|
+
state: 'OPEN',
|
|
176
|
+
nextActionDate: null,
|
|
177
|
+
nextActionHour: null,
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
await useCase.run({
|
|
181
|
+
targetDates: [targetDate],
|
|
182
|
+
project: basicProject,
|
|
183
|
+
issues: [issue],
|
|
184
|
+
cacheUsed: false,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalled();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should skip issue that has a story:workflow-management label', async () => {
|
|
191
|
+
const issue: Issue = {
|
|
192
|
+
...mock<Issue>(),
|
|
193
|
+
labels: ['story:workflow-management'],
|
|
194
|
+
story: null,
|
|
195
|
+
state: 'OPEN',
|
|
196
|
+
nextActionDate: null,
|
|
197
|
+
nextActionHour: null,
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
await useCase.run({
|
|
201
|
+
targetDates: [targetDate],
|
|
202
|
+
project: basicProject,
|
|
203
|
+
issues: [issue],
|
|
204
|
+
cacheUsed: false,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalled();
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('should skip issue that has a story: label with uppercase prefix', async () => {
|
|
211
|
+
const issue: Issue = {
|
|
212
|
+
...mock<Issue>(),
|
|
213
|
+
labels: ['STORY:high-priority'],
|
|
214
|
+
story: null,
|
|
215
|
+
state: 'OPEN',
|
|
216
|
+
nextActionDate: null,
|
|
217
|
+
nextActionHour: null,
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
await useCase.run({
|
|
221
|
+
targetDates: [targetDate],
|
|
222
|
+
project: basicProject,
|
|
223
|
+
issues: [issue],
|
|
224
|
+
cacheUsed: false,
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalled();
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('should skip issue that already has a story assigned', async () => {
|
|
231
|
+
const issue: Issue = {
|
|
232
|
+
...mock<Issue>(),
|
|
233
|
+
labels: [],
|
|
234
|
+
story: 'regular / NO STORY',
|
|
235
|
+
state: 'OPEN',
|
|
236
|
+
nextActionDate: null,
|
|
237
|
+
nextActionHour: null,
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
await useCase.run({
|
|
241
|
+
targetDates: [targetDate],
|
|
242
|
+
project: basicProject,
|
|
243
|
+
issues: [issue],
|
|
244
|
+
cacheUsed: false,
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalled();
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it('should skip CLOSED issue', async () => {
|
|
251
|
+
const issue: Issue = {
|
|
252
|
+
...mock<Issue>(),
|
|
253
|
+
labels: [],
|
|
254
|
+
story: null,
|
|
255
|
+
state: 'CLOSED',
|
|
256
|
+
nextActionDate: null,
|
|
257
|
+
nextActionHour: null,
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
await useCase.run({
|
|
261
|
+
targetDates: [targetDate],
|
|
262
|
+
project: basicProject,
|
|
263
|
+
issues: [issue],
|
|
264
|
+
cacheUsed: false,
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalled();
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('should skip issue with nextActionDate in the future', async () => {
|
|
271
|
+
const futureDate = new Date('2000-01-02T00:00:00Z');
|
|
272
|
+
const issue: Issue = {
|
|
273
|
+
...mock<Issue>(),
|
|
274
|
+
labels: [],
|
|
275
|
+
story: null,
|
|
276
|
+
state: 'OPEN',
|
|
277
|
+
nextActionDate: futureDate,
|
|
278
|
+
nextActionHour: null,
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
await useCase.run({
|
|
282
|
+
targetDates: [targetDate],
|
|
283
|
+
project: basicProject,
|
|
284
|
+
issues: [issue],
|
|
285
|
+
cacheUsed: false,
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalled();
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it('should skip issue with nextActionHour set', async () => {
|
|
292
|
+
const issue: Issue = {
|
|
293
|
+
...mock<Issue>(),
|
|
294
|
+
labels: [],
|
|
295
|
+
story: null,
|
|
296
|
+
state: 'OPEN',
|
|
297
|
+
nextActionDate: null,
|
|
298
|
+
nextActionHour: 9,
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
await useCase.run({
|
|
302
|
+
targetDates: [targetDate],
|
|
303
|
+
project: basicProject,
|
|
304
|
+
issues: [issue],
|
|
305
|
+
cacheUsed: false,
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalled();
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it('should process issue with nextActionDate equal to or before target date', async () => {
|
|
312
|
+
const pastDate = new Date('2000-01-01T00:00:00Z');
|
|
313
|
+
const issue: Issue = {
|
|
314
|
+
...mock<Issue>(),
|
|
315
|
+
labels: [],
|
|
316
|
+
story: null,
|
|
317
|
+
state: 'OPEN',
|
|
318
|
+
nextActionDate: pastDate,
|
|
319
|
+
nextActionHour: null,
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
const promise = useCase.run({
|
|
323
|
+
targetDates: [targetDate],
|
|
324
|
+
project: basicProject,
|
|
325
|
+
issues: [issue],
|
|
326
|
+
cacheUsed: false,
|
|
327
|
+
});
|
|
328
|
+
await jest.runAllTimersAsync();
|
|
329
|
+
await promise;
|
|
330
|
+
|
|
331
|
+
expect(mockIssueRepository.updateStory.mock.calls).toEqual([
|
|
332
|
+
[{ ...basicProject, story: basicProject.story }, issue, 'noStoryId'],
|
|
333
|
+
]);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it('should process multiple eligible issues and skip those with story: labels', async () => {
|
|
337
|
+
const eligibleIssue: Issue = {
|
|
338
|
+
...mock<Issue>(),
|
|
339
|
+
labels: [],
|
|
340
|
+
story: null,
|
|
341
|
+
state: 'OPEN',
|
|
342
|
+
nextActionDate: null,
|
|
343
|
+
nextActionHour: null,
|
|
344
|
+
};
|
|
345
|
+
const issueWithStoryLabel: Issue = {
|
|
346
|
+
...mock<Issue>(),
|
|
347
|
+
labels: ['story:high-priority'],
|
|
348
|
+
story: null,
|
|
349
|
+
state: 'OPEN',
|
|
350
|
+
nextActionDate: null,
|
|
351
|
+
nextActionHour: null,
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
const promise = useCase.run({
|
|
355
|
+
targetDates: [targetDate],
|
|
356
|
+
project: basicProject,
|
|
357
|
+
issues: [eligibleIssue, issueWithStoryLabel],
|
|
358
|
+
cacheUsed: false,
|
|
359
|
+
});
|
|
360
|
+
await jest.runAllTimersAsync();
|
|
361
|
+
await promise;
|
|
362
|
+
|
|
363
|
+
expect(mockIssueRepository.updateStory.mock.calls).toEqual([
|
|
364
|
+
[
|
|
365
|
+
{ ...basicProject, story: basicProject.story },
|
|
366
|
+
eligibleIssue,
|
|
367
|
+
'noStoryId',
|
|
368
|
+
],
|
|
369
|
+
]);
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
});
|
|
@@ -22,11 +22,13 @@ export class SetNoStoryIssueToStoryUseCase {
|
|
|
22
22
|
const isTargetIssue = (issue: Issue): boolean => {
|
|
23
23
|
return (
|
|
24
24
|
issue.story === null &&
|
|
25
|
+
!issue.labels.some((label) =>
|
|
26
|
+
label.toLowerCase().startsWith('story:'),
|
|
27
|
+
) &&
|
|
25
28
|
(issue.nextActionDate === null ||
|
|
26
29
|
issue.nextActionDate.getTime() <= input.targetDates[0].getTime()) &&
|
|
27
30
|
issue.nextActionHour === null &&
|
|
28
|
-
issue.state === 'OPEN'
|
|
29
|
-
issue.story === null
|
|
31
|
+
issue.state === 'OPEN'
|
|
30
32
|
);
|
|
31
33
|
};
|
|
32
34
|
const firstStory = input.project.story?.stories[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SetNoStoryIssueToStoryUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/SetNoStoryIssueToStoryUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,qBAAa,6BAA6B;IAC5B,QAAQ,CAAC,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC;gBAArD,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC;IAE1E,GAAG,GAAU,OAAO;QAClB,WAAW,EAAE,IAAI,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;KACpB,KAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"SetNoStoryIssueToStoryUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/SetNoStoryIssueToStoryUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,qBAAa,6BAA6B;IAC5B,QAAQ,CAAC,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC;gBAArD,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC;IAE1E,GAAG,GAAU,OAAO;QAClB,WAAW,EAAE,IAAI,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;KACpB,KAAG,OAAO,CAAC,IAAI,CAAC,CAoCf;CACH"}
|