Skip to content

Commit

Permalink
feat(gapic-common): Support numeric_enums in the ClientStub (#817)
Browse files Browse the repository at this point in the history
  • Loading branch information
dazuma authored Sep 14, 2022
1 parent fc0065a commit f097484
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 13 deletions.
32 changes: 19 additions & 13 deletions gapic-common/lib/gapic/rest/client_stub.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,17 @@ class ClientStub
# @param credentials [Google::Auth::Credentials]
# Credentials to send with calls in form of a googleauth credentials object.
# (see the [googleauth docs](https://googleapis.dev/ruby/googleauth/latest/index.html))
# @param numeric_enums [Boolean] Whether to signal the server to JSON-encode enums as ints
#
# @yield [Faraday::Connection]
#
def initialize endpoint:, credentials:
def initialize endpoint:, credentials:, numeric_enums: false
@endpoint = endpoint
@endpoint = "https://#{endpoint}" unless /^https?:/.match? endpoint
@endpoint = @endpoint.sub %r{/$}, ""

@credentials = credentials
@numeric_enums = numeric_enums

@connection = Faraday.new url: @endpoint do |conn|
conn.headers = { "Content-Type" => "application/json" }
Expand All @@ -58,8 +60,8 @@ def initialize endpoint:, credentials:
#
# @param uri [String] uri to send this request to
# @param params [Hash] query string parameters for the request
# @param options [::Gapic::CallOptions] gapic options to be applied to the REST call.
# Currently only timeout and headers are supported.
# @param options [::Gapic::CallOptions,Hash] gapic options to be applied
# to the REST call. Currently only timeout and headers are supported.
# @return [Faraday::Response]
def make_get_request uri:, params: {}, options: {}
make_http_request :get, uri: uri, body: nil, params: params, options: options
Expand All @@ -70,8 +72,8 @@ def make_get_request uri:, params: {}, options: {}
#
# @param uri [String] uri to send this request to
# @param params [Hash] query string parameters for the request
# @param options [::Gapic::CallOptions] gapic options to be applied to the REST call.
# Currently only timeout and headers are supported.
# @param options [::Gapic::CallOptions,Hash] gapic options to be applied
# to the REST call. Currently only timeout and headers are supported.
# @return [Faraday::Response]
def make_delete_request uri:, params: {}, options: {}
make_http_request :delete, uri: uri, body: nil, params: params, options: options
Expand All @@ -83,8 +85,8 @@ def make_delete_request uri:, params: {}, options: {}
# @param uri [String] uri to send this request to
# @param body [String] a body to send with the request, nil for requests without a body
# @param params [Hash] query string parameters for the request
# @param options [::Gapic::CallOptions] gapic options to be applied to the REST call.
# Currently only timeout and headers are supported.
# @param options [::Gapic::CallOptions,Hash] gapic options to be applied
# to the REST call. Currently only timeout and headers are supported.
# @return [Faraday::Response]
def make_patch_request uri:, body:, params: {}, options: {}
make_http_request :patch, uri: uri, body: body, params: params, options: options
Expand All @@ -96,8 +98,8 @@ def make_patch_request uri:, body:, params: {}, options: {}
# @param uri [String] uri to send this request to
# @param body [String] a body to send with the request, nil for requests without a body
# @param params [Hash] query string parameters for the request
# @param options [::Gapic::CallOptions] gapic options to be applied to the REST call.
# Currently only timeout and headers are supported.
# @param options [::Gapic::CallOptions,Hash] gapic options to be applied
# to the REST call. Currently only timeout and headers are supported.
# @return [Faraday::Response]
def make_post_request uri:, body: nil, params: {}, options: {}
make_http_request :post, uri: uri, body: body, params: params, options: options
Expand All @@ -109,8 +111,8 @@ def make_post_request uri:, body: nil, params: {}, options: {}
# @param uri [String] uri to send this request to
# @param body [String] a body to send with the request, nil for requests without a body
# @param params [Hash] query string parameters for the request
# @param options [::Gapic::CallOptions] gapic options to be applied to the REST call.
# Currently only timeout and headers are supported.
# @param options [::Gapic::CallOptions,Hash] gapic options to be applied
# to the REST call. Currently only timeout and headers are supported.
# @return [Faraday::Response]
def make_put_request uri:, body: nil, params: {}, options: {}
make_http_request :put, uri: uri, body: body, params: params, options: options
Expand All @@ -123,10 +125,14 @@ def make_put_request uri:, body: nil, params: {}, options: {}
# @param uri [String] uri to send this request to
# @param body [String, nil] a body to send with the request, nil for requests without a body
# @param params [Hash] query string parameters for the request
# @param options [::Gapic::CallOptions] gapic options to be applied to the REST call.
# Currently only timeout and headers are supported.
# @param options [::Gapic::CallOptions,Hash] gapic options to be applied
# to the REST call. Currently only timeout and headers are supported.
# @return [Faraday::Response]
def make_http_request verb, uri:, body:, params:, options:
if @numeric_enums && (!params.key?("$alt") || params["$alt"] == "json")
params = params.merge({ "$alt" => "json;enum-encoding=int" })
end
options = ::Gapic::CallOptions.new(**options.to_h) unless options.is_a? ::Gapic::CallOptions
@connection.send verb, uri do |req|
req.params = params if params.any?
req.body = body unless body.nil?
Expand Down
123 changes: 123 additions & 0 deletions gapic-common/test/gapic/rest/client_stub_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require "test_helper"
require "gapic/rest"

class ClientStubTest < Minitest::Test
ENDPOINT = "google.example.com"
CREDENTIALS = :dummy_credentials
STANDARD_HEADER = { "Content-Type" => "application/json" }

FakeOptions = ::Struct.new :timeout

FakeRequest = ::Struct.new :params, :body, :headers, :options do
def initialize
self.options = FakeOptions.new
self.headers = {}
end

def self.default
req = FakeRequest.new
req.headers = STANDARD_HEADER.dup
req
end
end

def make_client_stub numeric_enums: false
::Gapic::Rest::ClientStub.new endpoint: ENDPOINT,
credentials: CREDENTIALS,
numeric_enums: numeric_enums
end

def expect_connection client_stub, verb, uri, req
mock = ::Minitest::Mock.new
client_stub.instance_variable_set :@connection, mock
mock.expect verb, nil do |actual_uri, &block|
actual_req = FakeRequest.default
block.call actual_req
uri == actual_uri && req == actual_req
end
end

def test_make_get_request_simple
client_stub = make_client_stub
expected_req = FakeRequest.default
mock = expect_connection client_stub, :get, "/foo", expected_req
client_stub.make_get_request uri: "/foo"
mock.verify
end

def test_make_get_request_with_params
client_stub = make_client_stub
expected_req = FakeRequest.default
expected_req.params = {"Foo" => "bar"}
mock = expect_connection client_stub, :get, "/foo", expected_req
client_stub.make_get_request uri: "/foo", params: {"Foo" => "bar"}
mock.verify
end

def test_make_get_request_with_numeric_enums
client_stub = make_client_stub numeric_enums: true
expected_req = FakeRequest.default
expected_req.params = {"$alt" => "json;enum-encoding=int"}
mock = expect_connection client_stub, :get, "/foo", expected_req
client_stub.make_get_request uri: "/foo"
mock.verify
end

def test_make_get_request_with_numeric_enums_and_existing_alt_param
client_stub = make_client_stub numeric_enums: true
expected_req = FakeRequest.default
expected_req.params = {"Foo" => "bar", "$alt" => "json;enum-encoding=int"}
mock = expect_connection client_stub, :get, "/foo", expected_req
client_stub.make_get_request uri: "/foo", params: {"Foo" => "bar", "$alt" => "json"}
mock.verify
end

def test_make_delete_request_simple
client_stub = make_client_stub
expected_req = FakeRequest.default
mock = expect_connection client_stub, :delete, "/foo", expected_req
client_stub.make_delete_request uri: "/foo"
mock.verify
end

def test_make_patch_request_simple
client_stub = make_client_stub
expected_req = FakeRequest.default
expected_req.body = "hello"
mock = expect_connection client_stub, :patch, "/foo", expected_req
client_stub.make_patch_request uri: "/foo", body: "hello"
mock.verify
end

def test_make_post_request_simple
client_stub = make_client_stub
expected_req = FakeRequest.default
expected_req.body = "hello"
mock = expect_connection client_stub, :post, "/foo", expected_req
client_stub.make_post_request uri: "/foo", body: "hello"
mock.verify
end

def test_make_put_request_simple
client_stub = make_client_stub
expected_req = FakeRequest.default
expected_req.body = "hello"
mock = expect_connection client_stub, :put, "/foo", expected_req
client_stub.make_put_request uri: "/foo", body: "hello"
mock.verify
end
end

0 comments on commit f097484

Please sign in to comment.