github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/analyzer/language/nodejs/npm/npm_test.go (about)

     1  package npm
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"sort"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/devseccon/trivy/pkg/fanal/analyzer"
    13  	"github.com/devseccon/trivy/pkg/fanal/types"
    14  	"github.com/devseccon/trivy/pkg/log"
    15  )
    16  
    17  func TestMain(m *testing.M) {
    18  	_ = log.InitLogger(false, true)
    19  	os.Exit(m.Run())
    20  }
    21  
    22  func Test_npmLibraryAnalyzer_Analyze(t *testing.T) {
    23  	tests := []struct {
    24  		name string
    25  		dir  string
    26  		want *analyzer.AnalysisResult
    27  	}{
    28  		{
    29  			name: "with node_modules",
    30  			dir:  "testdata/happy",
    31  			want: &analyzer.AnalysisResult{
    32  				Applications: []types.Application{
    33  					{
    34  						Type:     types.Npm,
    35  						FilePath: "package-lock.json",
    36  						Libraries: types.Packages{
    37  							{
    38  								ID:       "ansi-colors@3.2.3",
    39  								Name:     "ansi-colors",
    40  								Version:  "3.2.3",
    41  								Dev:      true,
    42  								Indirect: true,
    43  								Locations: []types.Location{
    44  									{
    45  										StartLine: 6,
    46  										EndLine:   11,
    47  									},
    48  								},
    49  							},
    50  							{
    51  								ID:       "array-flatten@1.1.1",
    52  								Name:     "array-flatten",
    53  								Version:  "1.1.1",
    54  								Indirect: true,
    55  								Locations: []types.Location{
    56  									{
    57  										StartLine: 12,
    58  										EndLine:   16,
    59  									},
    60  								},
    61  							},
    62  							{
    63  								ID:        "body-parser@1.18.3",
    64  								Name:      "body-parser",
    65  								Version:   "1.18.3",
    66  								Indirect:  true,
    67  								DependsOn: []string{"debug@2.6.9"},
    68  								Licenses:  []string{"MIT"},
    69  								Locations: []types.Location{
    70  									{
    71  										StartLine: 17,
    72  										EndLine:   39,
    73  									},
    74  								},
    75  							},
    76  							{
    77  								ID:        "debug@2.6.9",
    78  								Name:      "debug",
    79  								Version:   "2.6.9",
    80  								Indirect:  true,
    81  								DependsOn: []string{"ms@2.0.0"},
    82  								Licenses:  []string{"MIT"},
    83  								Locations: []types.Location{
    84  									{
    85  										StartLine: 25,
    86  										EndLine:   32,
    87  									},
    88  									{
    89  										StartLine: 48,
    90  										EndLine:   55,
    91  									},
    92  								},
    93  							},
    94  							{
    95  								ID:        "express@4.16.4",
    96  								Name:      "express",
    97  								Version:   "4.16.4",
    98  								Indirect:  true,
    99  								DependsOn: []string{"debug@2.6.9"},
   100  								Licenses:  []string{"MIT"},
   101  								Locations: []types.Location{
   102  									{
   103  										StartLine: 40,
   104  										EndLine:   62,
   105  									},
   106  								},
   107  							},
   108  							{
   109  								ID:       "ms@2.0.0",
   110  								Name:     "ms",
   111  								Version:  "2.0.0",
   112  								Indirect: true,
   113  								Licenses: []string{"MIT"},
   114  								Locations: []types.Location{
   115  									{
   116  										StartLine: 33,
   117  										EndLine:   37,
   118  									},
   119  									{
   120  										StartLine: 56,
   121  										EndLine:   60,
   122  									},
   123  								},
   124  							},
   125  							{
   126  								ID:       "ms@2.1.1",
   127  								Name:     "ms",
   128  								Version:  "2.1.1",
   129  								Indirect: true,
   130  								Licenses: []string{"MIT"},
   131  								Locations: []types.Location{
   132  									{
   133  										StartLine: 63,
   134  										EndLine:   67,
   135  									},
   136  								},
   137  							},
   138  						},
   139  					},
   140  				},
   141  			},
   142  		},
   143  		{
   144  			name: "without node_modules",
   145  			dir:  "testdata/no-node_modules",
   146  			want: &analyzer.AnalysisResult{
   147  				Applications: []types.Application{
   148  					{
   149  						Type:     types.Npm,
   150  						FilePath: "package-lock.json",
   151  						Libraries: types.Packages{
   152  							{
   153  								ID:       "ms@2.1.1",
   154  								Name:     "ms",
   155  								Version:  "2.1.1",
   156  								Indirect: true,
   157  								Locations: []types.Location{
   158  									{
   159  										StartLine: 6,
   160  										EndLine:   10,
   161  									},
   162  								},
   163  							},
   164  						},
   165  					},
   166  				},
   167  			},
   168  		},
   169  		{
   170  			name: "sad path",
   171  			dir:  "testdata/sad",
   172  			want: &analyzer.AnalysisResult{},
   173  		},
   174  	}
   175  	for _, tt := range tests {
   176  		t.Run(tt.name, func(t *testing.T) {
   177  			a, err := newNpmLibraryAnalyzer(analyzer.AnalyzerOptions{})
   178  			require.NoError(t, err)
   179  
   180  			got, err := a.PostAnalyze(context.Background(), analyzer.PostAnalysisInput{
   181  				FS: os.DirFS(tt.dir),
   182  			})
   183  
   184  			assert.NoError(t, err)
   185  			if len(got.Applications) > 0 {
   186  				sort.Sort(got.Applications[0].Libraries)
   187  			}
   188  			assert.Equal(t, tt.want, got)
   189  		})
   190  	}
   191  }
   192  
   193  func Test_nodePkgLibraryAnalyzer_Required(t *testing.T) {
   194  	tests := []struct {
   195  		name     string
   196  		filePath string
   197  		want     bool
   198  	}{
   199  		{
   200  			name:     "lock file",
   201  			filePath: "npm/package-lock.json",
   202  			want:     true,
   203  		},
   204  		{
   205  			name:     "package.json",
   206  			filePath: "npm/node_modules/ms/package.json",
   207  			want:     true,
   208  		},
   209  		{
   210  			name:     "sad path",
   211  			filePath: "npm/node_modules/package.json",
   212  			want:     false,
   213  		},
   214  		{
   215  			name:     "lock file in node_modules",
   216  			filePath: "npm/node_modules/html2canvas/package-lock.json",
   217  			want:     false,
   218  		},
   219  	}
   220  	for _, tt := range tests {
   221  		t.Run(tt.name, func(t *testing.T) {
   222  			a := npmLibraryAnalyzer{}
   223  			got := a.Required(tt.filePath, nil)
   224  			assert.Equal(t, tt.want, got)
   225  		})
   226  	}
   227  }