Skip to content

Commit

Permalink
feat: Implement UT - Meeds-io/MIPs#121 (#14)
Browse files Browse the repository at this point in the history
Implement UT
  • Loading branch information
AzmiTouil committed May 30, 2024
1 parent 61703b2 commit 43686cb
Show file tree
Hide file tree
Showing 16 changed files with 973 additions and 99 deletions.
5 changes: 4 additions & 1 deletion gamification-crowdin-services/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
<artifactId>gamification-crowdin-service</artifactId>
<packaging>jar</packaging>
<name>Meeds:: Gamification Crowdin - Service</name>
<properties>
<exo.test.coverage.ratio>0.28</exo.test.coverage.ratio>
</properties>
<dependencies>
<dependency>
<groupId>org.exoplatform.social</groupId>
Expand All @@ -46,6 +49,6 @@
</dependency>
</dependencies>
<build>
<finalName>gamification-crowdin-service</finalName>
<finalName>${project.artifactId}</finalName>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@
import io.meeds.gamification.crowdin.rest.model.WebHookList;
import io.meeds.gamification.crowdin.rest.model.WebHookRestEntity;
import io.meeds.gamification.crowdin.services.WebhookService;
import io.meeds.gamification.crowdin.storage.CrowdinConsumerStorage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.exoplatform.commons.ObjectAlreadyExistsException;
import org.exoplatform.commons.exception.ObjectNotFoundException;
Expand All @@ -48,29 +51,26 @@
import static io.meeds.gamification.utils.Utils.getCurrentUser;

@RestController
@RequestMapping("/crowdin/hooks")
@RequestMapping("crowdin/hooks")
@Tag(name = "hooks", description = "An endpoint to manage crowdin webhooks")
public class HooksManagementController {
public class HooksManagementRest {

public static final String CROWDIN_HOOK_NOT_FOUND = "The Crowdin hook doesn't exit";
public static final String CROWDIN_HOOK_NOT_FOUND = "The Crowdin hook doesn't exit";

@Autowired
private WebhookService webhookService;
private WebhookService webhookService;

@Autowired
private WebHookBuilder webHookBuilder;
private CrowdinConsumerStorage crowdinConsumerStorage;

@GetMapping
@Secured("rewarding")
@Operation(summary = "Retrieves the list Crowdin webHooks", method = "GET")
@ApiResponse(responseCode = "200", description = "Request fulfilled")
@ApiResponse(responseCode = "404", description = "Not found")
@ApiResponse(responseCode = "400", description = "Bad request")
@ApiResponse(responseCode = "401", description = "Unauthorized")
@ApiResponse(responseCode = "503", description = "Service unavailable")
public List<WebHookRestEntity> getWebHooks(@RequestParam("offset") int offset,
@Parameter(description = "Query results limit", required = true) @RequestParam("limit") int limit,
@Parameter(description = "Include languages") @Schema(defaultValue = "false") @RequestParam("includeLanguages") boolean includeLanguages) {
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Request fulfilled"),
@ApiResponse(responseCode = "500", description = "Internal server error") })
public WebHookList getWebHooks(@RequestParam("offset") int offset,
@Parameter(description = "Query results limit", required = true) @RequestParam("limit") int limit,
@Parameter(description = "Include languages") @Schema(defaultValue = "false") @RequestParam("includeLanguages") boolean includeLanguages) {

String currentUser = getCurrentUser();
List<WebHookRestEntity> webHookRestEntities;
Expand All @@ -80,10 +80,9 @@ public List<WebHookRestEntity> getWebHooks(@RequestParam("offset") int offset,
webHookList.setWebhooks(webHookRestEntities);
webHookList.setOffset(offset);
webHookList.setLimit(limit);
return webHookRestEntities;
return webHookList;
} catch (IllegalAccessException e) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, e.getMessage());

throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
}
}

Expand Down Expand Up @@ -119,13 +118,12 @@ public WebHook getWebHookById(@Parameter(description = "WebHook technical identi
@ApiResponse(responseCode = "400", description = "Bad request")
@ApiResponse(responseCode = "401", description = "Unauthorized")
@ApiResponse(responseCode = "503", description = "Service unavailable")
public List<RemoteDirectory> getProjectDirectories(@Parameter(description = "Remote project identifier", required = true) @PathVariable("projectId") long projectId,
public List<RemoteDirectory> getProjectDirectories(HttpServletRequest request,
@Parameter(description = "Remote project identifier", required = true) @PathVariable("projectId") long projectId,
@RequestParam("offset") int offset,
@Parameter(description = "Query results limit") @RequestParam("limit") int limit) {
String currentUser = getCurrentUser();

try {
return webhookService.getProjectDirectories(projectId, currentUser, offset, limit);
return webhookService.getProjectDirectories(projectId, request.getRemoteUser(), offset, limit);
} catch (IllegalArgumentException e) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage());
} catch (IllegalAccessException e) {
Expand All @@ -135,7 +133,7 @@ public List<RemoteDirectory> getProjectDirectories(@Parameter(description = "Rem
}
}

@GetMapping("get-projects")
@GetMapping("projects")
@Secured("rewarding")
@Operation(summary = "Retrieves a list of projects from crowdin", method = "GET")
@ApiResponse(responseCode = "200", description = "Request fulfilled")
Expand Down Expand Up @@ -169,7 +167,8 @@ public List<RemoteProject> getProjects(@Parameter(description = "Crowdin access
@ApiResponse(responseCode = "401", description = "Unauthorized")
@ApiResponse(responseCode = "409", description = "Conflict")
@ApiResponse(responseCode = "503", description = "Service unavailable")
public ResponseEntity<Object> createWebhookHook(@Parameter(description = "Crowdin project id", required = true) @RequestParam("projectId") Long projectId,
public ResponseEntity<Object> createWebhookHook(HttpServletRequest request,
@Parameter(description = "Crowdin project id", required = true) @RequestParam("projectId") Long projectId,
@Parameter(description = "Crowdin project name", required = true) @RequestParam("projectName") String projectName,
@Parameter(description = "Crowdin personal access token", required = true) @RequestParam("accessToken") String accessToken) {

Expand All @@ -179,9 +178,8 @@ public ResponseEntity<Object> createWebhookHook(@Parameter(description = "Crowdi
if (StringUtils.isBlank(accessToken)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "'accessToken' parameter is mandatory");
}
String currentUser = ConversationState.getCurrent().getIdentity().getUserId();
try {
webhookService.createWebhook(projectId, projectName, accessToken, currentUser);
webhookService.createWebhook(projectId, projectName, accessToken, request.getRemoteUser());
return ResponseEntity.status(HttpStatus.CREATED).build();
} catch (IllegalAccessException e) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, e.getMessage());
Expand All @@ -199,7 +197,8 @@ public ResponseEntity<Object> createWebhookHook(@Parameter(description = "Crowdi
@ApiResponse(responseCode = "401", description = "Unauthorized")
@ApiResponse(responseCode = "409", description = "Conflict")
@ApiResponse(responseCode = "503", description = "Service unavailable")
public Response updateWebHookAccessToken(@Parameter(description = "webHook id", required = true) @RequestParam("webHookId") long webHookId,
public Response updateWebHookAccessToken(HttpServletRequest request,
@Parameter(description = "webHook id", required = true) @RequestParam("webHookId") long webHookId,
@Parameter(description = "Crowdin personal access token", required = true) @RequestParam("accessToken") String accessToken) {

if (webHookId <= 0) {
Expand All @@ -208,9 +207,8 @@ public Response updateWebHookAccessToken(@Parameter(description = "webHook id",
if (StringUtils.isBlank(accessToken)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "'accessToken' parameter is mandatory");
}
String currentUser = ConversationState.getCurrent().getIdentity().getUserId();
try {
webhookService.updateWebHookAccessToken(webHookId, accessToken, currentUser);
webhookService.updateWebHookAccessToken(webHookId, accessToken, request.getRemoteUser());
return Response.status(Response.Status.CREATED).build();
} catch (IllegalAccessException e) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, e.getMessage());
Expand All @@ -227,13 +225,13 @@ public Response updateWebHookAccessToken(@Parameter(description = "webHook id",
@ApiResponse(responseCode = "400", description = "Bad request")
@ApiResponse(responseCode = "401", description = "Unauthorized")
@ApiResponse(responseCode = "503", description = "Service unavailable")
public void deleteWebhookHook(@Parameter(description = "Crowdin project id", required = true) @PathVariable("projectId") long projectId) {
public void deleteWebhookHook(HttpServletRequest request,
@Parameter(description = "Crowdin project id", required = true) @PathVariable("projectId") long projectId) {
if (projectId <= 0) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "'hookName' parameter is mandatory");
}
String currentUser = ConversationState.getCurrent().getIdentity().getUserId();
try {
webhookService.deleteWebhookHook(projectId, currentUser);
webhookService.deleteWebhook(projectId, request.getRemoteUser());
} catch (IllegalAccessException e) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, e.getMessage());
} catch (ObjectNotFoundException e) {
Expand All @@ -244,7 +242,7 @@ public void deleteWebhookHook(@Parameter(description = "Crowdin project id", req
private List<WebHookRestEntity> getWebHookRestEntities(String username,
boolean includeLanguages) throws IllegalAccessException {
Collection<WebHook> webHooks = webhookService.getWebhooks(username, 0, 20, false);
return webHookBuilder.toRestEntities(webHooks, includeLanguages);
return WebHookBuilder.toRestEntities(crowdinConsumerStorage, webHooks, includeLanguages);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@
import io.meeds.gamification.crowdin.model.RemoteProject;
import io.meeds.gamification.crowdin.model.WebHook;
import io.meeds.gamification.crowdin.rest.model.WebHookRestEntity;
import io.meeds.gamification.crowdin.services.WebhookService;
import io.meeds.gamification.crowdin.storage.CrowdinConsumerStorage;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collection;
Expand All @@ -34,19 +32,15 @@
@Component
public class WebHookBuilder {

private static final Log LOG = ExoLogger.getLogger(WebHookBuilder.class);

@Autowired
private WebhookService webhookService;

@Autowired
private CrowdinConsumerStorage crowdinConsumerStorage;
private static final Log LOG = ExoLogger.getLogger(WebHookBuilder.class);

private WebHookBuilder() {
// Class with static methods
}

public WebHookRestEntity toRestEntity(WebHook webHook, boolean includeLanguages) {
public static WebHookRestEntity toRestEntity(CrowdinConsumerStorage crowdinConsumerStorage,
WebHook webHook,
boolean includeLanguages) {
if (webHook == null) {
return null;
}
Expand Down Expand Up @@ -75,7 +69,9 @@ public WebHookRestEntity toRestEntity(WebHook webHook, boolean includeLanguages)
remoteProject != null);
}

public List<WebHookRestEntity> toRestEntities(Collection<WebHook> webHooks, boolean includeLanguages) {
return webHooks.stream().map(webHook -> toRestEntity(webHook, includeLanguages)).toList();
public static List<WebHookRestEntity> toRestEntities(CrowdinConsumerStorage crowdinConsumerStorage,
Collection<WebHook> webHooks,
boolean includeLanguages) {
return webHooks.stream().map(webHook -> toRestEntity(crowdinConsumerStorage, webHook, includeLanguages)).toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void handleTriggerAsync(String bearerToken, String payload) {

@ContainerTransactional
@SuppressWarnings("unchecked")
private void handleTrigger(String bearerToken, String payload) {
public void handleTrigger(String bearerToken, String payload) {

Map<String, Object> payloadMap = fromJsonStringToMap(payload);

Expand Down Expand Up @@ -106,7 +106,7 @@ private void handleTrigger(String bearerToken, String payload) {
}
}

private void processEvents(List<Event> events, String projectId) {
public void processEvents(List<Event> events, String projectId) {
events.stream().filter(event -> isTriggerEnabled(event.getName(), projectId)).forEach(this::processEvent);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ public class WebhookService {
@Autowired
private WebHookStorage webHookStorage;

private static final String[] CROWDIN_EVENTS = new String[] { "stringComment.created", "stringComment.deleted",
"suggestion.added", "suggestion.deleted", "suggestion.approved", "suggestion.disapproved" };

public List<RemoteProject> getProjectsFromWebhookId(long webHookId) throws IllegalAccessException, ObjectNotFoundException {
WebHook webHook = webHookStorage.getWebHookById(webHookId);
if (webHook == null) {
Expand All @@ -59,7 +56,7 @@ public List<RemoteProject> getProjects(String accessToken) throws IllegalAccessE
return crowdinConsumerStorage.getProjects(accessToken);
}

public void createWebhook(long projectId,
public WebHook createWebhook(long projectId,
String projectName,
String accessToken,
String currentUser) throws ObjectAlreadyExistsException, IllegalAccessException {
Expand All @@ -77,8 +74,9 @@ public void createWebhook(long projectId,
if (webHook != null) {
webHook.setProjectName(projectName);
webHook.setWatchedBy(currentUser);
webHookStorage.saveWebHook(webHook);
return webHookStorage.saveWebHook(webHook);
}
return null;
}

public void updateWebHookAccessToken(long webHookId, String accessToken, String currentUser) throws IllegalAccessException,
Expand All @@ -103,7 +101,7 @@ public List<WebHook> getWebhooks(String currentUser, int offset, int limit, bool
return getWebhooks(offset, limit, forceUpdate);
}

public void deleteWebhookHook(long projectId, String currentUser) throws IllegalAccessException, ObjectNotFoundException {
public WebHook deleteWebhook(long projectId, String currentUser) throws IllegalAccessException, ObjectNotFoundException {
if (!Utils.isRewardingManager(currentUser)) {
throw new IllegalAccessException("The user is not authorized to delete Crowdin hook");
}
Expand All @@ -113,12 +111,13 @@ public void deleteWebhookHook(long projectId, String currentUser) throws Illegal
}
String response = crowdinConsumerStorage.deleteWebhook(webHook);
if (response != null) {
deleteWebhook(projectId);
return deleteWebhook(projectId);
}
return null;
}

public void deleteWebhook(long projectId) {
webHookStorage.deleteWebHook(projectId);
public WebHook deleteWebhook(long projectId) {
return webHookStorage.deleteWebHook(projectId);
}

public List<WebHook> getWebhooks(int offset, int limit, boolean forceUpdate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,11 @@ public static WebHook fromEntity(WebhookEntity webhookEntity) {
if (webhookEntity == null) {
return null;
}
IdentityManager identityManager = CommonsUtils.getService(IdentityManager.class);
String watchedBy = identityManager.getIdentity(String.valueOf(webhookEntity.getWatchedBy())).getRemoteId();
String watchedBy = null;
if (webhookEntity.getWatchedBy() != null) {
IdentityManager identityManager = CommonsUtils.getService(IdentityManager.class);
watchedBy = identityManager.getIdentity(String.valueOf(webhookEntity.getWatchedBy())).getRemoteId();
}
return new WebHook(webhookEntity.getId(),
webhookEntity.getWebhookId(),
webhookEntity.getProjectId(),
Expand Down
Loading

0 comments on commit 43686cb

Please sign in to comment.