Commit ea864f53e97a822f322ad9c26f1a7de98462e0cf

Authored by bernard
1 parent 8f984e42

Handle command error

1 -package pl.itcrowd.youtrack.api;  
2 -  
3 -import org.apache.commons.io.IOUtils;  
4 -import pl.itcrowd.youtrack.api.rest.ObjectFactory;  
5 -  
6 -import javax.xml.bind.JAXBContext;  
7 -import javax.xml.bind.JAXBElement;  
8 -import javax.xml.bind.JAXBException;  
9 -import java.io.IOException;  
10 -import java.io.Reader;  
11 -import java.io.StringReader;  
12 -  
13 -//TODO methods from this class should be probably merged with YoutrackUnmarshaller  
14 -public final class ErrorUnmarshaller {  
15 -  
16 - public static String unmarshal(String string) throws JAXBException, IOException  
17 - {  
18 - return unmarshal(new StringReader(string));  
19 - }  
20 -  
21 - public static String unmarshal(Reader reader) throws JAXBException, IOException  
22 - {  
23 - String content = IOUtils.toString(reader);  
24 - try {  
25 - JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);  
26 - @SuppressWarnings("unchecked")  
27 - final JAXBElement<String> element = (JAXBElement<String>) jaxbContext.createUnmarshaller().unmarshal(new StringReader(content));  
28 - return element.getValue();  
29 - } catch (JAXBException e) {  
30 -// TODO we need logging here  
31 - System.err.println("Cannot unmarshal input stream.\n" + content + e);  
32 - throw e;  
33 - }  
34 - }  
35 -  
36 - private ErrorUnmarshaller()  
37 - {  
38 - }  
39 -}  
@@ -345,13 +345,14 @@ public class YoutrackAPI { @@ -345,13 +345,14 @@ public class YoutrackAPI {
345 345
346 private String execute(HttpUriRequest request) throws IOException 346 private String execute(HttpUriRequest request) throws IOException
347 { 347 {
  348 + request.addHeader("Accept","application/xml");
348 final HttpResponse response = httpClient.execute(request); 349 final HttpResponse response = httpClient.execute(request);
349 final StatusLine statusLine = response.getStatusLine(); 350 final StatusLine statusLine = response.getStatusLine();
350 final HttpEntity entity = response.getEntity(); 351 final HttpEntity entity = response.getEntity();
351 String responseText = entity == null ? null : EntityUtils.toString(entity); 352 String responseText = entity == null ? null : EntityUtils.toString(entity);
352 if (statusLine.getStatusCode() >= 300) { 353 if (statusLine.getStatusCode() >= 300) {
353 try { 354 try {
354 - final String error = ErrorUnmarshaller.unmarshal(responseText); 355 + final String error = YoutrackUnmarshaller.unmarshalError(responseText);
355 throw new YoutrackErrorException(error, statusLine.getStatusCode()); 356 throw new YoutrackErrorException(error, statusLine.getStatusCode());
356 } catch (JAXBException e) { 357 } catch (JAXBException e) {
357 LOG.error("Cannot unmarshal following response text:\n" + responseText, e); 358 LOG.error("Cannot unmarshal following response text:\n" + responseText, e);
1 package pl.itcrowd.youtrack.api; 1 package pl.itcrowd.youtrack.api;
2 2
  3 +import org.apache.commons.io.IOUtils;
  4 +import org.apache.commons.logging.Log;
  5 +import org.apache.commons.logging.LogFactory;
  6 +import pl.itcrowd.youtrack.api.exceptions.YoutrackAPIException;
  7 +import pl.itcrowd.youtrack.api.rest.ErrorType;
3 import pl.itcrowd.youtrack.api.rest.ObjectFactory; 8 import pl.itcrowd.youtrack.api.rest.ObjectFactory;
4 9
5 import javax.xml.bind.JAXBContext; 10 import javax.xml.bind.JAXBContext;
  11 +import javax.xml.bind.JAXBElement;
6 import javax.xml.bind.JAXBException; 12 import javax.xml.bind.JAXBException;
  13 +import java.io.IOException;
7 import java.io.Reader; 14 import java.io.Reader;
  15 +import java.io.Serializable;
8 import java.io.StringReader; 16 import java.io.StringReader;
9 17
10 public final class YoutrackUnmarshaller { 18 public final class YoutrackUnmarshaller {
11 19
  20 + private static Log LOG = LogFactory.getLog(YoutrackUnmarshaller.class);
  21 +
  22 + private YoutrackUnmarshaller()
  23 + {
  24 + }
  25 +
  26 + public static String unmarshalError(String string) throws JAXBException, IOException
  27 + {
  28 + return unmarshalError(new StringReader(string));
  29 + }
  30 +
  31 + public static String unmarshalError(Reader reader) throws JAXBException, IOException
  32 + {
  33 + String content = IOUtils.toString(reader);
  34 + try {
  35 + JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
  36 + @SuppressWarnings("unchecked")
  37 + final JAXBElement<ErrorType> element = (JAXBElement<ErrorType>) jaxbContext.createUnmarshaller().unmarshal(new StringReader(content));
  38 + final ErrorType value = element.getValue();
  39 + final int contentSize = value.getContent().size();
  40 + if (contentSize == 0) {
  41 + return "";
  42 + } else if (contentSize == 1) {
  43 + final Serializable serializable = value.getContent().get(0);
  44 + if (serializable instanceof JAXBElement) {
  45 + if ("message".equals(((JAXBElement) serializable).getName().getLocalPart())) {
  46 + final Object messageValue = ((JAXBElement) serializable).getValue();
  47 + return messageValue == null ? "" : messageValue.toString();
  48 + }
  49 + } else {
  50 + return serializable == null ? "" : serializable.toString();
  51 + }
  52 + } else if (contentSize == 2) {
  53 + for (Serializable serializable : value.getContent()) {
  54 + if (serializable instanceof JAXBElement) {
  55 + if ("message".equals(((JAXBElement) serializable).getName().getLocalPart())) {
  56 + final Object messageValue = ((JAXBElement) serializable).getValue();
  57 + return messageValue == null ? "" : messageValue.toString();
  58 + }
  59 + }
  60 + }
  61 + }
  62 + throw new YoutrackAPIException("Cannot unserialize error.\n" + content);
  63 + } catch (JAXBException e) {
  64 + LOG.error("Cannot unmarshal error.\n" + content, e);
  65 + throw e;
  66 + }
  67 + }
  68 +
12 public static Object unmarshall(String string) throws JAXBException 69 public static Object unmarshall(String string) throws JAXBException
13 { 70 {
14 return unmarshall(new StringReader(string)); 71 return unmarshall(new StringReader(string));
@@ -18,8 +75,4 @@ public final class YoutrackUnmarshaller { @@ -18,8 +75,4 @@ public final class YoutrackUnmarshaller {
18 { 75 {
19 return JAXBContext.newInstance(ObjectFactory.class).createUnmarshaller().unmarshal(reader); 76 return JAXBContext.newInstance(ObjectFactory.class).createUnmarshaller().unmarshal(reader);
20 } 77 }
21 -  
22 - private YoutrackUnmarshaller()  
23 - {  
24 - }  
25 } 78 }
@@ -108,8 +108,8 @@ public class Comment { @@ -108,8 +108,8 @@ public class Comment {
108 * <p/> 108 * <p/>
109 * Objects of the following type(s) are allowed in the list 109 * Objects of the following type(s) are allowed in the list
110 * {@link JAXBElement }{@code <}{@link Comment.Value }{@code >} 110 * {@link JAXBElement }{@code <}{@link Comment.Value }{@code >}
111 - * {@link JAXBElement }{@code <}{@link String }{@code >}  
112 * {@link String } 111 * {@link String }
  112 + * {@link JAXBElement }{@code <}{@link String }{@code >}
113 */ 113 */
114 public List<Serializable> getContent() 114 public List<Serializable> getContent()
115 { 115 {
  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.itcrowd.youtrack.api.rest;
  7 +
  8 +import javax.xml.bind.JAXBElement;
  9 +import javax.xml.bind.annotation.XmlAccessType;
  10 +import javax.xml.bind.annotation.XmlAccessorType;
  11 +import javax.xml.bind.annotation.XmlElementRef;
  12 +import javax.xml.bind.annotation.XmlElementRefs;
  13 +import javax.xml.bind.annotation.XmlMixed;
  14 +import javax.xml.bind.annotation.XmlType;
  15 +import java.io.Serializable;
  16 +import java.util.ArrayList;
  17 +import java.util.List;
  18 +
  19 +/**
  20 + * <p>Java class for errorType complex type.
  21 + * <p/>
  22 + * <p>The following schema fragment specifies the expected content contained within this class.
  23 + * <p/>
  24 + * <pre>
  25 + * &lt;complexType name="errorType">
  26 + * &lt;complexContent>
  27 + * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
  28 + * &lt;sequence>
  29 + * &lt;element name="message" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
  30 + * &lt;element name="field" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
  31 + * &lt;/sequence>
  32 + * &lt;/restriction>
  33 + * &lt;/complexContent>
  34 + * &lt;/complexType>
  35 + * </pre>
  36 + */
  37 +@XmlAccessorType(XmlAccessType.FIELD)
  38 +@XmlType(name = "errorType", propOrder = {"content"})
  39 +public class ErrorType {
  40 +
  41 + @XmlElementRefs({@XmlElementRef(name = "message", type = JAXBElement.class), @XmlElementRef(name = "field", type = JAXBElement.class)})
  42 + @XmlMixed
  43 + protected List<Serializable> content;
  44 +
  45 + /**
  46 + * Gets the value of the content property.
  47 + * <p/>
  48 + * <p/>
  49 + * This accessor method returns a reference to the live list,
  50 + * not a snapshot. Therefore any modification you make to the
  51 + * returned list will be present inside the JAXB object.
  52 + * This is why there is not a <CODE>set</CODE> method for the content property.
  53 + * <p/>
  54 + * <p/>
  55 + * For example, to add a new item, do as follows:
  56 + * <pre>
  57 + * getContent().add(newItem);
  58 + * </pre>
  59 + * <p/>
  60 + * <p/>
  61 + * <p/>
  62 + * Objects of the following type(s) are allowed in the list
  63 + * {@link JAXBElement }{@code <}{@link String }{@code >}
  64 + * {@link String }
  65 + * {@link JAXBElement }{@code <}{@link String }{@code >}
  66 + */
  67 + public List<Serializable> getContent()
  68 + {
  69 + if (content == null) {
  70 + content = new ArrayList<Serializable>();
  71 + }
  72 + return this.content;
  73 + }
  74 +}
@@ -37,7 +37,7 @@ import java.util.List; @@ -37,7 +37,7 @@ import java.util.List;
37 @XmlType(name = "issueType", propOrder = {"fieldOrComment"}) 37 @XmlType(name = "issueType", propOrder = {"fieldOrComment"})
38 public class Issue { 38 public class Issue {
39 39
40 - @XmlElements({@XmlElement(name = "comment", type = Comment.class), @XmlElement(name = "field", type = Field.class)}) 40 + @XmlElements({@XmlElement(name = "field", type = Field.class), @XmlElement(name = "comment", type = Comment.class)})
41 protected List<Object> fieldOrComment; 41 protected List<Object> fieldOrComment;
42 42
43 @XmlAttribute 43 @XmlAttribute
@@ -61,8 +61,8 @@ public class Issue { @@ -61,8 +61,8 @@ public class Issue {
61 * <p/> 61 * <p/>
62 * <p/> 62 * <p/>
63 * Objects of the following type(s) are allowed in the list 63 * Objects of the following type(s) are allowed in the list
64 - * {@link Comment }  
65 * {@link Field } 64 * {@link Field }
  65 + * {@link Comment }
66 */ 66 */
67 public List<Object> getFieldOrComment() 67 public List<Object> getFieldOrComment()
68 { 68 {
@@ -38,6 +38,10 @@ public class ObjectFactory { @@ -38,6 +38,10 @@ public class ObjectFactory {
38 38
39 private final static QName _CommentValue_QNAME = new QName("", "value"); 39 private final static QName _CommentValue_QNAME = new QName("", "value");
40 40
  41 + private final static QName _ErrorTypeField_QNAME = new QName("", "field");
  42 +
  43 + private final static QName _ErrorTypeMessage_QNAME = new QName("", "message");
  44 +
41 /** 45 /**
42 * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: pl.itcrowd.youtrack.api.rest 46 * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: pl.itcrowd.youtrack.api.rest
43 */ 47 */
@@ -46,27 +50,27 @@ public class ObjectFactory { @@ -46,27 +50,27 @@ public class ObjectFactory {
46 } 50 }
47 51
48 /** 52 /**
49 - * Create an instance of {@link Comment.Value } 53 + * Create an instance of {@link Field }
50 */ 54 */
51 - public Comment.Value createCommentValue() 55 + public Field createField()
52 { 56 {
53 - return new Comment.Value(); 57 + return new Field();
54 } 58 }
55 59
56 /** 60 /**
57 - * Create an instance of {@link EnumerationValue } 61 + * Create an instance of {@link Enumeration }
58 */ 62 */
59 - public EnumerationValue createEnumerationValue() 63 + public Enumeration createEnumeration()
60 { 64 {
61 - return new EnumerationValue(); 65 + return new Enumeration();
62 } 66 }
63 67
64 /** 68 /**
65 - * Create an instance of {@link Issue } 69 + * Create an instance of {@link User }
66 */ 70 */
67 - public Issue createIssue() 71 + public User createUser()
68 { 72 {
69 - return new Issue(); 73 + return new User();
70 } 74 }
71 75
72 /** 76 /**
@@ -78,59 +82,67 @@ public class ObjectFactory { @@ -78,59 +82,67 @@ public class ObjectFactory {
78 } 82 }
79 83
80 /** 84 /**
81 - * Create an instance of {@link User } 85 + * Create an instance of {@link Issues }
82 */ 86 */
83 - public User createUser() 87 + public Issues createIssues()
84 { 88 {
85 - return new User(); 89 + return new Issues();
86 } 90 }
87 91
88 /** 92 /**
89 - * Create an instance of {@link Issues } 93 + * Create an instance of {@link AssigneeList }
90 */ 94 */
91 - public Issues createIssues() 95 + public AssigneeList createAssigneeList()
92 { 96 {
93 - return new Issues(); 97 + return new AssigneeList();
94 } 98 }
95 99
96 /** 100 /**
97 - * Create an instance of {@link Field } 101 + * Create an instance of {@link Field.Value }
98 */ 102 */
99 - public Field createField() 103 + public Field.Value createFieldValue()
100 { 104 {
101 - return new Field(); 105 + return new Field.Value();
102 } 106 }
103 107
104 /** 108 /**
105 - * Create an instance of {@link Comment } 109 + * Create an instance of {@link AssigneeType }
106 */ 110 */
107 - public Comment createComment() 111 + public AssigneeType createAssigneeType()
108 { 112 {
109 - return new Comment(); 113 + return new AssigneeType();
110 } 114 }
111 115
112 /** 116 /**
113 - * Create an instance of {@link AssigneeList.Assignees } 117 + * Create an instance of {@link ErrorType }
114 */ 118 */
115 - public AssigneeList.Assignees createAssigneeListAssignees() 119 + public ErrorType createErrorType()
116 { 120 {
117 - return new AssigneeList.Assignees(); 121 + return new ErrorType();
118 } 122 }
119 123
120 /** 124 /**
121 - * Create an instance of {@link Enumeration } 125 + * Create an instance of {@link AssignedByType }
122 */ 126 */
123 - public Enumeration createEnumeration() 127 + public AssignedByType createAssignedByType()
124 { 128 {
125 - return new Enumeration(); 129 + return new AssignedByType();
126 } 130 }
127 131
128 /** 132 /**
129 - * Create an instance of {@link AssigneeList } 133 + * Create an instance of {@link EnumerationValue }
130 */ 134 */
131 - public AssigneeList createAssigneeList() 135 + public EnumerationValue createEnumerationValue()
132 { 136 {
133 - return new AssigneeList(); 137 + return new EnumerationValue();
  138 + }
  139 +
  140 + /**
  141 + * Create an instance of {@link AssigneeList.Assignees }
  142 + */
  143 + public AssigneeList.Assignees createAssigneeListAssignees()
  144 + {
  145 + return new AssigneeList.Assignees();
134 } 146 }
135 147
136 /** 148 /**
@@ -142,36 +154,36 @@ public class ObjectFactory { @@ -142,36 +154,36 @@ public class ObjectFactory {
142 } 154 }
143 155
144 /** 156 /**
145 - * Create an instance of {@link Field.Value } 157 + * Create an instance of {@link Comment }
146 */ 158 */
147 - public Field.Value createFieldValue() 159 + public Comment createComment()
148 { 160 {
149 - return new Field.Value(); 161 + return new Comment();
150 } 162 }
151 163
152 /** 164 /**
153 - * Create an instance of {@link AssignedByType } 165 + * Create an instance of {@link Comment.Value }
154 */ 166 */
155 - public AssignedByType createAssignedByType() 167 + public Comment.Value createCommentValue()
156 { 168 {
157 - return new AssignedByType(); 169 + return new Comment.Value();
158 } 170 }
159 171
160 /** 172 /**
161 - * Create an instance of {@link AssigneeType } 173 + * Create an instance of {@link Issue }
162 */ 174 */
163 - public AssigneeType createAssigneeType() 175 + public Issue createIssue()
164 { 176 {
165 - return new AssigneeType(); 177 + return new Issue();
166 } 178 }
167 179
168 /** 180 /**
169 - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} 181 + * Create an instance of {@link JAXBElement }{@code <}{@link ErrorType }{@code >}}
170 */ 182 */
171 @XmlElementDecl(namespace = "", name = "error") 183 @XmlElementDecl(namespace = "", name = "error")
172 - public JAXBElement<String> createError(String value) 184 + public JAXBElement<ErrorType> createError(ErrorType value)
173 { 185 {
174 - return new JAXBElement<String>(_Error_QNAME, String.class, null, value); 186 + return new JAXBElement<ErrorType>(_Error_QNAME, ErrorType.class, null, value);
175 } 187 }
176 188
177 /** 189 /**
@@ -218,4 +230,22 @@ public class ObjectFactory { @@ -218,4 +230,22 @@ public class ObjectFactory {
218 { 230 {
219 return new JAXBElement<Comment.Value>(_CommentValue_QNAME, Comment.Value.class, Comment.class, value); 231 return new JAXBElement<Comment.Value>(_CommentValue_QNAME, Comment.Value.class, Comment.class, value);
220 } 232 }
  233 +
  234 + /**
  235 + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}}
  236 + */
  237 + @XmlElementDecl(namespace = "", name = "field", scope = ErrorType.class)
  238 + public JAXBElement<String> createErrorTypeField(String value)
  239 + {
  240 + return new JAXBElement<String>(_ErrorTypeField_QNAME, String.class, ErrorType.class, value);
  241 + }
  242 +
  243 + /**
  244 + * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}}
  245 + */
  246 + @XmlElementDecl(namespace = "", name = "message", scope = ErrorType.class)
  247 + public JAXBElement<String> createErrorTypeMessage(String value)
  248 + {
  249 + return new JAXBElement<String>(_ErrorTypeMessage_QNAME, String.class, ErrorType.class, value);
  250 + }
221 } 251 }
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 2 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3 - <xs:element name="error" type="xs:string"/> 3 +
  4 + <xs:include schemaLocation="types.xsd"/>
  5 +
  6 + <xs:element name="error" type="errorType"/>
  7 +
4 </xs:schema> 8 </xs:schema>
@@ -30,6 +30,13 @@ @@ -30,6 +30,13 @@
30 </xs:simpleContent> 30 </xs:simpleContent>
31 </xs:complexType> 31 </xs:complexType>
32 32
  33 + <xs:complexType name="errorType" mixed="true">
  34 + <xs:sequence>
  35 + <xs:element type="xs:string" name="message" minOccurs="0"/>
  36 + <xs:element type="xs:string" name="field" minOccurs="0"/>
  37 + </xs:sequence>
  38 + </xs:complexType>
  39 +
33 <xs:complexType name="fieldType"> 40 <xs:complexType name="fieldType">
34 <xs:sequence id="value" maxOccurs="unbounded" minOccurs="0"> 41 <xs:sequence id="value" maxOccurs="unbounded" minOccurs="0">
35 <xs:element name="value"> 42 <xs:element name="value">
  1 +package pl.itcrowd.youtrack.api.rest;
  2 +
  3 +import org.junit.Test;
  4 +import pl.itcrowd.youtrack.api.YoutrackUnmarshaller;
  5 +import pl.itcrowd.youtrack.api.exceptions.YoutrackAPIException;
  6 +
  7 +import javax.xml.bind.JAXBException;
  8 +import java.io.IOException;
  9 +
  10 +import static junit.framework.Assert.assertEquals;
  11 +
  12 +public class YoutrackUnmarshallerTest {
  13 +
  14 + @Test
  15 + public void unmarshalEmptyError() throws JAXBException, IOException
  16 + {
  17 +// Given
  18 + final String extendedErrorResponse = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><error></error>";
  19 +
  20 +// When
  21 + final String errorText = YoutrackUnmarshaller.unmarshalError(extendedErrorResponse);
  22 +
  23 +// THen
  24 + assertEquals("", errorText);
  25 + }
  26 +
  27 + @Test
  28 + public void unmarshalError() throws JAXBException, IOException
  29 + {
  30 +// Given
  31 + final String extendedErrorResponse = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><error>Estimated completion time</error>";
  32 +
  33 +// When
  34 + final String errorText = YoutrackUnmarshaller.unmarshalError(extendedErrorResponse);
  35 +
  36 +// THen
  37 + assertEquals("Estimated completion time", errorText);
  38 + }
  39 +
  40 + @Test
  41 + public void unmarshalExtendedError() throws JAXBException, IOException
  42 + {
  43 +// Given
  44 + final String extendedErrorResponse = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><error><message>Estimate task before starting work on it</message><field>Estimated completion time</field></error>";
  45 +
  46 +// When
  47 + final String errorText = YoutrackUnmarshaller.unmarshalError(extendedErrorResponse);
  48 +
  49 +// Then
  50 + assertEquals("Estimate task before starting work on it", errorText);
  51 + }
  52 +
  53 + @Test
  54 + public void unmarshalExtendedErrorWithMessageOnly() throws JAXBException, IOException
  55 + {
  56 +// Given
  57 + final String extendedErrorResponse = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><error><message>Estimate task before starting work on it</message></error>";
  58 +
  59 +// When
  60 + final String errorText = YoutrackUnmarshaller.unmarshalError(extendedErrorResponse);
  61 +
  62 +// Then
  63 + assertEquals("Estimate task before starting work on it", errorText);
  64 + }
  65 +
  66 + @Test
  67 + public void unmarshalExtendedErrorWithEmptyMessage() throws JAXBException, IOException
  68 + {
  69 +// Given
  70 + final String extendedErrorResponse = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><error><message></message><field>Estimated completion time</field></error>";
  71 +
  72 +// When
  73 + final String errorText = YoutrackUnmarshaller.unmarshalError(extendedErrorResponse);
  74 +
  75 +// Then
  76 + assertEquals("", errorText);
  77 + }
  78 +
  79 + @Test(expected = YoutrackAPIException.class)
  80 + public void unmarshalExtendedErrorWithoutMessage() throws JAXBException, IOException
  81 + {
  82 +// Given
  83 + final String extendedErrorResponse = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><error><field>Estimated completion time</field></error>";
  84 +
  85 +// When
  86 + YoutrackUnmarshaller.unmarshalError(extendedErrorResponse);
  87 + }
  88 +}
Please register or login to post a comment