Skip to content

Commit 2fe954b

Browse files
author
kaushikchaubal
committed
Adding ability to update user avatar
1 parent d4008a3 commit 2fe954b

File tree

4 files changed

+219
-4
lines changed

4 files changed

+219
-4
lines changed

pom.xml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@
8888
<slfj4-version>1.7.21</slfj4-version>
8989
<jaxrs-version>2.0.1</jaxrs-version>
9090
<junit-version>4.12</junit-version>
91-
<mokito-version>1.10.19</mokito-version>
91+
<mokito-version>2.4.0</mokito-version>
92+
<powermock-version>1.7.0RC2</powermock-version>
9293
<jsoup-version>1.9.2</jsoup-version>
9394
<jackson.version>2.8.8</jackson.version>
9495
</properties>
@@ -120,6 +121,16 @@
120121
<artifactId>mockito-core</artifactId>
121122
<version>${mokito-version}</version>
122123
</dependency>
124+
<dependency>
125+
<groupId>org.powermock</groupId>
126+
<artifactId>powermock-module-junit4</artifactId>
127+
<version>${powermock-version}</version>
128+
</dependency>
129+
<dependency>
130+
<groupId>org.powermock</groupId>
131+
<artifactId>powermock-api-mockito2</artifactId>
132+
<version>${powermock-version}</version>
133+
</dependency>
123134
<dependency>
124135
<groupId>org.jsoup</groupId>
125136
<artifactId>jsoup</artifactId>

symphony-client/src/main/java/org/symphonyoss/symphony/clients/UsersClient.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,6 @@ public interface UsersClient {
5555
Set<SymUser> getAllUsersWithDetails() throws UsersClientException;
5656

5757
SymUser getUserBySession(SymAuth symAuth) throws UsersClientException;
58+
59+
void updateUserAvatar(long userId, byte[] avatar) throws UsersClientException;
5860
}

symphony-client/src/main/java/org/symphonyoss/symphony/clients/impl/UsersClientImpl.java

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,20 @@
3737
import org.symphonyoss.symphony.pod.api.UsersApi;
3838
import org.symphonyoss.symphony.pod.invoker.ApiClient;
3939
import org.symphonyoss.symphony.pod.invoker.ApiException;
40-
import org.symphonyoss.symphony.pod.model.*;
40+
import org.symphonyoss.symphony.pod.model.AvatarUpdate;
41+
import org.symphonyoss.symphony.pod.model.FeatureList;
42+
import org.symphonyoss.symphony.pod.model.MemberInfo;
43+
import org.symphonyoss.symphony.pod.model.MembershipList;
44+
import org.symphonyoss.symphony.pod.model.SuccessResponse;
45+
import org.symphonyoss.symphony.pod.model.UserAttributes;
46+
import org.symphonyoss.symphony.pod.model.UserCreate;
47+
import org.symphonyoss.symphony.pod.model.UserDetail;
48+
import org.symphonyoss.symphony.pod.model.UserIdList;
49+
import org.symphonyoss.symphony.pod.model.UserStatus;
50+
import org.symphonyoss.symphony.pod.model.UserV2;
4151

4252
import javax.ws.rs.client.Client;
53+
import java.util.Base64;
4354
import java.util.HashSet;
4455
import java.util.Set;
4556
import java.util.concurrent.ConcurrentHashMap;
@@ -446,6 +457,45 @@ public SymUser getUserBySession(SymAuth symAuth) throws UsersClientException{
446457

447458
}
448459

449-
450-
460+
/**
461+
* Update the avatar of a particular user
462+
*
463+
* @param userId
464+
* User ID as a decimal integer (required)
465+
* @param avatar
466+
* user image. Should be less then 2MB.
467+
* @throws UsersClientException
468+
* if fails to make the avatar update
469+
*/
470+
@Override
471+
public void updateUserAvatar(long userId, byte[] avatar) throws UsersClientException {
472+
if (avatar != null) {
473+
UserApi usersApi = new UserApi(apiClient);
474+
try {
475+
String sessionToken = getSessionToken();
476+
477+
String image = Base64.getEncoder().encodeToString(avatar);
478+
479+
AvatarUpdate avatarUpdate = new AvatarUpdate();
480+
avatarUpdate.setImage(image);
481+
482+
SuccessResponse response = usersApi.v1AdminUserUidAvatarUpdatePost(sessionToken, userId, avatarUpdate);
483+
484+
if (!"OK".equals(response.getMessage())) {
485+
throw new IllegalStateException(
486+
"The message differs from expected OK message. Response message: " + response.getMessage());
487+
}
488+
489+
} catch (ApiException e) {
490+
String message = "API error communicating with POD, while updating avatar";
491+
logger.error(message, e);
492+
throw new UsersClientException(message,
493+
new RestException(usersApi.getApiClient().getBasePath(), e.getCode(), e));
494+
} catch (IllegalStateException e) {
495+
String message = "Avatar update failed";
496+
logger.error(message, e);
497+
throw new UsersClientException(message);
498+
}
499+
}
500+
}
451501
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package org.symphonyoss.symphony.clients.impl;
2+
3+
import org.junit.Before;
4+
import org.junit.Test;
5+
import org.junit.runner.RunWith;
6+
import org.mockito.Mock;
7+
8+
import org.powermock.api.mockito.PowerMockito;
9+
import org.powermock.core.classloader.annotations.PrepareForTest;
10+
import org.powermock.modules.junit4.PowerMockRunner;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
13+
import org.symphonyoss.client.exceptions.UsersClientException;
14+
import org.symphonyoss.client.model.SymAuth;
15+
import org.symphonyoss.symphony.authenticator.model.Token;
16+
import org.symphonyoss.symphony.pod.api.UserApi;
17+
import org.symphonyoss.symphony.pod.invoker.ApiClient;
18+
import org.symphonyoss.symphony.pod.invoker.ApiException;
19+
import org.symphonyoss.symphony.pod.invoker.Configuration;
20+
import org.symphonyoss.symphony.pod.model.AvatarUpdate;
21+
import org.symphonyoss.symphony.pod.model.SuccessResponse;
22+
23+
import java.util.Random;
24+
25+
import static org.mockito.Mockito.times;
26+
import static org.mockito.Mockito.verify;
27+
import static org.mockito.Mockito.eq;
28+
import static org.mockito.Mockito.any;
29+
import static org.mockito.Mockito.anyString;
30+
import static org.powermock.api.mockito.PowerMockito.mockStatic;
31+
import static org.powermock.api.mockito.PowerMockito.verifyNew;
32+
import static org.powermock.api.mockito.PowerMockito.when;
33+
import static org.powermock.api.mockito.PowerMockito.whenNew;
34+
35+
@RunWith(PowerMockRunner.class)
36+
@PrepareForTest({ LoggerFactory.class, Configuration.class, UsersClientImpl.class })
37+
public class UsersClientImplTest {
38+
39+
private static final int IMAGE_LENGTH = 3;
40+
private static final String TOKEN_STRING = "tokenString";
41+
private static final String OK_RESPONSE = "OK";
42+
private static final String NOT_OK_RESPONSE = "NOT_OK";
43+
private static final long USER_ID = 123L;
44+
private static final String API_ERROR_COMMUNICATING_WITH_POD_WHILE_UPDATING_AVATAR = "API error communicating with POD, while updating avatar";
45+
private static final String AVATAR_UPDATE_FAILED = "Avatar update failed";
46+
private static final String POD_URL = "podUrl";
47+
48+
private static Logger LOG;
49+
50+
private UsersClientImpl usersClient;
51+
52+
@Mock
53+
private ApiClient apiClientMock;
54+
55+
@Mock
56+
private SymAuth symAuthMock;
57+
58+
@Mock
59+
private UserApi userApiMock;
60+
61+
@Mock
62+
private AvatarUpdate avatarUpdateMock;
63+
64+
@Mock
65+
private SuccessResponse successResponseMock;
66+
67+
@Before
68+
public void before() throws Exception {
69+
mockLogger();
70+
mockConfiguration();
71+
72+
whenNew(UserApi.class).withArguments(apiClientMock).thenReturn(userApiMock);
73+
74+
whenNew(AvatarUpdate.class).withNoArguments().thenReturn(avatarUpdateMock);
75+
76+
usersClient = new UsersClientImpl(symAuthMock, POD_URL);
77+
}
78+
79+
@Test
80+
public void avatarArryIsNull() throws Exception {
81+
usersClient.updateUserAvatar(USER_ID, null);
82+
verifyNew(UserApi.class, times(0)).withArguments(eq(apiClientMock));
83+
}
84+
85+
@Test
86+
public void successfulAvatarUpdate() throws ApiException, UsersClientException {
87+
mockSessionToken();
88+
mockUserApi(OK_RESPONSE);
89+
90+
usersClient.updateUserAvatar(USER_ID, generateImageData());
91+
92+
verify(LOG, times(0)).error(anyString(), any(Exception.class));
93+
94+
}
95+
96+
@Test(expected = UsersClientException.class)
97+
public void unsuccessfulAvatarUpdate() throws ApiException, UsersClientException {
98+
mockSessionToken();
99+
mockUserApi(NOT_OK_RESPONSE);
100+
101+
usersClient.updateUserAvatar(USER_ID, generateImageData());
102+
103+
verify(LOG, times(1)).error(eq(AVATAR_UPDATE_FAILED), any(IllegalStateException.class));
104+
}
105+
106+
@Test(expected = UsersClientException.class)
107+
public void apiExceptionAvatarUpdate() throws ApiException, UsersClientException {
108+
mockSessionToken();
109+
mockUserApiException();
110+
111+
usersClient.updateUserAvatar(USER_ID, generateImageData());
112+
113+
verify(LOG, times(1)).error(eq(API_ERROR_COMMUNICATING_WITH_POD_WHILE_UPDATING_AVATAR),
114+
any(ApiException.class));
115+
}
116+
117+
private void mockUserApi(String response) throws ApiException {
118+
when(userApiMock.v1AdminUserUidAvatarUpdatePost(TOKEN_STRING, USER_ID, avatarUpdateMock))
119+
.thenReturn(successResponseMock);
120+
when(successResponseMock.getMessage()).thenReturn(response);
121+
}
122+
123+
private void mockUserApiException() throws ApiException {
124+
when(userApiMock.getApiClient()).thenReturn(apiClientMock);
125+
when(userApiMock.v1AdminUserUidAvatarUpdatePost(TOKEN_STRING, USER_ID, avatarUpdateMock))
126+
.thenThrow(new ApiException());
127+
}
128+
129+
private void mockSessionToken() {
130+
Token token = new Token();
131+
token.setToken(TOKEN_STRING);
132+
when(symAuthMock.getSessionToken()).thenReturn(token);
133+
}
134+
135+
private byte[] generateImageData() {
136+
byte[] imageData = new byte[IMAGE_LENGTH];
137+
new Random().nextBytes(imageData);
138+
return imageData;
139+
}
140+
141+
private void mockConfiguration() {
142+
mockStatic(Configuration.class);
143+
when(Configuration.getDefaultApiClient()).thenReturn(apiClientMock);
144+
}
145+
146+
private void mockLogger() {
147+
mockStatic(LoggerFactory.class);
148+
LOG = PowerMockito.mock(Logger.class);
149+
when(LoggerFactory.getLogger(UsersClientImpl.class)).thenReturn(LOG);
150+
}
151+
152+
}

0 commit comments

Comments
 (0)