implement accounts api

This commit is contained in:
Konstantin Haase 2015-04-13 13:12:18 +02:00
parent 0511223ca5
commit 5efdcc24c8
10 changed files with 175 additions and 20 deletions

View File

@ -50,7 +50,7 @@ GIT
GIT
remote: git://github.com/travis-ci/travis-core.git
revision: ba10e214824632f15598555a2634ce3347d2f227
revision: 4834399048b8c9cff4882d435f770826930665f6
specs:
travis-core (0.0.1)
actionmailer (~> 3.2.19)
@ -81,7 +81,7 @@ GIT
GIT
remote: git://github.com/travis-ci/travis-support.git
revision: 4fdd220ed7b06a12951e5d74a763c05a80eb0d20
revision: e7f81093f83bd029cca6508739c5720e57e3d571
specs:
travis-support (0.0.1)

View File

@ -0,0 +1,20 @@
module Travis::API::V3
class Queries::Account < Query
def find
find!(:organization) || find!(:user)
end
private
def query(type, main_type: self.main_type, params: self.params)
main_type = type if main_type == :account
params = params.merge("#{type}.login" => params["account.login".freeze]) if params["account.login".freeze]
Queries[type].new(params, main_type)
end
def find!(type)
query(type).find
rescue WrongParams => e
end
end
end

View File

@ -1,10 +1,11 @@
module Travis::API::V3
class Queries::Organization < Query
params :id
params :id, :login
def find
return Models::Organization.find_by_id(id) if id
raise WrongParams, 'missing organization.id'.freeze
return Models::Organization.find_by_id(id) if id
return Models::Organization.find_by_login(login) if login
raise WrongParams, 'missing organization.id or organization.login'.freeze
end
end
end

View File

@ -1,10 +1,11 @@
module Travis::API::V3
class Queries::User < Query
params :id
params :id, :login
def find
return Models::User.find_by_id(id) if id
raise WrongParams, 'missing user.id'.freeze
return Models::User.find_by_id(id) if id
return Models::User.find_by_login(login) if login
raise WrongParams, 'missing user.id or user.login'.freeze
end
end
end

View File

@ -3,6 +3,11 @@ module Travis::API::V3
require 'travis/api/v3/routes/dsl'
extend DSL
resource :account do
route '/account/({account.login}|{user.login}|{organization.login})'
get :find
end
resource :repository do
route '/repo/{repository.id}'
get :find

View File

@ -16,15 +16,15 @@ module Travis::API::V3
@github = {}
end
def query(type = self.class.result_type)
@queries[type] ||= Queries[type].new(params, self.class.result_type)
def query(type = result_type)
@queries[type] ||= Queries[type].new(params, result_type)
end
def github(user = nil)
@github[user] ||= GitHub.new(user)
end
def find(type = self.class.result_type, *args)
def find(type = result_type, *args)
not_found(true, type) unless object = query(type).find(*args)
not_found(false, type) unless access_control.visible? object
object
@ -33,16 +33,20 @@ module Travis::API::V3
def not_found(actually_not_found = false, type = nil)
type, actually_not_found = actually_not_found, false if actually_not_found.is_a? Symbol
error = actually_not_found ? EntityMissing : NotFound
raise(error, type || self.class.result_type)
raise(error, type || result_type)
end
def run!
not_implemented
end
def result_type
self.class.result_type
end
def run
not_found unless result = run!
result = Result.new(self.class.result_type, result) unless result.is_a? Result
result = Result.new(result_type, result) unless result.is_a? Result
result
end
@ -53,7 +57,7 @@ module Travis::API::V3
end
def accepted(**payload)
payload[:resource_type] ||= self.class.result_type
payload[:resource_type] ||= result_type
Result.new(:accepted, payload, status: 202)
end

View File

@ -2,6 +2,7 @@ module Travis::API::V3
module Services
extend ConstantResolver
Account = Module.new { extend Services }
Branch = Module.new { extend Services }
Build = Module.new { extend Services }
Organization = Module.new { extend Services }

View File

@ -0,0 +1,20 @@
module Travis::API::V3
class Services::Account::Find < Service
def result_type
@result_type ||= super
end
def run!
account = find
@result_type = type_for(account)
account
end
def type_for(account)
case account
when Models::User then :user
when Models::Organization then :organization
end
end
end
end

View File

@ -86,6 +86,19 @@ describe Travis::API::V3::ServiceIndex do
"request_method"=>"GET",
"uri_template"=>"#{path}org/{organization.id}"}]},
"attributes"=>["id", "login", "name", "github_id"]},
"account"=>
{"@type"=>"resource",
"actions"=>
{"find"=>
[{"@type"=>"template",
"request_method"=>"GET",
"uri_template"=>"#{path}account/{account.login}"},
{"@type"=>"template",
"request_method"=>"GET",
"uri_template"=>"#{path}account/{user.login}"},
{"@type"=>"template",
"request_method"=>"GET",
"uri_template"=>"#{path}account/{organization.login}"}]}},
"organizations"=>
{"@type"=>"resource",
"actions"=>
@ -108,22 +121,27 @@ describe Travis::API::V3::ServiceIndex do
"attributes"=>["id", "login", "name", "github_id", "is_syncing", "synced_at"]}}
}
shared_examples 'service index' do
describe :resources do
specify { expect(json['resources']).to include(expected_resources) }
specify { expect(json['resources'].keys.sort) .to be == expected_resources.keys.sort }
end
specify { expect(json['@href']).to be == path }
end
describe 'with /v3 prefix' do
let(:path) { '/v3/' }
specify(:resources) { expect(json['resources']) .to be == expected_resources }
specify(:@href) { expect(json['@href']) .to be == '/v3/' }
it_behaves_like 'service index'
end
describe 'with Accept header' do
let(:headers) { { 'HTTP_ACCEPT' => 'application/vnd.travis-ci.3+json' } }
specify(:resources) { expect(json['resources']) .to be == expected_resources }
specify(:@href) { expect(json['@href']) .to be == '/' }
it_behaves_like 'service index'
end
describe 'with Travis-API-Version header' do
let(:headers) { { 'HTTP_TRAVIS_API_VERSION' => '3' } }
specify(:resources) { expect(json['resources']) .to be == expected_resources }
specify(:@href) { expect(json['@href']) .to be == '/' }
it_behaves_like 'service index'
end
end

View File

@ -0,0 +1,85 @@
require 'spec_helper'
describe Travis::API::V3::Services::Account::Find do
describe "organization" do
let(:org) { Organization.new(login: 'example-org') }
before { org.save! }
after { org.delete }
describe 'existing org, public api' do
before { get("/v3/account/example-org") }
example { expect(last_response).to be_ok }
example { expect(JSON.load(body)).to be == {
"@type" => "organization",
"@href" => "/v3/org/#{org.id}",
"id" => org.id,
"login" => "example-org",
"name" => nil,
"github_id" => nil
}}
end
describe "does not allow overriding org id" do
let(:other) { Organization.new(login: 'other-org') }
before { other.save! }
after { other.delete }
before { get("/v3/account/example-org?organization.id=#{other.id}") }
example { expect(last_response).to be_ok }
pending "param whitelisting not yet implemented" do
example { expect(JSON.load(body)).to be == {
"@type" => "organization",
"@href" => "/v3/org/#{org.id}",
"id" => org.id,
"login" => "example-org",
"name" => nil,
"github_id" => nil
}}
end
end
end
describe "user" do
let(:user) { User.new(login: 'example-user') }
before { user.save! }
after { user.delete }
describe 'existing user, public api' do
before { get("/v3/account/example-user") }
example { expect(last_response).to be_ok }
example { expect(JSON.load(body)).to be == {
"@type" => "user",
"@href" => "/v3/user/#{user.id}",
"id" => user.id,
"login" => "example-user",
"name" => nil,
"github_id" => nil,
"is_syncing"=> nil,
"synced_at" => nil
}}
end
describe "does not allow overriding user id" do
let(:other) { User.new(login: 'other-user') }
before { other.save! }
after { other.delete }
before { get("/v3/account/example-org?user.id=#{other.id}") }
example { expect(last_response).to be_ok }
pending "param whitelisting not yet implemented" do
example { expect(JSON.load(body)).to be == {
"@type" => "user",
"@href" => "/v3/user/#{user.id}",
"id" => user.id,
"login" => "example-user",
"name" => nil,
"github_id" => nil,
"is_syncing"=> nil,
"synced_at" => nil
}}
end
end
end
end