Geb Spock - Repeating the Entire Test Suite - spock
In combination with Geb and Spock, is there a way to iterate the entire test suite?
As an example, consider a test suite class - MyExampleTestSpec with two specs in it.
Class MyExampleTestSpec extends GebSpec {
def "testSpec1"(){
when:
then:
}
def "testSpec2"(){
given:
when:
then:
where:
}
}
A single Spec can be re-iterated using the "where" clause. But what is the option to re-iterate the entire suite?
Please let me know.
Thanks in advance!
So it really depends on what you are testing. There is no way to do a where on a class level by default. you could make an annotation to pull from a source and do a replace on values.
Something I have done is have a more generic test. Notice that parameters can be inserted into the BDD method comments. you could make these each a custom parameter. the only issue is that you would need to have the same number of elements each time.
#Unroll
def "Failed request to obtain Oath Token by #failure"(){
given: "a user is attempting to use the 'Obtain OAuth Token' endpoint"
when: "the Content-Type is set to #content_type"
request.setContentType(content_type)
and: "the Accept type is set to #accept"
request.addHeader("Accept", accept)
and: "the user sets the client_id as #clientId"
and: "the user set the client_secret as #clientSecret"
and: "the grant_type is set as #grantType"
and: "the request type is #requestType"
request.setPostBody(ApiRequestBody.oAuthBody(client_id:clientId,client_secret:clientSecret,grant_type:grantType))
response = request.postExecute()
then: "an appropriate status code (#status) is returned"
response.status == status
and: "the error response is '#error_message'"
response.data.errors[0].message == error_message
and: "the error code is #error_code"
response.data.errors[0].code == error_code
and: "the response type is #response_type"
response.contentType == response_type
where:
[failure, content_type, accept, clientId, clientSecret, grantType, requestType, status, error_message, error_code, response_type] <<
[
["wrong grant_type",ContentType.URLENC,ContentType.JSON,ID,SECRET,"${GRANT}_wrong","POST", ApiUtility.ERRORS.'113'.status, ApiUtility.ERRORS.'113'.message, ApiUtility.ERRORS.'113'.code, ContentType.JSON.toString()],
["wrong Client_Secret",ContentType.URLENC,ContentType.JSON,ID,"${SECRET}_Wrong",GRANT,"POST", ApiUtility.ERRORS.'112'.status, ApiUtility.ERRORS.'112'.message, ApiUtility.ERRORS.'112'.code, ContentType.JSON.toString()],
["wrong Client_ID",ContentType.URLENC,ContentType.JSON,"${ID}_Wrong",SECRET,GRANT,"POST", ApiUtility.ERRORS.'112'.status, ApiUtility.ERRORS.'112'.message, ApiUtility.ERRORS.'112'.code, ContentType.JSON.toString()],
["mismatch of ID and Secret",ContentType.URLENC,ContentType.JSON,ID,otherToken,GRANT,"POST", ApiUtility.ERRORS.'112'.status, ApiUtility.ERRORS.'112'.message, ApiUtility.ERRORS.'112'.code, ContentType.JSON.toString()],
["an empty body",ContentType.URLENC,ContentType.JSON,"","","","POST", ApiUtility.ERRORS.'114'.status, "Missing or invalid parameters client_id,client_secret,grant_type", ApiUtility.ERRORS.'114'.code, ContentType.JSON.toString()],
["an empty grant_type",ContentType.URLENC,ContentType.JSON,ID,SECRET,"","POST", ApiUtility.ERRORS.'114'.status, "Missing or invalid parameters grant_type", ApiUtility.ERRORS.'114'.code, ContentType.JSON.toString()],
["an empty Client_Secret",ContentType.URLENC,ContentType.JSON,ID,"",GRANT,"POST", ApiUtility.ERRORS.'114'.status, "Missing or invalid parameters client_secret", ApiUtility.ERRORS.'114'.code, ContentType.JSON.toString()],
["an empty Client_ID",ContentType.URLENC,ContentType.JSON,"",SECRET,GRANT,"POST", ApiUtility.ERRORS.'114'.status, "Missing or invalid parameters client_id", ApiUtility.ERRORS.'114'.code, ContentType.JSON.toString()],
["wrong Content_Type",ContentType.JSON,ContentType.JSON,ID,SECRET,GRANT,"POST", ApiUtility.ERRORS.'114'.status, "Missing or invalid parameters client_id,client_secret,grant_type", ApiUtility.ERRORS.'114'.code, ContentType.JSON.toString()]
]
}
Related
Google reCAPTCHA Enterprise Unknown field error when Create Assessment
I did follow their documentation on https://googleapis.dev/ruby/google-cloud-recaptcha_enterprise-v1/latest/index.html I first added the env variable RECAPTCHA_ENTERPRISE_CREDENTIALS then run the client = ::Google::Cloud::RecaptchaEnterprise::V1::RecaptchaEnterpriseService::Client.new documentation says response = client.create_assessment request but documentation didn't add sample request so I did assume that it will look like in this documentation https://cloud.google.com/recaptcha-enterprise/docs/create-assessment { "event": { "token": "token", "siteKey": "key" } } But when I execute the client.create_assessment it is giving me error ArgumentError: Unknown field name 'event' in initialization map entry. I also tried to follow this https://googleapis.dev/ruby/google-cloud-recaptcha_enterprise-v1/latest/Google/Cloud/RecaptchaEnterprise/V1/RecaptchaEnterpriseService/Client.html#create_assessment-instance_method where the parameters is request and also gives me error ArgumentError: Unknown field name 'request' in initialization map entry. What could be the correct parameter/request for creating assessment? Gem I used is google-cloud-recaptcha_enterprise-v1 and google-cloud-recaptcha_enterprise
So I solve this issue by using client.create_assessment(parent: "projects/{your project-id}", assessment: event) my event value was event = Google::Cloud::RecaptchaEnterprise::V1::Event.new(token: "token from execute", site_key: "your site key") It solves the error and answers the question (but another error after this one occurred about permission denied). I Will update once resolved.
Extracting hash key that may or may not be an array
I'm making an API call that returns XML (JSON also available) and the response body will show errors if any. There may be only one error or multiple errors. When the XML (or JSON) is parsed into a hash, the key that holds the errors will be an array when multiple errors are present but will be just a standard key when only one error is present. This makes parsing difficult as I can't seem to come up with one line of code that would fit both cases The call to the API returns this when one error <?xml version=\"1.0\" encoding=\"utf-8\"?><response><version>1.0</version><code>6</code><message>Data validation failed</message><errors><error><parameter>rptFilterValue1</parameter><message>Parameter is too small</message></error></errors></response> And this when multiple errors <?xml version=\"1.0\" encoding=\"utf-8\"?><response><version>1.0</version><code>6</code><message>Data validation failed</message><errors><error><parameter>rptFilterValue1</parameter><message>Parameter is too small</message></error><error><parameter>rptFilterValue2</parameter><message>Missing required parameter</message></error></errors></response> I use the following to convert the XML to a Hash Hash.from_xml(response.body).deep_symbolize_keys This returns the following hash. When there is only one error, the hash looks like this {:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}}}} When there are 2 errors, the hash looks like this {:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>[{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}, {:parameter=>"rptFilterValue2", :message=>"Missing required parameter"}]}}} When I first tested the API response, I had multiple errors so the way I went about getting the error message was like this data = Hash.from_xml(response.body).deep_symbolize_keys if data[:response].has_key?(:errors) errors = data[:response][:errors][:error].map{|x| "#{x.values[0]} #{x.values[1]}"} However when there is only one error, the code errors out with undefined method 'values' for parameter The only actual workaround I found was to test the class of the error key. When Array I use one method for extracting and when Hash I use another method. if data[:response][:errors][:error].class == Array errors = data[:response][:errors][:error].map{|x| "#{x.values[0]} #{x.values[1]}"} else errors = data[:response][:errors][:error].map{|x| "#{x[1]}"} end But I just hate hate hate it. There has to be a way to extract xml/json data from a key that may or may not be an array. The solution may be in the conversion from xml to hash rather than when parsing the actual hash. I couldn't find anything online. I'll appreciate any help or tip.
If you're using Rails, Array#wrap is available if you can do your .dig first: single = {:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}}}} Array.wrap(single.dig(:response, :errors, :error)) This returns an Array of size 1: [ { :message => "Parameter is too small", :parameter => "rptFilterValue1" } ] For multiples: multiple = {:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>[{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}, {:parameter=>"rptFilterValue2", :message=>"Missing required parameter"}]}}} Array.wrap(multiple.dig(:response, :errors, :error)) This returns an Array of size 2: [ { :message => "Parameter is too small", :parameter => "rptFilterValue1" }, { :message => "Missing required parameter", :parameter => "rptFilterValue2" } ]
You can parse XML with Nokogiri and xpath, which returns array even if selector points out single element errors = Nokogiri::XML(xml_response).xpath('//error') errors.map { |e| e.children.each_with_object({}) { |x, h| h[x.name] = x.content } } Your API response with single error gives => [{"parameter"=>"rptFilterValue1", "message"=>"Parameter is too small"}] and API result with multiple errors => [{"parameter"=>"rptFilterValue1", "message"=>"Parameter is too small"}, {"parameter"=>"rptFilterValue2", "message"=>"Missing required parameter"}] If there's no error elements you'll get an empty array.
how to test jwt sample? and what are userid?
My development Environment : eclipse java I would like test a requestJWTuserToken sample, but I'm getting an error. Test code: OAuth.OAuthToken oAuthToken = apiClient.requestJWTUserToken(IntegratorKey, userId, scopes, privateKeyBytes, 3600); Assert.assertNotSame(null, oAuthToken); apiClient.setAccessToken(oAuthToken.getAccessToken(), oAuthToken.getExpiresIn()); UserInfo userInfo = apiClient.getUserInfo(oAuthToken.getAccessToken()); Assert.assertNotSame(null, userInfo); Assert.assertNotNull(userInfo.getAccounts()); Assert.assertTrue(userInfo.getAccounts().size() > 0); Error message: com.docusign.esign.client.ApiException: Error while requesting an access token: class OAuthToken { accessToken: null tokenType: null refreshToken: null expiresIn: 0 at com.docusign.esign.client.ApiClient.requestJWTUserToken(ApiClient.java:719) at smartsuite.app.util.DocuSignUtil.settingAuthentication(DocuSignUtil.java:112) what are userid? I found a admin sendbox at user > API username enter image description here
This error is sometimes encountered when there is a problem with the RSA private key that you are using in your JWT request. Start by verifying how you are passing your key's private data into the request, if you are reading from a environment variable for example make sure the key's value is contained on a single line, otherwise it might be getting truncated. If your key spans multiple lines as an environment variable try doing a regular expression find/replace where you replace all newline \n characters with the string literal "\n" and then pass that through to see if it resolves your issue.
Ebay getOffer API token problems
I need help in understanding a problem of token when trying to get an offer's information using https://api.ebay.com/sell/inventory/v1/offer/OFFER_ID endpoint. I've got 2 types of tokens: User token and Access token. Documentation clearly gives me the explanation that I must use the USER TOKEN. I made it using Auth'n'Auth method, I agreed to give permission as a seller. Now I am trying to use this token like that: public void getOffer(#RequestBody Map<String, String> args) throws IOException { HttpClient client = HttpClientBuilder.create().build(); HttpGet httpGet = new HttpGet("https://api.ebay.com/sell/inventory/v1/offer/OFFER_ID"); httpGet.setHeader("Authorization", "Bearer " + args.get("token")); httpGet.setHeader("Content-Language", "en-US"); HttpResponse response = client.execute(httpGet); System.out.print(EntityUtils.toString(response.getEntity())); } It keeps returning me: { "errors" : [ { "errorId" : 1001, "domain" : "OAuth", "category" : "REQUEST", "message" : "Invalid access token", "longMessage" : "Invalid access token. Check the value of the Authorization HTTP request header." } ] } What can be wrong and what steps I missed? Thank you in advance
Well it's giving you the exact error that is occurring: "Invalid access token. Check the value of the Authorization HTTP request header." That means you have an issue with this line of code... httpGet.setHeader("Authorization", "Bearer " + args.get("token")); Something is wrong with the Authorization header, so either the token is wrong, the value isn't correct, or it's just not receiving it. Is the word "Bearer" supposed to be send with the header? And does the value of the args.get("token") contain the correct value? Another issue that happens a lot with REST services, sometimes you have to use an HTML entities function to encode the strings/ldata you are attaching to a web request. Because you have a space in the authorization, perhaps the space isn't interpreting correctly from eBay and you have to use HTML entities on the string. Something like this... httpGet.setHeader("Authorization", HttpUtility.HtmlEncode("Bearer " + args.get("token"));
I made it using Auth'n'Auth method There are two versions of an User Token. eBay provides an older style called "Auth 'n' Auth" and a newer OAuth version. The "Auth 'n' Auth" token does not work with the new RESTFul APIs. You need to generate an OAuth User Token following the process found in the documentation.
Bug in function message_route of mail.thread Openerp
Seems to me that one of the default behaviors (i.e. The 3rd attempt to get the message route: "Fallback to the provided parameters, if they work") of .message_route(...) is not working properly. It is supposed to parse the subject for an expression like [ID] to be used as 'thread_id' to post the message. So far, so good. The problem is that the message is being parsed (of course) in .message_parse(...) before getting to this point, which makes that, when getting the 'thread_id' this way, we end up with a unicode-string instead of the required #ID as integer or long. Am I right or am I missing something here? def message_route(self, cr, uid, message, model=None, thread_id=None, custom_values=None, context=None): [...] 3. Fallback to the ``model``, ``thread_id`` and ``custom_values`` provided. [...] # 3. Fallback to the provided parameters, if they work if not thread_id: # Legacy: fallback to matching [ID] in the Subject match = tools.res_re.search(decode_header(message, 'Subject')) thread_id = match and match.group(1) assert thread_id and hasattr(model_pool, 'message_update') or hasattr(model_pool, 'message_new'), \ "No possible route found for incoming message with Message-Id %s. " \ "Create an appropriate mail.alias or force the destination model." % message_id if thread_id and not model_pool.exists(cr, uid, thread_id): _logger.warning('Received mail reply to missing document %s! Ignoring and creating new document instead for Message-Id %s', thread_id, message_id) thread_id = None _logger.debug('Routing mail with Message-Id %s: fallback to model:%s, thread_id:%s, custom_values:%s, uid:%s', message_id, model, thread_id, custom_values, uid) return [(model, thread_id, custom_values, uid)]