diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..d25b9f1 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/wrapper/src/main/java/wekan/wrapper/api/CardService.java b/wrapper/src/main/java/wekan/wrapper/api/CardService.java new file mode 100644 index 0000000..19f5e96 --- /dev/null +++ b/wrapper/src/main/java/wekan/wrapper/api/CardService.java @@ -0,0 +1,74 @@ +package wekan.wrapper.api; + +import retrofit2.Call; +import retrofit2.http.*; +import wekan.wrapper.entity.Card; + +import java.util.List; + +public interface CardService { + + /** + * Get all cards belonging to a list + * + * @param boardID The board ID of cards + * @param lidtID The list ID of cards + * @return list of cards in the list + */ + @GET("/api/boards/{board}/lists/{list}/cards") + Call> getAllCards(@Path("board") String boardID, @Path("list") String lidtID); + + /** + * Delete a card + * + * @param boardID The board ID of card + * @param listID The list ID of card + * @param cardID The card ID + * @return void + */ + @DELETE("/api/boards/{board}/lists/{list}/cards/{card}") + Call deleteCard(@Path("board") String boardID, @Path("list") String listID, @Path("card") String cardID); + + /** + * + * @param card new Card + * @param boardID The ID of the board destination + * @param listID The ID of the list destination + * @return the card with matching ID + */ + @POST("/api/boards/{board}/lists/{list}/cards") + Call newCard(@Path("board") String boardID, @Path("list") String listID, @Body Card card); + + /** + * Get information card + * @param boardID the ID of the board + * @param listID the ID of the list + * @param cardID the ID of the card + * @return card body + */ + @GET("/api/boards/{board}/lists/{list}/cards/{card}") + Call getCard(@Path("board") String boardID, @Path("list") String listID, @Path("card") String cardID); + + /** + * Get list of cards by swinlaneID + * @param boardID the ID of the board + * @param swimlaneID the ID of the swimlane + * @return list of swimlane cards + */ + @GET("/api/boards/{board}/swimlanes/{swimlane}/cards") + Call> getCardsForswimlane(@Path("board") String boardID, @Path("swimlane") String swimlaneID); + + /** + * Update a card + * + * @param card params to update + * @param boardID the id of the board + * @param listID the id of the list + * @param cardID the id of the card to modify + * @return The card with the matching ID + */ + @Headers("Content-Type: application/merge-patch+json") + @PUT("/api/boards/{board}/lists/{list}/cards/{card}") + Call putCard(@Path("board") String boardID, @Path("list") String listID, + @Path("card") String cardID, @Body Card card); +} diff --git a/wrapper/src/main/java/wekan/wrapper/entity/Card.java b/wrapper/src/main/java/wekan/wrapper/entity/Card.java new file mode 100644 index 0000000..14d7bde --- /dev/null +++ b/wrapper/src/main/java/wekan/wrapper/entity/Card.java @@ -0,0 +1,328 @@ +package wekan.wrapper.entity; + +import com.google.gson.annotations.SerializedName; +import java.util.Date; +import java.util.List; + +public class Card { + + //Constructor for add card + public Card(String authorId, String title, String swimlaneId, String description) { + this.authorId= authorId; + this.title = title; + this.swimlaneId = swimlaneId; + this.description = description; + } + + public Card() { + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Boolean getArchived() { + return archived; + } + + public void setArchived(Boolean archived) { + this.archived = archived; + } + + public String getParentId() { + return parentId; + } + + public void setParentId(String parentId) { + this.parentId = parentId; + } + + public String getListId() { + return listId; + } + + public void setListId(String listId) { + this.listId = listId; + } + + public String getSwimlaneId() { + return swimlaneId; + } + + public void setSwimlaneId(String swimlaneId) { + this.swimlaneId = swimlaneId; + } + + public String getBoardId() { + return boardId; + } + + public void setBoardId(String boardId) { + this.boardId = boardId; + } + + public String getCoverId() { + return coverId; + } + + public void setCoverId(String coverId) { + this.coverId = coverId; + } + + public Color getColor() { + return color; + } + + public void setColor(Color color) { + this.color = color; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getModifiedAt() { + return modifiedAt; + } + + public void setModifiedAt(Date modifiedAt) { + this.modifiedAt = modifiedAt; + } + + public List getCustomFields() { + return customFields; + } + + public void setCustomFields(List customFields) { + this.customFields = customFields; + } + + public Date getDateLastActivity() { + return dateLastActivity; + } + + public void setDateLastActivity(Date dateLastActivity) { + this.dateLastActivity = dateLastActivity; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getRequestedBy() { + return requestedBy; + } + + public void setRequestedBy(String requestedBy) { + this.requestedBy = requestedBy; + } + + public String getAssignedBy() { + return assignedBy; + } + + public void setAssignedBy(String assignedBy) { + this.assignedBy = assignedBy; + } + + public List getLabelIds() { + return labelIds; + } + + public void setLabelIds(List labelIds) { + this.labelIds = labelIds; + } + + public List getMembers() { + return members; + } + + public void setMembers(List members) { + this.members = members; + } + + public List getAssignees() { + return assignees; + } + + public void setAssignees(List assignees) { + this.assignees = assignees; + } + + public Date getReceivedAt() { + return receivedAt; + } + + public void setReceivedAt(Date receivedAt) { + this.receivedAt = receivedAt; + } + + public Date getStartAt() { + return startAt; + } + + public void setStartAt(Date startAt) { + this.startAt = startAt; + } + + public Date getDueAt() { + return dueAt; + } + + public void setDueAt(Date dueAt) { + this.dueAt = dueAt; + } + + public Date getEndAt() { + return endAt; + } + + public void setEndAt(Date endAt) { + this.endAt = endAt; + } + + public int getSpentTime() { + return spentTime; + } + + public void setSpentTime(int spentTime) { + this.spentTime = spentTime; + } + + public Boolean getOvertime() { + return isOvertime; + } + + public void setOvertime(Boolean overtime) { + isOvertime = overtime; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public int getSort() { + return sort; + } + + public void setSort(int sort) { + this.sort = sort; + } + + public int getSubtaskSort() { + return subtaskSort; + } + + public void setSubtaskSort(int subtaskSort) { + this.subtaskSort = subtaskSort; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getLinkedId() { + return linkedId; + } + + public void setLinkedId(String linkedId) { + this.linkedId = linkedId; + } + + @Override + public String toString() { + return "Card{" + + "id='" + id + '\'' + + ", title='" + title + '\'' + + ", archived=" + archived + + ", parentId='" + parentId + '\'' + + ", listId='" + listId + '\'' + + ", swimlaneId='" + swimlaneId + '\'' + + ", boardId='" + boardId + '\'' + + ", coverId='" + coverId + '\'' + + ", color='" + color + '\'' + + ", createdAt=" + createdAt + + ", modifiedAt=" + modifiedAt + + ", customFields=" + customFields + + ", dateLastActivity=" + dateLastActivity + + ", description='" + description + '\'' + + ", requestedBy='" + requestedBy + '\'' + + ", assignedBy='" + assignedBy + '\'' + + ", labelIds=" + labelIds + + ", members=" + members + + ", assignees=" + assignees + + ", receivedAt='" + receivedAt + '\'' + + ", startAt='" + startAt + '\'' + + ", dueAt='" + dueAt + '\'' + + ", endAt='" + endAt + '\'' + + ", spentTime=" + spentTime + + ", isOvertime=" + isOvertime + + ", userId='" + userId + '\'' + + ", sort=" + sort + + ", subtaskSort=" + subtaskSort + + ", type='" + type + '\'' + + ", linkedId='" + linkedId + '\'' + + '}'; + } + + @SerializedName("_id") + private String id; + private String title; + private Boolean archived; + private String parentId; + private String listId; + private String swimlaneId; + private String boardId; + private String coverId; + private Color color; + private Date createdAt; + private Date modifiedAt; + private List customFields; + private Date dateLastActivity; + private String description; + private String requestedBy; + private String assignedBy; + private List labelIds; + private List members; + private List assignees; + private Date receivedAt; + private Date startAt; + private Date dueAt; + private Date endAt; + private int spentTime; + private Boolean isOvertime; + private String userId; + private int sort; + private int subtaskSort; + private String type; + private String linkedId; + private String authorId; +} diff --git a/wrapper/src/test/java/wekan/wrapper/api/CardServiceTest.java b/wrapper/src/test/java/wekan/wrapper/api/CardServiceTest.java new file mode 100644 index 0000000..be4bbe0 --- /dev/null +++ b/wrapper/src/test/java/wekan/wrapper/api/CardServiceTest.java @@ -0,0 +1,192 @@ +package wekan.wrapper.api; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import wekan.wrapper.entity.Card; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class CardServiceTest { + private MockWebServer mockWebServer = new MockWebServer(); + private CardService service = null; + + @Before + public void setUp() { + try { + mockWebServer.start(); + service = new Retrofit.Builder() + .baseUrl(mockWebServer.url("")) + .addConverterFactory(GsonConverterFactory.create()) + .build() + .create(CardService.class); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @After + public void teardown() { + try { + mockWebServer.shutdown(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Test + public void getAllCardsTest(){ + MockResponse response = new MockResponse() + .setResponseCode(HttpURLConnection.HTTP_OK) + .setBody( + "[{\"_id\":\"J5a86fPe2DhqN3QbF0\",\"title\":\"card 0\",\"description\":\"proof 0\"}," + + "{\"_id\":\"J5a86fPe2DhqN3QbF1\",\"title\":\"card 1\",\"description\":\"proof 1\"}]" + ); + + mockWebServer.enqueue(response); + + try { + List cards = service.getAllCards("oKthRbLqoXZr5NNua","iA6pmp6fENvF7AaTX"). + execute().body(); + + assertNotNull(cards); + assertEquals("Numbero of card not ok",2, cards.size()); + + for (int i = 0; i < cards.size(); i++) { + assertEquals("J5a86fPe2DhqN3QbF" + i, cards.get(i).getId()); + assertEquals("card " + i, cards.get(i).getTitle()); + assertEquals("proof " + i, cards.get(i).getDescription()); + } + + + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Test + public void getCardTest(){ + MockResponse response = new MockResponse() + .setResponseCode(HttpURLConnection.HTTP_OK) + .setBody(card); + try { + Card card = service.getCard( + "oKthRbLqoXZr5NNua","iA6pmp6fENvF7AaTX","J5a86fPe2DhqN3QbF") + .execute().body(); + assertNotNull(card); + assertEquals("J5a86fPe2DhqN3QbF", card.getId() ); + assertEquals("patch", card.getTitle()); + assertEquals("iA6pmp6fENvF7AaTX", card.getListId()); + assertEquals("2019-11-10T11:21:31.116Z", card.getCreatedAt().toString()); + + }catch (IOException e){ + e.printStackTrace(); + } + mockWebServer.enqueue(response); + + } + + @Test + public void newCardTest(){ + MockResponse response = new MockResponse() + .setResponseCode(HttpURLConnection.HTTP_OK) + .setBody( + "{\"_id\":\"FGgYsTzrwLJM8QT6W\"}" + ); + + mockWebServer.enqueue(response); + + try { + Card card = service.newCard( + "oKthRbLqoXZr5NNua","iA6pmp6fENvF7AaTX",cardToAdd) + .execute().body(); + + assertNotNull(card); + assertEquals("FGgYsTzrwLJM8QT6W", card.getId()); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Test + public void getCardsForSwimlaneTest() throws IOException { + MockResponse response = new MockResponse() + .setResponseCode(HttpURLConnection.HTTP_OK) + .setBody("[{\"_id\":\"J5a86fPe2DhqN3QbF0\",\"title\":\"card 0\",\"description\":\"proof\",\"listId\":\"iA6pmp6fENvF7AaTX0\"}," + + "{\"_id\":\"J5a86fPe2DhqN3QbF1\",\"title\":\"card 1\",\"description\":\"proof\",\"listId\":\"iA6pmp6fENvF7AaTX1\"}," + + "{\"_id\":\"J5a86fPe2DhqN3QbF2\",\"title\":\"card 2\",\"description\":\"proof\",\"listId\":\"iA6pmp6fENvF7AaTX2\"}]"); + + mockWebServer.enqueue(response); + List cards = service.getCardsForswimlane( + "oKthRbLqoXZr5NNua","ScwkAWCRW23duajxJ") + .execute().body(); + assertNotNull(cards); + assertEquals(3, cards.size()); + for(int i = 0; i < cards.size(); i++){ + assertEquals("J5a86fPe2DhqN3QbF" + i, cards.get(i).getId()); + assertEquals("card " + i, cards.get(i).getTitle()); + assertEquals("iA6pmp6fENvF7AaTX" + i, cards.get(i).getListId()); + assertEquals("proof", cards.get(i).getDescription()); + } + } + + @Test + public void updateCardTest() throws Exception { + MockResponse response = new MockResponse() + .setResponseCode(HttpURLConnection.HTTP_OK) + .setBody("{\"_id\":\"sig8KLcMcPTGx5GfF\"}"); + + mockWebServer.enqueue(response); + Card update = new Card(); + update.setTitle("newTitle"); + + Card card = service.putCard("","","",update) + .execute().body(); + assertNotNull(card); + assertEquals("sig8KLcMcPTGx5GfF", card.getId()); + + } + + private static final String card = + "{"+ + "\"_id\":\"J5a86fPe2DhqN3QbF\"," + + "\"title\":\"title1\","+ + "\"boardId\":\"oKthRbLqoXZr5NNua\"," + + "\"listId\":\"iA6pmp6fENvF7AaTX\"," + + "\"description\":\"proof\"," + + "\"userId\":\"jPdkf3a9bmfZWx3GR\"," + + "\"swimlaneId\":\"ScwkAWCRW23duajxJ\"," + + "\"sort\":\"1\"," + + "\"members\":\"[]\"," + + "\"archived\":\"false\"," + + "\"parentId\":\"\"," + + "\"coverId\":\"\"," + + "\"createdAt\":\"2019-11-10T11:21:31.116Z\"," + + "\"modifiedAt\":\"2019-11-10T21:49:58.023Z\"," + + "\"customFields\":\"[]\"," + + "\"dateLastActivity\":\"2019-11-10T21:49:58.024Z\"," + + "\"requestedBy\":\"\"," + + "\"assignedBy\":\"\"," + + "\"labelIds\":\"[]\"," + + "\"assignees\":\"[]\"," + + "\"spentTime\":\"0\"," + + "\"isOvertime\":\"false\"," + + "\"subtaskSort\":\"-1\"," + + "\"type\":\"cardType-card\"," + + "\"linkedId\":\"" + + "}"; + + private static final Card cardToAdd = new Card( + "jPdkf3a9bmfZWx3GR","cardAdded","ScwkAWCRW23duajxJ", + "proof"); +}