[RSpec] Make the response of the request to the Google API stubized by stub_request (: post) the same format as the actual one.

The title is long

Added a process to update an event on the calendar with the Google Calendar API from the Rails application, extract a specific attribute from the response, and handle it. Since the JSON received in the response is converted by google-api-ruby-client to the object of Google :: API :: V3 :: Event class, the response of the stub request is also converted by ruby-client or the same structure is used. I had to make it an object I had.

TL;DR

--If you make a request to Google API using google-api-ruby-client, the response will be returned in JSON format and then converted by google-api-ruby-client. --If you add 'X-Goog-Upload-Status':'final' to the header of the return value from stub_request, it will be in the same format as the response from the actual API.

Difference between stubized request and response when actually requesting API

The code below is requesting using google-api-ruby-client and trying to get the event ID from the response

request

service = Google::Apis::CalendarV3::CalendarService.new
service.authorization = access_token

response = service.update_event('primary', event_id, body)
event_id = response.id

At this time, response is as follows.

#<Google::Apis::CalendarV3::Event:0x000055c94da58f18
 @attachments=[],
 @attendees=[#<Google::Apis::CalendarV3::EventAttendee:xxxxxxxxxxxxxxxxxxx @email="[email protected]", @organizer=true, @self=true>],
 @created=Mon, 01 Jan 2020 00:00:00 +0000,
 @creator=#<Google::Apis::CalendarV3::Event::Creator:xxxxxxxxxxxxxxxxxxx @email="[email protected]", @self=true>,
 @description="",
 @end=#<Google::Apis::CalendarV3::EventDateTime:xxxxxxxxxxxxxxxxxxx>,
 @etag="xxxxxxxxxxxxxxxxxxx",
 @id="abcdefghijklmnopqrstu",
 @organizer=#<Google::Apis::CalendarV3::Event::Organizer:xxxxxxxxxxxxxxxxxxx @email="[email protected]">,
 @start=#<Google::Apis::CalendarV3::EventDateTime:xxxxxxxxxxxxxxxxxxx>,
 @updated=Mon, 01 Jan 2020 00:00:00 +0000>

Therefore, you can get the value from the response object with the getter method ʻid`.

On the other hand, in most cases, the API response will be defined in RSpec as follows:

let(:response) do
  {
    id: 'abcdefghijklmnopqrstu',
    start: { date_time: Time.zone.today },
    end: { date_time: Time.zone.today },
    html_link: 'https://www.google.com/calendar/event?eid=xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    i_cal_uid: '[email protected]',
    summary: 'event name',
    updated: Time.zone.today,

    ...

  }.to_json
end

In this case, in order to get the event ID, it is necessary to do something like JSON.parse (response) ['id'], and response.id becomes NoMethodError.

counter-measure

In order to return this JSON format response as an Event class object, it is necessary to add 'X-Goog-Upload-Status':'final' to the response header as shown below.

stub_request(
  :put, url
).to_return(
  status: 201,
  body: response,
  headers: {
    content_type: 'application/json',
    'X-Goog-Upload-Status': 'final'
  }
)

[Similar header information is added to the response] in the test spec of google-api-ruby-client [https://github.com/googleapis/google-api-ruby-client/blob/29f9544b1497358888cd93175e5579cab83fd247/spec/ google / apis / core / upload_spec.rb # L154).

It happened that my colleague found an article and an issue on GitHub and it was solved, but if not, I think I was addicted to it for 3 days.

Former story

Recommended Posts

[RSpec] Make the response of the request to the Google API stubized by stub_request (: post) the same format as the actual one.
The format of the message obtained by Slack API is subtly difficult to use
Play music by hitting the unofficial API of Google Play Music
Python beginners hit the unofficial API of Google Play Music to play music
Try to scrape as much as you can scrape the sample program of Google Spreadsheet API (v4) quick start