Commit 841ca03a355c4f19aa447cc5128fe2caf076ce17
1 parent
edab96f4
Add getBundle method to YoutrackAPI
Showing
10 changed files
with
332 additions
and
2 deletions
| ... | ... | @@ -24,6 +24,12 @@ | 
| 24 | 24 | <artifactId>commons-io</artifactId> | 
| 25 | 25 | <version>2.3</version> | 
| 26 | 26 | </dependency> | 
| 27 | + <dependency> | |
| 28 | + <groupId>org.mockito</groupId> | |
| 29 | + <artifactId>mockito-all</artifactId> | |
| 30 | + <version>1.9.0-rc1</version> | |
| 31 | + <scope>test</scope> | |
| 32 | + </dependency> | |
| 27 | 33 | </dependencies> | 
| 28 | 34 | |
| 29 | 35 | <build> | ... | ... | 
| ... | ... | @@ -31,6 +31,7 @@ import pl.com.it_crowd.youtrack.api.exceptions.NoResultFoundException; | 
| 31 | 31 | import pl.com.it_crowd.youtrack.api.exceptions.YoutrackAPIException; | 
| 32 | 32 | import pl.com.it_crowd.youtrack.api.exceptions.YoutrackErrorException; | 
| 33 | 33 | import pl.com.it_crowd.youtrack.api.rest.AssigneeList; | 
| 34 | +import pl.com.it_crowd.youtrack.api.rest.Enumeration; | |
| 34 | 35 | import pl.com.it_crowd.youtrack.api.rest.Issue; | 
| 35 | 36 | import pl.com.it_crowd.youtrack.api.rest.Issues; | 
| 36 | 37 | import pl.com.it_crowd.youtrack.api.rest.User; | 
| ... | ... | @@ -61,6 +62,8 @@ import java.util.regex.Pattern; | 
| 61 | 62 | public class YoutrackAPI { | 
| 62 | 63 | // ------------------------------ FIELDS ------------------------------ | 
| 63 | 64 | |
| 65 | + private final static QName Enumeration_QNAME = new QName("", "enumeration"); | |
| 66 | + | |
| 64 | 67 | private final static QName Issue_QNAME = new QName("", "issue"); | 
| 65 | 68 | |
| 66 | 69 | private HttpClient httpClient; | 
| ... | ... | @@ -241,6 +244,29 @@ public class YoutrackAPI { | 
| 241 | 244 | } | 
| 242 | 245 | } | 
| 243 | 246 | |
| 247 | + public Enumeration getBundle(String customField) throws IOException, JAXBException | |
| 248 | + { | |
| 249 | + final URI uri; | |
| 250 | + try { | |
| 251 | + uri = new URIBuilder(serviceLocation + "/rest/admin/customfield/bundle/" + customField).build(); | |
| 252 | + } catch (URISyntaxException e) { | |
| 253 | + throw new RuntimeException(e); | |
| 254 | + } | |
| 255 | + final Object result = YoutrackUnmarshaller.unmarshall(execute(new HttpGet(uri))); | |
| 256 | + if (result instanceof Enumeration) { | |
| 257 | + return (Enumeration) result; | |
| 258 | + } else if (result instanceof JAXBElement) { | |
| 259 | + final JAXBElement jaxbElement = (JAXBElement) result; | |
| 260 | + if (Enumeration_QNAME.equals(jaxbElement.getName())) { | |
| 261 | + return (Enumeration) ((JAXBElement) result).getValue(); | |
| 262 | + } else { | |
| 263 | + throw new YoutrackAPIException("Unexpected type: " + jaxbElement.getValue()); | |
| 264 | + } | |
| 265 | + } else { | |
| 266 | + throw new YoutrackAPIException("Unexpected type: " + result); | |
| 267 | + } | |
| 268 | + } | |
| 269 | + | |
| 244 | 270 | public List<User> getIndividualAssignees(String project) throws IOException, JAXBException | 
| 245 | 271 | { | 
| 246 | 272 | final URI uri; | ... | ... | 
| 1 | +// | |
| 2 | +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 | |
| 3 | +// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> | |
| 4 | +// Any modifications to this file will be lost upon recompilation of the source schema. | |
| 5 | +// | |
| 6 | +package pl.com.it_crowd.youtrack.api.rest; | |
| 7 | + | |
| 8 | +import javax.xml.bind.annotation.XmlAccessType; | |
| 9 | +import javax.xml.bind.annotation.XmlAccessorType; | |
| 10 | +import javax.xml.bind.annotation.XmlAttribute; | |
| 11 | +import javax.xml.bind.annotation.XmlElement; | |
| 12 | +import javax.xml.bind.annotation.XmlType; | |
| 13 | +import java.util.ArrayList; | |
| 14 | +import java.util.List; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * <p>Java class for enumerationType complex type. | |
| 18 | + * <p/> | |
| 19 | + * <p>The following schema fragment specifies the expected content contained within this class. | |
| 20 | + * <p/> | |
| 21 | + * <pre> | |
| 22 | + * <complexType name="enumerationType"> | |
| 23 | + * <complexContent> | |
| 24 | + * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> | |
| 25 | + * <sequence> | |
| 26 | + * <element name="value" type="{}enumerationValueType" maxOccurs="unbounded" minOccurs="0"/> | |
| 27 | + * </sequence> | |
| 28 | + * <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" /> | |
| 29 | + * </restriction> | |
| 30 | + * </complexContent> | |
| 31 | + * </complexType> | |
| 32 | + * </pre> | |
| 33 | + */ | |
| 34 | +@XmlAccessorType(XmlAccessType.FIELD) | |
| 35 | +@XmlType(name = "enumerationType", propOrder = {"values"}) | |
| 36 | +public class Enumeration { | |
| 37 | +// ------------------------------ FIELDS ------------------------------ | |
| 38 | + | |
| 39 | + @XmlAttribute | |
| 40 | + protected String name; | |
| 41 | + | |
| 42 | + @XmlElement(name = "value") | |
| 43 | + protected List<EnumerationValue> values; | |
| 44 | + | |
| 45 | +// --------------------- GETTER / SETTER METHODS --------------------- | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * Gets the value of the name property. | |
| 49 | + * | |
| 50 | + * @return possible object is | |
| 51 | + * {@link String } | |
| 52 | + */ | |
| 53 | + public String getName() | |
| 54 | + { | |
| 55 | + return name; | |
| 56 | + } | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * Sets the value of the name property. | |
| 60 | + * | |
| 61 | + * @param value allowed object is | |
| 62 | + * {@link String } | |
| 63 | + */ | |
| 64 | + public void setName(String value) | |
| 65 | + { | |
| 66 | + this.name = value; | |
| 67 | + } | |
| 68 | + | |
| 69 | + /** | |
| 70 | + * Gets the value of the values property. | |
| 71 | + * <p/> | |
| 72 | + * <p/> | |
| 73 | + * This accessor method returns a reference to the live list, | |
| 74 | + * not a snapshot. Therefore any modification you make to the | |
| 75 | + * returned list will be present inside the JAXB object. | |
| 76 | + * This is why there is not a <CODE>set</CODE> method for the values property. | |
| 77 | + * <p/> | |
| 78 | + * <p/> | |
| 79 | + * For example, to add a new item, do as follows: | |
| 80 | + * <pre> | |
| 81 | + * getValues().add(newItem); | |
| 82 | + * </pre> | |
| 83 | + * <p/> | |
| 84 | + * <p/> | |
| 85 | + * <p/> | |
| 86 | + * Objects of the following type(s) are allowed in the list | |
| 87 | + * {@link EnumerationValue } | |
| 88 | + */ | |
| 89 | + public List<EnumerationValue> getValues() | |
| 90 | + { | |
| 91 | + if (values == null) { | |
| 92 | + values = new ArrayList<EnumerationValue>(); | |
| 93 | + } | |
| 94 | + return this.values; | |
| 95 | + } | |
| 96 | +} | ... | ... | 
| 1 | +// | |
| 2 | +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 | |
| 3 | +// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> | |
| 4 | +// Any modifications to this file will be lost upon recompilation of the source schema. | |
| 5 | +// | |
| 6 | +package pl.com.it_crowd.youtrack.api.rest; | |
| 7 | + | |
| 8 | +import javax.xml.bind.annotation.XmlAccessType; | |
| 9 | +import javax.xml.bind.annotation.XmlAccessorType; | |
| 10 | +import javax.xml.bind.annotation.XmlAttribute; | |
| 11 | +import javax.xml.bind.annotation.XmlType; | |
| 12 | +import javax.xml.bind.annotation.XmlValue; | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * <p>Java class for enumerationValueType complex type. | |
| 16 | + * <p/> | |
| 17 | + * <p>The following schema fragment specifies the expected content contained within this class. | |
| 18 | + * <p/> | |
| 19 | + * <pre> | |
| 20 | + * <complexType name="enumerationValueType"> | |
| 21 | + * <simpleContent> | |
| 22 | + * <extension base="<http://www.w3.org/2001/XMLSchema>string"> | |
| 23 | + * <attribute name="colorIndex" type="{http://www.w3.org/2001/XMLSchema}long" /> | |
| 24 | + * </extension> | |
| 25 | + * </simpleContent> | |
| 26 | + * </complexType> | |
| 27 | + * </pre> | |
| 28 | + */ | |
| 29 | +@XmlAccessorType(XmlAccessType.FIELD) | |
| 30 | +@XmlType(name = "enumerationValueType", propOrder = {"value"}) | |
| 31 | +public class EnumerationValue { | |
| 32 | +// ------------------------------ FIELDS ------------------------------ | |
| 33 | + | |
| 34 | + @XmlAttribute | |
| 35 | + protected Long colorIndex; | |
| 36 | + | |
| 37 | + @XmlValue | |
| 38 | + protected String value; | |
| 39 | + | |
| 40 | +// --------------------- GETTER / SETTER METHODS --------------------- | |
| 41 | + | |
| 42 | + /** | |
| 43 | + * Gets the value of the colorIndex property. | |
| 44 | + * | |
| 45 | + * @return possible object is | |
| 46 | + * {@link Long } | |
| 47 | + */ | |
| 48 | + public Long getColorIndex() | |
| 49 | + { | |
| 50 | + return colorIndex; | |
| 51 | + } | |
| 52 | + | |
| 53 | + /** | |
| 54 | + * Sets the value of the colorIndex property. | |
| 55 | + * | |
| 56 | + * @param value allowed object is | |
| 57 | + * {@link Long } | |
| 58 | + */ | |
| 59 | + public void setColorIndex(Long value) | |
| 60 | + { | |
| 61 | + this.colorIndex = value; | |
| 62 | + } | |
| 63 | + | |
| 64 | + /** | |
| 65 | + * Gets the value of the value property. | |
| 66 | + * | |
| 67 | + * @return possible object is | |
| 68 | + * {@link String } | |
| 69 | + */ | |
| 70 | + public String getValue() | |
| 71 | + { | |
| 72 | + return value; | |
| 73 | + } | |
| 74 | + | |
| 75 | + /** | |
| 76 | + * Sets the value of the value property. | |
| 77 | + * | |
| 78 | + * @param value allowed object is | |
| 79 | + * {@link String } | |
| 80 | + */ | |
| 81 | + public void setValue(String value) | |
| 82 | + { | |
| 83 | + this.value = value; | |
| 84 | + } | |
| 85 | +} | ... | ... | 
| ... | ... | @@ -31,6 +31,8 @@ public class ObjectFactory { | 
| 31 | 31 | |
| 32 | 32 | private final static QName _CommentValue_QNAME = new QName("", "value"); | 
| 33 | 33 | |
| 34 | + private final static QName _Enumeration_QNAME = new QName("", "enumeration"); | |
| 35 | + | |
| 34 | 36 | private final static QName _Error_QNAME = new QName("", "error"); | 
| 35 | 37 | |
| 36 | 38 | private final static QName _Int_QNAME = new QName("", "int"); | 
| ... | ... | @@ -115,6 +117,31 @@ public class ObjectFactory { | 
| 115 | 117 | } | 
| 116 | 118 | |
| 117 | 119 | /** | 
| 120 | + * Create an instance of {@link Enumeration } | |
| 121 | + */ | |
| 122 | + public Enumeration createEnumeration() | |
| 123 | + { | |
| 124 | + return new Enumeration(); | |
| 125 | + } | |
| 126 | + | |
| 127 | + /** | |
| 128 | + * Create an instance of {@link JAXBElement }{@code <}{@link Enumeration }{@code >}} | |
| 129 | + */ | |
| 130 | + @XmlElementDecl(namespace = "", name = "enumeration") | |
| 131 | + public JAXBElement<Enumeration> createEnumeration(Enumeration value) | |
| 132 | + { | |
| 133 | + return new JAXBElement<Enumeration>(_Enumeration_QNAME, Enumeration.class, null, value); | |
| 134 | + } | |
| 135 | + | |
| 136 | + /** | |
| 137 | + * Create an instance of {@link EnumerationValue } | |
| 138 | + */ | |
| 139 | + public EnumerationValue createEnumerationValue() | |
| 140 | + { | |
| 141 | + return new EnumerationValue(); | |
| 142 | + } | |
| 143 | + | |
| 144 | + /** | |
| 118 | 145 | * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} | 
| 119 | 146 | */ | 
| 120 | 147 | @XmlElementDecl(namespace = "", name = "error") | ... | ... | 
| 1 | -<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" | |
| 2 | - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
| 1 | +<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
| 3 | 2 | xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"> | 
| 4 | 3 | |
| 5 | 4 | |
| ... | ... | @@ -25,6 +24,17 @@ | 
| 25 | 24 | |
| 26 | 25 | <jxb:globalBindings localScoping="nested"/> | 
| 27 | 26 | |
| 27 | + <jxb:bindings node=".//xs:complexType[@name='enumerationType']"> | |
| 28 | + <jxb:bindings node="./xs:sequence[@id='enumerationTypeValue']"> | |
| 29 | + <jxb:property name="values"/> | |
| 30 | + </jxb:bindings> | |
| 31 | + <jxb:class name="Enumeration"/> | |
| 32 | + </jxb:bindings> | |
| 33 | + | |
| 34 | + <jxb:bindings node=".//xs:complexType[@name='enumerationValueType']"> | |
| 35 | + <jxb:class name="EnumerationValue"/> | |
| 36 | + </jxb:bindings> | |
| 37 | + | |
| 28 | 38 | <jxb:bindings node=".//xs:complexType[@name='fieldType']"> | 
| 29 | 39 | <jxb:bindings node="./xs:sequence[@id='value']"> | 
| 30 | 40 | <jxb:property name="values"/> | ... | ... | 
src/main/xsd/bundle.xml
0 → 100644
| 1 | +<enumeration name="Priorities"> | |
| 2 | + <value colorIndex="20">Show-stopper</value> | |
| 3 | + <value colorIndex="19">Critical</value> | |
| 4 | + <value colorIndex="18">Major</value> | |
| 5 | + <value colorIndex="17">Normal</value> | |
| 6 | + <value colorIndex="16">Minor</value> | |
| 7 | +</enumeration> | |
| \ No newline at end of file | ... | ... | 
src/main/xsd/bundle.xsd
0 → 100644
| ... | ... | @@ -15,6 +15,21 @@ | 
| 15 | 15 | <xs:attribute type="xs:string" name="isIndividualAssignee" use="optional"/> | 
| 16 | 16 | </xs:complexType> | 
| 17 | 17 | |
| 18 | + <xs:complexType name="enumerationType"> | |
| 19 | + <xs:sequence id="enumerationTypeValue"> | |
| 20 | + <xs:element type="enumerationValueType" name="value" maxOccurs="unbounded" minOccurs="0"/> | |
| 21 | + </xs:sequence> | |
| 22 | + <xs:attribute type="xs:string" name="name"/> | |
| 23 | + </xs:complexType> | |
| 24 | + | |
| 25 | + <xs:complexType name="enumerationValueType"> | |
| 26 | + <xs:simpleContent> | |
| 27 | + <xs:extension base="xs:string"> | |
| 28 | + <xs:attribute type="xs:long" name="colorIndex" use="optional"/> | |
| 29 | + </xs:extension> | |
| 30 | + </xs:simpleContent> | |
| 31 | + </xs:complexType> | |
| 32 | + | |
| 18 | 33 | <xs:complexType name="fieldType"> | 
| 19 | 34 | <xs:sequence id="value" maxOccurs="unbounded" minOccurs="0"> | 
| 20 | 35 | <xs:element name="value"> | ... | ... | 
| 1 | 1 | package pl.com.it_crowd.youtrack.api.rest; | 
| 2 | 2 | |
| 3 | 3 | import junit.framework.Assert; | 
| 4 | +import org.apache.commons.io.input.ReaderInputStream; | |
| 5 | +import org.apache.http.HttpEntity; | |
| 6 | +import org.apache.http.HttpResponse; | |
| 4 | 7 | import org.apache.http.HttpStatus; | 
| 8 | +import org.apache.http.StatusLine; | |
| 5 | 9 | import org.apache.http.auth.AuthenticationException; | 
| 10 | +import org.apache.http.client.HttpClient; | |
| 11 | +import org.apache.http.client.methods.HttpUriRequest; | |
| 6 | 12 | import org.junit.Test; | 
| 7 | 13 | import pl.com.it_crowd.youtrack.api.Command; | 
| 8 | 14 | import pl.com.it_crowd.youtrack.api.Filter; | 
| ... | ... | @@ -15,8 +21,15 @@ import pl.com.it_crowd.youtrack.api.exceptions.YoutrackErrorException; | 
| 15 | 21 | |
| 16 | 22 | import javax.xml.bind.JAXBException; | 
| 17 | 23 | import java.io.IOException; | 
| 24 | +import java.io.StringReader; | |
| 18 | 25 | import java.util.List; | 
| 19 | 26 | |
| 27 | +import static org.junit.Assert.assertEquals; | |
| 28 | +import static org.junit.Assert.assertNotNull; | |
| 29 | +import static org.mockito.Matchers.any; | |
| 30 | +import static org.mockito.Mockito.mock; | |
| 31 | +import static org.mockito.Mockito.when; | |
| 32 | + | |
| 20 | 33 | /** | 
| 21 | 34 | * This test requires Youtrack instance with "Test(TST)" project to be running and expects following JVM params: | 
| 22 | 35 | * youtrackLocation, youtrackUsername and youtrackPassword. | 
| ... | ... | @@ -104,6 +117,43 @@ public class YoutrackAPITest { | 
| 104 | 117 | } | 
| 105 | 118 | |
| 106 | 119 | @Test | 
| 120 | + public void getBundle() throws Exception | |
| 121 | + { | |
| 122 | +// Given | |
| 123 | + final HttpResponse httpResponse = mock(HttpResponse.class); | |
| 124 | + final HttpEntity httpEntity = mock(HttpEntity.class); | |
| 125 | + final String response = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><enumeration name=\"Priorities\"><value colorIndex=\"20\">Show-stopper</value><value colorIndex=\"19\">Critical</value><value colorIndex=\"18\">Major</value><value colorIndex=\"17\">Normal</value><value colorIndex=\"16\">Minor</value></enumeration>"; | |
| 126 | + when(httpEntity.getContent()).thenReturn(new ReaderInputStream(new StringReader(response))); | |
| 127 | + when(httpEntity.getContentLength()).thenReturn((long) response.getBytes().length); | |
| 128 | + when(httpResponse.getEntity()).thenReturn(httpEntity); | |
| 129 | + final StatusLine statusLine = mock(StatusLine.class); | |
| 130 | + when(statusLine.getStatusCode()).thenReturn(200); | |
| 131 | + when(httpResponse.getStatusLine()).thenReturn(statusLine); | |
| 132 | + final HttpClient httpClient = mock(HttpClient.class); | |
| 133 | + when(httpClient.execute(any(HttpUriRequest.class))).thenReturn(httpResponse); | |
| 134 | + final YoutrackAPI youtrackAPI = new YoutrackAPI("zonk", httpClient); | |
| 135 | + | |
| 136 | +// When | |
| 137 | + final Enumeration priorities = youtrackAPI.getBundle("Priorities"); | |
| 138 | + | |
| 139 | +// Then | |
| 140 | + assertNotNull(priorities); | |
| 141 | + assertEquals("Priorities", priorities.getName()); | |
| 142 | + assertNotNull(priorities.getValues()); | |
| 143 | + assertEquals(5, priorities.getValues().size()); | |
| 144 | + assertEquals("Show-stopper", priorities.getValues().get(0).getValue()); | |
| 145 | + assertEquals(new Long(20), priorities.getValues().get(0).getColorIndex()); | |
| 146 | + assertEquals("Critical", priorities.getValues().get(1).getValue()); | |
| 147 | + assertEquals(new Long(19), priorities.getValues().get(1).getColorIndex()); | |
| 148 | + assertEquals("Major", priorities.getValues().get(2).getValue()); | |
| 149 | + assertEquals(new Long(18), priorities.getValues().get(2).getColorIndex()); | |
| 150 | + assertEquals("Normal", priorities.getValues().get(3).getValue()); | |
| 151 | + assertEquals(new Long(17), priorities.getValues().get(3).getColorIndex()); | |
| 152 | + assertEquals("Minor", priorities.getValues().get(4).getValue()); | |
| 153 | + assertEquals(new Long(16), priorities.getValues().get(4).getColorIndex()); | |
| 154 | + } | |
| 155 | + | |
| 156 | + @Test | |
| 107 | 157 | public void getIndividualAssignees() throws IOException, JAXBException | 
| 108 | 158 | { | 
| 109 | 159 | final YoutrackAPI api = new YoutrackAPI(getServiceLocation(), getUsername(), getPassword()); | ... | ... | 
Please
register
or
login
to post a comment