From 0e6bfbdd261ef983c69f30ef6d1000c12a1e3726 Mon Sep 17 00:00:00 2001 From: Ben Schumacher Date: Mon, 8 Jul 2024 21:25:21 +0200 Subject: [PATCH] [MM-57963] Log Name and DisplayName of groups (#26836) --- server/public/model/builtin.go | 10 +++ server/public/model/builtin_test.go | 39 ++++++++++++ server/public/model/group.go | 36 +++++++---- server/public/model/group_test.go | 99 +++++++++++++++++++++++++++++ 4 files changed, 171 insertions(+), 13 deletions(-) create mode 100644 server/public/model/builtin_test.go create mode 100644 server/public/model/group_test.go diff --git a/server/public/model/builtin.go b/server/public/model/builtin.go index 38e01f8b2c..4b268954aa 100644 --- a/server/public/model/builtin.go +++ b/server/public/model/builtin.go @@ -7,3 +7,13 @@ func NewBool(b bool) *bool { return &b } func NewInt(n int) *int { return &n } func NewInt64(n int64) *int64 { return &n } func NewString(s string) *string { return &s } + +// SafeDereference returns the zero value of T if t is nil. +// Otherwise it return the derference of t. +func SafeDereference[T any](t *T) T { + if t == nil { + var t T + return t + } + return *t +} diff --git a/server/public/model/builtin_test.go b/server/public/model/builtin_test.go new file mode 100644 index 0000000000..8212173e43 --- /dev/null +++ b/server/public/model/builtin_test.go @@ -0,0 +1,39 @@ +package model + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSafeDereference(t *testing.T) { + t.Run("any", func(t *testing.T) { + s := SafeDereference[any](nil) + assert.Nil(t, s) + }) + + t.Run("struct", func(t *testing.T) { + s := SafeDereference[struct{}](nil) + assert.Equal(t, struct{}{}, s) + + s = SafeDereference(&struct{}{}) + assert.Equal(t, struct{}{}, s) + }) + + t.Run("string", func(t *testing.T) { + s := SafeDereference[string](nil) + assert.Equal(t, "", s) + + s = SafeDereference(NewString("foo")) + assert.Equal(t, "foo", s) + }) + + t.Run("string pointer", func(t *testing.T) { + s := SafeDereference[*string](nil) + assert.Nil(t, s) + + f := NewString("foo") + s = SafeDereference(&f) + assert.Equal(t, f, s) + }) +} diff --git a/server/public/model/group.go b/server/public/model/group.go index 9fced06836..95f3576324 100644 --- a/server/public/model/group.go +++ b/server/public/model/group.go @@ -52,18 +52,30 @@ func (group *Group) Auditable() map[string]interface{} { return map[string]interface{}{ "id": group.Id, "source": group.Source, - "remote_id": group.RemoteId, + "remote_id": group.GetRemoteId(), "create_at": group.CreateAt, "update_at": group.UpdateAt, "delete_at": group.DeleteAt, "has_syncables": group.HasSyncables, - "member_count": group.MemberCount, + "member_count": group.GetMemberCount(), "allow_reference": group.AllowReference, } } func (group *Group) LogClone() any { - return group.Auditable() + return map[string]interface{}{ + "id": group.Id, + "name": group.GetName(), + "display_name": group.DisplayName, + "source": group.Source, + "remote_id": group.GetRemoteId(), + "create_at": group.CreateAt, + "update_at": group.UpdateAt, + "delete_at": group.DeleteAt, + "has_syncables": group.HasSyncables, + "member_count": group.GetMemberCount(), + "allow_reference": group.AllowReference, + } } type GroupWithUserIds struct { @@ -75,12 +87,12 @@ func (group *GroupWithUserIds) Auditable() map[string]interface{} { return map[string]interface{}{ "id": group.Id, "source": group.Source, - "remote_id": group.RemoteId, + "remote_id": group.GetRemoteId(), "create_at": group.CreateAt, "update_at": group.UpdateAt, "delete_at": group.DeleteAt, "has_syncables": group.HasSyncables, - "member_count": group.MemberCount, + "member_count": group.GetMemberCount(), "allow_reference": group.AllowReference, "user_ids": group.UserIds, } @@ -268,17 +280,15 @@ func (group *Group) IsValidName() *AppError { } func (group *Group) GetName() string { - if group.Name == nil { - return "" - } - return *group.Name + return SafeDereference(group.Name) } func (group *Group) GetRemoteId() string { - if group.RemoteId == nil { - return "" - } - return *group.RemoteId + return SafeDereference(group.RemoteId) +} + +func (group *Group) GetMemberCount() int { + return SafeDereference(group.MemberCount) } type GroupsWithCount struct { diff --git a/server/public/model/group_test.go b/server/public/model/group_test.go new file mode 100644 index 0000000000..cde022cef3 --- /dev/null +++ b/server/public/model/group_test.go @@ -0,0 +1,99 @@ +package model + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGroupAuditable(t *testing.T) { + t.Run("zero value", func(t *testing.T) { + var g Group + m := g.Auditable() + require.NotNil(t, m) + assert.Equal(t, "", m["remote_id"]) + }) + + t.Run("values set", func(t *testing.T) { + id := NewId() + now := GetMillis() + g := Group{ + Id: id, + Name: NewString("some name"), + DisplayName: "some display name", + Source: GroupSourceLdap, + RemoteId: NewString("some_remote"), + CreateAt: now, + UpdateAt: now, + DeleteAt: now, + HasSyncables: true, + MemberCount: NewInt(10), + AllowReference: true, + } + m := g.Auditable() + + expected := map[string]any{ + "id": id, + "source": GroupSourceLdap, + "remote_id": "some_remote", + "create_at": now, + "update_at": now, + "delete_at": now, + "has_syncables": true, + "member_count": 10, + "allow_reference": true, + } + + assert.Equal(t, expected, m) + }) +} + +func TestGroupLogClone(t *testing.T) { + t.Run("zero value", func(t *testing.T) { + var g Group + l := g.LogClone() + require.NotNil(t, l) + + m, ok := l.(map[string]interface{}) + require.True(t, ok) + assert.Equal(t, "", m["remote_id"]) + }) + + t.Run("values set", func(t *testing.T) { + id := NewId() + now := GetMillis() + g := Group{ + Id: id, + Name: NewString("some name"), + DisplayName: "some display name", + Source: GroupSourceLdap, + RemoteId: NewString("some_remote"), + CreateAt: now, + UpdateAt: now, + DeleteAt: now, + HasSyncables: true, + MemberCount: NewInt(10), + AllowReference: true, + } + l := g.LogClone() + m, ok := l.(map[string]interface{}) + require.True(t, ok) + + expected := map[string]any{ + "id": id, + "name": "some name", + "display_name": "some display name", + "source": GroupSourceLdap, + "remote_id": "some_remote", + "create_at": now, + "update_at": now, + "delete_at": now, + "has_syncables": true, + "member_count": 10, + "allow_reference": true, + } + + assert.Equal(t, expected, m) + }) +}