func TestTrackTestSuite(t *testing.T) {
	suite.Run(t, new(TrackTestSuite))
}
In order for 'go test' to run this suite, we need to create
a normal test function and pass our suite to suite.Run
package handlers
import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
	"github.com/go-chi/chi"
	"github.com/optimizely/go-sdk/pkg/client"
	"github.com/optimizely/go-sdk/pkg/config"
	"github.com/optimizely/go-sdk/pkg/entities"
	"github.com/optimizely/go-sdk/pkg/notification"
	"github.com/stretchr/testify/suite"
	"github.com/optimizely/agent/pkg/middleware"
	"github.com/optimizely/agent/pkg/optimizely"
	"github.com/optimizely/agent/pkg/optimizely/optimizelytest"
)
type TrackTestSuite struct {
	suite.Suite
	oc  *optimizely.OptlyClient
	tc  *optimizelytest.TestClient
	mux *chi.Mux
}
func (suite *TrackTestSuite) ClientCtx(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ctx := context.WithValue(r.Context(), middleware.OptlyClientKey, suite.oc)
		next.ServeHTTP(w, r.WithContext(ctx))
	})
}
type ErrorConfigManager struct{}
func (e ErrorConfigManager) RemoveOnProjectConfigUpdate(id int) error {
	panic("implement me")
}
func (e ErrorConfigManager) OnProjectConfigUpdate(callback func(notification.ProjectConfigUpdateNotification)) (int, error) {
	panic("implement me")
}
func (e ErrorConfigManager) GetConfig() (config.ProjectConfig, error) {
	return nil, fmt.Errorf("config error")
}
func (e ErrorConfigManager) GetOptimizelyConfig() *config.OptimizelyConfig {
	panic("implement me")
}
func (e ErrorConfigManager) SyncConfig() {
	panic("implement me")
}
type MockConfigManager struct {
	config config.ProjectConfig
}
func (m MockConfigManager) RemoveOnProjectConfigUpdate(int) error {
	panic("implement me")
}
func (m MockConfigManager) OnProjectConfigUpdate(callback func(notification.ProjectConfigUpdateNotification)) (int, error) {
	panic("implement me")
}
func (m MockConfigManager) GetConfig() (config.ProjectConfig, error) {
	return m.config, nil
}
func (m MockConfigManager) GetOptimizelyConfig() *config.OptimizelyConfig {
	panic("implement me")
}
func (m MockConfigManager) SyncConfig() {
	panic("implement me")
}
func (suite *TrackTestSuite) SetupTest() {
	testClient := optimizelytest.NewClient()
	optlyClient := &optimizely.OptlyClient{
		OptimizelyClient: testClient.OptimizelyClient,
		ConfigManager:    MockConfigManager{config: testClient.ProjectConfig},
		ForcedVariations: testClient.ForcedVariations,
	}
	mux := chi.NewMux()
	mux.With(suite.ClientCtx).Post("/track", TrackEvent)
	suite.oc = optlyClient
	suite.tc = testClient
	suite.mux = mux
}
func (suite *TrackTestSuite) TestTrackEventNoTags() {
	eventKey := "test-event"
	event := entities.Event{Key: eventKey}
	suite.tc.AddEvent(event)
	tb := trackBody{
		UserID:         "testUser",
		UserAttributes: map[string]interface{}{"test": "attr"},
		EventTags:      nil,
	}
	body, err := json.Marshal(tb)
	suite.NoError(err)
	req := httptest.NewRequest("POST", "/track?eventKey="+eventKey, bytes.NewBuffer(body))
	rec := httptest.NewRecorder()
	suite.mux.ServeHTTP(rec, req)
	suite.Equal(http.StatusOK, rec.Code)
	var actual optimizely.Track
	suite.NoError(json.Unmarshal(rec.Body.Bytes(), &actual))
	expected := optimizely.Track{
		UserID:   "testUser",
		EventKey: eventKey,
	}
	suite.Equal(expected, actual)
	events := suite.tc.GetProcessedEvents()
	suite.Equal(1, len(events))
	actualEvent := events[0]
	suite.Equal(eventKey, actualEvent.Conversion.Key)
	suite.Equal("testUser", actualEvent.VisitorID)
}
func (suite *TrackTestSuite) TestTrackEventWithTags() {
	eventKey := "test-event"
	event := entities.Event{Key: eventKey}
	suite.tc.AddEvent(event)
	tb := trackBody{
		UserID:         "testUser",
		UserAttributes: nil,
		EventTags:      map[string]interface{}{"key1": "val"},
	}
	body, err := json.Marshal(tb)
	suite.NoError(err)
	req := httptest.NewRequest("POST", "/track?eventKey="+eventKey, bytes.NewBuffer(body))
	rec := httptest.NewRecorder()
	suite.mux.ServeHTTP(rec, req)
	suite.Equal(http.StatusOK, rec.Code)
	var actual optimizely.Track
	suite.NoError(json.Unmarshal(rec.Body.Bytes(), &actual))
	expected := optimizely.Track{
		UserID:   "testUser",
		EventKey: eventKey,
	}
	suite.Equal(expected, actual)
	events := suite.tc.GetProcessedEvents()
	suite.Equal(1, len(events))
	actualEvent := events[0]
	suite.Equal(eventKey, actualEvent.Conversion.Key)
	suite.Equal(tb.UserID, actualEvent.VisitorID)
	suite.Equal(tb.EventTags, actualEvent.Conversion.Tags)
}
func (suite *TrackTestSuite) TestTrackEventWithInvalidTags() {
	eventKey := "test-event"
	event := entities.Event{Key: eventKey}
	suite.tc.AddEvent(event)
	req := httptest.NewRequest("POST", "/track?eventKey="+eventKey, bytes.NewBufferString("invalid"))
	rec := httptest.NewRecorder()
	suite.mux.ServeHTTP(rec, req)
	suite.assertError(rec, "error parsing request body", http.StatusBadRequest)
}
func (suite *TrackTestSuite) TestTrackEventParamError() {
	scenarios := []struct {
		param   string
		code    int
		message string
	}{
		{"?eventKey=invalid", http.StatusOK, "Event with key invalid not found"},
		{"?eventKey=", http.StatusBadRequest, "missing required path parameter: eventKey"},
		{"", http.StatusBadRequest, "missing required path parameter: eventKey"},
	}
	for _, scenario := range scenarios {
		req := httptest.NewRequest("POST", "/track"+scenario.param, nil)
		rec := httptest.NewRecorder()
		suite.mux.ServeHTTP(rec, req)
		suite.assertError(rec, scenario.message, scenario.code)
	}
}
func (suite *TrackTestSuite) assertError(rec *httptest.ResponseRecorder, msg string, code int) {
	assertError(suite.T(), rec, msg, code)
}