Skip to content

Commit

Permalink
Merge c46620a into 91331cb
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolaracco committed Feb 9, 2015
2 parents 91331cb + c46620a commit dd2cbb7
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 8 deletions.
5 changes: 5 additions & 0 deletions lib/lol/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ def static
@static_request ||= StaticRequest.new(api_key, region, cache_store)
end

# @return [LolStatusRequest]
def lol_status
@lol_status ||= LolStatusRequest.new(region, cache_store)
end

# Initializes a Lol::Client
# @param api_key [String]
# @param options [Hash]
Expand Down
57 changes: 57 additions & 0 deletions lib/lol/dynamic_model.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
require 'ostruct'
require 'active_support/core_ext/string/inflections'

# DynamicModel extends OpenStruct adding the following features:
# - nested generation ({a: {}}) results in DynamicModel(a: DynamicModel)
# - parsing of date/time when property name ends with _at or _date and the value is a number
class DynamicModel < OpenStruct
def initialize(hash={})
raise ArgumentError, 'An hash is required as parameter' unless hash.is_a? Hash
@table = {}
@hash_table = {}

hash.each do |k,v|
key = k.to_s.underscore
set_property key, v
new_ostruct_member(key)
end
end

def to_h
@hash_table
end

def as_json opts={}
@table.as_json
end

private

def date_key? key
key.match(/^(.+_)?(at|date)$/)
end

def set_property key, v
if date_key?(key) && v.is_a?(Fixnum)
@table[key.to_sym] = @hash_table[key.to_sym] = value_to_date v
else
@table[key.to_sym] = convert_object v
@hash_table[key.to_sym] = v
end
end

def value_to_date v
Time.at(v / 1000)
end

def convert_object obj
if obj.is_a? Hash
self.class.new obj
elsif obj.respond_to?(:map)
obj.map { |o| convert_object o }
else
obj
end
end

end
34 changes: 34 additions & 0 deletions lib/lol/lol_status_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Lol
class LolStatusRequest < Request

def self.api_version
"v1.0"
end

def initialize region = nil, cache_store = {}
super nil, region, cache_store
end

# Returns a list of each shard status
# This special call works against all regions
# @return [Array] an array of DynamicModel representing the response
def shards
perform_request(api_url('shards')).map do |shard_data|
DynamicModel.new shard_data
end
end

# Returns a detailed status of the current shard
# @return [DynamicModel]
def current_shard
shard_data = perform_request(api_url('shards', region))
DynamicModel.new shard_data
end

def api_url path, params = {}
"http://status.leagueoflegends.com/#{path}".tap do |url|
url << "/#{params}" unless params.empty?
end
end
end
end
39 changes: 39 additions & 0 deletions spec/fixtures/v1.0/get-lol-status-shard-by-region.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"region_tag": "eu",
"services": [
{
"incidents": [],
"status": "online",
"name": "Forums",
"slug": "forums"
},
{
"incidents": [],
"status": "online",
"name": "Game",
"slug": "game"
},
{
"incidents": [],
"status": "online",
"name": "Store",
"slug": "store"
},
{
"incidents": [],
"status": "online",
"name": "Website",
"slug": "web"
}
],
"locales": [
"en_GB",
"de_DE",
"es_ES",
"fr_FR",
"it_IT"
],
"name": "EU West",
"hostname": "prod.euw1.lol.riotgames.com",
"slug": "euw"
}
78 changes: 78 additions & 0 deletions spec/fixtures/v1.0/get-lol-status-shards.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
[
{
"region_tag": "na1",
"locales": ["en_US"],
"name": "North America",
"hostname": "prod.na1.lol.riotgames.com",
"slug": "na"
},
{
"region_tag": "eu",
"locales": [
"en_GB",
"de_DE",
"es_ES",
"fr_FR",
"it_IT"
],
"name": "EU West",
"hostname": "prod.euw1.lol.riotgames.com",
"slug": "euw"
},
{
"region_tag": "eun1",
"locales": [
"en_PL",
"pl_PL",
"el_GR",
"ro_RO",
"cs_CZ",
"hu_HU"
],
"name": "EU Nordic & East",
"hostname": "prod.eun1.lol.riotgames.com",
"slug": "eune"
},
{
"region_tag": "la1",
"locales": ["es_MX"],
"name": "Latin America North",
"hostname": "prod.la1.lol.riotgames.com",
"slug": "lan"
},
{
"region_tag": "la2",
"locales": ["es_AR"],
"name": "Latin America South",
"hostname": "prod.la2.lol.riotgames.com",
"slug": "las"
},
{
"region_tag": null,
"locales": ["pt_BR"],
"name": "Brazil",
"hostname": "prod.br.lol.riotgames.com",
"slug": "br"
},
{
"region_tag": null,
"locales": ["tr_TR"],
"name": "Turkey",
"hostname": "prod.tr.lol.riotgames.com",
"slug": "tr"
},
{
"region_tag": null,
"locales": ["ru_RU"],
"name": "Russia",
"hostname": "prod.ru.lol.riotgames.com",
"slug": "ru"
},
{
"region_tag": "oc1",
"locales": ["en_AU"],
"name": "Oceania",
"hostname": "prod.oc1.lol.riotgames.com",
"slug": "oce"
}
]
6 changes: 6 additions & 0 deletions spec/lol/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@
end
end

describe '#lol_status' do
it 'return an instance of LolStatusRequest' do
expect(subject.lol_status).to be_a(LolStatusRequest)
end
end

describe "#api_key" do
it "returns an api key" do
expect(subject.api_key).to eq("foo")
Expand Down
74 changes: 74 additions & 0 deletions spec/lol/dynamic_model_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
require 'spec_helper'
require 'lol/dynamic_model'

include Lol

describe DynamicModel do
shared_examples 'enables date parsing' do
let(:timestamp_value) { 1423243755000 }
subject { DynamicModel.new attribute => timestamp_value}
let(:attribute_value) { subject.send attribute }

it 'and casts the value to Time' do
expect(attribute_value).to be_a Time
end

it 'and divides the number by 1000' do
expect(attribute_value.to_i).to eq timestamp_value / 1000
end

it 'and ignores casting when the value is not an integer' do
subject = DynamicModel.new attribute => 'foo bar'
expect(subject.send attribute).not_to be_a Time
end
end

context 'when is not initialized with an hash' do
subject { DynamicModel.new 'not enumerable data' }

it 'raises an argument error' do
expect{ subject }.to raise_error ArgumentError, 'An hash is required as parameter'
end
end

context 'when initialized with hash' do
subject { DynamicModel.new key: 'value' }

it 'does not raise error' do
expect { subject }.not_to raise_error
end

it 'defines a method per each argument key' do
expect(subject).to respond_to(:key)
end
end

%w(date at).each do |attr_name|
context "when an hash key is called '#{attr_name}'" do
it_behaves_like 'enables date parsing' do
let(:attribute) { attr_name }
end
end

context "when an hash key ends with '_#{attr_name}'" do
it_behaves_like 'enables date parsing' do
let(:attribute) { "a2342_#{attr_name}"}
end
end
end

context "when an hash value is an array" do
it 'preserves the array' do
subject = DynamicModel.new foo: ['foo']
expect(subject.foo).to eq ['foo']
end

context 'and one or more array items are hashes' do
subject { DynamicModel.new foo: [{}] }

it 'casts each hash to another DynamicModel instance' do
expect(subject.foo.map(&:class).uniq).to eq [DynamicModel]
end
end
end
end
55 changes: 55 additions & 0 deletions spec/lol/lol_status_request_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
require "spec_helper"
require "lol"

include Lol

describe LolStatusRequest do
it 'inherits from Request' do
expect(LolStatusRequest.ancestors[1]).to eq(Request)
end

describe '#api_url' do
it 'returns full url for' do
expect(subject.api_url('shards')).to eq 'http://status.leagueoflegends.com/shards'
end

it 'returns full url with path' do
expect(subject.api_url('shards', 'something')).to eq 'http://status.leagueoflegends.com/shards/something'
end
end

describe "#shards" do
let(:response) { subject.shards }

before(:each) { stub_request(subject, 'lol-status-shards', 'shards') }

it 'returns an array' do
expect(response).to be_a(Array)
end

it 'returns an array of Shard' do
expect(response.map(&:class).uniq).to eq([DynamicModel])
end

it 'fetches shards from the API' do
fixture = load_fixture('lol-status-shards', LolStatusRequest.api_version)
expect(response.size).to eq(fixture.size)
end
end

describe '#current_shard' do
subject { LolStatusRequest.new 'euw'}
let(:response) { subject.current_shard }

before(:each) { stub_request(subject, 'lol-status-shard-by-region', 'shards', 'euw') }

it 'returns a Shard' do
expect(response).to be_a(DynamicModel)
end

it 'services returns an array of Services' do
expect(response.services.map(&:class).uniq).to eq([DynamicModel])
end
end

end
8 changes: 0 additions & 8 deletions spec/support/model_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,6 @@
expect(model.send(attribute).size).to eq 2
end

context 'if the value is not enumerable' do
it 'raises an error' do
expect {
subject_class.new({ attribute => 'asd' })
}.to raise_error NoMethodError
end
end

context 'if the value is enumerable' do
context 'and contains items as Hash' do
it 'parses the item' do
Expand Down

0 comments on commit dd2cbb7

Please sign in to comment.