xref: /aosp_15_r20/external/spdx-tools/rdfloader/parser2v3/parse_relationship_test.go (revision ba677afa8f67bb56cbc794f4d0e378e0da058e16)
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