Skip to content

Commit 8905e86

Browse files
chore: wip tests for remote
1 parent 6031995 commit 8905e86

File tree

2 files changed

+195
-13
lines changed

2 files changed

+195
-13
lines changed

internal/analysis/analysis_test.go

Lines changed: 138 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"testing"
2727
"time"
2828

29+
"github.com/google/uuid"
2930
"github.com/snyk/code-client-go/sarif"
3031

3132
"github.com/golang/mock/gomock"
@@ -641,18 +642,6 @@ func TestAnalysis_RunAnalysis_GetFindingsError(t *testing.T) {
641642
req := i.(*http.Request)
642643
return req.URL.String() == "http://localhost/rest/orgs/b6fc8954-5918-45ce-bc89-54591815ce1b/scans/a6fb2742-b67f-4dc3-bb27-42b67f1dc344?version=2024-02-16~experimental" &&
643644
req.Method == http.MethodGet
644-
})).Times(1).Return(&http.Response{
645-
StatusCode: http.StatusOK,
646-
Header: http.Header{
647-
"Content-Type": []string{"application/vnd.api+json"},
648-
},
649-
Body: io.NopCloser(bytes.NewReader([]byte(`{"data":{"attributes": {"status": "done", "components":[{"findings_url": "http://findings_url"}]}, "id": "a6fb2742-b67f-4dc3-bb27-42b67f1dc344"}}`))),
650-
}, nil)
651-
652-
mockHTTPClient.EXPECT().Do(mock.MatchedBy(func(i interface{}) bool {
653-
req := i.(*http.Request)
654-
return req.URL.String() == "http://findings_url" &&
655-
req.Method == http.MethodGet
656645
})).Times(1).Return(nil, errors.New("error"))
657646

658647
analysisOrchestrator := analysis.NewAnalysisOrchestrator(
@@ -665,8 +654,9 @@ func TestAnalysis_RunAnalysis_GetFindingsError(t *testing.T) {
665654
)
666655

667656
_, err := analysisOrchestrator.RunAnalysis(context.Background(), "b6fc8954-5918-45ce-bc89-54591815ce1b", "rootPath", "c172d1db-b465-4764-99e1-ecedad03b06a")
668-
require.ErrorContains(t, err, "error")
657+
assert.ErrorContains(t, err, "error")
669658
}
659+
670660
func TestAnalysis_RunAnalysis_GetFindingsNotSuccessful(t *testing.T) {
671661
mockConfig, mockHTTPClient, mockInstrumentor, mockErrorReporter, mockTracker, mockTrackerFactory, logger := setup(t, nil)
672662

@@ -718,3 +708,138 @@ func TestAnalysis_RunAnalysis_GetFindingsNotSuccessful(t *testing.T) {
718708
_, err := analysisOrchestrator.RunAnalysis(context.Background(), "b6fc8954-5918-45ce-bc89-54591815ce1b", "rootPath", "c172d1db-b465-4764-99e1-ecedad03b06a")
719709
require.ErrorContains(t, err, "failed to retrieve findings from findings URL")
720710
}
711+
712+
func TestAnalysis_RunTestRemote(t *testing.T) {
713+
mockConfig, mockHTTPClient, mockInstrumentor, mockErrorReporter, mockTracker, mockTrackerFactory, logger := setup(t, nil)
714+
715+
mockTracker.EXPECT().Begin(gomock.Eq("Snyk Code analysis for remote project"), gomock.Eq("Retrieving results...")).Return()
716+
mockTracker.EXPECT().End(gomock.Eq("Analysis complete.")).Return()
717+
718+
projectId := uuid.New()
719+
commitId := "abc123"
720+
report := true
721+
722+
// Mock the initial test creation request
723+
mockHTTPClient.EXPECT().Do(mock.MatchedBy(func(i interface{}) bool {
724+
req := i.(*http.Request)
725+
return req.URL.String() == "http://localhost/hidden/orgs/4a72d1db-b465-4764-99e1-ecedad03b06a/tests?version=2024-12-21" &&
726+
req.Method == http.MethodPost
727+
})).Times(1).Return(&http.Response{
728+
StatusCode: http.StatusCreated,
729+
Header: http.Header{
730+
"Content-Type": []string{"application/json"},
731+
},
732+
Body: io.NopCloser(bytes.NewReader([]byte(`{
733+
"data": {
734+
"id": "a6fb2742-b67f-4dc3-bb27-42b67f1dc344",
735+
"type": "test-result",
736+
"attributes": {
737+
"status": "completed",
738+
"documents": {
739+
"enriched_sarif": "/tests/123/sarif"
740+
}
741+
}
742+
},
743+
"jsonapi": {
744+
"version": "1.0"
745+
},
746+
"links": {
747+
"self": "http://localhost/hidden/orgs/4a72d1db-b465-4764-99e1-ecedad03b06a/tests/a6fb2742-b67f-4dc3-bb27-42b67f1dc344"
748+
}
749+
}`))),
750+
}, nil)
751+
// Mock the findings retrieval request
752+
mockHTTPClient.EXPECT().Do(mock.MatchedBy(func(i interface{}) bool {
753+
req := i.(*http.Request)
754+
return req.URL.String() == "http://localhost/tests/123/sarif" &&
755+
req.Method == http.MethodGet
756+
})).Times(1).Return(&http.Response{
757+
StatusCode: http.StatusOK,
758+
Body: io.NopCloser(bytes.NewReader(fakeResponse)),
759+
}, nil)
760+
761+
analysisOrchestrator := analysis.NewAnalysisOrchestrator(
762+
mockConfig,
763+
mockHTTPClient,
764+
analysis.WithLogger(&logger),
765+
analysis.WithInstrumentor(mockInstrumentor),
766+
analysis.WithTrackerFactory(mockTrackerFactory),
767+
analysis.WithErrorReporter(mockErrorReporter),
768+
)
769+
770+
result, err := analysisOrchestrator.RunTestRemote(
771+
context.Background(),
772+
"4a72d1db-b465-4764-99e1-ecedad03b06a",
773+
"b372d1db-b465-4764-99e1-ecedad03b06a",
774+
analysis.ReportingConfig{
775+
ProjectId: &projectId,
776+
CommitId: &commitId,
777+
Report: &report,
778+
},
779+
)
780+
781+
require.NoError(t, err)
782+
assert.NotNil(t, result)
783+
}
784+
785+
func TestAnalysis_RunTestRemote_MissingRequiredParams(t *testing.T) {
786+
mockConfig, mockHTTPClient, mockInstrumentor, mockErrorReporter, mockTracker, mockTrackerFactory, logger := setup(t, nil)
787+
mockTrackerFactory.EXPECT().GenerateTracker().Return(mockTracker).AnyTimes()
788+
789+
mockTracker.EXPECT().Begin(gomock.Eq("Snyk Code analysis for remote project"), gomock.Eq("Retrieving results...")).Return().AnyTimes()
790+
mockHTTPClient.EXPECT().Do(gomock.Any()).Times(0)
791+
792+
analysisOrchestrator := analysis.NewAnalysisOrchestrator(
793+
mockConfig,
794+
mockHTTPClient,
795+
analysis.WithLogger(&logger),
796+
analysis.WithInstrumentor(mockInstrumentor),
797+
analysis.WithTrackerFactory(mockTrackerFactory),
798+
analysis.WithErrorReporter(mockErrorReporter),
799+
)
800+
801+
t.Run("missing both projectId and commitId", func(t *testing.T) {
802+
result, err := analysisOrchestrator.RunTestRemote(
803+
context.Background(),
804+
"4a72d1db-b465-4764-99e1-ecedad03b06a",
805+
"b372d1db-b465-4764-99e1-ecedad03b06a",
806+
analysis.ReportingConfig{},
807+
)
808+
809+
assert.Error(t, err)
810+
assert.Contains(t, err.Error(), "projectId and commitId are required")
811+
assert.Nil(t, result)
812+
})
813+
814+
t.Run("missing projectId", func(t *testing.T) {
815+
commitId := "abc123"
816+
result, err := analysisOrchestrator.RunTestRemote(
817+
context.Background(),
818+
"4a72d1db-b465-4764-99e1-ecedad03b06a",
819+
"b372d1db-b465-4764-99e1-ecedad03b06a",
820+
analysis.ReportingConfig{
821+
CommitId: &commitId,
822+
},
823+
)
824+
825+
assert.Error(t, err)
826+
assert.Contains(t, err.Error(), "projectId and commitId are required")
827+
assert.Nil(t, result)
828+
})
829+
830+
t.Run("missing commitId", func(t *testing.T) {
831+
projectId := uuid.New()
832+
result, err := analysisOrchestrator.RunTestRemote(
833+
context.Background(),
834+
"4a72d1db-b465-4764-99e1-ecedad03b06a",
835+
"b372d1db-b465-4764-99e1-ecedad03b06a",
836+
analysis.ReportingConfig{
837+
ProjectId: &projectId,
838+
},
839+
)
840+
841+
assert.Error(t, err)
842+
assert.Contains(t, err.Error(), "projectId and commitId are required")
843+
assert.Nil(t, result)
844+
})
845+
}

scan_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,63 @@ func Test_UploadAndAnalyze(t *testing.T) {
163163
)
164164
}
165165

166+
func TestAnalyzeRemote(t *testing.T) {
167+
ctrl := gomock.NewController(t)
168+
defer ctrl.Finish()
169+
mockConfig := confMocks.NewMockConfig(ctrl)
170+
mockConfig.EXPECT().Organization().AnyTimes().Return("mockOrgId")
171+
172+
mockHTTPClient := httpmocks.NewMockHTTPClient(ctrl)
173+
mockInstrumentor := mocks.NewMockInstrumentor(ctrl)
174+
mockErrorReporter := mocks.NewMockErrorReporter(ctrl)
175+
mockSpan := mocks.NewMockSpan(ctrl)
176+
mockSpan.EXPECT().GetTraceId().AnyTimes().Return("testTraceId")
177+
mockSpan.EXPECT().Context().AnyTimes().Return(context.Background())
178+
mockInstrumentor.EXPECT().StartSpan(gomock.Any(), gomock.Any()).AnyTimes().Return(mockSpan)
179+
mockInstrumentor.EXPECT().Finish(gomock.Any()).AnyTimes()
180+
181+
logger := zerolog.Nop()
182+
mockAnalysisOrchestrator := mockAnalysis.NewMockAnalysisOrchestrator(ctrl)
183+
184+
codeScanner := codeclient.NewCodeScanner(
185+
mockConfig,
186+
mockHTTPClient,
187+
codeclient.WithInstrumentor(mockInstrumentor),
188+
codeclient.WithErrorReporter(mockErrorReporter),
189+
codeclient.WithLogger(&logger),
190+
).WithAnalysisOrchestrator(mockAnalysisOrchestrator)
191+
192+
t.Run("returns valid response", func(t *testing.T) {
193+
mockAnalysisOrchestrator.EXPECT().RunTestRemote(
194+
gomock.Any(),
195+
"mockOrgId",
196+
"mockInteractionId",
197+
gomock.Any(),
198+
).Return(&sarif.SarifResponse{Status: "COMPLETE"}, nil)
199+
200+
response, err := codeScanner.AnalyzeRemote(context.Background(), "mockInteractionId")
201+
if err != nil {
202+
t.Fatalf("AnalyzeRemote failed: %v", err)
203+
}
204+
if response == nil || response.Status != "COMPLETE" {
205+
t.Fatalf("expected COMPLETE, got %+v", response)
206+
}
207+
})
208+
209+
t.Run("handles orchestrator error", func(t *testing.T) {
210+
mockAnalysisOrchestrator.EXPECT().RunTestRemote(
211+
gomock.Any(),
212+
gomock.Any(),
213+
gomock.Any(),
214+
gomock.Any(),
215+
).Return(nil, assert.AnError)
216+
217+
response, err := codeScanner.AnalyzeRemote(context.Background(), "mockInteractionId")
218+
assert.Nil(t, response)
219+
assert.Error(t, err)
220+
})
221+
}
222+
166223
func setupDocs(t *testing.T) (string, string, string, []byte, []byte) {
167224
t.Helper()
168225
path := t.TempDir()

0 commit comments

Comments
 (0)