@@ -73,73 +73,155 @@ describe("ComponentDetection.addPackagesToManifests", () => {
7373 test ( "adds package as direct dependency when no top level referrers" , ( ) => {
7474 const manifests : any [ ] = [ ] ;
7575
76- const mockPackage = {
76+ const testPackage = {
7777 id : "test-package-1" ,
7878 packageUrl : "pkg:npm/test-package@1.0.0" ,
7979 isDevelopmentDependency : false ,
80- topLevelReferrers : [ ] ,
80+ topLevelReferrers : [ ] , // Empty array = direct dependency
8181 locationsFoundAt : [ "package.json" ] ,
8282 containerDetailIds : [ ] ,
8383 containerLayerIds : [ ] ,
8484 packageID : ( ) => "pkg:npm/test-package@1.0.0" ,
8585 packageURL : { toString : ( ) => "pkg:npm/test-package@1.0.0" }
8686 } ;
8787
88- ComponentDetection . addPackagesToManifests ( [ mockPackage ] as any , manifests ) ;
88+ ComponentDetection . addPackagesToManifests ( [ testPackage ] as any , manifests ) ;
8989
9090 expect ( manifests ) . toHaveLength ( 1 ) ;
9191 expect ( manifests [ 0 ] . name ) . toBe ( "package.json" ) ;
92+
93+ // Test the actual manifest state instead of mock calls
94+ expect ( manifests [ 0 ] . directDependencies ( ) ) . toHaveLength ( 1 ) ;
95+ expect ( manifests [ 0 ] . indirectDependencies ( ) ) . toHaveLength ( 0 ) ;
96+ expect ( manifests [ 0 ] . countDependencies ( ) ) . toBe ( 1 ) ;
9297 } ) ;
9398
9499 test ( "adds package as indirect dependency when has top level referrers" , ( ) => {
95100 const manifests : any [ ] = [ ] ;
96101
97- const mockPackage = {
102+ const testPackage = {
98103 id : "test-package-2" ,
99104 packageUrl : "pkg:npm/test-package@2.0.0" ,
100105 isDevelopmentDependency : false ,
101- topLevelReferrers : [ { packageUrl : "pkg:npm/parent-package@1.0.0" } ] ,
106+ topLevelReferrers : [ { packageUrl : "pkg:npm/parent-package@1.0.0" } ] , // Has referrers = indirect
102107 locationsFoundAt : [ "package.json" ] ,
103108 containerDetailIds : [ ] ,
104109 containerLayerIds : [ ] ,
105110 packageID : ( ) => "pkg:npm/test-package@2.0.0" ,
106111 packageURL : { toString : ( ) => "pkg:npm/test-package@2.0.0" }
107112 } ;
108113
109- ComponentDetection . addPackagesToManifests ( [ mockPackage ] as any , manifests ) ;
114+ ComponentDetection . addPackagesToManifests ( [ testPackage ] as any , manifests ) ;
110115
111116 expect ( manifests ) . toHaveLength ( 1 ) ;
112117 expect ( manifests [ 0 ] . name ) . toBe ( "package.json" ) ;
113- } ) ;
114118
115- test ( "reuses existing manifest when same location found" , ( ) => {
116- let directDependencyCallCount = 0 ;
117- let indirectDependencyCallCount = 0 ;
119+ expect ( manifests [ 0 ] . directDependencies ( ) ) . toHaveLength ( 0 ) ;
120+ expect ( manifests [ 0 ] . indirectDependencies ( ) ) . toHaveLength ( 1 ) ;
121+ expect ( manifests [ 0 ] . countDependencies ( ) ) . toBe ( 1 ) ;
122+ } ) ;
118123
119- const existingManifest = {
120- name : "package.json" ,
121- addDirectDependency : ( ) => { directDependencyCallCount ++ ; } ,
122- addIndirectDependency : ( ) => { indirectDependencyCallCount ++ ; }
123- } ;
124- const manifests : any [ ] = [ existingManifest ] ;
124+ test ( "adds package as indirect dependency when top level referrer is itself" , ( ) => {
125+ const manifests : any [ ] = [ ] ;
125126
126- const mockPackage = {
127+ const testPackage = {
127128 id : "test-package-3" ,
128129 packageUrl : "pkg:npm/test-package@3.0.0" ,
129130 isDevelopmentDependency : false ,
130- topLevelReferrers : [ ] ,
131+ topLevelReferrers : [ { packageUrl : "pkg:npm/test-package@3.0.0" } ] , // Self-reference case
131132 locationsFoundAt : [ "package.json" ] ,
132133 containerDetailIds : [ ] ,
133134 containerLayerIds : [ ] ,
134135 packageID : ( ) => "pkg:npm/test-package@3.0.0" ,
135136 packageURL : { toString : ( ) => "pkg:npm/test-package@3.0.0" }
136137 } ;
137138
138- ComponentDetection . addPackagesToManifests ( [ mockPackage ] as any , manifests ) ;
139+ ComponentDetection . addPackagesToManifests ( [ testPackage ] as any , manifests ) ;
140+
141+ expect ( manifests ) . toHaveLength ( 1 ) ;
142+ expect ( manifests [ 0 ] . name ) . toBe ( "package.json" ) ;
143+
144+ // Self-referencing packages are currently treated as indirect - this might be a bug to investigate
145+ expect ( manifests [ 0 ] . directDependencies ( ) ) . toHaveLength ( 0 ) ;
146+ expect ( manifests [ 0 ] . indirectDependencies ( ) ) . toHaveLength ( 1 ) ;
147+ expect ( manifests [ 0 ] . countDependencies ( ) ) . toBe ( 1 ) ;
148+ } ) ;
149+
150+ test ( "handles multiple packages with mixed dependency types" , ( ) => {
151+ const manifests : any [ ] = [ ] ;
152+
153+ const directTestPackage = {
154+ id : "direct-package" ,
155+ packageUrl : "pkg:npm/direct-package@1.0.0" ,
156+ isDevelopmentDependency : false ,
157+ topLevelReferrers : [ ] , // Direct
158+ locationsFoundAt : [ "package.json" ] ,
159+ containerDetailIds : [ ] ,
160+ containerLayerIds : [ ] ,
161+ packageID : ( ) => "pkg:npm/direct-package@1.0.0" ,
162+ packageURL : { toString : ( ) => "pkg:npm/direct-package@1.0.0" }
163+ } ;
164+
165+ const indirectTestPackage = {
166+ id : "indirect-package" ,
167+ packageUrl : "pkg:npm/indirect-package@1.0.0" ,
168+ isDevelopmentDependency : false ,
169+ topLevelReferrers : [ { packageUrl : "pkg:npm/parent@1.0.0" } ] , // Indirect
170+ locationsFoundAt : [ "package.json" ] ,
171+ containerDetailIds : [ ] ,
172+ containerLayerIds : [ ] ,
173+ packageID : ( ) => "pkg:npm/indirect-package@1.0.0" ,
174+ packageURL : { toString : ( ) => "pkg:npm/indirect-package@1.0.0" }
175+ } ;
176+
177+ ComponentDetection . addPackagesToManifests ( [ directTestPackage , indirectTestPackage ] as any , manifests ) ;
139178
140179 expect ( manifests ) . toHaveLength ( 1 ) ;
141- expect ( manifests [ 0 ] ) . toBe ( existingManifest ) ;
142- expect ( directDependencyCallCount ) . toBe ( 1 ) ;
143- expect ( indirectDependencyCallCount ) . toBe ( 0 ) ;
180+ expect ( manifests [ 0 ] . name ) . toBe ( "package.json" ) ;
181+
182+ expect ( manifests [ 0 ] . directDependencies ( ) ) . toHaveLength ( 1 ) ;
183+ expect ( manifests [ 0 ] . indirectDependencies ( ) ) . toHaveLength ( 1 ) ;
184+ expect ( manifests [ 0 ] . countDependencies ( ) ) . toBe ( 2 ) ;
185+ } ) ;
186+
187+ test ( "creates separate manifests for different locations" , ( ) => {
188+ const manifests : any [ ] = [ ] ;
189+
190+ const packageJsonTestPackage = {
191+ id : "package-json-dep" ,
192+ packageUrl : "pkg:npm/package-json-dep@1.0.0" ,
193+ isDevelopmentDependency : false ,
194+ topLevelReferrers : [ ] ,
195+ locationsFoundAt : [ "package.json" ] ,
196+ containerDetailIds : [ ] ,
197+ containerLayerIds : [ ] ,
198+ packageID : ( ) => "pkg:npm/package-json-dep@1.0.0" ,
199+ packageURL : { toString : ( ) => "pkg:npm/package-json-dep@1.0.0" }
200+ } ;
201+
202+ const csprojTestPackage = {
203+ id : "csproj-dep" ,
204+ packageUrl : "pkg:nuget/csproj-dep@1.0.0" ,
205+ isDevelopmentDependency : false ,
206+ topLevelReferrers : [ ] ,
207+ locationsFoundAt : [ "project.csproj" ] ,
208+ containerDetailIds : [ ] ,
209+ containerLayerIds : [ ] ,
210+ packageID : ( ) => "pkg:nuget/csproj-dep@1.0.0" ,
211+ packageURL : { toString : ( ) => "pkg:nuget/csproj-dep@1.0.0" }
212+ } ;
213+
214+ ComponentDetection . addPackagesToManifests ( [ packageJsonTestPackage , csprojTestPackage ] as any , manifests ) ;
215+
216+ expect ( manifests ) . toHaveLength ( 2 ) ;
217+
218+ const packageJsonManifest = manifests . find ( m => m . name === "package.json" ) ;
219+ const csprojManifest = manifests . find ( m => m . name === "project.csproj" ) ;
220+
221+ expect ( packageJsonManifest ) . toBeDefined ( ) ;
222+ expect ( csprojManifest ) . toBeDefined ( ) ;
223+
224+ expect ( packageJsonManifest . countDependencies ( ) ) . toBe ( 1 ) ;
225+ expect ( csprojManifest . countDependencies ( ) ) . toBe ( 1 ) ;
144226 } ) ;
145227} ) ;
0 commit comments