From cbcf089722a3bc444ef04a781bdc49c3ca87d7f9 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Dupont Date: Mon, 30 May 2016 16:40:26 -0400 Subject: [PATCH] Adding Epic resource, with test. --- README.md | 7 +- src/main/java/net/rcarz/jiraclient/Field.java | 199 +++++++++--------- .../rcarz/jiraclient/agile/AgileClient.java | 48 ++++- .../rcarz/jiraclient/agile/AgileResource.java | 181 ++++++++-------- .../net/rcarz/jiraclient/agile/Board.java | 16 +- .../java/net/rcarz/jiraclient/agile/Epic.java | 16 +- .../rcarz/jiraclient/agile/Estimation.java | 7 - .../net/rcarz/jiraclient/agile/Issue.java | 7 +- .../net/rcarz/jiraclient/agile/Sprint.java | 20 +- .../agile/AbstractResourceTest.groovy | 52 +++-- .../jiraclient/agile/AgileClientTest.groovy | 54 ++++- .../rcarz/jiraclient/agile/BoardTest.groovy | 23 +- .../rcarz/jiraclient/agile/EpicTest.groovy | 44 ++++ .../rcarz/jiraclient/agile/IssueTest.groovy | 8 +- .../jiraclient/agile/JSONResources.groovy | 37 +++- .../rcarz/jiraclient/agile/SprintTest.groovy | 17 +- 16 files changed, 447 insertions(+), 289 deletions(-) delete mode 100644 src/main/java/net/rcarz/jiraclient/agile/Estimation.java create mode 100644 src/test/groovy/net/rcarz/jiraclient/agile/EpicTest.groovy diff --git a/README.md b/README.md index b3d328c..f58e16e 100644 --- a/README.md +++ b/README.md @@ -283,6 +283,7 @@ https://docs.atlassian.com/jira-software/REST/cloud/ 1. GET /rest/agile/1.0/board 1. GET /rest/agile/1.0/board/{boardId} 1. GET /rest/agile/1.0/sprint/{sprintId} + 1. GET /rest/agile/1.0/issue/{issueIdOrKey} 1. [Board](src/main/java/net/rcarz/jiraclient/agile/Board.java) 1. GET /rest/agile/1.0/board 1. GET /rest/agile/1.0/board/{boardId} @@ -290,17 +291,17 @@ https://docs.atlassian.com/jira-software/REST/cloud/ 1. [Sprint](src/main/java/net/rcarz/jiraclient/agile/Sprint.java) 1. GET /rest/agile/1.0/sprint/{sprintId} 1. GET /rest/agile/1.0/board/{boardId}/sprint + 1. [Issue](src/main/java/net/rcarz/jiraclient/agile/Issue.java) + 1. GET /rest/agile/1.0/issue/{issueIdOrKey} + 1. To implement 1. -- GET /rest/agile/1.0/board/{boardId}/backlog 1. -- GET /rest/agile/1.0/board/{boardId}/epic 1. -- GET /rest/agile/1.0/board/{boardId}/epic/{epicId}/issue 1. -- GET /rest/agile/1.0/board/{boardId}/epic/none/issue 1. -- GET /rest/agile/1.0/board/{boardId}/sprint/{sprintId}/issue - 1. -- GET /rest/agile/1.0/epic/{epicIdOrKey} 1. -- GET /rest/agile/1.0/epic/{epicIdOrKey}/issue 1. -- GET /rest/agile/1.0/epic/none/issue - 1. -- GET /rest/agile/1.0/issue/{issueIdOrKey} - 1. -- GET /rest/agile/1.0/issue/{issueIdOrKey}/estimation 1. -- GET /rest/agile/1.0/sprint/{sprintId}/issue diff --git a/src/main/java/net/rcarz/jiraclient/Field.java b/src/main/java/net/rcarz/jiraclient/Field.java index 87c0bdc..f38fb86 100644 --- a/src/main/java/net/rcarz/jiraclient/Field.java +++ b/src/main/java/net/rcarz/jiraclient/Field.java @@ -19,107 +19,24 @@ package net.rcarz.jiraclient; -import java.lang.Iterable; -import java.lang.UnsupportedOperationException; +import net.sf.json.JSONArray; +import net.sf.json.JSONNull; +import net.sf.json.JSONObject; + import java.sql.Timestamp; import java.text.ParsePosition; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import net.sf.json.JSONNull; +import java.util.*; /** * Utility functions for translating between JSON and fields. */ public final class Field { - /** - * Field metadata structure. - */ - public static final class Meta { - public boolean required; - public String type; - public String items; - public String name; - public String system; - public String custom; - public int customId; - } - - /** - * Field update operation. - */ - public static final class Operation { - public String name; - public Object value; - - /** - * Initialises a new update operation. - * - * @param name Operation name - * @param value Field value - */ - public Operation(String name, Object value) { - this.name = name; - this.value = value; - } - } - - /** - * Allowed value types. - */ - public enum ValueType { - KEY("key"), NAME("name"), ID_NUMBER("id"), VALUE("value"); - private String typeName; - - private ValueType(String typeName) { - this.typeName = typeName; - } - - @Override - public String toString() { - return typeName; - } - }; - - /** - * Value and value type pair. - */ - public static final class ValueTuple { - public final String type; - public final Object value; - - /** - * Initialises the value tuple. - * - * @param type - * @param value - */ - public ValueTuple(String type, Object value) { - this.type = type; - this.value = (value != null ? value : JSONNull.getInstance()); - } - - /** - * Initialises the value tuple. - * - * @param type - * @param value - */ - public ValueTuple(ValueType type, Object value) { - this(type.toString(), value); - } - } - public static final String ASSIGNEE = "assignee"; public static final String ATTACHMENT = "attachment"; public static final String CHANGE_LOG = "changelog"; + ; public static final String CHANGE_LOG_ENTRIES = "histories"; public static final String CHANGE_LOG_ITEMS = "items"; public static final String COMMENT = "comment"; @@ -149,10 +66,8 @@ public final class Field { public static final String CREATED_DATE = "created"; public static final String UPDATED_DATE = "updated"; public static final String TRANSITION_TO_STATUS = "to"; - public static final String DATE_FORMAT = "yyyy-MM-dd"; public static final String DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; - private Field() { } /** @@ -204,7 +119,7 @@ public final class Field { return results; } - + /** * Gets a list of remote links from the given object. * @@ -290,6 +205,24 @@ public final class Field { return result; } + /** + * Gets a long from the given object. + * + * @param i a Long or an Integer instance + * + * @return a long primitive or 0 if i isn't a Long or an Integer instance + */ + public static long getLong(Object i) { + long result = 0; + + if (i instanceof Long) + result = ((Long) i).longValue(); + if (i instanceof Integer) + result = ((Integer) i).intValue(); + + return result; + } + /** * Gets a generic map from the given object. * @@ -553,7 +486,7 @@ public final class Field { } else if (type.equals("string") && custom != null && (custom.equals("com.atlassian.jira.plugin.system.customfieldtypes:multicheckboxes") || custom.equals("com.atlassian.jira.plugin.system.customfieldtypes:multiselect"))) { - + realResult = new JSONObject(); ((JSONObject)realResult).put(ValueType.VALUE.toString(), realValue.toString()); } else if (type.equals("string")) @@ -658,7 +591,7 @@ public final class Field { else if (value instanceof TimeTracking) return ((TimeTracking) value).toJsonObject(); } else if (m.type.equals("number")) { - if(!(value instanceof java.lang.Integer) && !(value instanceof java.lang.Double) && !(value + if (!(value instanceof java.lang.Integer) && !(value instanceof java.lang.Double) && !(value instanceof java.lang.Float) && !(value instanceof java.lang.Long) ) { throw new JiraException("Field '" + name + "' expects a Numeric value"); @@ -722,5 +655,83 @@ public final class Field { public static ValueTuple valueById(String id) { return new ValueTuple(ValueType.ID_NUMBER, id); } + + /** + * Allowed value types. + */ + public enum ValueType { + KEY("key"), NAME("name"), ID_NUMBER("id"), VALUE("value"); + private String typeName; + + private ValueType(String typeName) { + this.typeName = typeName; + } + + @Override + public String toString() { + return typeName; + } + } + + /** + * Field metadata structure. + */ + public static final class Meta { + public boolean required; + public String type; + public String items; + public String name; + public String system; + public String custom; + public int customId; + } + + /** + * Field update operation. + */ + public static final class Operation { + public String name; + public Object value; + + /** + * Initialises a new update operation. + * + * @param name Operation name + * @param value Field value + */ + public Operation(String name, Object value) { + this.name = name; + this.value = value; + } + } + + /** + * Value and value type pair. + */ + public static final class ValueTuple { + public final String type; + public final Object value; + + /** + * Initialises the value tuple. + * + * @param type + * @param value + */ + public ValueTuple(String type, Object value) { + this.type = type; + this.value = (value != null ? value : JSONNull.getInstance()); + } + + /** + * Initialises the value tuple. + * + * @param type + * @param value + */ + public ValueTuple(ValueType type, Object value) { + this(type.toString(), value); + } + } } diff --git a/src/main/java/net/rcarz/jiraclient/agile/AgileClient.java b/src/main/java/net/rcarz/jiraclient/agile/AgileClient.java index 948204b..e51ee80 100644 --- a/src/main/java/net/rcarz/jiraclient/agile/AgileClient.java +++ b/src/main/java/net/rcarz/jiraclient/agile/AgileClient.java @@ -27,6 +27,7 @@ import java.util.List; /** * An Agile extension to the JIRA client. + * * @see "https://docs.atlassian.com/jira-software/REST/cloud/" */ public class AgileClient { @@ -43,23 +44,20 @@ public class AgileClient { } /** - * Retreives the board with the given ID. + * Retrieves the board with the given ID. * * @param id Board ID - * * @return a Board instance - * * @throws JiraException when something goes wrong */ - public Board getBoard(int id) throws JiraException { + public Board getBoard(long id) throws JiraException { return Board.get(restclient, id); } /** - * Retreives all boards visible to the session user. + * Retrieves all boards visible to the session user. * * @return a list of boards - * * @throws JiraException when something goes wrong */ public List getBoards() throws JiraException { @@ -67,17 +65,47 @@ public class AgileClient { } /** - * Retreives the sprint with the given ID. + * Retrieves the sprint with the given ID. * * @param id Sprint ID - * * @return a Sprint instance - * * @throws JiraException when something goes wrong */ - public Sprint getSprint(int id) throws JiraException { + public Sprint getSprint(long id) throws JiraException { return Sprint.get(restclient, id); } + /** + * Retrieves the issue with the given ID. + * + * @param id Issue ID + * @return an Issue instance + * @throws JiraException when something goes wrong + */ + public Issue getIssue(long id) throws JiraException { + return Issue.get(restclient, id); + } + + /** + * Retrieves the issue with the given Key. + * + * @param key Issue Key + * @return an Issue instance + * @throws JiraException when something goes wrong + */ + public Issue getIssue(String key) throws JiraException { + return Issue.get(restclient, key); + } + + /** + * Retrieves the epic with the given ID. + * + * @param id Epic ID + * @return an Epic instance + * @throws JiraException when something goes wrong + */ + public Epic getEpic(long id) throws JiraException { + return Epic.get(restclient, id); + } } diff --git a/src/main/java/net/rcarz/jiraclient/agile/AgileResource.java b/src/main/java/net/rcarz/jiraclient/agile/AgileResource.java index 9fb7e35..24c608a 100644 --- a/src/main/java/net/rcarz/jiraclient/agile/AgileResource.java +++ b/src/main/java/net/rcarz/jiraclient/agile/AgileResource.java @@ -48,7 +48,7 @@ public abstract class AgileResource { public static final String RESOURCE_URI = "/rest/agile/1.0/"; private RestClient restclient = null; - private int id = 0; + private long id = 0; private String name; private String self; private Map attributes = new HashMap(); @@ -66,94 +66,6 @@ public abstract class AgileResource { } } - /** - * @return Internal JIRA ID. - */ - public int getId() { - return id; - } - - /** - * @return The resource name. - */ - public String getName() { - return name; - } - - /** - * @return The resource URL. - */ - public String getSelfURL() { - return self; - } - - /** - * @return The REST client used to access the current resource. - */ - protected RestClient getRestclient() { - return restclient; - } - - /** - * Retrieve the specified attribute as a generic object. - * - * @param name The name of the attribute to retrieve. - * @return The value of the attribute. - */ - public String getAttribute(String name) { - return (String) attributes.get(name); - } - - /** - * Retrieve the specified attribute as a generic object. - * - * @param name The name of the attribute to retrieve. - * @return The value of the attribute. - */ - public int getAttributeAsInt(String name) { - return NumberUtils.toInt(getAttribute(name), 0); - } - - /** - * Retrieve the specified attribute as a generic object. - * - * @param name The name of the attribute to retrieve. - * @return The value of the attribute. - */ - public boolean getAttributeAsBoolean(String name) { - return BooleanUtils.toBoolean(getAttribute(name)); - } - - /** - * Deserialize the json to extract standard attributes and keep a reference of - * other attributes. - * - * @param json The JSON object to read. - */ - protected void deserialize(JSONObject json) { - Map map = json; - - id = getInteger(map.get("id")); - name = Field.getString(map.get("name")); - self = Field.getString(map.get("self")); - attributes.putAll(map); - } - - private int getInteger(Object o) { - if (o instanceof Integer) { - return Field.getInteger(o); - } else if (o instanceof String && NumberUtils.isDigits((String) o)) { - return NumberUtils.toInt((String) o, 0); - } else { - return 0; - } - } - - @Override - public String toString() { - return String.format("%s{id=%s, name='%s'}", getClass().getSimpleName(), id, name); - } - /** * Gets an Agile resource from the given object. * @@ -223,7 +135,7 @@ public abstract class AgileResource { */ static List list(RestClient restclient, Class type, String url) throws JiraException { - JSON result = null; + JSON result; try { result = restclient.get(url); } catch (Exception ex) { @@ -246,7 +158,7 @@ public abstract class AgileResource { */ static T get(RestClient restclient, Class type, String url) throws JiraException { - JSON result = null; + JSON result; try { result = restclient.get(url); } catch (Exception ex) { @@ -259,5 +171,92 @@ public abstract class AgileResource { restclient ); } + + /** + * @return Internal JIRA ID. + */ + public long getId() { + return id; + } + + /** + * @return The resource name. + */ + public String getName() { + return name; + } + + /** + * @return The resource URL. + */ + public String getSelfURL() { + return self; + } + + /** + * @return The REST client used to access the current resource. + */ + protected RestClient getRestclient() { + return restclient; + } + + /** + * Retrieve the specified attribute as a generic object. + * + * @param name The name of the attribute to retrieve. + * @return The value of the attribute. + */ + String getAttribute(String name) { + return (String) attributes.get(name); + } + + /** + * Retrieve the specified attribute as a generic object. + * + * @param name The name of the attribute to retrieve. + * @return The value of the attribute. + */ + int getAttributeAsInt(String name) { + return NumberUtils.toInt(getAttribute(name), 0); + } + + /** + * Retrieve the specified attribute as a generic object. + * + * @param name The name of the attribute to retrieve. + * @return The value of the attribute. + */ + boolean getAttributeAsBoolean(String name) { + return BooleanUtils.toBoolean(getAttribute(name)); + } + + /** + * Deserialize the json to extract standard attributes and keep a reference of + * other attributes. + * + * @param json The JSON object to read. + */ + protected void deserialize(JSONObject json) { + + id = getLong(json.get("id")); + name = Field.getString(json.get("name")); + self = Field.getString(json.get("self")); + attributes.putAll(json); + } + + long getLong(Object o) { + if (o instanceof Integer || o instanceof Long) { + return Field.getInteger(o); + } else if (o instanceof String && NumberUtils.isDigits((String) o)) { + return NumberUtils.toLong((String) o, 0L); + } else { + return 0L; + } + } + + @Override + public String toString() { + return String.format("%s{id=%s, name='%s'}", getClass().getSimpleName(), id, name); + } } diff --git a/src/main/java/net/rcarz/jiraclient/agile/Board.java b/src/main/java/net/rcarz/jiraclient/agile/Board.java index 73463d1..fae1a0a 100644 --- a/src/main/java/net/rcarz/jiraclient/agile/Board.java +++ b/src/main/java/net/rcarz/jiraclient/agile/Board.java @@ -33,7 +33,7 @@ import java.util.List; */ public class Board extends AgileResource { - public static final String ATTR_TYPE = "type"; + private static final String ATTR_TYPE = "type"; private String type; @@ -47,12 +47,6 @@ public class Board extends AgileResource { super(restclient, json); } - @Override - protected void deserialize(JSONObject json) { - super.deserialize(json); - type = Field.getString(json.get(ATTR_TYPE)); - } - /** * Retrieves the given rapid view. * @@ -61,7 +55,7 @@ public class Board extends AgileResource { * @return a rapid view instance * @throws JiraException when the retrieval fails */ - public static Board get(RestClient restclient, int id) throws JiraException { + public static Board get(RestClient restclient, long id) throws JiraException { return AgileResource.get(restclient, Board.class, RESOURCE_URI + "board/" + id); } @@ -76,6 +70,12 @@ public class Board extends AgileResource { return AgileResource.list(restclient, Board.class, RESOURCE_URI + "board"); } + @Override + protected void deserialize(JSONObject json) { + super.deserialize(json); + type = Field.getString(json.get(ATTR_TYPE)); + } + /** * @return The board type. */ diff --git a/src/main/java/net/rcarz/jiraclient/agile/Epic.java b/src/main/java/net/rcarz/jiraclient/agile/Epic.java index 0fc3b3f..8445e84 100644 --- a/src/main/java/net/rcarz/jiraclient/agile/Epic.java +++ b/src/main/java/net/rcarz/jiraclient/agile/Epic.java @@ -1,10 +1,12 @@ package net.rcarz.jiraclient.agile; +import net.rcarz.jiraclient.JiraException; import net.rcarz.jiraclient.RestClient; import net.sf.json.JSONObject; /** - * Created by pldupont on 2016-05-20. + * Created on 2016-05-20. + * @author pldupont */ public class Epic extends AgileResource { @@ -17,4 +19,16 @@ public class Epic extends AgileResource { public Epic(RestClient restclient, JSONObject json) { super(restclient, json); } + + /** + * Retrieves the epic matching the ID. + * + * @param restclient REST client instance + * @param id Internal JIRA ID of the epic + * @return an epic instance + * @throws JiraException when the retrieval fails + */ + public static Epic get(RestClient restclient, long id) throws JiraException { + return AgileResource.get(restclient, Epic.class, RESOURCE_URI + "epic/" + id); + } } diff --git a/src/main/java/net/rcarz/jiraclient/agile/Estimation.java b/src/main/java/net/rcarz/jiraclient/agile/Estimation.java deleted file mode 100644 index b864c65..0000000 --- a/src/main/java/net/rcarz/jiraclient/agile/Estimation.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.rcarz.jiraclient.agile; - -/** - * Created by pldupont on 2016-05-20. - */ -public class Estimation { -} diff --git a/src/main/java/net/rcarz/jiraclient/agile/Issue.java b/src/main/java/net/rcarz/jiraclient/agile/Issue.java index d834995..7851ea0 100644 --- a/src/main/java/net/rcarz/jiraclient/agile/Issue.java +++ b/src/main/java/net/rcarz/jiraclient/agile/Issue.java @@ -4,10 +4,9 @@ import net.rcarz.jiraclient.JiraException; import net.rcarz.jiraclient.RestClient; import net.sf.json.JSONObject; -import java.util.List; - /** - * Created by pldupont on 2016-05-20. + * Created on 2016-05-20. + * @author pldupont */ public class Issue extends AgileResource { @@ -29,7 +28,7 @@ public class Issue extends AgileResource { * @return an issue instance * @throws JiraException when the retrieval fails */ - public static Issue get(RestClient restclient, int id) throws JiraException { + public static Issue get(RestClient restclient, long id) throws JiraException { return AgileResource.get(restclient, Issue.class, RESOURCE_URI + "issue/" + id); } diff --git a/src/main/java/net/rcarz/jiraclient/agile/Sprint.java b/src/main/java/net/rcarz/jiraclient/agile/Sprint.java index 696378a..00f58e0 100644 --- a/src/main/java/net/rcarz/jiraclient/agile/Sprint.java +++ b/src/main/java/net/rcarz/jiraclient/agile/Sprint.java @@ -34,14 +34,14 @@ import java.util.List; */ public class Sprint extends AgileResource { - public static final String ATTR_STATE = "state"; - public static final String ATTR_ORIGIN_BOARD_ID = "originBoardId"; - public static final String ATTR_START_DATE = "startDate"; - public static final String ATTR_END_DATE = "endDate"; - public static final String ATTR_COMPLETE_DATE = "completeDate"; + private static final String ATTR_STATE = "state"; + private static final String ATTR_ORIGIN_BOARD_ID = "originBoardId"; + private static final String ATTR_START_DATE = "startDate"; + private static final String ATTR_END_DATE = "endDate"; + private static final String ATTR_COMPLETE_DATE = "completeDate"; private String state; - private int originBoardId; + private long originBoardId; private Date startDate; private Date endDate; private Date completeDate; @@ -64,7 +64,7 @@ public class Sprint extends AgileResource { * @return The sprint for the specified ID. * @throws JiraException when the retrieval fails */ - public static Sprint get(RestClient restclient, int sprintId) throws JiraException { + public static Sprint get(RestClient restclient, long sprintId) throws JiraException { return AgileResource.get(restclient, Sprint.class, RESOURCE_URI + "sprint/" + sprintId); } @@ -76,7 +76,7 @@ public class Sprint extends AgileResource { * @return The list of sprints associated to the board. * @throws JiraException when the retrieval fails */ - public static List getAll(RestClient restclient, int boardId) throws JiraException { + public static List getAll(RestClient restclient, long boardId) throws JiraException { return AgileResource.list(restclient, Sprint.class, RESOURCE_URI + "board/" + boardId + "/sprint"); } @@ -84,7 +84,7 @@ public class Sprint extends AgileResource { protected void deserialize(JSONObject json) { super.deserialize(json); state = Field.getString(json.get(ATTR_STATE)); - originBoardId = Field.getInteger(json.get(ATTR_ORIGIN_BOARD_ID)); + originBoardId = getLong(json.get(ATTR_ORIGIN_BOARD_ID)); startDate = Field.getDateTime(json.get(ATTR_START_DATE)); endDate = Field.getDateTime(json.get(ATTR_END_DATE)); completeDate = Field.getDateTime(json.get(ATTR_COMPLETE_DATE)); @@ -94,7 +94,7 @@ public class Sprint extends AgileResource { return state; } - public int getOriginBoardId() { + public long getOriginBoardId() { return originBoardId; } diff --git a/src/test/groovy/net/rcarz/jiraclient/agile/AbstractResourceTest.groovy b/src/test/groovy/net/rcarz/jiraclient/agile/AbstractResourceTest.groovy index b1f317b..20d00c1 100644 --- a/src/test/groovy/net/rcarz/jiraclient/agile/AbstractResourceTest.groovy +++ b/src/test/groovy/net/rcarz/jiraclient/agile/AbstractResourceTest.groovy @@ -2,6 +2,8 @@ package net.rcarz.jiraclient.agile import net.rcarz.jiraclient.JiraClient import net.rcarz.jiraclient.RestClient +import net.sf.json.JSONObject +import net.sf.json.JSONSerializer import org.hamcrest.core.IsEqual import org.hamcrest.core.IsNot import org.hamcrest.core.IsNull @@ -11,7 +13,8 @@ import static org.mockito.Mockito.mock import static org.mockito.Mockito.when /** - * Created by pldupont on 2016-05-19. + * Created on 2016-05-19. + * @author pldupont */ class AbstractResourceTest { AgileClient agileClient; @@ -29,25 +32,30 @@ class AbstractResourceTest { return mockRestClient } - void "Assert equals to Board 84"(Board board) { + Issue "given an Issue"() { + mockRestClient = mock RestClient.class + return new Issue(mockRestClient, JSONSerializer.toJSON(JSONResources.ISSUE) as JSONObject) + } + + static void "Assert equals to Board 84"(Board board) { assertThat board, new IsNot<>(new IsNull()) - assertThat board.getId(), new IsEqual(JSONResources.BOARD_ID) - assertThat board.getName(), new IsEqual(JSONResources.BOARD_NAME) - assertThat board.getType(), new IsEqual(JSONResources.BOARD_TYPE) - assertThat board.getSelfURL(), new IsEqual(JSONResources.BOARD_SELF) + assertThat board.getId(), new IsEqual(JSONResources.BOARD_ID) + assertThat board.getName(), new IsEqual(JSONResources.BOARD_NAME) + assertThat board.getType(), new IsEqual(JSONResources.BOARD_TYPE) + assertThat board.getSelfURL(), new IsEqual(JSONResources.BOARD_SELF) assertThat board.toString(), new IsEqual( String.format("Board{id=%s, name='%s'}", JSONResources.BOARD_ID, JSONResources.BOARD_NAME)) } - void "Assert equals to Sprint 37"(Sprint sprint) { + static void "Assert equals to Sprint 37"(Sprint sprint) { assertThat sprint, new IsNot<>(new IsNull()) - assertThat sprint.getId(), new IsEqual(JSONResources.SPRINT_ID) - assertThat sprint.getName(), new IsEqual(JSONResources.SPRINT_NAME) - assertThat sprint.getSelfURL(), new IsEqual(JSONResources.SPRINT_SELF) - assertThat sprint.getState(), new IsEqual(JSONResources.SPRINT_STATE) - assertThat sprint.getOriginBoardId(), new IsEqual(JSONResources.SPRINT_ORIGIN_BOARD_ID) + assertThat sprint.getId(), new IsEqual(JSONResources.SPRINT_ID) + assertThat sprint.getName(), new IsEqual(JSONResources.SPRINT_NAME) + assertThat sprint.getSelfURL(), new IsEqual(JSONResources.SPRINT_SELF) + assertThat sprint.getState(), new IsEqual(JSONResources.SPRINT_STATE) + assertThat sprint.getOriginBoardId(), new IsEqual(JSONResources.SPRINT_ORIGIN_BOARD_ID) assertThat sprint.getStartDate(), new IsEqual(JSONResources.SPRINT_START_DATE) assertThat sprint.getEndDate(), new IsEqual(JSONResources.SPRINT_END_DATE) assertThat sprint.getCompleteDate(), new IsEqual(JSONResources.SPRINT_COMPLETE_DATE) @@ -56,15 +64,23 @@ class AbstractResourceTest { JSONResources.SPRINT_ID, JSONResources.SPRINT_NAME)) } - void "Assert equals to Issue 10001"(Issue issue) { - assertThat issue, new IsNot<>(new IsNull()) - assertThat issue.getId(), new IsEqual(JSONResources.ISSUE_ID) - assertThat issue.getName(), new IsNull() - assertThat issue.getSelfURL(), new IsEqual(JSONResources.ISSUE_SELF) + static void "Assert equals to Epic 23"(Epic epic) { + assertThat epic, new IsNot<>(new IsNull()) + assertThat epic.getId(), new IsEqual(JSONResources.EPIC_ID) + assertThat epic.getName(), new IsEqual(JSONResources.EPIC_NAME) + assertThat epic.getSelfURL(), new IsEqual(JSONResources.EPIC_SELF) } - void "Assert equals to Issue HSP-1"(Issue issue) { + static void "Assert equals to Issue 10001"(Issue issue) { + assertThat issue, new IsNot<>(new IsNull()) + assertThat issue.getId(), new IsEqual(JSONResources.ISSUE_ID) + assertThat issue.getName(), new IsNull() + assertThat issue.getSelfURL(), new IsEqual(JSONResources.ISSUE_SELF) + + } + + static void "Assert equals to Issue HSP-1"(Issue issue) { "Assert equals to Issue 10001"(issue) } diff --git a/src/test/groovy/net/rcarz/jiraclient/agile/AgileClientTest.groovy b/src/test/groovy/net/rcarz/jiraclient/agile/AgileClientTest.groovy index 7820536..19ecf71 100644 --- a/src/test/groovy/net/rcarz/jiraclient/agile/AgileClientTest.groovy +++ b/src/test/groovy/net/rcarz/jiraclient/agile/AgileClientTest.groovy @@ -10,7 +10,8 @@ import static org.junit.Assert.assertThat import static org.mockito.Mockito.when /** - * Created by pldupont on 2016-05-19. + * Created on 2016-05-19. + * @author pldupont */ class AgileClientTest extends AbstractResourceTest { @@ -24,30 +25,63 @@ class AgileClientTest extends AbstractResourceTest { assertThat boards, new IsNot<>(new IsNull()) assertThat boards.size(), new IsEqual(2) - "Assert equals to Board 84"(boards.get(0)) + "Assert equals to Board ${JSONResources.BOARD_ID}"(boards.get(0)) } @Test - void "Given an agileClient, when calling getBoard(84), then receive one Board."() { + void "Given an agileClient, when calling getBoard(boardId), then receive one Board."() { "given an Agile Client"() - when(mockRestClient.get(AgileResource.RESOURCE_URI + "board/84")) + when(mockRestClient.get(AgileResource.RESOURCE_URI + "board/" + JSONResources.BOARD_ID)) .thenReturn(JSONSerializer.toJSON(JSONResources.BOARD)) - Board board = agileClient.getBoard(84); + Board board = agileClient.getBoard(JSONResources.BOARD_ID); assertThat board, new IsNot<>(new IsNull()) - "Assert equals to Board 84"(board) + "Assert equals to Board ${JSONResources.BOARD_ID}"(board) } @Test - void "Given an agileClient, when calling getSprint(37), then receive one Sprint."() { + void "Given an agileClient, when calling getSprint(sprintId), then receive one Sprint."() { "given an Agile Client"() - when(mockRestClient.get(AgileResource.RESOURCE_URI + "sprint/37")) + when(mockRestClient.get(AgileResource.RESOURCE_URI + "sprint/" + JSONResources.SPRINT_ID)) .thenReturn(JSONSerializer.toJSON(JSONResources.SPRINT)) - Sprint sprint = agileClient.getSprint(37); + Sprint sprint = agileClient.getSprint(JSONResources.SPRINT_ID); assertThat sprint, new IsNot<>(new IsNull()) - "Assert equals to Sprint 37"(sprint) + "Assert equals to Sprint ${JSONResources.SPRINT_ID}"(sprint) + } + + @Test + void "Given an agileClient, when calling getIssue(id), then receive one Issue."() { + "given an Agile Client"() + when(mockRestClient.get(AgileResource.RESOURCE_URI + "issue/" + JSONResources.ISSUE_ID)) + .thenReturn(JSONSerializer.toJSON(JSONResources.ISSUE)) + + Issue issue = agileClient.getIssue(JSONResources.ISSUE_ID); + + "Assert equals to Issue ${JSONResources.ISSUE_ID}"(issue) + } + + @Test + void "Given an agileClient, when calling getIssue(key), then receive one Issue."() { + "given an Agile Client"() + when(mockRestClient.get(AgileResource.RESOURCE_URI + "issue/" + JSONResources.ISSUE_KEY)) + .thenReturn(JSONSerializer.toJSON(JSONResources.ISSUE)) + + Issue issue = agileClient.getIssue(JSONResources.ISSUE_KEY); + + "Assert equals to Issue ${JSONResources.ISSUE_KEY}"(issue) + } + + @Test + void "Given an agileClient, when calling getEpic(id), then receive one Epic."() { + "given an Agile Client"() + when(mockRestClient.get(AgileResource.RESOURCE_URI + "epic/" + JSONResources.EPIC_ID)) + .thenReturn(JSONSerializer.toJSON(JSONResources.EPIC)) + + Epic epic = agileClient.getEpic(JSONResources.EPIC_ID); + + "Assert equals to Epic ${JSONResources.EPIC_ID}"(epic) } } diff --git a/src/test/groovy/net/rcarz/jiraclient/agile/BoardTest.groovy b/src/test/groovy/net/rcarz/jiraclient/agile/BoardTest.groovy index 8ed3fa0..4061331 100644 --- a/src/test/groovy/net/rcarz/jiraclient/agile/BoardTest.groovy +++ b/src/test/groovy/net/rcarz/jiraclient/agile/BoardTest.groovy @@ -15,7 +15,8 @@ import static org.junit.Assert.assertThat import static org.mockito.Mockito.when /** - * Created by pldupont on 2016-05-19. + * Created on 2016-05-19. + * @author pldupont */ class BoardTest extends AbstractResourceTest { @@ -44,16 +45,16 @@ class BoardTest extends AbstractResourceTest { expectedException.expect(JiraException.class); expectedException.expectMessage("Failed to retrieve a list of Board : /rest/agile/1.0/board"); - List boards = Board.getAll(mockRestClient); + Board.getAll(mockRestClient); } @Test - void "Given a RestClient, when calling getBoard(84), then receive one Board."() { + void "Given a RestClient, when calling getBoard(boardId), then receive one Board."() { RestClient mockRestClient = "given a REST Client"() - when(mockRestClient.get(AgileResource.RESOURCE_URI + "board/84")) + when(mockRestClient.get(AgileResource.RESOURCE_URI + "board/${JSONResources.BOARD_ID}")) .thenReturn(JSONSerializer.toJSON(JSONResources.BOARD)) - Board board = Board.get(mockRestClient, 84); + Board board = Board.get(mockRestClient, JSONResources.BOARD_ID); "Assert equals to Board 84"(board) } @@ -67,24 +68,24 @@ class BoardTest extends AbstractResourceTest { expectedException.expect(JiraException.class); expectedException.expectMessage("Failed to retrieve Board : /rest/agile/1.0/board/666"); - Board board = Board.get(mockRestClient, 666); + Board.get(mockRestClient, 666); } @Test void "Given a valid Board, when calling getSprints(), then receive a list of Sprints."() { RestClient mockRestClient = "given a REST Client"() - when(mockRestClient.get(AgileResource.RESOURCE_URI + "board/84")) + when(mockRestClient.get(AgileResource.RESOURCE_URI + "board/${JSONResources.BOARD_ID}")) .thenReturn(JSONSerializer.toJSON(JSONResources.BOARD)) - when(mockRestClient.get(AgileResource.RESOURCE_URI + "board/84/sprint")) + when(mockRestClient.get(AgileResource.RESOURCE_URI + "board/${JSONResources.BOARD_ID}/sprint")) .thenReturn(JSONSerializer.toJSON(JSONResources.LIST_OF_SPRINTS)) - Board board = Board.get(mockRestClient, 84); - "Assert equals to Board 84"(board) + Board board = Board.get(mockRestClient, JSONResources.BOARD_ID); + "Assert equals to Board ${JSONResources.BOARD_ID}"(board) List sprints = board.getSprints(); assertThat sprints, new IsNot<>(new IsNull()) assertThat sprints.size(), new IsEqual(2) - "Assert equals to Sprint 37"(sprints.get(0)) + "Assert equals to Sprint ${JSONResources.SPRINT_ID}"(sprints.get(0)) } } diff --git a/src/test/groovy/net/rcarz/jiraclient/agile/EpicTest.groovy b/src/test/groovy/net/rcarz/jiraclient/agile/EpicTest.groovy new file mode 100644 index 0000000..bae381b --- /dev/null +++ b/src/test/groovy/net/rcarz/jiraclient/agile/EpicTest.groovy @@ -0,0 +1,44 @@ +package net.rcarz.jiraclient.agile + +import net.rcarz.jiraclient.JiraException +import net.rcarz.jiraclient.RestClient +import net.rcarz.jiraclient.RestException +import net.sf.json.JSONSerializer +import org.junit.Rule +import org.junit.Test +import org.junit.rules.ExpectedException + +import static org.mockito.Mockito.when + +/** + * Created on 2016-05-20. + * @author pldupont + */ +class EpicTest extends AbstractResourceTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + void "Given a valid Epic ID, when calling Epic.get(id), then receive one Epic."() { + RestClient mockRestClient = "given a REST Client"() + when(mockRestClient.get(AgileResource.RESOURCE_URI + "epic/" + JSONResources.EPIC_ID)) + .thenReturn(JSONSerializer.toJSON(JSONResources.EPIC)) + + Epic epic = Epic.get(mockRestClient, JSONResources.EPIC_ID); + + "Assert equals to Epic ${JSONResources.EPIC_ID}"(epic) + } + + @Test + void "Given an invalid epic ID, when calling getEpic(666), then throws an 404 error."() { + RestException unauthorized = new RestException("Do not have access", 404, "Unauthorized") + RestClient mockRestClient = "given a REST Client"() + when(mockRestClient.get(AgileResource.RESOURCE_URI + "epic/666")) + .thenThrow(unauthorized) + expectedException.expect(JiraException.class); + expectedException.expectMessage("Failed to retrieve Epic : /rest/agile/1.0/epic/666"); + + Epic.get(mockRestClient, 666); + } +} diff --git a/src/test/groovy/net/rcarz/jiraclient/agile/IssueTest.groovy b/src/test/groovy/net/rcarz/jiraclient/agile/IssueTest.groovy index 33ff1f4..67870f2 100644 --- a/src/test/groovy/net/rcarz/jiraclient/agile/IssueTest.groovy +++ b/src/test/groovy/net/rcarz/jiraclient/agile/IssueTest.groovy @@ -8,11 +8,11 @@ import org.junit.Rule import org.junit.Test import org.junit.rules.ExpectedException -import static org.mockito.Mockito.when import static org.mockito.Mockito.when /** - * Created by pldupont on 2016-05-20. + * Created on 2016-05-20. + * @author pldupont */ class IssueTest extends AbstractResourceTest { @@ -39,7 +39,7 @@ class IssueTest extends AbstractResourceTest { expectedException.expect(JiraException.class); expectedException.expectMessage("Failed to retrieve Issue : /rest/agile/1.0/issue/666"); - Issue issue = Issue.get(mockRestClient, 666); + Issue.get(mockRestClient, 666); } @Test @@ -62,6 +62,6 @@ class IssueTest extends AbstractResourceTest { expectedException.expect(JiraException.class); expectedException.expectMessage("Failed to retrieve Issue : /rest/agile/1.0/issue/HSP-2"); - Issue issue = Issue.get(mockRestClient, "HSP-2"); + Issue.get(mockRestClient, "HSP-2"); } } diff --git a/src/test/groovy/net/rcarz/jiraclient/agile/JSONResources.groovy b/src/test/groovy/net/rcarz/jiraclient/agile/JSONResources.groovy index 3b8c90c..922c60c 100644 --- a/src/test/groovy/net/rcarz/jiraclient/agile/JSONResources.groovy +++ b/src/test/groovy/net/rcarz/jiraclient/agile/JSONResources.groovy @@ -3,14 +3,15 @@ package net.rcarz.jiraclient.agile import net.rcarz.jiraclient.Field /** - * Created by pldupont on 2016-05-19. + * Created on 2016-05-19. + * @author pldupont */ interface JSONResources { - String BOARD_SELF = "http://www.example.com/jira/rest/agile/1.0/board/84" + long BOARD_ID = 84L + String BOARD_SELF = "http://www.example.com/jira/rest/agile/1.0/board/${BOARD_ID}" String BOARD_NAME = "scrum board" String BOARD_TYPE = "scrum" - int BOARD_ID = 84 String BOARD = """{ "id": ${BOARD_ID}, "self": "${BOARD_SELF}", @@ -34,11 +35,11 @@ interface JSONResources { ] }""" - int SPRINT_ID = 37 + long SPRINT_ID = 37L String SPRINT_NAME = "sprint 1" - String SPRINT_SELF = "http://www.example.com/jira/rest/agile/1.0/sprint/23" + String SPRINT_SELF = "http://www.example.com/jira/rest/agile/1.0/sprint/${SPRINT_ID}" String SPRINT_STATE = "closed" - int SPRINT_ORIGIN_BOARD_ID = BOARD_ID + long SPRINT_ORIGIN_BOARD_ID = BOARD_ID Date SPRINT_START_DATE = Field.getDateTime("2015-04-11T15:22:00.000+10:00") Date SPRINT_END_DATE = Field.getDateTime("2015-04-20T01:22:00.000+10:00") Date SPRINT_COMPLETE_DATE = Field.getDateTime("2015-04-20T11:04:00.000+10:00") @@ -69,7 +70,23 @@ interface JSONResources { ] }""" - int ISSUE_ID = 10001 + long EPIC_ID = 23 + String EPIC_SELF = "http://www.example.com/jira/rest/agile/1.0/epic/${EPIC_ID}" + String EPIC_NAME = "epic 1" + String EPIC_SUMMARY = "epic 1 summary" + boolean EPIC_DONE = true + String EPIC = """{ + "id": ${EPIC_ID}, + "self": "${EPIC_SELF}", + "name": "${EPIC_NAME}", + "summary": "${EPIC_SUMMARY}", + "color": { + "key": "color_4" + }, + "done": ${EPIC_DONE} +}""" + + long ISSUE_ID = 10001L String ISSUE_SELF = "http://www.example.com/jira/rest/agile/1.0/board/92/issue/10001" String ISSUE_KEY = "HSP-1" String ISSUE = """{ @@ -80,14 +97,14 @@ interface JSONResources { "fields": { "flagged": true, "sprint": { - "id": 37, - "self": "http://www.example.com/jira/rest/agile/1.0/sprint/13", + "id": ${SPRINT_ID}, + "self": "http://www.example.com/jira/rest/agile/1.0/sprint/${SPRINT_ID}", "state": "future", "name": "sprint 2" }, "closedSprints": [ { - "id": 37, + "id": 23, "self": "http://www.example.com/jira/rest/agile/1.0/sprint/23", "state": "closed", "name": "sprint 1", diff --git a/src/test/groovy/net/rcarz/jiraclient/agile/SprintTest.groovy b/src/test/groovy/net/rcarz/jiraclient/agile/SprintTest.groovy index 8ae4c1f..05ffd32 100644 --- a/src/test/groovy/net/rcarz/jiraclient/agile/SprintTest.groovy +++ b/src/test/groovy/net/rcarz/jiraclient/agile/SprintTest.groovy @@ -15,7 +15,8 @@ import static org.junit.Assert.assertThat import static org.mockito.Mockito.when /** - * Created by pldupont on 2016-05-19. + * Created on 2016-05-19. + * @author pldupont */ class SprintTest extends AbstractResourceTest { @@ -32,7 +33,7 @@ class SprintTest extends AbstractResourceTest { assertThat sprints, new IsNot<>(new IsNull()) assertThat sprints.size(), new IsEqual(2) - "Assert equals to Sprint 37"(sprints.get(0)) + "Assert equals to Sprint ${JSONResources.SPRINT_ID}"(sprints.get(0)) } @Test @@ -44,18 +45,18 @@ class SprintTest extends AbstractResourceTest { expectedException.expect(JiraException.class); expectedException.expectMessage("Failed to retrieve a list of Sprint : /rest/agile/1.0/board/" + JSONResources.SPRINT_ORIGIN_BOARD_ID + "/sprint"); - List sprints = Sprint.getAll(mockRestClient, JSONResources.SPRINT_ORIGIN_BOARD_ID); + Sprint.getAll(mockRestClient, JSONResources.SPRINT_ORIGIN_BOARD_ID); } @Test - void "Given a RestClient, when calling getSprint(84), then receive one Sprint."() { + void "Given a RestClient, when calling getSprint(sprintId), then receive one Sprint."() { RestClient mockRestClient = "given a REST Client"() - when(mockRestClient.get(AgileResource.RESOURCE_URI + "sprint/37")) + when(mockRestClient.get(AgileResource.RESOURCE_URI + "sprint/${JSONResources.SPRINT_ID}")) .thenReturn(JSONSerializer.toJSON(JSONResources.SPRINT)) - Sprint sprint = Sprint.get(mockRestClient, 37); + Sprint sprint = Sprint.get(mockRestClient, JSONResources.SPRINT_ID); - "Assert equals to Sprint 37"(sprint) + "Assert equals to Sprint ${JSONResources.SPRINT_ID}"(sprint) } @Test @@ -67,6 +68,6 @@ class SprintTest extends AbstractResourceTest { expectedException.expect(JiraException.class); expectedException.expectMessage("Failed to retrieve Sprint : /rest/agile/1.0/sprint/666"); - Sprint sprint = Sprint.get(mockRestClient, 666); + Sprint.get(mockRestClient, 666); } }