Skip to content

Commit

Permalink
Change the way how the client lazy initialisation works.
Browse files Browse the repository at this point in the history
  • Loading branch information
tszolar committed Mar 27, 2015
1 parent 5bbfa52 commit 0439b5b
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 30 deletions.
6 changes: 3 additions & 3 deletions lib/kosapi_client/api_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ class ApiClient
##
# Creates a new KOSapi client.
#
def initialize(http_client, base_url = DEFAULT_KOSAPI_BASE_URL)
@http_client = http_client
@base_url = base_url
def initialize(config)
http_adapter = OAuth2HttpAdapter.new(config.credentials, config.base_url)
@http_client = HTTPClient.new(http_adapter)
end

def create_builder(resource_name)
Expand Down
14 changes: 11 additions & 3 deletions lib/kosapi_client/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
module KOSapiClient
class Configuration
class Configuration < Struct.new(:client_id, :client_secret, :base_url)

attr_accessor :client_id, :client_secret
DEFAULT_OPTIONS = {
base_url: 'https://kosapi.fit.cvut.cz/api/3'
}

def initialize(options = {})
DEFAULT_OPTIONS.merge(options).each do |option, value|
self[option] = value
end
end

def credentials
if client_id && client_secret
{client_id: client_id, client_secret: client_secret}
else
raise 'No credentials set'
{}
end
end

Expand Down
33 changes: 17 additions & 16 deletions lib/kosapi_client/kosapi_client.rb
Original file line number Diff line number Diff line change
@@ -1,42 +1,43 @@
module KOSapiClient

DEFAULT_KOSAPI_BASE_URL = 'https://kosapi.fit.cvut.cz/api/3'

singleton_class.class_eval do

attr_reader :client

def new(credentials, base_url = DEFAULT_KOSAPI_BASE_URL)
http_adapter = OAuth2HttpAdapter.new(credentials, base_url)
http_client = HTTPClient.new(http_adapter)
ApiClient.new(http_client, base_url)
def new(options = {})
ApiClient.new(Configuration.new(options))
end

def configure
config = Configuration.new
reset
yield config
@client = new(config.credentials)
self
end

def client
@client ||= ApiClient.new(config)
end

# Calling this method clears stored ApiClient instance
# if configured previously.
def reset

This comment has been minimized.

Copy link
@jnv

jnv Mar 27, 2015

Contributor

Do you think this should be exposed as public API? It causes object to be in an invalid state. Maybe it would be better to not have this method at all and just rewrite config and @client directly in the configure method.

This comment has been minimized.

Copy link
@tszolar

tszolar Mar 27, 2015

Author Member

This does not leave object in an invalid state, because next time you request either KOSapiClient.client or config, a new instance will be created automatically. Only the config will be empty.

@config = nil
@client = nil
end

def method_missing(method, *args, &block)
if @client.nil?
raise "Client not configured. Either you forgot to call configure or you have typo in method name '#{method}'."
end
if @client.respond_to?(method)
@client.send(method, *args, &block)
if client.respond_to?(method)
client.send(method, *args, &block)
else
super
end
end

def respond_to_missing?(method_name, include_private = false)
@client.respond_to?(method_name, include_private)
client.respond_to?(method_name, include_private)
end

private
def config
@config ||= Configuration.new
end

end
Expand Down
2 changes: 2 additions & 0 deletions lib/kosapi_client/oauth2_http_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ class OAuth2HttpAdapter

def initialize(credentials, base_url, opts = {})
@base_url = base_url
@credentials = credentials
auth_url = opts[:auth_url] || DEFAULT_AUTH_URL
token_url = opts[:token_url] || DEFAULT_TOKEN_URL
MultiXml.parser = :ox # make sure to use Ox because of different namespace handling in other MultiXML parsers
@client = OAuth2::Client.new(credentials[:client_id], credentials[:client_secret], site: base_url, authorize_url: auth_url, token_url: token_url)
end

def send_request(verb, url, options = {})
raise 'No credentials set' if @credentials.empty?
token.request(verb, url, options)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/kosapi_client/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module KOSapiClient
VERSION = '0.3.0'
VERSION = '0.3.1'
end
2 changes: 1 addition & 1 deletion spec/kosapi_client/api_client_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'spec_helper'

describe KOSapiClient::ApiClient do
subject(:client) { KOSapiClient::ApiClient.new(double) }
subject(:client) { KOSapiClient::ApiClient.new(KOSapiClient::Configuration.new) }

This comment has been minimized.

Copy link
@jnv

jnv Mar 27, 2015

Contributor

Maybe ApiClient could initialize an empty configuration by itself?

This comment has been minimized.

Copy link
@tszolar

tszolar Mar 27, 2015

Author Member

Sounds like a good idea.


it 'responds to api resource methods' do
expect(client).to respond_to :course_events
Expand Down
4 changes: 2 additions & 2 deletions spec/kosapi_client/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
expect(configuration.credentials).to eq({client_id: 'foo', client_secret: 'bar'})
end

it 'throws error when no credentials set' do
expect { configuration.credentials }.to raise_error(RuntimeError)
it 'returns empty hash when no credentials set' do
expect(configuration.credentials).to eq({})
end

end
Expand Down
9 changes: 5 additions & 4 deletions spec/kosapi_client/kosapi_client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
describe KOSapiClient do

before do
@client = KOSapiClient.configure do |c|
KOSapiClient.configure do |c|
c.client_id = 'foo'
c.client_secret = 'bar'
end
@client = KOSapiClient.client
end

describe '.configure' do
Expand All @@ -21,7 +22,7 @@

it 'cleans stored ApiClient instance' do
KOSapiClient.reset
expect(KOSapiClient.client).to be_nil
expect(KOSapiClient.client).not_to be @client
end

end
Expand All @@ -43,9 +44,9 @@
expect { KOSapiClient.foo }.to raise_error NoMethodError
end

it 'throws error when calling client methods with no configured client' do
it 'throws error when sending request with no configured credentials' do
KOSapiClient.reset
expect { KOSapiClient.course_events }.to raise_error(RuntimeError)
expect { KOSapiClient.course_events.items }.to raise_error(RuntimeError)
end

it 'responds to client methods' do
Expand Down

0 comments on commit 0439b5b

Please sign in to comment.