From d0e9df71965f65be44ceed38c9ba06c83f43a89d Mon Sep 17 00:00:00 2001 From: mlnm-capco <81622370+mlnm-capco@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:35:51 +0100 Subject: [PATCH 1/3] feat: User profiles - create and lookup --- .../java/org/zendesk/client/v2/Zendesk.java | 66 +++++-- .../zendesk/client/v2/model/UserProfile.java | 183 ++++++++++++++++++ .../client/v2/model/UserProfileTest.java | 48 +++++ 3 files changed, 277 insertions(+), 20 deletions(-) create mode 100644 src/main/java/org/zendesk/client/v2/model/UserProfile.java create mode 100644 src/test/java/org/zendesk/client/v2/model/UserProfileTest.java diff --git a/src/main/java/org/zendesk/client/v2/Zendesk.java b/src/main/java/org/zendesk/client/v2/Zendesk.java index 26d5e8e9..03ac693d 100644 --- a/src/main/java/org/zendesk/client/v2/Zendesk.java +++ b/src/main/java/org/zendesk/client/v2/Zendesk.java @@ -8,26 +8,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.util.StdDateFormat; -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.function.Function; import org.asynchttpclient.AsyncCompletionHandler; import org.asynchttpclient.AsyncHttpClient; import org.asynchttpclient.DefaultAsyncHttpClient; @@ -80,6 +60,7 @@ import org.zendesk.client.v2.model.TwitterMonitor; import org.zendesk.client.v2.model.User; import org.zendesk.client.v2.model.UserField; +import org.zendesk.client.v2.model.UserProfile; import org.zendesk.client.v2.model.UserRelatedInfo; import org.zendesk.client.v2.model.View; import org.zendesk.client.v2.model.dynamic.DynamicContentItem; @@ -104,6 +85,27 @@ import org.zendesk.client.v2.model.targets.TwitterTarget; import org.zendesk.client.v2.model.targets.UrlTarget; +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; + /** * @author stephenc * @since 04/04/2013 13:08 @@ -1344,6 +1346,30 @@ public void changeUserPassword(User user, String oldPassword, String newPassword handleStatus())); } + public UserProfile createUserProfile(UserProfile userProfile) { + String idQuery = String.format( + "%s:%s:%s:%s", + userProfile.getSource(), + userProfile.getType(), + userProfile.getIdentifiers().get(0).getType(), + userProfile.getIdentifiers().get(0).getValue()); + + return complete( + submit( + req( + "PUT", + tmpl("/user_profiles?identifier={idQuery}") + .set("idQuery", idQuery), + JSON, + json(Collections.singletonMap("profile", userProfile))), + handle(UserProfile.class, "profile"))); + } + + public List getUserProfilesForUser(User user) { + return complete( + submit(req("GET", tmpl("/users/{user_id}/profiles").set("user_id", user.getId())), handleList(UserProfile.class, "profiles"))); + } + public List getUserIdentities(User user) { checkHasId(user); return getUserIdentities(user.getId()); diff --git a/src/main/java/org/zendesk/client/v2/model/UserProfile.java b/src/main/java/org/zendesk/client/v2/model/UserProfile.java new file mode 100644 index 00000000..207199ad --- /dev/null +++ b/src/main/java/org/zendesk/client/v2/model/UserProfile.java @@ -0,0 +1,183 @@ +package org.zendesk.client.v2.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public class UserProfile implements SearchResultEntity, Serializable { + + private Map attributes; + private Date createdAt; + private String id; + private List identifiers; + private String name; + private String source; + private String type; + private Date updatedAt; + private String userId; + + public UserProfile( + Map attributes, + Date createdAt, + String id, + List identifiers, + String name, + String source, + String type, + Date updatedAt, + String userId) { + + this.attributes = attributes; + this.createdAt = createdAt; + this.id = id; + this.identifiers = identifiers; + this.name = name; + this.source = source; + this.type = type; + this.updatedAt = updatedAt; + this.userId = userId; + } + + public UserProfile() {} + + public static class Identifier { + + private String type; + private String value; + + public Identifier() { + } + + public Identifier(String type, String value) { + + this.type = type; + this.value = value; + } + + public String getType() { + + return type; + } + + public String getValue() { + + return value; + } + + @Override + public boolean equals(Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Identifier that = (Identifier) o; + return Objects.equals(type, that.type) && Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + + return Objects.hash(type, value); + } + + @Override + public String toString() { + + return "Identifier{" + + "type='" + type + '\'' + + ", value='" + value + '\'' + + '}'; + } + } + + public Map getAttributes() { + + return attributes; + } + + + @JsonProperty("created_at") + public Date getCreatedAt() { + + return createdAt; + } + + public String getId() { + + return id; + } + + public List getIdentifiers() { + + return identifiers; + } + + public String getName() { + + return name; + } + + public String getSource() { + + return source; + } + + public String getType() { + + return type; + } + + @JsonProperty("updated_at") + public Date getUpdatedAt() { + + return updatedAt; + } + + @JsonProperty("user_id") + public String getUserId() { + + return userId; + } + + @Override + public boolean equals(Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UserProfile that = (UserProfile) o; + return Objects.equals(attributes, that.attributes) && Objects.equals(createdAt, that.createdAt) && Objects.equals(id, that.id) && Objects.equals(identifiers, that.identifiers) && Objects.equals(name, that.name) && Objects.equals(source, that.source) && Objects.equals(type, that.type) && Objects.equals(updatedAt, that.updatedAt) && Objects.equals(userId, that.userId); + } + + @Override + public int hashCode() { + + return Objects.hash(attributes, createdAt, id, identifiers, name, source, type, updatedAt, userId); + } + + @Override + public String toString() { + + return "UserProfile{" + + "attributes=" + attributes + + ", created_at=" + createdAt + + ", id='" + id + '\'' + + ", identifiers=" + identifiers + + ", name='" + name + '\'' + + ", source='" + source + '\'' + + ", type='" + type + '\'' + + ", updated_at=" + updatedAt + + ", user_id='" + userId + '\'' + + '}'; + } +} diff --git a/src/test/java/org/zendesk/client/v2/model/UserProfileTest.java b/src/test/java/org/zendesk/client/v2/model/UserProfileTest.java new file mode 100644 index 00000000..af61c5fa --- /dev/null +++ b/src/test/java/org/zendesk/client/v2/model/UserProfileTest.java @@ -0,0 +1,48 @@ +package org.zendesk.client.v2.model; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; +import org.zendesk.client.v2.Zendesk; + +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +public class UserProfileTest { + + public static final Long USER_ID = 123L; + public static final String PROFILE_NAME = "name"; + + @Test + public void serializeDeserialize() throws JsonProcessingException { + ObjectMapper mapper = Zendesk.createMapper(); + String email = "user123@example.com"; + UserProfile profile = createSampleUserProfile(email); + String serialized = mapper.writeValueAsString(profile); + + UserProfile deserialized = mapper.readValue(serialized, UserProfile.class); + assertThat(deserialized.getName()).isEqualTo(PROFILE_NAME); + assertThat(deserialized.getUserId()).isEqualTo("123"); + assertThat(deserialized.getIdentifiers()).contains(new UserProfile.Identifier("email", email)); + } + + private UserProfile createSampleUserProfile(String email) { + var identifiers = List.of(new UserProfile.Identifier("email", email)); + + return new UserProfile( + Map.of("customer_ref", "ref123"), + Date.from(Instant.now()), + "12345", + identifiers, + PROFILE_NAME, + "source", + "type", + Date.from(Instant.now()), + USER_ID.toString() + ); + } +} From 0b7dea165d6cecc0aefaa26619faf82dc47e390f Mon Sep 17 00:00:00 2001 From: mlnm-capco <81622370+mlnm-capco@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:23:17 +0000 Subject: [PATCH 2/3] feat: CRUD operations for User Profiles --- .../java/org/zendesk/client/v2/Zendesk.java | 82 +++++++++++++++++-- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/zendesk/client/v2/Zendesk.java b/src/main/java/org/zendesk/client/v2/Zendesk.java index 03ac693d..0d2e6e3d 100644 --- a/src/main/java/org/zendesk/client/v2/Zendesk.java +++ b/src/main/java/org/zendesk/client/v2/Zendesk.java @@ -1346,28 +1346,94 @@ public void changeUserPassword(User user, String oldPassword, String newPassword handleStatus())); } - public UserProfile createUserProfile(UserProfile userProfile) { - String idQuery = String.format( + public List getUserProfilesForUser(User user) { + return getUserProfilesForUser(user.getId()); + } + + public List getUserProfilesForUser(long userId) { + return complete( + submit( + req( + "GET", + tmpl("/users/{user_id}/profiles") + .set("user_id", userId)), + handleList(UserProfile.class, "profiles"))); + } + + public UserProfile getUserProfile(UserProfile userProfile) { + return getUserProfile(userProfile.getId()); + } + + public UserProfile getUserProfile(String userProfileId) { + return complete( + submit( + req( + "GET", + tmpl("/user_profiles/{profile_id}") + .set("profile_id", userProfileId)), + handle(UserProfile.class, "profile"))); + } + + public UserProfile getUserProfilebyIdentifier(String identifier) { + return complete( + submit( + req( + "GET", + tmpl("/user_profiles?identifier={identifier}") + .set("identifier", identifier)), + handle(UserProfile.class, "profile"))); + } + + public UserProfile createOrUpdateUserProfile(UserProfile userProfile) { + return createOrUpdateUserProfile(userProfile, + userProfile.getIdentifiers().get(0).getType(), + userProfile.getIdentifiers().get(0).getValue()); + } + + public UserProfile createOrUpdateUserProfile(UserProfile userProfile, String identifierType, String identifierValue) { + String identifier = String.format( "%s:%s:%s:%s", userProfile.getSource(), userProfile.getType(), - userProfile.getIdentifiers().get(0).getType(), - userProfile.getIdentifiers().get(0).getValue()); + identifierType, + identifierValue); return complete( submit( req( "PUT", - tmpl("/user_profiles?identifier={idQuery}") - .set("idQuery", idQuery), + tmpl("/user_profiles?identifier={identifier}") + .set("identifier", identifier), JSON, json(Collections.singletonMap("profile", userProfile))), handle(UserProfile.class, "profile"))); } - public List getUserProfilesForUser(User user) { + public UserProfile updateUserProfile(UserProfile userProfile) { + return complete( - submit(req("GET", tmpl("/users/{user_id}/profiles").set("user_id", user.getId())), handleList(UserProfile.class, "profiles"))); + submit( + req( + "PUT", + tmpl("/user_profiles/{profile_id}") + .set("profile_id", userProfile.getId()), + JSON, + json(Collections.singletonMap("profile", userProfile))), + handle(UserProfile.class, "profile"))); + } + + public void deleteUserProfile(UserProfile userProfile) { + deleteUserProfile(userProfile.getId()); + } + + public void deleteUserProfile(String userProfileId) { + complete( + submit( + req( + "DELETE", + tmpl("/user_profiles/{profile_id}") + .set("profile_id", userProfileId)), + handleStatus())); } public List getUserIdentities(User user) { From 46c3483c85e0932db7e957515cae4da05610ff94 Mon Sep 17 00:00:00 2001 From: mlnm-capco <81622370+mlnm-capco@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:41:12 +0000 Subject: [PATCH 3/3] add smoke tests --- .../java/org/zendesk/client/v2/Zendesk.java | 85 ++--- .../zendesk/client/v2/model/UserProfile.java | 342 +++++++++++------- .../org/zendesk/client/v2/RealSmokeTest.java | 98 +++++ .../client/v2/model/UserProfileTest.java | 73 ++-- 4 files changed, 386 insertions(+), 212 deletions(-) diff --git a/src/main/java/org/zendesk/client/v2/Zendesk.java b/src/main/java/org/zendesk/client/v2/Zendesk.java index 0d2e6e3d..ca1cdfdc 100644 --- a/src/main/java/org/zendesk/client/v2/Zendesk.java +++ b/src/main/java/org/zendesk/client/v2/Zendesk.java @@ -8,6 +8,26 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.util.StdDateFormat; +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; import org.asynchttpclient.AsyncCompletionHandler; import org.asynchttpclient.AsyncHttpClient; import org.asynchttpclient.DefaultAsyncHttpClient; @@ -85,27 +105,6 @@ import org.zendesk.client.v2.model.targets.TwitterTarget; import org.zendesk.client.v2.model.targets.UrlTarget; -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.function.Function; - /** * @author stephenc * @since 04/04/2013 13:08 @@ -1353,10 +1352,7 @@ public List getUserProfilesForUser(User user) { public List getUserProfilesForUser(long userId) { return complete( submit( - req( - "GET", - tmpl("/users/{user_id}/profiles") - .set("user_id", userId)), + req("GET", tmpl("/users/{user_id}/profiles").set("user_id", userId)), handleList(UserProfile.class, "profiles"))); } @@ -1367,10 +1363,7 @@ public UserProfile getUserProfile(UserProfile userProfile) { public UserProfile getUserProfile(String userProfileId) { return complete( submit( - req( - "GET", - tmpl("/user_profiles/{profile_id}") - .set("profile_id", userProfileId)), + req("GET", tmpl("/user_profiles/{profile_id}").set("profile_id", userProfileId)), handle(UserProfile.class, "profile"))); } @@ -1379,31 +1372,29 @@ public UserProfile getUserProfilebyIdentifier(String identifier) { submit( req( "GET", - tmpl("/user_profiles?identifier={identifier}") - .set("identifier", identifier)), + tmpl("/user_profiles?identifier={identifier}").set("identifier", identifier)), handle(UserProfile.class, "profile"))); } public UserProfile createOrUpdateUserProfile(UserProfile userProfile) { - return createOrUpdateUserProfile(userProfile, - userProfile.getIdentifiers().get(0).getType(), - userProfile.getIdentifiers().get(0).getValue()); + return createOrUpdateUserProfile( + userProfile, + userProfile.getIdentifiers().get(0).getType(), + userProfile.getIdentifiers().get(0).getValue()); } - public UserProfile createOrUpdateUserProfile(UserProfile userProfile, String identifierType, String identifierValue) { - String identifier = String.format( - "%s:%s:%s:%s", - userProfile.getSource(), - userProfile.getType(), - identifierType, - identifierValue); + public UserProfile createOrUpdateUserProfile( + UserProfile userProfile, String identifierType, String identifierValue) { + String identifier = + String.format( + "%s:%s:%s:%s", + userProfile.getSource(), userProfile.getType(), identifierType, identifierValue); return complete( submit( req( "PUT", - tmpl("/user_profiles?identifier={identifier}") - .set("identifier", identifier), + tmpl("/user_profiles?identifier={identifier}").set("identifier", identifier), JSON, json(Collections.singletonMap("profile", userProfile))), handle(UserProfile.class, "profile"))); @@ -1415,8 +1406,7 @@ public UserProfile updateUserProfile(UserProfile userProfile) { submit( req( "PUT", - tmpl("/user_profiles/{profile_id}") - .set("profile_id", userProfile.getId()), + tmpl("/user_profiles/{profile_id}").set("profile_id", userProfile.getId()), JSON, json(Collections.singletonMap("profile", userProfile))), handle(UserProfile.class, "profile"))); @@ -1429,10 +1419,7 @@ public void deleteUserProfile(UserProfile userProfile) { public void deleteUserProfile(String userProfileId) { complete( submit( - req( - "DELETE", - tmpl("/user_profiles/{profile_id}") - .set("profile_id", userProfileId)), + req("DELETE", tmpl("/user_profiles/{profile_id}").set("profile_id", userProfileId)), handleStatus())); } diff --git a/src/main/java/org/zendesk/client/v2/model/UserProfile.java b/src/main/java/org/zendesk/client/v2/model/UserProfile.java index 207199ad..6e5f074b 100644 --- a/src/main/java/org/zendesk/client/v2/model/UserProfile.java +++ b/src/main/java/org/zendesk/client/v2/model/UserProfile.java @@ -1,8 +1,8 @@ package org.zendesk.client.v2.model; import com.fasterxml.jackson.annotation.JsonProperty; - import java.io.Serializable; +import java.time.Instant; import java.util.Date; import java.util.List; import java.util.Map; @@ -10,174 +10,262 @@ public class UserProfile implements SearchResultEntity, Serializable { - private Map attributes; - private Date createdAt; - private String id; - private List identifiers; - private String name; - private String source; + private Map attributes; + private Date createdAt; + private String id; + private List identifiers; + private String name; + private String source; + private String type; + private Date updatedAt; + private String userId; + + public UserProfile( + Map attributes, + List identifiers, + String name, + String source, + String type) { + this( + attributes, + Date.from(Instant.now()), + null, + identifiers, + name, + source, + type, + Date.from(Instant.now()), + null); + } + + public UserProfile( + Map attributes, + List identifiers, + String name, + String source, + String type, + String userId) { + this( + attributes, + Date.from(Instant.now()), + null, + identifiers, + name, + source, + type, + Date.from(Instant.now()), + userId); + } + + public UserProfile( + Map attributes, + Date createdAt, + String id, + List identifiers, + String name, + String source, + String type, + Date updatedAt, + String userId) { + + this.attributes = attributes; + this.createdAt = createdAt; + this.id = id; + this.identifiers = identifiers; + this.name = name; + this.source = source; + this.type = type; + this.updatedAt = updatedAt; + this.userId = userId; + } + + public UserProfile() {} + + public static class Identifier { + private String type; - private Date updatedAt; - private String userId; - - public UserProfile( - Map attributes, - Date createdAt, - String id, - List identifiers, - String name, - String source, - String type, - Date updatedAt, - String userId) { - - this.attributes = attributes; - this.createdAt = createdAt; - this.id = id; - this.identifiers = identifiers; - this.name = name; - this.source = source; - this.type = type; - this.updatedAt = updatedAt; - this.userId = userId; + private String value; + + public Identifier() {} + + public Identifier(String type, String value) { + + this.type = type; + this.value = value; } - public UserProfile() {} + public String getType() { - public static class Identifier { + return type; + } - private String type; - private String value; + public String getValue() { - public Identifier() { - } + return value; + } - public Identifier(String type, String value) { + @Override + public boolean equals(Object o) { - this.type = type; - this.value = value; - } + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Identifier that = (Identifier) o; + return Objects.equals(type, that.type) && Objects.equals(value, that.value); + } - public String getType() { + @Override + public int hashCode() { - return type; - } + return Objects.hash(type, value); + } - public String getValue() { + @Override + public String toString() { - return value; - } + return "Identifier{" + "type='" + type + '\'' + ", value='" + value + '\'' + '}'; + } + } - @Override - public boolean equals(Object o) { + public Map getAttributes() { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Identifier that = (Identifier) o; - return Objects.equals(type, that.type) && Objects.equals(value, that.value); - } + return attributes; + } - @Override - public int hashCode() { + @JsonProperty("created_at") + public Date getCreatedAt() { - return Objects.hash(type, value); - } + return createdAt; + } - @Override - public String toString() { + public String getId() { - return "Identifier{" + - "type='" + type + '\'' + - ", value='" + value + '\'' + - '}'; - } - } + return id; + } - public Map getAttributes() { + public List getIdentifiers() { - return attributes; - } + return identifiers; + } + public String getName() { - @JsonProperty("created_at") - public Date getCreatedAt() { + return name; + } - return createdAt; - } + public String getSource() { - public String getId() { + return source; + } - return id; - } + public String getType() { - public List getIdentifiers() { + return type; + } - return identifiers; - } + @JsonProperty("updated_at") + public Date getUpdatedAt() { - public String getName() { + return updatedAt; + } - return name; - } + @JsonProperty("user_id") + public String getUserId() { - public String getSource() { + return userId; + } - return source; - } + public void addAttribute(String key, Object value) { + this.attributes.put(key, Objects.requireNonNull(value)); + } - public String getType() { + public void setAttributes(Map attributes) { - return type; - } + this.attributes = attributes; + } - @JsonProperty("updated_at") - public Date getUpdatedAt() { + public void addIdentifier(Identifier identifier) { + this.identifiers.add(identifier); + } - return updatedAt; - } + public void setIdentifiers(List identifiers) { - @JsonProperty("user_id") - public String getUserId() { + this.identifiers = identifiers; + } - return userId; - } + public void setName(String name) { - @Override - public boolean equals(Object o) { + this.name = name; + } - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - UserProfile that = (UserProfile) o; - return Objects.equals(attributes, that.attributes) && Objects.equals(createdAt, that.createdAt) && Objects.equals(id, that.id) && Objects.equals(identifiers, that.identifiers) && Objects.equals(name, that.name) && Objects.equals(source, that.source) && Objects.equals(type, that.type) && Objects.equals(updatedAt, that.updatedAt) && Objects.equals(userId, that.userId); - } + public void setType(String type) { - @Override - public int hashCode() { + this.type = type; + } - return Objects.hash(attributes, createdAt, id, identifiers, name, source, type, updatedAt, userId); - } + public void setSource(String source) { - @Override - public String toString() { + this.source = source; + } - return "UserProfile{" + - "attributes=" + attributes + - ", created_at=" + createdAt + - ", id='" + id + '\'' + - ", identifiers=" + identifiers + - ", name='" + name + '\'' + - ", source='" + source + '\'' + - ", type='" + type + '\'' + - ", updated_at=" + updatedAt + - ", user_id='" + userId + '\'' + - '}'; + @Override + public boolean equals(Object o) { + + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; } + UserProfile that = (UserProfile) o; + return Objects.equals(attributes, that.attributes) + && Objects.equals(createdAt, that.createdAt) + && Objects.equals(id, that.id) + && Objects.equals(identifiers, that.identifiers) + && Objects.equals(name, that.name) + && Objects.equals(source, that.source) + && Objects.equals(type, that.type) + && Objects.equals(updatedAt, that.updatedAt) + && Objects.equals(userId, that.userId); + } + + @Override + public int hashCode() { + + return Objects.hash( + attributes, createdAt, id, identifiers, name, source, type, updatedAt, userId); + } + + @Override + public String toString() { + + return "UserProfile{" + + "attributes=" + + attributes + + ", created_at=" + + createdAt + + ", id='" + + id + + '\'' + + ", identifiers=" + + identifiers + + ", name='" + + name + + '\'' + + ", source='" + + source + + '\'' + + ", type='" + + type + + '\'' + + ", updated_at=" + + updatedAt + + ", user_id='" + + userId + + '\'' + + '}'; + } } diff --git a/src/test/java/org/zendesk/client/v2/RealSmokeTest.java b/src/test/java/org/zendesk/client/v2/RealSmokeTest.java index 2721ca80..2e2209a0 100644 --- a/src/test/java/org/zendesk/client/v2/RealSmokeTest.java +++ b/src/test/java/org/zendesk/client/v2/RealSmokeTest.java @@ -5,6 +5,7 @@ import static java.util.concurrent.TimeUnit.SECONDS; import static org.awaitility.Awaitility.await; import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; @@ -13,11 +14,14 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.isEmptyOrNullString; import static org.hamcrest.Matchers.isOneOf; import static org.hamcrest.Matchers.lessThanOrEqualTo; +import static org.hamcrest.collection.IsMapWithSize.aMapWithSize; import static org.hamcrest.core.StringContains.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -35,6 +39,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Properties; @@ -91,6 +96,7 @@ import org.zendesk.client.v2.model.Trigger; import org.zendesk.client.v2.model.Type; import org.zendesk.client.v2.model.User; +import org.zendesk.client.v2.model.UserProfile; import org.zendesk.client.v2.model.View; import org.zendesk.client.v2.model.dynamic.DynamicContentItem; import org.zendesk.client.v2.model.dynamic.DynamicContentItemVariant; @@ -1132,6 +1138,87 @@ public void createUser() throws Exception { createdUser.getIanaTimeZone()); } + @Test + public void createUserProfile() throws Exception { + // given + createClientWithTokenOrPassword(); + UserProfile userProfile = newTestUserProfile(); + + // when + UserProfile createdUserProfile = instance.createOrUpdateUserProfile(userProfile); + + // then + assertThat("A unique ID must be set", createdUserProfile.getId(), notNullValue()); + assertThat("A user must have been created", createdUserProfile.getUserId(), notNullValue()); + assertThat("An identifier should be present", createdUserProfile.getIdentifiers(), hasSize(1)); + assertThat( + "An email identifier should be present", + createdUserProfile.getIdentifiers().get(0).getType(), + equalTo("email")); + assertThat( + "An attribute should be set", createdUserProfile.getAttributes(), is(aMapWithSize(1))); + } + + @Test + public void getUserProfile() throws Exception { + // given + createClientWithTokenOrPassword(); + UserProfile userProfile = newTestUserProfile(); + UserProfile createdUserProfile = instance.createOrUpdateUserProfile(userProfile); + + // when + UserProfile queriedProfile = instance.getUserProfile(createdUserProfile.getId()); + + // then + assertThat("A unique ID must be set", queriedProfile.getId(), notNullValue()); + assertThat("A user must have been created", queriedProfile.getUserId(), notNullValue()); + assertThat("An identifier should be present", queriedProfile.getIdentifiers(), hasSize(1)); + assertThat( + "An email identifier should be present", + queriedProfile.getIdentifiers().get(0).getType(), + equalTo("email")); + assertThat("An attribute should be set", queriedProfile.getAttributes(), is(aMapWithSize(1))); + } + + @Test + public void updateUserProfile() throws Exception { + // given + String phoneNumber = "555-123-4567"; + createClientWithTokenOrPassword(); + UserProfile userProfile = newTestUserProfile(); + UserProfile createdUserProfile = instance.createOrUpdateUserProfile(userProfile); + + // when + createdUserProfile.addAttribute("phone", phoneNumber); + createdUserProfile.setName(createdUserProfile.getName() + "updated"); + + UserProfile updateUserProfile = instance.updateUserProfile(createdUserProfile); + + // then + assertThat("Name must have been updated", updateUserProfile.getName(), endsWith("updated")); + assertThat( + "Attribute must have been added", updateUserProfile.getAttributes().entrySet(), hasSize(2)); + assertThat( + "Added attribute must have correct key and value", + updateUserProfile.getAttributes(), + hasEntry("phone", phoneNumber)); + } + + @Test + public void deleteUserProfile() throws Exception { + // given + createClientWithTokenOrPassword(); + UserProfile userProfile = newTestUserProfile(); + UserProfile createdUserProfile = instance.createOrUpdateUserProfile(userProfile); + assertThat(instance.getUserProfile(createdUserProfile.getId()), notNullValue()); + + // when + instance.deleteUserProfile(createdUserProfile.getId()); + + // then + assertThat(instance.getUserProfile(createdUserProfile.getId()), nullValue()); + } + @Test public void updateUsers() throws Exception { createClientWithTokenOrPassword(); @@ -2909,6 +2996,17 @@ private User newTestUser() { return user; } + /** Creates a new user profile for the given user */ + private UserProfile newTestUserProfile() { + final String id = UUID.randomUUID().toString(); + return new UserProfile( + Map.of("createdBy", "zendesk-java-client"), + List.of(new UserProfile.Identifier("email", id + "@test.com")), + "zendesk-java-client user profile" + id, + "integration", + "test"); + } + /** * Creates in zendesk few tickets (2 entries min, 5 entries max) and verify their existence. * diff --git a/src/test/java/org/zendesk/client/v2/model/UserProfileTest.java b/src/test/java/org/zendesk/client/v2/model/UserProfileTest.java index af61c5fa..2848902b 100644 --- a/src/test/java/org/zendesk/client/v2/model/UserProfileTest.java +++ b/src/test/java/org/zendesk/client/v2/model/UserProfileTest.java @@ -1,48 +1,49 @@ package org.zendesk.client.v2.model; +import static org.assertj.core.api.Assertions.assertThat; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Test; -import org.zendesk.client.v2.Zendesk; - import java.time.Instant; import java.util.Date; import java.util.List; import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; +import org.zendesk.client.v2.Zendesk; public class UserProfileTest { - public static final Long USER_ID = 123L; - public static final String PROFILE_NAME = "name"; - - @Test - public void serializeDeserialize() throws JsonProcessingException { - ObjectMapper mapper = Zendesk.createMapper(); - String email = "user123@example.com"; - UserProfile profile = createSampleUserProfile(email); - String serialized = mapper.writeValueAsString(profile); - - UserProfile deserialized = mapper.readValue(serialized, UserProfile.class); - assertThat(deserialized.getName()).isEqualTo(PROFILE_NAME); - assertThat(deserialized.getUserId()).isEqualTo("123"); - assertThat(deserialized.getIdentifiers()).contains(new UserProfile.Identifier("email", email)); - } - - private UserProfile createSampleUserProfile(String email) { - var identifiers = List.of(new UserProfile.Identifier("email", email)); - - return new UserProfile( - Map.of("customer_ref", "ref123"), - Date.from(Instant.now()), - "12345", - identifiers, - PROFILE_NAME, - "source", - "type", - Date.from(Instant.now()), - USER_ID.toString() - ); - } + public static final String USER_ID = "123"; + public static final String PROFILE_NAME = "name"; + public static final String EMAIL = "user123@example.com"; + + @Test + public void serializeDeserialize() throws JsonProcessingException { + ObjectMapper mapper = Zendesk.createMapper(); + UserProfile profile = createSampleUserProfile(); + String serialized = mapper.writeValueAsString(profile); + + UserProfile deserialized = mapper.readValue(serialized, UserProfile.class); + assertThat(deserialized.getName()).isEqualTo(PROFILE_NAME); + assertThat(deserialized.getUserId()).isEqualTo(USER_ID); + assertThat(deserialized.getIdentifiers()) + .first() + .extracting(UserProfile.Identifier::getType, UserProfile.Identifier::getValue) + .contains("email", EMAIL); + } + + private UserProfile createSampleUserProfile() { + var identifiers = List.of(new UserProfile.Identifier("email", EMAIL)); + + return new UserProfile( + Map.of("customer_ref", "ref123"), + Date.from(Instant.now()), + "12345", + identifiers, + PROFILE_NAME, + "source", + "type", + Date.from(Instant.now()), + USER_ID); + } }