dependabot-nuget 0.321.3 → 0.322.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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/Directory.Packages.props +22 -22
  3. data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Cli/Program.cs +21 -7
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +19 -11
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/CloneCommand.cs +19 -9
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +21 -14
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/FrameworkCheckCommand.cs +8 -5
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +29 -16
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +20 -19
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Program.cs +2 -1
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +1 -1
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +10 -23
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +9 -0
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +15 -232
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +1 -154
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +3 -12
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/GlobalJsonBuildFile.cs +5 -13
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/PrivateSourceTimedOutException.cs +12 -0
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +4 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PrivateSourceTimedOut.cs +10 -0
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/AzurePackageDetailFinder.cs +30 -0
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/DetailedPullRequestBodyGenerator.cs +237 -0
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/GitHubPackageDetailFinder.cs +101 -0
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/GitLabPackageDetailFinder.cs +107 -0
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/HttpFetcher.cs +32 -0
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/IHttpFetcher.cs +30 -0
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/IPackageDetailFinder.cs +47 -0
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/IPullRequestBodyGenerator.cs +11 -0
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/SimplePullRequestBodyGenerator.cs +15 -0
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestTextGenerator.cs +7 -3
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +3 -525
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +2 -2
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +4 -4
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandler.cs +2 -2
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandler.cs +2 -2
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandler.cs +2 -2
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/FileWriterWorker.cs +85 -35
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/XmlFileWriter.cs +27 -8
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +1 -856
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdateOperationBase.cs +18 -7
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +16 -200
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +21 -556
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +9 -73
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/CloneWorkerTests.cs +2 -2
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/DependencySolver/MSBuildDependencySolverTests.cs +1 -1
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +1 -20
  47. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +0 -2
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +3 -62
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +13 -563
  50. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +20 -269
  51. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +2 -2
  52. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/GlobalJsonBuildFileTests.cs +0 -1
  53. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/EndToEndTests.cs +131 -131
  54. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/HttpApiHandlerTests.cs +1 -0
  55. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/JobErrorBaseTests.cs +7 -0
  56. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MessageReportTests.cs +11 -0
  57. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +0 -203
  58. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestBodyGenerator/DetailedPullRequestBodyGeneratorTests.cs +871 -0
  59. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestBodyGenerator/IPackageDetailFinderTests.cs +28 -0
  60. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestBodyGenerator/TestHttpFetcher.cs +23 -0
  61. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestTextTests.cs +24 -24
  62. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +14 -12
  63. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandlerTests.cs +6 -6
  64. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/GroupUpdateAllVersionsHandlerTests.cs +18 -18
  65. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandlerTests.cs +15 -15
  66. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandlerTests.cs +21 -21
  67. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandlerTests.cs +15 -15
  68. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/UpdateHandlersTestsBase.cs +1 -8
  69. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterWorkerTests.cs +2 -2
  70. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterWorkerTests_MiscellaneousTests.cs +45 -0
  71. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/XmlFileWriterTests.cs +111 -0
  72. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackageReferenceUpdaterTests.cs +1 -159
  73. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +26 -660
  74. data/helpers/lib/NuGetUpdater/global.json +1 -1
  75. metadata +18 -10
  76. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunResult.cs +0 -13
  77. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestMessageTests.cs +0 -296
  78. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +0 -3592
  79. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatePermittedAndMessageTests.cs +0 -457
  80. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DirsProj.cs +0 -378
  81. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/SdkPackageUpdaterHelperTests.cs +0 -175
@@ -0,0 +1,871 @@
1
+ using System.Collections.Immutable;
2
+ using System.Text;
3
+
4
+ using NuGet.Versioning;
5
+
6
+ using NuGetUpdater.Core.Run.ApiModel;
7
+ using NuGetUpdater.Core.Run.PullRequestBodyGenerator;
8
+ using NuGetUpdater.Core.Updater;
9
+
10
+ using Xunit;
11
+
12
+ namespace NuGetUpdater.Core.Test.Run.PullRequestBodyGenerator;
13
+
14
+ public class DetailedPullRequestBodyGeneratorTests
15
+ {
16
+ [Fact]
17
+ public async Task GeneratePrBody_Azure()
18
+ {
19
+ await TestAsync(
20
+ updateOperationsPerformed: [
21
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
22
+ ],
23
+ updatedDependencies: [
24
+ new ReportedDependency()
25
+ {
26
+ Name = "Some.Dependency",
27
+ PreviousVersion = "1.0.0",
28
+ Version = "2.0.0",
29
+ Requirements = [
30
+ new ReportedRequirement()
31
+ {
32
+ File = "",
33
+ Requirement = "2.0.0",
34
+ Source = new()
35
+ {
36
+ SourceUrl = "https://dev.azure.com/Some.Organization/Some.Owner/_git/Some.Dependency",
37
+ },
38
+ }
39
+ ],
40
+ }
41
+ ],
42
+ httpResponses: [],
43
+ expectedBody: """
44
+ Updated [Some.Dependency](https://dev.azure.com/Some.Organization/Some.Owner/_git/Some.Dependency) from 1.0.0 to 2.0.0.
45
+
46
+ <details>
47
+ <summary>Release notes</summary>
48
+
49
+ _Sourced from [Some.Dependency's releases](https://dev.azure.com/Some.Organization/Some.Owner/_git/Some.Dependency/tags)._
50
+
51
+ No release notes found for this version range.
52
+
53
+ Commits viewable in [compare view](https://dev.azure.com/Some.Organization/Some.Owner/_git/Some.Dependency/commits).
54
+ </details>
55
+ """
56
+ );
57
+ }
58
+
59
+ [Fact]
60
+ public async Task GeneratePrBody_Azure_VisualStudioDomain()
61
+ {
62
+ await TestAsync(
63
+ updateOperationsPerformed: [
64
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
65
+ ],
66
+ updatedDependencies: [
67
+ new ReportedDependency()
68
+ {
69
+ Name = "Some.Dependency",
70
+ PreviousVersion = "1.0.0",
71
+ Version = "2.0.0",
72
+ Requirements = [
73
+ new ReportedRequirement()
74
+ {
75
+ File = "",
76
+ Requirement = "2.0.0",
77
+ Source = new()
78
+ {
79
+ SourceUrl = "https://example-org.visualstudio.com/Some.Owner/_git/Some.Dependency",
80
+ },
81
+ }
82
+ ],
83
+ }
84
+ ],
85
+ httpResponses: [],
86
+ expectedBody: """
87
+ Updated [Some.Dependency](https://example-org.visualstudio.com/Some.Owner/_git/Some.Dependency) from 1.0.0 to 2.0.0.
88
+
89
+ <details>
90
+ <summary>Release notes</summary>
91
+
92
+ _Sourced from [Some.Dependency's releases](https://example-org.visualstudio.com/Some.Owner/_git/Some.Dependency/tags)._
93
+
94
+ No release notes found for this version range.
95
+
96
+ Commits viewable in [compare view](https://example-org.visualstudio.com/Some.Owner/_git/Some.Dependency/commits).
97
+ </details>
98
+ """
99
+ );
100
+ }
101
+
102
+ [Fact]
103
+ public async Task GeneratePrBody_GitHub()
104
+ {
105
+ await TestAsync(
106
+ updateOperationsPerformed: [
107
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
108
+ ],
109
+ updatedDependencies: [
110
+ new ReportedDependency()
111
+ {
112
+ Name = "Some.Dependency",
113
+ PreviousVersion = "1.0.0",
114
+ Version = "2.0.0",
115
+ Requirements = [
116
+ new ReportedRequirement()
117
+ {
118
+ File = "",
119
+ Requirement = "2.0.0",
120
+ Source = new()
121
+ {
122
+ SourceUrl = "https://github.com/Some.Owner/Some.Dependency",
123
+ },
124
+ }
125
+ ],
126
+ }
127
+ ],
128
+ httpResponses: [
129
+ ("https://api.github.com/repos/Some.Owner/Some.Dependency/releases?per_page=100", """
130
+ [
131
+ {
132
+ "name": "2.0.0",
133
+ "tag_name": "2.0.0",
134
+ "body": "* point 5\n* point 6"
135
+ },
136
+ {
137
+ "name": "1.0.1",
138
+ "tag_name": "1.0.1",
139
+ "body": "* point 3\n* point 4"
140
+ },
141
+ {
142
+ "name": "1.0.0",
143
+ "tag_name": "1.0.0",
144
+ "body": "* point 1\n* point 2"
145
+ }
146
+ ]
147
+ """)
148
+ ],
149
+ expectedBody: """
150
+ Updated [Some.Dependency](https://github.com/Some.Owner/Some.Dependency) from 1.0.0 to 2.0.0.
151
+
152
+ <details>
153
+ <summary>Release notes</summary>
154
+
155
+ _Sourced from [Some.Dependency's releases](https://github.com/Some.Owner/Some.Dependency/releases)._
156
+
157
+ ## 2.0.0
158
+
159
+ * point 5
160
+ * point 6
161
+
162
+ ## 1.0.1
163
+
164
+ * point 3
165
+ * point 4
166
+
167
+ Commits viewable in [compare view](https://github.com/Some.Owner/Some.Dependency/compare/1.0.0...2.0.0).
168
+ </details>
169
+ """
170
+ );
171
+ }
172
+
173
+ [Fact]
174
+ public async Task GeneratePrBody_GitHub_EmptyApiResponses()
175
+ {
176
+ await TestAsync(
177
+ updateOperationsPerformed: [
178
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
179
+ ],
180
+ updatedDependencies: [
181
+ new ReportedDependency()
182
+ {
183
+ Name = "Some.Dependency",
184
+ PreviousVersion = "1.0.0",
185
+ Version = "2.0.0",
186
+ Requirements = [
187
+ new ReportedRequirement()
188
+ {
189
+ File = "",
190
+ Requirement = "2.0.0",
191
+ Source = new()
192
+ {
193
+ SourceUrl = "https://github.com/Some.Owner/Some.Dependency",
194
+ },
195
+ }
196
+ ],
197
+ }
198
+ ],
199
+ httpResponses: [],
200
+ expectedBody: """
201
+ Updated [Some.Dependency](https://github.com/Some.Owner/Some.Dependency) from 1.0.0 to 2.0.0.
202
+
203
+ <details>
204
+ <summary>Release notes</summary>
205
+
206
+ _Sourced from [Some.Dependency's releases](https://github.com/Some.Owner/Some.Dependency/releases)._
207
+
208
+ No release notes found for this version range.
209
+
210
+ Commits viewable in [compare view](https://github.com/Some.Owner/Some.Dependency/commits).
211
+ </details>
212
+ """
213
+ );
214
+ }
215
+
216
+ [Fact]
217
+ public async Task GeneratePrBody_GitHub_NonJsonResponse()
218
+ {
219
+ await TestAsync(
220
+ updateOperationsPerformed: [
221
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
222
+ ],
223
+ updatedDependencies: [
224
+ new ReportedDependency()
225
+ {
226
+ Name = "Some.Dependency",
227
+ PreviousVersion = "1.0.0",
228
+ Version = "2.0.0",
229
+ Requirements = [
230
+ new ReportedRequirement()
231
+ {
232
+ File = "",
233
+ Requirement = "2.0.0",
234
+ Source = new()
235
+ {
236
+ SourceUrl = "https://github.com/Some.Owner/Some.Dependency",
237
+ },
238
+ }
239
+ ],
240
+ }
241
+ ],
242
+ httpResponses: [
243
+ ("https://api.github.com/repos/Some.Owner/Some.Dependency/releases?per_page=100", """
244
+ this is not JSON
245
+ """)
246
+ ],
247
+ expectedBody: """
248
+ Updated [Some.Dependency](https://github.com/Some.Owner/Some.Dependency) from 1.0.0 to 2.0.0.
249
+
250
+ <details>
251
+ <summary>Release notes</summary>
252
+
253
+ _Sourced from [Some.Dependency's releases](https://github.com/Some.Owner/Some.Dependency/releases)._
254
+
255
+ No release notes found for this version range.
256
+
257
+ Commits viewable in [compare view](https://github.com/Some.Owner/Some.Dependency/commits).
258
+ </details>
259
+ """
260
+ );
261
+ }
262
+
263
+ [Fact]
264
+ public async Task GeneratePrBody_GitLab()
265
+ {
266
+ await TestAsync(
267
+ updateOperationsPerformed: [
268
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
269
+ ],
270
+ updatedDependencies: [
271
+ new ReportedDependency()
272
+ {
273
+ Name = "Some.Dependency",
274
+ PreviousVersion = "1.0.0",
275
+ Version = "2.0.0",
276
+ Requirements = [
277
+ new ReportedRequirement()
278
+ {
279
+ File = "",
280
+ Requirement = "2.0.0",
281
+ Source = new()
282
+ {
283
+ SourceUrl = "https://gitlab.com/Some.Owner/Some.Dependency",
284
+ },
285
+ }
286
+ ],
287
+ }
288
+ ],
289
+ httpResponses: [
290
+ ("https://gitlab.com/api/v4/projects/Some.Owner%2FSome.Dependency/repository/tags", """
291
+ [
292
+ {
293
+ "name": "2.0.0",
294
+ "release": {
295
+ "tag_name": "2.0.0",
296
+ "description": "* point 5\n* point 6"
297
+ }
298
+ },
299
+ {
300
+ "name": "1.0.1",
301
+ "release": null
302
+ },
303
+ {
304
+ "name": "1.0.0",
305
+ "release": null
306
+ }
307
+ ]
308
+ """)
309
+ ],
310
+ expectedBody: """
311
+ Updated [Some.Dependency](https://gitlab.com/Some.Owner/Some.Dependency) from 1.0.0 to 2.0.0.
312
+
313
+ <details>
314
+ <summary>Release notes</summary>
315
+
316
+ _Sourced from [Some.Dependency's releases](https://gitlab.com/Some.Owner/Some.Dependency/-/releases)._
317
+
318
+ ## 2.0.0
319
+
320
+ * point 5
321
+ * point 6
322
+
323
+ ## 1.0.1
324
+
325
+ Commits viewable in [compare view](https://gitlab.com/Some.Owner/Some.Dependency/-/compare/1.0.0...2.0.0).
326
+ </details>
327
+ """
328
+ );
329
+ }
330
+
331
+ [Fact]
332
+ public async Task GeneratePrBody_GitLab_EmptyApiResponses()
333
+ {
334
+ await TestAsync(
335
+ updateOperationsPerformed: [
336
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
337
+ ],
338
+ updatedDependencies: [
339
+ new ReportedDependency()
340
+ {
341
+ Name = "Some.Dependency",
342
+ PreviousVersion = "1.0.0",
343
+ Version = "2.0.0",
344
+ Requirements = [
345
+ new ReportedRequirement()
346
+ {
347
+ File = "",
348
+ Requirement = "2.0.0",
349
+ Source = new()
350
+ {
351
+ SourceUrl = "https://gitlab.com/Some.Owner/Some.Dependency",
352
+ },
353
+ }
354
+ ],
355
+ }
356
+ ],
357
+ httpResponses: [],
358
+ expectedBody: """
359
+ Updated [Some.Dependency](https://gitlab.com/Some.Owner/Some.Dependency) from 1.0.0 to 2.0.0.
360
+
361
+ <details>
362
+ <summary>Release notes</summary>
363
+
364
+ _Sourced from [Some.Dependency's releases](https://gitlab.com/Some.Owner/Some.Dependency/-/releases)._
365
+
366
+ No release notes found for this version range.
367
+
368
+ Commits viewable in [compare view](https://gitlab.com/Some.Owner/Some.Dependency/-/commits).
369
+ </details>
370
+ """
371
+ );
372
+ }
373
+
374
+ [Fact]
375
+ public async Task GeneratePrBody_GitLab_NonJsonResponse()
376
+ {
377
+ await TestAsync(
378
+ updateOperationsPerformed: [
379
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
380
+ ],
381
+ updatedDependencies: [
382
+ new ReportedDependency()
383
+ {
384
+ Name = "Some.Dependency",
385
+ PreviousVersion = "1.0.0",
386
+ Version = "2.0.0",
387
+ Requirements = [
388
+ new ReportedRequirement()
389
+ {
390
+ File = "",
391
+ Requirement = "2.0.0",
392
+ Source = new()
393
+ {
394
+ SourceUrl = "https://gitlab.com/Some.Owner/Some.Dependency",
395
+ },
396
+ }
397
+ ],
398
+ }
399
+ ],
400
+ httpResponses: [
401
+ ("https://gitlab.com/api/v4/projects/Some.Owner%2FSome.Dependency/repository/tags", """
402
+ this is not JSON
403
+ """)
404
+ ],
405
+ expectedBody: """
406
+ Updated [Some.Dependency](https://gitlab.com/Some.Owner/Some.Dependency) from 1.0.0 to 2.0.0.
407
+
408
+ <details>
409
+ <summary>Release notes</summary>
410
+
411
+ _Sourced from [Some.Dependency's releases](https://gitlab.com/Some.Owner/Some.Dependency/-/releases)._
412
+
413
+ No release notes found for this version range.
414
+
415
+ Commits viewable in [compare view](https://gitlab.com/Some.Owner/Some.Dependency/-/commits).
416
+ </details>
417
+ """
418
+ );
419
+ }
420
+
421
+ [Fact]
422
+ public async Task GeneratePrBody_NoSource()
423
+ {
424
+ await TestAsync(
425
+ updateOperationsPerformed: [
426
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
427
+ ],
428
+ updatedDependencies: [
429
+ new ReportedDependency()
430
+ {
431
+ Name = "Some.Dependency",
432
+ PreviousVersion = "1.0.0",
433
+ Version = "2.0.0",
434
+ Requirements = [
435
+ new ReportedRequirement()
436
+ {
437
+ File = "",
438
+ Requirement = "2.0.0",
439
+ }
440
+ ],
441
+ }
442
+ ],
443
+ httpResponses: [],
444
+ expectedBody: """
445
+ Updated Some.Dependency from 1.0.0 to 2.0.0.
446
+ """
447
+ );
448
+ }
449
+
450
+ [Fact]
451
+ public async Task GeneratePrBody_NoSource_DuplicateUpdateOperations()
452
+ {
453
+ await TestAsync(
454
+ updateOperationsPerformed: [
455
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
456
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
457
+ ],
458
+ updatedDependencies: [
459
+ new ReportedDependency()
460
+ {
461
+ Name = "Some.Dependency",
462
+ PreviousVersion = "1.0.0",
463
+ Version = "2.0.0",
464
+ Requirements = [
465
+ new ReportedRequirement()
466
+ {
467
+ File = "",
468
+ Requirement = "2.0.0",
469
+ }
470
+ ],
471
+ }
472
+ ],
473
+ httpResponses: [],
474
+ expectedBody: """
475
+ Updated Some.Dependency from 1.0.0 to 2.0.0.
476
+ """
477
+ );
478
+ }
479
+
480
+ [Fact]
481
+ public async Task GeneratePrBody_NoSource_MultipleUpdates()
482
+ {
483
+ await TestAsync(
484
+ updateOperationsPerformed: [
485
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
486
+ new DirectUpdate() { DependencyName = "Other.Dependency", OldVersion = NuGetVersion.Parse("3.0.0"), NewVersion = NuGetVersion.Parse("4.0.0"), UpdatedFiles = [] },
487
+ ],
488
+ updatedDependencies: [
489
+ new ReportedDependency()
490
+ {
491
+ Name = "Some.Dependency",
492
+ PreviousVersion = "1.0.0",
493
+ Version = "2.0.0",
494
+ Requirements = [
495
+ new ReportedRequirement()
496
+ {
497
+ File = "",
498
+ Requirement = "2.0.0",
499
+ }
500
+ ],
501
+ },
502
+ new ReportedDependency()
503
+ {
504
+ Name = "Other.Dependency",
505
+ PreviousVersion = "3.0.0",
506
+ Version = "4.0.0",
507
+ Requirements = [
508
+ new ReportedRequirement()
509
+ {
510
+ File = "",
511
+ Requirement = "4.0.0",
512
+ }
513
+ ],
514
+ },
515
+ ],
516
+ httpResponses: [],
517
+ expectedBody: """
518
+ Updated Other.Dependency from 3.0.0 to 4.0.0.
519
+
520
+ Updated Some.Dependency from 1.0.0 to 2.0.0.
521
+ """
522
+ );
523
+ }
524
+
525
+ [Fact]
526
+ public async Task GeneratePrBody_UnsupportedSource()
527
+ {
528
+ await TestAsync(
529
+ updateOperationsPerformed: [
530
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
531
+ ],
532
+ updatedDependencies: [
533
+ new ReportedDependency()
534
+ {
535
+ Name = "Some.Dependency",
536
+ PreviousVersion = "1.0.0",
537
+ Version = "2.0.0",
538
+ Requirements = [
539
+ new ReportedRequirement()
540
+ {
541
+ File = "",
542
+ Requirement = "2.0.0",
543
+ Source = new()
544
+ {
545
+ SourceUrl = "https://example.com/git/Some.Dependency",
546
+ },
547
+ }
548
+ ],
549
+ }
550
+ ],
551
+ httpResponses: [],
552
+ expectedBody: """
553
+ Updated [Some.Dependency](https://example.com/git/Some.Dependency) from 1.0.0 to 2.0.0.
554
+ """
555
+ );
556
+ }
557
+
558
+ [Fact]
559
+ public async Task GeneratePrBody_NoHtmlIfNotSupported()
560
+ {
561
+ // PR will be pushed to a repo that doesn't support HTML in the PR body
562
+ await TestAsync(
563
+ sourceProvider: "azure",
564
+ updateOperationsPerformed: [
565
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
566
+ ],
567
+ updatedDependencies: [
568
+ new ReportedDependency()
569
+ {
570
+ Name = "Some.Dependency",
571
+ PreviousVersion = "1.0.0",
572
+ Version = "2.0.0",
573
+ Requirements = [
574
+ new ReportedRequirement()
575
+ {
576
+ File = "",
577
+ Requirement = "2.0.0",
578
+ Source = new()
579
+ {
580
+ SourceUrl = "https://github.com/Some.Owner/Some.Dependency",
581
+ },
582
+ }
583
+ ],
584
+ }
585
+ ],
586
+ httpResponses: [
587
+ ("https://api.github.com/repos/Some.Owner/Some.Dependency/releases?per_page=100", """
588
+ [
589
+ {
590
+ "name": "2.0.0",
591
+ "tag_name": "2.0.0",
592
+ "body": "* point 5\n* point 6"
593
+ },
594
+ {
595
+ "name": "1.0.1",
596
+ "tag_name": "1.0.1",
597
+ "body": "* point 3\n* point 4"
598
+ },
599
+ {
600
+ "name": "1.0.0",
601
+ "tag_name": "1.0.0",
602
+ "body": "* point 1\n* point 2"
603
+ }
604
+ ]
605
+ """)
606
+ ],
607
+ expectedBody: """
608
+ Updated [Some.Dependency](https://github.com/Some.Owner/Some.Dependency) from 1.0.0 to 2.0.0.
609
+
610
+ # Release notes
611
+
612
+ _Sourced from [Some.Dependency's releases](https://github.com/Some.Owner/Some.Dependency/releases)._
613
+
614
+ ## 2.0.0
615
+
616
+ * point 5
617
+ * point 6
618
+
619
+ ## 1.0.1
620
+
621
+ * point 3
622
+ * point 4
623
+
624
+ Commits viewable in [compare view](https://github.com/Some.Owner/Some.Dependency/compare/1.0.0...2.0.0).
625
+ """
626
+ );
627
+ }
628
+
629
+ [Fact]
630
+ public async Task GeneratePrBody_ReleaseNotesAreTruncated()
631
+ {
632
+ // individual release notes are truncated by lines
633
+ var longReleaseNote = new StringBuilder();
634
+ for (int i = 1; i <= 60; i++)
635
+ {
636
+ longReleaseNote.AppendLine($"* line {i}");
637
+ }
638
+
639
+ // only generating 49 lines so we can manually verify the 50th
640
+ var expectedReleaseNote = new StringBuilder();
641
+ for (int i = 1; i <= 49; i++)
642
+ {
643
+ expectedReleaseNote.AppendLine($"* line {i}");
644
+ }
645
+
646
+ await TestAsync(
647
+ sourceProvider: "azure",
648
+ updateOperationsPerformed: [
649
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
650
+ ],
651
+ updatedDependencies: [
652
+ new ReportedDependency()
653
+ {
654
+ Name = "Some.Dependency",
655
+ PreviousVersion = "1.0.0",
656
+ Version = "2.0.0",
657
+ Requirements = [
658
+ new ReportedRequirement()
659
+ {
660
+ File = "",
661
+ Requirement = "2.0.0",
662
+ Source = new()
663
+ {
664
+ SourceUrl = "https://github.com/Some.Owner/Some.Dependency",
665
+ },
666
+ }
667
+ ],
668
+ }
669
+ ],
670
+ httpResponses: [
671
+ ("https://api.github.com/repos/Some.Owner/Some.Dependency/releases?per_page=100", $$"""
672
+ [
673
+ {
674
+ "name": "2.0.0",
675
+ "tag_name": "2.0.0",
676
+ "body": "{{longReleaseNote.ToString().Replace("\r", "").Trim().Replace("\n", "\\n")}}"
677
+ },
678
+ {
679
+ "name": "1.0.0",
680
+ "tag_name": "1.0.0",
681
+ "body": "* line 1\n* line 2"
682
+ }
683
+ ]
684
+ """)
685
+ ],
686
+ expectedBody: $"""
687
+ Updated [Some.Dependency](https://github.com/Some.Owner/Some.Dependency) from 1.0.0 to 2.0.0.
688
+
689
+ # Release notes
690
+
691
+ _Sourced from [Some.Dependency's releases](https://github.com/Some.Owner/Some.Dependency/releases)._
692
+
693
+ ## 2.0.0
694
+
695
+ {expectedReleaseNote.ToString().Replace("\r", "").Trim()}
696
+ * line 50
697
+ ... (truncated)
698
+
699
+ Commits viewable in [compare view](https://github.com/Some.Owner/Some.Dependency/compare/1.0.0...2.0.0).
700
+ """
701
+ );
702
+ }
703
+
704
+ [Fact]
705
+ public async Task GeneratePrBody_PrLengthIsTruncated()
706
+ {
707
+ // azure source provider has the shortest PR limit of 3999 characters
708
+ var sourceProvider = "azure";
709
+ var longReleaseNote = new string('x', 5000);
710
+
711
+ var expectedHeader = """
712
+ Updated [Some.Dependency](https://github.com/Some.Owner/Some.Dependency) from 1.0.0 to 2.0.0.
713
+
714
+ # Release notes
715
+
716
+ _Sourced from [Some.Dependency's releases](https://github.com/Some.Owner/Some.Dependency/releases)._
717
+
718
+ ## 2.0.0
719
+
720
+ """.Replace("\r", "");
721
+ var extraCharacterCount = DetailedPullRequestBodyGenerator.GetMaxPrLength(sourceProvider)!.Value
722
+ - expectedHeader.Length
723
+ - DetailedPullRequestBodyGenerator.TruncatedMessage.Length
724
+ - 1; // this `1` accounts for a newline
725
+ var expectedReleaseNote = new string('x', extraCharacterCount);
726
+ await TestAsync(
727
+ sourceProvider: sourceProvider,
728
+ updateOperationsPerformed: [
729
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
730
+ ],
731
+ updatedDependencies: [
732
+ new ReportedDependency()
733
+ {
734
+ Name = "Some.Dependency",
735
+ PreviousVersion = "1.0.0",
736
+ Version = "2.0.0",
737
+ Requirements = [
738
+ new ReportedRequirement()
739
+ {
740
+ File = "",
741
+ Requirement = "2.0.0",
742
+ Source = new()
743
+ {
744
+ SourceUrl = "https://github.com/Some.Owner/Some.Dependency",
745
+ },
746
+ }
747
+ ],
748
+ }
749
+ ],
750
+ httpResponses: [
751
+ ("https://api.github.com/repos/Some.Owner/Some.Dependency/releases?per_page=100", $$"""
752
+ [
753
+ {
754
+ "name": "2.0.0",
755
+ "tag_name": "2.0.0",
756
+ "body": "{{longReleaseNote}}"
757
+ },
758
+ {
759
+ "name": "1.0.0",
760
+ "tag_name": "1.0.0",
761
+ "body": "* line 1\n* line 2"
762
+ }
763
+ ]
764
+ """)
765
+ ],
766
+ expectedBody: $"""
767
+ {expectedHeader}
768
+ {expectedReleaseNote}...
769
+
770
+ _Description has been truncated_
771
+ """
772
+ );
773
+ }
774
+
775
+ [Fact]
776
+ public async Task GeneratePrBody_LinksAndMentionsAreScrubbed()
777
+ {
778
+ await TestAsync(
779
+ updateOperationsPerformed: [
780
+ new DirectUpdate() { DependencyName = "Some.Dependency", OldVersion = NuGetVersion.Parse("1.0.0"), NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = [] },
781
+ ],
782
+ updatedDependencies: [
783
+ new ReportedDependency()
784
+ {
785
+ Name = "Some.Dependency",
786
+ PreviousVersion = "1.0.0",
787
+ Version = "2.0.0",
788
+ Requirements = [
789
+ new ReportedRequirement()
790
+ {
791
+ File = "",
792
+ Requirement = "2.0.0",
793
+ Source = new()
794
+ {
795
+ SourceUrl = "https://github.com/Some.Owner/Some.Dependency",
796
+ },
797
+ }
798
+ ],
799
+ }
800
+ ],
801
+ httpResponses: [
802
+ ("https://api.github.com/repos/Some.Owner/Some.Dependency/releases?per_page=100", """
803
+ [
804
+ {
805
+ "name": "2.0.0",
806
+ "tag_name": "2.0.0",
807
+ "body": "Direct mention of @example user on @team/example."
808
+ },
809
+ {
810
+ "name": "1.0.1",
811
+ "tag_name": "1.0.1",
812
+ "body": "Issue #123 as well as owner/repo#456."
813
+ },
814
+ {
815
+ "name": "1.0.0",
816
+ "tag_name": "1.0.0",
817
+ "body": "* point 1\n* point 2"
818
+ }
819
+ ]
820
+ """)
821
+ ],
822
+ expectedBody: $"""
823
+ Updated [Some.Dependency](https://github.com/Some.Owner/Some.Dependency) from 1.0.0 to 2.0.0.
824
+
825
+ <details>
826
+ <summary>Release notes</summary>
827
+
828
+ _Sourced from [Some.Dependency's releases](https://github.com/Some.Owner/Some.Dependency/releases)._
829
+
830
+ ## 2.0.0
831
+
832
+ Direct mention of @{"\u200B"}example user on @{"\u200B"}team/example.
833
+
834
+ ## 1.0.1
835
+
836
+ Issue #{"\u200B"}123 as well as owner/repo#{"\u200B"}456.
837
+
838
+ Commits viewable in [compare view](https://github.com/Some.Owner/Some.Dependency/compare/1.0.0...2.0.0).
839
+ </details>
840
+ """
841
+ );
842
+ }
843
+
844
+ private static async Task TestAsync(
845
+ ImmutableArray<UpdateOperationBase> updateOperationsPerformed,
846
+ ImmutableArray<ReportedDependency> updatedDependencies,
847
+ (string Url, string Body)[] httpResponses,
848
+ string expectedBody,
849
+ string sourceProvider = "github"
850
+ )
851
+ {
852
+ // arrange
853
+ var job = new Job()
854
+ {
855
+ Source = new()
856
+ {
857
+ Provider = sourceProvider,
858
+ Repo = "test/repo",
859
+ }
860
+ };
861
+
862
+ // act
863
+ var responses = httpResponses.ToDictionary(x => x.Url, x => x.Body);
864
+ var httpFetcher = new TestHttpFetcher(responses);
865
+ var generator = new DetailedPullRequestBodyGenerator(httpFetcher);
866
+ var actualBody = await generator.GeneratePullRequestBodyTextAsync(job, updateOperationsPerformed, updatedDependencies);
867
+
868
+ // assert
869
+ Assert.Equal(expectedBody.Replace("\r", ""), actualBody.Replace("\r", ""));
870
+ }
871
+ }