dependabot-nuget 0.308.0 → 0.310.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.
Files changed (20) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/NuGetUpdater.Cli.csproj +19 -0
  3. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Program.cs +5 -0
  4. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +6 -6
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +6 -0
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/HttpApiHandler.cs +12 -3
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +23 -3
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SpecialImportsConditionPatcher.cs +14 -2
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/BOMHandling.cs +35 -0
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +0 -8
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +3 -3
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/EndToEndTests.cs +355 -0
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +703 -550
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestDiscoveryWorker.cs +3 -4
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestHttpServer.cs +16 -6
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/SpecialFilePatcherTests.cs +19 -0
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/BOMHandlingTests.cs +66 -0
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/EOLHandlingTests.cs +227 -13
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +331 -164
  20. metadata +8 -5
@@ -19,6 +19,7 @@ namespace NuGetUpdater.Core.Test.Run;
19
19
  using static NuGetUpdater.Core.Utilities.EOLHandling;
20
20
 
21
21
  using TestFile = (string Path, string Content);
22
+ using RawTestFile = (string Path, byte[] Content);
22
23
 
23
24
  public class RunWorkerTests
24
25
  {
@@ -26,11 +27,8 @@ public class RunWorkerTests
26
27
  public const string TestPullRequestTitle = "test-pull-request-title";
27
28
  public const string TestPullRequestBody = "test-pull-request-body";
28
29
 
29
- [Theory]
30
- [InlineData(EOLType.CR)]
31
- [InlineData(EOLType.LF)]
32
- [InlineData(EOLType.CRLF)]
33
- public async Task UpdateSinglePackageProducedExpectedAPIMessages(EOLType EOL)
30
+ [Fact]
31
+ public async Task UpdateSinglePackageProducedExpectedAPIMessages()
34
32
  {
35
33
  await RunAsync(
36
34
  packages: [],
@@ -54,7 +52,7 @@ public class RunWorkerTests
54
52
  <PackageReference Include="Some.Package" Version="1.0.0" />
55
53
  </ItemGroup>
56
54
  </Project>
57
- """.SetEOL(EOL))
55
+ """)
58
56
  ],
59
57
  discoveryWorker: new TestDiscoveryWorker(_input =>
60
58
  {
@@ -105,7 +103,7 @@ public class RunWorkerTests
105
103
  <PackageReference Include="Some.Package" Version="1.0.1" />
106
104
  </ItemGroup>
107
105
  </Project>
108
- """.SetEOL(EOL));
106
+ """);
109
107
  return new UpdateOperationResult()
110
108
  {
111
109
  UpdateOperations = [
@@ -135,7 +133,8 @@ public class RunWorkerTests
135
133
  <PackageReference Include="Some.Package" Version="1.0.0" />
136
134
  </ItemGroup>
137
135
  </Project>
138
- """.SetEOL(EOL)))
136
+ """)),
137
+ ContentEncoding = "base64"
139
138
  }
140
139
  ],
141
140
  BaseCommitSha = "TEST-COMMIT-SHA",
@@ -220,7 +219,7 @@ public class RunWorkerTests
220
219
  <PackageReference Include="Some.Package" Version="1.0.1" />
221
220
  </ItemGroup>
222
221
  </Project>
223
- """.SetEOL(EOL),
222
+ """,
224
223
  },
225
224
  ],
226
225
  BaseCommitSha = "TEST-COMMIT-SHA",
@@ -233,14 +232,11 @@ public class RunWorkerTests
233
232
  );
234
233
  }
235
234
 
236
- [Theory]
237
- [InlineData(EOLType.CR)]
238
- [InlineData(EOLType.LF)]
239
- [InlineData(EOLType.CRLF)]
240
- public async Task UpdateHandlesSemicolonsInPackageReference(EOLType EOL)
235
+ [Fact]
236
+ public async Task UpdateHandlesSemicolonsInPackageReference()
241
237
  {
242
- var repoMetadata = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package" />""".SetEOL(EOL));
243
- var repoMetadata2 = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package2" />""".SetEOL(EOL));
238
+ var repoMetadata = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package" />""");
239
+ var repoMetadata2 = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package2" />""");
244
240
  await RunAsync(
245
241
  packages:
246
242
  [
@@ -270,7 +266,7 @@ public class RunWorkerTests
270
266
  <PackageReference Include="Some.Package;Some.Package2" Version="1.0.0" />
271
267
  </ItemGroup>
272
268
  </Project>
273
- """.SetEOL(EOL))
269
+ """)
274
270
  ],
275
271
  discoveryWorker: new TestDiscoveryWorker(_input =>
276
272
  {
@@ -323,7 +319,7 @@ public class RunWorkerTests
323
319
  <PackageReference Include="Some.Package;Some.Package2" Version="1.0.1" />
324
320
  </ItemGroup>
325
321
  </Project>
326
- """.SetEOL(EOL));
322
+ """);
327
323
  return new UpdateOperationResult()
328
324
  {
329
325
  UpdateOperations = [
@@ -359,7 +355,8 @@ public class RunWorkerTests
359
355
  <PackageReference Include="Some.Package;Some.Package2" Version="1.0.0" />
360
356
  </ItemGroup>
361
357
  </Project>
362
- """.SetEOL(EOL)))
358
+ """)),
359
+ ContentEncoding = "base64"
363
360
  }
364
361
  ],
365
362
  BaseCommitSha = "TEST-COMMIT-SHA",
@@ -487,7 +484,7 @@ public class RunWorkerTests
487
484
  <PackageReference Include="Some.Package;Some.Package2" Version="1.0.1" />
488
485
  </ItemGroup>
489
486
  </Project>
490
- """.SetEOL(EOL),
487
+ """,
491
488
  }
492
489
 
493
490
  ],
@@ -501,11 +498,8 @@ public class RunWorkerTests
501
498
  );
502
499
  }
503
500
 
504
- [Theory]
505
- [InlineData(EOLType.CR)]
506
- [InlineData(EOLType.LF)]
507
- [InlineData(EOLType.CRLF)]
508
- public async Task PrivateSourceAuthenticationFailureIsForwaredToApiHandler(EOLType EOL)
501
+ [Fact]
502
+ public async Task PrivateSourceAuthenticationFailureIsForwaredToApiHandler()
509
503
  {
510
504
  await RunAsync(
511
505
  packages:
@@ -529,7 +523,7 @@ public class RunWorkerTests
529
523
  <add key="private_feed" value="http://example.com/nuget/index.json" allowInsecureConnections="true" />
530
524
  </packageSources>
531
525
  </configuration>
532
- """.SetEOL(EOL)),
526
+ """),
533
527
  ("project.csproj", """
534
528
  <Project Sdk="Microsoft.NET.Sdk">
535
529
  <PropertyGroup>
@@ -539,7 +533,7 @@ public class RunWorkerTests
539
533
  <PackageReference Include="Some.Package" Version="1.0.0" />
540
534
  </ItemGroup>
541
535
  </Project>
542
- """.SetEOL(EOL))
536
+ """)
543
537
  ],
544
538
  discoveryWorker: new TestDiscoveryWorker((_input) =>
545
539
  {
@@ -560,14 +554,11 @@ public class RunWorkerTests
560
554
  );
561
555
  }
562
556
 
563
- [Theory]
564
- [InlineData(EOLType.CR)]
565
- [InlineData(EOLType.LF)]
566
- [InlineData(EOLType.CRLF)]
567
- public async Task UpdateHandlesPackagesConfigFiles(EOLType EOL)
557
+ [Fact]
558
+ public async Task UpdateHandlesPackagesConfigFiles()
568
559
  {
569
- var repoMetadata = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package" />""".SetEOL(EOL));
570
- var repoMetadata2 = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package2" />""".SetEOL(EOL));
560
+ var repoMetadata = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package" />""");
561
+ var repoMetadata2 = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package2" />""");
571
562
  await RunAsync(
572
563
  packages:
573
564
  [
@@ -597,13 +588,13 @@ public class RunWorkerTests
597
588
  <PackageReference Include="Some.Package" Version="1.0.0" />
598
589
  </ItemGroup>
599
590
  </Project>
600
- """.SetEOL(EOL)),
591
+ """),
601
592
  ("some-dir/packages.config", """
602
593
  <?xml version="1.0" encoding="utf-8"?>
603
594
  <packages>
604
595
  <package id="Some.Package2" version="2.0.0" targetFramework="net8.0" />
605
596
  </packages>
606
- """.SetEOL(EOL)),
597
+ """),
607
598
  ],
608
599
  discoveryWorker: new TestDiscoveryWorker(_input =>
609
600
  {
@@ -676,7 +667,7 @@ public class RunWorkerTests
676
667
  <PackageReference Include="Some.Package" Version="1.0.1" />
677
668
  </ItemGroup>
678
669
  </Project>
679
- """.SetEOL(EOL));
670
+ """);
680
671
  break;
681
672
  case "Some.Package2":
682
673
  await File.WriteAllTextAsync(projectPath, """
@@ -694,14 +685,14 @@ public class RunWorkerTests
694
685
  </Reference>
695
686
  </ItemGroup>
696
687
  </Project>
697
- """.SetEOL(EOL));
688
+ """);
698
689
  var packagesConfigPath = Path.Join(Path.GetDirectoryName(projectPath)!, "packages.config");
699
690
  await File.WriteAllTextAsync(packagesConfigPath, """
700
691
  <?xml version="1.0" encoding="utf-8"?>
701
692
  <packages>
702
693
  <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
703
694
  </packages>
704
- """.SetEOL(EOL));
695
+ """);
705
696
  break;
706
697
  default:
707
698
  throw new NotSupportedException();
@@ -732,7 +723,8 @@ public class RunWorkerTests
732
723
  <packages>
733
724
  <package id="Some.Package2" version="2.0.0" targetFramework="net8.0" />
734
725
  </packages>
735
- """.SetEOL(EOL)))
726
+ """)),
727
+ ContentEncoding = "base64"
736
728
  },
737
729
  new DependencyFile()
738
730
  {
@@ -747,7 +739,8 @@ public class RunWorkerTests
747
739
  <PackageReference Include="Some.Package" Version="1.0.0" />
748
740
  </ItemGroup>
749
741
  </Project>
750
- """.SetEOL(EOL)))
742
+ """)),
743
+ ContentEncoding = "base64"
751
744
  },
752
745
  ],
753
746
  BaseCommitSha = "TEST-COMMIT-SHA",
@@ -871,7 +864,7 @@ public class RunWorkerTests
871
864
  <packages>
872
865
  <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
873
866
  </packages>
874
- """.SetEOL(EOL),
867
+ """,
875
868
  },
876
869
  new DependencyFile()
877
870
  {
@@ -892,7 +885,7 @@ public class RunWorkerTests
892
885
  </Reference>
893
886
  </ItemGroup>
894
887
  </Project>
895
- """.SetEOL(EOL),
888
+ """,
896
889
  },
897
890
  ],
898
891
  BaseCommitSha = "TEST-COMMIT-SHA",
@@ -905,14 +898,11 @@ public class RunWorkerTests
905
898
  );
906
899
  }
907
900
 
908
- [Theory]
909
- [InlineData(EOLType.CR)]
910
- [InlineData(EOLType.LF)]
911
- [InlineData(EOLType.CRLF)]
912
- public async Task UpdateHandlesPackagesConfigFromReferencedCsprojFiles(EOLType EOL)
901
+ [Fact]
902
+ public async Task UpdateHandlesPackagesConfigFromReferencedCsprojFiles()
913
903
  {
914
- var repoMetadata = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package" />""".SetEOL(EOL));
915
- var repoMetadata2 = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package2" />""".SetEOL(EOL));
904
+ var repoMetadata = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package" />""");
905
+ var repoMetadata2 = XElement.Parse("""<repository type="git" url="https://nuget.example.com/some-package2" />""");
916
906
  await RunAsync(
917
907
  packages:
918
908
  [
@@ -945,13 +935,13 @@ public class RunWorkerTests
945
935
  <ProjectReference Include="../ProjectB/ProjectB.csproj" />
946
936
  </ItemGroup>
947
937
  </Project>
948
- """.SetEOL(EOL)),
938
+ """),
949
939
  ("some-dir/ProjectA/packages.config", """
950
940
  <?xml version="1.0" encoding="utf-8"?>
951
941
  <packages>
952
942
  <package id="Some.Package2" version="2.0.0" targetFramework="net8.0" />
953
943
  </packages>
954
- """.SetEOL(EOL)),
944
+ """),
955
945
  ("some-dir/ProjectB/ProjectB.csproj", """
956
946
  <Project Sdk="Microsoft.NET.Sdk">
957
947
  <PropertyGroup>
@@ -961,13 +951,13 @@ public class RunWorkerTests
961
951
  <PackageReference Include="Some.Package" Version="1.0.0" />
962
952
  </ItemGroup>
963
953
  </Project>
964
- """.SetEOL(EOL)),
954
+ """),
965
955
  ("some-dir/ProjectB/packages.config", """
966
956
  <?xml version="1.0" encoding="utf-8"?>
967
957
  <packages>
968
958
  <package id="Some.Package2" version="2.0.0" targetFramework="net8.0" />
969
959
  </packages>
970
- """.SetEOL(EOL)),
960
+ """),
971
961
  ],
972
962
  discoveryWorker: new TestDiscoveryWorker(_input =>
973
963
  {
@@ -1058,7 +1048,7 @@ public class RunWorkerTests
1058
1048
  <ProjectReference Include="../ProjectB/ProjectB.csproj" />
1059
1049
  </ItemGroup>
1060
1050
  </Project>
1061
- """.SetEOL(EOL));
1051
+ """);
1062
1052
  break;
1063
1053
  case ("ProjectA.csproj", "Some.Package2"):
1064
1054
  await File.WriteAllTextAsync(projectPath, """
@@ -1079,13 +1069,13 @@ public class RunWorkerTests
1079
1069
  </Reference>
1080
1070
  </ItemGroup>
1081
1071
  </Project>
1082
- """.SetEOL(EOL));
1072
+ """);
1083
1073
  await File.WriteAllTextAsync(packagesConfigPath, """
1084
1074
  <?xml version="1.0" encoding="utf-8"?>
1085
1075
  <packages>
1086
1076
  <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
1087
1077
  </packages>
1088
- """.SetEOL(EOL));
1078
+ """);
1089
1079
  break;
1090
1080
  case ("ProjectB.csproj", "Some.Package"):
1091
1081
  await File.WriteAllTextAsync(projectPath, """
@@ -1097,7 +1087,7 @@ public class RunWorkerTests
1097
1087
  <PackageReference Include="Some.Package" Version="1.0.1" />
1098
1088
  </ItemGroup>
1099
1089
  </Project>
1100
- """.SetEOL(EOL));
1090
+ """);
1101
1091
  break;
1102
1092
  case ("ProjectB.csproj", "Some.Package2"):
1103
1093
  await File.WriteAllTextAsync(projectPath, """
@@ -1115,13 +1105,13 @@ public class RunWorkerTests
1115
1105
  </Reference>
1116
1106
  </ItemGroup>
1117
1107
  </Project>
1118
- """.SetEOL(EOL));
1108
+ """);
1119
1109
  await File.WriteAllTextAsync(packagesConfigPath, """
1120
1110
  <?xml version="1.0" encoding="utf-8"?>
1121
1111
  <packages>
1122
1112
  <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
1123
1113
  </packages>
1124
- """.SetEOL(EOL));
1114
+ """);
1125
1115
  break;
1126
1116
  default:
1127
1117
  throw new NotSupportedException();
@@ -1152,7 +1142,8 @@ public class RunWorkerTests
1152
1142
  <packages>
1153
1143
  <package id="Some.Package2" version="2.0.0" targetFramework="net8.0" />
1154
1144
  </packages>
1155
- """.SetEOL(EOL)))
1145
+ """)),
1146
+ ContentEncoding = "base64"
1156
1147
  },
1157
1148
  new DependencyFile()
1158
1149
  {
@@ -1170,7 +1161,8 @@ public class RunWorkerTests
1170
1161
  <ProjectReference Include="../ProjectB/ProjectB.csproj" />
1171
1162
  </ItemGroup>
1172
1163
  </Project>
1173
- """.SetEOL(EOL)))
1164
+ """)),
1165
+ ContentEncoding = "base64"
1174
1166
  },
1175
1167
  new DependencyFile()
1176
1168
  {
@@ -1181,7 +1173,8 @@ public class RunWorkerTests
1181
1173
  <packages>
1182
1174
  <package id="Some.Package2" version="2.0.0" targetFramework="net8.0" />
1183
1175
  </packages>
1184
- """.SetEOL(EOL)))
1176
+ """)),
1177
+ ContentEncoding = "base64"
1185
1178
  },
1186
1179
  new DependencyFile()
1187
1180
  {
@@ -1196,7 +1189,8 @@ public class RunWorkerTests
1196
1189
  <PackageReference Include="Some.Package" Version="1.0.0" />
1197
1190
  </ItemGroup>
1198
1191
  </Project>
1199
- """.SetEOL(EOL)))
1192
+ """)),
1193
+ ContentEncoding = "base64"
1200
1194
  },
1201
1195
  ],
1202
1196
  BaseCommitSha = "TEST-COMMIT-SHA",
@@ -1406,7 +1400,7 @@ public class RunWorkerTests
1406
1400
  <packages>
1407
1401
  <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
1408
1402
  </packages>
1409
- """.SetEOL(EOL),
1403
+ """,
1410
1404
  },
1411
1405
  new DependencyFile()
1412
1406
  {
@@ -1430,7 +1424,7 @@ public class RunWorkerTests
1430
1424
  </Reference>
1431
1425
  </ItemGroup>
1432
1426
  </Project>
1433
- """.SetEOL(EOL),
1427
+ """,
1434
1428
  },
1435
1429
  new DependencyFile()
1436
1430
  {
@@ -1441,7 +1435,7 @@ public class RunWorkerTests
1441
1435
  <packages>
1442
1436
  <package id="Some.Package2" version="2.0.1" targetFramework="net8.0" />
1443
1437
  </packages>
1444
- """.SetEOL(EOL),
1438
+ """,
1445
1439
  },
1446
1440
  new DependencyFile()
1447
1441
  {
@@ -1462,7 +1456,7 @@ public class RunWorkerTests
1462
1456
  </Reference>
1463
1457
  </ItemGroup>
1464
1458
  </Project>
1465
- """.SetEOL(EOL),
1459
+ """,
1466
1460
  },
1467
1461
  ],
1468
1462
  BaseCommitSha = "TEST-COMMIT-SHA",
@@ -1475,11 +1469,8 @@ public class RunWorkerTests
1475
1469
  );
1476
1470
  }
1477
1471
 
1478
- [Theory]
1479
- [InlineData(EOLType.CR)]
1480
- [InlineData(EOLType.LF)]
1481
- [InlineData(EOLType.CRLF)]
1482
- public async Task UpdatedFilesAreOnlyReportedOnce(EOLType EOL)
1472
+ [Fact]
1473
+ public async Task UpdatedFilesAreOnlyReportedOnce()
1483
1474
  {
1484
1475
  await RunAsync(
1485
1476
  job: new()
@@ -1506,14 +1497,14 @@ public class RunWorkerTests
1506
1497
  <ProjectFile Include="project2/project2.csproj" />
1507
1498
  </ItemGroup>
1508
1499
  </Project>
1509
- """.SetEOL(EOL)),
1500
+ """),
1510
1501
  ("Directory.Build.props", """
1511
1502
  <Project>
1512
1503
  <PropertyGroup>
1513
1504
  <SomePackageVersion>1.0.0</SomePackageVersion>
1514
1505
  </PropertyGroup>
1515
1506
  </Project>
1516
- """.SetEOL(EOL)),
1507
+ """),
1517
1508
  ("project1/project1.csproj", """
1518
1509
  <Project Sdk="Microsoft.NET.Sdk">
1519
1510
  <PropertyGroup>
@@ -1523,7 +1514,7 @@ public class RunWorkerTests
1523
1514
  <PackageReference Include="Some.Package" Version="$(SomePackageVersion)" />
1524
1515
  </ItemGroup>
1525
1516
  </Project>
1526
- """.SetEOL(EOL)),
1517
+ """),
1527
1518
  ("project2/project2.csproj", """
1528
1519
  <Project Sdk="Microsoft.NET.Sdk">
1529
1520
  <PropertyGroup>
@@ -1533,7 +1524,7 @@ public class RunWorkerTests
1533
1524
  <PackageReference Include="Some.Package" Version="$(SomePackageVersion)" />
1534
1525
  </ItemGroup>
1535
1526
  </Project>
1536
- """.SetEOL(EOL))
1527
+ """)
1537
1528
  ],
1538
1529
  discoveryWorker: new TestDiscoveryWorker(_input =>
1539
1530
  {
@@ -1598,7 +1589,7 @@ public class RunWorkerTests
1598
1589
  <SomePackageVersion>1.1.0</SomePackageVersion>
1599
1590
  </PropertyGroup>
1600
1591
  </Project>
1601
- """.SetEOL(EOL));
1592
+ """);
1602
1593
  return new UpdateOperationResult()
1603
1594
  {
1604
1595
  UpdateOperations = [
@@ -1625,7 +1616,8 @@ public class RunWorkerTests
1625
1616
  <SomePackageVersion>1.0.0</SomePackageVersion>
1626
1617
  </PropertyGroup>
1627
1618
  </Project>
1628
- """.SetEOL(EOL)))
1619
+ """)),
1620
+ ContentEncoding = "base64"
1629
1621
  },
1630
1622
  new DependencyFile()
1631
1623
  {
@@ -1640,7 +1632,8 @@ public class RunWorkerTests
1640
1632
  <PackageReference Include="Some.Package" Version="$(SomePackageVersion)" />
1641
1633
  </ItemGroup>
1642
1634
  </Project>
1643
- """.SetEOL(EOL)))
1635
+ """)),
1636
+ ContentEncoding = "base64"
1644
1637
  },
1645
1638
  new DependencyFile()
1646
1639
  {
@@ -1655,7 +1648,8 @@ public class RunWorkerTests
1655
1648
  <PackageReference Include="Some.Package" Version="$(SomePackageVersion)" />
1656
1649
  </ItemGroup>
1657
1650
  </Project>
1658
- """.SetEOL(EOL)))
1651
+ """)),
1652
+ ContentEncoding = "base64"
1659
1653
  },
1660
1654
  ],
1661
1655
  BaseCommitSha = "TEST-COMMIT-SHA",
@@ -1780,7 +1774,7 @@ public class RunWorkerTests
1780
1774
  <SomePackageVersion>1.1.0</SomePackageVersion>
1781
1775
  </PropertyGroup>
1782
1776
  </Project>
1783
- """.SetEOL(EOL),
1777
+ """,
1784
1778
  }
1785
1779
  ],
1786
1780
  BaseCommitSha = "TEST-COMMIT-SHA",
@@ -1793,168 +1787,58 @@ public class RunWorkerTests
1793
1787
  );
1794
1788
  }
1795
1789
 
1796
- [Theory]
1797
- [InlineData(EOLType.CR)]
1798
- [InlineData(EOLType.LF)]
1799
- [InlineData(EOLType.CRLF)]
1800
- public async Task UpdatePackageWithDifferentVersionsInDifferentDirectories(EOLType EOL)
1790
+ [Fact]
1791
+ public async Task PackageListedInSecurityAdvisoriesSectionIsNotVulnerable()
1801
1792
  {
1802
- // this test passes `null` for discovery, analyze, and update workers to fully test the desired behavior
1803
-
1804
- // the same dependency Some.Package is reported for 3 cases:
1805
- // library1.csproj - top level dependency, already up to date
1806
- // library2.csproj - top level dependency, needs direct update
1807
- // library3.csproj - transitive dependency, needs pin
1808
1793
  await RunAsync(
1809
- experimentsManager: new ExperimentsManager() { UseDirectDiscovery = true },
1810
- packages: [
1811
- MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0"),
1812
- MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", "net8.0"),
1813
- MockNuGetPackage.CreateSimplePackage("Package.With.Transitive.Dependency", "0.1.0", "net8.0", [(null, [("Some.Package", "1.0.0")])]),
1814
- ],
1815
- job: new Job()
1794
+ job: new()
1816
1795
  {
1817
- AllowedUpdates = [new() { UpdateType = UpdateType.Security }],
1818
- SecurityAdvisories =
1819
- [
1820
- new()
1821
- {
1822
- DependencyName = "Some.Package",
1823
- AffectedVersions = [Requirement.Parse("= 1.0.0")]
1824
- }
1825
- ],
1826
1796
  Source = new()
1827
1797
  {
1828
1798
  Provider = "github",
1829
1799
  Repo = "test/repo",
1830
- Directory = "/"
1831
- }
1800
+ },
1801
+ SecurityUpdatesOnly = true,
1802
+ SecurityAdvisories = [
1803
+ new()
1804
+ {
1805
+ DependencyName = "Package.Is.Not.Vulnerable",
1806
+ AffectedVersions = [Requirement.Parse("< 1.0.0")]
1807
+ }
1808
+ ]
1832
1809
  },
1833
1810
  files: [
1834
- ("dirs.proj", """
1835
- <Project>
1836
- <ItemGroup>
1837
- <ProjectFile Include="library1\library1.csproj" />
1838
- <ProjectFile Include="library2\library2.csproj" />
1839
- <ProjectFile Include="library3\library3.csproj" />
1840
- </ItemGroup>
1841
- </Project>
1842
- """.SetEOL(EOL)),
1843
- ("Directory.Build.props", "<Project />"),
1844
- ("Directory.Build.targets", "<Project />"),
1845
- ("Directory.Packages.props", """
1846
- <Project>
1847
- <PropertyGroup>
1848
- <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
1849
- </PropertyGroup>
1850
- </Project>
1851
- """.SetEOL(EOL)),
1852
- ("library1/library1.csproj", """
1853
- <Project Sdk="Microsoft.NET.Sdk">
1854
- <PropertyGroup>
1855
- <TargetFramework>net8.0</TargetFramework>
1856
- </PropertyGroup>
1857
- <ItemGroup>
1858
- <PackageReference Include="Some.Package" Version="2.0.0" />
1859
- </ItemGroup>
1860
- </Project>
1861
- """.SetEOL(EOL)),
1862
- ("library2/library2.csproj", """
1863
- <Project Sdk="Microsoft.NET.Sdk">
1864
- <PropertyGroup>
1865
- <TargetFramework>net8.0</TargetFramework>
1866
- </PropertyGroup>
1867
- <ItemGroup>
1868
- <PackageReference Include="Some.Package" Version="1.0.0" />
1869
- </ItemGroup>
1870
- </Project>
1871
- """.SetEOL(EOL)),
1872
- ("library3/library3.csproj", """
1873
- <Project Sdk="Microsoft.NET.Sdk">
1874
- <PropertyGroup>
1875
- <TargetFramework>net8.0</TargetFramework>
1876
- </PropertyGroup>
1877
- <ItemGroup>
1878
- <PackageReference Include="Package.With.Transitive.Dependency" Version="0.1.0" />
1879
- </ItemGroup>
1880
- </Project>
1881
- """.SetEOL(EOL)),
1811
+ ("project.csproj", "contents irrelevant")
1882
1812
  ],
1883
- discoveryWorker: null,
1884
- analyzeWorker: null,
1885
- updaterWorker: null,
1886
- expectedResult: new RunResult()
1813
+ discoveryWorker: new TestDiscoveryWorker(_input =>
1887
1814
  {
1888
- Base64DependencyFiles =
1889
- [
1890
- new DependencyFile()
1891
- {
1892
- Directory = "/",
1893
- Name = "Directory.Build.props",
1894
- Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("<Project />"))
1895
- },
1896
- new DependencyFile()
1897
- {
1898
- Directory = "/",
1899
- Name = "Directory.Build.targets",
1900
- Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("<Project />"))
1901
- },
1902
- new DependencyFile()
1815
+ return Task.FromResult(new WorkspaceDiscoveryResult()
1816
+ {
1817
+ Path = "",
1818
+ Projects = [
1819
+ new()
1820
+ {
1821
+ FilePath = "project.csproj",
1822
+ Dependencies = [
1823
+ new("Package.Is.Not.Vulnerable", "1.0.1", DependencyType.PackageReference)
1824
+ ],
1825
+ ImportedFiles = [],
1826
+ AdditionalFiles = [],
1827
+ }
1828
+ ]
1829
+ });
1830
+ }),
1831
+ analyzeWorker: new TestAnalyzeWorker(_input => throw new NotImplementedException("test shouldn't get this far")),
1832
+ updaterWorker: new TestUpdaterWorker(_input => throw new NotImplementedException("test shouldn't get this far")),
1833
+ expectedResult: new()
1834
+ {
1835
+ Base64DependencyFiles = [
1836
+ new()
1903
1837
  {
1904
1838
  Directory = "/",
1905
- Name = "Directory.Packages.props",
1906
- Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("""
1907
- <Project>
1908
- <PropertyGroup>
1909
- <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
1910
- </PropertyGroup>
1911
- </Project>
1912
- """.SetEOL(EOL)))
1913
- },
1914
- new DependencyFile()
1915
- {
1916
- Directory = "/library1",
1917
- Name = "library1.csproj",
1918
- Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("""
1919
- <Project Sdk="Microsoft.NET.Sdk">
1920
- <PropertyGroup>
1921
- <TargetFramework>net8.0</TargetFramework>
1922
- </PropertyGroup>
1923
- <ItemGroup>
1924
- <PackageReference Include="Some.Package" Version="2.0.0" />
1925
- </ItemGroup>
1926
- </Project>
1927
- """.SetEOL(EOL)))
1928
- },
1929
- new DependencyFile()
1930
- {
1931
- Directory = "/library2",
1932
- Name = "library2.csproj",
1933
- Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("""
1934
- <Project Sdk="Microsoft.NET.Sdk">
1935
- <PropertyGroup>
1936
- <TargetFramework>net8.0</TargetFramework>
1937
- </PropertyGroup>
1938
- <ItemGroup>
1939
- <PackageReference Include="Some.Package" Version="1.0.0" />
1940
- </ItemGroup>
1941
- </Project>
1942
- """.SetEOL(EOL)))
1943
- },
1944
- new DependencyFile()
1945
- {
1946
- Directory = "/library3",
1947
- Name = "library3.csproj",
1948
- Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("""
1949
- <Project Sdk="Microsoft.NET.Sdk">
1950
- <PropertyGroup>
1951
- <TargetFramework>net8.0</TargetFramework>
1952
- </PropertyGroup>
1953
- <ItemGroup>
1954
- <PackageReference Include="Package.With.Transitive.Dependency" Version="0.1.0" />
1955
- </ItemGroup>
1956
- </Project>
1957
- """.SetEOL(EOL)))
1839
+ Name = "project.csproj",
1840
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("contents irrelevant")),
1841
+ ContentEncoding = "base64"
1958
1842
  }
1959
1843
  ],
1960
1844
  BaseCommitSha = "TEST-COMMIT-SHA",
@@ -1965,338 +1849,109 @@ public class RunWorkerTests
1965
1849
  Dependencies = [
1966
1850
  new()
1967
1851
  {
1968
- Name = "Some.Package",
1969
- Version = "2.0.0",
1852
+ Name = "Package.Is.Not.Vulnerable",
1853
+ Version = "1.0.1",
1970
1854
  Requirements = [
1971
1855
  new()
1972
1856
  {
1973
- Requirement = "2.0.0",
1974
- File = "/library1/library1.csproj",
1857
+ Requirement = "1.0.1",
1858
+ File = "/project.csproj",
1975
1859
  Groups = ["dependencies"],
1976
1860
  }
1977
1861
  ]
1978
- },
1862
+ }
1863
+ ],
1864
+ DependencyFiles = ["/project.csproj"]
1865
+ },
1866
+ new IncrementMetric()
1867
+ {
1868
+ Metric = "updater.started",
1869
+ Tags = new()
1870
+ {
1871
+ ["operation"] = "create_security_pr"
1872
+ }
1873
+ },
1874
+ new SecurityUpdateNotNeeded("Package.Is.Not.Vulnerable"),
1875
+ new MarkAsProcessed("TEST-COMMIT-SHA"),
1876
+ ]
1877
+ );
1878
+ }
1879
+
1880
+ [Fact]
1881
+ public async Task PackageListedInSecurityAdvisoriesSectionIsNotPresent()
1882
+ {
1883
+ await RunAsync(
1884
+ job: new()
1885
+ {
1886
+ Source = new()
1887
+ {
1888
+ Provider = "github",
1889
+ Repo = "test/repo",
1890
+ },
1891
+ SecurityUpdatesOnly = true,
1892
+ SecurityAdvisories = [
1893
+ new()
1894
+ {
1895
+ DependencyName = "Package.Is.Not.Vulnerable",
1896
+ AffectedVersions = [Requirement.Parse("< 1.0.0")]
1897
+ }
1898
+ ]
1899
+ },
1900
+ files: [
1901
+ ("project.csproj", "contents irrelevant")
1902
+ ],
1903
+ discoveryWorker: new TestDiscoveryWorker(_input =>
1904
+ {
1905
+ return Task.FromResult(new WorkspaceDiscoveryResult()
1906
+ {
1907
+ Path = "",
1908
+ Projects = [
1979
1909
  new()
1980
1910
  {
1981
- Name = "Some.Package",
1982
- Version = "1.0.0",
1983
- Requirements = [
1984
- new()
1985
- {
1986
- Requirement = "1.0.0",
1987
- File = "/library2/library2.csproj",
1988
- Groups = ["dependencies"],
1989
- }
1990
- ]
1991
- },
1911
+ FilePath = "project.csproj",
1912
+ Dependencies = [
1913
+ new("Unrelated.Package", "0.1.0", DependencyType.PackageReference)
1914
+ ],
1915
+ ImportedFiles = [],
1916
+ AdditionalFiles = [],
1917
+ }
1918
+ ]
1919
+ });
1920
+ }),
1921
+ analyzeWorker: new TestAnalyzeWorker(_input => throw new NotImplementedException("test shouldn't get this far")),
1922
+ updaterWorker: new TestUpdaterWorker(_input => throw new NotImplementedException("test shouldn't get this far")),
1923
+ expectedResult: new()
1924
+ {
1925
+ Base64DependencyFiles = [
1926
+ new()
1927
+ {
1928
+ Directory = "/",
1929
+ Name = "project.csproj",
1930
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("contents irrelevant")),
1931
+ ContentEncoding = "base64"
1932
+ }
1933
+ ],
1934
+ BaseCommitSha = "TEST-COMMIT-SHA",
1935
+ },
1936
+ expectedApiMessages: [
1937
+ new UpdatedDependencyList()
1938
+ {
1939
+ Dependencies = [
1992
1940
  new()
1993
1941
  {
1994
- Name = "Package.With.Transitive.Dependency",
1942
+ Name = "Unrelated.Package",
1995
1943
  Version = "0.1.0",
1996
1944
  Requirements = [
1997
1945
  new()
1998
1946
  {
1999
1947
  Requirement = "0.1.0",
2000
- File = "/library3/library3.csproj",
2001
- Groups = ["dependencies"],
2002
- }
2003
- ]
2004
- },
2005
- new()
2006
- {
2007
- Name = "Some.Package",
2008
- Version = "1.0.0",
2009
- Requirements = [
2010
- new()
2011
- {
2012
- Requirement = "1.0.0",
2013
- File = "/library3/library3.csproj",
1948
+ File = "/project.csproj",
2014
1949
  Groups = ["dependencies"],
2015
1950
  }
2016
1951
  ]
2017
- },
2018
- ],
2019
- DependencyFiles = [
2020
- "/Directory.Build.props",
2021
- "/Directory.Build.targets",
2022
- "/Directory.Packages.props",
2023
- "/library1/library1.csproj",
2024
- "/library2/library2.csproj",
2025
- "/library3/library3.csproj",
1952
+ }
2026
1953
  ],
2027
- },
2028
- new IncrementMetric()
2029
- {
2030
- Metric = "updater.started",
2031
- Tags = new()
2032
- {
2033
- ["operation"] = "create_security_pr"
2034
- }
2035
- },
2036
- new CreatePullRequest()
2037
- {
2038
- Dependencies = [
2039
- new()
2040
- {
2041
- Name = "Some.Package",
2042
- Version = "2.0.0",
2043
- Requirements = [
2044
- new()
2045
- {
2046
- Requirement = "2.0.0",
2047
- File = "/library2/library2.csproj",
2048
- Groups = ["dependencies"],
2049
- Source = new()
2050
- {
2051
- SourceUrl = null,
2052
- Type = "nuget_repo",
2053
- }
2054
- }
2055
- ],
2056
- PreviousVersion = "1.0.0",
2057
- PreviousRequirements = [
2058
- new()
2059
- {
2060
- Requirement = "1.0.0",
2061
- File = "/library2/library2.csproj",
2062
- Groups = ["dependencies"],
2063
- }
2064
- ],
2065
- },
2066
- new()
2067
- {
2068
- Name = "Some.Package",
2069
- Version = "2.0.0",
2070
- Requirements = [
2071
- new()
2072
- {
2073
- Requirement = "2.0.0",
2074
- File = "/library3/library3.csproj",
2075
- Groups = ["dependencies"],
2076
- Source = new()
2077
- {
2078
- SourceUrl = null,
2079
- Type = "nuget_repo",
2080
- }
2081
- }
2082
- ],
2083
- PreviousVersion = "1.0.0",
2084
- PreviousRequirements = [
2085
- new()
2086
- {
2087
- Requirement = "1.0.0",
2088
- File = "/library3/library3.csproj",
2089
- Groups = ["dependencies"],
2090
- }
2091
- ],
2092
- },
2093
- ],
2094
- UpdatedDependencyFiles = [
2095
- new()
2096
- {
2097
- Directory = "/library2",
2098
- Name = "library2.csproj",
2099
- Content = """
2100
- <Project Sdk="Microsoft.NET.Sdk">
2101
- <PropertyGroup>
2102
- <TargetFramework>net8.0</TargetFramework>
2103
- </PropertyGroup>
2104
- <ItemGroup>
2105
- <PackageReference Include="Some.Package" Version="2.0.0" />
2106
- </ItemGroup>
2107
- </Project>
2108
- """.SetEOL(EOL)
2109
- },
2110
- new()
2111
- {
2112
- Directory = "/library3",
2113
- Name = "library3.csproj",
2114
- Content = """
2115
- <Project Sdk="Microsoft.NET.Sdk">
2116
- <PropertyGroup>
2117
- <TargetFramework>net8.0</TargetFramework>
2118
- </PropertyGroup>
2119
- <ItemGroup>
2120
- <PackageReference Include="Package.With.Transitive.Dependency" Version="0.1.0" />
2121
- <PackageReference Include="Some.Package" Version="2.0.0" />
2122
- </ItemGroup>
2123
- </Project>
2124
- """.SetEOL(EOL)
2125
- }
2126
- ],
2127
- BaseCommitSha = "TEST-COMMIT-SHA",
2128
- CommitMessage = TestPullRequestCommitMessage,
2129
- PrTitle = TestPullRequestTitle,
2130
- PrBody = TestPullRequestBody
2131
- },
2132
- new MarkAsProcessed("TEST-COMMIT-SHA")
2133
- ]
2134
- );
2135
- }
2136
-
2137
- [Fact]
2138
- public async Task PackageListedInSecurityAdvisoriesSectionIsNotVulnerable()
2139
- {
2140
- await RunAsync(
2141
- job: new()
2142
- {
2143
- Source = new()
2144
- {
2145
- Provider = "github",
2146
- Repo = "test/repo",
2147
- },
2148
- SecurityUpdatesOnly = true,
2149
- SecurityAdvisories = [
2150
- new()
2151
- {
2152
- DependencyName = "Package.Is.Not.Vulnerable",
2153
- AffectedVersions = [Requirement.Parse("< 1.0.0")]
2154
- }
2155
- ]
2156
- },
2157
- files: [
2158
- ("project.csproj", "contents irrelevant")
2159
- ],
2160
- discoveryWorker: new TestDiscoveryWorker(_input =>
2161
- {
2162
- return Task.FromResult(new WorkspaceDiscoveryResult()
2163
- {
2164
- Path = "",
2165
- Projects = [
2166
- new()
2167
- {
2168
- FilePath = "project.csproj",
2169
- Dependencies = [
2170
- new("Package.Is.Not.Vulnerable", "1.0.1", DependencyType.PackageReference)
2171
- ],
2172
- ImportedFiles = [],
2173
- AdditionalFiles = [],
2174
- }
2175
- ]
2176
- });
2177
- }),
2178
- analyzeWorker: new TestAnalyzeWorker(_input => throw new NotImplementedException("test shouldn't get this far")),
2179
- updaterWorker: new TestUpdaterWorker(_input => throw new NotImplementedException("test shouldn't get this far")),
2180
- expectedResult: new()
2181
- {
2182
- Base64DependencyFiles = [
2183
- new()
2184
- {
2185
- Directory = "/",
2186
- Name = "project.csproj",
2187
- Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("contents irrelevant"))
2188
- }
2189
- ],
2190
- BaseCommitSha = "TEST-COMMIT-SHA",
2191
- },
2192
- expectedApiMessages: [
2193
- new UpdatedDependencyList()
2194
- {
2195
- Dependencies = [
2196
- new()
2197
- {
2198
- Name = "Package.Is.Not.Vulnerable",
2199
- Version = "1.0.1",
2200
- Requirements = [
2201
- new()
2202
- {
2203
- Requirement = "1.0.1",
2204
- File = "/project.csproj",
2205
- Groups = ["dependencies"],
2206
- }
2207
- ]
2208
- }
2209
- ],
2210
- DependencyFiles = ["/project.csproj"]
2211
- },
2212
- new IncrementMetric()
2213
- {
2214
- Metric = "updater.started",
2215
- Tags = new()
2216
- {
2217
- ["operation"] = "create_security_pr"
2218
- }
2219
- },
2220
- new SecurityUpdateNotNeeded("Package.Is.Not.Vulnerable"),
2221
- new MarkAsProcessed("TEST-COMMIT-SHA"),
2222
- ]
2223
- );
2224
- }
2225
-
2226
- [Fact]
2227
- public async Task PackageListedInSecurityAdvisoriesSectionIsNotPresent()
2228
- {
2229
- await RunAsync(
2230
- job: new()
2231
- {
2232
- Source = new()
2233
- {
2234
- Provider = "github",
2235
- Repo = "test/repo",
2236
- },
2237
- SecurityUpdatesOnly = true,
2238
- SecurityAdvisories = [
2239
- new()
2240
- {
2241
- DependencyName = "Package.Is.Not.Vulnerable",
2242
- AffectedVersions = [Requirement.Parse("< 1.0.0")]
2243
- }
2244
- ]
2245
- },
2246
- files: [
2247
- ("project.csproj", "contents irrelevant")
2248
- ],
2249
- discoveryWorker: new TestDiscoveryWorker(_input =>
2250
- {
2251
- return Task.FromResult(new WorkspaceDiscoveryResult()
2252
- {
2253
- Path = "",
2254
- Projects = [
2255
- new()
2256
- {
2257
- FilePath = "project.csproj",
2258
- Dependencies = [
2259
- new("Unrelated.Package", "0.1.0", DependencyType.PackageReference)
2260
- ],
2261
- ImportedFiles = [],
2262
- AdditionalFiles = [],
2263
- }
2264
- ]
2265
- });
2266
- }),
2267
- analyzeWorker: new TestAnalyzeWorker(_input => throw new NotImplementedException("test shouldn't get this far")),
2268
- updaterWorker: new TestUpdaterWorker(_input => throw new NotImplementedException("test shouldn't get this far")),
2269
- expectedResult: new()
2270
- {
2271
- Base64DependencyFiles = [
2272
- new()
2273
- {
2274
- Directory = "/",
2275
- Name = "project.csproj",
2276
- Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("contents irrelevant"))
2277
- }
2278
- ],
2279
- BaseCommitSha = "TEST-COMMIT-SHA",
2280
- },
2281
- expectedApiMessages: [
2282
- new UpdatedDependencyList()
2283
- {
2284
- Dependencies = [
2285
- new()
2286
- {
2287
- Name = "Unrelated.Package",
2288
- Version = "0.1.0",
2289
- Requirements = [
2290
- new()
2291
- {
2292
- Requirement = "0.1.0",
2293
- File = "/project.csproj",
2294
- Groups = ["dependencies"],
2295
- }
2296
- ]
2297
- }
2298
- ],
2299
- DependencyFiles = ["/project.csproj"]
1954
+ DependencyFiles = ["/project.csproj"]
2300
1955
  },
2301
1956
  new IncrementMetric()
2302
1957
  {
@@ -2391,13 +2046,15 @@ public class RunWorkerTests
2391
2046
  {
2392
2047
  Directory = "/.config",
2393
2048
  Name = "dotnet-tools.json",
2394
- Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("dotnet-tools.json content old"))
2049
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("dotnet-tools.json content old")),
2050
+ ContentEncoding = "base64"
2395
2051
  },
2396
2052
  new()
2397
2053
  {
2398
2054
  Directory = "/",
2399
2055
  Name = "global.json",
2400
- Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("global.json content old"))
2056
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("global.json content old")),
2057
+ ContentEncoding = "base64"
2401
2058
  },
2402
2059
  ],
2403
2060
  BaseCommitSha = "TEST-COMMIT-SHA",
@@ -2598,7 +2255,8 @@ public class RunWorkerTests
2598
2255
  {
2599
2256
  Directory = "/",
2600
2257
  Name = "project.csproj",
2601
- Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("contents irrelevant"))
2258
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("contents irrelevant")),
2259
+ ContentEncoding = "base64"
2602
2260
  }
2603
2261
  ],
2604
2262
  BaseCommitSha = "TEST-COMMIT-SHA",
@@ -2637,18 +2295,513 @@ public class RunWorkerTests
2637
2295
  );
2638
2296
  }
2639
2297
 
2640
- private static async Task RunAsync(Job job, TestFile[] files, IDiscoveryWorker? discoveryWorker, IAnalyzeWorker? analyzeWorker, IUpdaterWorker? updaterWorker, RunResult expectedResult, object[] expectedApiMessages, MockNuGetPackage[]? packages = null, ExperimentsManager? experimentsManager = null, string? repoContentsPath = null)
2298
+ [Fact]
2299
+ public async Task ByteOrderMarksAreDetectedAndRestored()
2300
+ {
2301
+ var rawBOM = Encoding.UTF8.GetPreamble();
2302
+
2303
+ // file1 goes from BOM to no BOM
2304
+ var file1ContentOriginal = rawBOM.Concat(Encoding.ASCII.GetBytes("content1")).ToArray();
2305
+ var file1ContentUpdated = Encoding.ASCII.GetBytes("updated1");
2306
+
2307
+ // file2 goes from no BOM to BOM
2308
+ var file2ContentOriginal = Encoding.ASCII.GetBytes("content2");
2309
+ var file2ContentUpdated = rawBOM.Concat(Encoding.ASCII.GetBytes("updated2")).ToArray();
2310
+
2311
+ await RunAsync(
2312
+ job: new Job()
2313
+ {
2314
+ Source = new()
2315
+ {
2316
+ Provider = "github",
2317
+ Repo = "test/repo",
2318
+ Directory = "/",
2319
+ }
2320
+ },
2321
+ rawFiles:
2322
+ [
2323
+ ("file1", file1ContentOriginal),
2324
+ ("file2", file2ContentOriginal)
2325
+ ],
2326
+ discoveryWorker: TestDiscoveryWorker.FromResults(("/", new()
2327
+ {
2328
+ Path = "/",
2329
+ Projects = [
2330
+ new()
2331
+ {
2332
+ FilePath = "file1",
2333
+ Dependencies = [new("Dependency1", "1.0.0", DependencyType.PackageReference)],
2334
+ ImportedFiles = [],
2335
+ AdditionalFiles = [],
2336
+ },
2337
+ new()
2338
+ {
2339
+ FilePath = "file2",
2340
+ Dependencies = [new("Dependency2", "2.0.0", DependencyType.PackageReference)],
2341
+ ImportedFiles = [],
2342
+ AdditionalFiles = [],
2343
+ }
2344
+ ]
2345
+ })),
2346
+ analyzeWorker: new TestAnalyzeWorker(args =>
2347
+ {
2348
+ AnalysisResult result = args.Item3.Name switch
2349
+ {
2350
+ "Dependency1" => new()
2351
+ {
2352
+ CanUpdate = true,
2353
+ UpdatedVersion = "1.0.1",
2354
+ UpdatedDependencies = [new("Dependency1", "1.0.1", DependencyType.PackageReference)],
2355
+ },
2356
+ "Dependency2" => new()
2357
+ {
2358
+ CanUpdate = true,
2359
+ UpdatedVersion = "2.0.1",
2360
+ UpdatedDependencies = [new("Dependency2", "2.0.1", DependencyType.PackageReference)],
2361
+ },
2362
+ _ => throw new NotImplementedException()
2363
+ };
2364
+ return Task.FromResult(result);
2365
+ }),
2366
+ updaterWorker: new TestUpdaterWorker(async args =>
2367
+ {
2368
+ var (repoRoot, filePath, dependencyName, _previousVersion, _newVersion, _isTransitive) = args;
2369
+
2370
+ // file1 is rewritten without BOM, file2 is rewritten with BOM
2371
+ var (updatedFileContent, newVersion) = dependencyName switch
2372
+ {
2373
+ "Dependency1" => (file1ContentUpdated, "1.0.1"),
2374
+ "Dependency2" => (file2ContentUpdated, "2.0.1"),
2375
+ _ => throw new NotImplementedException(),
2376
+ };
2377
+ var fullFilePath = Path.Join(repoRoot, filePath);
2378
+ await File.WriteAllBytesAsync(fullFilePath, updatedFileContent);
2379
+ return new UpdateOperationResult()
2380
+ {
2381
+ UpdateOperations = [new DirectUpdate()
2382
+ {
2383
+ DependencyName = dependencyName,
2384
+ NewVersion = NuGetVersion.Parse(newVersion),
2385
+ UpdatedFiles = [filePath],
2386
+ }],
2387
+ };
2388
+ }),
2389
+ expectedResult: new()
2390
+ {
2391
+ Base64DependencyFiles = [
2392
+ new()
2393
+ {
2394
+ Directory = "/",
2395
+ Name = "file1",
2396
+ Content = Convert.ToBase64String(file1ContentOriginal),
2397
+ ContentEncoding = "base64",
2398
+ },
2399
+ new()
2400
+ {
2401
+ Directory = "/",
2402
+ Name = "file2",
2403
+ Content = Convert.ToBase64String(file2ContentOriginal),
2404
+ ContentEncoding = "base64",
2405
+ }
2406
+ ],
2407
+ BaseCommitSha = "TEST-COMMIT-SHA",
2408
+ },
2409
+ expectedApiMessages: [
2410
+ new UpdatedDependencyList()
2411
+ {
2412
+ Dependencies = [
2413
+ new()
2414
+ {
2415
+ Name = "Dependency1",
2416
+ Version = "1.0.0",
2417
+ Requirements = [
2418
+ new()
2419
+ {
2420
+ Requirement = "1.0.0",
2421
+ File = "/file1",
2422
+ Groups = ["dependencies"],
2423
+ }
2424
+ ]
2425
+ },
2426
+ new()
2427
+ {
2428
+ Name = "Dependency2",
2429
+ Version = "2.0.0",
2430
+ Requirements = [
2431
+ new()
2432
+ {
2433
+ Requirement = "2.0.0",
2434
+ File = "/file2",
2435
+ Groups = ["dependencies"]
2436
+ }
2437
+ ]
2438
+ }
2439
+ ],
2440
+ DependencyFiles = ["/file1", "/file2"]
2441
+ },
2442
+ new IncrementMetric()
2443
+ {
2444
+ Metric = "updater.started",
2445
+ Tags = new()
2446
+ {
2447
+ ["operation"] = "group_update_all_versions"
2448
+ }
2449
+ },
2450
+ new CreatePullRequest()
2451
+ {
2452
+ Dependencies =
2453
+ [
2454
+ new ReportedDependency()
2455
+ {
2456
+ Name = "Dependency1",
2457
+ Version = "1.0.1",
2458
+ Requirements =
2459
+ [
2460
+ new ReportedRequirement()
2461
+ {
2462
+ Requirement = "1.0.1",
2463
+ File = "/file1",
2464
+ Groups = ["dependencies"],
2465
+ Source = new() { SourceUrl = null },
2466
+ }
2467
+ ],
2468
+ PreviousVersion = "1.0.0",
2469
+ PreviousRequirements =
2470
+ [
2471
+ new ReportedRequirement()
2472
+ {
2473
+ Requirement = "1.0.0",
2474
+ File = "/file1",
2475
+ Groups = ["dependencies"],
2476
+ }
2477
+ ],
2478
+ },
2479
+ new ReportedDependency()
2480
+ {
2481
+ Name = "Dependency2",
2482
+ Version = "2.0.1",
2483
+ Requirements =
2484
+ [
2485
+ new ReportedRequirement()
2486
+ {
2487
+ Requirement = "2.0.1",
2488
+ File = "/file2",
2489
+ Groups = ["dependencies"],
2490
+ Source = new() { SourceUrl = null },
2491
+ }
2492
+ ],
2493
+ PreviousVersion = "2.0.0",
2494
+ PreviousRequirements =
2495
+ [
2496
+ new ReportedRequirement()
2497
+ {
2498
+ Requirement = "2.0.0",
2499
+ File = "/file2",
2500
+ Groups = ["dependencies"],
2501
+ }
2502
+ ],
2503
+ },
2504
+ ],
2505
+ UpdatedDependencyFiles =
2506
+ [
2507
+ // original line endings have been restored
2508
+ new DependencyFile()
2509
+ {
2510
+ Name = "file1",
2511
+ Directory = "/",
2512
+ Content = Convert.ToBase64String(rawBOM.Concat(file1ContentUpdated).ToArray()),
2513
+ ContentEncoding = "base64",
2514
+ },
2515
+ new DependencyFile()
2516
+ {
2517
+ Name = "file2",
2518
+ Directory = "/",
2519
+ Content = "updated2",
2520
+ },
2521
+ ],
2522
+ BaseCommitSha = "TEST-COMMIT-SHA",
2523
+ CommitMessage = TestPullRequestCommitMessage,
2524
+ PrTitle = TestPullRequestTitle,
2525
+ PrBody = TestPullRequestBody,
2526
+ },
2527
+ new MarkAsProcessed("TEST-COMMIT-SHA"),
2528
+ ]
2529
+ );
2530
+ }
2531
+
2532
+ [Fact]
2533
+ public async Task LineEndingsAreDetectedAndRestored()
2534
+ {
2535
+ await RunAsync(
2536
+ job: new Job()
2537
+ {
2538
+ Source = new()
2539
+ {
2540
+ Provider = "github",
2541
+ Repo = "test/repo",
2542
+ Directory = "/",
2543
+ }
2544
+ },
2545
+ files:
2546
+ [
2547
+ // initially LF
2548
+ ("file1", string.Concat(
2549
+ "file1-line1\n",
2550
+ "file1-line2\n",
2551
+ "file1-line3\n"
2552
+ )
2553
+ ),
2554
+ // initially CRLF
2555
+ ("file2", string.Concat(
2556
+ "file2-line1\r\n",
2557
+ "file2-line2\r\n",
2558
+ "file2-line3\r\n"
2559
+ )
2560
+ )
2561
+ ],
2562
+ discoveryWorker: TestDiscoveryWorker.FromResults(("/", new()
2563
+ {
2564
+ Path = "/",
2565
+ Projects = [
2566
+ new()
2567
+ {
2568
+ FilePath = "file1",
2569
+ Dependencies = [new("Dependency1", "1.0.0", DependencyType.PackageReference)],
2570
+ ImportedFiles = [],
2571
+ AdditionalFiles = [],
2572
+ },
2573
+ new()
2574
+ {
2575
+ FilePath = "file2",
2576
+ Dependencies = [new("Dependency2", "2.0.0", DependencyType.PackageReference)],
2577
+ ImportedFiles = [],
2578
+ AdditionalFiles = [],
2579
+ }
2580
+ ]
2581
+ })),
2582
+ analyzeWorker: new TestAnalyzeWorker(args =>
2583
+ {
2584
+ AnalysisResult result = args.Item3.Name switch
2585
+ {
2586
+ "Dependency1" => new()
2587
+ {
2588
+ CanUpdate = true,
2589
+ UpdatedVersion = "1.0.1",
2590
+ UpdatedDependencies = [new("Dependency1", "1.0.1", DependencyType.PackageReference)],
2591
+ },
2592
+ "Dependency2" => new()
2593
+ {
2594
+ CanUpdate = true,
2595
+ UpdatedVersion = "2.0.1",
2596
+ UpdatedDependencies = [new("Dependency2", "2.0.1", DependencyType.PackageReference)],
2597
+ },
2598
+ _ => throw new NotImplementedException()
2599
+ };
2600
+ return Task.FromResult(result);
2601
+ }),
2602
+ updaterWorker: new TestUpdaterWorker(async args =>
2603
+ {
2604
+ var (repoRoot, filePath, dependencyName, _previousVersion, _newVersion, _isTransitive) = args;
2605
+
2606
+ // file is explicitly updated with CR
2607
+ var (updatedFileContent, newVersion) = dependencyName switch
2608
+ {
2609
+ "Dependency1" => (string.Concat(
2610
+ "file1-line1-updated\r",
2611
+ "file1-line2-updated\r",
2612
+ "file1-line3-updated\r"), "1.0.1"),
2613
+ "Dependency2" => (string.Concat(
2614
+ "file2-line1-updated\r",
2615
+ "file2-line2-updated\r",
2616
+ "file2-line3-updated\r"), "2.0.1"),
2617
+ _ => throw new NotImplementedException(),
2618
+ };
2619
+ var fullFilePath = Path.Join(repoRoot, filePath);
2620
+ await File.WriteAllTextAsync(fullFilePath, updatedFileContent);
2621
+ return new UpdateOperationResult()
2622
+ {
2623
+ UpdateOperations = [new DirectUpdate()
2624
+ {
2625
+ DependencyName = dependencyName,
2626
+ NewVersion = NuGetVersion.Parse(newVersion),
2627
+ UpdatedFiles = [filePath],
2628
+ }],
2629
+ };
2630
+ }),
2631
+ expectedResult: new()
2632
+ {
2633
+ Base64DependencyFiles = [
2634
+ new()
2635
+ {
2636
+ Directory = "/",
2637
+ Name = "file1",
2638
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Concat(
2639
+ "file1-line1\n",
2640
+ "file1-line2\n",
2641
+ "file1-line3\n"))),
2642
+ ContentEncoding = "base64",
2643
+ },
2644
+ new()
2645
+ {
2646
+ Directory = "/",
2647
+ Name = "file2",
2648
+ Content = Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Concat(
2649
+ "file2-line1\r\n",
2650
+ "file2-line2\r\n",
2651
+ "file2-line3\r\n"))),
2652
+ ContentEncoding = "base64",
2653
+ }
2654
+ ],
2655
+ BaseCommitSha = "TEST-COMMIT-SHA",
2656
+ },
2657
+ expectedApiMessages: [
2658
+ new UpdatedDependencyList()
2659
+ {
2660
+ Dependencies = [
2661
+ new()
2662
+ {
2663
+ Name = "Dependency1",
2664
+ Version = "1.0.0",
2665
+ Requirements = [
2666
+ new()
2667
+ {
2668
+ Requirement = "1.0.0",
2669
+ File = "/file1",
2670
+ Groups = ["dependencies"],
2671
+ }
2672
+ ]
2673
+ },
2674
+ new()
2675
+ {
2676
+ Name = "Dependency2",
2677
+ Version = "2.0.0",
2678
+ Requirements = [
2679
+ new()
2680
+ {
2681
+ Requirement = "2.0.0",
2682
+ File = "/file2",
2683
+ Groups = ["dependencies"]
2684
+ }
2685
+ ]
2686
+ }
2687
+ ],
2688
+ DependencyFiles = ["/file1", "/file2"]
2689
+ },
2690
+ new IncrementMetric()
2691
+ {
2692
+ Metric = "updater.started",
2693
+ Tags = new()
2694
+ {
2695
+ ["operation"] = "group_update_all_versions"
2696
+ }
2697
+ },
2698
+ new CreatePullRequest()
2699
+ {
2700
+ Dependencies =
2701
+ [
2702
+ new ReportedDependency()
2703
+ {
2704
+ Name = "Dependency1",
2705
+ Version = "1.0.1",
2706
+ Requirements =
2707
+ [
2708
+ new ReportedRequirement()
2709
+ {
2710
+ Requirement = "1.0.1",
2711
+ File = "/file1",
2712
+ Groups = ["dependencies"],
2713
+ Source = new() { SourceUrl = null },
2714
+ }
2715
+ ],
2716
+ PreviousVersion = "1.0.0",
2717
+ PreviousRequirements =
2718
+ [
2719
+ new ReportedRequirement()
2720
+ {
2721
+ Requirement = "1.0.0",
2722
+ File = "/file1",
2723
+ Groups = ["dependencies"],
2724
+ }
2725
+ ],
2726
+ },
2727
+ new ReportedDependency()
2728
+ {
2729
+ Name = "Dependency2",
2730
+ Version = "2.0.1",
2731
+ Requirements =
2732
+ [
2733
+ new ReportedRequirement()
2734
+ {
2735
+ Requirement = "2.0.1",
2736
+ File = "/file2",
2737
+ Groups = ["dependencies"],
2738
+ Source = new() { SourceUrl = null },
2739
+ }
2740
+ ],
2741
+ PreviousVersion = "2.0.0",
2742
+ PreviousRequirements =
2743
+ [
2744
+ new ReportedRequirement()
2745
+ {
2746
+ Requirement = "2.0.0",
2747
+ File = "/file2",
2748
+ Groups = ["dependencies"],
2749
+ }
2750
+ ],
2751
+ },
2752
+ ],
2753
+ UpdatedDependencyFiles =
2754
+ [
2755
+ // original line endings have been restored
2756
+ new DependencyFile()
2757
+ {
2758
+ Name = "file1",
2759
+ Directory = "/",
2760
+ Content = string.Concat(
2761
+ "file1-line1-updated\n",
2762
+ "file1-line2-updated\n",
2763
+ "file1-line3-updated\n"
2764
+ ),
2765
+ },
2766
+ new DependencyFile()
2767
+ {
2768
+ Name = "file2",
2769
+ Directory = "/",
2770
+ Content = string.Concat(
2771
+ "file2-line1-updated\r\n",
2772
+ "file2-line2-updated\r\n",
2773
+ "file2-line3-updated\r\n"
2774
+ ),
2775
+ },
2776
+ ],
2777
+ BaseCommitSha = "TEST-COMMIT-SHA",
2778
+ CommitMessage = TestPullRequestCommitMessage,
2779
+ PrTitle = TestPullRequestTitle,
2780
+ PrBody = TestPullRequestBody,
2781
+ },
2782
+ new MarkAsProcessed("TEST-COMMIT-SHA"),
2783
+ ]
2784
+ );
2785
+ }
2786
+
2787
+ internal static Task RunAsync(Job job, TestFile[] files, IDiscoveryWorker? discoveryWorker, IAnalyzeWorker? analyzeWorker, IUpdaterWorker? updaterWorker, RunResult expectedResult, object[] expectedApiMessages, MockNuGetPackage[]? packages = null, ExperimentsManager? experimentsManager = null, string? repoContentsPath = null)
2788
+ {
2789
+ var rawTestFiles = files.Select(f => (f.Path, Encoding.UTF8.GetBytes(f.Content))).ToArray();
2790
+ return RunAsync(job, rawTestFiles, discoveryWorker, analyzeWorker, updaterWorker, expectedResult, expectedApiMessages, packages, experimentsManager, repoContentsPath);
2791
+ }
2792
+
2793
+ private static async Task RunAsync(Job job, RawTestFile[] rawFiles, IDiscoveryWorker? discoveryWorker, IAnalyzeWorker? analyzeWorker, IUpdaterWorker? updaterWorker, RunResult expectedResult, object[] expectedApiMessages, MockNuGetPackage[]? packages = null, ExperimentsManager? experimentsManager = null, string? repoContentsPath = null)
2641
2794
  {
2642
2795
  // arrange
2643
2796
  using var tempDirectory = new TemporaryDirectory();
2644
2797
  repoContentsPath ??= tempDirectory.DirectoryPath;
2645
2798
  await UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, repoContentsPath);
2646
- foreach (var (path, content) in files)
2799
+ foreach (var (path, content) in rawFiles)
2647
2800
  {
2648
2801
  var fullPath = Path.Combine(repoContentsPath, path);
2649
2802
  var directory = Path.GetDirectoryName(fullPath)!;
2650
2803
  Directory.CreateDirectory(directory);
2651
- await File.WriteAllTextAsync(fullPath, content);
2804
+ await File.WriteAllBytesAsync(fullPath, content);
2652
2805
  }
2653
2806
 
2654
2807
  // act