github.com/CycloneDX/sbom-utility@v0.16.0/cmd/license_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  /*
     3   * Licensed to the Apache Software Foundation (ASF) under one or more
     4   * contributor license agreements.  See the NOTICE file distributed with
     5   * this work for additional information regarding copyright ownership.
     6   * The ASF licenses this file to You under the Apache License, Version 2.0
     7   * (the "License"); you may not use this file except in compliance with
     8   * the License.  You may obtain a copy of the License at
     9   *
    10   *     http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package cmd
    20  
    21  import (
    22  	"bufio"
    23  	"bytes"
    24  	"io/fs"
    25  	"testing"
    26  
    27  	"github.com/CycloneDX/sbom-utility/common"
    28  	"github.com/CycloneDX/sbom-utility/schema"
    29  	"github.com/CycloneDX/sbom-utility/utils"
    30  )
    31  
    32  const (
    33  	// Test "license list" command
    34  	TEST_LICENSE_LIST_CDX_1_3                         = "test/cyclonedx/cdx-1-3-license-list.json"
    35  	TEST_LICENSE_LIST_CDX_1_3_NONE_FOUND              = "test/cyclonedx/cdx-1-3-license-list-none-found.json"
    36  	TEST_LICENSE_LIST_CDX_1_4_NONE_FOUND              = "test/cyclonedx/cdx-1-4-license-list-none-found.json"
    37  	TEST_LICENSE_LIST_CDX_1_5_LICENSE_CHOICE_VARIANTS = "test/cyclonedx/cdx-1-5-license-choice-variants.json"
    38  
    39  	TEST_LICENSE_LIST_TEXT_CDX_1_4_INVALID_LICENSE_ID    = "test/cyclonedx/cdx-1-4-license-policy-invalid-spdx-id.json"
    40  	TEST_LICENSE_LIST_TEXT_CDX_1_4_INVALID_LICENSE_NAME  = "test/cyclonedx/cdx-1-4-license-policy-invalid-license-name.json"
    41  	TEST_LICENSE_LIST_CDX_1_4_LICENSE_EXPRESSION_IN_NAME = "test/cyclonedx/cdx-1-4-license-expression-in-name.json"
    42  )
    43  
    44  type LicenseTestInfo struct {
    45  	CommonTestInfo
    46  	ListLineWrap bool
    47  	PolicyFile   string // Note: if not filled in, uses default file: DEFAULT_LICENSE_POLICIES
    48  }
    49  
    50  func (ti *LicenseTestInfo) String() string {
    51  	buffer, _ := utils.EncodeAnyToDefaultIndentedJSONStr(ti)
    52  	return buffer.String()
    53  }
    54  
    55  func NewLicenseTestInfo(inputFile string, listFormat string, listSummary bool) *LicenseTestInfo {
    56  	var ti = new(LicenseTestInfo)
    57  	var pCommon = &ti.CommonTestInfo
    58  	pCommon.InitBasic(inputFile, listFormat, nil)
    59  	ti.ListSummary = listSummary
    60  	return ti
    61  }
    62  
    63  // -------------------------------------------
    64  // license test helper functions
    65  // -------------------------------------------
    66  
    67  func innerTestLicenseListBuffered(testInfo *LicenseTestInfo, whereFilters []common.WhereFilter) (outputBuffer bytes.Buffer, err error) {
    68  	// Declare an output outputBuffer/outputWriter to use used during tests
    69  	var outputWriter = bufio.NewWriter(&outputBuffer)
    70  	// MUST ensure all data is written to buffer before further validation
    71  	defer outputWriter.Flush()
    72  
    73  	// Use a test input SBOM formatted in SPDX
    74  	utils.GlobalFlags.PersistentFlags.InputFile = testInfo.InputFile
    75  	utils.GlobalFlags.PersistentFlags.OutputFormat = testInfo.OutputFormat
    76  	utils.GlobalFlags.PersistentFlags.OutputFile = testInfo.OutputFile
    77  	utils.GlobalFlags.PersistentFlags.OutputIndent = testInfo.OutputIndent
    78  	utils.GlobalFlags.LicenseFlags.Summary = testInfo.ListSummary
    79  
    80  	// set license policy config. per-test
    81  	var policyConfig *schema.LicensePolicyConfig = LicensePolicyConfig
    82  	if testInfo.PolicyFile != "" && testInfo.PolicyFile != DEFAULT_LICENSE_POLICY_CONFIG {
    83  		policyConfig = new(schema.LicensePolicyConfig)
    84  		err = policyConfig.LoadHashPolicyConfigurationFile(testInfo.PolicyFile, "")
    85  		if err != nil {
    86  			getLogger().Warningf("unable to load policy configuration file: %v", err.Error())
    87  			return
    88  		}
    89  	}
    90  
    91  	// Invoke the actual List command (API)
    92  	err = ListLicenses(outputWriter, policyConfig, utils.GlobalFlags.PersistentFlags, utils.GlobalFlags.LicenseFlags, whereFilters)
    93  
    94  	return
    95  }
    96  
    97  func innerTestLicenseList(t *testing.T, testInfo *LicenseTestInfo) (outputBuffer bytes.Buffer) {
    98  
    99  	// Parse out --where filters and exit out if error detected
   100  	whereFilters, err := prepareWhereFilters(t, &testInfo.CommonTestInfo)
   101  	if err != nil {
   102  		return
   103  	}
   104  
   105  	// Perform the test with buffered output
   106  	outputBuffer, err = innerTestLicenseListBuffered(testInfo, whereFilters)
   107  	if err != nil {
   108  		getLogger().Tracef("%s", err)
   109  		return
   110  	}
   111  
   112  	// Run all common tests against "result" values in the CommonTestInfo struct
   113  	err = innerRunReportResultTests(t, &testInfo.CommonTestInfo, outputBuffer, err)
   114  	if err != nil {
   115  		getLogger().Tracef("%s", err)
   116  		return
   117  	}
   118  
   119  	return
   120  }
   121  
   122  func innerTestLicenseExpressionParsing(t *testing.T, expression string, expectedPolicy string) (parsedExpression *schema.CompoundExpression) {
   123  	var err error
   124  	parsedExpression, err = schema.ParseExpression(LicensePolicyConfig, expression)
   125  	if err != nil {
   126  		t.Errorf("unable to parse expression: `%s`\n", expression)
   127  	}
   128  
   129  	getLogger().Infof("expression:\n%v", parsedExpression)
   130  	if parsedExpression.CompoundUsagePolicy != expectedPolicy {
   131  		t.Errorf("License Expression: expected `%s`, actual `%s`\n",
   132  			expectedPolicy, parsedExpression.CompoundUsagePolicy)
   133  	}
   134  	return
   135  }
   136  
   137  // ----------------------------------------
   138  // Command flag tests
   139  // ----------------------------------------
   140  
   141  func TestLicenseListInvalidInputFileLoad(t *testing.T) {
   142  	lti := NewLicenseTestInfo(TEST_INPUT_FILE_NON_EXISTENT, FORMAT_DEFAULT, false)
   143  	lti.ResultExpectedError = &fs.PathError{}
   144  	innerTestLicenseList(t, lti)
   145  }
   146  
   147  // -------------------------------------------
   148  // Test format unsupported (SPDX)
   149  // -------------------------------------------
   150  func TestLicenseListFormatUnsupportedSPDX1(t *testing.T) {
   151  	lti := NewLicenseTestInfo(TEST_SPDX_2_2_MIN_REQUIRED, FORMAT_DEFAULT, false)
   152  	lti.ResultExpectedError = &schema.UnsupportedFormatError{}
   153  	innerTestLicenseList(t, lti)
   154  }
   155  
   156  func TestLicenseListFormatUnsupportedSPDX2(t *testing.T) {
   157  	lti := NewLicenseTestInfo(TEST_SPDX_2_2_EXAMPLE_1, FORMAT_DEFAULT, false)
   158  	lti.ResultExpectedError = &schema.UnsupportedFormatError{}
   159  	innerTestLicenseList(t, lti)
   160  }
   161  
   162  //---------------------------
   163  // Test LicenseChoice variants
   164  // - for all formats
   165  //---------------------------
   166  
   167  func TestLicenseListCdx15VariantsJSON(t *testing.T) {
   168  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_5_LICENSE_CHOICE_VARIANTS, FORMAT_JSON, false)
   169  	innerTestLicenseList(t, lti)
   170  }
   171  
   172  func TestLicenseListCdx15VariantsText(t *testing.T) {
   173  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_5_LICENSE_CHOICE_VARIANTS, FORMAT_TEXT, false)
   174  	innerTestLicenseList(t, lti)
   175  }
   176  
   177  func TestLicenseListCdx15VariantsCSV(t *testing.T) {
   178  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_5_LICENSE_CHOICE_VARIANTS, FORMAT_CSV, false)
   179  	innerTestLicenseList(t, lti)
   180  }
   181  
   182  func TestLicenseListCdx15VariantsMarkdown(t *testing.T) {
   183  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_5_LICENSE_CHOICE_VARIANTS, FORMAT_MARKDOWN, false)
   184  	innerTestLicenseList(t, lti)
   185  }
   186  
   187  // ---------------------------
   188  // Raw output tests
   189  // ---------------------------
   190  
   191  // Verify "license list" command finds all licenses regardless of where they
   192  // are declared in schema (e.g., metadata.component, components list, service list, etc.)
   193  // Note: this includes licenses in ANY hierarchical nesting of components as well.
   194  func TestLicenseListCdx13JsonNoneFound(t *testing.T) {
   195  	// Test CDX 1.3 document
   196  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_3_NONE_FOUND, FORMAT_JSON, false)
   197  	lti.ResultExpectedLineCount = 2 // null (valid json) + newline
   198  	innerTestLicenseList(t, lti)
   199  }
   200  
   201  func TestLicenseListCdx14JsonNoneFound(t *testing.T) {
   202  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_4_NONE_FOUND, FORMAT_JSON, false)
   203  	lti.ResultExpectedLineCount = 2 // null (valid json) + newline
   204  	innerTestLicenseList(t, lti)
   205  }
   206  
   207  func TestLicenseListCdx13CsvNoneFound(t *testing.T) {
   208  	// Test CDX 1.3 document
   209  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_3_NONE_FOUND, FORMAT_CSV, false)
   210  	lti.ResultExpectedLineCount = 13 // title only + 11 UNDEFINED + newline
   211  	innerTestLicenseList(t, lti)
   212  }
   213  
   214  func TestLicenseListCdx14CsvNoneFound(t *testing.T) {
   215  	// Test CDX 1.4 document
   216  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_4_NONE_FOUND, FORMAT_CSV, false)
   217  	lti.ResultExpectedLineCount = 4 // title only + 2 UNDEFINED + newline
   218  	innerTestLicenseList(t, lti)
   219  }
   220  
   221  func TestLicenseListCdx13MarkdownNoneFound(t *testing.T) {
   222  	// Test CDX 1.3 document
   223  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_3_NONE_FOUND, FORMAT_MARKDOWN, false)
   224  	lti.ResultExpectedLineCount = 14 // title only + alignment row + 11 UNDEFINED + newline
   225  	innerTestLicenseList(t, lti)
   226  }
   227  
   228  func TestLicenseListCdx14MarkdownNoneFound(t *testing.T) {
   229  	// Test CDX 1.4 document
   230  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_4_NONE_FOUND, FORMAT_MARKDOWN, false)
   231  	lti.ResultExpectedLineCount = 5 // title + alignment row + 2 UNDEFINED + newline
   232  	innerTestLicenseList(t, lti)
   233  }
   234  
   235  func TestLicenseListCdx13Json(t *testing.T) {
   236  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_3, FORMAT_JSON, false)
   237  	lti.ResultExpectedLineCount = 93 // array of LicenseChoice JSON objects + newline
   238  	lti.OutputIndent = 6
   239  	lti.ResultExpectedIndentLength = int(lti.OutputIndent)
   240  	lti.ResultExpectedIndentAtLineNum = 1
   241  	buffer := innerTestLicenseList(t, lti)
   242  	lti.ResultExpectedIndentLength = int(lti.OutputIndent) * 2
   243  	lti.ResultExpectedIndentAtLineNum = 2
   244  	verifyFileLineCountAndIndentation(t, buffer, &lti.CommonTestInfo)
   245  }
   246  
   247  // NOTE: non-summary
   248  func TestLicenseListCdx13Text(t *testing.T) {
   249  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_3, FORMAT_TEXT, false)
   250  	// lti.ResultExpectedLineCount = 93 // array of LicenseChoice JSON objects + newline
   251  	// lti.OutputIndent = 6
   252  	// lti.ResultExpectedIndentLength = int(lti.OutputIndent)
   253  	// lti.ResultExpectedIndentAtLineNum = 1
   254  	innerTestLicenseList(t, lti)
   255  }
   256  
   257  //---------------------------
   258  // Summary flag tests
   259  //---------------------------
   260  
   261  // Assure listing (report) works with summary flag (i.e., format: "txt")
   262  func TestLicenseListSummaryCdx13Text(t *testing.T) {
   263  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_3, FORMAT_TEXT, true)
   264  	lti.ResultExpectedLineCount = 21 // title, separator and data rows + newline
   265  	innerTestLicenseList(t, lti)
   266  }
   267  
   268  func TestLicenseListSummaryCdx13Markdown(t *testing.T) {
   269  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_3, FORMAT_MARKDOWN, true)
   270  	lti.ResultExpectedLineCount = 21 // title, separator and data rows + newline
   271  	innerTestLicenseList(t, lti)
   272  }
   273  
   274  func TestLicenseListSummaryCdx13Csv(t *testing.T) {
   275  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_3, FORMAT_CSV, true)
   276  	lti.ResultExpectedLineCount = 20 // title and data rows + newline
   277  	innerTestLicenseList(t, lti)
   278  }
   279  
   280  func TestLicenseListTextSummaryCdx14TextContainsUndefined(t *testing.T) {
   281  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_4_NONE_FOUND, FORMAT_TEXT, true)
   282  	lti.ResultExpectedLineCount = 5 // 2 title, 2 with UNDEFINED + newline
   283  	unknownLCValue := schema.GetLicenseChoiceTypeName(schema.LC_LOC_UNKNOWN)
   284  	lti.ResultLineContainsValues = []string{schema.POLICY_UNDEFINED, unknownLCValue, LICENSE_NO_ASSERTION, "package-lock.json"}
   285  	lti.ResultLineContainsValuesAtLineNum = 3
   286  	innerTestLicenseList(t, lti)
   287  }
   288  
   289  func TestLicenseListPolicyCdx14InvalidLicenseId(t *testing.T) {
   290  	TEST_LICENSE_ID_OR_NAME := "foo"
   291  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_TEXT_CDX_1_4_INVALID_LICENSE_ID, FORMAT_TEXT, true)
   292  	lti.ResultLineContainsValues = []string{schema.POLICY_UNDEFINED, schema.LC_VALUE_ID, TEST_LICENSE_ID_OR_NAME}
   293  	lti.ResultLineContainsValuesAtLineNum = 3
   294  	innerTestLicenseList(t, lti)
   295  }
   296  
   297  func TestLicenseListPolicyCdx14InvalidLicenseName(t *testing.T) {
   298  	TEST_LICENSE_ID_OR_NAME := "bar"
   299  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_TEXT_CDX_1_4_INVALID_LICENSE_NAME, FORMAT_TEXT, true)
   300  	lti.ResultLineContainsValues = []string{schema.POLICY_UNDEFINED, schema.LC_VALUE_NAME, TEST_LICENSE_ID_OR_NAME}
   301  	lti.ResultLineContainsValuesAtLineNum = 3
   302  	innerTestLicenseList(t, lti)
   303  }
   304  
   305  // ---------------------------
   306  // Where filter tests
   307  // ---------------------------
   308  func TestLicenseListSummaryTextCdx13WhereUsageNeedsReview(t *testing.T) {
   309  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_3, FORMAT_TEXT, true)
   310  	lti.WhereClause = "usage-policy=needs-review"
   311  	lti.ResultExpectedLineCount = 9 // title and data rows
   312  	innerTestLicenseList(t, lti)
   313  }
   314  
   315  func TestLicenseListSummaryTextCdx13WhereUsageUndefined(t *testing.T) {
   316  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_3, FORMAT_TEXT, true)
   317  	lti.WhereClause = "usage-policy=UNDEFINED"
   318  	lti.ResultExpectedLineCount = 5 // title and data rows
   319  	innerTestLicenseList(t, lti)
   320  }
   321  
   322  func TestLicenseListSummaryTextCdx13WhereLicenseTypeName(t *testing.T) {
   323  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_CDX_1_3, FORMAT_TEXT, true)
   324  	lti.WhereClause = "license-type=name"
   325  	lti.ResultExpectedLineCount = 9 // title and data rows
   326  	innerTestLicenseList(t, lti)
   327  }
   328  
   329  func TestLicenseListSummaryTextCdx14LicenseExpInName(t *testing.T) {
   330  	lti := NewLicenseTestInfo(
   331  		TEST_LICENSE_LIST_CDX_1_4_LICENSE_EXPRESSION_IN_NAME,
   332  		FORMAT_TEXT, true)
   333  	lti.WhereClause = "license-type=name"
   334  	lti.ResultLineContainsValues = []string{schema.POLICY_UNDEFINED, "BSD-3-Clause OR MIT"}
   335  	lti.ResultLineContainsValuesAtLineNum = 3
   336  	lti.ResultExpectedLineCount = 5 // title and data rows
   337  	innerTestLicenseList(t, lti)
   338  }
   339  
   340  // Test custom marshal of CDXLicense (empty CDXAttachment)
   341  func TestLicenseListCdx13JsonEmptyAttachment(t *testing.T) {
   342  	lti := NewLicenseTestInfo(
   343  		"test/cyclonedx/cdx-1-3-license-list-no-attachment.json",
   344  		FORMAT_JSON,
   345  		false)
   346  	lti.ResultExpectedLineCount = 37
   347  	lti.ResultLineContainsValues = []string{"\"content\": \"CiAgICAgICAgICAgICA...\""}
   348  	lti.ResultLineContainsValuesAtLineNum = -1 // JSON Hashmaps in Go are not ordered, match any line
   349  	innerTestLicenseList(t, lti)
   350  }
   351  
   352  // Tests for expression parser
   353  func TestLicenseExpressionParsingTestComplex1(t *testing.T) {
   354  	SPDX_LICENSE_EXPRESSION_TEST1 := "Apache-2.0 AND (MIT OR GPL-2.0-only)"
   355  	EXPECTED_POLICY := schema.POLICY_ALLOW
   356  	result := innerTestLicenseExpressionParsing(t, SPDX_LICENSE_EXPRESSION_TEST1, EXPECTED_POLICY)
   357  	if result.LeftUsagePolicy != schema.POLICY_ALLOW && result.RightUsagePolicy != schema.POLICY_ALLOW {
   358  		t.Errorf("License Expression: expectedLeft `%s`, actualLeft `%s`, expectedRight `%s`, actualRight `%s`\n",
   359  			schema.POLICY_ALLOW, result.LeftUsagePolicy, schema.POLICY_ALLOW, result.RightUsagePolicy)
   360  	}
   361  }
   362  
   363  func TestLicenseExpressionParsingTestComplex2(t *testing.T) {
   364  	SPDX_LICENSE_EXPRESSION_TEST1 := "MPL-1.0 AND (MIT AND AGPL-3.0)"
   365  	EXPECTED_POLICY := schema.POLICY_NEEDS_REVIEW
   366  	result := innerTestLicenseExpressionParsing(t, SPDX_LICENSE_EXPRESSION_TEST1, EXPECTED_POLICY)
   367  	if result.LeftUsagePolicy != schema.POLICY_ALLOW && result.RightUsagePolicy != schema.POLICY_ALLOW {
   368  		t.Errorf("License Expression: expectedLeft `%s`, actualLeft `%s`, expectedRight `%s`, actualRight `%s`\n",
   369  			schema.POLICY_ALLOW, result.LeftUsagePolicy, schema.POLICY_ALLOW, result.RightUsagePolicy)
   370  	}
   371  }
   372  
   373  func TestLicenseExpressionParsingCompoundRightSide(t *testing.T) {
   374  	EXP := "Apache-2.0 AND (MIT OR GPL-2.0-only )"
   375  	EXPECTED_POLICY := schema.POLICY_ALLOW
   376  	innerTestLicenseExpressionParsing(t, EXP, EXPECTED_POLICY)
   377  }
   378  
   379  func TestLicenseExpressionCompoundLeftSide(t *testing.T) {
   380  	EXP := "(Apache-1.0 OR Apache-1.1 ) AND 0BSD"
   381  	EXPECTED_POLICY := schema.POLICY_ALLOW
   382  	innerTestLicenseExpressionParsing(t, EXP, EXPECTED_POLICY)
   383  }
   384  
   385  // Test license expression entirely inside a logical group (i.e., outer parens)
   386  func TestLicenseExpressionSingleCompoundAllow(t *testing.T) {
   387  	EXP := "(MIT OR CC0-1.0)"
   388  	EXPECTED_POLICY := schema.POLICY_ALLOW
   389  	innerTestLicenseExpressionParsing(t, EXP, EXPECTED_POLICY)
   390  }
   391  
   392  func TestLicenseExpressionSingleCompoundUndefinedBoth(t *testing.T) {
   393  	EXP := "(FOO OR BAR)"
   394  	EXPECTED_POLICY := schema.POLICY_UNDEFINED
   395  	innerTestLicenseExpressionParsing(t, EXP, EXPECTED_POLICY)
   396  }
   397  
   398  func TestLicenseExpressionSingleCompoundUndefinedLeft(t *testing.T) {
   399  	EXP := "(FOO OR MIT)"
   400  	EXPECTED_POLICY := schema.POLICY_ALLOW
   401  	innerTestLicenseExpressionParsing(t, EXP, EXPECTED_POLICY)
   402  }
   403  
   404  func TestLicenseExpressionSingleCompoundUndefinedRight(t *testing.T) {
   405  	EXP := "(MIT OR BAR)"
   406  	EXPECTED_POLICY := schema.POLICY_ALLOW
   407  	innerTestLicenseExpressionParsing(t, EXP, EXPECTED_POLICY)
   408  }
   409  
   410  func TestLicenseExpressionSingleCompoundInvalid(t *testing.T) {
   411  	EXP := "()"
   412  	EXPECTED_POLICY := schema.POLICY_UNDEFINED
   413  	innerTestLicenseExpressionParsing(t, EXP, EXPECTED_POLICY)
   414  }
   415  
   416  func TestLicenseExpressionSingleCompoundInvalidAND(t *testing.T) {
   417  	EXP := "AND"
   418  	EXPECTED_POLICY := schema.POLICY_UNDEFINED
   419  	innerTestLicenseExpressionParsing(t, EXP, EXPECTED_POLICY)
   420  }
   421  
   422  func TestLicenseExpressionSingleCompoundInvalidOR(t *testing.T) {
   423  	EXP := "OR"
   424  	EXPECTED_POLICY := schema.POLICY_UNDEFINED
   425  	innerTestLicenseExpressionParsing(t, EXP, EXPECTED_POLICY)
   426  }
   427  
   428  func TestLicenseExpressionSingleCompoundInvalidAND2(t *testing.T) {
   429  	EXP := "AND GPL-2.0-only"
   430  	EXPECTED_POLICY := schema.POLICY_UNDEFINED
   431  	innerTestLicenseExpressionParsing(t, EXP, EXPECTED_POLICY)
   432  }
   433  
   434  func TestLicenseExpressionSingleCompoundInvalidOR2(t *testing.T) {
   435  	EXP := "OR GPL-2.0-only"
   436  	EXPECTED_POLICY := schema.POLICY_NEEDS_REVIEW
   437  	innerTestLicenseExpressionParsing(t, EXP, EXPECTED_POLICY)
   438  }
   439  
   440  // ---------------------------
   441  // License Policy Config tests
   442  // ---------------------------
   443  const (
   444  	// Test custom license policy (with license expression)
   445  	TEST_CUSTOM_POLICY_1                           = "test/policy/license-policy-expression-outer-parens.policy.json"
   446  	TEST_LICENSE_LIST_TEXT_CDX_1_4_CUSTOM_POLICY_1 = "test/policy/license-policy-expression-outer-parens.bom.json"
   447  )
   448  
   449  // TODO: uncomment once we have a means to dynamically pass in the license config. object
   450  func TestLicenseListPolicyCdx14CustomPolicy(t *testing.T) {
   451  	TEST_LICENSE_ID_OR_NAME := "(MIT OR CC0-1.0)"
   452  
   453  	lti := NewLicenseTestInfo(TEST_LICENSE_LIST_TEXT_CDX_1_4_CUSTOM_POLICY_1, FORMAT_TEXT, true)
   454  	lti.ResultLineContainsValues = []string{schema.POLICY_ALLOW, schema.LC_VALUE_EXPRESSION, TEST_LICENSE_ID_OR_NAME}
   455  	lti.ResultLineContainsValuesAtLineNum = 2
   456  	lti.PolicyFile = TEST_CUSTOM_POLICY_1
   457  
   458  	// Load a custom policy file ONLY for the specific unit test
   459  	innerTestLicenseList(t, lti)
   460  }