diff --git a/lib/travis/api/v3/queries/repositories.rb b/lib/travis/api/v3/queries/repositories.rb index 3994c384..56593383 100644 --- a/lib/travis/api/v3/queries/repositories.rb +++ b/lib/travis/api/v3/queries/repositories.rb @@ -3,7 +3,15 @@ module Travis::API::V3 params :active, :private, :starred, prefix: :repository sortable_by :id, :github_id, :owner_name, :name, active: sort_condition(:active), :'default_branch.last_build' => 'builds.started_at', - :current_build_id => "repositories.current_build_id %{order} NULLS LAST" + :current_build => "repositories.current_build_id %{order} NULLS LAST" + + # this is a hack for a bug in AR that generates invalid query when it tries + # to include `current_build` and join it at the same time. We don't actually + # need the join, but it will be automatically added, because `current_build` + # is an association. This prevents adding the join. We will probably be able + # to remove it once we move to newer AR versions + prevent_sortable_join :current_build + experimental_sortable_by :current_build def for_member(user, **options) all(user: user, **options).joins(:users).where(users: user_condition(user), invalidated_at: nil) @@ -37,7 +45,7 @@ module Travis::API::V3 end list = list.includes(default_branch: :last_build) - list = list.includes(:current_build) + list = list.includes(:current_build) if includes? 'repository.current_build'.freeze list = list.includes(default_branch: { last_build: :commit }) if includes? 'build.commit'.freeze sort list end diff --git a/lib/travis/api/v3/query.rb b/lib/travis/api/v3/query.rb index af4e5006..b9d47fe7 100644 --- a/lib/travis/api/v3/query.rb +++ b/lib/travis/api/v3/query.rb @@ -70,6 +70,26 @@ module Travis::API::V3 mapping.each { |key, value| sort_by[key.to_s] = prefix(value) } end + def self.prevent_sortable_join(*fields) + dont_join.push(*fields.map(&:to_s)) + end + + @dont_join = [] + def self.dont_join + @dont_join ||= superclass.dont_join.dup + end + + @experimental_sortable_by = [] + def self.experimental_sortable_by(*fields) + @experimental_sortable_by ||= [] + + if fields.first + @experimental_sortable_by.push(*fields.map(&:to_s)) + end + + @experimental_sortable_by + end + def self.sort_condition(condition) if condition.is_a? Hash condition = condition.map { |e| e.map { |v| prefix(v) }.join(" = ".freeze) }.join(" and ".freeze) @@ -172,6 +192,7 @@ module Travis::API::V3 end def sort_join?(collection, field) + return if self.class.dont_join.include?(field) !collection.reflect_on_association(field.to_sym).nil? end diff --git a/lib/travis/api/v3/renderer/model_renderer.rb b/lib/travis/api/v3/renderer/model_renderer.rb index 0b3a0c5e..dd5bdc0b 100644 --- a/lib/travis/api/v3/renderer/model_renderer.rb +++ b/lib/travis/api/v3/renderer/model_renderer.rb @@ -26,6 +26,17 @@ module Travis::API::V3 @representations ||= superclass.representations.dup end + @experimental_representations = [] + def self.experimental_representations(*representations) + @experimental_representations ||= superclass.experimental_representations.dup + + if representations.first + @experimental_representations.push(*representations) + end + + @experimental_representations + end + @available_attributes = Set.new def self.available_attributes @available_attributes ||= superclass.available_attributes.dup diff --git a/lib/travis/api/v3/renderer/repository.rb b/lib/travis/api/v3/renderer/repository.rb index c1c3bf30..546b4c6e 100644 --- a/lib/travis/api/v3/renderer/repository.rb +++ b/lib/travis/api/v3/renderer/repository.rb @@ -3,7 +3,10 @@ require 'travis/api/v3/renderer/model_renderer' module Travis::API::V3 class Renderer::Repository < Renderer::ModelRenderer representation(:minimal, :id, :name, :slug) - representation(:standard, :id, :name, :slug, :description, :github_language, :active, :private, :owner, :default_branch, :starred, :current_build) + representation(:standard, :id, :name, :slug, :description, :github_language, :active, :private, :owner, :default_branch, :starred) + representation(:experimental, :id, :name, :slug, :description, :github_language, :active, :private, :owner, :default_branch, :starred, :current_build) + + experimental_representations(:experimental) def active !!model.active diff --git a/lib/travis/api/v3/service_index.rb b/lib/travis/api/v3/service_index.rb index 0d17b0ea..ee3ebd04 100644 --- a/lib/travis/api/v3/service_index.rb +++ b/lib/travis/api/v3/service_index.rb @@ -85,9 +85,17 @@ module Travis::API::V3 data = resources[resource.identifier] ||= { :@type => :resource, :actions => {} } data.merge! resource.meta_data - if renderer = Renderer[resource.identifier, false] - data[:attributes] = renderer.available_attributes if renderer.respond_to? :available_attributes - data[:representations] = renderer.representations if renderer.respond_to? :representations + if renderer = Renderer[resource.identifier, false] + + data[:attributes] = renderer.available_attributes if renderer.respond_to? :available_attributes + + if renderer.respond_to? :representations + representations = renderer.representations + if renderer.respond_to? :experimental_representations + representations = representations.reject { |k| renderer.experimental_representations.include? k } + end + data[:representations] = representations + end end if permissions = Permissions[resource.identifier, false] @@ -102,7 +110,7 @@ module Travis::API::V3 if factory.params and factory.params.include? "sort_by".freeze query = Queries[resource.identifier] if query and query.sortable? - resources[resource.identifier][:sortable_by] = query.sort_by.keys + resources[resource.identifier][:sortable_by] = query.sort_by.keys - query.experimental_sortable_by resources[resource.identifier][:default_sort] = query.default_sort unless query.default_sort.empty? end end diff --git a/spec/v3/services/owner/find_spec.rb b/spec/v3/services/owner/find_spec.rb index ddab6ccf..5bb8e591 100644 --- a/spec/v3/services/owner/find_spec.rb +++ b/spec/v3/services/owner/find_spec.rb @@ -79,8 +79,7 @@ describe Travis::API::V3::Services::Owner::Find, set_app: true do "@href" => "/v3/repo/#{repo.id}/branch/master", "@representation" => "minimal", "name" => "master"}, - "starred" => false, - "current_build" => nil + "starred" => false }] }} end @@ -128,8 +127,7 @@ describe Travis::API::V3::Services::Owner::Find, set_app: true do "@href" => "/v3/repo/#{repo.id}/branch/master", "@representation"=> "minimal", "name" => "master"}, - "starred" => false, - "current_build" => nil + "starred" => false }] }} end diff --git a/spec/v3/services/repositories/for_current_user_spec.rb b/spec/v3/services/repositories/for_current_user_spec.rb index f724bbb7..0d86a6d2 100644 --- a/spec/v3/services/repositories/for_current_user_spec.rb +++ b/spec/v3/services/repositories/for_current_user_spec.rb @@ -2,7 +2,6 @@ describe Travis::API::V3::Services::Repositories::ForCurrentUser, set_app: true let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first } let(:build) { repo.builds.first } let(:jobs) { Travis::API::V3::Models::Build.find(build.id).jobs } - let(:current_build) { repo.builds.first } let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) } let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }} @@ -11,7 +10,6 @@ describe Travis::API::V3::Services::Repositories::ForCurrentUser, set_app: true after { repo.update_attribute(:private, false) } describe "private repository, private API, authenticated as user with access" do - before { repo.update_attribute(:current_build_id, current_build.id) } before { get("/v3/repos", {}, headers) } example { expect(last_response).to be_ok } example { expect(JSON.load(body)).to be == { @@ -64,18 +62,6 @@ describe Travis::API::V3::Services::Repositories::ForCurrentUser, set_app: true "@representation" => "minimal", "name" => "master"}, "starred" => false, - "current_build" => { - "@type" => "build", - "@href" => "/v3/build/#{current_build.id}", - "@representation" => "minimal", - "id" => current_build.id.to_i, - "number" => current_build.number, - "state" => current_build.state, - "duration" => current_build.duration, - "event_type" => current_build.event_type, - "previous_state" => current_build.previous_state, - "started_at" => current_build.started_at.strftime("%Y-%m-%dT%H:%M:%SZ"), - "finished_at" => nil}, }] }} end diff --git a/spec/v3/services/repositories/for_owner_spec.rb b/spec/v3/services/repositories/for_owner_spec.rb index feca85ac..9dbdae21 100644 --- a/spec/v3/services/repositories/for_owner_spec.rb +++ b/spec/v3/services/repositories/for_owner_spec.rb @@ -63,7 +63,6 @@ describe Travis::API::V3::Services::Repositories::ForOwner, set_app: true do "@representation" => "minimal", "name" => "master"}, "starred" => false, - "current_build" => nil }]}} end @@ -140,8 +139,7 @@ describe Travis::API::V3::Services::Repositories::ForOwner, set_app: true do "@href" => "/v3/repo/1/branch/master", "@representation"=>"minimal", "name" => "master" }, - "starred" => false, - "current_build" => nil }, { + "starred" => false }, { "@type" => "repository", "@href" => "/v3/repo/#{repo2.id}", "@representation" => "standard", @@ -170,7 +168,6 @@ describe Travis::API::V3::Services::Repositories::ForOwner, set_app: true do "@href" => "/v3/repo/#{repo2.id}/branch/master", "@representation"=>"minimal", "name" =>"master" }, - "starred" => false, - "current_build" => nil}]} + "starred" => false}]} end end diff --git a/spec/v3/services/repository/find_spec.rb b/spec/v3/services/repository/find_spec.rb index 0527d5e9..57683c3f 100644 --- a/spec/v3/services/repository/find_spec.rb +++ b/spec/v3/services/repository/find_spec.rb @@ -54,7 +54,6 @@ describe Travis::API::V3::Services::Repository::Find, set_app: true do "@representation" => "minimal", "name" => "master"}, "starred" => false, - "current_build" => nil }} end @@ -133,7 +132,6 @@ describe Travis::API::V3::Services::Repository::Find, set_app: true do "@representation" => "minimal", "name" => "master"}, "starred" => false, - "current_build" => nil }} end @@ -197,7 +195,6 @@ describe Travis::API::V3::Services::Repository::Find, set_app: true do "@representation" => "minimal", "name" => "master"}, "starred" => false, - "current_build" => nil }} end @@ -267,7 +264,6 @@ describe Travis::API::V3::Services::Repository::Find, set_app: true do "@representation" => "minimal", "name" => "master"}, "starred" => false, - "current_build" => nil }} end