Stub for google calendar API when using rspec in ROR3 - ruby-on-rails-3

The following is the method I am trying to use for getting the API to make the calls to Google calendar. I am not sure what the stub should return. Should I capture the normal response and use it as is or is there a reference with minimum set of parameters?
api = client.discovered_api('calendar', 'v3')
result = client.execute!(:api_method => api.calendar_list.list)

I can see that Omniauth provides it's own mock support and I can see that Google provides Python mock libraries, but I'm not aware of any direct Google support for mocking from Ruby.
That said, given your example, you would need test doubles for client and api. It's not clear where client is coming from, but assuming that's established as a double somehow, you'd have at a minimum:
api = double('api')
client.should_receive(:discovered_api).and_return(api)
api.stub_chain(:calendar_list, :list)
client.should_receive(:execute!).and_return(... whatever result you want ...)
If in addition you want to confirm that your code is passing the right parameters to the Google API, then you'd need to augment the above with message expectations and, in the case of the api stub_chain, a return value which would then have to feed into the message expectations for the execute! call.
I'm still not sure that answers your question, but if not, I'll look forward to reading any additional comments.

Related

REST API signature guidance

Seeking guidance on REST API Signature for an API.
To handle logistics, we want to support shipping label generation for courier packages.
Which of these would be a more RESTFul way to model these APIs.
Generate Label API : POST /package/{package-id}/label.
Regenerate Label API : POST /package/{package-id}/label/regenerate.
vs
Generate Label API : POST /package/{package-id}/label?operation=generate.
Regenerate Label API : POST /package/{package-id}/label?operation=regenerate.
Regenerate API ends up creating a new Label for the package, based on updated shipping dates, etc passed as part of request payload.
Just use:
POST /package/{package-id}/label
PUT/PATCH /package/{package-id}/label
https://restfulapi.net/http-methods/
If the /package/{package-id}/label is a 'label resource' that you're creating, then the appropriate method is probably PUT here.
But 'regenerating' is a bit hard to explain here. Could you just fetch the label over and over again by doing a GET request on /package/{package-id}/label.
If 'creating a label' or 'regenerating a label' doesn't have side-effects (such as a physical printer printing a label), then a GET might work best.
If 'creating a label' or 'regenerating a label' is not really returning a label but causing some external effect in a different system, then it feels better for this to be more like the RPC call you mentioned.
POST /package/{package-id}/label
Then my question is, why is there a difference between 'generating' and 'regenerating'. It sounds like you're just doing the same thing twice. Do you really need 2 endpoints? Can't the system figure out if a label was created before for the {package-id}?
If the system doesn't know the label is generated vs regenerated, and only the client can know I would be inclined to use the same endpoint and add some flag to the request body instead of having 2 different URLS.

API call inside a JavaScript function present in a feature file

I tried my best but could not find information on calling an API inside the Javascript function when dealing with automation in Karate. Now, I might get suggestions to call the API outside the function and then do operations inside the function. However, my use case is such that I have to call the API inside the function only. Is there a way to do this?
One approach is to create a Java file and then write the code in java. However, I specifically want to know if there is any way to call an API inside a JS function in a FEATURE FILE itself.
First, these kinds of "clever" tests are not recommended, please read this to understand why: https://stackoverflow.com/a/54126724/143475
If you still want to do this, read on.
First - most of the time, this kind of need can be achieved by doing a call to a second feature file:
* if (condition) karate.call('first.feature')
Finally, this is an experimental and un-documented feature in Karate, but there is a JS API to perform HTTP requests:
* eval
"""
var http = karate.http('https://httpbin.org');
http.path('anything');
var response = http.get().body;
karate.log('response:', response);
"""
It is a "fluent API" so you can do everything in one-line:
var body = karate.http('https://httpbin.org/get').get().body;
If you need details, read the source-code of the HttpRequestBuilder and Response classes in the Karate project.

How to define REST API with to Parameter

I am currently working on a REST API for a project. In the process I should search for events. I would like to make an endpoint for searching events in a period. That is, specify two parameters with from - to.
For the search you normally take a GET operation. My question is now it makes sense to specify two parameters in the path or should I rather fall back to a POST operation for something like that.
Example for the path /Events{From}{To}
Is this even feasible with multiple parameters?
If you are not making a change on the resource, you should use GET operation.
More detailed explanation:
If you were writing a plain old RPC API call, they could technically interchangeable as long as the processing server side were no different between both calls. However, in order for the call to be RESTful, calling the endpoint via the GET method should have a distinct functionality (which is to get resource(s)) from the POST method (which is to create new resources).
GET request with multiple parameters: /events?param1=value1&param2=value2
GET request with an array as parameter: /events?param=value1,value2,value3

Accessing the built request details in Karate

Just like how the response information can be accessed through response, responseHeaders etc, is there any way to access the request information? I noticed that request information is not available through variables. Are there are any workarounds to access this information?
I understand that we build the request ourselves in the test scenario using the Given, When steps, so it may sound redundant. The reason I'm looking for this is I would like to access the complete request details Karate would've built using our test definition. The idea is to make this information available to a java class which can be called through the Java Interop. More specifically, I'm trying to build a swagger request and response validator to be used from karate.
The workaround I am using is to explicitly create variables like apipath and apimethod and use them with path and method. This does the job, but still one has to ensure that these variables are explicitly set. It will be cleaner if whatever request Karate built is just accessible through a variable.
Please raise a feature request. We can look at making this available as karate.request or similar.

Properly testing an SDK that calls an API

I have an API that I've written and now I'm in the middle of writing an SDK for 3rd parties to more easily interact with my API.
When writing tests for my SDK, it's my understanding that it's best not to simply call all of the API endpoints because:
The tests in the API will be responsible for making sure that the API works.
If the SDK tests did directly call the API, my tests would be really slow.
As an example, let's say my API has this endpoint:
/account
In my API test suite I actually call this endpoint to verify that it returns the proper data.
What approach do I take to test this in my SDK? Should I be mocking a request to /account? What else would I need to do to give my SDK good coverage?
I've looked to other SDKs to see how they're handling this (Stripe, Algolia, AWS), but in some cases it does look like they're calling a sandbox version of the actual API.
(I'm currently working with PHPUnit, but I'll be writing SDKs in other languages as well.)
I ended up taking this approach:
I have both unit tests AND integration tests.
My integration tests call the actual API. I usually run this much less frequently — like before I push code to a remote. (Anyone who consumes my code will have to supply their own API credentials)
My unit tests — which I run very frequently — just make sure that the responses from my code are what I expect them to look like. I trust the 3rd party API is going to give me good data (and I still have the integration tests to back that up).
I've accomplished this by mocking Guzzle, using Reflection to replace the client instance in my SDK code, and then using Mock Handlers to mock the actual response I expect.
Here's an example:
/** #test */
public function it_retrieves_an_account()
{
$account = $this->mockClient()->retrieve();
$this->assertEquals(json_decode('{"id": "9876543210"}'), $account);
}
protected function mockClient()
{
$stream = Psr7\stream_for('{"id": "9876543210"}');
$mock = new MockHandler([new Response(
200,
['Content-Type' => 'application/json'],
Psr7\stream_for($stream)
)]);
$handler = HandlerStack::create($mock);
$mockClient = new Client(['handler' => $handler]);
$account = new SparklyAppsAccount(new SparklyApps('0123456789'));
$reflection = new \ReflectionClass($account);
$reflection_property = $reflection->getProperty('client');
$reflection_property->setAccessible(true);
$reflection_property->setValue($account, $mockClient);
return $account;
}
When writing tests for the SDK you assume that your api DOES work exactly like it should (and you write tests for your api to assure that).
So using some kind of sandbox or even a complete mock of your api is sufficient.
I would recommend to mock your API using something like wiremock and then write your unit tests around that mock API to make sure everything works as desired.
This way when your production app with break, you can at-least make sure (by running unit tests) that nothing broken in your application side but there can be problem with actual API (i.e response format being changed).