117 lines
2.2 KiB
Go
117 lines
2.2 KiB
Go
package mixpanel
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// Mocked version of Mixpanel which can be used in unit tests.
|
|
type Mock struct {
|
|
// All People identified, mapped by distinctId
|
|
People map[string]*MockPeople
|
|
}
|
|
|
|
func NewMock() *Mock {
|
|
return &Mock{
|
|
People: map[string]*MockPeople{},
|
|
}
|
|
}
|
|
|
|
func (m *Mock) String() string {
|
|
str := ""
|
|
for id, p := range m.People {
|
|
str += id + ":\n" + p.String()
|
|
}
|
|
return str
|
|
}
|
|
|
|
// Identifies a user. The user will be added to the People map.
|
|
func (m *Mock) people(distinctId string) *MockPeople {
|
|
p := m.People[distinctId]
|
|
if p == nil {
|
|
p = &MockPeople{
|
|
Properties: map[string]interface{}{},
|
|
}
|
|
m.People[distinctId] = p
|
|
}
|
|
|
|
return p
|
|
}
|
|
|
|
func (m *Mock) Track(distinctId, eventName string, e *Event) error {
|
|
p := m.people(distinctId)
|
|
p.Events = append(p.Events, MockEvent{
|
|
Event: *e,
|
|
Name: eventName,
|
|
})
|
|
return nil
|
|
}
|
|
|
|
type MockPeople struct {
|
|
Properties map[string]interface{}
|
|
Time *time.Time
|
|
IP string
|
|
Events []MockEvent
|
|
}
|
|
|
|
func (mp *MockPeople) String() string {
|
|
timeStr := ""
|
|
if mp.Time != nil {
|
|
timeStr = mp.Time.Format(time.RFC3339)
|
|
}
|
|
|
|
str := fmt.Sprintf(" ip: %s\n time: %s\n", mp.IP, timeStr)
|
|
str += " properties:\n"
|
|
for key, val := range mp.Properties {
|
|
str += fmt.Sprintf(" %s: %v\n", key, val)
|
|
}
|
|
str += " events:\n"
|
|
for _, event := range mp.Events {
|
|
str += " " + event.Name + ":\n"
|
|
str += fmt.Sprintf(" IP: %s\n", event.IP)
|
|
if event.Timestamp != nil {
|
|
str += fmt.Sprintf(
|
|
" Timestamp: %s\n", event.Timestamp.Format(time.RFC3339),
|
|
)
|
|
} else {
|
|
str += " Timestamp:\n"
|
|
}
|
|
for key, val := range event.Properties {
|
|
str += fmt.Sprintf(" %s: %v\n", key, val)
|
|
}
|
|
}
|
|
return str
|
|
}
|
|
|
|
func (m *Mock) Update(distinctId string, u *Update) error {
|
|
p := m.people(distinctId)
|
|
|
|
if u.IP != "" {
|
|
p.IP = u.IP
|
|
}
|
|
if u.Timestamp != nil && u.Timestamp != IgnoreTime {
|
|
p.Time = u.Timestamp
|
|
}
|
|
|
|
switch u.Operation {
|
|
case "$set":
|
|
for key, val := range u.Properties {
|
|
p.Properties[key] = val
|
|
}
|
|
default:
|
|
return errors.New("mixpanel.Mock only supports the $set operation")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *Mock) Alias(distinctId, newId string) error {
|
|
return nil
|
|
}
|
|
|
|
type MockEvent struct {
|
|
Event
|
|
Name string
|
|
}
|