Merge pull request #275 from travis-ci/jc-v3-settings

Add settings to API V3
This commit is contained in:
carlad 2016-06-09 14:51:06 +02:00
commit b67c226515
12 changed files with 224 additions and 0 deletions

View File

@ -92,6 +92,10 @@ module Travis::API::V3
private_repository_visible?(repository)
end
def settings_visible?(settings)
repository_visible?(settings.repository)
end
def private_repository_visible?(repository)
false
end

View File

@ -0,0 +1,27 @@
module Travis::API::V3
class Models::Settings
DEFAULTS = {
'builds_only_with_travis_yml' => false,
'build_pushes' => true,
'build_pull_requests' => true,
'maximum_number_of_builds' => 0
}.freeze
attr_reader :repository
def initialize(repository)
@repository = repository
end
def to_h
DEFAULTS.merge(repository.settings || {})
end
def update(settings = {})
settings = to_h.merge(settings)
repository.settings.clear
settings.each { |k, v| repository.settings[k] = v }
repository.save!
end
end
end

View File

@ -0,0 +1,15 @@
module Travis::API::V3
class Queries::Settings < Query
params :builds_only_with_travis_yml, :build_pushes, :build_pull_requests, :maximum_number_of_builds, prefix: :settings
def find(repository)
Models::Settings.new(repository)
end
def update(repository)
settings = find(repository)
settings.update(settings_params)
settings
end
end
end

View File

@ -32,6 +32,15 @@ module Travis::API::V3
end
RUBY
@@prefixed_params_accessor = <<-RUBY
def %<prefix>s_params
@%<prefix>s ||= begin
params = @params.select { |key, _| key.start_with?('%<prefix>s.'.freeze) }
Hash[params.map { |key, value| [key.split('.'.freeze).last, value] }]
end
end
RUBY
def self.type
name[/[^:]+$/].underscore
end
@ -48,6 +57,7 @@ module Travis::API::V3
check_type: check_type
})
end
class_eval(@@prefixed_params_accessor % { prefix: prefix })
end
def self.prefix(input)

View File

@ -0,0 +1,15 @@
module Travis::API::V3
module Renderer::Settings
extend self
AVAILABLE_ATTRIBUTES = [:settings]
def available_attributes
AVAILABLE_ATTRIBUTES
end
def render(settings, **)
{ '@type' => 'settings'.freeze }.merge!(settings.to_h)
end
end
end

View File

@ -117,6 +117,12 @@ module Travis::API::V3
get :find
post :create
end
resource :settings do
route '/settings'
get :find
patch :update
end
end
resource :user do

View File

@ -60,6 +60,10 @@ module Travis::API::V3
current_resource.add_service('POST'.freeze, *args)
end
def patch(*args)
current_resource.add_service('PATCH'.freeze, *args)
end
def delete(*args)
current_resource.add_service('DELETE'.freeze, *args)
end

View File

@ -20,6 +20,7 @@ module Travis::API::V3
Repositories = Module.new { extend Services }
Repository = Module.new { extend Services }
Requests = Module.new { extend Services }
Settings = Module.new { extend Services }
User = Module.new { extend Services }
def result_type

View File

@ -0,0 +1,9 @@
module Travis::API::V3
class Services::Settings::Find < Service
def run!
raise LoginRequired unless access_control.logged_in? or access_control.full_access?
raise NotFound unless repo = find(:repository)
find(:settings, repo)
end
end
end

View File

@ -0,0 +1,11 @@
module Travis::API::V3
class Services::Settings::Update < Service
params :builds_only_with_travis_yml, :build_pushes, :build_pull_requests, :maximum_number_of_builds, prefix: :settings
def run!
raise LoginRequired unless access_control.logged_in? or access_control.full_access?
raise NotFound unless repository = find(:repository)
query.update(repository)
end
end
end

View File

@ -0,0 +1,122 @@
require 'spec_helper'
describe Travis::API::V3::Services::Settings do
let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first_or_create }
let(:token) { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) }
let(:auth_headers) { { 'HTTP_AUTHORIZATION' => "token #{token}" } }
let(:json_headers) { { 'CONTENT_TYPE' => 'application/json' } }
describe :Find do
describe 'not authenticated' do
before { get("/v3/repo/#{repo.id}/settings") }
example { expect(last_response.status).to eq(403) }
example do
expect(JSON.load(body)).to eq(
'@type' => 'error',
'error_type' => 'login_required',
'error_message' => 'login required'
)
end
end
describe 'authenticated, missing repo' do
before { get('/v3/repo/9999999999/settings', {}, auth_headers) }
example { expect(last_response.status).to eq(404) }
example do
expect(JSON.load(body)).to eq(
'@type' => 'error',
'error_type' => 'not_found',
'error_message' => 'repository not found (or insufficient access)',
'resource_type' => 'repository'
)
end
end
describe 'authenticated, existing repo, repo has no settings' do
before { get("/v3/repo/#{repo.id}/settings", {}, auth_headers) }
example { expect(last_response.status).to eq(200) }
example do
expect(JSON.load(body)).to eq(
'@type' => 'settings',
'builds_only_with_travis_yml' => false,
'build_pushes' => true,
'build_pull_requests' => true,
'maximum_number_of_builds' => 0
)
end
end
describe 'authenticated, existing repo, repo has some settings' do
before do
repo.update_attributes(settings: JSON.dump('build_pushes' => false))
get("/v3/repo/#{repo.id}/settings", {}, auth_headers)
end
example { expect(last_response.status).to eq(200) }
example do
expect(JSON.load(body)).to eq(
'@type' => 'settings',
'builds_only_with_travis_yml' => false,
'build_pushes' => false,
'build_pull_requests' => true,
'maximum_number_of_builds' => 0
)
end
end
end
describe :Update do
describe 'not authenticated' do
before do
patch("/v3/repo/#{repo.id}/settings", JSON.dump(build_pushes: false), json_headers)
end
example { expect(last_response.status).to eq(403) }
example do
expect(JSON.load(body)).to eq(
'@type' => 'error',
'error_type' => 'login_required',
'error_message' => 'login required'
)
end
end
describe 'authenticated, missing repo' do
before do
patch('/v3/repo/9999999999/settings', JSON.dump(build_pushes: false), json_headers.merge(auth_headers))
end
example { expect(last_response.status).to eq(404) }
example do
expect(JSON.load(body)).to eq(
'@type' => 'error',
'error_type' => 'not_found',
'error_message' => 'repository not found (or insufficient access)',
'resource_type' => 'repository'
)
end
end
describe 'authenticated, existing repo' do
let(:params) { JSON.dump('settings.build_pushes' => false) }
before do
repo.update_attributes(settings: JSON.dump('maximum_number_of_builds' => 20))
patch("/v3/repo/#{repo.id}/settings", params, json_headers.merge(auth_headers))
end
example { expect(last_response.status).to eq(200) }
example do
expect(JSON.load(body)).to eq(
'@type' => 'settings',
'builds_only_with_travis_yml' => false,
'build_pushes' => false,
'build_pull_requests' => true,
'maximum_number_of_builds' => 20
)
end
end
end
end