Support user profile's custom fields
https://github.com/nlopes/slack/pull/298#pullrequestreview-116493858
Suzuki Shunsuke authored 6 years ago
James committed 6 years ago
17 | 17 | |
18 | 18 | // UserProfile contains all the information details of a given user |
19 | 19 | type UserProfile struct { |
20 | FirstName string `json:"first_name"` | |
21 | LastName string `json:"last_name"` | |
22 | RealName string `json:"real_name"` | |
23 | RealNameNormalized string `json:"real_name_normalized"` | |
24 | DisplayName string `json:"display_name"` | |
25 | DisplayNameNormalized string `json:"display_name_normalized"` | |
26 | Email string `json:"email"` | |
27 | Skype string `json:"skype"` | |
28 | Phone string `json:"phone"` | |
29 | Image24 string `json:"image_24"` | |
30 | Image32 string `json:"image_32"` | |
31 | Image48 string `json:"image_48"` | |
32 | Image72 string `json:"image_72"` | |
33 | Image192 string `json:"image_192"` | |
34 | ImageOriginal string `json:"image_original"` | |
35 | Title string `json:"title"` | |
36 | BotID string `json:"bot_id,omitempty"` | |
37 | ApiAppID string `json:"api_app_id,omitempty"` | |
38 | StatusText string `json:"status_text,omitempty"` | |
39 | StatusEmoji string `json:"status_emoji,omitempty"` | |
40 | Team string `json:"team"` | |
20 | FirstName string `json:"first_name"` | |
21 | LastName string `json:"last_name"` | |
22 | RealName string `json:"real_name"` | |
23 | RealNameNormalized string `json:"real_name_normalized"` | |
24 | DisplayName string `json:"display_name"` | |
25 | DisplayNameNormalized string `json:"display_name_normalized"` | |
26 | Email string `json:"email"` | |
27 | Skype string `json:"skype"` | |
28 | Phone string `json:"phone"` | |
29 | Image24 string `json:"image_24"` | |
30 | Image32 string `json:"image_32"` | |
31 | Image48 string `json:"image_48"` | |
32 | Image72 string `json:"image_72"` | |
33 | Image192 string `json:"image_192"` | |
34 | ImageOriginal string `json:"image_original"` | |
35 | Title string `json:"title"` | |
36 | BotID string `json:"bot_id,omitempty"` | |
37 | ApiAppID string `json:"api_app_id,omitempty"` | |
38 | StatusText string `json:"status_text,omitempty"` | |
39 | StatusEmoji string `json:"status_emoji,omitempty"` | |
40 | Team string `json:"team"` | |
41 | Fields UserProfileCustomFields `json:"fields"` | |
42 | } | |
43 | ||
44 | // UserProfileCustomFields represents user profile's custom fields. | |
45 | // Slack API's response data type is inconsistent so we use the struct. | |
46 | // For detail, please see below. | |
47 | // https://github.com/nlopes/slack/pull/298#discussion_r185159233 | |
48 | type UserProfileCustomFields struct { | |
49 | fields map[string]UserProfileCustomField | |
50 | } | |
51 | ||
52 | // UnmarshalJSON is the implementation of the json.Unmarshaler interface. | |
53 | func (fields *UserProfileCustomFields) UnmarshalJSON(b []byte) error { | |
54 | // https://github.com/nlopes/slack/pull/298#discussion_r185159233 | |
55 | if string(b) == "[]" { | |
56 | return nil | |
57 | } | |
58 | return json.Unmarshal(b, &fields.fields) | |
59 | } | |
60 | ||
61 | // MarshalJSON is the implementation of the json.Marshaler interface. | |
62 | func (fields UserProfileCustomFields) MarshalJSON() ([]byte, error) { | |
63 | if len(fields.fields) == 0 { | |
64 | return []byte("[]"), nil | |
65 | } | |
66 | return json.Marshal(fields.fields) | |
67 | } | |
68 | ||
69 | // ToMap returns a map of custom fields. | |
70 | func (fields *UserProfileCustomFields) ToMap() map[string]UserProfileCustomField { | |
71 | return fields.fields | |
72 | } | |
73 | ||
74 | // Len returns the number of custom fields. | |
75 | func (fields *UserProfileCustomFields) Len() int { | |
76 | return len(fields.fields) | |
77 | } | |
78 | ||
79 | // SetMap sets a map of custom fields. | |
80 | func (fields *UserProfileCustomFields) SetMap(m map[string]UserProfileCustomField) { | |
81 | fields.fields = m | |
82 | } | |
83 | ||
84 | // FieldsMap returns a map of custom fields. | |
85 | func (profile *UserProfile) FieldsMap() map[string]UserProfileCustomField { | |
86 | return profile.Fields.ToMap() | |
87 | } | |
88 | ||
89 | // SetFieldsMap sets a map of custom fields. | |
90 | func (profile *UserProfile) SetFieldsMap(m map[string]UserProfileCustomField) { | |
91 | profile.Fields.SetMap(m) | |
92 | } | |
93 | ||
94 | // UserProfileCustomField represents a custom user profile field | |
95 | type UserProfileCustomField struct { | |
96 | Value string `json:"value"` | |
97 | Alt string `json:"alt"` | |
98 | Label string `json:"label"` | |
41 | 99 | } |
42 | 100 | |
43 | 101 | // User contains all the information of a user |
16 | 16 | "testing" |
17 | 17 | ) |
18 | 18 | |
19 | func getTestUserProfileCustomField() UserProfileCustomField { | |
20 | return UserProfileCustomField{ | |
21 | Value: "test value", | |
22 | Alt: "", | |
23 | Label: "", | |
24 | } | |
25 | } | |
26 | ||
27 | func getTestUserProfileCustomFields() UserProfileCustomFields { | |
28 | return UserProfileCustomFields{ | |
29 | fields: map[string]UserProfileCustomField{ | |
30 | "Xxxxxx": getTestUserProfileCustomField(), | |
31 | }} | |
32 | } | |
33 | ||
19 | 34 | func getTestUserProfile() UserProfile { |
20 | 35 | return UserProfile{ |
21 | 36 | StatusText: "testStatus", |
30 | 45 | Image48: "https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2016-10-18/92962080834_ef14c1469fc0741caea1_48.jpg", |
31 | 46 | Image72: "https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2016-10-18/92962080834_ef14c1469fc0741caea1_72.jpg", |
32 | 47 | Image192: "https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2016-10-18/92962080834_ef14c1469fc0741caea1_192.jpg", |
48 | Fields: getTestUserProfileCustomFields(), | |
33 | 49 | } |
34 | 50 | } |
35 | 51 | |
89 | 105 | func getUserByEmail(rw http.ResponseWriter, r *http.Request) { |
90 | 106 | rw.Header().Set("Content-Type", "application/json") |
91 | 107 | response, _ := json.Marshal(struct { |
92 | Ok bool | |
93 | User User | |
108 | Ok bool `json:"ok"` | |
109 | User User `json:"user"` | |
94 | 110 | }{ |
95 | 111 | Ok: true, |
96 | 112 | User: getTestUser(), |
431 | 447 | t.Fatalf(`profile.DisplayName = "%s", wanted "%s"`, profile.DisplayName, exp.DisplayName) |
432 | 448 | } |
433 | 449 | } |
450 | ||
451 | func TestSetFieldsMap(t *testing.T) { | |
452 | p := &UserProfile{} | |
453 | exp := map[string]UserProfileCustomField{ | |
454 | "Xxxxxx": getTestUserProfileCustomField(), | |
455 | } | |
456 | p.SetFieldsMap(exp) | |
457 | act := p.FieldsMap() | |
458 | if !reflect.DeepEqual(act, exp) { | |
459 | t.Fatalf(`p.FieldsMap() = %v, wanted %v`, act, exp) | |
460 | } | |
461 | } | |
462 | ||
463 | func TestUserProfileCustomFieldsUnmarshalJSON(t *testing.T) { | |
464 | fields := &UserProfileCustomFields{} | |
465 | if err := json.Unmarshal([]byte(`[]`), fields); err != nil { | |
466 | t.Fatal(err) | |
467 | } | |
468 | if err := json.Unmarshal([]byte(`{ | |
469 | "Xxxxxx": { | |
470 | "value": "test value", | |
471 | "alt": "" | |
472 | } | |
473 | }`), fields); err != nil { | |
474 | t.Fatal(err) | |
475 | } | |
476 | act := fields.ToMap()["Xxxxxx"].Value | |
477 | exp := "test value" | |
478 | if act != exp { | |
479 | t.Fatalf(`fields.ToMap()["Xxxxxx"]["value"] = "%s", wanted "%s"`, act, exp) | |
480 | } | |
481 | } | |
482 | ||
483 | func TestUserProfileCustomFieldsMarshalJSON(t *testing.T) { | |
484 | fields := UserProfileCustomFields{} | |
485 | b, err := json.Marshal(fields) | |
486 | if err != nil { | |
487 | t.Fatal(err) | |
488 | } | |
489 | if string(b) != "[]" { | |
490 | t.Fatalf(`string(b) = "%s", wanted "[]"`, string(b)) | |
491 | } | |
492 | fields = getTestUserProfileCustomFields() | |
493 | if _, err := json.Marshal(fields); err != nil { | |
494 | t.Fatal(err) | |
495 | } | |
496 | } | |
497 | ||
498 | func TestUserProfileCustomFieldsToMap(t *testing.T) { | |
499 | m := map[string]UserProfileCustomField{ | |
500 | "Xxxxxx": getTestUserProfileCustomField(), | |
501 | } | |
502 | fields := UserProfileCustomFields{fields: m} | |
503 | act := fields.ToMap() | |
504 | if !reflect.DeepEqual(act, m) { | |
505 | t.Fatalf(`fields.ToMap() = %v, wanted %v`, act, m) | |
506 | } | |
507 | } | |
508 | ||
509 | func TestUserProfileCustomFieldsLen(t *testing.T) { | |
510 | fields := UserProfileCustomFields{ | |
511 | fields: map[string]UserProfileCustomField{ | |
512 | "Xxxxxx": getTestUserProfileCustomField(), | |
513 | }} | |
514 | if fields.Len() != 1 { | |
515 | t.Fatalf(`fields.Len() = %d, wanted 1`, fields.Len()) | |
516 | } | |
517 | } | |
518 | ||
519 | func TestUserProfileCustomFieldsSetMap(t *testing.T) { | |
520 | fields := UserProfileCustomFields{} | |
521 | m := map[string]UserProfileCustomField{ | |
522 | "Xxxxxx": getTestUserProfileCustomField(), | |
523 | } | |
524 | fields.SetMap(m) | |
525 | if !reflect.DeepEqual(fields.fields, m) { | |
526 | t.Fatalf(`fields.fields = %v, wanted %v`, fields.fields, m) | |
527 | } | |
528 | } |