Added initial API endpoint to fetch basic user and associated team information.

This commit is contained in:
Luke Barratt 2014-03-29 00:59:26 +00:00
parent 28fb2cc64d
commit 8fd28245f2
14 changed files with 180 additions and 3 deletions

View file

@ -5,6 +5,7 @@ ruby '2.1.1'
gem 'dotenv-rails', '~> 0.10.0'
gem 'rails', '~> 3.2.17'
gem 'mysql2', '~> 0.3.15'
gem 'oj', '~> 2.5.5'
# Libraries
gem 'jquery-rails', '~> 2.0.2'

View file

@ -127,6 +127,7 @@ GEM
mini_portile (~> 0.5.0)
nokogiri (1.6.1-x86-mingw32)
mini_portile (~> 0.5.0)
oj (2.5.5)
poltergeist (1.5.0)
capybara (~> 2.1)
cliver (~> 0.3.1)
@ -267,6 +268,7 @@ DEPENDENCIES
mysql2 (~> 0.3.15)
newrelic_rpm (~> 3.7.2.195)
nokogiri (~> 1.6.1)
oj (~> 2.5.5)
poltergeist (~> 1.5.0)
pry-debugger (~> 0.2.2)
rails (~> 3.2.17)

View file

@ -0,0 +1,3 @@
class Api::V1::BaseController < ActionController::Base
respond_to :json
end

View file

@ -0,0 +1,5 @@
class Api::V1::UsersController < Api::V1::BaseController
def index
respond_with Api::V1::UsersCollection.as_json
end
end

View file

@ -0,0 +1,5 @@
class Api::V1::Collection
def execute_query
ActiveRecord::Base.connection.execute(arel_query.to_sql)
end
end

View file

@ -0,0 +1,58 @@
class Api::V1::UsersCollection < Api::V1::Collection
def self.as_json
self.new.data.to_json
end
def data
{ users: map_query }
end
private
def users_table
User.arel_table
end
def teams_table
Team.arel_table
end
def joins
[
users_table[:team_id].eq(teams_table[:id])
]
end
def columns
[
users_table[:username],
users_table[:steamid],
teams_table[:name],
teams_table[:tag],
teams_table[:logo]
]
end
def arel_query
users_table
.project(columns)
.join(teams_table, Arel::Nodes::OuterJoin)
.on(joins)
.where(users_table[:team_id].not_eq(nil))
.order(users_table[:id])
end
def map_query
execute_query.map do |row|
{
username: row[0],
steamid: row[1],
team: {
name: row[2],
tag: row[3],
logo: row[4]
}
}
end
end
end

View file

@ -10,7 +10,7 @@ module Ensl
# -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
config.autoload_paths += Dir["#{config.root}/app/services/**/"]
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins nowt explicitly named.

View file

@ -115,4 +115,10 @@ Ensl::Application.routes.draw do
match ':controller/:action/:id'
match ':controller/:action/:id.:format'
match ':controller/:action/:id/:id2'
namespace :api do
namespace :v1 do
resources :users
end
end
end

View file

@ -0,0 +1,36 @@
require 'spec_helper'
describe Api::V1::UsersController do
before do
request.accept = 'application/json'
end
describe '#index' do
before do
10.times { create(:user_with_team) }
end
it 'returns all users and associated teams' do
users = User.all
get :index
expect(response).to be_success
expect(json["users"].size).to eq(users.size)
end
it 'returns the excpected JSON keys' do
get :index
user_json = json["users"].first
nested_team_json = user_json["team"]
expect(user_json).to have_key("username")
expect(user_json).to have_key("steamid")
expect(user_json).to have_key("team")
expect(nested_team_json).to have_key("name")
expect(nested_team_json).to have_key("tag")
expect(nested_team_json).to have_key("logo")
end
end
end

14
spec/factories/team.rb Normal file
View file

@ -0,0 +1,14 @@
FactoryGirl.define do
sequence :name do |n|
"Team ##{n}"
end
factory :team do
name
irc "#team"
web "http://team.com"
tag "[TEAM]"
country "EU"
comment "We are a team"
end
end

View file

@ -7,13 +7,23 @@ FactoryGirl.define do
"player#{n}@ensl.org"
end
sequence :steamid do |n|
"0:1:#{n}"
end
factory :user do
username
email
steamid
firstname "ENSL"
lastname "Player"
steamid "0:1:23456789"
country "EU"
raw_password "PasswordABC123"
factory :user_with_team do
after(:create) do |user|
create(:team, founder: user)
end
end
end
end

View file

@ -0,0 +1,29 @@
describe Api::V1::UsersCollection do
let(:collection) { Api::V1::UsersCollection.new }
describe '#execute_query' do
describe 'when there are users with no teams' do
before do
3.times { create(:user) }
end
it 'returns 0 results' do
expect(collection.execute_query.size).to eq(0)
end
end
describe 'when there are some users with teams' do
before do
3.times { create(:user_with_team) }
end
it 'returns 3 results' do
expect(collection.execute_query.size).to eq(3)
end
it 'returns 5 columns' do
expect(collection.execute_query.first.size).to eq(5)
end
end
end
end

View file

@ -16,6 +16,7 @@ Capybara.javascript_driver = :poltergeist
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
config.include Controllers::JsonHelpers, :type => :controller
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true

View file

@ -0,0 +1,7 @@
module Controllers
module JsonHelpers
def json
@json ||= JSON.parse(response.body)
end
end
end