dependabot-nuget 0.315.0 → 0.316.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.
- checksums.yaml +4 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +6 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +3 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/ClosePullRequest.cs +15 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CreatePullRequest.cs +47 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +60 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +151 -23
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +4 -18
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequestExistsForSecurityUpdate.cs +15 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/SecurityUpdateDependencyNotFound.cs +9 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/SecurityUpdateIgnored.cs +10 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/SecurityUpdateNotFound.cs +11 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/SecurityUpdateNotPossible.cs +13 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UpdatePullRequest.cs +6 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ModifiedFilesTracker.cs +151 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestTextGenerator.cs +78 -32
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +99 -111
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +169 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +271 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/IUpdateHandler.cs +22 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandler.cs +192 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandler.cs +187 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandler.cs +175 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdateOperationBase.cs +43 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ILogger.cs +17 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +15 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MarkdownListBuilder.cs +65 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/ApiModel/JobTests.cs +405 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/EndToEndTests.cs +92 -82
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/HttpApiHandlerTests.cs +5 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MessageReportTests.cs +67 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +445 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestMessageTests.cs +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestTextTests.cs +260 -20
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +30 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +69 -10
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandlerTests.cs +766 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/GroupUpdateAllVersionsHandlerTests.cs +636 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandlerTests.cs +513 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandlerTests.cs +806 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandlerTests.cs +589 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/UpdateHandlerSelectionTests.cs +183 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/UpdateHandlersTestsBase.cs +43 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateOperationBaseTests.cs +121 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Mixed.cs +6 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +51 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MarkdownListBuilderTests.cs +42 -0
- metadata +26 -4
@@ -0,0 +1,766 @@
|
|
1
|
+
using System.Collections.Immutable;
|
2
|
+
|
3
|
+
using NuGet.Versioning;
|
4
|
+
|
5
|
+
using NuGetUpdater.Core.Analyze;
|
6
|
+
using NuGetUpdater.Core.Discover;
|
7
|
+
using NuGetUpdater.Core.Run.ApiModel;
|
8
|
+
using NuGetUpdater.Core.Run.UpdateHandlers;
|
9
|
+
using NuGetUpdater.Core.Updater;
|
10
|
+
|
11
|
+
using Xunit;
|
12
|
+
|
13
|
+
namespace NuGetUpdater.Core.Test.Run.UpdateHandlers;
|
14
|
+
|
15
|
+
public class CreateSecurityUpdatePullRequestHandlerTests : UpdateHandlersTestsBase
|
16
|
+
{
|
17
|
+
[Fact]
|
18
|
+
public async Task GeneratesCreatePullRequest()
|
19
|
+
{
|
20
|
+
await TestAsync(
|
21
|
+
job: new Job()
|
22
|
+
{
|
23
|
+
Dependencies = ["Some.Dependency"],
|
24
|
+
SecurityAdvisories = [new() { DependencyName = "Some.Dependency", AffectedVersions = [Requirement.Parse("= 1.0.0")] }],
|
25
|
+
SecurityUpdatesOnly = true,
|
26
|
+
Source = CreateJobSource("/src"),
|
27
|
+
},
|
28
|
+
files: [
|
29
|
+
("src/project.csproj", "initial contents"),
|
30
|
+
],
|
31
|
+
discoveryWorker: TestDiscoveryWorker.FromResults(
|
32
|
+
("/src", new WorkspaceDiscoveryResult()
|
33
|
+
{
|
34
|
+
Path = "/src",
|
35
|
+
Projects = [
|
36
|
+
new()
|
37
|
+
{
|
38
|
+
FilePath = "project.csproj",
|
39
|
+
Dependencies = [
|
40
|
+
new("Some.Dependency", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
|
41
|
+
new("Unrelated.Dependency", "3.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
|
42
|
+
],
|
43
|
+
ImportedFiles = [],
|
44
|
+
AdditionalFiles = [],
|
45
|
+
}
|
46
|
+
],
|
47
|
+
})
|
48
|
+
),
|
49
|
+
analyzeWorker: new TestAnalyzeWorker(input =>
|
50
|
+
{
|
51
|
+
var repoRoot = input.Item1;
|
52
|
+
var discovery = input.Item2;
|
53
|
+
var dependencyInfo = input.Item3;
|
54
|
+
if (dependencyInfo.Name != "Some.Dependency")
|
55
|
+
{
|
56
|
+
throw new NotImplementedException($"Test didn't expect to update dependency {dependencyInfo.Name}");
|
57
|
+
}
|
58
|
+
|
59
|
+
return Task.FromResult(new AnalysisResult()
|
60
|
+
{
|
61
|
+
CanUpdate = true,
|
62
|
+
UpdatedVersion = "2.0.0",
|
63
|
+
UpdatedDependencies = [],
|
64
|
+
});
|
65
|
+
}),
|
66
|
+
updaterWorker: new TestUpdaterWorker(async input =>
|
67
|
+
{
|
68
|
+
var repoRoot = input.Item1;
|
69
|
+
var workspacePath = input.Item2;
|
70
|
+
var dependencyName = input.Item3;
|
71
|
+
var previousVersion = input.Item4;
|
72
|
+
var newVersion = input.Item5;
|
73
|
+
var isTransitive = input.Item6;
|
74
|
+
|
75
|
+
await File.WriteAllTextAsync(Path.Join(repoRoot, workspacePath), "updated contents");
|
76
|
+
|
77
|
+
return new UpdateOperationResult()
|
78
|
+
{
|
79
|
+
UpdateOperations = [new DirectUpdate() { DependencyName = "Some.Dependency", NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = ["/src/project.csproj"] }],
|
80
|
+
};
|
81
|
+
}),
|
82
|
+
expectedUpdateHandler: CreateSecurityUpdatePullRequestHandler.Instance,
|
83
|
+
expectedApiMessages: [
|
84
|
+
new UpdatedDependencyList()
|
85
|
+
{
|
86
|
+
Dependencies = [
|
87
|
+
new()
|
88
|
+
{
|
89
|
+
Name = "Some.Dependency",
|
90
|
+
Version = "1.0.0",
|
91
|
+
Requirements = [
|
92
|
+
new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
93
|
+
],
|
94
|
+
},
|
95
|
+
new()
|
96
|
+
{
|
97
|
+
Name = "Unrelated.Dependency",
|
98
|
+
Version = "3.0.0",
|
99
|
+
Requirements = [
|
100
|
+
new() { Requirement = "3.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
101
|
+
],
|
102
|
+
},
|
103
|
+
],
|
104
|
+
DependencyFiles = ["/src/project.csproj"],
|
105
|
+
},
|
106
|
+
new IncrementMetric()
|
107
|
+
{
|
108
|
+
Metric = "updater.started",
|
109
|
+
Tags = new()
|
110
|
+
{
|
111
|
+
["operation"] = "create_security_pr",
|
112
|
+
}
|
113
|
+
},
|
114
|
+
new CreatePullRequest()
|
115
|
+
{
|
116
|
+
Dependencies = [
|
117
|
+
new()
|
118
|
+
{
|
119
|
+
Name = "Some.Dependency",
|
120
|
+
Version = "2.0.0",
|
121
|
+
Requirements = [
|
122
|
+
new() { Requirement = "2.0.0", File = "/src/project.csproj", Groups = ["dependencies"], Source = new() { SourceUrl = null } },
|
123
|
+
],
|
124
|
+
PreviousVersion = "1.0.0",
|
125
|
+
PreviousRequirements = [
|
126
|
+
new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
127
|
+
],
|
128
|
+
}
|
129
|
+
],
|
130
|
+
UpdatedDependencyFiles = [
|
131
|
+
new()
|
132
|
+
{
|
133
|
+
Directory = "/src",
|
134
|
+
Name = "project.csproj",
|
135
|
+
Content = "updated contents",
|
136
|
+
}
|
137
|
+
],
|
138
|
+
BaseCommitSha = "TEST-COMMIT-SHA",
|
139
|
+
CommitMessage = RunWorkerTests.TestPullRequestCommitMessage,
|
140
|
+
PrTitle = RunWorkerTests.TestPullRequestTitle,
|
141
|
+
PrBody = RunWorkerTests.TestPullRequestBody,
|
142
|
+
DependencyGroup = null,
|
143
|
+
},
|
144
|
+
new MarkAsProcessed("TEST-COMMIT-SHA"),
|
145
|
+
]
|
146
|
+
);
|
147
|
+
}
|
148
|
+
|
149
|
+
[Fact]
|
150
|
+
public async Task GeneratesCreatePullRequest_UpdatingOneProjectImplicitlyUpdatesTheOther()
|
151
|
+
{
|
152
|
+
await TestAsync(
|
153
|
+
job: new Job()
|
154
|
+
{
|
155
|
+
Dependencies = ["Some.Dependency"],
|
156
|
+
SecurityAdvisories = [new() { DependencyName = "Some.Dependency", AffectedVersions = [Requirement.Parse("= 1.0.0")] }],
|
157
|
+
SecurityUpdatesOnly = true,
|
158
|
+
Source = CreateJobSource("/src"),
|
159
|
+
},
|
160
|
+
files: [
|
161
|
+
("src/Directory.Packages.props", "initial contents"),
|
162
|
+
("src/project1.csproj", "initial contents"),
|
163
|
+
("src/project2.csproj", "initial contents"),
|
164
|
+
],
|
165
|
+
discoveryWorker: TestDiscoveryWorker.FromResults(
|
166
|
+
("/src", new WorkspaceDiscoveryResult()
|
167
|
+
{
|
168
|
+
Path = "/src",
|
169
|
+
Projects = [
|
170
|
+
new()
|
171
|
+
{
|
172
|
+
FilePath = "project1.csproj",
|
173
|
+
Dependencies = [
|
174
|
+
new("Some.Dependency", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
|
175
|
+
],
|
176
|
+
ImportedFiles = ["Directory.Packages.props"],
|
177
|
+
AdditionalFiles = [],
|
178
|
+
},
|
179
|
+
new()
|
180
|
+
{
|
181
|
+
FilePath = "project2.csproj",
|
182
|
+
Dependencies = [
|
183
|
+
new("Some.Dependency", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
|
184
|
+
],
|
185
|
+
ImportedFiles = ["Directory.Packages.props"],
|
186
|
+
AdditionalFiles = [],
|
187
|
+
},
|
188
|
+
],
|
189
|
+
})
|
190
|
+
),
|
191
|
+
analyzeWorker: new TestAnalyzeWorker(input =>
|
192
|
+
{
|
193
|
+
var repoRoot = input.Item1;
|
194
|
+
var discovery = input.Item2;
|
195
|
+
var dependencyInfo = input.Item3;
|
196
|
+
if (dependencyInfo.Name != "Some.Dependency")
|
197
|
+
{
|
198
|
+
throw new NotImplementedException($"Test didn't expect to update dependency {dependencyInfo.Name}");
|
199
|
+
}
|
200
|
+
|
201
|
+
return Task.FromResult(new AnalysisResult()
|
202
|
+
{
|
203
|
+
CanUpdate = true,
|
204
|
+
UpdatedVersion = "2.0.0",
|
205
|
+
UpdatedDependencies = [],
|
206
|
+
});
|
207
|
+
}),
|
208
|
+
updaterWorker: new TestUpdaterWorker(async input =>
|
209
|
+
{
|
210
|
+
var repoRoot = input.Item1;
|
211
|
+
var workspacePath = input.Item2;
|
212
|
+
var dependencyName = input.Item3;
|
213
|
+
var previousVersion = input.Item4;
|
214
|
+
var newVersion = input.Item5;
|
215
|
+
var isTransitive = input.Item6;
|
216
|
+
|
217
|
+
await File.WriteAllTextAsync(Path.Join(repoRoot, "src/Directory.Packages.props"), "updated contents");
|
218
|
+
|
219
|
+
// only report an update performed on the first project
|
220
|
+
ImmutableArray<UpdateOperationBase> updateOperations = workspacePath.EndsWith("project1.csproj")
|
221
|
+
? [new DirectUpdate() { DependencyName = "Some.Dependency", NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = ["/src/Directory.Packages.csproj"] }]
|
222
|
+
: [];
|
223
|
+
|
224
|
+
return new UpdateOperationResult()
|
225
|
+
{
|
226
|
+
UpdateOperations = updateOperations,
|
227
|
+
};
|
228
|
+
}),
|
229
|
+
expectedUpdateHandler: CreateSecurityUpdatePullRequestHandler.Instance,
|
230
|
+
expectedApiMessages: [
|
231
|
+
new UpdatedDependencyList()
|
232
|
+
{
|
233
|
+
Dependencies = [
|
234
|
+
new()
|
235
|
+
{
|
236
|
+
Name = "Some.Dependency",
|
237
|
+
Version = "1.0.0",
|
238
|
+
Requirements = [
|
239
|
+
new() { Requirement = "1.0.0", File = "/src/project1.csproj", Groups = ["dependencies"] },
|
240
|
+
],
|
241
|
+
},
|
242
|
+
new()
|
243
|
+
{
|
244
|
+
Name = "Some.Dependency",
|
245
|
+
Version = "1.0.0",
|
246
|
+
Requirements = [
|
247
|
+
new() { Requirement = "1.0.0", File = "/src/project2.csproj", Groups = ["dependencies"] },
|
248
|
+
],
|
249
|
+
},
|
250
|
+
],
|
251
|
+
DependencyFiles = ["/src/Directory.Packages.props", "/src/project1.csproj", "/src/project2.csproj"],
|
252
|
+
},
|
253
|
+
new IncrementMetric()
|
254
|
+
{
|
255
|
+
Metric = "updater.started",
|
256
|
+
Tags = new()
|
257
|
+
{
|
258
|
+
["operation"] = "create_security_pr",
|
259
|
+
}
|
260
|
+
},
|
261
|
+
new CreatePullRequest()
|
262
|
+
{
|
263
|
+
Dependencies = [
|
264
|
+
new()
|
265
|
+
{
|
266
|
+
Name = "Some.Dependency",
|
267
|
+
Version = "2.0.0",
|
268
|
+
Requirements = [
|
269
|
+
new() { Requirement = "2.0.0", File = "/src/project1.csproj", Groups = ["dependencies"], Source = new() { SourceUrl = null } },
|
270
|
+
],
|
271
|
+
PreviousVersion = "1.0.0",
|
272
|
+
PreviousRequirements = [
|
273
|
+
new() { Requirement = "1.0.0", File = "/src/project1.csproj", Groups = ["dependencies"] },
|
274
|
+
],
|
275
|
+
}
|
276
|
+
],
|
277
|
+
UpdatedDependencyFiles = [
|
278
|
+
new()
|
279
|
+
{
|
280
|
+
Directory = "/src",
|
281
|
+
Name = "Directory.Packages.props",
|
282
|
+
Content = "updated contents",
|
283
|
+
}
|
284
|
+
],
|
285
|
+
BaseCommitSha = "TEST-COMMIT-SHA",
|
286
|
+
CommitMessage = RunWorkerTests.TestPullRequestCommitMessage,
|
287
|
+
PrTitle = RunWorkerTests.TestPullRequestTitle,
|
288
|
+
PrBody = RunWorkerTests.TestPullRequestBody,
|
289
|
+
DependencyGroup = null,
|
290
|
+
},
|
291
|
+
new MarkAsProcessed("TEST-COMMIT-SHA"),
|
292
|
+
]
|
293
|
+
);
|
294
|
+
}
|
295
|
+
|
296
|
+
[Fact]
|
297
|
+
public async Task GeneratesSecurityUpdateDependencyNotFound()
|
298
|
+
{
|
299
|
+
// requested dependency doesn't exist
|
300
|
+
await TestAsync(
|
301
|
+
job: new Job()
|
302
|
+
{
|
303
|
+
Dependencies = ["This.Dependency.Does.Not.Exist"],
|
304
|
+
SecurityAdvisories = [new() { DependencyName = "This.Dependency.Does.Not.Exist", AffectedVersions = [Requirement.Parse("= 1.0.0")] }],
|
305
|
+
SecurityUpdatesOnly = true,
|
306
|
+
Source = CreateJobSource("/src"),
|
307
|
+
},
|
308
|
+
files: [
|
309
|
+
("src/project.csproj", "initial contents"),
|
310
|
+
],
|
311
|
+
discoveryWorker: TestDiscoveryWorker.FromResults(
|
312
|
+
("/src", new WorkspaceDiscoveryResult()
|
313
|
+
{
|
314
|
+
Path = "/src",
|
315
|
+
Projects = [
|
316
|
+
new()
|
317
|
+
{
|
318
|
+
FilePath = "project.csproj",
|
319
|
+
Dependencies = [
|
320
|
+
new("Some.Dependency", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
|
321
|
+
],
|
322
|
+
ImportedFiles = [],
|
323
|
+
AdditionalFiles = [],
|
324
|
+
}
|
325
|
+
],
|
326
|
+
})
|
327
|
+
),
|
328
|
+
analyzeWorker: new TestAnalyzeWorker(_ => throw new NotImplementedException("test shouldn't get this far")),
|
329
|
+
updaterWorker: new TestUpdaterWorker(_ => throw new NotImplementedException("test shouldn't get this far")),
|
330
|
+
expectedUpdateHandler: CreateSecurityUpdatePullRequestHandler.Instance,
|
331
|
+
expectedApiMessages: [
|
332
|
+
new UpdatedDependencyList()
|
333
|
+
{
|
334
|
+
Dependencies = [
|
335
|
+
new()
|
336
|
+
{
|
337
|
+
Name = "Some.Dependency",
|
338
|
+
Version = "1.0.0",
|
339
|
+
Requirements = [
|
340
|
+
new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
341
|
+
],
|
342
|
+
}
|
343
|
+
],
|
344
|
+
DependencyFiles = ["/src/project.csproj"],
|
345
|
+
},
|
346
|
+
new IncrementMetric()
|
347
|
+
{
|
348
|
+
Metric = "updater.started",
|
349
|
+
Tags = new()
|
350
|
+
{
|
351
|
+
["operation"] = "create_security_pr",
|
352
|
+
}
|
353
|
+
},
|
354
|
+
new SecurityUpdateDependencyNotFound(),
|
355
|
+
new MarkAsProcessed("TEST-COMMIT-SHA"),
|
356
|
+
]
|
357
|
+
);
|
358
|
+
}
|
359
|
+
|
360
|
+
[Fact]
|
361
|
+
public async Task GeneratesSecurityUpdateNotNeeded()
|
362
|
+
{
|
363
|
+
// requested dependency exists, but isn't vulnerable
|
364
|
+
await TestAsync(
|
365
|
+
job: new Job()
|
366
|
+
{
|
367
|
+
Dependencies = ["Some.Dependency"],
|
368
|
+
SecurityAdvisories = [new() { DependencyName = "Some.Dependency", AffectedVersions = [Requirement.Parse("= 1.0.0")] }],
|
369
|
+
SecurityUpdatesOnly = true,
|
370
|
+
Source = CreateJobSource("/src"),
|
371
|
+
},
|
372
|
+
files: [
|
373
|
+
("src/project.csproj", "initial contents"),
|
374
|
+
],
|
375
|
+
discoveryWorker: TestDiscoveryWorker.FromResults(
|
376
|
+
("/src", new WorkspaceDiscoveryResult()
|
377
|
+
{
|
378
|
+
Path = "/src",
|
379
|
+
Projects = [
|
380
|
+
new()
|
381
|
+
{
|
382
|
+
FilePath = "project.csproj",
|
383
|
+
Dependencies = [
|
384
|
+
new("Some.Dependency", "2.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
|
385
|
+
],
|
386
|
+
ImportedFiles = [],
|
387
|
+
AdditionalFiles = [],
|
388
|
+
}
|
389
|
+
],
|
390
|
+
})
|
391
|
+
),
|
392
|
+
analyzeWorker: new TestAnalyzeWorker(_ => throw new NotImplementedException("test shouldn't get this far")),
|
393
|
+
updaterWorker: new TestUpdaterWorker(_ => throw new NotImplementedException("test shouldn't get this far")),
|
394
|
+
expectedUpdateHandler: CreateSecurityUpdatePullRequestHandler.Instance,
|
395
|
+
expectedApiMessages: [
|
396
|
+
new UpdatedDependencyList()
|
397
|
+
{
|
398
|
+
Dependencies = [
|
399
|
+
new()
|
400
|
+
{
|
401
|
+
Name = "Some.Dependency",
|
402
|
+
Version = "2.0.0",
|
403
|
+
Requirements = [
|
404
|
+
new() { Requirement = "2.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
405
|
+
],
|
406
|
+
}
|
407
|
+
],
|
408
|
+
DependencyFiles = ["/src/project.csproj"],
|
409
|
+
},
|
410
|
+
new IncrementMetric()
|
411
|
+
{
|
412
|
+
Metric = "updater.started",
|
413
|
+
Tags = new()
|
414
|
+
{
|
415
|
+
["operation"] = "create_security_pr",
|
416
|
+
}
|
417
|
+
},
|
418
|
+
new SecurityUpdateNotNeeded("Some.Dependency"),
|
419
|
+
new MarkAsProcessed("TEST-COMMIT-SHA"),
|
420
|
+
]
|
421
|
+
);
|
422
|
+
}
|
423
|
+
|
424
|
+
[Fact]
|
425
|
+
public async Task GeneratesSecurityUpdateNotFound()
|
426
|
+
{
|
427
|
+
// dependency exists and is vulnerable, but non-vulnerable version isn't on feed
|
428
|
+
await TestAsync(
|
429
|
+
job: new Job()
|
430
|
+
{
|
431
|
+
Dependencies = ["Some.Dependency"],
|
432
|
+
SecurityAdvisories = [new() { DependencyName = "Some.Dependency", AffectedVersions = [Requirement.Parse("= 1.0.0")] }],
|
433
|
+
SecurityUpdatesOnly = true,
|
434
|
+
Source = CreateJobSource("/src"),
|
435
|
+
},
|
436
|
+
files: [
|
437
|
+
("src/project.csproj", "initial contents"),
|
438
|
+
],
|
439
|
+
discoveryWorker: TestDiscoveryWorker.FromResults(
|
440
|
+
("/src", new WorkspaceDiscoveryResult()
|
441
|
+
{
|
442
|
+
Path = "/src",
|
443
|
+
Projects = [
|
444
|
+
new()
|
445
|
+
{
|
446
|
+
FilePath = "project.csproj",
|
447
|
+
Dependencies = [
|
448
|
+
new("Some.Dependency", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
|
449
|
+
],
|
450
|
+
ImportedFiles = [],
|
451
|
+
AdditionalFiles = [],
|
452
|
+
}
|
453
|
+
],
|
454
|
+
})
|
455
|
+
),
|
456
|
+
analyzeWorker: new TestAnalyzeWorker(input =>
|
457
|
+
{
|
458
|
+
var repoRoot = input.Item1;
|
459
|
+
var discovery = input.Item2;
|
460
|
+
var dependencyInfo = input.Item3;
|
461
|
+
if (dependencyInfo.Name != "Some.Dependency")
|
462
|
+
{
|
463
|
+
throw new NotImplementedException($"Test didn't expect to update dependency {dependencyInfo.Name}");
|
464
|
+
}
|
465
|
+
|
466
|
+
return Task.FromResult(new AnalysisResult()
|
467
|
+
{
|
468
|
+
CanUpdate = false,
|
469
|
+
UpdatedVersion = "1.0.0",
|
470
|
+
UpdatedDependencies = [],
|
471
|
+
});
|
472
|
+
}),
|
473
|
+
updaterWorker: new TestUpdaterWorker(_ => throw new NotImplementedException("test shouldn't get this far")),
|
474
|
+
expectedUpdateHandler: CreateSecurityUpdatePullRequestHandler.Instance,
|
475
|
+
expectedApiMessages: [
|
476
|
+
new UpdatedDependencyList()
|
477
|
+
{
|
478
|
+
Dependencies = [
|
479
|
+
new()
|
480
|
+
{
|
481
|
+
Name = "Some.Dependency",
|
482
|
+
Version = "1.0.0",
|
483
|
+
Requirements = [
|
484
|
+
new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
485
|
+
],
|
486
|
+
}
|
487
|
+
],
|
488
|
+
DependencyFiles = ["/src/project.csproj"],
|
489
|
+
},
|
490
|
+
new IncrementMetric()
|
491
|
+
{
|
492
|
+
Metric = "updater.started",
|
493
|
+
Tags = new()
|
494
|
+
{
|
495
|
+
["operation"] = "create_security_pr",
|
496
|
+
}
|
497
|
+
},
|
498
|
+
new SecurityUpdateNotFound("Some.Dependency", "1.0.0"),
|
499
|
+
new MarkAsProcessed("TEST-COMMIT-SHA"),
|
500
|
+
]
|
501
|
+
);
|
502
|
+
}
|
503
|
+
|
504
|
+
[Fact]
|
505
|
+
public async Task GeneratesSecurityUpdateIgnored()
|
506
|
+
{
|
507
|
+
// vulnerable dependency exists, but it is explicitly ignored
|
508
|
+
await TestAsync(
|
509
|
+
job: new Job()
|
510
|
+
{
|
511
|
+
Dependencies = ["Some.Dependency"],
|
512
|
+
IgnoreConditions = [new() { DependencyName = "Some.Dependency" }],
|
513
|
+
SecurityAdvisories = [new() { DependencyName = "Some.Dependency", AffectedVersions = [Requirement.Parse("= 1.0.0")] }],
|
514
|
+
SecurityUpdatesOnly = true,
|
515
|
+
Source = CreateJobSource("/src"),
|
516
|
+
},
|
517
|
+
files: [
|
518
|
+
("src/project.csproj", "initial contents"),
|
519
|
+
],
|
520
|
+
discoveryWorker: TestDiscoveryWorker.FromResults(
|
521
|
+
("/src", new WorkspaceDiscoveryResult()
|
522
|
+
{
|
523
|
+
Path = "/src",
|
524
|
+
Projects = [
|
525
|
+
new()
|
526
|
+
{
|
527
|
+
FilePath = "project.csproj",
|
528
|
+
Dependencies = [
|
529
|
+
new("Some.Dependency", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
|
530
|
+
],
|
531
|
+
ImportedFiles = [],
|
532
|
+
AdditionalFiles = [],
|
533
|
+
}
|
534
|
+
],
|
535
|
+
})
|
536
|
+
),
|
537
|
+
analyzeWorker: new TestAnalyzeWorker(input =>
|
538
|
+
{
|
539
|
+
var repoRoot = input.Item1;
|
540
|
+
var discovery = input.Item2;
|
541
|
+
var dependencyInfo = input.Item3;
|
542
|
+
if (dependencyInfo.Name != "Some.Dependency")
|
543
|
+
{
|
544
|
+
throw new NotImplementedException($"Test didn't expect to update dependency {dependencyInfo.Name}");
|
545
|
+
}
|
546
|
+
|
547
|
+
return Task.FromResult(new AnalysisResult()
|
548
|
+
{
|
549
|
+
CanUpdate = true,
|
550
|
+
UpdatedVersion = "2.0.0",
|
551
|
+
UpdatedDependencies = [],
|
552
|
+
});
|
553
|
+
}),
|
554
|
+
updaterWorker: new TestUpdaterWorker(_ => throw new NotImplementedException("test shouldn't get this far")),
|
555
|
+
expectedUpdateHandler: CreateSecurityUpdatePullRequestHandler.Instance,
|
556
|
+
expectedApiMessages: [
|
557
|
+
new UpdatedDependencyList()
|
558
|
+
{
|
559
|
+
Dependencies = [
|
560
|
+
new()
|
561
|
+
{
|
562
|
+
Name = "Some.Dependency",
|
563
|
+
Version = "1.0.0",
|
564
|
+
Requirements = [
|
565
|
+
new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
566
|
+
],
|
567
|
+
}
|
568
|
+
],
|
569
|
+
DependencyFiles = ["/src/project.csproj"],
|
570
|
+
},
|
571
|
+
new IncrementMetric()
|
572
|
+
{
|
573
|
+
Metric = "updater.started",
|
574
|
+
Tags = new()
|
575
|
+
{
|
576
|
+
["operation"] = "create_security_pr",
|
577
|
+
}
|
578
|
+
},
|
579
|
+
new SecurityUpdateIgnored("Some.Dependency"),
|
580
|
+
new MarkAsProcessed("TEST-COMMIT-SHA"),
|
581
|
+
]
|
582
|
+
);
|
583
|
+
}
|
584
|
+
|
585
|
+
[Fact]
|
586
|
+
public async Task GeneratesSecurityUpdateNotPossible()
|
587
|
+
{
|
588
|
+
// vulnerable dependency exists and update was attempted, but nothing could be done
|
589
|
+
await TestAsync(
|
590
|
+
job: new Job()
|
591
|
+
{
|
592
|
+
Dependencies = ["Some.Dependency"],
|
593
|
+
SecurityAdvisories = [new() { DependencyName = "Some.Dependency", AffectedVersions = [Requirement.Parse("= 1.0.0")] }],
|
594
|
+
SecurityUpdatesOnly = true,
|
595
|
+
Source = CreateJobSource("/src"),
|
596
|
+
},
|
597
|
+
files: [
|
598
|
+
("src/project.csproj", "initial contents"),
|
599
|
+
],
|
600
|
+
discoveryWorker: TestDiscoveryWorker.FromResults(
|
601
|
+
("/src", new WorkspaceDiscoveryResult()
|
602
|
+
{
|
603
|
+
Path = "/src",
|
604
|
+
Projects = [
|
605
|
+
new()
|
606
|
+
{
|
607
|
+
FilePath = "project.csproj",
|
608
|
+
Dependencies = [
|
609
|
+
new("Some.Dependency", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
|
610
|
+
],
|
611
|
+
ImportedFiles = [],
|
612
|
+
AdditionalFiles = [],
|
613
|
+
}
|
614
|
+
],
|
615
|
+
})
|
616
|
+
),
|
617
|
+
analyzeWorker: new TestAnalyzeWorker(input =>
|
618
|
+
{
|
619
|
+
var repoRoot = input.Item1;
|
620
|
+
var discovery = input.Item2;
|
621
|
+
var dependencyInfo = input.Item3;
|
622
|
+
if (dependencyInfo.Name != "Some.Dependency")
|
623
|
+
{
|
624
|
+
throw new NotImplementedException($"Test didn't expect to update dependency {dependencyInfo.Name}");
|
625
|
+
}
|
626
|
+
|
627
|
+
return Task.FromResult(new AnalysisResult()
|
628
|
+
{
|
629
|
+
CanUpdate = true,
|
630
|
+
UpdatedVersion = "2.0.0",
|
631
|
+
UpdatedDependencies = [],
|
632
|
+
});
|
633
|
+
}),
|
634
|
+
updaterWorker: new TestUpdaterWorker(input =>
|
635
|
+
{
|
636
|
+
return Task.FromResult(new UpdateOperationResult()
|
637
|
+
{
|
638
|
+
UpdateOperations = [], // nothing could be done
|
639
|
+
});
|
640
|
+
}),
|
641
|
+
expectedUpdateHandler: CreateSecurityUpdatePullRequestHandler.Instance,
|
642
|
+
expectedApiMessages: [
|
643
|
+
new UpdatedDependencyList()
|
644
|
+
{
|
645
|
+
Dependencies = [
|
646
|
+
new()
|
647
|
+
{
|
648
|
+
Name = "Some.Dependency",
|
649
|
+
Version = "1.0.0",
|
650
|
+
Requirements = [
|
651
|
+
new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
652
|
+
],
|
653
|
+
}
|
654
|
+
],
|
655
|
+
DependencyFiles = ["/src/project.csproj"],
|
656
|
+
},
|
657
|
+
new IncrementMetric()
|
658
|
+
{
|
659
|
+
Metric = "updater.started",
|
660
|
+
Tags = new()
|
661
|
+
{
|
662
|
+
["operation"] = "create_security_pr",
|
663
|
+
}
|
664
|
+
},
|
665
|
+
new SecurityUpdateNotPossible("Some.Dependency", "2.0.0", "2.0.0", []),
|
666
|
+
new MarkAsProcessed("TEST-COMMIT-SHA"),
|
667
|
+
]
|
668
|
+
);
|
669
|
+
}
|
670
|
+
|
671
|
+
[Fact]
|
672
|
+
public async Task GeneratesPullRequestExistsForSecurityUpdate()
|
673
|
+
{
|
674
|
+
// everything was successful, but a PR already exists
|
675
|
+
await TestAsync(
|
676
|
+
job: new Job()
|
677
|
+
{
|
678
|
+
Dependencies = ["Some.Dependency"],
|
679
|
+
ExistingPullRequests = [new() { Dependencies = [new() { DependencyName = "Some.Dependency", DependencyVersion = NuGetVersion.Parse("2.0.0") }] }],
|
680
|
+
SecurityAdvisories = [new() { DependencyName = "Some.Dependency", AffectedVersions = [Requirement.Parse("= 1.0.0")] }],
|
681
|
+
SecurityUpdatesOnly = true,
|
682
|
+
Source = CreateJobSource("/src"),
|
683
|
+
},
|
684
|
+
files: [
|
685
|
+
("src/project.csproj", "initial contents"),
|
686
|
+
],
|
687
|
+
discoveryWorker: TestDiscoveryWorker.FromResults(
|
688
|
+
("/src", new WorkspaceDiscoveryResult()
|
689
|
+
{
|
690
|
+
Path = "/src",
|
691
|
+
Projects = [
|
692
|
+
new()
|
693
|
+
{
|
694
|
+
FilePath = "project.csproj",
|
695
|
+
Dependencies = [
|
696
|
+
new("Some.Dependency", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
|
697
|
+
],
|
698
|
+
ImportedFiles = [],
|
699
|
+
AdditionalFiles = [],
|
700
|
+
}
|
701
|
+
],
|
702
|
+
})
|
703
|
+
),
|
704
|
+
analyzeWorker: new TestAnalyzeWorker(input =>
|
705
|
+
{
|
706
|
+
var repoRoot = input.Item1;
|
707
|
+
var discovery = input.Item2;
|
708
|
+
var dependencyInfo = input.Item3;
|
709
|
+
if (dependencyInfo.Name != "Some.Dependency")
|
710
|
+
{
|
711
|
+
throw new NotImplementedException($"Test didn't expect to update dependency {dependencyInfo.Name}");
|
712
|
+
}
|
713
|
+
|
714
|
+
return Task.FromResult(new AnalysisResult()
|
715
|
+
{
|
716
|
+
CanUpdate = true,
|
717
|
+
UpdatedVersion = "2.0.0",
|
718
|
+
UpdatedDependencies = [],
|
719
|
+
});
|
720
|
+
}),
|
721
|
+
updaterWorker: new TestUpdaterWorker(async input =>
|
722
|
+
{
|
723
|
+
var repoRoot = input.Item1;
|
724
|
+
var workspacePath = input.Item2;
|
725
|
+
var dependencyName = input.Item3;
|
726
|
+
var previousVersion = input.Item4;
|
727
|
+
var newVersion = input.Item5;
|
728
|
+
var isTransitive = input.Item6;
|
729
|
+
|
730
|
+
await File.WriteAllTextAsync(Path.Join(repoRoot, workspacePath), "updated contents");
|
731
|
+
|
732
|
+
return new UpdateOperationResult()
|
733
|
+
{
|
734
|
+
UpdateOperations = [new DirectUpdate() { DependencyName = "Some.Dependency", NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = ["/src/project.csproj"] }],
|
735
|
+
};
|
736
|
+
}),
|
737
|
+
expectedUpdateHandler: CreateSecurityUpdatePullRequestHandler.Instance,
|
738
|
+
expectedApiMessages: [
|
739
|
+
new UpdatedDependencyList()
|
740
|
+
{
|
741
|
+
Dependencies = [
|
742
|
+
new()
|
743
|
+
{
|
744
|
+
Name = "Some.Dependency",
|
745
|
+
Version = "1.0.0",
|
746
|
+
Requirements = [
|
747
|
+
new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
|
748
|
+
],
|
749
|
+
}
|
750
|
+
],
|
751
|
+
DependencyFiles = ["/src/project.csproj"],
|
752
|
+
},
|
753
|
+
new IncrementMetric()
|
754
|
+
{
|
755
|
+
Metric = "updater.started",
|
756
|
+
Tags = new()
|
757
|
+
{
|
758
|
+
["operation"] = "create_security_pr",
|
759
|
+
}
|
760
|
+
},
|
761
|
+
new PullRequestExistsForSecurityUpdate([new("Some.Dependency", "2.0.0", DependencyType.Unknown)]),
|
762
|
+
new MarkAsProcessed("TEST-COMMIT-SHA"),
|
763
|
+
]
|
764
|
+
);
|
765
|
+
}
|
766
|
+
}
|