From 737a31ad23d257ea40f2df4556583088f540f501 Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Tue, 27 Jan 2015 15:50:21 +0100 Subject: [PATCH] v3: add /orgs endpoint, fixes travis-pro/api-v3#1 --- lib/travis/api/v3.rb | 4 +-- lib/travis/api/v3/queries/organizations.rb | 7 +++++ lib/travis/api/v3/queries/repositories.rb | 11 ------- lib/travis/api/v3/query.rb | 9 ++++++ lib/travis/api/v3/renderer/organization.rb | 14 +++++++++ lib/travis/api/v3/renderer/organizations.rb | 9 ++++++ lib/travis/api/v3/routes.rb | 5 +++ .../organizations_for_current_user.rb | 10 ++++++ spec/v3/service_index_spec.rb | 8 +++-- .../organizations_for_current_user_spec.rb | 31 +++++++++++++++++++ 10 files changed, 92 insertions(+), 16 deletions(-) create mode 100644 lib/travis/api/v3/queries/organizations.rb create mode 100644 lib/travis/api/v3/renderer/organization.rb create mode 100644 lib/travis/api/v3/renderer/organizations.rb create mode 100644 lib/travis/api/v3/services/organizations_for_current_user.rb create mode 100644 spec/v3/services/organizations_for_current_user_spec.rb diff --git a/lib/travis/api/v3.rb b/lib/travis/api/v3.rb index 397835c8..29589008 100644 --- a/lib/travis/api/v3.rb +++ b/lib/travis/api/v3.rb @@ -4,8 +4,8 @@ module Travis V3 = self def load_dir(dir, recursive: true) - Dir.glob("#{dir}/*.rb").each { |f| require f[%r[(?<=lib/).+(?=\.rb$)]] } - Dir.glob("#{dir}/*").each { |dir| load_dir(dir) } if recursive + Dir.glob("#{dir}/*.rb").sort.each { |f| require f[%r[(?<=lib/).+(?=\.rb$)]] } + Dir.glob("#{dir}/*").sort.each { |dir| load_dir(dir) } if recursive end def response(payload, headers = {}, content_type: 'application/json'.freeze, status: 200) diff --git a/lib/travis/api/v3/queries/organizations.rb b/lib/travis/api/v3/queries/organizations.rb new file mode 100644 index 00000000..42d84d4f --- /dev/null +++ b/lib/travis/api/v3/queries/organizations.rb @@ -0,0 +1,7 @@ +module Travis::API::V3 + class Queries::Organizations < Query + def for_member(user) + ::Organization.joins(:users).where(users: user_condition(user)) + end + end +end diff --git a/lib/travis/api/v3/queries/repositories.rb b/lib/travis/api/v3/queries/repositories.rb index cb8fe209..1f4c0c22 100644 --- a/lib/travis/api/v3/queries/repositories.rb +++ b/lib/travis/api/v3/queries/repositories.rb @@ -6,17 +6,6 @@ module Travis::API::V3 all.joins(:users).where(users: user_condition(user)) end - private - - def user_condition(value) - case value - when String then { login: value } - when Integer then { id: value } - when ::User then { id: value.id } - else raise WrongParams - end - end - def all @all ||= begin all = ::Repository diff --git a/lib/travis/api/v3/query.rb b/lib/travis/api/v3/query.rb index 271187af..0d1061e6 100644 --- a/lib/travis/api/v3/query.rb +++ b/lib/travis/api/v3/query.rb @@ -15,5 +15,14 @@ module Travis::API::V3 return false if value == 'false'.freeze !!value end + + def user_condition(value) + case value + when String then { login: value } + when Integer then { id: value } + when ::User then { id: value.id } + else raise WrongParams + end + end end end diff --git a/lib/travis/api/v3/renderer/organization.rb b/lib/travis/api/v3/renderer/organization.rb new file mode 100644 index 00000000..85def8dc --- /dev/null +++ b/lib/travis/api/v3/renderer/organization.rb @@ -0,0 +1,14 @@ +module Travis::API::V3 + module Renderer::Organization + DIRECT_ATTRIBUTES = %i[id login name github_id] + extend self + + def render(organization) + { :@type => 'organization'.freeze, **direct_attributes(organization) } + end + + def direct_attributes(repository) + DIRECT_ATTRIBUTES.map { |a| [a, repository.public_send(a)] }.to_h + end + end +end diff --git a/lib/travis/api/v3/renderer/organizations.rb b/lib/travis/api/v3/renderer/organizations.rb new file mode 100644 index 00000000..d9ff3081 --- /dev/null +++ b/lib/travis/api/v3/renderer/organizations.rb @@ -0,0 +1,9 @@ +module Travis::API::V3 + module Renderer::Organizations + extend self + + def render(repositories) + Renderer[:collection].render(:organizations, :organization, repositories) + end + end +end diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index 8f7821f3..5394d7dc 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -12,5 +12,10 @@ module Travis::API::V3 route '/repos' get :repositories_for_current_user end + + resource :organizations do + route '/orgs' + get :organizations_for_current_user + end end end diff --git a/lib/travis/api/v3/services/organizations_for_current_user.rb b/lib/travis/api/v3/services/organizations_for_current_user.rb new file mode 100644 index 00000000..518fa838 --- /dev/null +++ b/lib/travis/api/v3/services/organizations_for_current_user.rb @@ -0,0 +1,10 @@ +module Travis::API::V3 + class Services::OrganizationsForCurrentUser < Service + result_type :organizations + + def run! + raise LoginRequired unless access_control.logged_in? + query.for_member(access_control.user) + end + end +end diff --git a/spec/v3/service_index_spec.rb b/spec/v3/service_index_spec.rb index 4b460def..83e872e8 100644 --- a/spec/v3/service_index_spec.rb +++ b/spec/v3/service_index_spec.rb @@ -8,10 +8,12 @@ describe Travis::API::V3::ServiceIndex do describe "custom json entry point" do let(:expected_resources) {{ - "repository" => { + "repository" => { "find" => [{"request-method"=>"GET", "uri-template"=>"#{path}repo/{repository.id}"}] }, - "repositories" => { - "for_current_user" => [{"request-method"=>"GET", "uri-template"=>"#{path}repos"}] } + "repositories" => { + "for_current_user" => [{"request-method"=>"GET", "uri-template"=>"#{path}repos"}] }, + "organizations" => { + "for_current_user" => [{"request-method"=>"GET", "uri-template"=>"#{path}orgs"}] } }} describe 'with /v3 prefix' do diff --git a/spec/v3/services/organizations_for_current_user_spec.rb b/spec/v3/services/organizations_for_current_user_spec.rb new file mode 100644 index 00000000..69d94e44 --- /dev/null +++ b/spec/v3/services/organizations_for_current_user_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe Travis::API::V3::Services::FindRepository do + let(:repo) { Repository.by_slug('svenfuchs/minimal').first } + + let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) } + let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }} + before { Permission.create(repository: repo, user: repo.owner, pull: true) } + before { repo.update_attribute(:private, true) } + after { repo.update_attribute(:private, false) } + + let(:org) { Organization.new(login: 'example-org') } + before { org.save! } + before { org.memberships.create(user: repo.owner) } + after { org.delete } + + describe "authenticated as user with access" do + before { get("/v3/orgs", {}, headers) } + example { expect(last_response).to be_ok } + example { expect(JSON.load(body)).to be == { + "@type" => "organizations", + "organizations" => [{ + "@type" => "organization", + "id" => org.id, + "login" => "example-org", + "name" => nil, + "github_id" => nil + }] + }} + end +end \ No newline at end of file