604 строки
23 KiB
C#
604 строки
23 KiB
C#
namespace Microsoft.ComponentDetection.Detectors.Tests;
|
|
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using FluentAssertions;
|
|
using Microsoft.ComponentDetection.Common.DependencyGraph;
|
|
using Microsoft.ComponentDetection.Contracts;
|
|
using Microsoft.ComponentDetection.Contracts.TypedComponent;
|
|
using Microsoft.ComponentDetection.Detectors.Pnpm;
|
|
using Microsoft.ComponentDetection.Detectors.Tests.Utilities;
|
|
using Microsoft.ComponentDetection.TestsUtilities;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using Moq;
|
|
|
|
[TestClass]
|
|
[TestCategory("Governance/All")]
|
|
[TestCategory("Governance/ComponentDetection")]
|
|
public class PnpmDetectorTests : BaseDetectorTest<PnpmComponentDetectorFactory>
|
|
{
|
|
public PnpmDetectorTests()
|
|
{
|
|
var componentRecorder = new ComponentRecorder(enableManualTrackingOfExplicitReferences: false);
|
|
this.DetectorTestUtility.WithScanRequest(
|
|
new ScanRequest(
|
|
new DirectoryInfo(Path.GetTempPath()),
|
|
null,
|
|
null,
|
|
new Dictionary<string, string>(),
|
|
null,
|
|
componentRecorder));
|
|
this.DetectorTestUtility.AddServiceMock(new Mock<ILogger<FileComponentDetector>>());
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_SingleFileLocatesExpectedInputAsync()
|
|
{
|
|
var yamlFile = @"
|
|
dependencies:
|
|
'query-string': 4.3.4,
|
|
'@babel/helper-compilation-targets': 7.10.4_@babel+core@7.10.5
|
|
|
|
packages:
|
|
/query-string-🙌/4.3.4:
|
|
dependencies:
|
|
object-assign: 4.1.1
|
|
strict-uri-encode: 1.1.0
|
|
test: 1.0.0
|
|
dev: true
|
|
engines:
|
|
node: '>=0.10.0'
|
|
resolution:
|
|
integrity: sha1-u7aTucqRXCMlFbIosaArYJBD2+s=
|
|
/object-assign/4.1.1:
|
|
dev: true
|
|
engines:
|
|
node: '>=0.10.0'
|
|
resolution:
|
|
integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
|
/strict-uri-encode/1.1.0:
|
|
engines:
|
|
node: '>=0.10.0'
|
|
resolution:
|
|
integrity: sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
|
|
/test/1.0.0:
|
|
dev: true
|
|
engines:
|
|
node: '>=0.10.0'
|
|
resolution:
|
|
integrity: sha1-A5siXfHVgrH1TmWt3UNS4Y+qBxM=
|
|
/@babel/helper-compilation-targets/7.10.4_@babel+core@7.10.5:
|
|
dev: false
|
|
registry: 'https://test/registry'
|
|
shrinkwrapMinorVersion: 7
|
|
shrinkwrapVersion: 3";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("shrinkwrap1.yaml", yamlFile)
|
|
.ExecuteDetectorAsync();
|
|
|
|
scanResult.ResultCode.Should().Be(ProcessingResultCode.Success);
|
|
|
|
var detectedComponents = componentRecorder.GetDetectedComponents();
|
|
detectedComponents.Should().HaveCount(5);
|
|
|
|
var queryString = detectedComponents.Single(component => ((NpmComponent)component.Component).Name.Contains("query-string"));
|
|
componentRecorder.AssertAllExplicitlyReferencedComponents<NpmComponent>(
|
|
queryString.Component.Id,
|
|
parentComponent => parentComponent.Name == "query-string-🙌");
|
|
|
|
((NpmComponent)queryString.Component).Version.Should().Be("4.3.4");
|
|
componentRecorder.GetEffectiveDevDependencyValue(queryString.Component.Id).GetValueOrDefault(false).Should().BeTrue();
|
|
|
|
var objectAssign = detectedComponents.Single(component => ((NpmComponent)component.Component).Name.Contains("object-assign"));
|
|
componentRecorder.AssertAllExplicitlyReferencedComponents<NpmComponent>(
|
|
objectAssign.Component.Id,
|
|
parentComponent => parentComponent.Name == "query-string-🙌" && parentComponent.Version == "4.3.4");
|
|
((NpmComponent)objectAssign.Component).Version.Should().Be("4.1.1");
|
|
componentRecorder.GetEffectiveDevDependencyValue(objectAssign.Component.Id).GetValueOrDefault(false).Should().BeTrue();
|
|
|
|
var strictUriEncode = detectedComponents.Single(component => ((NpmComponent)component.Component).Name.Contains("strict-uri-encode"));
|
|
componentRecorder.AssertAllExplicitlyReferencedComponents<NpmComponent>(
|
|
strictUriEncode.Component.Id,
|
|
parentComponent => parentComponent.Name == "query-string-🙌" && parentComponent.Version == "4.3.4");
|
|
((NpmComponent)strictUriEncode.Component).Version.Should().Be("1.1.0");
|
|
componentRecorder.GetEffectiveDevDependencyValue(strictUriEncode.Component.Id).GetValueOrDefault(true).Should().BeFalse();
|
|
|
|
var babelHelperCompilation = detectedComponents.Single(component => ((NpmComponent)component.Component).Name.Contains("helper-compilation-targets"));
|
|
componentRecorder.AssertAllExplicitlyReferencedComponents<NpmComponent>(
|
|
babelHelperCompilation.Component.Id,
|
|
parentComponent => parentComponent.Name == "@babel/helper-compilation-targets" && parentComponent.Version == "7.10.4");
|
|
componentRecorder.GetEffectiveDevDependencyValue(babelHelperCompilation.Component.Id).GetValueOrDefault(true).Should().BeFalse();
|
|
|
|
var test = detectedComponents.Single(component => ((NpmComponent)component.Component).Name.Contains("test"));
|
|
componentRecorder.AssertAllExplicitlyReferencedComponents<NpmComponent>(
|
|
test.Component.Id,
|
|
parentComponent => parentComponent.Name == "query-string-🙌" && parentComponent.Version == "4.3.4");
|
|
componentRecorder.GetEffectiveDevDependencyValue(test.Component.Id).GetValueOrDefault(false).Should().BeTrue();
|
|
|
|
componentRecorder.ForAllComponents(grouping => grouping.AllFileLocations.First().Should().Contain("shrinkwrap1.yaml"));
|
|
|
|
foreach (var component in detectedComponents)
|
|
{
|
|
ComponentType.Npm.Should().Be(component.Component.Type);
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_SameComponentMergesRootsAndLocationsAcrossMultipleFilesAsync()
|
|
{
|
|
var yamlFile1 = @"
|
|
dependencies:
|
|
'query-string': 4.3.4
|
|
packages:
|
|
/query-string/4.3.4:
|
|
dependencies:
|
|
strict-uri-encode: 1.1.0
|
|
dev: false
|
|
engines:
|
|
node: '>=0.10.0'
|
|
resolution:
|
|
integrity: sha1-u7aTucqRXCMlFbIosaArYJBD2+s=
|
|
/strict-uri-encode/1.1.0:
|
|
dev: false
|
|
engines:
|
|
node: '>=0.10.0'
|
|
resolution:
|
|
integrity: sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
|
|
registry: 'https://test/registry'
|
|
shrinkwrapMinorVersion: 7
|
|
shrinkwrapVersion: 3";
|
|
|
|
var yamlFile2 = @"
|
|
dependencies:
|
|
'some-other-root': 1.2.3
|
|
packages:
|
|
/some-other-root/1.2.3:
|
|
dependencies:
|
|
strict-uri-encode: 1.1.0
|
|
dev: false
|
|
engines:
|
|
node: '>=0.10.0'
|
|
resolution:
|
|
integrity: sha1-u7aTucqRXCMlFbIosaArYJBD2+s=
|
|
/strict-uri-encode/1.1.0:
|
|
dev: false
|
|
engines:
|
|
node: '>=0.10.0'
|
|
resolution:
|
|
integrity: sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
|
|
registry: 'https://test/registry'
|
|
shrinkwrapMinorVersion: 7
|
|
shrinkwrapVersion: 3";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("shrinkwrap1.yaml", yamlFile1)
|
|
.WithFile("shrinkwrap2.yaml", yamlFile2)
|
|
.ExecuteDetectorAsync();
|
|
|
|
scanResult.ResultCode.Should().Be(ProcessingResultCode.Success);
|
|
|
|
var detectedComponents = componentRecorder.GetDetectedComponents();
|
|
detectedComponents.Should().HaveCount(3);
|
|
var strictUriEncodeComponent = detectedComponents.Select(x => new { Component = x.Component as NpmComponent, DetectedComponent = x }).FirstOrDefault(x => x.Component.Name.Contains("strict-uri-encode"));
|
|
|
|
strictUriEncodeComponent.Should().NotBeNull();
|
|
|
|
componentRecorder.AssertAllExplicitlyReferencedComponents<NpmComponent>(
|
|
strictUriEncodeComponent.Component.Id,
|
|
parentComponent => parentComponent.Name == "some-other-root",
|
|
parentComponent => parentComponent.Name == "query-string");
|
|
|
|
componentRecorder.ForOneComponent(strictUriEncodeComponent.Component.Id, grouping => grouping.AllFileLocations.Should().HaveCount(2));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_SpecialDependencyVersionStringDoesntBlowUsUpAsync()
|
|
{
|
|
var yamlFile1 = @"
|
|
dependencies:
|
|
'query-string': 4.3.4
|
|
packages:
|
|
/query-string/4.3.4:
|
|
dependencies:
|
|
'@ms/items-view': /@ms/items-view/0.128.9/react-dom@15.6.2+react@15.6.2
|
|
dev: false
|
|
engines:
|
|
node: '>=0.10.0'
|
|
resolution:
|
|
integrity: sha1-u7aTucqRXCMlFbIosaArYJBD2+s=
|
|
/@ms/items-view/0.128.9/react-dom@15.6.2+react@15.6.2:
|
|
dev: false
|
|
engines:
|
|
node: '>=0.10.0'
|
|
resolution:
|
|
integrity: sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
|
|
registry: 'https://test/registry'
|
|
shrinkwrapMinorVersion: 7
|
|
shrinkwrapVersion: 3";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("shrinkwrap1.yaml", yamlFile1)
|
|
.ExecuteDetectorAsync();
|
|
|
|
scanResult.ResultCode.Should().Be(ProcessingResultCode.Success);
|
|
|
|
var detectedComponents = componentRecorder.GetDetectedComponents();
|
|
detectedComponents.Should().HaveCount(2);
|
|
var msItemsViewComponent = detectedComponents.Select(x => new { Component = x.Component as NpmComponent, DetectedComponent = x }).FirstOrDefault(x => x.Component.Name.Contains("@ms/items-view"));
|
|
|
|
msItemsViewComponent.Should().NotBeNull();
|
|
componentRecorder.AssertAllExplicitlyReferencedComponents<NpmComponent>(
|
|
msItemsViewComponent.Component.Id,
|
|
parentComponent => parentComponent.Name == "query-string");
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_DetectorRecognizeDevDependenciesValuesAsync()
|
|
{
|
|
var yamlFile1 = @"
|
|
dependencies:
|
|
'query-string': 4.3.4,
|
|
'strict-uri-encode': 1.1.0
|
|
packages:
|
|
/query-string/4.3.4:
|
|
dev: false
|
|
/strict-uri-encode/1.1.0:
|
|
dev: true";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("shrinkwrap1.yaml", yamlFile1)
|
|
.ExecuteDetectorAsync();
|
|
|
|
var detectedComponents = componentRecorder.GetDetectedComponents();
|
|
var noDevDependencyComponent = detectedComponents.Select(x => new { Component = x.Component as NpmComponent, DetectedComponent = x }).FirstOrDefault(x => x.Component.Name.Contains("query-string"));
|
|
var devDependencyComponent = detectedComponents.Select(x => new { Component = x.Component as NpmComponent, DetectedComponent = x }).FirstOrDefault(x => x.Component.Name.Contains("strict-uri-encode"));
|
|
|
|
componentRecorder.GetEffectiveDevDependencyValue(noDevDependencyComponent.Component.Id).Should().BeFalse();
|
|
componentRecorder.GetEffectiveDevDependencyValue(devDependencyComponent.Component.Id).Should().BeTrue();
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_DetectorRecognizeDevDependenciesValues_InWeirdCasesAsync()
|
|
{
|
|
var yamlFile1 = @"
|
|
dependencies:
|
|
'query-string': 4.3.4,
|
|
'strict-uri-encode': 1.1.0
|
|
packages:
|
|
/query-string/4.3.4:
|
|
dependencies:
|
|
solo-non-dev-dep: 0.1.2
|
|
shared-non-dev-dep: 0.1.2
|
|
dev: false
|
|
/strict-uri-encode/1.1.0:
|
|
dependencies:
|
|
solo-dev-dep: 0.1.2
|
|
shared-non-dev-dep: 0.1.2
|
|
dev: true";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("shrinkwrap1.yaml", yamlFile1)
|
|
.ExecuteDetectorAsync();
|
|
|
|
componentRecorder.GetEffectiveDevDependencyValue("solo-non-dev-dep 0.1.2 - Npm").Value.Should().BeFalse();
|
|
componentRecorder.GetEffectiveDevDependencyValue("solo-dev-dep 0.1.2 - Npm").Value.Should().BeTrue();
|
|
componentRecorder.GetEffectiveDevDependencyValue("shared-non-dev-dep 0.1.2 - Npm").Value.Should().BeFalse();
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_HandlesMalformedYamlAsync()
|
|
{
|
|
// This is a clearly malformed Yaml. We expect parsing it to "succeed" but find no components
|
|
var yamlFile1 = @"dependencies";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("shrinkwrap1.yaml", yamlFile1)
|
|
.ExecuteDetectorAsync();
|
|
|
|
scanResult.ResultCode.Should().Be(ProcessingResultCode.Success);
|
|
componentRecorder.GetDetectedComponents().Should().BeEmpty();
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_DependencyGraphIsCreatedAsync()
|
|
{
|
|
var yamlFile = @"
|
|
dependencies:
|
|
'query-string': 4.3.4,
|
|
|
|
packages:
|
|
/query-string/4.3.4:
|
|
dependencies:
|
|
object-assign: 4.1.1
|
|
test: 1.0.0
|
|
dev: false
|
|
/object-assign/4.1.1:
|
|
dependencies:
|
|
strict-uri-encode: 1.1.0
|
|
dev: false
|
|
/strict-uri-encode/1.1.0:
|
|
dev: false
|
|
/test/1.0.0:
|
|
dev: true";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("shrinkwrap1.yaml", yamlFile)
|
|
.ExecuteDetectorAsync();
|
|
|
|
scanResult.ResultCode.Should().Be(ProcessingResultCode.Success);
|
|
componentRecorder.GetDetectedComponents().Should().HaveCount(4);
|
|
|
|
var queryStringComponentId = PnpmParsingUtilities.CreateDetectedComponentFromPnpmPathV5("/query-string/4.3.4").Component.Id;
|
|
var objectAssignComponentId = PnpmParsingUtilities.CreateDetectedComponentFromPnpmPathV5("/object-assign/4.1.1").Component.Id;
|
|
var strictUriComponentId = PnpmParsingUtilities.CreateDetectedComponentFromPnpmPathV5("/strict-uri-encode/1.1.0").Component.Id;
|
|
var testComponentId = PnpmParsingUtilities.CreateDetectedComponentFromPnpmPathV5("/test/1.0.0").Component.Id;
|
|
|
|
var dependencyGraph = componentRecorder.GetDependencyGraphsByLocation().Values.First();
|
|
|
|
var queryStringDependencies = dependencyGraph.GetDependenciesForComponent(queryStringComponentId);
|
|
queryStringDependencies.Should().HaveCount(2);
|
|
queryStringDependencies.Should().Contain(objectAssignComponentId);
|
|
queryStringDependencies.Should().Contain(testComponentId);
|
|
|
|
var objectAssignDependencies = dependencyGraph.GetDependenciesForComponent(objectAssignComponentId);
|
|
objectAssignDependencies.Should().ContainSingle();
|
|
objectAssignDependencies.Should().Contain(strictUriComponentId);
|
|
|
|
var stringUriDependencies = dependencyGraph.GetDependenciesForComponent(strictUriComponentId);
|
|
stringUriDependencies.Should().BeEmpty();
|
|
|
|
var testDependencies = dependencyGraph.GetDependenciesForComponent(testComponentId);
|
|
testDependencies.Should().BeEmpty();
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_DependenciesRefeToLocalPaths_DependenciesAreIgnoredAsync()
|
|
{
|
|
var yamlFile = @"
|
|
dependencies:
|
|
'query-string': 4.3.4,
|
|
'@rush-temp/file-annotation-bar': file:projects/file-annotation-bar.tgz_node-sass@4.14.1
|
|
|
|
packages:
|
|
file:projects/file-annotation-bar.tgz_node-sass@4.14.1:
|
|
resolution: {integrity: sha1-G7T22scAcvwxPoyc0UF7UHTAoSU=}
|
|
/query-string/4.3.4:
|
|
dependencies:
|
|
'@learningclient/common': link:../common
|
|
nth-check: 2.0.0
|
|
/nth-check/2.0.0:
|
|
resolution: {integrity: sha1-G7T22scAcvwxPoyc0UF7UHTAoSU=} ";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("shrinkwrap1.yaml", yamlFile)
|
|
.ExecuteDetectorAsync();
|
|
|
|
scanResult.ResultCode.Should().Be(ProcessingResultCode.Success);
|
|
componentRecorder.GetDetectedComponents().Should().HaveCount(2, "Components that comes from a file (file:* or link:*) should be ignored.");
|
|
|
|
var queryStringComponentId = PnpmParsingUtilities.CreateDetectedComponentFromPnpmPathV5("/query-string/4.3.4").Component.Id;
|
|
var nthcheck = PnpmParsingUtilities.CreateDetectedComponentFromPnpmPathV5("/nth-check/2.0.0").Component.Id;
|
|
|
|
var dependencyGraph = componentRecorder.GetDependencyGraphsByLocation().Values.First();
|
|
|
|
var queryStringDependencies = dependencyGraph.GetDependenciesForComponent(queryStringComponentId);
|
|
queryStringDependencies.Should().ContainSingle();
|
|
queryStringDependencies.Should().Contain(nthcheck);
|
|
|
|
var nthCheckDependencies = dependencyGraph.GetDependenciesForComponent(nthcheck);
|
|
nthCheckDependencies.Should().BeEmpty();
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_BadLockVersion_EmptyAsync()
|
|
{
|
|
var yamlFile = @"
|
|
lockfileVersion: '4.0'
|
|
settings:
|
|
autoInstallPeers: true
|
|
excludeLinksFromLockfile: false
|
|
dependencies:
|
|
renamed:
|
|
specifier: npm:minimist@*
|
|
version: /minimist@1.2.8
|
|
packages:
|
|
/minimist@1.2.8:
|
|
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
|
dev: false
|
|
";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("pnpm-lock.yaml", yamlFile)
|
|
.ExecuteDetectorAsync();
|
|
|
|
scanResult.ResultCode.Should().Be(ProcessingResultCode.Success);
|
|
|
|
var detectedComponents = componentRecorder.GetDetectedComponents();
|
|
detectedComponents.Should().BeEmpty();
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_V5_GoodLockVersion_ParsedDependenciesAsync()
|
|
{
|
|
var yamlFile = @"
|
|
lockfileVersion: '5.0'
|
|
dependencies:
|
|
'query-string': 4.3.4,
|
|
'strict-uri-encode': 1.1.0
|
|
packages:
|
|
/query-string/4.3.4:
|
|
dev: false
|
|
/strict-uri-encode/1.1.0:
|
|
dev: true";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("pnpm-lock.yaml", yamlFile)
|
|
.ExecuteDetectorAsync();
|
|
|
|
scanResult.ResultCode.Should().Be(ProcessingResultCode.Success);
|
|
|
|
var detectedComponents = componentRecorder.GetDetectedComponents();
|
|
var noDevDependencyComponent = detectedComponents.Select(x => new { Component = x.Component as NpmComponent, DetectedComponent = x }).FirstOrDefault(x => x.Component.Name.Contains("query-string"));
|
|
var devDependencyComponent = detectedComponents.Select(x => new { Component = x.Component as NpmComponent, DetectedComponent = x }).FirstOrDefault(x => x.Component.Name.Contains("strict-uri-encode"));
|
|
|
|
componentRecorder.GetEffectiveDevDependencyValue(noDevDependencyComponent.Component.Id).Should().BeFalse();
|
|
componentRecorder.GetEffectiveDevDependencyValue(devDependencyComponent.Component.Id).Should().BeTrue();
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_V6_SuccessAsync()
|
|
{
|
|
var yamlFile = @"
|
|
lockfileVersion: '6.0'
|
|
settings:
|
|
autoInstallPeers: true
|
|
excludeLinksFromLockfile: false
|
|
dependencies:
|
|
minimist:
|
|
specifier: 1.2.8
|
|
version: 1.2.8
|
|
packages:
|
|
/minimist@1.2.8:
|
|
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
|
dev: false
|
|
";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("pnpm-lock.yaml", yamlFile)
|
|
.ExecuteDetectorAsync();
|
|
|
|
scanResult.ResultCode.Should().Be(ProcessingResultCode.Success);
|
|
|
|
var detectedComponents = componentRecorder.GetDetectedComponents();
|
|
detectedComponents.Should().ContainSingle();
|
|
|
|
var minimist = detectedComponents.Single(component => ((NpmComponent)component.Component).Name.Contains("minimist"));
|
|
componentRecorder.AssertAllExplicitlyReferencedComponents<NpmComponent>(
|
|
minimist.Component.Id,
|
|
parentComponent => parentComponent.Name == "minimist");
|
|
|
|
componentRecorder.ForAllComponents(grouping => grouping.AllFileLocations.First().Should().Contain("pnpm-lock.yaml"));
|
|
|
|
foreach (var component in detectedComponents)
|
|
{
|
|
component.Component.Type.Should().Be(ComponentType.Npm);
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_V6_WorkspaceAsync()
|
|
{
|
|
var yamlFile = @"
|
|
lockfileVersion: '6.0'
|
|
settings:
|
|
autoInstallPeers: true
|
|
excludeLinksFromLockfile: false
|
|
importers:
|
|
.:
|
|
dependencies:
|
|
minimist:
|
|
specifier: 1.2.8
|
|
version: 1.2.8
|
|
packages:
|
|
/minimist@1.2.8:
|
|
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
|
dev: false
|
|
";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("pnpm-lock.yaml", yamlFile)
|
|
.ExecuteDetectorAsync();
|
|
|
|
scanResult.ResultCode.Should().Be(ProcessingResultCode.Success);
|
|
|
|
var detectedComponents = componentRecorder.GetDetectedComponents();
|
|
detectedComponents.Should().ContainSingle();
|
|
|
|
var minimist = detectedComponents.Single(component => ((NpmComponent)component.Component).Name.Contains("minimist"));
|
|
componentRecorder.AssertAllExplicitlyReferencedComponents<NpmComponent>(
|
|
minimist.Component.Id,
|
|
parentComponent => parentComponent.Name == "minimist");
|
|
|
|
componentRecorder.ForAllComponents(grouping => grouping.AllFileLocations.First().Should().Contain("pnpm-lock.yaml"));
|
|
|
|
foreach (var component in detectedComponents)
|
|
{
|
|
component.Component.Type.Should().Be(ComponentType.Npm);
|
|
}
|
|
}
|
|
|
|
// Test that renamed package is handled correctly, and that resolved version gets used (not specifier)
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_V6_RenamedAsync()
|
|
{
|
|
var yamlFile = @"
|
|
lockfileVersion: '6.0'
|
|
settings:
|
|
autoInstallPeers: true
|
|
excludeLinksFromLockfile: false
|
|
dependencies:
|
|
renamed:
|
|
specifier: npm:minimist@*
|
|
version: /minimist@1.2.8
|
|
packages:
|
|
/minimist@1.2.8:
|
|
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
|
dev: false
|
|
";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("pnpm-lock.yaml", yamlFile)
|
|
.ExecuteDetectorAsync();
|
|
|
|
scanResult.ResultCode.Should().Be(ProcessingResultCode.Success);
|
|
|
|
var detectedComponents = componentRecorder.GetDetectedComponents();
|
|
detectedComponents.Should().ContainSingle();
|
|
|
|
var minimist = detectedComponents.Single(component => ((NpmComponent)component.Component).Name.Equals("minimist"));
|
|
componentRecorder.AssertAllExplicitlyReferencedComponents<NpmComponent>(
|
|
minimist.Component.Id,
|
|
parentComponent => parentComponent.Name == "minimist");
|
|
((NpmComponent)minimist.Component).Version.Should().BeEquivalentTo("1.2.8");
|
|
|
|
componentRecorder.ForAllComponents(grouping => grouping.AllFileLocations.First().Should().Contain("pnpm-lock.yaml"));
|
|
|
|
foreach (var component in detectedComponents)
|
|
{
|
|
component.Component.Type.Should().Be(ComponentType.Npm);
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task TestPnpmDetector_V6_BadLockVersion_EmptyAsync()
|
|
{
|
|
var yamlFile = @"
|
|
lockfileVersion: '5.0'
|
|
settings:
|
|
autoInstallPeers: true
|
|
excludeLinksFromLockfile: false
|
|
dependencies:
|
|
renamed:
|
|
specifier: npm:minimist@*
|
|
version: /minimist@1.2.8
|
|
packages:
|
|
/minimist@1.2.8:
|
|
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
|
dev: false
|
|
";
|
|
|
|
var (scanResult, componentRecorder) = await this.DetectorTestUtility
|
|
.WithFile("pnpm-lock.yaml", yamlFile)
|
|
.ExecuteDetectorAsync();
|
|
|
|
scanResult.ResultCode.Should().Be(ProcessingResultCode.Success);
|
|
|
|
var detectedComponents = componentRecorder.GetDetectedComponents();
|
|
detectedComponents.Should().BeEmpty();
|
|
}
|
|
}
|