From b17786f2cec52a409316070df40f8d83d66c4165 Mon Sep 17 00:00:00 2001 From: Anton Novojilov Date: Wed, 30 Oct 2024 17:01:54 +0300 Subject: [PATCH 1/5] Add helper Tags.Names --- pachca.go | 11 +++++++++++ pachca_test.go | 2 ++ 2 files changed, 13 insertions(+) diff --git a/pachca.go b/pachca.go index 1982d86..b1aab75 100644 --- a/pachca.go +++ b/pachca.go @@ -1949,6 +1949,17 @@ func (t Tags) Get(id uint64) *Tag { return nil } +// Names returns names of all tags +func (t Tags) Names() []string { + var result []string + + for _, tt := range t { + result = append(result, tt.Name) + } + + return result +} + // InChat only returns tags that are present in the given chat func (t Tags) InChat(chat *Chat) Tags { if chat == nil { diff --git a/pachca_test.go b/pachca_test.go index 20a6cd7..05f5a2c 100644 --- a/pachca_test.go +++ b/pachca_test.go @@ -444,6 +444,8 @@ func (s *PachcaSuite) TestTagsHelpers(c *C) { c.Assert(tt.InChat(nil), IsNil) c.Assert(tt.InChat(chat), HasLen, 3) + + c.Assert(tt.Names(), DeepEquals, []string{"Test1", "Test2", "Test3"}) } func (s *PachcaSuite) TestURLHelpers(c *C) { From 8643575b672ff402aeefbbee2abe801c60e92437 Mon Sep 17 00:00:00 2001 From: Anton Novojilov Date: Thu, 31 Oct 2024 11:49:25 +0300 Subject: [PATCH 2/5] Make all 'Find' helpers case-insensitive --- pachca.go | 26 +++++++++++++++++++++++--- pachca_test.go | 10 +++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/pachca.go b/pachca.go index b1aab75..00da59f 100644 --- a/pachca.go +++ b/pachca.go @@ -1588,8 +1588,10 @@ func (p Properties) HasAny(name ...string) bool { // Find returns custom property with given name func (p Properties) Find(name string) *Property { + name = strings.ToLower(name) + for _, pp := range p { - if pp.Name == name { + if strings.ToLower(pp.Name) == name { return pp } } @@ -1764,8 +1766,11 @@ func (u Users) InChat(chat *Chat) Users { // Find returns user with given nickname or email func (u Users) Find(nicknameOrEmail string) *User { + nicknameOrEmail = strings.ToLower(nicknameOrEmail) + for _, uu := range u { - if uu.Nickname == nicknameOrEmail || uu.Email == nicknameOrEmail { + if strings.ToLower(uu.Nickname) == nicknameOrEmail || + strings.ToLower(uu.Email) == nicknameOrEmail { return uu } } @@ -1877,8 +1882,10 @@ func (c Chats) Get(id uint64) *Chat { // Find returns chat with given name func (c Chats) Find(name string) *Chat { + name = strings.ToLower(name) + for _, cc := range c { - if cc.Name == name { + if strings.ToLower(cc.Name) == name { return cc } } @@ -1949,6 +1956,19 @@ func (t Tags) Get(id uint64) *Tag { return nil } +// Find returns tag with given name +func (t Tags) Find(name string) *Tag { + name = strings.ToLower(name) + + for _, tt := range t { + if strings.ToLower(tt.Name) == name { + return tt + } + } + + return nil +} + // Names returns names of all tags func (t Tags) Names() []string { var result []string diff --git a/pachca_test.go b/pachca_test.go index 05f5a2c..210b2eb 100644 --- a/pachca_test.go +++ b/pachca_test.go @@ -346,7 +346,7 @@ func (s *PachcaSuite) TestPropertiesHelpers(c *C) { _, err = p.Find("test5").ToInt() c.Assert(err, IsNil) - _, err = p.Find("test2").ToInt() + _, err = p.Find("TEST2").ToInt() c.Assert(err, NotNil) var pp *Property @@ -399,7 +399,7 @@ func (s *PachcaSuite) TestUsersHelpers(c *C) { c.Assert(uu.Find("test"), IsNil) c.Assert(uu.Find("j.doe"), NotNil) - c.Assert(uu.Find("test@example.com"), NotNil) + c.Assert(uu.Find("TEST@EXAMPLE.COM"), NotNil) c.Assert(uu.Get(100), IsNil) c.Assert(uu.Get(6).ID, Equals, uint64(6)) @@ -421,7 +421,7 @@ func (s *PachcaSuite) TestChatsHelpers(c *C) { c.Assert(cc.Get(100), IsNil) c.Assert(cc.Find("test"), IsNil) - c.Assert(cc.Find("test1"), NotNil) + c.Assert(cc.Find("TEST1"), NotNil) c.Assert(cc.Public()[0].ID, Equals, uint64(3)) c.Assert(cc.Channels()[0].ID, Equals, uint64(4)) @@ -440,6 +440,10 @@ func (s *PachcaSuite) TestTagsHelpers(c *C) { c.Assert(tt.Get(1), NotNil) c.Assert(tt.Get(10), IsNil) + c.Assert(tt.Find("test"), IsNil) + c.Assert(tt.Find("test1"), NotNil) + c.Assert(tt.Find("test1").ID, Equals, uint64(1)) + chat := &Chat{ID: 1, Name: "test1", GroupTags: []uint64{1, 2, 3, 100, 101, 102}} c.Assert(tt.InChat(nil), IsNil) From 4982d3d926de6201a826fad94f0e5f24ed8537b8 Mon Sep 17 00:00:00 2001 From: Anton Novojilov Date: Thu, 31 Oct 2024 11:54:08 +0300 Subject: [PATCH 3/5] Make all 'Find' helpers case-insensitive --- pachca.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pachca.go b/pachca.go index 00da59f..da7964a 100644 --- a/pachca.go +++ b/pachca.go @@ -14,7 +14,6 @@ import ( "mime/multipart" "os" "regexp" - "slices" "strconv" "strings" "time" @@ -1601,9 +1600,11 @@ func (p Properties) Find(name string) *Property { // FindAny returns first found property with one of given names func (p Properties) FindAny(name ...string) *Property { - for _, pp := range p { - if slices.Contains(name, pp.Name) { - return pp + for _, n := range name { + p := p.Find(n) + + if p != nil { + return p } } From adccc01e0272d1d598208995d4eb4a7909b9b331 Mon Sep 17 00:00:00 2001 From: Anton Novojilov Date: Thu, 31 Oct 2024 17:00:25 +0300 Subject: [PATCH 4/5] Improve working with custom properties --- pachca.go | 57 +++++++++++++++++++++++++++++++++++++++----------- pachca_test.go | 9 ++++++++ 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/pachca.go b/pachca.go index da7964a..8bfce19 100644 --- a/pachca.go +++ b/pachca.go @@ -320,20 +320,29 @@ type ChatFilter struct { // UserRequest is a struct with information needed to create or modify a user type UserRequest struct { - Email string `json:"email"` - FirstName string `json:"first_name,omitempty"` - LastName string `json:"last_name,omitempty"` - Nickname string `json:"nickname,omitempty"` - Role UserRole `json:"role,omitempty"` - PhoneNumber string `json:"phone_number,omitempty"` - Title string `json:"title,omitempty"` - Department string `json:"department,omitempty"` - Properties Properties `json:"custom_properties,omitempty"` - Tags []string `json:"list_tags,omitempty"` - IsSuspended bool `json:"suspended,omitempty"` - SkipEmailNotify bool `json:"skip_email_notify,omitempty"` + Email string `json:"email"` + FirstName string `json:"first_name,omitempty"` + LastName string `json:"last_name,omitempty"` + Nickname string `json:"nickname,omitempty"` + Role UserRole `json:"role,omitempty"` + PhoneNumber string `json:"phone_number,omitempty"` + Title string `json:"title,omitempty"` + Department string `json:"department,omitempty"` + Properties PropertyRequests `json:"custom_properties,omitempty"` + Tags []string `json:"list_tags,omitempty"` + IsSuspended bool `json:"suspended,omitempty"` + SkipEmailNotify bool `json:"skip_email_notify,omitempty"` } +// PropertyRequest is a struct with property info +type PropertyRequest struct { + ID uint64 + Value string +} + +// PropertyRequests is a slice with properties requests +type PropertyRequests []*PropertyRequest + // ChatRequest is a struct with information needed to create or modify a chat type ChatRequest struct { Name string `json:"name"` @@ -443,6 +452,30 @@ func NewClient(token string) (*Client, error) { }, nil } +// NewPropertyRequest creates new custom property +func NewPropertyRequest(id uint64, value any) *PropertyRequest { + var v string + + switch t := value.(type) { + case time.Time: + v = formatDate(t.UTC()) + + case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: + v = fmt.Sprintf("%d", value) + + case float32: + v = fmt.Sprintf("%d", int64(t)) + + case float64: + v = fmt.Sprintf("%d", int64(t)) + + default: + v = fmt.Sprintf("%v", value) + } + + return &PropertyRequest{ID: id, Value: v} +} + // ValidateToken validates API access token func ValidateToken(token string) error { switch { diff --git a/pachca_test.go b/pachca_test.go index 210b2eb..51bc462 100644 --- a/pachca_test.go +++ b/pachca_test.go @@ -163,6 +163,15 @@ func (s *PachcaSuite) TestNilClient(c *C) { c.Assert(err, Equals, ErrNilClient) } +func (s *PachcaSuite) TestNewPropertyRequest(c *C) { + c.Assert(NewPropertyRequest(1, "test").Value, Equals, "test") + c.Assert(NewPropertyRequest(1, 100).Value, Equals, "100") + c.Assert(NewPropertyRequest(1, float32(100.12)).Value, Equals, "100") + c.Assert(NewPropertyRequest(1, float64(100.12)).Value, Equals, "100") + c.Assert(NewPropertyRequest(1, time.Date(2020, 1, 1, 12, 0, 0, 0, time.UTC)).Value, Equals, "2020-01-01T12:00:00Z") + c.Assert(NewPropertyRequest(1, true).Value, Equals, "true") +} + func (s *PachcaSuite) TestErrors(c *C) { cc, err := NewClient("YQlf-6Vce7jM1RMZZUs_iWKYPt24PeR4c7k_RwzqjI5") c.Assert(cc, NotNil) From 0c45d61371d5186c881af512838f15a98fdd2f26 Mon Sep 17 00:00:00 2001 From: Anton Novojilov Date: Thu, 31 Oct 2024 22:40:35 +0300 Subject: [PATCH 5/5] Fix PropertyRequest json fields --- pachca.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pachca.go b/pachca.go index 8bfce19..00e744a 100644 --- a/pachca.go +++ b/pachca.go @@ -336,8 +336,8 @@ type UserRequest struct { // PropertyRequest is a struct with property info type PropertyRequest struct { - ID uint64 - Value string + ID uint64 `json:"id"` + Value string `json:"value"` } // PropertyRequests is a slice with properties requests