• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

moosetechnology / GitProjectHealth / 11163602359

03 Oct 2024 02:08PM UTC coverage: 58.906% (+5.6%) from 53.297%
11163602359

push

github

web-flow
feat: bitbucket importer (#74)

* feat: add bitbucket package + base bitbucket api

* chore: add bitbucket package in baseline

* feat: get user method in bitBucket api

* feat: importUser for bitbucket importer

* feat: change bitbucket api for 1.0 + add projects method

* feat(BitBucketApi): repositories of a project

* feat(BitBucketApi): commits of repo in project since until date

* feat(BitBucketImporter): importContributedProjectsOfUser method

* refactor: improve repo/project transformation into GLHProject

* test: add tests for bitbucket api and importer

* feat: base completeImportProject

* feat: import commits of project in bit bucket importer

* feat(bitBucketImporter): import creator of commit method

* refactor: move testImportUser method

* refactor: rename importCommitsOfProject:since:until

* fix: change imporContributedProject test to work on any date

* feat(BitBucketApi): remove merge commit in commitsOfRepo:Inproject

* feat(bitBucketImporter): add getContributionFromDiff

* test: improve tests getContributionFromDiffs:

* feat(bitBucketModelImporter): add withInitialCommits

* feat(BitBucketApi): add usersByUserName

* feat(BitBucketModelImporter): importUserByUsername

* fix: problem with commitsInRepoOfProject

* fix: small fix in bitbucket importer

* fix: infinit loop with importContributedProjects

* feat(BitBucketModelImporter): fix importCreatorOfCommit + add tests

* test(BitBucketModelImporter): fix test importContributedProject

* feat: add parentsId in bit bucket importer  commit parsing

* feat(BitBucketApi): pullrequestsOfRepo:InProject:Since:Until

* feat(bitbucketModelImporter): importMergeRequests:since:until

* fix(bitBucketImporter): improve precision in dates

* feat(BitBucketModelImporter): add reviewers in parsing of pull requests

* feat(BitBucketApi):  activities of pull requests

* feat(BitBucketModelImporter): import merge request merger
... (continued)

1952 of 2214 new or added lines in 12 files covered. (88.17%)

1 existing line in 1 file now uncovered.

8903 of 15114 relevant lines covered (58.91%)

0.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.48
/src/BitBucketHealth-Model-Importer-Tests/BitBucketApiMock.class.st
1
Class {
2
        #name : #BitBucketApiMock,
3
        #superclass : #Object,
4
        #instVars : [
5
                'userMock',
6
                'commits',
7
                'diffs',
8
                'mergeRequests'
9
        ],
10
        #category : #'BitBucketHealth-Model-Importer-Tests'
11
}
12

13
{ #category : #'api - pull-requests' }
14
BitBucketApiMock >> activitiesOfPullRequest: pullRequestId inRepo: repoSlug ofProject: projectKey [
1✔
15

1✔
16
        ^self pullRequestActivities
1✔
17
]
1✔
18

19
{ #category : #accessing }
20
BitBucketApiMock >> commits [
1✔
21

1✔
22
        ^ commits
1✔
23
]
1✔
24

25
{ #category : #accessing }
26
BitBucketApiMock >> commits1 [
1✔
27

1✔
28
        | commits1 |
1✔
29
        commits1 := '[
1✔
30
    {
1✔
31
      "id": "abcdef0123abcdef4567abcdef8987abcdef6543",
1✔
32
                "message": "message test",
1✔
33
      "displayId": "abcdef0123a",
1✔
34
      "author": {
1✔
35
        "name": "charlie",
1✔
36
        "emailAddress": "charlie@example.com"
1✔
37
      },
1✔
38
      "authorTimestamp": 1727168151000,
1✔
39
      "committer": {
1✔
40
        "name": "charlie",
1✔
41
        "emailAddress": "charlie@example.com"
1✔
42
      },
1✔
43
      "committerTimestamp": 1727168151000,
1✔
44
      "message": "WIP on feature 1",
1✔
45
      "parents": [
1✔
46
        {
1✔
47
          "id": "abcdef0123abcdef4567abcdef8987abcdef6543",
1✔
48
          "displayId": "abcdef0"
1✔
49
        }
1✔
50
      ]
1✔
51
    }
1✔
52
  ]'.
1✔
53

1✔
54
        ^ commits1 := (NeoJSONReader on: commits1 readStream) next
1✔
55
]
1✔
56

57
{ #category : #accessing }
58
BitBucketApiMock >> commits: anObject [
1✔
59

1✔
60
        commits := anObject
1✔
61
]
1✔
62

63
{ #category : #'api - pull-requests' }
64
BitBucketApiMock >> commitsOfPullRequest: mergeRequestId ofRepo: repoSlug inProject: projectKey [
1✔
65

1✔
66
        ^commits
1✔
67
]
1✔
68

69
{ #category : #'api - projects' }
70
BitBucketApiMock >> commitsOfRepo: repositorySlug inProject: projectKey since: since until: until [
1✔
71

1✔
72
        ^ self commits select: [ :commit |
1✔
73
                  | commitDate |
1✔
74
                  commitDate := DateAndTime fromUnixTime:
1✔
75
                                        (commit at: #committerTimestamp) / 1000.
1✔
76
                  commitDate >= since asDate and: commitDate <= until asDate ]
1✔
77
]
1✔
78

79
{ #category : #accessing }
80
BitBucketApiMock >> declinedMergeRequest [
1✔
81

1✔
82
        | pullRequest |
1✔
83
        pullRequest := '{
1✔
84
      "id": 539,
1✔
85
      "version": 10,
1✔
86
      "title": "title",
1✔
87
      "state": "DECLINED",
1✔
88
      "open": false,
1✔
89
      "closed": true,
1✔
90
                  "createdDate": 1721396425473,
1✔
91
                  "updatedDate": 1721457513310,
1✔
92
                  "closedDate": 1721457513310,
1✔
93
      "fromRef": {
1✔
94
        "id": "refs/heads/wip/1",
1✔
95
        "displayId": "wip/1",
1✔
96
        "latestCommit": "2",
1✔
97
        "repository": {
1✔
98
          "slug": "repoSlug",
1✔
99
          "id": 242,
1✔
100
          "name": "repo-name",
1✔
101
          "scmId": "git",
1✔
102
          "state": "AVAILABLE",
1✔
103
          "statusMessage": "Available",
1✔
104
          "forkable": true,
1✔
105
          "project": {
1✔
106
            "key": "project-key",
1✔
107
            "id": 242,
1✔
108
            "name": "project-name",
1✔
109
            "description": "project description",
1✔
110
            "public": true,
1✔
111
            "type": "NORMAL",
1✔
112
            "links": {
1✔
113
              "self": [
1✔
114
                {
1✔
115
                  "href": "link"
1✔
116
                }
1✔
117
              ]
1✔
118
            }
1✔
119
          },
1✔
120
          "public": false,
1✔
121
          "links": {
1✔
122
            "clone": [
1✔
123
              {
1✔
124
                "href": "clone",
1✔
125
                "name": "ssh"
1✔
126
              },
1✔
127
              {
1✔
128
                "href": "clone",
1✔
129
                "name": "http"
1✔
130
              }
1✔
131
            ],
1✔
132
            "self": [
1✔
133
              {
1✔
134
                "href": "link"
1✔
135
              }
1✔
136
            ]
1✔
137
          }
1✔
138
        }
1✔
139
      },
1✔
140
      "toRef": {
1✔
141
        "id": "refs/heads/develop/trunk",
1✔
142
        "displayId": "develop/trunk",
1✔
143
        "latestCommit": "3",
1✔
144
        "repository": {
1✔
145
          "slug": "repo-slug",
1✔
146
          "id": 242,
1✔
147
          "name": "repo-name",
1✔
148
          "scmId": "git",
1✔
149
          "state": "AVAILABLE",
1✔
150
          "statusMessage": "Available",
1✔
151
          "forkable": true,
1✔
152
          "project": {
1✔
153
            "key": "project-key",
1✔
154
            "id": 242,
1✔
155
            "name": "project-name",
1✔
156
            "description": "description",
1✔
157
            "public": true,
1✔
158
            "type": "NORMAL",
1✔
159
            "links": {
1✔
160
              "self": [
1✔
161
                {
1✔
162
                  "href": "link"
1✔
163
                }
1✔
164
              ]
1✔
165
            }
1✔
166
          },
1✔
167
          "public": false,
1✔
168
          "links": {
1✔
169
            "clone": [
1✔
170
              {
1✔
171
                "href": "link",
1✔
172
                "name": "ssh"
1✔
173
              },
1✔
174
              {
1✔
175
                "href": "link-http",
1✔
176
                "name": "http"
1✔
177
              }
1✔
178
            ],
1✔
179
            "self": [
1✔
180
              {
1✔
181
                "href": "link-self"
1✔
182
              }
1✔
183
            ]
1✔
184
          }
1✔
185
        }
1✔
186
      },
1✔
187
      "locked": false,
1✔
188
      "author": {
1✔
189
        "user": {
1✔
190
          "name": "user-name",
1✔
191
          "id": 1,
1✔
192
          "displayName": "user-display-name",
1✔
193
          "active": false,
1✔
194
          "slug": "user-slug",
1✔
195
          "type": "NORMAL",
1✔
196
          "links": {
1✔
197
            "self": [
1✔
198
              {
1✔
199
                "href": "link-self"
1✔
200
              }
1✔
201
            ]
1✔
202
          }
1✔
203
        },
1✔
204
        "role": "AUTHOR",
1✔
205
        "approved": false,
1✔
206
        "status": "UNAPPROVED"
1✔
207
      },
1✔
208
      "reviewers": [
1✔
209
        {
1✔
210
          "user": {
1✔
211
            "name": "reviewer-name",
1✔
212
            "emailAddress": "reviewer@email.com",
1✔
213
            "id": 1713,
1✔
214
            "displayName": "reviewer-display-name",
1✔
215
            "active": true,
1✔
216
            "slug": "reviewer-slug",
1✔
217
            "type": "NORMAL",
1✔
218
            "links": {
1✔
219
              "self": [
1✔
220
                {
1✔
221
                  "href": "link-self"
1✔
222
                }
1✔
223
              ]
1✔
224
            }
1✔
225
          },
1✔
226
          "lastReviewedCommit": "2",
1✔
227
          "role": "REVIEWER",
1✔
228
          "approved": true,
1✔
229
          "status": "APPROVED"
1✔
230
        },
1✔
231
        {
1✔
232
          "user": {
1✔
233
            "name": "reveiwer2-name",
1✔
234
            "emailAddress": "reviewer2@email.com",
1✔
235
            "id": 49,
1✔
236
            "displayName": "reviewer2 display name",
1✔
237
            "active": true,
1✔
238
            "slug": "reviewer2-slug",
1✔
239
            "type": "NORMAL",
1✔
240
            "links": {
1✔
241
              "self": [
1✔
242
                {
1✔
243
                  "href": "link-self"
1✔
244
                }
1✔
245
              ]
1✔
246
            }
1✔
247
          },
1✔
248
          "role": "REVIEWER",
1✔
249
          "approved": false,
1✔
250
          "status": "UNAPPROVED"
1✔
251
        }
1✔
252
      ],
1✔
253
      "participants": [],
1✔
254
      "properties": {
1✔
255
        "mergeResult": {
1✔
256
          "outcome": "CONFLICTED",
1✔
257
          "current": true
1✔
258
        },
1✔
259
        "resolvedTaskCount": 0,
1✔
260
        "commentCount": 4,
1✔
261
        "openTaskCount": 0
1✔
262
      },
1✔
263
      "links": {
1✔
264
        "self": [
1✔
265
          {
1✔
266
            "href": "link"
1✔
267
          }
1✔
268
        ]
1✔
269
      }
1✔
270
    }'.
1✔
271

1✔
272
        ^ pullRequest := (NeoJSONReader on: pullRequest readStream) next
1✔
273
]
1✔
274

275
{ #category : #accessing }
276
BitBucketApiMock >> diffs [
1✔
277

1✔
278
        ^ diffs
1✔
279
]
1✔
280

281
{ #category : #accessing }
282
BitBucketApiMock >> diffs1 [
1✔
283

1✔
284
        | diffs1 |
1✔
285
        diffs1 := '{
1✔
286
  "fromHash": null,
1✔
287
  "toHash": "123",
1✔
288
  "contextLines": 10,
1✔
289
  "whitespace": "SHOW",
1✔
290
  "diffs": [
1✔
291
    {
1✔
292
      "source": {
1✔
293
        "components": [
1✔
294
          "build.gradle"
1✔
295
        ],
1✔
296
        "parent": "",
1✔
297
        "name": "build.gradle",
1✔
298
        "extension": "gradle",
1✔
299
        "toString": "build.gradle"
1✔
300
      },
1✔
301
      "destination": {
1✔
302
        "components": [
1✔
303
          "build.gradle"
1✔
304
        ],
1✔
305
        "parent": "",
1✔
306
        "name": "build.gradle",
1✔
307
        "extension": "gradle",
1✔
308
        "toString": "build.gradle"
1✔
309
      },
1✔
310
      "hunks": [
1✔
311
        {
1✔
312
          "sourceLine": 1,
1✔
313
          "sourceSpan": 14,
1✔
314
          "destinationLine": 1,
1✔
315
          "destinationSpan": 14,
1✔
316
          "segments": [
1✔
317
            {
1✔
318
              "type": "CONTEXT",
1✔
319
              "lines": [
1✔
320
                {
1✔
321
                  "source": 3,
1✔
322
                  "destination": 3,
1✔
323
                  "line": " line",
1✔
324
                  "truncated": false
1✔
325
                }
1✔
326
              ],
1✔
327
              "truncated": false
1✔
328
            },
1✔
329
            {
1✔
330
              "type": "REMOVED",
1✔
331
              "lines": [
1✔
332
                {
1✔
333
                  "source": 4,
1✔
334
                  "destination": 4,
1✔
335
                  "line": "line4",
1✔
336
                  "truncated": false
1✔
337
                }
1✔
338
              ],
1✔
339
              "truncated": false
1✔
340
            },
1✔
341
            {
1✔
342
              "type": "ADDED",
1✔
343
              "lines": [
1✔
344
                {
1✔
345
                  "source": 5,
1✔
346
                  "destination": 4,
1✔
347
                  "line": "line5",
1✔
348
                  "truncated": false
1✔
349
                }
1✔
350
              ],
1✔
351
              "truncated": false
1✔
352
            },
1✔
353
            {
1✔
354
              "type": "CONTEXT",
1✔
355
              "lines": [
1✔
356
                {
1✔
357
                  "source": 14,
1✔
358
                  "destination": 14,
1✔
359
                  "line": "",
1✔
360
                  "truncated": false
1✔
361
                }
1✔
362
              ],
1✔
363
              "truncated": false
1✔
364
            }
1✔
365
          ],
1✔
366
          "truncated": false
1✔
367
        }
1✔
368
      ],
1✔
369
      "truncated": false
1✔
370
    }
1✔
371
  ],
1✔
372
  "truncated": false
1✔
373
}'.
1✔
374

1✔
375
        ^ diffs1 := (NeoJSONReader on: diffs1 readStream) next
1✔
376
]
1✔
377

378
{ #category : #accessing }
379
BitBucketApiMock >> diffs: anObject [
1✔
380

1✔
381
        diffs := anObject
1✔
382
]
1✔
383

384
{ #category : #'api - commits' }
385
BitBucketApiMock >> diffsOfCommit: commitID inRepo: repositorySlug inProject: projectKey [
1✔
386
        ^diffs 
1✔
387
]
1✔
388

389
{ #category : #accessing }
390
BitBucketApiMock >> diffsWithoutAdded [
1✔
391

1✔
392
        | diffsWithoutAdded |
1✔
393
        diffsWithoutAdded := '{
1✔
394
  "fromHash": null,
1✔
395
  "toHash": "3",
1✔
396
  "contextLines": 10,
1✔
397
  "whitespace": "SHOW",
1✔
398
  "diffs": [
1✔
399
    {
1✔
400
      "source": {
1✔
401
        "components": [
1✔
402
          "build.gradle"
1✔
403
        ],
1✔
404
        "parent": "",
1✔
405
        "name": "build.gradle",
1✔
406
        "extension": "gradle",
1✔
407
        "toString": "build.gradle"
1✔
408
      },
1✔
409
      "destination": {
1✔
410
        "components": [
1✔
411
          "build.gradle"
1✔
412
        ],
1✔
413
        "parent": "",
1✔
414
        "name": "build.gradle",
1✔
415
        "extension": "gradle",
1✔
416
        "toString": "build.gradle"
1✔
417
      },
1✔
418
      "hunks": [
1✔
419
        {
1✔
420
          "sourceLine": 1,
1✔
421
          "sourceSpan": 14,
1✔
422
          "destinationLine": 1,
1✔
423
          "destinationSpan": 14,
1✔
424
          "segments": [
1✔
425
            {
1✔
426
              "type": "CONTEXT",
1✔
427
              "lines": [
1✔
428
                {
1✔
429
                  "source": 1,
1✔
430
                  "destination": 1,
1✔
431
                  "line": "line1",
1✔
432
                  "truncated": false
1✔
433
                },
1✔
434
                {
1✔
435
                  "source": 2,
1✔
436
                  "destination": 2,
1✔
437
                  "line": "line2",
1✔
438
                  "truncated": false
1✔
439
                },
1✔
440
                {
1✔
441
                  "source": 3,
1✔
442
                  "destination": 3,
1✔
443
                  "line": "line3",
1✔
444
                  "truncated": false
1✔
445
                }
1✔
446
              ],
1✔
447
              "truncated": false
1✔
448
            },
1✔
449
            {
1✔
450
              "type": "REMOVED",
1✔
451
              "lines": [
1✔
452
                {
1✔
453
                  "source": 4,
1✔
454
                  "destination": 4,
1✔
455
                  "line": "line4",
1✔
456
                  "truncated": false
1✔
457
                }
1✔
458
              ],
1✔
459
              "truncated": false
1✔
460
            },
1✔
461
            {
1✔
462
              "type": "CONTEXT",
1✔
463
              "lines": [
1✔
464
                {
1✔
465
                  "source": 5,
1✔
466
                  "destination": 5,
1✔
467
                  "line": "",
1✔
468
                  "truncated": false
1✔
469
                }
1✔
470
              ],
1✔
471
              "truncated": false
1✔
472
            }
1✔
473
          ],
1✔
474
          "truncated": false
1✔
475
        }
1✔
476
      ],
1✔
477
      "truncated": false
1✔
478
    }
1✔
479
  ],
1✔
480
  "truncated": false
1✔
481
}'.
1✔
482

1✔
483
        ^ diffsWithoutAdded := (NeoJSONReader on:
1✔
484
                                        diffsWithoutAdded readStream) next
1✔
485
]
1✔
486

487
{ #category : #accessing }
488
BitBucketApiMock >> diffsWithoutHunks [
1✔
489

1✔
490
        | diffsWithoutHunks |
1✔
491
        diffsWithoutHunks := '{
1✔
492
  "fromHash": null,
1✔
493
  "toHash": "2",
1✔
494
  "contextLines": 10,
1✔
495
  "whitespace": "SHOW",
1✔
496
  "diffs": [
1✔
497
    {
1✔
498
      "source": {
1✔
499
        "components": [
1✔
500
          "build.gradle"
1✔
501
        ],
1✔
502
        "parent": "",
1✔
503
        "name": "build.gradle",
1✔
504
        "extension": "gradle",
1✔
505
        "toString": "build.gradle"
1✔
506
      },
1✔
507
      "destination": {
1✔
508
        "components": [
1✔
509
          "build.gradle"
1✔
510
        ],
1✔
511
        "parent": "",
1✔
512
        "name": "build.gradle",
1✔
513
        "extension": "gradle",
1✔
514
        "toString": "build.gradle"
1✔
515
      },
1✔
516
          
1✔
517
      "truncated": false
1✔
518
    }
1✔
519
  ],
1✔
520
  "truncated": false
1✔
521
}'.
1✔
522

1✔
523
        ^ diffsWithoutHunks := (NeoJSONReader on:
1✔
524
                                        diffsWithoutHunks readStream) next
1✔
525
]
1✔
526

527
{ #category : #accessing }
528
BitBucketApiMock >> diffsWithoutRemoved [
1✔
529

1✔
530
        | diffsWithoutRemoved |
1✔
531
        diffsWithoutRemoved := '{
1✔
532
  "fromHash": null,
1✔
533
  "toHash": "1",
1✔
534
  "contextLines": 10,
1✔
535
  "whitespace": "SHOW",
1✔
536
  "diffs": [
1✔
537
    {
1✔
538
      "source": {
1✔
539
        "components": [
1✔
540
          "build.gradle"
1✔
541
        ],
1✔
542
        "parent": "",
1✔
543
        "name": "build.gradle",
1✔
544
        "extension": "gradle",
1✔
545
        "toString": "build.gradle"
1✔
546
      },
1✔
547
      "destination": {
1✔
548
        "components": [
1✔
549
          "build.gradle"
1✔
550
        ],
1✔
551
        "parent": "",
1✔
552
        "name": "build.gradle",
1✔
553
        "extension": "gradle",
1✔
554
        "toString": "build.gradle"
1✔
555
      },
1✔
556
      "hunks": [
1✔
557
        {
1✔
558
          "sourceLine": 1,
1✔
559
          "sourceSpan": 14,
1✔
560
          "destinationLine": 1,
1✔
561
          "destinationSpan": 14,
1✔
562
          "segments": [
1✔
563
            {
1✔
564
              "type": "CONTEXT",
1✔
565
              "lines": [
1✔
566
                {
1✔
567
                  "source": 3,
1✔
568
                  "destination": 3,
1✔
569
                  "line": " line",
1✔
570
                  "truncated": false
1✔
571
                }
1✔
572
              ],
1✔
573
              "truncated": false
1✔
574
            },
1✔
575
            {
1✔
576
              "type": "ADDED",
1✔
577
              "lines": [
1✔
578
                {
1✔
579
                  "source": 5,
1✔
580
                  "destination": 4,
1✔
581
                  "line": "    test2",
1✔
582
                  "truncated": false
1✔
583
                }
1✔
584
              ],
1✔
585
              "truncated": false
1✔
586
            },
1✔
587
            {
1✔
588
              "type": "CONTEXT",
1✔
589
              "lines": [
1✔
590
                {
1✔
591
                  "source": 6,
1✔
592
                  "destination": 6,
1✔
593
                  "line": "",
1✔
594
                  "truncated": false
1✔
595
                }
1✔
596
              ],
1✔
597
              "truncated": false
1✔
598
            }
1✔
599
          ],
1✔
600
          "truncated": false
1✔
601
        }
1✔
602
      ],
1✔
603
      "truncated": false
1✔
604
    }
1✔
605
  ],
1✔
606
  "truncated": false
1✔
607
}'.
1✔
608

1✔
609
        ^ diffsWithoutRemoved := (NeoJSONReader on:
1✔
610
                                          diffsWithoutRemoved readStream) next
1✔
611
]
1✔
612

613
{ #category : #initialization }
614
BitBucketApiMock >> initialize [
1✔
615

1✔
616
        commits := self commits1.
1✔
617
        diffs := self diffs1.
1✔
618
        userMock := self user1.
1✔
619
        mergeRequests := { self openedMergeRequest }
1✔
620
]
1✔
621

622
{ #category : #accessing }
NEW
623
BitBucketApiMock >> mergeRequests [
×
NEW
624

×
NEW
625
        ^ mergeRequests
×
NEW
626
]
×
627

628
{ #category : #accessing }
629
BitBucketApiMock >> mergeRequests: anObject [
1✔
630

1✔
631
        mergeRequests := anObject
1✔
632
]
1✔
633

634
{ #category : #accessing }
635
BitBucketApiMock >> mergedMergeRequest [
1✔
636

1✔
637
        | pullRequest |
1✔
638
        pullRequest := '{
1✔
639
      "id": 539,
1✔
640
      "version": 10,
1✔
641
      "title": "title",
1✔
642
      "state": "MERGED",
1✔
643
      "open": false,
1✔
644
      "closed": true,
1✔
645
                  "createdDate": 1721396425473,
1✔
646
                  "updatedDate": 1721457513310,
1✔
647
                  "closedDate": 1721457513310,
1✔
648
      "fromRef": {
1✔
649
        "id": "refs/heads/wip/1",
1✔
650
        "displayId": "wip/1",
1✔
651
        "latestCommit": "2",
1✔
652
        "repository": {
1✔
653
          "slug": "repoSlug",
1✔
654
          "id": 242,
1✔
655
          "name": "repo-name",
1✔
656
          "scmId": "git",
1✔
657
          "state": "AVAILABLE",
1✔
658
          "statusMessage": "Available",
1✔
659
          "forkable": true,
1✔
660
          "project": {
1✔
661
            "key": "project-key",
1✔
662
            "id": 242,
1✔
663
            "name": "project-name",
1✔
664
            "description": "project description",
1✔
665
            "public": true,
1✔
666
            "type": "NORMAL",
1✔
667
            "links": {
1✔
668
              "self": [
1✔
669
                {
1✔
670
                  "href": "link"
1✔
671
                }
1✔
672
              ]
1✔
673
            }
1✔
674
          },
1✔
675
          "public": false,
1✔
676
          "links": {
1✔
677
            "clone": [
1✔
678
              {
1✔
679
                "href": "clone",
1✔
680
                "name": "ssh"
1✔
681
              },
1✔
682
              {
1✔
683
                "href": "clone",
1✔
684
                "name": "http"
1✔
685
              }
1✔
686
            ],
1✔
687
            "self": [
1✔
688
              {
1✔
689
                "href": "link"
1✔
690
              }
1✔
691
            ]
1✔
692
          }
1✔
693
        }
1✔
694
      },
1✔
695
      "toRef": {
1✔
696
        "id": "refs/heads/develop/trunk",
1✔
697
        "displayId": "develop/trunk",
1✔
698
        "latestCommit": "3",
1✔
699
        "repository": {
1✔
700
          "slug": "repo-slug",
1✔
701
          "id": 242,
1✔
702
          "name": "repo-name",
1✔
703
          "scmId": "git",
1✔
704
          "state": "AVAILABLE",
1✔
705
          "statusMessage": "Available",
1✔
706
          "forkable": true,
1✔
707
          "project": {
1✔
708
            "key": "project-key",
1✔
709
            "id": 242,
1✔
710
            "name": "project-name",
1✔
711
            "description": "description",
1✔
712
            "public": true,
1✔
713
            "type": "NORMAL",
1✔
714
            "links": {
1✔
715
              "self": [
1✔
716
                {
1✔
717
                  "href": "link"
1✔
718
                }
1✔
719
              ]
1✔
720
            }
1✔
721
          },
1✔
722
          "public": false,
1✔
723
          "links": {
1✔
724
            "clone": [
1✔
725
              {
1✔
726
                "href": "link",
1✔
727
                "name": "ssh"
1✔
728
              },
1✔
729
              {
1✔
730
                "href": "link-http",
1✔
731
                "name": "http"
1✔
732
              }
1✔
733
            ],
1✔
734
            "self": [
1✔
735
              {
1✔
736
                "href": "link-self"
1✔
737
              }
1✔
738
            ]
1✔
739
          }
1✔
740
        }
1✔
741
      },
1✔
742
      "locked": false,
1✔
743
      "author": {
1✔
744
        "user": {
1✔
745
          "name": "user-name",
1✔
746
          "id": 1,
1✔
747
          "displayName": "user-display-name",
1✔
748
          "active": false,
1✔
749
          "slug": "user-slug",
1✔
750
          "type": "NORMAL",
1✔
751
          "links": {
1✔
752
            "self": [
1✔
753
              {
1✔
754
                "href": "link-self"
1✔
755
              }
1✔
756
            ]
1✔
757
          }
1✔
758
        },
1✔
759
        "role": "AUTHOR",
1✔
760
        "approved": false,
1✔
761
        "status": "UNAPPROVED"
1✔
762
      },
1✔
763
      "reviewers": [
1✔
764
        {
1✔
765
          "user": {
1✔
766
            "name": "reviewer-name",
1✔
767
            "emailAddress": "reviewer@email.com",
1✔
768
            "id": 1713,
1✔
769
            "displayName": "reviewer-display-name",
1✔
770
            "active": true,
1✔
771
            "slug": "reviewer-slug",
1✔
772
            "type": "NORMAL",
1✔
773
            "links": {
1✔
774
              "self": [
1✔
775
                {
1✔
776
                  "href": "link-self"
1✔
777
                }
1✔
778
              ]
1✔
779
            }
1✔
780
          },
1✔
781
          "lastReviewedCommit": "2",
1✔
782
          "role": "REVIEWER",
1✔
783
          "approved": true,
1✔
784
          "status": "APPROVED"
1✔
785
        },
1✔
786
        {
1✔
787
          "user": {
1✔
788
            "name": "reveiwer2-name",
1✔
789
            "emailAddress": "reviewer2@email.com",
1✔
790
            "id": 49,
1✔
791
            "displayName": "reviewer2 display name",
1✔
792
            "active": true,
1✔
793
            "slug": "reviewer2-slug",
1✔
794
            "type": "NORMAL",
1✔
795
            "links": {
1✔
796
              "self": [
1✔
797
                {
1✔
798
                  "href": "link-self"
1✔
799
                }
1✔
800
              ]
1✔
801
            }
1✔
802
          },
1✔
803
          "role": "REVIEWER",
1✔
804
          "approved": false,
1✔
805
          "status": "UNAPPROVED"
1✔
806
        }
1✔
807
      ],
1✔
808
      "participants": [],
1✔
809
      "properties": {
1✔
810
        "mergeResult": {
1✔
811
          "outcome": "CONFLICTED",
1✔
812
          "current": true
1✔
813
        },
1✔
814
        "resolvedTaskCount": 0,
1✔
815
        "commentCount": 4,
1✔
816
        "openTaskCount": 0
1✔
817
      },
1✔
818
      "links": {
1✔
819
        "self": [
1✔
820
          {
1✔
821
            "href": "link"
1✔
822
          }
1✔
823
        ]
1✔
824
      }
1✔
825
    }'.
1✔
826

1✔
827
        ^ pullRequest := (NeoJSONReader on: pullRequest readStream) next
1✔
828
]
1✔
829

830
{ #category : #accessing }
831
BitBucketApiMock >> openedMergeRequest [
1✔
832

1✔
833
        | pullRequest |
1✔
834
        pullRequest := '{
1✔
835
      "id": 539,
1✔
836
      "version": 10,
1✔
837
      "title": "title",
1✔
838
      "state": "OPEN",
1✔
839
      "open": true,
1✔
840
      "closed": false,
1✔
841
      "createdDate": 1709726344893,
1✔
842
      "updatedDate": 1709728944248,
1✔
843
      "fromRef": {
1✔
844
        "id": "refs/heads/wip/1",
1✔
845
        "displayId": "wip/1",
1✔
846
        "latestCommit": "2",
1✔
847
        "repository": {
1✔
848
          "slug": "repoSlug",
1✔
849
          "id": 242,
1✔
850
          "name": "repo-name",
1✔
851
          "scmId": "git",
1✔
852
          "state": "AVAILABLE",
1✔
853
          "statusMessage": "Available",
1✔
854
          "forkable": true,
1✔
855
          "project": {
1✔
856
            "key": "project-key",
1✔
857
            "id": 242,
1✔
858
            "name": "project-name",
1✔
859
            "description": "project description",
1✔
860
            "public": true,
1✔
861
            "type": "NORMAL",
1✔
862
            "links": {
1✔
863
              "self": [
1✔
864
                {
1✔
865
                  "href": "link"
1✔
866
                }
1✔
867
              ]
1✔
868
            }
1✔
869
          },
1✔
870
          "public": false,
1✔
871
          "links": {
1✔
872
            "clone": [
1✔
873
              {
1✔
874
                "href": "clone",
1✔
875
                "name": "ssh"
1✔
876
              },
1✔
877
              {
1✔
878
                "href": "clone",
1✔
879
                "name": "http"
1✔
880
              }
1✔
881
            ],
1✔
882
            "self": [
1✔
883
              {
1✔
884
                "href": "link"
1✔
885
              }
1✔
886
            ]
1✔
887
          }
1✔
888
        }
1✔
889
      },
1✔
890
      "toRef": {
1✔
891
        "id": "refs/heads/develop/trunk",
1✔
892
        "displayId": "develop/trunk",
1✔
893
        "latestCommit": "3",
1✔
894
        "repository": {
1✔
895
          "slug": "repo-slug",
1✔
896
          "id": 242,
1✔
897
          "name": "repo-name",
1✔
898
          "scmId": "git",
1✔
899
          "state": "AVAILABLE",
1✔
900
          "statusMessage": "Available",
1✔
901
          "forkable": true,
1✔
902
          "project": {
1✔
903
            "key": "project-key",
1✔
904
            "id": 242,
1✔
905
            "name": "project-name",
1✔
906
            "description": "description",
1✔
907
            "public": true,
1✔
908
            "type": "NORMAL",
1✔
909
            "links": {
1✔
910
              "self": [
1✔
911
                {
1✔
912
                  "href": "link"
1✔
913
                }
1✔
914
              ]
1✔
915
            }
1✔
916
          },
1✔
917
          "public": false,
1✔
918
          "links": {
1✔
919
            "clone": [
1✔
920
              {
1✔
921
                "href": "link",
1✔
922
                "name": "ssh"
1✔
923
              },
1✔
924
              {
1✔
925
                "href": "link-http",
1✔
926
                "name": "http"
1✔
927
              }
1✔
928
            ],
1✔
929
            "self": [
1✔
930
              {
1✔
931
                "href": "link-self"
1✔
932
              }
1✔
933
            ]
1✔
934
          }
1✔
935
        }
1✔
936
      },
1✔
937
      "locked": false,
1✔
938
      "author": {
1✔
939
        "user": {
1✔
940
          "name": "user-name",
1✔
941
          "id": 1,
1✔
942
          "displayName": "user-display-name",
1✔
943
          "active": false,
1✔
944
          "slug": "user-slug",
1✔
945
          "type": "NORMAL",
1✔
946
          "links": {
1✔
947
            "self": [
1✔
948
              {
1✔
949
                "href": "link-self"
1✔
950
              }
1✔
951
            ]
1✔
952
          }
1✔
953
        },
1✔
954
        "role": "AUTHOR",
1✔
955
        "approved": false,
1✔
956
        "status": "UNAPPROVED"
1✔
957
      },
1✔
958
      "reviewers": [
1✔
959
        {
1✔
960
          "user": {
1✔
961
            "name": "reviewer-name",
1✔
962
            "emailAddress": "reviewer@email.com",
1✔
963
            "id": 1713,
1✔
964
            "displayName": "reviewer-display-name",
1✔
965
            "active": true,
1✔
966
            "slug": "reviewer-slug",
1✔
967
            "type": "NORMAL",
1✔
968
            "links": {
1✔
969
              "self": [
1✔
970
                {
1✔
971
                  "href": "link-self"
1✔
972
                }
1✔
973
              ]
1✔
974
            }
1✔
975
          },
1✔
976
          "lastReviewedCommit": "2",
1✔
977
          "role": "REVIEWER",
1✔
978
          "approved": true,
1✔
979
          "status": "APPROVED"
1✔
980
        },
1✔
981
        {
1✔
982
          "user": {
1✔
983
            "name": "reveiwer2-name",
1✔
984
            "emailAddress": "reviewer2@email.com",
1✔
985
            "id": 49,
1✔
986
            "displayName": "reviewer2 display name",
1✔
987
            "active": true,
1✔
988
            "slug": "reviewer2-slug",
1✔
989
            "type": "NORMAL",
1✔
990
            "links": {
1✔
991
              "self": [
1✔
992
                {
1✔
993
                  "href": "link-self"
1✔
994
                }
1✔
995
              ]
1✔
996
            }
1✔
997
          },
1✔
998
          "role": "REVIEWER",
1✔
999
          "approved": false,
1✔
1000
          "status": "UNAPPROVED"
1✔
1001
        }
1✔
1002
      ],
1✔
1003
      "participants": [],
1✔
1004
      "properties": {
1✔
1005
        "mergeResult": {
1✔
1006
          "outcome": "CONFLICTED",
1✔
1007
          "current": true
1✔
1008
        },
1✔
1009
        "resolvedTaskCount": 0,
1✔
1010
        "commentCount": 4,
1✔
1011
        "openTaskCount": 0
1✔
1012
      },
1✔
1013
      "links": {
1✔
1014
        "self": [
1✔
1015
          {
1✔
1016
            "href": "link"
1✔
1017
          }
1✔
1018
        ]
1✔
1019
      }
1✔
1020
    }'.
1✔
1021

1✔
1022
        ^pullRequest := (NeoJSONReader on: pullRequest readStream) next.
1✔
1023
]
1✔
1024

1025
{ #category : #accessing }
1026
BitBucketApiMock >> projects [
1✔
1027

1✔
1028
        | projects |
1✔
1029
        projects := '[
1✔
1030
    {
1✔
1031
      "key": "PRJ",
1✔
1032
      "id": 1,
1✔
1033
      "name": "My Cool Project",
1✔
1034
      "description": "The description for my cool project.",
1✔
1035
      "public": true,
1✔
1036
      "type": "NORMAL",
1✔
1037
      "links": {
1✔
1038
        "self": [{"href": "http://link/to/project"}]
1✔
1039
      }
1✔
1040
    }
1✔
1041
  ],
1✔
1042
'.
1✔
1043

1✔
1044
        projects := (NeoJSONReader on: projects readStream) next.
1✔
1045

1✔
1046
        ^ projects
1✔
1047
]
1✔
1048

1049
{ #category : #accessing }
1050
BitBucketApiMock >> pullRequestActivities [
1✔
1051

1✔
1052
        | pullRequestActivities |
1✔
1053
        pullRequestActivities := '
1✔
1054
    [{
1✔
1055
      "id": 1,
1✔
1056
      "createdDate": 1720510446734,
1✔
1057
      "user": {
1✔
1058
        "name": "user-name",
1✔
1059
        "emailAddress": "user-name@email.com",
1✔
1060
        "id": 24,
1✔
1061
        "displayName": "user name",
1✔
1062
        "active": true,
1✔
1063
        "slug": "un",
1✔
1064
        "type": "NORMAL",
1✔
1065
        "links": {
1✔
1066
          "self": [
1✔
1067
            {
1✔
1068
              "href": "link"
1✔
1069
            }
1✔
1070
          ]
1✔
1071
        }
1✔
1072
      },
1✔
1073
      "action": "MERGED"
1✔
1074
}]'.
1✔
1075

1✔
1076
        ^ pullRequestActivities := (NeoJSONReader on:
1✔
1077
                                            pullRequestActivities readStream) next
1✔
1078
]
1✔
1079

1080
{ #category : #'api - pull-requests' }
1081
BitBucketApiMock >> pullRequestsOfRepo: repoSlug inProject: projectKey since: since until: until [
1✔
1082
        
1✔
1083
        ^ mergeRequests
1✔
1084
]
1✔
1085

1086
{ #category : #'api - projects' }
1087
BitBucketApiMock >> repositoriesOfProject: projectKey [
1✔
1088

1✔
1089
        | repos |
1✔
1090
        repos := '[
1✔
1091
    {
1✔
1092
      "slug": "my-repo",
1✔
1093
      "id": 1,
1✔
1094
      "name": "My repo",
1✔
1095
      "scmId": "git",
1✔
1096
      "state": "AVAILABLE",
1✔
1097
      "statusMessage": "Available",
1✔
1098
      "forkable": true,
1✔
1099
      "project": {
1✔
1100
        "key": "PRJ",
1✔
1101
        "id": 1,
1✔
1102
        "name": "My Cool Project",
1✔
1103
        "description": "The description for my cool project.",
1✔
1104
        "public": true,
1✔
1105
        "type": "NORMAL",
1✔
1106
        "links": {
1✔
1107
          "self": [{"href": "http://link/to/project"}]
1✔
1108
        }
1✔
1109
      },
1✔
1110
      "public": true,
1✔
1111
      "links": {
1✔
1112
        "clone": [
1✔
1113
          {"href": "ssh://git@<baseURL>/PRJ/my-repo.git", "name": "ssh"},
1✔
1114
          {"href": "https://<baseURL>/scm/PRJ/my-repo.git", "name": "http"}
1✔
1115
        ],
1✔
1116
        "self": [{"href": "http://link/to/repository"}]
1✔
1117
      }
1✔
1118
    }
1✔
1119
  ],'.
1✔
1120

1✔
1121
repos := (NeoJSONReader on: repos readStream) next.
1✔
1122

1✔
1123
^repos
1✔
1124
]
1✔
1125

1126
{ #category : #accessing }
1127
BitBucketApiMock >> user1 [
1✔
1128

1✔
1129
        | user1 |
1✔
1130
        user1 := '
1✔
1131
    {
1✔
1132
      "name": "test",
1✔
1133
      "emailAddress": "test@test.com",
1✔
1134
      "id": 1,
1✔
1135
      "displayName": "test test",
1✔
1136
      "active": true,
1✔
1137
      "slug": "test",
1✔
1138
      "type": "NORMAL",
1✔
1139
      "directoryName": "directory",
1✔
1140
      "deletable": false,
1✔
1141
      "lastAuthenticationTimestamp": 1727444943000,
1✔
1142
      "mutableDetails": false,
1✔
1143
      "mutableGroups": true,
1✔
1144
      "links": {
1✔
1145
        "self": [
1✔
1146
          {
1✔
1147
            "href": "test.com"
1✔
1148
          }
1✔
1149
        ]
1✔
1150
      }
1✔
1151
    }
1✔
1152
  '.
1✔
1153

1✔
1154

1✔
1155
        ^ user1 := (NeoJSONReader on: user1 readStream) next
1✔
1156
]
1✔
1157

1158
{ #category : #accessing }
NEW
1159
BitBucketApiMock >> user: accountId [
×
NEW
1160

×
NEW
1161
        | user |
×
NEW
1162
        user := '{
×
NEW
1163
        "type": "user",
×
NEW
1164
        "nickname": "evzijst",
×
NEW
1165
        "display_name": "Erik van Zijst",
×
NEW
1166
                  "created_on": "12-04-2024",
×
NEW
1167
        "uuid": "{d301aafa-d676-4ee0-88be-962be7417567}"
×
NEW
1168
   }'.
×
NEW
1169

×
NEW
1170
        ^ user
×
NEW
1171
]
×
1172

1173
{ #category : #accessing }
1174
BitBucketApiMock >> userMock [
1✔
1175

1✔
1176
        ^ userMock
1✔
1177
]
1✔
1178

1179
{ #category : #accessing }
1180
BitBucketApiMock >> userMock: anObject [
1✔
1181

1✔
1182
        userMock := anObject
1✔
1183
]
1✔
1184

1185
{ #category : #'api - user' }
1186
BitBucketApiMock >> usersByUsername: username [
1✔
1187

1✔
1188
        userMock ifNil: [ ^Array new ] ifNotNil: [ ^{ userMock }]
1✔
1189
]
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc