@@ -3,6 +3,7 @@ package tests
33import (
44 "bytes"
55 "encoding/json"
6+ "net/http"
67 "net/http/httptest"
78 "os"
89 "testing"
@@ -17,12 +18,120 @@ import (
1718 "github.com/l3montree-dev/devguard/mocks"
1819 "github.com/l3montree-dev/devguard/shared"
1920
21+ "github.com/labstack/echo/v4"
2022 "github.com/stretchr/testify/assert"
2123 "github.com/stretchr/testify/mock"
2224 gitlab "gitlab.com/gitlab-org/api/client-go"
2325 "go.uber.org/fx"
2426)
2527
28+ func TestDependencyVulnControllerGetRecommendation (t * testing.T ) {
29+ buildController := func (t * testing.T , depVulnRepo * mocks.DependencyVulnRepository ) * controllers.DependencyVulnController {
30+ return controllers .NewDependencyVulnController (
31+ depVulnRepo ,
32+ mocks .NewDependencyVulnService (t ),
33+ mocks .NewProjectService (t ),
34+ mocks .NewStatisticsService (t ),
35+ mocks .NewVulnEventRepository (t ),
36+ nil ,
37+ )
38+ }
39+
40+ t .Run ("uses packageName/packageValue and returns extracted version" , func (t * testing.T ) {
41+ depVulnRepo := mocks .NewDependencyVulnRepository (t )
42+ controller := buildController (t , depVulnRepo )
43+
44+ recommendedPurl := "pkg:npm/lodash@4.17.21"
45+ depVulnRepo .On ("GetDirectDependencyFixedVersionByPackageName" , mock .Anything , mock .Anything , "lodash" ).Return (& recommendedPurl , nil ).Once ()
46+
47+ req := httptest .NewRequest (http .MethodGet , "/dependency_vuln/recommendation?packageName=lodash&packageValue=^4.0.0" , nil )
48+ rec := httptest .NewRecorder ()
49+ ctx := NewContext (req , rec )
50+
51+ err := controller .GetRecommendation (ctx )
52+ assert .NoError (t , err )
53+ assert .Equal (t , http .StatusOK , rec .Code )
54+
55+ var response dtos.Recommendation
56+ assert .NoError (t , json .Unmarshal (rec .Body .Bytes (), & response ))
57+ assert .Equal (t , "4.17.21" , response .RecommendedVersion )
58+ depVulnRepo .AssertExpectations (t )
59+ })
60+
61+ t .Run ("uses depName/currentValue aliases and returns empty recommendation for non-PURL value" , func (t * testing.T ) {
62+ depVulnRepo := mocks .NewDependencyVulnRepository (t )
63+ controller := buildController (t , depVulnRepo )
64+
65+ recommendedVersion := "2.3.4"
66+ depVulnRepo .On ("GetDirectDependencyFixedVersionByPackageName" , mock .Anything , mock .Anything , "leftpad" ).Return (& recommendedVersion , nil ).Once ()
67+
68+ req := httptest .NewRequest (http .MethodGet , "/dependency_vuln/recommendation?depName=leftpad¤tValue=2.0.0" , nil )
69+ rec := httptest .NewRecorder ()
70+ ctx := NewContext (req , rec )
71+
72+ err := controller .GetRecommendation (ctx )
73+ assert .NoError (t , err )
74+ assert .Equal (t , http .StatusOK , rec .Code )
75+
76+ var response map [string ]string
77+ assert .NoError (t , json .Unmarshal (rec .Body .Bytes (), & response ))
78+ assert .Equal (t , "" , response ["recommendedVersion" ])
79+ depVulnRepo .AssertExpectations (t )
80+ })
81+
82+ t .Run ("returns empty recommendation when repository returns nil" , func (t * testing.T ) {
83+ depVulnRepo := mocks .NewDependencyVulnRepository (t )
84+ controller := buildController (t , depVulnRepo )
85+
86+ depVulnRepo .On ("GetDirectDependencyFixedVersionByPackageName" , mock .Anything , mock .Anything , "chalk" ).Return ((* string )(nil ), nil ).Once ()
87+
88+ req := httptest .NewRequest (http .MethodGet , "/dependency_vuln/recommendation?packageName=chalk&packageValue=5.0.0" , nil )
89+ rec := httptest .NewRecorder ()
90+ ctx := NewContext (req , rec )
91+
92+ err := controller .GetRecommendation (ctx )
93+ assert .NoError (t , err )
94+ assert .Equal (t , http .StatusOK , rec .Code )
95+
96+ var response dtos.Recommendation
97+ assert .NoError (t , json .Unmarshal (rec .Body .Bytes (), & response ))
98+ assert .Equal (t , "" , response .RecommendedVersion )
99+ depVulnRepo .AssertExpectations (t )
100+ })
101+
102+ t .Run ("returns bad request when package name params are missing" , func (t * testing.T ) {
103+ depVulnRepo := mocks .NewDependencyVulnRepository (t )
104+ controller := buildController (t , depVulnRepo )
105+
106+ req := httptest .NewRequest (http .MethodGet , "/dependency_vuln/recommendation?packageValue=1.2.3" , nil )
107+ rec := httptest .NewRecorder ()
108+ ctx := NewContext (req , rec )
109+
110+ err := controller .GetRecommendation (ctx )
111+ httpErr , ok := err .(* echo.HTTPError )
112+ assert .True (t , ok )
113+ assert .Equal (t , http .StatusBadRequest , httpErr .Code )
114+ assert .Equal (t , "missing packageName or depName" , httpErr .Message )
115+ depVulnRepo .AssertNotCalled (t , "GetDirectDependencyFixedVersionByPackageName" , mock .Anything , mock .Anything , mock .Anything )
116+ })
117+
118+ t .Run ("returns bad request when current version params are missing" , func (t * testing.T ) {
119+ depVulnRepo := mocks .NewDependencyVulnRepository (t )
120+ controller := buildController (t , depVulnRepo )
121+
122+ req := httptest .NewRequest (http .MethodGet , "/dependency_vuln/recommendation?packageName=react" , nil )
123+ rec := httptest .NewRecorder ()
124+ ctx := NewContext (req , rec )
125+
126+ err := controller .GetRecommendation (ctx )
127+ httpErr , ok := err .(* echo.HTTPError )
128+ assert .True (t , ok )
129+ assert .Equal (t , http .StatusBadRequest , httpErr .Code )
130+ assert .Equal (t , "missing packageValue or currentValue" , httpErr .Message )
131+ depVulnRepo .AssertNotCalled (t , "GetDirectDependencyFixedVersionByPackageName" , mock .Anything , mock .Anything , mock .Anything )
132+ })
133+ }
134+
26135func TestDependencyVulnControllerCreateEvent (t * testing.T ) {
27136 os .Setenv ("FRONTEND_URL" , "http://localhost:3000" )
28137
0 commit comments