We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stakwork Run
File: routes/ticket_routes.go
package handlers import ( "bytes" "context" "encoding/json" "errors" "fmt" "io" "net/http" "net/http/httptest" "os" "testing" "github.com/go-chi/chi" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) // MockHttpClient is a mock for the HTTP client type MockHttpClient struct { mock.Mock } func (m *MockHttpClient) Do(req *http.Request) (*http.Response, error) { args := m.Called(req) return args.Get(0).(*http.Response), args.Error(1) } // MockWebsocketPool is a mock for the Websocket pool type MockWebsocketPool struct { mock.Mock } func (m *MockWebsocketPool) SendTicketMessage(message TicketMessage) error { args := m.Called(message) return args.Error(0) } // SetupSuite sets up the test suite func SetupSuite(t *testing.T) func(t *testing.T) { // Setup code here return func(t *testing.T) { // Teardown code here } } // TestPostTicketDataToStakwork tests the PostTicketDataToStakwork function func TestPostTicketDataToStakwork(t *testing.T) { teardownSuite := SetupSuite(t) defer teardownSuite(t) mockHttpClient := new(MockHttpClient) mockWebsocketPool := new(MockWebsocketPool) tHandler := NewTicketHandler(mockHttpClient, db.TestDB) t.Run("Successful Ticket Submission", func(t *testing.T) { // Setup os.Setenv("HOST", "http://localhost") os.Setenv("SWWFKEY", "test-api-key") ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Mock HTTP client response mockHttpClient.On("Do", mock.Anything).Return(&http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString(`{"success": true, "data": {"project_id": 12345}}`)), }, nil) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusOK, rr.Code) var response TicketResponse assert.NoError(t, json.Unmarshal(rr.Body.Bytes(), &response)) assert.True(t, response.Success) assert.Equal(t, ticketRequest.Ticket.UUID.String(), response.TicketID) }) t.Run("Ticket Submission with WebSocket Notification", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, Metadata: Metadata{ Source: "websocket", ID: "session-id", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Mock HTTP client response mockHttpClient.On("Do", mock.Anything).Return(&http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString(`{"success": true, "data": {"project_id": 12345}}`)), }, nil) // Mock WebSocket message sending mockWebsocketPool.On("SendTicketMessage", mock.Anything).Return(nil) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusOK, rr.Code) var response TicketResponse assert.NoError(t, json.Unmarshal(rr.Body.Bytes(), &response)) assert.True(t, response.Success) mockWebsocketPool.AssertCalled(t, "SendTicketMessage", mock.Anything) }) t.Run("Missing Authorization Key", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, nil) assert.NoError(t, err) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusUnauthorized, rr.Code) }) t.Run("Invalid UUID Format", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.Nil, FeatureUUID: "invalid-uuid", PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusBadRequest, rr.Code) var response TicketResponse assert.NoError(t, json.Unmarshal(rr.Body.Bytes(), &response)) assert.False(t, response.Success) assert.Contains(t, response.Errors, "Invalid UUID format") }) t.Run("Feature Not Found", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Mock HTTP client response mockHttpClient.On("Do", mock.Anything).Return(&http.Response{ StatusCode: http.StatusInternalServerError, Body: io.NopCloser(bytes.NewBufferString(`{"success": false, "message": "Feature not found with the provided UUID"}`)), }, nil) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusInternalServerError, rr.Code) var response TicketResponse assert.NoError(t, json.Unmarshal(rr.Body.Bytes(), &response)) assert.False(t, response.Success) assert.Contains(t, response.Errors, "Feature not found with the provided UUID") }) t.Run("Error Reading Request Body", func(t *testing.T) { // Setup req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", nil, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Simulate error in reading request body req.Body = io.NopCloser(&errorReader{}) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusBadRequest, rr.Code) }) t.Run("Error Parsing Request Body", func(t *testing.T) { // Setup body := []byte(`{"invalid_json":`) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusBadRequest, rr.Code) }) t.Run("Error Creating HTTP Request", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Simulate error in creating HTTP request mockHttpClient.On("Do", mock.Anything).Return(nil, errors.New("error creating request")) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusInternalServerError, rr.Code) }) t.Run("Error Sending HTTP Request", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Simulate network failure mockHttpClient.On("Do", mock.Anything).Return(nil, errors.New("network error")) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusInternalServerError, rr.Code) }) t.Run("Error Reading HTTP Response", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Simulate error in reading response body mockHttpClient.On("Do", mock.Anything).Return(&http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(&errorReader{}), }, nil) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusInternalServerError, rr.Code) }) t.Run("Error Parsing Stakwork Response", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Simulate invalid JSON response mockHttpClient.On("Do", mock.Anything).Return(&http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString(`{"invalid_json":`)), }, nil) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusInternalServerError, rr.Code) }) t.Run("Large Payload Handling", func(t *testing.T) { // Setup largeDescription := make([]byte, 10*1024*1024) // 10MB payload ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: string(largeDescription), }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Mock HTTP client response mockHttpClient.On("Do", mock.Anything).Return(&http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString(`{"success": true, "data": {"project_id": 12345}}`)), }, nil) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusOK, rr.Code) var response TicketResponse assert.NoError(t, json.Unmarshal(rr.Body.Bytes(), &response)) assert.True(t, response.Success) }) t.Run("Concurrent Ticket Submissions", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Mock HTTP client response mockHttpClient.On("Do", mock.Anything).Return(&http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString(`{"success": true, "data": {"project_id": 12345}}`)), }, nil) // Execute concurrent requests const numRequests = 10 results := make(chan bool, numRequests) for i := 0; i < numRequests; i++ { go func() { rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) results <- rr.Code == http.StatusOK }() } // Assert for i := 0; i < numRequests; i++ { assert.True(t, <-results) } }) t.Run("Missing HOST Environment Variable", func(t *testing.T) { // Setup os.Unsetenv("HOST") ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusInternalServerError, rr.Code) }) t.Run("Missing API Key Environment Variable", func(t *testing.T) { // Setup os.Unsetenv("SWWFKEY") ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusInternalServerError, rr.Code) }) t.Run("WebSocket Client Not Found", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, Metadata: Metadata{ Source: "websocket", ID: "non-existent-session-id", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Mock HTTP client response mockHttpClient.On("Do", mock.Anything).Return(&http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString(`{"success": true, "data": {"project_id": 12345}}`)), }, nil) // Mock WebSocket message sending failure mockWebsocketPool.On("SendTicketMessage", mock.Anything).Return(errors.New("client not found")) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusOK, rr.Code) var response TicketResponse assert.NoError(t, json.Unmarshal(rr.Body.Bytes(), &response)) assert.True(t, response.Success) assert.Contains(t, response.Errors, "client not found") }) t.Run("Stakwork API Failure", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Simulate Stakwork API returning a non-200 status code mockHttpClient.On("Do", mock.Anything).Return(&http.Response{ StatusCode: http.StatusBadGateway, Body: io.NopCloser(bytes.NewBufferString(`{"success": false, "message": "Stakwork API error"}`)), }, nil) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusBadGateway, rr.Code) var response TicketResponse assert.NoError(t, json.Unmarshal(rr.Body.Bytes(), &response)) assert.False(t, response.Success) assert.Contains(t, response.Errors, "Stakwork API error") }) t.Run("Invalid FeatureUUID Format", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: "invalid-feature-uuid", PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusBadRequest, rr.Code) var response TicketResponse assert.NoError(t, json.Unmarshal(rr.Body.Bytes(), &response)) assert.False(t, response.Success) assert.Contains(t, response.Errors, "Invalid FeatureUUID format") }) t.Run("Database Connection Failure", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Simulate database connection failure mockHttpClient.On("Do", mock.Anything).Return(nil, errors.New("database connection error")) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusInternalServerError, rr.Code) }) t.Run("WebSocket Message Send Failure", func(t *testing.T) { // Setup ticketRequest := UpdateTicketRequest{ Ticket: &db.Tickets{ UUID: uuid.New(), FeatureUUID: uuid.New().String(), PhaseUUID: uuid.New().String(), Name: "Test Ticket", Description: "Test Description", }, Metadata: Metadata{ Source: "websocket", ID: "session-id", }, } body, _ := json.Marshal(ticketRequest) req, err := setupTestRequest(http.MethodPost, "/bounties/ticket/review/send", body, map[interface{}]interface{}{auth.ContextKey: "valid-pubkey"}) assert.NoError(t, err) // Mock HTTP client response mockHttpClient.On("Do", mock.Anything).Return(&http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString(`{"success": true, "data": {"project_id": 12345}}`)), }, nil) // Simulate WebSocket message send failure mockWebsocketPool.On("SendTicketMessage", mock.Anything).Return(errors.New("failed to send websocket message")) // Execute rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.PostTicketDataToStakwork) handler.ServeHTTP(rr, req) // Assert assert.Equal(t, http.StatusOK, rr.Code) var response TicketResponse assert.NoError(t, json.Unmarshal(rr.Body.Bytes(), &response)) assert.True(t, response.Success) assert.Contains(t, response.Errors, "failed to send websocket message") }) } // errorReader is a helper type to simulate an error when reading from a request body type errorReader struct{} func (e *errorReader) Read(p []byte) (n int, err error) { return 0, errors.New("read error") }
The text was updated successfully, but these errors were encountered:
@tomsmith8 assign me
Sorry, something went wrong.
No branches or pull requests
Integration Test Coverage for "/bounties/ticket/review/send"
Stakwork Run
Integration Test Code
File: routes/ticket_routes.go
The text was updated successfully, but these errors were encountered: