From 971cce8ca3da46b3b38f229d2aa060a6571806f4 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Tue, 25 Oct 2022 00:08:51 +0200 Subject: [PATCH 1/7] feat: Extend User inteface by adding Data, Name and Segment --- CHANGELOG.md | 2 ++ interfaces.go | 11 +++++++---- scope.go | 4 ++-- scope_test.go | 4 ++-- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83fa381b..f51b34b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +- feat: Extend User inteface by adding Data, Name and Segment (#483) + ## 0.14.0 - feat: Add function to continue from trace string (#434) diff --git a/interfaces.go b/interfaces.go index a8250206..36674724 100644 --- a/interfaces.go +++ b/interfaces.go @@ -93,10 +93,13 @@ func (b *Breadcrumb) MarshalJSON() ([]byte, error) { // User describes the user associated with an Event. If this is used, at least // an ID or an IP address should be provided. type User struct { - Email string `json:"email,omitempty"` - ID string `json:"id,omitempty"` - IPAddress string `json:"ip_address,omitempty"` - Username string `json:"username,omitempty"` + Data map[string]string `json:"data,omitempty"` + Email string `json:"email,omitempty"` + ID string `json:"id,omitempty"` + IPAddress string `json:"ip_address,omitempty"` + Name string `json:"name,omitempty"` + Segment string `json:"segment,omitempty"` + Username string `json:"username,omitempty"` } // Request contains information on a HTTP request related to the event. diff --git a/scope.go b/scope.go index 51dd7fd3..0cfd199e 100644 --- a/scope.go +++ b/scope.go @@ -4,6 +4,7 @@ import ( "bytes" "io" "net/http" + "reflect" "sync" "time" ) @@ -379,8 +380,7 @@ func (scope *Scope) ApplyToEvent(event *Event, hint *EventHint) *Event { } } - var emptyUser User - if event.User == emptyUser { + if reflect.DeepEqual(event.User, User{}) { event.User = scope.user } diff --git a/scope_test.go b/scope_test.go index b7fb8c39..d6799cc0 100644 --- a/scope_test.go +++ b/scope_test.go @@ -37,8 +37,8 @@ func fillEventWithData(event *Event) *Event { func TestScopeSetUser(t *testing.T) { scope := NewScope() - scope.SetUser(User{ID: "foo"}) - assertEqual(t, User{ID: "foo"}, scope.user) + scope.SetUser(User{Data: map[string]string{"foo": "bar"}, Email: "foo@example.com", ID: "foo", IPAddress: "127.0.0.1", Name: "My Name", Segment: "My Segment", Username: "My Username"}) + assertEqual(t, User{Data: map[string]string{"foo": "bar"}, Email: "foo@example.com", ID: "foo", IPAddress: "127.0.0.1", Name: "My Name", Segment: "My Segment", Username: "My Username"}, scope.user) } func TestScopeSetUserOverrides(t *testing.T) { From 9c01ea57b7bbc12e1b4b59459a9bd3e03bc94f97 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Thu, 27 Oct 2022 01:46:49 +0200 Subject: [PATCH 2/7] Add User.isEmpty method --- interfaces.go | 38 +++++++++++++++++++++++++++++++++++--- scope.go | 3 +-- scope_test.go | 5 +++-- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/interfaces.go b/interfaces.go index 36674724..e1b8b46d 100644 --- a/interfaces.go +++ b/interfaces.go @@ -93,13 +93,45 @@ func (b *Breadcrumb) MarshalJSON() ([]byte, error) { // User describes the user associated with an Event. If this is used, at least // an ID or an IP address should be provided. type User struct { - Data map[string]string `json:"data,omitempty"` - Email string `json:"email,omitempty"` ID string `json:"id,omitempty"` + Email string `json:"email,omitempty"` IPAddress string `json:"ip_address,omitempty"` + Username string `json:"username,omitempty"` Name string `json:"name,omitempty"` Segment string `json:"segment,omitempty"` - Username string `json:"username,omitempty"` + Data map[string]string `json:"data,omitempty"` +} + +func (u User) IsEmpty() bool { + if len(u.ID) > 0 { + return false + } + + if len(u.Email) > 0 { + return false + } + + if len(u.IPAddress) > 0 { + return false + } + + if len(u.Username) > 0 { + return false + } + + if len(u.Name) > 0 { + return false + } + + if len(u.Segment) > 0 { + return false + } + + if len(u.Data) > 0 { + return false + } + + return true } // Request contains information on a HTTP request related to the event. diff --git a/scope.go b/scope.go index 0cfd199e..228de269 100644 --- a/scope.go +++ b/scope.go @@ -4,7 +4,6 @@ import ( "bytes" "io" "net/http" - "reflect" "sync" "time" ) @@ -380,7 +379,7 @@ func (scope *Scope) ApplyToEvent(event *Event, hint *EventHint) *Event { } } - if reflect.DeepEqual(event.User, User{}) { + if event.User.IsEmpty() { event.User = scope.user } diff --git a/scope_test.go b/scope_test.go index d6799cc0..d971ff76 100644 --- a/scope_test.go +++ b/scope_test.go @@ -37,8 +37,9 @@ func fillEventWithData(event *Event) *Event { func TestScopeSetUser(t *testing.T) { scope := NewScope() - scope.SetUser(User{Data: map[string]string{"foo": "bar"}, Email: "foo@example.com", ID: "foo", IPAddress: "127.0.0.1", Name: "My Name", Segment: "My Segment", Username: "My Username"}) - assertEqual(t, User{Data: map[string]string{"foo": "bar"}, Email: "foo@example.com", ID: "foo", IPAddress: "127.0.0.1", Name: "My Name", Segment: "My Segment", Username: "My Username"}, scope.user) + scope.SetUser(User{ ID: "foo", Email: "foo@example.com", IPAddress: "127.0.0.1", Username: "My Username", Name: "My Name", Segment: "My Segment", Data: map[string]string{"foo": "bar"}}) + + assertEqual(t, User{ ID: "foo", Email: "foo@example.com", IPAddress: "127.0.0.1", Username: "My Username", Name: "My Name", Segment: "My Segment", Data: map[string]string{"foo": "bar"}}, scope.user) } func TestScopeSetUserOverrides(t *testing.T) { From 9e6aed5eb6ff93e9605a220a9962e6d103e7de51 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Thu, 27 Oct 2022 11:16:04 +0200 Subject: [PATCH 3/7] CS --- scope_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scope_test.go b/scope_test.go index d971ff76..3b9fc6db 100644 --- a/scope_test.go +++ b/scope_test.go @@ -37,9 +37,9 @@ func fillEventWithData(event *Event) *Event { func TestScopeSetUser(t *testing.T) { scope := NewScope() - scope.SetUser(User{ ID: "foo", Email: "foo@example.com", IPAddress: "127.0.0.1", Username: "My Username", Name: "My Name", Segment: "My Segment", Data: map[string]string{"foo": "bar"}}) + scope.SetUser(User{ID: "foo", Email: "foo@example.com", IPAddress: "127.0.0.1", Username: "My Username", Name: "My Name", Segment: "My Segment", Data: map[string]string{"foo": "bar"}}) - assertEqual(t, User{ ID: "foo", Email: "foo@example.com", IPAddress: "127.0.0.1", Username: "My Username", Name: "My Name", Segment: "My Segment", Data: map[string]string{"foo": "bar"}}, scope.user) + assertEqual(t, User{ID: "foo", Email: "foo@example.com", IPAddress: "127.0.0.1", Username: "My Username", Name: "My Name", Segment: "My Segment", Data: map[string]string{"foo": "bar"}}, scope.user) } func TestScopeSetUserOverrides(t *testing.T) { From 1c5ef0645668ad68ee269f4fdbfa4fb131f0d1c0 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Thu, 27 Oct 2022 11:28:37 +0200 Subject: [PATCH 4/7] Add tests for User.IsEmpty --- interfaces_test.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/interfaces_test.go b/interfaces_test.go index 02dff0c1..262a5e86 100644 --- a/interfaces_test.go +++ b/interfaces_test.go @@ -19,6 +19,27 @@ var ( generate = flag.Bool("gen", false, "generate missing .golden files") ) +func TestIsEmpty(t *testing.T) { + tests := []struct { + input User + want bool + }{ + {input: User{}, want: true}, + {input: User{ID: "foo"}, want: false}, + {input: User{Email: "foo@example.com"}, want: false}, + {input: User{IPAddress: "127.0.0.1"}, want: false}, + {input: User{Username: "My Username"}, want: false}, + {input: User{Name: "My Name"}, want: false}, + {input: User{Segment: "My Segment"}, want: false}, + {input: User{Data: map[string]string{"foo": "bar"}}, want: false}, + {input: User{ID: "foo", Email: "foo@example.com", IPAddress: "127.0.0.1", Username: "My Username", Name: "My Name", Segment: "My Segment", Data: map[string]string{"foo": "bar"}}, want: false}, + } + + for _, test := range tests { + assertEqual(t, test.input.IsEmpty(), test.want) + } +} + func TestNewRequest(t *testing.T) { const payload = `{"test_data": true}` got := NewRequest(httptest.NewRequest("POST", "/test/?q=sentry", strings.NewReader(payload))) From c09110cf8bc8b9244b9d9c5f731a461791a3bbe1 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Thu, 27 Oct 2022 12:15:38 +0200 Subject: [PATCH 5/7] Add TestUserMarhsalJson --- interfaces_test.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/interfaces_test.go b/interfaces_test.go index 262a5e86..563d5bd3 100644 --- a/interfaces_test.go +++ b/interfaces_test.go @@ -40,6 +40,31 @@ func TestIsEmpty(t *testing.T) { } } +func TestUserMarhsalJson(t *testing.T) { + tests := []struct { + input User + want string + }{ + {input: User{}, want: `{}`}, + {input: User{ID: "foo"}, want: `{"id":"foo"}`}, + {input: User{Email: "foo@example.com"}, want: `{"email":"foo@example.com"}`}, + {input: User{IPAddress: "127.0.0.1"}, want: `{"ip_address":"127.0.0.1"}`}, + {input: User{Username: "My Username"}, want: `{"username":"My Username"}`}, + {input: User{Name: "My Name"}, want: `{"name":"My Name"}`}, + {input: User{Segment: "My Segment"}, want: `{"segment":"My Segment"}`}, + {input: User{Data: map[string]string{"foo": "bar"}}, want: `{"data":{"foo":"bar"}}`}, + } + + for _, test := range tests { + got, err := json.Marshal(test.input) + if err != nil { + t.Fatal(err) + } + + assertEqual(t, string(got), test.want) + } +} + func TestNewRequest(t *testing.T) { const payload = `{"test_data": true}` got := NewRequest(httptest.NewRequest("POST", "/test/?q=sentry", strings.NewReader(payload))) From a230779275ab4db15c1b378f2fe1a8fbcc19c8fd Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Thu, 27 Oct 2022 12:25:38 +0200 Subject: [PATCH 6/7] Update interfaces_test.go Co-authored-by: Abhijeet Prasad --- interfaces_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces_test.go b/interfaces_test.go index 563d5bd3..08b4d48a 100644 --- a/interfaces_test.go +++ b/interfaces_test.go @@ -40,7 +40,7 @@ func TestIsEmpty(t *testing.T) { } } -func TestUserMarhsalJson(t *testing.T) { +func TestUserMarshalJson(t *testing.T) { tests := []struct { input User want string From ddf0930917c0cbeed33b107f86703eab7ff23a47 Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Thu, 27 Oct 2022 12:27:13 +0200 Subject: [PATCH 7/7] Update interfaces_test.go Co-authored-by: Abhijeet Prasad --- interfaces_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces_test.go b/interfaces_test.go index 08b4d48a..ca48ae8e 100644 --- a/interfaces_test.go +++ b/interfaces_test.go @@ -19,7 +19,7 @@ var ( generate = flag.Bool("gen", false, "generate missing .golden files") ) -func TestIsEmpty(t *testing.T) { +func TestUserIsEmpty(t *testing.T) { tests := []struct { input User want bool