github-issue-tower-defence-management 1.28.0 → 1.30.0
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/.github/workflows/test.yml +2 -2
- package/CHANGELOG.md +14 -0
- package/bin/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.js +15 -3
- package/bin/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.js.map +1 -1
- package/package.json +2 -2
- package/src/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.test.ts +253 -22
- package/src/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.ts +19 -3
- package/types/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.d.ts +1 -0
- package/types/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.d.ts.map +1 -1
|
@@ -39,13 +39,13 @@ jobs:
|
|
|
39
39
|
DOTENV_CONFIG_QUIET: true
|
|
40
40
|
|
|
41
41
|
- name: Upload test results
|
|
42
|
-
uses: actions/upload-artifact@
|
|
42
|
+
uses: actions/upload-artifact@v7
|
|
43
43
|
with:
|
|
44
44
|
name: jest-junit-report
|
|
45
45
|
path: reports/jest-junit
|
|
46
46
|
|
|
47
47
|
- name: Upload artifacts
|
|
48
|
-
uses: actions/upload-artifact@
|
|
48
|
+
uses: actions/upload-artifact@v7
|
|
49
49
|
with:
|
|
50
50
|
name: reports
|
|
51
51
|
path: reports
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [1.30.0](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.29.0...v1.30.0) (2026-03-09)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **core:** upgrade gh-cookie package from 1.3.9 to 1.3.22 ([a53edd0](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/a53edd0ecc99bcd519768f43ab5ecaa07171af42)), closes [#cookie](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/cookie)
|
|
7
|
+
|
|
8
|
+
# [1.29.0](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.28.0...v1.29.0) (2026-03-08)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **core:** add story view link to top of story issue in ConvertCheckboxToIssueInStoryIssueUseCase ([6325145](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/6325145baed3e55783220a32dffcfa9e2d12768e))
|
|
14
|
+
|
|
1
15
|
# [1.28.0](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.27.1...v1.28.0) (2026-03-04)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ConvertCheckboxToIssueInStoryIssueUseCase = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
4
5
|
class ConvertCheckboxToIssueInStoryIssueUseCase {
|
|
5
6
|
constructor(issueRepository) {
|
|
6
7
|
this.issueRepository = issueRepository;
|
|
@@ -22,11 +23,19 @@ class ConvertCheckboxToIssueInStoryIssueUseCase {
|
|
|
22
23
|
storyIssue.status === input.disabledStatus) {
|
|
23
24
|
continue;
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
+
const storyViewLink = this.buildStoryViewLink(input.urlOfStoryView, storyOption.name);
|
|
27
|
+
let newBody = storyIssue.body;
|
|
28
|
+
if (!storyIssue.body.includes(storyViewLink)) {
|
|
29
|
+
newBody = `${storyViewLink}\n\n${newBody}`;
|
|
30
|
+
await this.issueRepository.updateIssue({
|
|
31
|
+
...storyIssue,
|
|
32
|
+
body: newBody,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
if (!newBody.includes('- [ ] ')) {
|
|
26
36
|
continue;
|
|
27
37
|
}
|
|
28
|
-
const checkboxTextsNotCreatedIssue = this.findCheckboxTextsNotCreatedIssue(
|
|
29
|
-
let newBody = storyIssue.body;
|
|
38
|
+
const checkboxTextsNotCreatedIssue = this.findCheckboxTextsNotCreatedIssue(newBody);
|
|
30
39
|
for (const checkboxText of checkboxTextsNotCreatedIssue) {
|
|
31
40
|
const issueTitle = checkboxText.replace('STORYNAME', `${storyOption.name} #${storyIssue.number}`);
|
|
32
41
|
const newIssueBody = `- Parent issue: ${storyIssue.url}`;
|
|
@@ -46,6 +55,9 @@ class ConvertCheckboxToIssueInStoryIssueUseCase {
|
|
|
46
55
|
}
|
|
47
56
|
}
|
|
48
57
|
};
|
|
58
|
+
this.buildStoryViewLink = (urlOfStoryView, storyName) => {
|
|
59
|
+
return `${urlOfStoryView}?sliceBy%5Bvalue%5D=${(0, utils_1.encodeForURI)(storyName)}`;
|
|
60
|
+
};
|
|
49
61
|
this.findCheckboxTextsNotCreatedIssue = (storyIssueBody) => {
|
|
50
62
|
const regexToFindCheckboxes = /^- \[ ] (.*)$/gm;
|
|
51
63
|
const match = storyIssueBody.match(regexToFindCheckboxes);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConvertCheckboxToIssueInStoryIssueUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"ConvertCheckboxToIssueInStoryIssueUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "github-issue-tower-defence-management",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.30.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "bin/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"commander": "^14.0.0",
|
|
79
79
|
"cookie": "^1.0.1",
|
|
80
80
|
"dotenv": "^16.4.5",
|
|
81
|
-
"gh-cookie": "^1.3.
|
|
81
|
+
"gh-cookie": "^1.3.22",
|
|
82
82
|
"googleapis": "^146.0.0",
|
|
83
83
|
"typia": "^9.0.0",
|
|
84
84
|
"yaml": "^2.6.0"
|
|
@@ -10,19 +10,20 @@ describe('ConvertCheckboxToIssueInStoryIssueUseCase', () => {
|
|
|
10
10
|
const mockIssueRepository = mock<IssueRepository>();
|
|
11
11
|
|
|
12
12
|
describe('run', () => {
|
|
13
|
+
const basicStory = {
|
|
14
|
+
name: 'Story Field',
|
|
15
|
+
databaseId: 1,
|
|
16
|
+
fieldId: 'storyFieldId',
|
|
17
|
+
stories: [
|
|
18
|
+
{ ...mock<StoryOption>(), id: 'story1', name: 'Story 1' },
|
|
19
|
+
{ ...mock<StoryOption>(), id: 'story2', name: 'Story 2' },
|
|
20
|
+
{ ...mock<StoryOption>(), id: 'regular3', name: 'regular / Story 3' },
|
|
21
|
+
],
|
|
22
|
+
workflowManagementStory: { id: 'workflow1', name: 'Workflow Story' },
|
|
23
|
+
};
|
|
13
24
|
const basicProject: Project = {
|
|
14
25
|
...mock<Project>(),
|
|
15
|
-
story:
|
|
16
|
-
name: 'Story Field',
|
|
17
|
-
databaseId: 1,
|
|
18
|
-
fieldId: 'storyFieldId',
|
|
19
|
-
stories: [
|
|
20
|
-
{ ...mock<StoryOption>(), id: 'story1', name: 'Story 1' },
|
|
21
|
-
{ ...mock<StoryOption>(), id: 'story2', name: 'Story 2' },
|
|
22
|
-
{ ...mock<StoryOption>(), id: 'regular3', name: 'regular / Story 3' },
|
|
23
|
-
],
|
|
24
|
-
workflowManagementStory: { id: 'workflow1', name: 'Workflow Story' },
|
|
25
|
-
},
|
|
26
|
+
story: basicStory,
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
const basicStoryIssue1 = {
|
|
@@ -202,7 +203,7 @@ describe('ConvertCheckboxToIssueInStoryIssueUseCase', () => {
|
|
|
202
203
|
expectedGetIssueByUrlCalls: [],
|
|
203
204
|
},
|
|
204
205
|
{
|
|
205
|
-
name: 'should create new issues for checkboxes
|
|
206
|
+
name: 'should add story view link and create new issues for checkboxes',
|
|
206
207
|
input: {
|
|
207
208
|
project: basicProject,
|
|
208
209
|
issues: [basicStoryIssue1, basicStoryIssue2],
|
|
@@ -249,28 +250,54 @@ describe('ConvertCheckboxToIssueInStoryIssueUseCase', () => {
|
|
|
249
250
|
[
|
|
250
251
|
{
|
|
251
252
|
...basicStoryIssue1,
|
|
252
|
-
body:
|
|
253
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%201
|
|
254
|
+
|
|
255
|
+
- [ ] Task 1
|
|
256
|
+
- [ ] Task 2`,
|
|
257
|
+
},
|
|
258
|
+
],
|
|
259
|
+
[
|
|
260
|
+
{
|
|
261
|
+
...basicStoryIssue1,
|
|
262
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%201
|
|
263
|
+
|
|
264
|
+
- [ ] https://github.com/org/repo/issues/1
|
|
253
265
|
- [ ] Task 2`,
|
|
254
266
|
},
|
|
255
267
|
],
|
|
256
268
|
[
|
|
257
269
|
{
|
|
258
270
|
...basicStoryIssue1,
|
|
259
|
-
body:
|
|
271
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%201
|
|
272
|
+
|
|
273
|
+
- [ ] https://github.com/org/repo/issues/1
|
|
260
274
|
- [ ] https://github.com/org/repo/issues/2`,
|
|
261
275
|
},
|
|
262
276
|
],
|
|
263
277
|
[
|
|
264
278
|
{
|
|
265
279
|
...basicStoryIssue2,
|
|
266
|
-
body:
|
|
280
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%202
|
|
281
|
+
|
|
282
|
+
- [ ] Task 3
|
|
267
283
|
- [ ] Task 4`,
|
|
268
284
|
},
|
|
269
285
|
],
|
|
270
286
|
[
|
|
271
287
|
{
|
|
272
288
|
...basicStoryIssue2,
|
|
273
|
-
body:
|
|
289
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%202
|
|
290
|
+
|
|
291
|
+
- [ ] https://github.com/org/repo/issues/3
|
|
292
|
+
- [ ] Task 4`,
|
|
293
|
+
},
|
|
294
|
+
],
|
|
295
|
+
[
|
|
296
|
+
{
|
|
297
|
+
...basicStoryIssue2,
|
|
298
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%202
|
|
299
|
+
|
|
300
|
+
- [ ] https://github.com/org/repo/issues/3
|
|
274
301
|
- [ ] https://github.com/org/repo/issues/4`,
|
|
275
302
|
},
|
|
276
303
|
],
|
|
@@ -316,6 +343,119 @@ describe('ConvertCheckboxToIssueInStoryIssueUseCase', () => {
|
|
|
316
343
|
['https://github.com/org/repo/issues/4'],
|
|
317
344
|
],
|
|
318
345
|
},
|
|
346
|
+
{
|
|
347
|
+
name: 'should not add story view link when it already exists',
|
|
348
|
+
input: {
|
|
349
|
+
project: {
|
|
350
|
+
...basicProject,
|
|
351
|
+
story: {
|
|
352
|
+
...basicStory,
|
|
353
|
+
stories: [
|
|
354
|
+
{ ...mock<StoryOption>(), id: 'story1', name: 'Story 1' },
|
|
355
|
+
],
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
issues: [
|
|
359
|
+
{
|
|
360
|
+
...basicStoryIssue1,
|
|
361
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%201
|
|
362
|
+
|
|
363
|
+
- [ ] Task 1`,
|
|
364
|
+
},
|
|
365
|
+
],
|
|
366
|
+
cacheUsed: false,
|
|
367
|
+
urlOfStoryView: 'https://example.com',
|
|
368
|
+
disabledStatus: 'Closed',
|
|
369
|
+
storyObjectMap: new Map([['Story 1', basicStoryObject1]]),
|
|
370
|
+
},
|
|
371
|
+
expectedCreateNewIssueCalls: [
|
|
372
|
+
[
|
|
373
|
+
'org',
|
|
374
|
+
'repo',
|
|
375
|
+
'Task 1',
|
|
376
|
+
'- Parent issue: https://github.com/org/repo/issues/123',
|
|
377
|
+
[],
|
|
378
|
+
[],
|
|
379
|
+
],
|
|
380
|
+
],
|
|
381
|
+
expectedUpdateIssueCalls: [
|
|
382
|
+
[
|
|
383
|
+
{
|
|
384
|
+
...basicStoryIssue1,
|
|
385
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%201
|
|
386
|
+
|
|
387
|
+
- [ ] https://github.com/org/repo/issues/1`,
|
|
388
|
+
},
|
|
389
|
+
],
|
|
390
|
+
],
|
|
391
|
+
expectedUpdateStoryCalls: [
|
|
392
|
+
[
|
|
393
|
+
{
|
|
394
|
+
...basicProject,
|
|
395
|
+
story: {
|
|
396
|
+
...basicStory,
|
|
397
|
+
stories: [
|
|
398
|
+
{ ...mock<StoryOption>(), id: 'story1', name: 'Story 1' },
|
|
399
|
+
],
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
...mock<Issue>(),
|
|
404
|
+
url: 'https://github.com/org/repo/issues/1',
|
|
405
|
+
},
|
|
406
|
+
'story1',
|
|
407
|
+
],
|
|
408
|
+
],
|
|
409
|
+
expectedGetIssueByUrlCalls: [['https://github.com/org/repo/issues/1']],
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
name: 'should add story view link even when no checkboxes exist',
|
|
413
|
+
input: {
|
|
414
|
+
project: {
|
|
415
|
+
...basicProject,
|
|
416
|
+
story: {
|
|
417
|
+
...basicStory,
|
|
418
|
+
stories: [
|
|
419
|
+
{ ...mock<StoryOption>(), id: 'story1', name: 'Story 1' },
|
|
420
|
+
],
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
issues: [
|
|
424
|
+
{
|
|
425
|
+
...basicStoryIssue1,
|
|
426
|
+
body: 'Some description without checkboxes',
|
|
427
|
+
},
|
|
428
|
+
],
|
|
429
|
+
cacheUsed: false,
|
|
430
|
+
urlOfStoryView: 'https://example.com',
|
|
431
|
+
disabledStatus: 'Closed',
|
|
432
|
+
storyObjectMap: new Map([
|
|
433
|
+
[
|
|
434
|
+
'Story 1',
|
|
435
|
+
{
|
|
436
|
+
...basicStoryObject1,
|
|
437
|
+
storyIssue: {
|
|
438
|
+
...basicStoryIssue1,
|
|
439
|
+
body: 'Some description without checkboxes',
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
],
|
|
443
|
+
]),
|
|
444
|
+
},
|
|
445
|
+
expectedCreateNewIssueCalls: [],
|
|
446
|
+
expectedUpdateIssueCalls: [
|
|
447
|
+
[
|
|
448
|
+
{
|
|
449
|
+
...basicStoryIssue1,
|
|
450
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%201
|
|
451
|
+
|
|
452
|
+
Some description without checkboxes`,
|
|
453
|
+
},
|
|
454
|
+
],
|
|
455
|
+
],
|
|
456
|
+
expectedUpdateStoryCalls: [],
|
|
457
|
+
expectedGetIssueByUrlCalls: [],
|
|
458
|
+
},
|
|
319
459
|
{
|
|
320
460
|
name: 'should create new issues with replaced STORYNAME for checkboxes and update story issue',
|
|
321
461
|
input: {
|
|
@@ -371,28 +511,54 @@ describe('ConvertCheckboxToIssueInStoryIssueUseCase', () => {
|
|
|
371
511
|
[
|
|
372
512
|
{
|
|
373
513
|
...basicStoryIssue1,
|
|
374
|
-
body:
|
|
514
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%201
|
|
515
|
+
|
|
516
|
+
- [ ] Task 1
|
|
375
517
|
- [ ] Task 2 for \`STORYNAME\``,
|
|
376
518
|
},
|
|
377
519
|
],
|
|
378
520
|
[
|
|
379
521
|
{
|
|
380
522
|
...basicStoryIssue1,
|
|
381
|
-
body:
|
|
523
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%201
|
|
524
|
+
|
|
525
|
+
- [ ] https://github.com/org/repo/issues/1
|
|
526
|
+
- [ ] Task 2 for \`STORYNAME\``,
|
|
527
|
+
},
|
|
528
|
+
],
|
|
529
|
+
[
|
|
530
|
+
{
|
|
531
|
+
...basicStoryIssue1,
|
|
532
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%201
|
|
533
|
+
|
|
534
|
+
- [ ] https://github.com/org/repo/issues/1
|
|
382
535
|
- [ ] https://github.com/org/repo/issues/2`,
|
|
383
536
|
},
|
|
384
537
|
],
|
|
385
538
|
[
|
|
386
539
|
{
|
|
387
540
|
...basicStoryIssue2,
|
|
388
|
-
body:
|
|
541
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%202
|
|
542
|
+
|
|
543
|
+
- [ ] Task 3
|
|
544
|
+
- [ ] Task 4`,
|
|
545
|
+
},
|
|
546
|
+
],
|
|
547
|
+
[
|
|
548
|
+
{
|
|
549
|
+
...basicStoryIssue2,
|
|
550
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%202
|
|
551
|
+
|
|
552
|
+
- [ ] https://github.com/org/repo/issues/3
|
|
389
553
|
- [ ] Task 4`,
|
|
390
554
|
},
|
|
391
555
|
],
|
|
392
556
|
[
|
|
393
557
|
{
|
|
394
558
|
...basicStoryIssue2,
|
|
395
|
-
body:
|
|
559
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%202
|
|
560
|
+
|
|
561
|
+
- [ ] https://github.com/org/repo/issues/3
|
|
396
562
|
- [ ] https://github.com/org/repo/issues/4`,
|
|
397
563
|
},
|
|
398
564
|
],
|
|
@@ -520,7 +686,29 @@ describe('ConvertCheckboxToIssueInStoryIssueUseCase', () => {
|
|
|
520
686
|
...basicStoryIssue1,
|
|
521
687
|
org: 'orgA',
|
|
522
688
|
repo: 'repoA',
|
|
523
|
-
body:
|
|
689
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%201
|
|
690
|
+
|
|
691
|
+
- [ ] Task 1`,
|
|
692
|
+
},
|
|
693
|
+
],
|
|
694
|
+
[
|
|
695
|
+
{
|
|
696
|
+
...basicStoryIssue1,
|
|
697
|
+
org: 'orgA',
|
|
698
|
+
repo: 'repoA',
|
|
699
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%201
|
|
700
|
+
|
|
701
|
+
- [ ] https://github.com/orgA/repoA/issues/1`,
|
|
702
|
+
},
|
|
703
|
+
],
|
|
704
|
+
[
|
|
705
|
+
{
|
|
706
|
+
...basicStoryIssue2,
|
|
707
|
+
org: 'orgB',
|
|
708
|
+
repo: 'repoB',
|
|
709
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%202
|
|
710
|
+
|
|
711
|
+
- [ ] Task 2`,
|
|
524
712
|
},
|
|
525
713
|
],
|
|
526
714
|
[
|
|
@@ -528,7 +716,9 @@ describe('ConvertCheckboxToIssueInStoryIssueUseCase', () => {
|
|
|
528
716
|
...basicStoryIssue2,
|
|
529
717
|
org: 'orgB',
|
|
530
718
|
repo: 'repoB',
|
|
531
|
-
body:
|
|
719
|
+
body: `https://example.com?sliceBy%5Bvalue%5D=Story%202
|
|
720
|
+
|
|
721
|
+
- [ ] https://github.com/orgB/repoB/issues/2`,
|
|
532
722
|
},
|
|
533
723
|
],
|
|
534
724
|
],
|
|
@@ -610,6 +800,47 @@ describe('ConvertCheckboxToIssueInStoryIssueUseCase', () => {
|
|
|
610
800
|
);
|
|
611
801
|
});
|
|
612
802
|
|
|
803
|
+
describe('buildStoryViewLink', () => {
|
|
804
|
+
const testCases: {
|
|
805
|
+
name: string;
|
|
806
|
+
urlOfStoryView: string;
|
|
807
|
+
storyName: string;
|
|
808
|
+
expected: string;
|
|
809
|
+
}[] = [
|
|
810
|
+
{
|
|
811
|
+
name: 'should build story view link with encoded story name',
|
|
812
|
+
urlOfStoryView: 'https://github.com/users/TestUser/projects/1/views/1',
|
|
813
|
+
storyName: 'Story 1',
|
|
814
|
+
expected:
|
|
815
|
+
'https://github.com/users/TestUser/projects/1/views/1?sliceBy%5Bvalue%5D=Story%201',
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
name: 'should handle story name with special characters',
|
|
819
|
+
urlOfStoryView: 'https://github.com/users/TestUser/projects/1/views/1',
|
|
820
|
+
storyName: 'planning business trip for next spring',
|
|
821
|
+
expected:
|
|
822
|
+
'https://github.com/users/TestUser/projects/1/views/1?sliceBy%5Bvalue%5D=planning%20business%20trip%20for%20next%20spring',
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
name: 'should handle story name with hash',
|
|
826
|
+
urlOfStoryView: 'https://github.com/users/TestUser/projects/1/views/1',
|
|
827
|
+
storyName: 'Story #1',
|
|
828
|
+
expected:
|
|
829
|
+
'https://github.com/users/TestUser/projects/1/views/1?sliceBy%5Bvalue%5D=Story%20%231',
|
|
830
|
+
},
|
|
831
|
+
];
|
|
832
|
+
|
|
833
|
+
testCases.forEach(({ name, urlOfStoryView, storyName, expected }) => {
|
|
834
|
+
it(name, () => {
|
|
835
|
+
const useCase = new ConvertCheckboxToIssueInStoryIssueUseCase(
|
|
836
|
+
mockIssueRepository,
|
|
837
|
+
);
|
|
838
|
+
const result = useCase.buildStoryViewLink(urlOfStoryView, storyName);
|
|
839
|
+
expect(result).toEqual(expected);
|
|
840
|
+
});
|
|
841
|
+
});
|
|
842
|
+
});
|
|
843
|
+
|
|
613
844
|
describe('findCheckboxTextsNotCreatedIssue', () => {
|
|
614
845
|
const testCases: {
|
|
615
846
|
name: string;
|
|
@@ -2,6 +2,7 @@ import { Issue } from '../entities/Issue';
|
|
|
2
2
|
import { IssueRepository } from './adapter-interfaces/IssueRepository';
|
|
3
3
|
import { Project } from '../entities/Project';
|
|
4
4
|
import { StoryObjectMap } from '../entities/StoryObjectMap';
|
|
5
|
+
import { encodeForURI } from './utils';
|
|
5
6
|
|
|
6
7
|
export class ConvertCheckboxToIssueInStoryIssueUseCase {
|
|
7
8
|
constructor(
|
|
@@ -38,12 +39,24 @@ export class ConvertCheckboxToIssueInStoryIssueUseCase {
|
|
|
38
39
|
storyIssue.status === input.disabledStatus
|
|
39
40
|
) {
|
|
40
41
|
continue;
|
|
41
|
-
}
|
|
42
|
+
}
|
|
43
|
+
const storyViewLink = this.buildStoryViewLink(
|
|
44
|
+
input.urlOfStoryView,
|
|
45
|
+
storyOption.name,
|
|
46
|
+
);
|
|
47
|
+
let newBody = storyIssue.body;
|
|
48
|
+
if (!storyIssue.body.includes(storyViewLink)) {
|
|
49
|
+
newBody = `${storyViewLink}\n\n${newBody}`;
|
|
50
|
+
await this.issueRepository.updateIssue({
|
|
51
|
+
...storyIssue,
|
|
52
|
+
body: newBody,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (!newBody.includes('- [ ] ')) {
|
|
42
56
|
continue;
|
|
43
57
|
}
|
|
44
58
|
const checkboxTextsNotCreatedIssue =
|
|
45
|
-
this.findCheckboxTextsNotCreatedIssue(
|
|
46
|
-
let newBody = storyIssue.body;
|
|
59
|
+
this.findCheckboxTextsNotCreatedIssue(newBody);
|
|
47
60
|
for (const checkboxText of checkboxTextsNotCreatedIssue) {
|
|
48
61
|
const issueTitle = checkboxText.replace(
|
|
49
62
|
'STORYNAME',
|
|
@@ -80,6 +93,9 @@ export class ConvertCheckboxToIssueInStoryIssueUseCase {
|
|
|
80
93
|
}
|
|
81
94
|
}
|
|
82
95
|
};
|
|
96
|
+
buildStoryViewLink = (urlOfStoryView: string, storyName: string): string => {
|
|
97
|
+
return `${urlOfStoryView}?sliceBy%5Bvalue%5D=${encodeForURI(storyName)}`;
|
|
98
|
+
};
|
|
83
99
|
findCheckboxTextsNotCreatedIssue = (storyIssueBody: string): string[] => {
|
|
84
100
|
const regexToFindCheckboxes = /^- \[ ] (.*)$/gm;
|
|
85
101
|
const match = storyIssueBody.match(regexToFindCheckboxes);
|
|
@@ -13,6 +13,7 @@ export declare class ConvertCheckboxToIssueInStoryIssueUseCase {
|
|
|
13
13
|
disabledStatus: string;
|
|
14
14
|
storyObjectMap: StoryObjectMap;
|
|
15
15
|
}) => Promise<void>;
|
|
16
|
+
buildStoryViewLink: (urlOfStoryView: string, storyName: string) => string;
|
|
16
17
|
findCheckboxTextsNotCreatedIssue: (storyIssueBody: string) => string[];
|
|
17
18
|
}
|
|
18
19
|
//# sourceMappingURL=ConvertCheckboxToIssueInStoryIssueUseCase.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConvertCheckboxToIssueInStoryIssueUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.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;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"ConvertCheckboxToIssueInStoryIssueUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.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;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG5D,qBAAa,yCAAyC;IAElD,QAAQ,CAAC,eAAe,EAAE,IAAI,CAC5B,eAAe,EACf,gBAAgB,GAAG,aAAa,GAAG,aAAa,GAAG,eAAe,CACnE;gBAHQ,eAAe,EAAE,IAAI,CAC5B,eAAe,EACf,gBAAgB,GAAG,aAAa,GAAG,aAAa,GAAG,eAAe,CACnE;IAGH,GAAG,UAAiB;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,cAAc,CAAC;KAChC,KAAG,OAAO,CAAC,IAAI,CAAC,CAyEf;IACF,kBAAkB,mBAAoB,MAAM,aAAa,MAAM,KAAG,MAAM,CAEtE;IACF,gCAAgC,mBAAoB,MAAM,KAAG,MAAM,EAAE,CAcnE;CACH"}
|