I have one that may have already been answered. I apologize if it has been, I tried searching for awhile before asking, and didn't find anything specifically for this scenario:
Creating a user, and the API returns a "appStatus": "X"
if X is APPROVE or COMPLETE then the test should pass.
given()
.header(headers)
.body(json)
.when()
.post(url)
.then()
.contentType(ContentType.JSON)
.extract().response()
.then().assertThat()
.statusCode(200)
.and()
.assertThat().body("appStatus", equalTo("APPROVE"))
.log().all();
You can use oneOf(T... elements) in Hamcrest
.assertThat().body("appStatus", oneOf("APPROVE", "COMPLETE"));
Related
I'm running a OpcUaClient.historyRead operation which returns me a HistoryResult with a continuationPoint set. The OPC UA spec tells:
When a ContinuationPoint is returned, a Client wanting the next numValuesPerNode values should call HistoryRead again with the continuationPoint set.
When looking at ReadRawModifiedDetails I cannot find any parameter for continuationPoint.
How can I submit a request containing the continuationPoint to request the missing data from the server?
As I got support on the Milo mailing list I can answer my own question. The continuationPoint can be passed to OpcUaClient.historyRead by using the nodesToRead parameter:
new HistoryReadValueId(
new NodeId(5, "Counter1"),
null,
QualifiedName.NULL_VALUE,
continuationPoint
);
What would be a good way in REST Assured to ensure that a cookie is absent? I checked that there are many .cookie and .cookies methods, but none support checking the absence of a cookie.
I'm not finding anything OOTB, but this works:
assertThat(response.getCookie("foo"), is(nullValue()));
Would fetching all cookies, iterating over it and asserting over that the expected cookie is not present solve your problem? Am i missing something here?
You need to extract the response to access the cookies directly. Here's a (hopefully) real world example:
#Test
public void traceNotSupported() {
ExtractableResponse<Response> response =
given()
.cookie(SOME_COOKIE)
.header(SOME_HEADER, "some-value")
.when()
.request(Method.TRACE)
.then()
.contentType(not(equalTo("message/http")))
.statusCode(HttpStatus.METHOD_NOT_ALLOWED_405)
.extract();
assertFalse(response.headers().hasHeaderWithName(SOME_HEADER));
assertFalse(response.cookies().containsKey(SOME_COOKIE));
}
We have a graphql server not written in javascript, which we're trying to conform to the relay specification. startCursor and endCursor show up in a few examples but not in any official docs; based on my reading of https://github.com/facebook/relay/issues/372 those fields are basically deprecated, but they do show up in some code still. Do we have to implement them:
to be spec compliant?
to work with existing clients?
to be spec compliant?
As you point out, these fields don't appear in the spec, so they must not be required to conform to the spec. I conclude this because I think that's the only conclusion any serious authors of a spec should want you to draw from the absence of something from their spec.
to work with existing clients?
This, of course, is a different, more practical question :). The only client that I am aware of that uses the Connection spec is Relay, and Relay Modern requires these fields. Since these values are used by the PaginationContainer, the Relay Modern compiler requires them on any field marked with the #connection directive:
[END_CURSOR, HAS_NEXT_PAGE, HAS_PREV_PAGE, START_CURSOR].forEach(
fieldName => {
const pageInfoField = pageInfoType.getFields()[fieldName];
invariant(
pageInfoField &&
SchemaUtils.getNullableType(pageInfoField.type) instanceof
GraphQLScalarType,
'RelayConnectionTransform: Expected type `%s` to have an ' +
'%s field for which the type is an scalar in document `%s`.',
pageInfo.type,
fieldName,
definitionName,
);
}
);
I never remember which of endCursor and startCursor corresponds to which pagination direction. Since they are not documented in the spec, you can look to graphql-relay-js for this information:
startCursor: {
type: GraphQLString,
description: 'When paginating backwards, the cursor to continue.'
},
endCursor: {
type: GraphQLString,
description: 'When paginating forwards, the cursor to continue.'
},
No, they're not deprecated, and they do show up in the docs. What that issue says is that you don't have to implement them if you don't want to use them directly in your app, because Relay is going to query the cursor for each edge in a connection automatically, and will use that when making requests during pagination.
I am trying to do a simple Salesforce-Asana integration. I have many functions working, but I am having trouble with adding a tag to a workspace. Since I can't find documentation on the addTag method, I'm sort of guessing at what is required.
If I post the following JSON to https://app.asana.com/api/1.0/workspaces/WORKSPACEID/tasks:
{"data":{"name":"MyTagName","notes":"Test Notes"}}
The tag gets created in Asana, but with blank notes and name fields. If I try to get a bit more fancy and post:
{"data":{"name":"MyTagName","notes":"Test Notes","followers":[{"id":"MY_USER_ID"}]}}
I receive:
{"errors":[{"message":"Invalid field: {\"data\":{\"name\":\"MyTagName\",\"notes\":\"Test Notes\",\"followers\":[{\"id\":\"MY_USER_ID\"}]}}"}]}
I'm thinking the backslashes may mean that my request is being modified by the post, though debug output shows a properly formatted json string before the post.
Sample Code:
JSONGenerator jsongen = JSON.createGenerator(false);
jsongen.writeStartObject();
jsongen.writeFieldName('data');
jsongen.writeStartObject();
jsongen.writeStringField('name', 'MyTagName');
jsongen.writeStringField('notes', 'Test Notes');
jsongen.writeFieldName('followers');
jsongen.writeStartArray();
jsongen.writeStartObject();
jsongen.writeStringField('id', 'MY_USER_ID');
jsongen.writeEndObject();
jsongen.writeEndArray();
jsongen.writeEndObject();
jsongen.writeEndObject();
String requestbody = jsongen.getAsString();
HttpRequest req = new HttpRequest();
req.setEndpoint('https://app.asana.com/api/1.0/workspaces/WORKSPACEID/tags');
req.setMethod('POST');
//===Auth header created here - working fine===
req.setBody(requestbody);
Http http = new Http();
HTTPResponse res = http.send(req);
return res.getBody();
Any help appreciated. I am inexperienced using JSON as well as the Asana API.
The problem was that I was posting to the wrong endpoint. Instead of workspaces/workspaceid/tags, I should have been using /tags and including workspaceid in the body of the request.
Aha, so you can add tags and even set followers despite the API not mentioning that you can or claiming that followers are read-only.
So to sum up for anyone else interested: POSTing to the endpoint https://app.asana.com/api/1.0/tags you can create a tag like this:
{ "data" : { "workspace": 1234567, "name" : "newtagname", "followers": [45678, 6789] } }
where 1234567 is your workspace ID and 45678 and 6789 are your new followers.
Since you posted this question, Asana's API and developer has introduced Tags. You documentation lays out the answer to your question pretty clearly:
https://asana.com/developers/api-reference/tags
I'm a bit confused by your question. Your ask "how to add a tag" but the first half of your question talks about adding a task. The problem with what you describe there is that you are trying to set a task's followers but the followers field is currently read-only according to Asana's API documentation. That is why you are getting an error. You can not set followers with the API right now.
The second part of your question - with the sample code - does look like you are trying to add a tag. However, right now the Asana API does not support this (at least according to the API documentation). You can update an existing tag but you can't add one.
So, to sum up: at this time the API does not allow you to add followers to a task or to create new tags.
EDIT:
I came across a confirmation of what I suspected: Using the twitter search API with JSONP causes the problem in isolation, so it seems that something is going wrong with Twitter.
See:
http://search.twitter.com/search.json?q=%23jimromeisburning&callback=dog
About 3/5 times, as of 3:44PM CT on 14 June, Twitter returns garbage. The rest of the time, it returns a valid javascript function call.
I'm using Sencha Touch to make a JSONP request to the Twitter search API, and about 1/100 times, I'm getting a javascript error that kills further polling:
Uncaught SyntaxError: Unexpected token ILLEGAL
So far I've tried the following with no leads:
Wrapping the call to Ext.util.JSONP.request({}) in a try/catch block. Doesn't catch the error (presumably because it's being called from a script tag in an iframe)
Dumping the query parameter passed into JSONP.request to make sure that it's valid. It is.
Looking for a pattern-- it seems to happen at unexpected times. Could be the very first request, or it could be 100 requests down the line.
My best guess is that Twitter is sending back garbage some of the time. That's ok, I just need a way to handle that error. Unfortunately, as far as I can tell, Sencha Touch doesn't have any built-in error handling for its JSONP requests.
Have you seen anything like this before? Do you have any ideas?
Thanks!
Here's what the ornery JSONP script response looks like:
Ext.util.JSONP.callback(�Řo�6ǿ
�`)֥��k�em��+�`�
-�-��RT��w�ɖ���$v�-A^ґ���Ow�|�4Tua*+����ת����Ⱥ��VbšҐ�֡5Ҫ/
芒�[�o�ƌ��NnjE9褪���*��N3�1j;QRǏ®T��E�r4��S
�#��w|��!a.���ġ�%�����#��*����>Z8^_h��녾z>u]�E��ϸ�V��u�k&##k
)Hc}=���;o%�.
����L��5�T�B*�?������{���꒼z�M���.}/dm�=���곒5i�KA��y����Q�n���n����
Һ�x��̼R�N���q�k��<�\+s�*���&[��DCњH�WE�Ƴ���uhj�ڼ����ȋ��,t"�>�'����o�VnK��ⳍ�\�p,'9�
��:~{��"���8n�
�x�ͫK���C�mx(�<�
����3>������B]A_�L�+=�%fY�*1��/���wO�vc�Z8d=)̦1����߳35����-F����.f���D|�.z6����Xs��s\愶 ���M*Z�D�� �7ڈ�)ϗ cA�^9N�n�aN#�w�/^
P��¸-�E�$R�����<�K�n�3A3���L+�mI��vՃ�0Ǎ}o���Q��4�����=e��n�q8��ģ�����.�C)s=�:+>�O�h9�C2Q5Y���PA����*�3y1�t�`���g��WǠ�YB�O�/�{+.�[����,ߴ��/�yQ�<t(���|ߥ�G����ݾ�b��ijBS�9��.E�>�D%�I���jz�켻0�q��0`Q��.��.�>88�춖��(i4fȻgW#�aI*�������#���z�j�\5g��\�n���e���c��7�o��w�z�,�|/��+�N�����}�z+v����nd�
NY�R��o�� }��hĚ�;��g�D2��9�����:-e�����^#Ua���j2C��#�U���k�9���I�'�ܐ���/H3�q(��d�<�$����q~͛5��}��V�ft�'U'{���0�����Ø��sC?|B��0I���B�E] %�c��S���6LC�x�Y�EQT�*�Akr��÷OyOn��N�7iSkW` �F�q�!�����+,[���I��1
�i�3C*����_��h�K �� ^�{�V|YìM�7ŬW�t��'��ek��y�lr�l�WM)Đ�>�O���F,`�w��r��6�a�X����B�n�2t�O\�R7��O�n���!`�#
M� i���MU]5_�k�TMR�� 'Z��Y��C�Sn�q.�V��";d�`x��k Β��Mr��/�����٬A��Fq�B|L���>+,B0��R��K�����˵u�_~縫}��Zw����E���7�K����:.�i�n%��4l�/F���������5_�����);
I recently answered a similar question in which the OP was encountering fail whales while using the search API.
I found this question which had some interesting answers regarding error handling in JSONP. To summarize, one approach is to wrap all errors returned by the server in JSON, and another provides a link to jQuery-JSONP, a nice looking reinterpretation of jQuery's JSONP implementation.
Interesting. You would need to override the callback method in the Ext.util.JSONP class, and wrap the line which calls the callback, in a try/catch block. Then in the catch block try and call an errorCallback (which you need to define in your actual JSONP request).
Ext.util.JSONP.callback = function(json) {
try {
this.current.callback.call(this.current.scope, json);
} catch(e) {
this.current.errorCallback.call(this.current.scope);
}
document.getElementsByTagName('head')[0].removeChild(this.current.script);
this.next();
};