mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-28 17:31:58 +08:00

* feat: adds server and handler changes Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * feat: add tracefunnel module and handler Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * feat: add required types for tracefunnels Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * feat: db operations, module and handler implementation Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * feat: add db migrations Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * chore: add utility functions Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * test: add utility function tests Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * test: add handler tests Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * test: add trace funnel module tests Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * chore: refactor handler and utils Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * chore: add funnel validation while processing funnel steps Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * test: add more tests to utils Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * chore: fix package naming Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * chore: fix naming convention Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * chore: update normalize funnel steps Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * chore: added some improvements Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * fix: optimize funnel creation by combining insert and update operations Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * chore: fix error handling Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * feat: trace funnel state management Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * fix: updated unit tests and mocks Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * fix: review comments Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * fix: minor fixes Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * fix: update funnel migration number Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * fix: review comments and some changes Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * fix: update modules Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> --------- Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com>
174 lines
5.0 KiB
Go
174 lines
5.0 KiB
Go
package impltracefunnel
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/SigNoz/signoz/pkg/types"
|
|
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
|
traceFunnels "github.com/SigNoz/signoz/pkg/types/tracefunneltypes"
|
|
"github.com/SigNoz/signoz/pkg/valuer"
|
|
"github.com/gorilla/mux"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
)
|
|
|
|
type MockModule struct {
|
|
mock.Mock
|
|
}
|
|
|
|
func (m *MockModule) Create(ctx context.Context, timestamp int64, name string, userID valuer.UUID, orgID valuer.UUID) (*traceFunnels.StorableFunnel, error) {
|
|
args := m.Called(ctx, timestamp, name, userID, orgID)
|
|
return args.Get(0).(*traceFunnels.StorableFunnel), args.Error(1)
|
|
}
|
|
|
|
func (m *MockModule) Get(ctx context.Context, funnelID valuer.UUID, orgID valuer.UUID) (*traceFunnels.StorableFunnel, error) {
|
|
args := m.Called(ctx, funnelID, orgID)
|
|
return args.Get(0).(*traceFunnels.StorableFunnel), args.Error(1)
|
|
}
|
|
|
|
func (m *MockModule) Update(ctx context.Context, funnel *traceFunnels.StorableFunnel, userID valuer.UUID) error {
|
|
args := m.Called(ctx, funnel, userID)
|
|
return args.Error(0)
|
|
}
|
|
|
|
func (m *MockModule) List(ctx context.Context, orgID valuer.UUID) ([]*traceFunnels.StorableFunnel, error) {
|
|
args := m.Called(ctx, orgID)
|
|
return args.Get(0).([]*traceFunnels.StorableFunnel), args.Error(1)
|
|
}
|
|
|
|
func (m *MockModule) Delete(ctx context.Context, funnelID valuer.UUID, orgID valuer.UUID) error {
|
|
args := m.Called(ctx, funnelID, orgID)
|
|
return args.Error(0)
|
|
}
|
|
|
|
func (m *MockModule) Save(ctx context.Context, funnel *traceFunnels.StorableFunnel, userID valuer.UUID, orgID valuer.UUID) error {
|
|
args := m.Called(ctx, funnel, userID, orgID)
|
|
return args.Error(0)
|
|
}
|
|
|
|
func (m *MockModule) GetFunnelMetadata(ctx context.Context, funnelID valuer.UUID, orgID valuer.UUID) (int64, int64, string, error) {
|
|
args := m.Called(ctx, funnelID, orgID)
|
|
return args.Get(0).(int64), args.Get(1).(int64), args.String(2), args.Error(3)
|
|
}
|
|
|
|
func TestHandler_List(t *testing.T) {
|
|
mockModule := new(MockModule)
|
|
handler := NewHandler(mockModule)
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v1/trace-funnels/list", nil)
|
|
|
|
orgID := valuer.GenerateUUID()
|
|
claims := authtypes.Claims{
|
|
OrgID: orgID.String(),
|
|
}
|
|
req = req.WithContext(authtypes.NewContextWithClaims(req.Context(), claims))
|
|
|
|
rr := httptest.NewRecorder()
|
|
|
|
funnel1ID := valuer.GenerateUUID()
|
|
funnel2ID := valuer.GenerateUUID()
|
|
expectedFunnels := []*traceFunnels.StorableFunnel{
|
|
{
|
|
Identifiable: types.Identifiable{
|
|
ID: funnel1ID,
|
|
},
|
|
Name: "funnel-1",
|
|
OrgID: orgID,
|
|
},
|
|
{
|
|
Identifiable: types.Identifiable{
|
|
ID: funnel2ID,
|
|
},
|
|
Name: "funnel-2",
|
|
OrgID: orgID,
|
|
},
|
|
}
|
|
|
|
mockModule.On("List", req.Context(), orgID).Return(expectedFunnels, nil)
|
|
|
|
handler.List(rr, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
var response struct {
|
|
Status string `json:"status"`
|
|
Data []traceFunnels.GettableFunnel `json:"data"`
|
|
}
|
|
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "success", response.Status)
|
|
assert.Len(t, response.Data, 2)
|
|
assert.Equal(t, "funnel-1", response.Data[0].FunnelName)
|
|
assert.Equal(t, "funnel-2", response.Data[1].FunnelName)
|
|
|
|
mockModule.AssertExpectations(t)
|
|
}
|
|
|
|
func TestHandler_Get(t *testing.T) {
|
|
mockModule := new(MockModule)
|
|
handler := NewHandler(mockModule)
|
|
|
|
funnelID := valuer.GenerateUUID()
|
|
orgID := valuer.GenerateUUID()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v1/trace-funnels/"+funnelID.String(), nil)
|
|
req = mux.SetURLVars(req, map[string]string{"funnel_id": funnelID.String()})
|
|
req = req.WithContext(authtypes.NewContextWithClaims(req.Context(), authtypes.Claims{
|
|
OrgID: orgID.String(),
|
|
}))
|
|
|
|
rr := httptest.NewRecorder()
|
|
|
|
expectedFunnel := &traceFunnels.StorableFunnel{
|
|
Identifiable: types.Identifiable{
|
|
ID: funnelID,
|
|
},
|
|
Name: "test-funnel",
|
|
OrgID: orgID,
|
|
}
|
|
|
|
mockModule.On("Get", req.Context(), funnelID, orgID).Return(expectedFunnel, nil)
|
|
|
|
handler.Get(rr, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
var response struct {
|
|
Status string `json:"status"`
|
|
Data traceFunnels.GettableFunnel `json:"data"`
|
|
}
|
|
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "success", response.Status)
|
|
assert.Equal(t, "test-funnel", response.Data.FunnelName)
|
|
assert.Equal(t, expectedFunnel.OrgID.String(), response.Data.OrgID)
|
|
|
|
mockModule.AssertExpectations(t)
|
|
}
|
|
|
|
func TestHandler_Delete(t *testing.T) {
|
|
mockModule := new(MockModule)
|
|
handler := NewHandler(mockModule)
|
|
|
|
funnelID := valuer.GenerateUUID()
|
|
orgID := valuer.GenerateUUID()
|
|
req := httptest.NewRequest(http.MethodDelete, "/api/v1/trace-funnels/"+funnelID.String(), nil)
|
|
req = mux.SetURLVars(req, map[string]string{"funnel_id": funnelID.String()})
|
|
req = req.WithContext(authtypes.NewContextWithClaims(req.Context(), authtypes.Claims{
|
|
OrgID: orgID.String(),
|
|
}))
|
|
|
|
rr := httptest.NewRecorder()
|
|
|
|
mockModule.On("Delete", req.Context(), funnelID, orgID).Return(nil)
|
|
|
|
handler.Delete(rr, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
mockModule.AssertExpectations(t)
|
|
}
|