From 6538446a55cb930b78227fe8128d356f313cac2b Mon Sep 17 00:00:00 2001 From: Prommah Date: Fri, 30 Oct 2015 01:37:44 +0000 Subject: [PATCH] Add team API --- app/controllers/api/v1/teams_controller.rb | 37 ++++++ app/services/api/v1/teams_collection.rb | 45 ++++++++ config/routes.rb | 105 +++++++++--------- .../api/v1/teams_controller_spec.rb | 78 +++++++++++++ spec/services/api/v1/teams_collection_spec.rb | 27 +++++ 5 files changed, 240 insertions(+), 52 deletions(-) create mode 100755 app/controllers/api/v1/teams_controller.rb create mode 100755 app/services/api/v1/teams_collection.rb mode change 100644 => 100755 config/routes.rb create mode 100755 spec/controllers/api/v1/teams_controller_spec.rb create mode 100755 spec/services/api/v1/teams_collection_spec.rb diff --git a/app/controllers/api/v1/teams_controller.rb b/app/controllers/api/v1/teams_controller.rb new file mode 100755 index 0000000..5a2a236 --- /dev/null +++ b/app/controllers/api/v1/teams_controller.rb @@ -0,0 +1,37 @@ +module Api + module V1 + class TeamsController < Api::V1::BaseController + def index + render json: Api::V1::TeamsCollection.as_json + end + + def show + team = Team.find(params[:id]) + + render json: { + id: team.id, + name: team.name, + tag: team.tag, + logo: team.logo.url, + roster: + Teamer + .joins(:user) + .select("users.id, users.username, users.team_id, users.steamid, teamers.rank") + .where(teamers: { team_id: team.id }) + .where("teamers.rank >= ?", Teamer::RANK_MEMBER) + .map do |user| + { + userid: user.id, + name: user.username, + steamid: user.steamid, + rank: user.rank, + primary: user.team_id == team.id + } + end + } + rescue ActiveRecord::RecordNotFound + raise ActionController::RoutingError.new("Team Not Found") + end + end + end +end diff --git a/app/services/api/v1/teams_collection.rb b/app/services/api/v1/teams_collection.rb new file mode 100755 index 0000000..66c1e48 --- /dev/null +++ b/app/services/api/v1/teams_collection.rb @@ -0,0 +1,45 @@ +module Api + module V1 + class TeamsCollection < Api::V1::Collection + def self.as_json + new.data.to_json + end + + def data + { teams: map_query } + end + + private + + def teams_table + Team.arel_table + end + + def columns + [ + teams_table[:id], + teams_table[:name], + teams_table[:tag], + teams_table[:logo], + ] + end + + def arel_query + teams_table + .project(columns) + .order(teams_table[:id]) + end + + def map_query + execute_query.map do |row| + { + id: row[0], + name: row[1], + tag: row[2], + logo: row[3] + } + end + end + end + end +end diff --git a/config/routes.rb b/config/routes.rb old mode 100644 new mode 100755 index 1442471..df9d101 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,4 @@ -Ensl::Application.routes.draw do +Ensl::Application.routes.draw do %w(403 404 422 500).each do |code| get code, to: 'errors#show', code: code end @@ -8,6 +8,7 @@ Ensl::Application.routes.draw do resources :users, only: [:show, :index] resources :servers, only: [:index] resources :maps, only: [:index] + resources :teams, only: [:show, :index] end end @@ -17,12 +18,12 @@ Ensl::Application.routes.draw do resources :versions end - match 'contests/del_map' - match 'contests/scores' - match 'contests/historical', to: "contests#historical" + match "contests/del_map" + match "contests/scores" + match "contests/historical", to: "contests#historical" resources :contests do - get 'current', on: :collection + get "current", on: :collection end resources :log_events @@ -30,7 +31,7 @@ Ensl::Application.routes.draw do resources :options resources :polls - match 'comments/quote' + match "comments/quote" resources :comments resources :shoutmsgs @@ -43,8 +44,8 @@ Ensl::Application.routes.draw do resources :forumers resources :topics - match 'forums/up' - match 'forums/down' + match "forums/up" + match "forums/down" resources :forums resources :users @@ -55,7 +56,7 @@ Ensl::Application.routes.draw do resources :servers resources :predictions resources :rounds - resources :matches do |m| + resources :matches do |_| get :admin, to: "matches#admin", on: :collection get :ref, to: "matches#ref" end @@ -73,66 +74,66 @@ Ensl::Application.routes.draw do resources :bans resources :tweets resources :issues - - match 'posts/quote' + + match "posts/quote" resources :posts resources :brackets - match 'about/action' - match 'about/staff' - match 'about/statistics' + match "about/action" + match "about/staff" + match "about/statistics" - match 'refresh', to: "application#refresh" - match 'search', to: "application#search" + match "refresh", to: "application#refresh" + match "search", to: "application#search" - match 'news', to: "articles#news_index" - match 'news/archive', to: "articles#news_archive" - match 'news/admin', to: "articles#admin" - match 'articles/cleanup' + match "news", to: "articles#news_index" + match "news/archive", to: "articles#news_archive" + match "news/admin", to: "articles#admin" + match "articles/cleanup" - match 'data_files/admin' - match 'data_files/addFile' - match 'data_files/delFile' - match 'data_files/trash' + match "data_files/admin" + match "data_files/addFile" + match "data_files/delFile" + match "data_files/trash" - match 'contesters/recalc' + match "contesters/recalc" - match 'directories', to: "directories#show", id: 1 + match "directories", to: "directories#show", id: 1 - match 'gathers/refresh' - match 'gathers/latest/:game', to: "gathers#latest", via: :get - match 'gather', to: "gathers#latest", game: "ns2", via: :get + match "gathers/refresh" + match "gathers/latest/:game", to: "gathers#latest", via: :get + match "gather", to: "gathers#latest", game: "ns2", via: :get - match 'gatherers/:id/status', to: "gatherers#status", via: :post + match "gatherers/:id/status", to: "gatherers#status", via: :post - match 'groups/addUser' - match 'groups/delUser' + match "groups/addUser" + match "groups/delUser" - match 'movies/download' - match 'movies/preview' - match 'movies/snapshot' + match "movies/download" + match "movies/preview" + match "movies/snapshot" - match 'plugin/user' + match "plugin/user" - match 'users/forgot' - match 'users/recover' - match 'users/agenda' - match 'users/logout' - match 'users/login' + match "users/forgot" + match "users/recover" + match "users/agenda" + match "users/logout" + match "users/login" - match 'users/agenda' - match 'users/login' - match 'users/logout' - match 'users/popup' - match 'users/forgot', to: "users#forgot" + match "users/agenda" + match "users/login" + match "users/logout" + match "users/popup" + match "users/forgot", to: "users#forgot" - match 'votes/create' + match "votes/create" - match ':controller/:action', requirements: { action: /A-Za-z/ } - match ':controller/:action/:id' - match ':controller/:action/:id.:format' - match ':controller/:action/:id/:id2' + match ":controller/:action", requirements: { action: /A-Za-z/ } + match ":controller/:action/:id" + match ":controller/:action/:id.:format" + match ":controller/:action/:id/:id2" - match 'teamers/replace', to: 'teamers#replace', as: 'teamers_replace' + match "teamers/replace", to: 'teamers#replace', as: "teamers_replace" end diff --git a/spec/controllers/api/v1/teams_controller_spec.rb b/spec/controllers/api/v1/teams_controller_spec.rb new file mode 100755 index 0000000..6756b48 --- /dev/null +++ b/spec/controllers/api/v1/teams_controller_spec.rb @@ -0,0 +1,78 @@ +require "spec_helper" + +describe Api::V1::TeamsController do + before do + request.accept = "application/json" + end + + describe "#show" do + before(:each) do + @user = create :user + @team = create(:team, founder: @user) + end + + def team_expectation(json, team) + expect(json["id"]).to eq(team.id) + expect(json["name"]).to eq(team.name) + expect(json["tag"]).to eq(team.tag) + expect(json["logo"]).to eq(team.logo.url) + end + + it "returns team data with empty roster" do + teamers = @user.teamers.of_team(@team).active + expect(teamers.length).to eq(1) + teamers[0].destroy + + get :show, id: @team.id + + expect(response).to be_success + team_expectation(json, @team) + expect(json["roster"]).to be_empty + end + + it "returns team data with a roster" do + get :show, id: @team.id + + expect(response).to be_success + team_expectation(json, @team) + expect(json["roster"].count).to eq(1) + + roster_user = json["roster"][0] + expect(roster_user["userid"]).to eq(@user.id) + expect(roster_user["name"]).to eq(@user.username) + expect(roster_user["steamid"]).to eq(@user.steamid) + expect(roster_user["rank"]).to eq(Teamer::RANK_LEADER) + expect(roster_user["primary"]).to eq(true) + end + + it "returns 404 if team does not exist" do + expect { get :show, id: -1 } + .to raise_error(ActionController::RoutingError) + end + end + + describe "#index" do + before do + 5.times { create(:user_with_team) } + end + + it "returns all teams" do + teams = Team.all + + get :index + + expect(response).to be_success + expect(json["teams"].size).to eq(teams.size) + end + + it "returns the excpected JSON keys" do + get :index + team_json = json["teams"].first + + expect(team_json).to have_key("id") + expect(team_json).to have_key("name") + expect(team_json).to have_key("tag") + expect(team_json).to have_key("logo") + end + end +end diff --git a/spec/services/api/v1/teams_collection_spec.rb b/spec/services/api/v1/teams_collection_spec.rb new file mode 100755 index 0000000..fd54cbe --- /dev/null +++ b/spec/services/api/v1/teams_collection_spec.rb @@ -0,0 +1,27 @@ +require "spec_helper" + +describe Api::V1::TeamsCollection do + let(:collection) { Api::V1::TeamsCollection.new } + + describe "#execute_query" do + describe "when there are no teams" do + it "returns 0 results" do + expect(collection.execute_query.size).to eq(0) + end + end + + describe "when there are some 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 4 columns" do + expect(collection.execute_query.first.size).to eq(4) + end + end + end +end