1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2 3package parser2v3 4 5import ( 6 "reflect" 7 "testing" 8 9 "github.com/spdx/gordf/rdfwriter" 10 "github.com/spdx/tools-golang/spdx/common" 11 "github.com/spdx/tools-golang/spdx/v2_3" 12) 13 14func Test_getReferenceFromURI(t *testing.T) { 15 // TestCase 1: noassertion uri 16 ref, err := getReferenceFromURI(SPDX_NOASSERTION_CAPS) 17 if err != nil { 18 t.Errorf("unexpected error: %v", err) 19 } 20 if ref.DocumentRefID != "" { 21 t.Errorf("reference's documentRefID should've been empty, found %s", ref.DocumentRefID) 22 } 23 if ref.ElementRefID != "NOASSERTION" { 24 t.Errorf("mismatching elementRefID. Found %s, expected %s", ref.ElementRefID, "NOASSERTION") 25 } 26 27 // TestCase 2: NONE uri 28 ref, err = getReferenceFromURI(SPDX_NONE_CAPS) 29 if err != nil { 30 t.Errorf("unexpected error: %v", err) 31 } 32 if ref.DocumentRefID != "" { 33 t.Errorf("reference's documentRefID should've been empty, found %s", ref.DocumentRefID) 34 } 35 if ref.ElementRefID != "NONE" { 36 t.Errorf("mismatching elementRefID. Found %s, expected %s", ref.ElementRefID, "NONE") 37 } 38 39 // TestCase 3: Valid URI 40 ref, err = getReferenceFromURI(NS_SPDX + "SPDXRef-item1") 41 if err != nil { 42 t.Errorf("unexpected error: %v", err) 43 } 44 if ref.DocumentRefID != "" { 45 t.Errorf("reference's documentRefID should've been empty, found %s", ref.DocumentRefID) 46 } 47 if ref.ElementRefID != "item1" { 48 t.Errorf("mismatching elementRefID. Found %s, expected %s", ref.ElementRefID, "item1") 49 } 50 51 // TestCase 3: Invalid URI 52 _, err = getReferenceFromURI(NS_SPDX + "item1") 53 if err == nil { 54 t.Errorf("should've raised an error for invalid input") 55 } 56} 57 58func Test_getRelationshipTypeFromURI(t *testing.T) { 59 // TestCase 1: valid relationshipType 60 relnType := "expandedFromArchive" 61 op, err := getRelationshipTypeFromURI(NS_SPDX + "relationshipType_" + relnType) 62 if err != nil { 63 t.Errorf("error getting relationship type from a valid input") 64 } 65 if op != relnType { 66 t.Errorf("expected %s, found %s", relnType, op) 67 } 68 69 // TestCase2: invalid relationshipType 70 relnType = "invalidRelationship" 71 _, err = getRelationshipTypeFromURI(NS_SPDX + "relationshipType_" + relnType) 72 if err == nil { 73 t.Errorf("should've raised an error for an invalid input(%s)", relnType) 74 } 75} 76 77func Test_rdfParser2_3_parseRelatedElementFromTriple(t *testing.T) { 78 // TestCase 1: Package as a related element 79 parser, _ := parserFromBodyContent(` 80 <spdx:Relationship> 81 <spdx:relatedSpdxElement> 82 <spdx:Package rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Saxon"/> 83 </spdx:relatedSpdxElement> 84 </spdx:Relationship> 85 `) 86 reln := &v2_3.Relationship{} 87 triple := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_PACKAGE)[0] 88 err := parser.parseRelatedElementFromTriple(reln, triple) 89 if err != nil { 90 t.Errorf("error parsing a valid example") 91 } 92 expectedRefA := common.DocElementID{ 93 DocumentRefID: "", 94 ElementRefID: "", 95 } 96 if !reflect.DeepEqual(expectedRefA, reln.RefA) { 97 t.Errorf("expected %+v, found %+v", expectedRefA, reln.RefA) 98 } 99 expectedRefB := common.DocElementID{ 100 DocumentRefID: "", 101 ElementRefID: "Saxon", 102 } 103 if !reflect.DeepEqual(expectedRefB, reln.RefB) { 104 t.Errorf("expected %+v, found %+v", expectedRefB, reln.RefB) 105 } 106 107 // TestCase 3: invalid package as a relatedElement 108 parser, _ = parserFromBodyContent(` 109 <spdx:Relationship> 110 <spdx:relatedSpdxElement> 111 <spdx:Package rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#Saxon"/> 112 </spdx:relatedSpdxElement> 113 </spdx:Relationship> 114 `) 115 reln = &v2_3.Relationship{} 116 triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_PACKAGE)[0] 117 err = parser.parseRelatedElementFromTriple(reln, triple) 118 if err == nil { 119 t.Errorf("expected an error due to invalid Package id, got %v", err) 120 } 121 122 // TestCase 4: valid File as a related element 123 parser, _ = parserFromBodyContent(` 124 <spdx:Relationship> 125 <spdx:relatedSpdxElement> 126 <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Saxon"/> 127 </spdx:relatedSpdxElement> 128 </spdx:Relationship> 129 `) 130 reln = &v2_3.Relationship{} 131 triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0] 132 err = parser.parseRelatedElementFromTriple(reln, triple) 133 if err != nil { 134 t.Errorf("error parsing a valid example") 135 } 136 expectedRefA = common.DocElementID{ 137 DocumentRefID: "", 138 ElementRefID: "", 139 } 140 if !reflect.DeepEqual(expectedRefA, reln.RefA) { 141 t.Errorf("expected %+v, found %+v", expectedRefA, reln.RefA) 142 } 143 expectedRefB = common.DocElementID{ 144 DocumentRefID: "", 145 ElementRefID: "Saxon", 146 } 147 if !reflect.DeepEqual(expectedRefB, reln.RefB) { 148 t.Errorf("expected %+v, found %+v", expectedRefB, reln.RefB) 149 } 150 151 // TestCase 5: invalid File as a relatedElement 152 parser, _ = parserFromBodyContent(` 153 <spdx:Relationship> 154 <spdx:relatedSpdxElement> 155 <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#Saxon"/> 156 </spdx:relatedSpdxElement> 157 </spdx:Relationship> 158 `) 159 reln = &v2_3.Relationship{} 160 triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0] 161 err = parser.parseRelatedElementFromTriple(reln, triple) 162 if err == nil { 163 t.Errorf("expected an error while parsing an invalid File, got %v", err) 164 } 165 166 // TestCase 6: valid SpdxElement as a related element 167 parser, _ = parserFromBodyContent(` 168 <spdx:Relationship> 169 <spdx:relatedSpdxElement> 170 <spdx:SpdxElement rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File"/> 171 </spdx:relatedSpdxElement> 172 </spdx:Relationship> 173 `) 174 reln = &v2_3.Relationship{} 175 triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_SPDX_ELEMENT)[0] 176 err = parser.parseRelatedElementFromTriple(reln, triple) 177 if err != nil { 178 t.Errorf("error parsing a valid example") 179 } 180 expectedRefA = common.DocElementID{ 181 DocumentRefID: "", 182 ElementRefID: "", 183 } 184 if !reflect.DeepEqual(expectedRefA, reln.RefA) { 185 t.Errorf("expected %+v, found %+v", expectedRefA, reln.RefA) 186 } 187 expectedRefB = common.DocElementID{ 188 DocumentRefID: "", 189 ElementRefID: "File", 190 } 191 if !reflect.DeepEqual(expectedRefB, reln.RefB) { 192 t.Errorf("expected %+v, found %+v", expectedRefB, reln.RefB) 193 } 194 195 // TestCase 7: invalid SpdxElement as a related element 196 parser, _ = parserFromBodyContent(` 197 <spdx:Relationship> 198 <spdx:relatedSpdxElement> 199 <spdx:SpdxElement rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-:File"/> 200 </spdx:relatedSpdxElement> 201 </spdx:Relationship> 202 `) 203 reln = &v2_3.Relationship{} 204 triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_SPDX_ELEMENT)[0] 205 err = parser.parseRelatedElementFromTriple(reln, triple) 206 if err == nil { 207 t.Errorf("expected an error due to invalid documentId for SpdxElement, got %v", err) 208 } 209} 210 211func Test_rdfParser2_3_parseRelationship(t *testing.T) { 212 // TestCase 1: invalid RefA 213 parser, _ := parserFromBodyContent(` 214 <spdx:File> 215 <spdx:relationship> 216 <spdx:Relationship> 217 <spdx:relatedSpdxElement> 218 <spdx:Package rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Saxon"/> 219 </spdx:relatedSpdxElement> 220 </spdx:Relationship> 221 </spdx:relationship> 222 </spdx:File> 223 `) 224 triple := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &SPDX_RELATIONSHIP, nil)[0] 225 err := parser.parseRelationship(triple) 226 if err == nil { 227 t.Errorf("should've raised an error due to invalid RefA") 228 } 229 230 // TestCase 3: invalid RefB 231 parser, _ = parserFromBodyContent(` 232 <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File"> 233 <spdx:relationship> 234 <spdx:Relationship> 235 <spdx:relatedSpdxElement> 236 <spdx:Package rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#Saxon"/> 237 </spdx:relatedSpdxElement> 238 </spdx:Relationship> 239 </spdx:relationship> 240 </spdx:File> 241 `) 242 triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &SPDX_RELATIONSHIP, nil)[0] 243 err = parser.parseRelationship(triple) 244 if err == nil { 245 t.Errorf("should've raised an error due to invalid RefB") 246 } 247 248 // TestCase 3: more than one typeTriple for relatedElement 249 parser, _ = parserFromBodyContent(` 250 <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File"> 251 <spdx:relationship> 252 <spdx:Relationship> 253 <spdx:relatedSpdxElement> 254 <spdx:Package rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Saxon"/> 255 </spdx:relatedSpdxElement> 256 <spdx:relatedSpdxElement> 257 <spdx:File/> 258 </spdx:relatedSpdxElement> 259 </spdx:Relationship> 260 </spdx:relationship> 261 </spdx:File> 262 `) 263 triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &SPDX_RELATIONSHIP, nil)[0] 264 err = parser.parseRelationship(triple) 265 if err == nil { 266 t.Errorf("should've raised an error due to more than one type triples") 267 } 268 269 // TestCase 4: undefined relatedSpdxElement 270 parser, _ = parserFromBodyContent(` 271 <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File"> 272 <spdx:relationship> 273 <spdx:Relationship> 274 <spdx:relatedSpdxElement> 275 <spdx:Unknown rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Saxon"/> 276 </spdx:relatedSpdxElement> 277 </spdx:Relationship> 278 </spdx:relationship> 279 </spdx:File> 280 `) 281 triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &SPDX_RELATIONSHIP, nil)[0] 282 err = parser.parseRelationship(triple) 283 if err == nil { 284 t.Errorf("should've raised an error due to unknown relatedElement, got %v", err) 285 } 286 287 // TestCase 6: relatedElement associated with more than one type 288 parser, _ = parserFromBodyContent(` 289 <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File"> 290 <spdx:relationship> 291 <spdx:Relationship> 292 <spdx:relatedSpdxElement> 293 <spdx:Package rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Saxon"/> 294 </spdx:relatedSpdxElement> 295 </spdx:Relationship> 296 </spdx:relationship> 297 </spdx:File> 298 <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Saxon"/> 299 `) 300 triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &SPDX_RELATIONSHIP, nil)[0] 301 err = parser.parseRelationship(triple) 302 if err == nil { 303 t.Errorf("expected an error due to invalid relatedElement, got %v", err) 304 } 305 306 // TestCase 5: unknown predicate inside a relationship 307 parser, _ = parserFromBodyContent(` 308 <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File"> 309 <spdx:relationship> 310 <spdx:Relationship> 311 <spdx:relatedSpdxElement> 312 <spdx:Unknown rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Saxon"/> 313 </spdx:relatedSpdxElement> 314 <spdx:unknownPredicate/> 315 </spdx:Relationship> 316 </spdx:relationship> 317 </spdx:File> 318 `) 319 triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &SPDX_RELATIONSHIP, nil)[0] 320 err = parser.parseRelationship(triple) 321 if err == nil { 322 t.Errorf("should've raised an error due to unknown predicate in a relationship") 323 } 324 325 // TestCase 8: Recursive relationships mustn't raise any error: 326 parser, _ = parserFromBodyContent(` 327 <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File"> 328 <spdx:relationship> 329 <spdx:Relationship rdf:about="#SPDXRef-reln"> 330 <spdx:relationshipType rdf:resource="http://spdx.org/rdf/terms#relationshipType_describes"/> 331 <spdx:relatedSpdxElement> 332 <spdx:Package rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Saxon"> 333 <spdx:relationship> 334 <spdx:Relationship rdf:about="#SPDXRef-reln"> 335 <spdx:relationshipType rdf:resource="http://spdx.org/rdf/terms#relationshipType_describes"/> 336 <spdx:relatedSpdxElement rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File"/> 337 </spdx:Relationship> 338 </spdx:relationship> 339 </spdx:Package> 340 </spdx:relatedSpdxElement> 341 </spdx:Relationship> 342 </spdx:relationship> 343 </spdx:File> 344 `) 345 triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &SPDX_RELATIONSHIP, nil)[0] 346 err = parser.parseRelationship(triple) 347 if err != nil { 348 t.Errorf("error parsing a valid example") 349 } 350 351 // TestCase 7: completely valid example: 352 parser, _ = parserFromBodyContent(` 353 <spdx:File rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-File"> 354 <spdx:relationship> 355 <spdx:Relationship> 356 <spdx:relationshipType rdf:resource="http://spdx.org/rdf/terms#relationshipType_describes"/> 357 <spdx:relatedSpdxElement> 358 <spdx:Package rdf:about="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Saxon"/> 359 </spdx:relatedSpdxElement> 360 <rdfs:comment>comment</rdfs:comment> 361 </spdx:Relationship> 362 </spdx:relationship> 363 </spdx:File> 364 `) 365 triple = rdfwriter.FilterTriples(parser.gordfParserObj.Triples, nil, &SPDX_RELATIONSHIP, nil)[0] 366 err = parser.parseRelationship(triple) 367 if err != nil { 368 t.Errorf("unexpected error parsing a valid relationship: %v", err) 369 } 370 // validating parsed attributes 371 if len(parser.doc.Relationships) != 1 { 372 t.Errorf("after parsing a valid relationship, doc should've had 1 relationship, found %d", len(parser.doc.Relationships)) 373 } 374 reln := parser.doc.Relationships[0] 375 expectedRelnType := "describes" 376 if reln.Relationship != expectedRelnType { 377 t.Errorf("expected %s, found %s", expectedRelnType, reln.Relationship) 378 } 379 expectedRefA := common.DocElementID{ 380 DocumentRefID: "", 381 ElementRefID: "File", 382 } 383 if !reflect.DeepEqual(expectedRefA, reln.RefA) { 384 t.Errorf("expected %+v, found %+v", expectedRefA, reln.RefA) 385 } 386 expectedRefB := common.DocElementID{ 387 DocumentRefID: "", 388 ElementRefID: "Saxon", 389 } 390 if !reflect.DeepEqual(expectedRefB, reln.RefB) { 391 t.Errorf("expected %+v, found %+v", expectedRefB, reln.RefB) 392 } 393 expectedComment := "comment" 394 if reln.RelationshipComment != expectedComment { 395 t.Errorf("expected %v, found %v", expectedComment, reln.RelationshipComment) 396 } 397} 398