<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Andrey Krivko</title>
    <description>The latest articles on Forem by Andrey Krivko (@jastkand).</description>
    <link>https://forem.com/jastkand</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F92150%2Fa6191a33-e57b-4eaa-a26d-4fbf1f12b709.jpg</url>
      <title>Forem: Andrey Krivko</title>
      <link>https://forem.com/jastkand</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jastkand"/>
    <language>en</language>
    <item>
      <title>Use webmock for stubbing multiple body parameters with the same name</title>
      <dc:creator>Andrey Krivko</dc:creator>
      <pubDate>Tue, 05 Feb 2019 07:24:00 +0000</pubDate>
      <link>https://forem.com/jastkand/use-webmock-for-stubbing-multiple-body-parameters-with-the-same-name-45c3</link>
      <guid>https://forem.com/jastkand/use-webmock-for-stubbing-multiple-body-parameters-with-the-same-name-45c3</guid>
      <description>&lt;p&gt;If you use Faraday to perform requests it's likely you'll have to use the &lt;code&gt;Faraday::FlatParamsEncoder&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Faraday&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;url: &lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;faraday&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;faraday&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt; &lt;span class="ss"&gt;:url_encoded&lt;/span&gt; &lt;span class="c1"&gt;# form-encode POST params&lt;/span&gt;
  &lt;span class="n"&gt;faraday&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;params_encoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Faraday&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FlatParamsEncoder&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It converts the JSON parameters to query string removing square brackets, so instead of converting &lt;code&gt;{ key: ['value1', 'value2'] }&lt;/code&gt; to &lt;code&gt;key[]=value1&amp;amp;key[]=value2&lt;/code&gt; it will convert it to &lt;code&gt;key=value1&amp;amp;key=value2&lt;/code&gt; instead. This approach is used in many services, for example, in Twilio API.&lt;/p&gt;

&lt;p&gt;The problem happens when you try to stub that API using &lt;code&gt;webmock&lt;/code&gt;. By default &lt;code&gt;webmock&lt;/code&gt; does not support multiple parameters with the same name in url encoded body. So the &lt;code&gt;key=value1&amp;amp;key=value2&lt;/code&gt; will become &lt;code&gt;key=value1&lt;/code&gt;. Here are the related issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/bblimke/webmock/issues/227"&gt;https://github.com/bblimke/webmock/issues/227&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bblimke/webmock/issues/490"&gt;https://github.com/bblimke/webmock/issues/490&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bblimke/webmock/issues/584"&gt;https://github.com/bblimke/webmock/issues/584&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The basic suggestion in the webmock repo is to use: &lt;code&gt;WebMock::Config.instance.query_values_notation = :flat_array&lt;/code&gt; option. I prefered the different approach though.&lt;/p&gt;

&lt;p&gt;As Faraday encodes the body with &lt;code&gt;Faraday::FlatParamsEncoder&lt;/code&gt; we can manually encode the body and pass the result to webmock.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;stub_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;twilio_api_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Accounts/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;subaccount_sid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/Calls.json"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;body: &lt;/span&gt;&lt;span class="no"&gt;Faraday&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FlatParamsEncoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request_params&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;body: &lt;/span&gt;&lt;span class="n"&gt;response_body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The following code block also works, but for consistency with the faraday behavior, I used the above one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;stub_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;twilio_api_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Accounts/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;subaccount_sid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/Calls.json"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;body: &lt;/span&gt;&lt;span class="no"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode_www_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request_params&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;body: &lt;/span&gt;&lt;span class="n"&gt;response_body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I hope this will help someone or at least save some time.&lt;/p&gt;

</description>
      <category>faraday</category>
      <category>webmock</category>
      <category>queryvaluesnotation</category>
      <category>flatparamsencoder</category>
    </item>
    <item>
      <title>How to stub an Upload request to Google API using webmock</title>
      <dc:creator>Andrey Krivko</dc:creator>
      <pubDate>Tue, 25 Dec 2018 10:15:37 +0000</pubDate>
      <link>https://forem.com/jastkand/how-to-stub-an-upload-request-to-google-api-using-webmock-32oo</link>
      <guid>https://forem.com/jastkand/how-to-stub-an-upload-request-to-google-api-using-webmock-32oo</guid>
      <description>&lt;p&gt;The &lt;code&gt;google-api-client&lt;/code&gt; gem doesn’t return any response for an upload request when the &lt;code&gt;X-Goog-Upload-Status&lt;/code&gt; is not set to &lt;code&gt;'final'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When you want to stub an API request you usually write code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;stub_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'https://www.googleapis.com/upload/gmail/v1/users/me/messages/send'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;headers: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;'X-Goog-Upload-Header-Content-Type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'message/rfc822'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;body: &lt;/span&gt;&lt;span class="n"&gt;upload_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="ss"&gt;headers: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="ss"&gt;content_type: &lt;/span&gt;&lt;span class="s1"&gt;'application/json'&lt;/span&gt;
             &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But it does not work for Google Upload API request – it will return &lt;code&gt;nil&lt;/code&gt; as a response. In order to fix this, you should add the &lt;code&gt;'X-Goog-Upload-Status': 'final'&lt;/code&gt; to response headers. So the code will look this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;stub_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'https://www.googleapis.com/upload/gmail/v1/users/me/messages/send'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;headers: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;'X-Goog-Upload-Header-Content-Type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'message/rfc822'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;body: &lt;/span&gt;&lt;span class="n"&gt;upload_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="ss"&gt;headers: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="ss"&gt;content_type: &lt;/span&gt;&lt;span class="s1"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="s1"&gt;'X-Goog-Upload-Status'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'final'&lt;/span&gt;
             &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>webmock</category>
      <category>rspec</category>
      <category>googleapiclient</category>
    </item>
  </channel>
</rss>
