4
4
5
5
from pathlib import Path
6
6
from typing import Any
7
+ from unittest import mock
7
8
8
9
import pytest
9
10
from pydantic import ValidationError
10
11
11
- from opossum_lib .scancode .model import File , ScanCodeData
12
+ from opossum_lib .opossum .opossum_file import OpossumPackage , SourceInfo
13
+ from opossum_lib .scancode .model import (
14
+ File ,
15
+ ScanCodeData ,
16
+ )
12
17
from opossum_lib .scancode .resource_tree import (
13
18
Node ,
14
19
convert_to_opossum_resources ,
20
+ create_attribution_mapping ,
15
21
scancode_to_resource_tree ,
16
22
)
17
23
@@ -60,12 +66,7 @@ def test_scancode_to_resource_tree() -> None:
60
66
)
61
67
62
68
tree = scancode_to_resource_tree (scancode_data )
63
- folder , subfolder , file1 , file2 , file3 = files
64
- inner = Node (file = subfolder , children = {"file3" : Node (file = file3 )})
65
- reference = Node (
66
- file = folder ,
67
- children = {"B" : inner , "file1" : Node (file = file1 ), "file2.txt" : Node (file = file2 )},
68
- )
69
+ reference = _create_reference_Node_structure ()
69
70
70
71
assert tree == reference
71
72
@@ -85,6 +86,57 @@ def test_convert_to_opossum_resources() -> None:
85
86
assert resources .to_dict () == reference
86
87
87
88
89
+ # OpossumUI automatically prepends every path with a "/"
90
+ # So our resourcesToAttributions needs to start every path with "/" as well
91
+ @mock .patch (
92
+ "opossum_lib.scancode.resource_tree.get_attribution_info" ,
93
+ autospec = True ,
94
+ return_value = [OpossumPackage (source = SourceInfo (name = "mocked" ))],
95
+ )
96
+ def test_create_attribution_mapping_paths_have_root_prefix (_ : Any ) -> None :
97
+ rootnode = _create_reference_Node_structure ()
98
+ # rootnode.children["file1"].file.license_detections = [ld1]
99
+ # rootnode.children["B"].children["file3"].file.license_detections = [ld2]
100
+ _ , resourcesToAttributions = create_attribution_mapping (rootnode )
101
+ assert "/A/file1" in resourcesToAttributions
102
+ assert "/A/file2.txt" in resourcesToAttributions
103
+ assert "/A/B/file3" in resourcesToAttributions
104
+
105
+
106
+ def test_create_attribution_mapping () -> None :
107
+ _ , _ , file1 , file2 , file3 = _create_reference_scancode_files ()
108
+ pkg1 = OpossumPackage (source = SourceInfo (name = "S1" ))
109
+ pkg2 = OpossumPackage (source = SourceInfo (name = "S2" ))
110
+ pkg3 = OpossumPackage (source = SourceInfo (name = "S3" ))
111
+
112
+ def get_attribution_info_mock (file : File ) -> list [OpossumPackage ]:
113
+ if file == file1 :
114
+ return [pkg1 , pkg2 ]
115
+ elif file == file2 :
116
+ return [pkg1 , pkg2 , pkg3 ]
117
+ elif file == file3 :
118
+ return []
119
+ else :
120
+ return []
121
+
122
+ rootnode = _create_reference_Node_structure ()
123
+
124
+ with mock .patch (
125
+ "opossum_lib.scancode.resource_tree.get_attribution_info" ,
126
+ new = get_attribution_info_mock ,
127
+ ):
128
+ externalAttributions , resourcesToAttributions = create_attribution_mapping (
129
+ rootnode
130
+ )
131
+ assert len (externalAttributions ) == 3 # deduplication worked
132
+
133
+ reverseMapping = {v : k for (k , v ) in externalAttributions .items ()}
134
+ id1 , id2 , id3 = reverseMapping [pkg1 ], reverseMapping [pkg2 ], reverseMapping [pkg3 ]
135
+ assert len (resourcesToAttributions ) == 2 # only files with attributions
136
+ assert set (resourcesToAttributions ["/" + file1 .path ]) == {id1 , id2 }
137
+ assert set (resourcesToAttributions ["/" + file2 .path ]) == {id1 , id2 , id3 }
138
+
139
+
88
140
def _create_reference_scancode_files () -> list [File ]:
89
141
return [
90
142
_create_file ("A" , "folder" ),
@@ -95,8 +147,18 @@ def _create_reference_scancode_files() -> list[File]:
95
147
]
96
148
97
149
150
+ def _create_reference_Node_structure () -> Node :
151
+ folder , subfolder , file1 , file2 , file3 = _create_reference_scancode_files ()
152
+ inner = Node (file = subfolder , children = {"file3" : Node (file = file3 )})
153
+ reference = Node (
154
+ file = folder ,
155
+ children = {"B" : inner , "file1" : Node (file = file1 ), "file2.txt" : Node (file = file2 )},
156
+ )
157
+ return reference
158
+
159
+
98
160
def _create_file (path : str , type : str , ** kwargs : dict [str , Any ]) -> File :
99
- dprops = {
161
+ defaultproperties = {
100
162
"path" : path ,
101
163
"type" : type ,
102
164
"name" : Path (path ).name ,
@@ -134,4 +196,4 @@ def _create_file(path: str, type: str, **kwargs: dict[str, Any]) -> File:
134
196
"scan_errors" : [],
135
197
** kwargs ,
136
198
}
137
- return File .model_validate (dprops )
199
+ return File .model_validate (defaultproperties )
0 commit comments