github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/syft/formats/common/spdxhelpers/license_test.go (about)

     1  package spdxhelpers
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/spdx/tools-golang/spdx"
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/anchore/syft/internal/spdxlicense"
    12  	"github.com/anchore/syft/syft/pkg"
    13  	"github.com/anchore/syft/syft/sbom"
    14  )
    15  
    16  func Test_License(t *testing.T) {
    17  	type expected struct {
    18  		concluded string
    19  		declared  string
    20  	}
    21  	tests := []struct {
    22  		name     string
    23  		input    pkg.Package
    24  		expected expected
    25  	}{
    26  		{
    27  			name:  "no licenses",
    28  			input: pkg.Package{},
    29  			expected: expected{
    30  				concluded: "NOASSERTION",
    31  				declared:  "NOASSERTION",
    32  			},
    33  		},
    34  		{
    35  			name: "no SPDX licenses",
    36  			input: pkg.Package{
    37  				Licenses: pkg.NewLicenseSet(pkg.NewLicense("made-up")),
    38  			},
    39  			expected: expected{
    40  				concluded: "NOASSERTION",
    41  				declared:  "LicenseRef-made-up",
    42  			},
    43  		},
    44  		{
    45  			name: "with SPDX license",
    46  			input: pkg.Package{
    47  				Licenses: pkg.NewLicenseSet(pkg.NewLicense("MIT")),
    48  			},
    49  			expected: struct {
    50  				concluded string
    51  				declared  string
    52  			}{
    53  				concluded: "NOASSERTION",
    54  				declared:  "MIT",
    55  			},
    56  		},
    57  		{
    58  			name: "with SPDX license expression",
    59  			input: pkg.Package{
    60  				Licenses: pkg.NewLicenseSet(
    61  					pkg.NewLicense("MIT"),
    62  					pkg.NewLicense("GPL-3.0-only"),
    63  				),
    64  			},
    65  			expected: expected{
    66  				concluded: "NOASSERTION",
    67  				// because we sort licenses alphabetically GPL ends up at the start
    68  				declared: "GPL-3.0-only AND MIT",
    69  			},
    70  		},
    71  		{
    72  			name: "includes valid LicenseRef-",
    73  			input: pkg.Package{
    74  				Licenses: pkg.NewLicenseSet(
    75  					pkg.NewLicense("one thing first"),
    76  					pkg.NewLicense("two things/#$^second"),
    77  					pkg.NewLicense("MIT"),
    78  				),
    79  			},
    80  			expected: expected{
    81  				concluded: "NOASSERTION",
    82  				// because we separate licenses between valid SPDX and non valid, valid ID always end at the front
    83  				declared: "MIT AND LicenseRef-one-thing-first AND LicenseRef-two-things----second",
    84  			},
    85  		},
    86  		{
    87  			name: "join parentheses correctly",
    88  			input: pkg.Package{
    89  				Licenses: pkg.NewLicenseSet(
    90  					pkg.NewLicense("one thing first"),
    91  					pkg.NewLicense("MIT AND GPL-3.0-only"),
    92  					pkg.NewLicense("MIT OR APACHE-2.0"),
    93  				),
    94  			},
    95  			expected: expected{
    96  				concluded: "NOASSERTION",
    97  				// because we separate licenses between valid SPDX and non valid, valid ID always end at the front
    98  				declared: "(MIT AND GPL-3.0-only) AND (MIT OR APACHE-2.0) AND LicenseRef-one-thing-first",
    99  			},
   100  		},
   101  	}
   102  	for _, test := range tests {
   103  		t.Run(test.name, func(t *testing.T) {
   104  			c, d := License(test.input)
   105  			assert.Equal(t, test.expected.concluded, c)
   106  			assert.Equal(t, test.expected.declared, d)
   107  		})
   108  	}
   109  }
   110  
   111  func Test_otherLicenses(t *testing.T) {
   112  	pkg1 := pkg.Package{
   113  		Name:    "first-pkg",
   114  		Version: "1.1",
   115  		Licenses: pkg.NewLicenseSet(
   116  			pkg.NewLicense("MIT"),
   117  		),
   118  	}
   119  	pkg2 := pkg.Package{
   120  		Name:    "second-pkg",
   121  		Version: "2.2",
   122  		Licenses: pkg.NewLicenseSet(
   123  			pkg.NewLicense("non spdx license"),
   124  		),
   125  	}
   126  	bigText := `
   127                                   Apache License
   128                             Version 2.0, January 2004`
   129  	pkg3 := pkg.Package{
   130  		Name:    "third-pkg",
   131  		Version: "3.3",
   132  		Licenses: pkg.NewLicenseSet(
   133  			pkg.NewLicense(bigText),
   134  		),
   135  	}
   136  
   137  	tests := []struct {
   138  		name     string
   139  		packages []pkg.Package
   140  		expected []*spdx.OtherLicense
   141  	}{
   142  		{
   143  			name:     "no other licenses when all valid spdx expressions",
   144  			packages: []pkg.Package{pkg1},
   145  			expected: nil,
   146  		},
   147  		{
   148  			name:     "other licenses includes original text",
   149  			packages: []pkg.Package{pkg2},
   150  			expected: []*spdx.OtherLicense{
   151  				{
   152  					LicenseIdentifier: "LicenseRef-non-spdx-license",
   153  					ExtractedText:     "non spdx license",
   154  				},
   155  			},
   156  		},
   157  		{
   158  			name:     "big licenses get hashed",
   159  			packages: []pkg.Package{pkg3},
   160  			expected: []*spdx.OtherLicense{
   161  				{
   162  					LicenseIdentifier: "LicenseRef-e9a1e42833d3e456f147052f4d312101bd171a0798893169fe596ca6b55c049e",
   163  					ExtractedText:     bigText,
   164  				},
   165  			},
   166  		},
   167  	}
   168  
   169  	for _, test := range tests {
   170  		t.Run(test.name, func(t *testing.T) {
   171  			s := sbom.SBOM{
   172  				Artifacts: sbom.Artifacts{
   173  					Packages: pkg.NewCollection(test.packages...),
   174  				},
   175  			}
   176  			got := ToFormatModel(s)
   177  			require.Equal(t, test.expected, got.OtherLicenses)
   178  		})
   179  	}
   180  }
   181  
   182  func Test_joinLicenses(t *testing.T) {
   183  	tests := []struct {
   184  		name string
   185  		args []string
   186  		want string
   187  	}{
   188  		{
   189  			name: "multiple licenses",
   190  			args: []string{"MIT", "GPL-3.0-only"},
   191  			want: "MIT AND GPL-3.0-only",
   192  		},
   193  		{
   194  			name: "multiple licenses with complex expressions",
   195  			args: []string{"MIT AND Apache", "GPL-3.0-only"},
   196  			want: "(MIT AND Apache) AND GPL-3.0-only",
   197  		},
   198  	}
   199  	for _, tt := range tests {
   200  		t.Run(tt.name, func(t *testing.T) {
   201  			assert.Equalf(t, tt.want, joinLicenses(toSpdxLicenses(tt.args)), "joinLicenses(%v)", tt.args)
   202  		})
   203  	}
   204  }
   205  
   206  func toSpdxLicenses(ids []string) (licenses []spdxLicense) {
   207  	for _, l := range ids {
   208  		license := spdxLicense{id: l}
   209  		if strings.HasPrefix(l, spdxlicense.LicenseRefPrefix) {
   210  			license.value = l
   211  		}
   212  		licenses = append(licenses, license)
   213  	}
   214  	return licenses
   215  }