xref: /aosp_15_r20/external/spdx-tools/rdfloader/parser2v2/parse_file_test.go (revision ba677afa8f67bb56cbc794f4d0e378e0da058e16)
1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2
3package parser2v2
4
5import (
6	"bufio"
7	"strings"
8	"testing"
9
10	gordfParser "github.com/spdx/gordf/rdfloader/parser"
11	rdfloader2 "github.com/spdx/gordf/rdfloader/xmlreader"
12	gordfWriter "github.com/spdx/gordf/rdfwriter"
13	"github.com/spdx/tools-golang/spdx/common"
14	"github.com/spdx/tools-golang/spdx/v2_2"
15)
16
17// content is the tags within the rdf:RDF tag
18// pads the content with the enclosing rdf:RDF tag
19func wrapIntoTemplate(content string) string {
20	header := `<rdf:RDF
21        xmlns:spdx="http://spdx.org/rdf/terms#"
22        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
23        xmlns="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#"
24        xmlns:doap="http://usefulinc.com/ns/doap#"
25        xmlns:j.0="http://www.w3.org/2009/pointers#"
26        xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">`
27	footer := `</rdf:RDF>`
28	return header + content + footer
29}
30
31func parserFromBodyContent(content string) (*rdfParser2_2, error) {
32	rdfContent := wrapIntoTemplate(content)
33	xmlreader := rdfloader2.XMLReaderFromFileObject(bufio.NewReader(strings.NewReader(rdfContent)))
34	rootBlock, err := xmlreader.Read()
35	if err != nil {
36		return nil, err
37	}
38	parser := gordfParser.New()
39	err = parser.Parse(rootBlock)
40	if err != nil {
41		return nil, err
42	}
43	nodeToTriples := gordfWriter.GetNodeToTriples(parser.Triples)
44	rdfParser := NewParser2_2(parser, nodeToTriples)
45	return rdfParser, err
46}
47
48func Test_rdfParser2_2_getArtifactFromNode(t *testing.T) {
49	// TestCase 1: artifactOf without project URI
50	rdfParser, err := parserFromBodyContent(
51		`<spdx:File>
52			<spdx:artifactOf>
53				<doap:Project>
54					<doap:homepage>http://www.openjena.org/</doap:homepage>
55					<doap:name>Jena</doap:name>
56				</doap:Project>
57			</spdx:artifactOf>
58		</spdx:File>`)
59	if err != nil {
60		t.Errorf("unexpected error while parsing a valid example: %v", err)
61	}
62	artifactOfNode := gordfWriter.FilterTriples(rdfParser.gordfParserObj.Triples, nil, &SPDX_ARTIFACT_OF, nil)[0].Object
63	artifact, err := rdfParser.getArtifactFromNode(artifactOfNode)
64	if err != nil {
65		t.Errorf("error parsing a valid artifactOf node: %v", err)
66	}
67	if artifact.Name != "Jena" {
68		t.Errorf("expected name of artifact: %s, found: %s", "Jena", artifact.Name)
69	}
70	expectedHomePage := "http://www.openjena.org/"
71	if artifact.HomePage != expectedHomePage {
72		t.Errorf("wrong artifact homepage. Expected: %s, found: %s", expectedHomePage, artifact.HomePage)
73	}
74	if artifact.URI != "" {
75		t.Errorf("wrong artifact URI. Expected: %s, found: %s", "", artifact.URI)
76	}
77
78	// TestCase 2: artifactOf with a Project URI
79	rdfParser, err = parserFromBodyContent(
80		`<spdx:File>
81			<spdx:artifactOf>
82				<doap:Project rdf:about="http://subversion.apache.org/doap.rdf">
83					<doap:homepage>http://www.openjena.org/</doap:homepage>
84					<doap:name>Jena</doap:name>
85				</doap:Project>
86			</spdx:artifactOf>
87		</spdx:File>`)
88	if err != nil {
89		t.Errorf("unexpected error while parsing a valid example: %v", err)
90	}
91	artifactOfNode = gordfWriter.FilterTriples(rdfParser.gordfParserObj.Triples, nil, &SPDX_ARTIFACT_OF, nil)[0].Object
92	artifact, err = rdfParser.getArtifactFromNode(artifactOfNode)
93	if err != nil {
94		t.Errorf("error parsing a valid artifactOf node: %v", err)
95	}
96	expectedURI := "http://subversion.apache.org/doap.rdf"
97	if artifact.URI != expectedURI {
98		t.Errorf("wrong artifact URI. Expected: %s, found: %s", expectedURI, artifact.URI)
99	}
100
101	// TestCase 3: artifactOf with unknown predicate
102	rdfParser, err = parserFromBodyContent(
103		`<spdx:File>
104			<spdx:artifactOf>
105				<doap:Project rdf:about="http://subversion.apache.org/doap.rdf">
106					<doap:homepage>http://www.openjena.org/</doap:homepage>
107					<doap:name>Jena</doap:name>
108					<doap:invalidTag rdf:ID="invalid"/>
109				</doap:Project>
110			</spdx:artifactOf>
111		</spdx:File>`)
112	if err != nil {
113		t.Errorf("unexpected error while parsing a valid example: %v", err)
114	}
115	artifactOfNode = gordfWriter.FilterTriples(rdfParser.gordfParserObj.Triples, nil, &SPDX_ARTIFACT_OF, nil)[0].Object
116	_, err = rdfParser.getArtifactFromNode(artifactOfNode)
117	if err == nil {
118		t.Errorf("must've raised an error for an invalid predicate")
119	}
120}
121
122func Test_rdfParser2_2_getFileTypeFromUri(t *testing.T) {
123	rdfParser, _ := parserFromBodyContent(``)
124
125	// TestCase 1: Valid fileType URI:
126	fileTypeURI := "http://spdx.org/rdf/terms#fileType_source"
127	fileType, err := rdfParser.getFileTypeFromUri(fileTypeURI)
128	if err != nil {
129		t.Errorf("error in a valid example: %v", err)
130	}
131	if fileType != "source" {
132		t.Errorf("wrong fileType. expected: %s, found: %s", "source", fileType)
133	}
134
135	// TestCase 2: Invalid fileType URI format.
136	fileTypeURI = "http://spdx.org/rdf/terms#source"
137	fileType, err = rdfParser.getFileTypeFromUri(fileTypeURI)
138	if err == nil {
139		t.Error("should've raised an error for invalid fileType")
140	}
141}
142
143func Test_rdfParser2_2_setUnpackagedFiles(t *testing.T) {
144	// unpackaged files are the files which are not associated with any package
145	// file associated with a package sets parser.assocWithPackage[fileID] to true.
146	rdfParser, _ := parserFromBodyContent(``)
147	file1 := &v2_2.File{FileSPDXIdentifier: common.ElementID("file1")}
148	file2 := &v2_2.File{FileSPDXIdentifier: common.ElementID("file2")}
149	file3 := &v2_2.File{FileSPDXIdentifier: common.ElementID("file3")}
150
151	// setting files to the document as if it were to be set when it was parsed using triples.
152	rdfParser.files[file1.FileSPDXIdentifier] = file1
153	rdfParser.files[file2.FileSPDXIdentifier] = file2
154	rdfParser.files[file3.FileSPDXIdentifier] = file3
155
156	// assuming file1 is associated with a package
157	rdfParser.assocWithPackage[file1.FileSPDXIdentifier] = true
158
159	rdfParser.setUnpackagedFiles()
160
161	// after setting unpackaged files, parser.doc.Files must've file2 and file3
162	if n := len(rdfParser.doc.Files); n != 2 {
163		t.Errorf("unpackage files should've had 2 files, found %d files", n)
164	}
165
166	// checking if the unpackagedFiles contain only file2 & file3.
167	for _, file := range rdfParser.doc.Files {
168		switch string(file.FileSPDXIdentifier) {
169		case "file2", "file3":
170			continue
171		default:
172			t.Errorf("unexpected file with id %s found in unpackaged files", file.FileSPDXIdentifier)
173		}
174	}
175}
176
177func Test_setFileIdentifier(t *testing.T) {
178	file := &v2_2.File{}
179
180	// TestCase 1: valid example
181	err := setFileIdentifier("http://spdx.org/documents/spdx-toolsv2.1.7-SNAPSHOT#SPDXRef-129", file)
182	if err != nil {
183		t.Errorf("unexpected error: %v", err)
184	}
185	if file.FileSPDXIdentifier != "129" {
186		t.Errorf("expected %s, found: %s", "129", file.FileSPDXIdentifier)
187	}
188
189	// TestCase 2: invalid example
190	err = setFileIdentifier("http://spdx.org/documents/spdx-toolsv2.1.7-SNAPSHOT#129", file)
191	if err == nil {
192		t.Errorf("should've raised an error for an invalid example")
193	}
194}
195
196func Test_rdfParser2_2_setFileChecksumFromNode(t *testing.T) {
197	// TestCase 1: md5 checksum
198	parser, _ := parserFromBodyContent(`
199		<spdx:Checksum>
200			<spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_md5" />
201		    <spdx:checksumValue>d2356e0fe1c0b85285d83c6b2ad51b5f</spdx:checksumValue>
202		</spdx:Checksum>
203    `)
204	checksumNode := gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_CHECKSUM_CAPITALIZED)[0].Subject
205	file := &v2_2.File{}
206	err := parser.setFileChecksumFromNode(file, checksumNode)
207	if err != nil {
208		t.Errorf("error parsing a valid checksum node")
209	}
210	checksumValue := "d2356e0fe1c0b85285d83c6b2ad51b5f"
211	for _, checksum := range file.Checksums {
212		switch checksum.Algorithm {
213		case common.SHA1:
214			if checksum.Value != "" {
215				t.Errorf("incorrectly set sha1, should've been empty")
216			}
217		case common.SHA256:
218			if checksum.Value != "" {
219				t.Errorf("incorrectly set sha256, should've been empty")
220			}
221		case common.MD5:
222			if checksum.Value != checksumValue {
223				t.Errorf("wrong checksum value for md5. Expected: %s, found: %s", checksumValue, checksum.Value)
224			}
225		}
226	}
227
228	// TestCase 2: valid sha1 checksum
229	parser, _ = parserFromBodyContent(`
230		<spdx:Checksum>
231			<spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha1" />
232		    <spdx:checksumValue>d2356e0fe1c0b85285d83c6b2ad51b5f</spdx:checksumValue>
233		</spdx:Checksum>
234    `)
235	checksumNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_CHECKSUM_CAPITALIZED)[0].Subject
236	file = &v2_2.File{}
237	err = parser.setFileChecksumFromNode(file, checksumNode)
238	if err != nil {
239		t.Errorf("error parsing a valid checksum node")
240	}
241	for _, checksum := range file.Checksums {
242		switch checksum.Algorithm {
243		case common.SHA1:
244			if checksum.Value != checksumValue {
245				t.Errorf("wrong checksum value for sha1. Expected: %s, found: %s", checksumValue, checksum.Value)
246			}
247		case common.SHA256:
248			if checksum.Value != "" {
249				t.Errorf("incorrectly set sha256, should've been empty")
250			}
251		case common.MD5:
252			if checksum.Value != checksumValue {
253				t.Errorf("incorrectly set md5, should've been empty")
254			}
255		}
256	}
257
258	// TestCase 3: valid sha256 checksum
259	parser, _ = parserFromBodyContent(`
260		<spdx:Checksum>
261			<spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha256" />
262		    <spdx:checksumValue>d2356e0fe1c0b85285d83c6b2ad51b5f</spdx:checksumValue>
263		</spdx:Checksum>
264    `)
265	checksumNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_CHECKSUM_CAPITALIZED)[0].Subject
266	file = &v2_2.File{}
267	err = parser.setFileChecksumFromNode(file, checksumNode)
268	if err != nil {
269		t.Errorf("error parsing a valid checksum node")
270	}
271	for _, checksum := range file.Checksums {
272		switch checksum.Algorithm {
273		case common.SHA1:
274			if checksum.Value != checksumValue {
275				t.Errorf("incorrectly set sha1, should've been empty")
276			}
277		case common.SHA256:
278			if checksum.Value != checksumValue {
279				t.Errorf("wrong checksum value for sha256. Expected: %s, found: %s", checksumValue, checksum.Value)
280			}
281		case common.MD5:
282			if checksum.Value != checksumValue {
283				t.Errorf("incorrectly set md5, should've been empty")
284			}
285		}
286	}
287
288	// TestCase 4: checksum node without one of the mandatory attributes
289	parser, _ = parserFromBodyContent(`
290		<spdx:Checksum>
291		    <spdx:checksumValue>d2356e0fe1c0b85285d83c6b2ad51b5f</spdx:checksumValue>
292		</spdx:Checksum>
293    `)
294	checksumNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_CHECKSUM_CAPITALIZED)[0].Subject
295	file = &v2_2.File{}
296	err = parser.setFileChecksumFromNode(file, checksumNode)
297	if err == nil {
298		t.Errorf("should've raised an error parsing an invalid checksum node")
299	}
300
301	// TestCase 5: invalid checksum algorithm
302	parser, _ = parserFromBodyContent(`
303		<spdx:Checksum>
304			<spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_md43" />
305		    <spdx:checksumValue>d2356e0fe1c0b85285d83c6b2ad51b5f</spdx:checksumValue>
306		</spdx:Checksum>
307    `)
308	checksumNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_CHECKSUM_CAPITALIZED)[0].Subject
309	file = &v2_2.File{}
310	err = parser.setFileChecksumFromNode(file, checksumNode)
311	if err == nil {
312		t.Errorf("should've raised an error parsing an invalid checksum node")
313	}
314
315	// TestCase 6: valid checksum algorithm which is invalid for file (like md4, md6, sha384, etc.)
316	parser, _ = parserFromBodyContent(`
317		<spdx:Checksum>
318			<spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha2000" />
319		    <spdx:checksumValue>d2356e0fe1c0b85285d83c6b2ad51b5f</spdx:checksumValue>
320		</spdx:Checksum>
321    `)
322	checksumNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_CHECKSUM_CAPITALIZED)[0].Subject
323	file = &v2_2.File{}
324	err = parser.setFileChecksumFromNode(file, checksumNode)
325	if err == nil {
326		t.Errorf("should've raised an error parsing an invalid checksum algorithm for a file")
327	}
328}
329
330func Test_rdfParser2_2_getFileFromNode(t *testing.T) {
331	// TestCase 1: file with invalid id
332	parser, _ := parserFromBodyContent(`
333		<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gzspdx.rdf#item177"/>
334	`)
335	fileNode := gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
336	_, err := parser.getFileFromNode(fileNode)
337	if err == nil {
338		t.Errorf("should've raised an error stating invalid file ID")
339	}
340
341	// TestCase 2: invalid fileType
342	parser, _ = parserFromBodyContent(`
343		<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
344			<spdx:fileType rdf:resource="http://spdx.org/rdf/terms#source"/>
345		</spdx:File>
346	`)
347	fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
348	_, err = parser.getFileFromNode(fileNode)
349	if err == nil {
350		t.Errorf("should've raised an error stating invalid fileType")
351	}
352
353	// TestCase 3: invalid file checksum
354	parser, _ = parserFromBodyContent(`
355		<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
356			<spdx:checksum>
357				<spdx:Checksum>
358					<spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha2000" />
359					<spdx:checksumValue>0a3a0e1ab72b7c132f5021c538a7a3ea6d539bcd</spdx:checksumValue>
360				</spdx:Checksum>
361			</spdx:checksum>
362		</spdx:File>
363	`)
364	fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
365	_, err = parser.getFileFromNode(fileNode)
366	if err == nil {
367		t.Errorf("should've raised an error stating invalid checksum")
368	}
369
370	// TestCase 4: invalid license concluded
371	parser, _ = parserFromBodyContent(`
372		<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
373			<spdx:licenseConcluded rdf:resource="http://spdx.org/rdf/terms#invalid_license" />
374		</spdx:File>
375	`)
376	fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
377	_, err = parser.getFileFromNode(fileNode)
378	if err == nil {
379		t.Errorf("should've raised an error stating invalid license Concluded")
380	}
381
382	// TestCase 5: invalid artifactOf attribute
383	parser, _ = parserFromBodyContent(`
384		<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
385			<spdx:artifactOf>
386				<doap:Project>
387					<doap:unknown_tag />
388					<doap:name>Jena</doap:name>
389				</doap:Project>
390			</spdx:artifactOf>
391		</spdx:File>
392	`)
393	fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
394	_, err = parser.getFileFromNode(fileNode)
395	if err == nil {
396		t.Errorf("should've raised an error stating invalid artifactOf predicate")
397	}
398
399	// TestCase 6: invalid file dependency
400	parser, _ = parserFromBodyContent(`
401		<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
402			<spdx:fileDependency rdf:resource="http://spdx.org/spdxdocs/spdx-example#CommonsLangSrc"/>
403		</spdx:File>
404	`)
405	fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
406	_, err = parser.getFileFromNode(fileNode)
407	if err == nil {
408		t.Errorf("should've raised an error stating invalid fileDependency")
409	}
410
411	// TestCase 7: invalid annotation with unknown predicate
412	parser, _ = parserFromBodyContent(`
413		<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
414			<spdx:annotation>
415				<spdx:Annotation>
416					<spdx:unknownAttribute />
417				</spdx:Annotation>
418			</spdx:annotation>
419		</spdx:File>
420	`)
421	fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
422	_, err = parser.getFileFromNode(fileNode)
423	if err == nil {
424		t.Errorf("should've raised an error stating invalid annotation predicate")
425	}
426
427	// TestCase 8: invalid relationship
428	parser, _ = parserFromBodyContent(`
429		<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
430			<spdx:relationship>
431				<spdx:Relationship>
432					<spdx:relationshipType rdf:resource="http://spdx.org/rdf/terms#dynamicLink"/>
433				</spdx:Relationship>
434			</spdx:relationship>
435		</spdx:File>
436	`)
437	fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
438	_, err = parser.getFileFromNode(fileNode)
439	if err == nil {
440		t.Errorf("should've raised an error stating invalid relationship Type")
441	}
442
443	// TestCase 8: unknown predicate
444	parser, _ = parserFromBodyContent(`
445		<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
446			<spdx:unknown />
447		</spdx:File>
448	`)
449	fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
450	_, err = parser.getFileFromNode(fileNode)
451	if err == nil {
452		t.Error("should've raised an error stating invalid predicate for a file")
453	}
454
455	// TestCase 9: invalid licenseInfoInFile.
456	parser, _ = parserFromBodyContent(`
457		<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
458			<spdx:licenseInfoInFile rdf:resource="http://spdx.org/licenses/DC0-1.0" />
459		</spdx:File>
460	`)
461	fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
462	_, err = parser.getFileFromNode(fileNode)
463	if err == nil {
464		t.Error("should've raised an error stating invalid licenseInfoInFile for a file")
465	}
466
467	// TestCase 10: Splitting of File definition into parents of different tags mustn't create new file objects.
468	fileDefinitions := []string{
469		`<spdx:Package rdf:about="#SPDXRef-Package1">
470			<spdx:hasFile>
471				<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
472					<spdx:fileName>time-1.9/ChangeLog</spdx:fileName>
473					<spdx:fileType rdf:resource="http://spdx.org/rdf/terms#fileType_source"/>
474				</spdx:File>
475			</spdx:hasFile>
476		</spdx:Package>`,
477		`<spdx:Package rdf:about="#SPDXRef-Package2">
478			<spdx:hasFile>
479				<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
480					<spdx:licenseConcluded rdf:resource="http://spdx.org/rdf/terms#noassertion" />
481					<spdx:licenseInfoInFile rdf:resource="http://spdx.org/rdf/terms#NOASSERTION" />
482				</spdx:File>
483			</spdx:hasFile>
484		</spdx:Package>`,
485	}
486	parser, _ = parserFromBodyContent(strings.Join(fileDefinitions, ""))
487
488	var file *v2_2.File
489	packageTypeTriples := gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_PACKAGE)
490	for _, typeTriple := range packageTypeTriples {
491		pkg, err := parser.getPackageFromNode(typeTriple.Subject)
492		if err != nil {
493			t.Errorf("unexpected error parsing a valid package: %v", err)
494		}
495		if n := len(pkg.Files); n != 1 {
496			t.Errorf("expected package to contain exactly 1 file. Found %d files", n)
497		}
498		for _, file = range pkg.Files {
499		}
500	}
501
502	// checking if all the attributes that spanned over a several tags are set in the same variable.
503	expectedFileName := "time-1.9/ChangeLog"
504	if file.FileName != expectedFileName {
505		t.Errorf("expected %s, found %s", expectedFileName, file.FileName)
506	}
507	expectedLicenseConcluded := "NOASSERTION"
508	if file.LicenseConcluded != expectedLicenseConcluded {
509		t.Errorf("expected %s, found %s", expectedLicenseConcluded, file.LicenseConcluded)
510	}
511	expectedFileType := "source"
512	if file.FileTypes[0] != expectedFileType {
513		t.Errorf("expected %s, found %s", expectedFileType, file.FileTypes)
514	}
515	expectedLicenseInfoInFile := "NOASSERTION"
516	if file.LicenseInfoInFiles[0] != expectedLicenseInfoInFile {
517		t.Errorf("expected %s, found %s", expectedLicenseInfoInFile, file.LicenseInfoInFiles[0])
518	}
519
520	// TestCase 12: checking if recursive dependencies are resolved.
521	parser, _ = parserFromBodyContent(`
522		<spdx:File rdf:about="#SPDXRef-ParentFile">
523			<spdx:fileType rdf:resource="http://spdx.org/rdf/terms#fileType_source"/>
524			<spdx:fileDependency>
525				<spdx:File rdf:about="#SPDXRef-ChildFile">
526					<spdx:fileDependency>
527						<spdx:File rdf:about="#SPDXRef-ParentFile">
528							<spdx:fileName>ParentFile</spdx:fileName>
529						</spdx:File>
530					</spdx:fileDependency>
531				</spdx:File>
532			</spdx:fileDependency>
533		</spdx:File>
534	`)
535	fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
536	file, err = parser.getFileFromNode(fileNode)
537
538	// TestCase 11: all valid attribute and it's values.
539	parser, _ = parserFromBodyContent(`
540		<spdx:File rdf:about="http://anupam-VirtualBox/repo/SPDX2_time-1.9.tar.gz_1535120734-spdx.rdf#SPDXRef-item177">
541			<spdx:fileName>time-1.9/ChangeLog</spdx:fileName>
542			<spdx:name/>
543			<spdx:fileType rdf:resource="http://spdx.org/rdf/terms#fileType_source"/>
544			<spdx:checksum>
545				<spdx:Checksum>
546					<spdx:algorithm rdf:resource="http://spdx.org/rdf/terms#checksumAlgorithm_sha1" />
547					<spdx:checksumValue>0a3a0e1ab72b7c132f5021c538a7a3ea6d539bcd</spdx:checksumValue>
548				</spdx:Checksum>
549			</spdx:checksum>
550			<spdx:licenseConcluded rdf:resource="http://spdx.org/rdf/terms#noassertion" />
551			<spdx:licenseInfoInFile rdf:resource="http://spdx.org/rdf/terms#NOASSERTION" />
552			<spdx:licenseComments>no comments</spdx:licenseComments>
553			<spdx:copyrightText>from spdx file</spdx:copyrightText>
554			<spdx:artifactOf>
555				<doap:Project>
556					<doap:homepage>http://www.openjena.org/</doap:homepage>
557					<doap:name>Jena</doap:name>
558				</doap:Project>
559			</spdx:artifactOf>
560			<rdfs:comment>no comments</rdfs:comment>
561			<spdx:noticeText rdf:resource="http://spdx.org/rdf/terms#noassertion"/>
562			<spdx:fileContributor>Some Organization</spdx:fileContributor>
563			<spdx:fileDependency rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-CommonsLangSrc"/>
564			<spdx:attributionText>attribution text</spdx:attributionText>
565			<spdx:annotation>
566				<spdx:Annotation>
567					<spdx:annotationDate>2011-01-29T18:30:22Z</spdx:annotationDate>
568					<rdfs:comment>File level annotation copied from a spdx document</rdfs:comment>
569					<spdx:annotator>Person: File Commenter</spdx:annotator>
570					<spdx:annotationType rdf:resource="http://spdx.org/rdf/terms#annotationType_other"/>
571				</spdx:Annotation>
572			</spdx:annotation>
573			<spdx:relationship>
574				<spdx:Relationship>
575					<spdx:relationshipType rdf:resource="http://spdx.org/rdf/terms#relationshipType_contains"/>
576					<spdx:relatedSpdxElement rdf:resource="http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#SPDXRef-Package"/>
577				</spdx:Relationship>
578			</spdx:relationship>
579		</spdx:File>
580	`)
581	fileNode = gordfWriter.FilterTriples(parser.gordfParserObj.Triples, nil, &RDF_TYPE, &SPDX_FILE)[0].Subject
582	file, err = parser.getFileFromNode(fileNode)
583	if err != nil {
584		t.Errorf("unexpected error parsing a valid file: %v", err)
585	}
586
587	// checking each and every attribute of the obtained file.
588
589	expectedFileName = "time-1.9/ChangeLog"
590	if file.FileName != expectedFileName {
591		t.Errorf("expected %s, found %s", expectedFileName, file.FileName)
592	}
593
594	if len(file.FileTypes) != 1 {
595		t.Errorf("given file should have 1 fileType attribute. found %d", len(file.FileTypes))
596	}
597	expectedFileType = "source"
598	if file.FileTypes[0] != expectedFileType {
599		t.Errorf("expected %s, found %s", expectedFileType, file.FileTypes)
600	}
601
602	expectedChecksum := "0a3a0e1ab72b7c132f5021c538a7a3ea6d539bcd"
603
604	for _, checksum := range file.Checksums {
605		switch checksum.Algorithm {
606		case common.SHA1:
607			if checksum.Value != expectedChecksum {
608				t.Errorf("expected %s, found %s", expectedChecksum, checksum.Value)
609			}
610		}
611	}
612
613	expectedLicenseConcluded = "NOASSERTION"
614	if file.LicenseConcluded != expectedLicenseConcluded {
615		t.Errorf("expected %s, found %s", expectedLicenseConcluded, file.LicenseConcluded)
616	}
617
618	if len(file.LicenseInfoInFiles) != 1 {
619		t.Errorf("given file should have 1 licenseInfoInFile attribute. found %d", len(file.LicenseInfoInFiles))
620	}
621	expectedLicenseInfoInFile = "NOASSERTION"
622	if file.LicenseInfoInFiles[0] != expectedLicenseInfoInFile {
623		t.Errorf("expected %s, found %s", expectedLicenseInfoInFile, file.LicenseInfoInFiles[0])
624	}
625
626	expectedLicenseComments := "no comments"
627	if file.LicenseComments != expectedLicenseComments {
628		t.Errorf("expected %s, found %s", expectedLicenseComments, file.LicenseComments)
629	}
630
631	expectedCopyrightText := "from spdx file"
632	if file.FileCopyrightText != expectedCopyrightText {
633		t.Errorf("expected %s, found %s", expectedCopyrightText, file.FileCopyrightText)
634	}
635
636	if n := len(file.ArtifactOfProjects); n != 1 {
637		t.Errorf("given file should have 1 artifactOfProjects attribute. found %d", n)
638	}
639	artifactOf := file.ArtifactOfProjects[0]
640	expectedHomePage := "http://www.openjena.org/"
641	if artifactOf.HomePage != expectedHomePage {
642		t.Errorf("expected %s, found %s", expectedHomePage, artifactOf.HomePage)
643	}
644	if artifactOf.Name != "Jena" {
645		t.Errorf("expected %s, found %s", "Jena", artifactOf.Name)
646	}
647	if artifactOf.URI != "" {
648		t.Errorf("expected artifactOf uri to be empty, found %s", artifactOf.URI)
649	}
650
651	expectedFileComment := "no comments"
652	if file.FileComment != expectedFileComment {
653		t.Errorf("expected %s, found %s", expectedFileName, file.FileComment)
654	}
655
656	expectedNoticeText := "NOASSERTION"
657	if file.FileNotice != expectedNoticeText {
658		t.Errorf("expected %s, found %s", expectedNoticeText, file.FileNotice)
659	}
660
661	if n := len(file.FileContributors); n != 1 {
662		t.Errorf("given file should have 1 fileContributor. found %d", n)
663	}
664	expectedFileContributor := "Some Organization"
665	if file.FileContributors[0] != expectedFileContributor {
666		t.Errorf("expected %s, found %s", expectedFileContributor, file.FileContributors)
667	}
668
669	if n := len(file.FileDependencies); n != 1 {
670		t.Errorf("given file should have 1 fileDependencies. found %d", n)
671	}
672	expectedFileDependency := "CommonsLangSrc"
673	if file.FileDependencies[0] != expectedFileDependency {
674		t.Errorf("expected %s, found %s", expectedFileDependency, file.FileDependencies[0])
675	}
676
677	if n := len(file.FileAttributionTexts); n != 1 {
678		t.Errorf("given file should have 1 attributionText. found %d", n)
679	}
680	expectedAttributionText := "attribution text"
681	if file.FileAttributionTexts[0] != expectedAttributionText {
682		t.Errorf("expected %s, found %s", expectedAttributionText, file.FileAttributionTexts[0])
683	}
684
685	if n := len(parser.doc.Annotations); n != 1 {
686		t.Errorf("doc should've had 1 annotation. found %d", n)
687	}
688	ann := parser.doc.Annotations[0]
689	expectedAnnDate := "2011-01-29T18:30:22Z"
690	if ann.AnnotationDate != expectedAnnDate {
691		t.Errorf("expected %s, found %s", expectedAnnDate, ann.AnnotationDate)
692	}
693	expectedAnnComment := "File level annotation copied from a spdx document"
694	if ann.AnnotationComment != expectedAnnComment {
695		t.Errorf("expected %s, found %s", expectedAnnComment, ann.AnnotationComment)
696	}
697	expectedAnnotationType := "OTHER"
698	if ann.AnnotationType != expectedAnnotationType {
699		t.Errorf("expected %s, found %s", expectedAnnotationType, ann.AnnotationType)
700	}
701	expectedAnnotator := "File Commenter"
702	if ann.Annotator.Annotator != expectedAnnotator {
703		t.Errorf("expected %s, found %s", expectedAnnotator, ann.Annotator)
704	}
705	expectedAnnotatorType := "Person"
706	if ann.AnnotationType != expectedAnnotationType {
707		t.Errorf("expected %s, found %s", expectedAnnotatorType, ann.Annotator.AnnotatorType)
708	}
709
710	if n := len(parser.doc.Relationships); n != 1 {
711		t.Errorf("doc should've had 1 relation. found %d", n)
712	}
713	reln := parser.doc.Relationships[0]
714	expectedRefAEID := "item177"
715	if reln.RefA.DocumentRefID != "" {
716		t.Errorf("expected refA.DocumentRefID to be empty, found %s", reln.RefA.DocumentRefID)
717	}
718	if string(reln.RefA.ElementRefID) != expectedRefAEID {
719		t.Errorf("expected %s, found %s", expectedRefAEID, reln.RefA.ElementRefID)
720	}
721	expectedRefBEID := "Package"
722	if reln.RefB.DocumentRefID != "" {
723		t.Errorf("expected refB.DocumentRefID to be empty, found %s", reln.RefB.DocumentRefID)
724	}
725	if string(reln.RefB.ElementRefID) != expectedRefBEID {
726		t.Errorf("expected %s, found %s", expectedRefBEID, reln.RefB.ElementRefID)
727	}
728	expectedRelationType := "contains"
729	if reln.Relationship != expectedRelationType {
730		t.Errorf("expected %s, found %s", expectedRefBEID, reln.RefB.ElementRefID)
731	}
732	if reln.RelationshipComment != "" {
733		t.Errorf("expected relationship comment to be empty, found %s", reln.RelationshipComment)
734	}
735}
736
737func Test_getNoticeTextFromNode(t *testing.T) {
738	// TestCase 1: SPDX_NOASSERTION_SMALL must return NOASSERTION
739	output := getNoticeTextFromNode(&gordfParser.Node{
740		NodeType: gordfParser.IRI,
741		ID:       SPDX_NOASSERTION_SMALL,
742	})
743	if strings.ToUpper(output) != "NOASSERTION" {
744		t.Errorf("expected NOASSERTION, found %s", strings.ToUpper(output))
745	}
746
747	// TestCase 2: SPDX_NOASSERTION_CAPS must return NOASSERTION
748	output = getNoticeTextFromNode(&gordfParser.Node{
749		NodeType: gordfParser.IRI,
750		ID:       SPDX_NOASSERTION_CAPS,
751	})
752	if strings.ToUpper(output) != "NOASSERTION" {
753		t.Errorf("expected NOASSERTION, found %s", strings.ToUpper(output))
754	}
755
756	// TestCase 3: not a NOASSERTION must return the field verbatim
757	// TestCase 1: SPDX_NOASSERTION_SMALL must return NOASSERTION
758	output = getNoticeTextFromNode(&gordfParser.Node{
759		NodeType: gordfParser.IRI,
760		ID:       "text",
761	})
762	if output != "text" {
763		t.Errorf("expected text, found %s", output)
764	}
765}
766