diff --git a/lib/travis/api/app/endpoint/artifacts.rb b/lib/travis/api/app/endpoint/artifacts.rb index fa3d0743..72cd4a25 100644 --- a/lib/travis/api/app/endpoint/artifacts.rb +++ b/lib/travis/api/app/endpoint/artifacts.rb @@ -6,7 +6,7 @@ class Travis::Api::App # artifacts class Artifacts < Endpoint # Fetches an artifact by it's *id*. - get('/:id') do |id| + get '/:id' do |id| body one(params).run end end diff --git a/lib/travis/api/app/endpoint/branches.rb b/lib/travis/api/app/endpoint/branches.rb index 2f076482..bf898790 100644 --- a/lib/travis/api/app/endpoint/branches.rb +++ b/lib/travis/api/app/endpoint/branches.rb @@ -3,7 +3,7 @@ require 'travis/api/app' class Travis::Api::App class Endpoint class Branches < Endpoint - get('/') do + get '/' do body all(params).run, type: :branches end end diff --git a/lib/travis/api/app/endpoint/hooks.rb b/lib/travis/api/app/endpoint/hooks.rb index b3100bf7..02154e56 100644 --- a/lib/travis/api/app/endpoint/hooks.rb +++ b/lib/travis/api/app/endpoint/hooks.rb @@ -3,11 +3,11 @@ require 'travis/api/app' class Travis::Api::App class Endpoint class Hooks < Endpoint - get('/', scope: :private) do + get '/', scope: :private do body all(params).run, type: :hooks end - put('/:id?', scope: :private) do + put '/:id?', scope: :private do update(id: params[:id] || params[:hook][:id], active: params[:hook][:active]).run 204 end diff --git a/lib/travis/api/app/endpoint/jobs.rb b/lib/travis/api/app/endpoint/jobs.rb index bd2463ab..893fefb4 100644 --- a/lib/travis/api/app/endpoint/jobs.rb +++ b/lib/travis/api/app/endpoint/jobs.rb @@ -3,11 +3,11 @@ require 'travis/api/app' class Travis::Api::App class Endpoint class Jobs < Endpoint - get('/') do + get '/' do body all(params).run end - get('/:id') do + get '/:id' do body one(params).run end end diff --git a/lib/travis/api/app/endpoint/repositories.rb b/lib/travis/api/app/endpoint/repositories.rb index a26161a9..ade57472 100644 --- a/lib/travis/api/app/endpoint/repositories.rb +++ b/lib/travis/api/app/endpoint/repositories.rb @@ -7,13 +7,9 @@ class Travis::Api::App body all(params).run end - get('/:id') do + get '/:id' do body one(params).run end - - # TODO make sure status images and cc.xml work - # rescue ActiveRecord::RecordNotFound - # raise unless params[:format] == 'png' end end end diff --git a/lib/travis/api/app/endpoint/result_image.rb b/lib/travis/api/app/endpoint/result_image.rb new file mode 100644 index 00000000..ec45c890 --- /dev/null +++ b/lib/travis/api/app/endpoint/result_image.rb @@ -0,0 +1,13 @@ +require 'travis/api/app' + +class Travis::Api::App + class Endpoint + class ResultImage < Endpoint + set(:prefix) { '/' } + + get '/:owner_name/:name.png' do + result_image service(:repositories, :one, params).run(:raise => false) + end + end + end +end diff --git a/lib/travis/api/app/endpoint/stats.rb b/lib/travis/api/app/endpoint/stats.rb index ac46bc7e..7bd2a2ee 100644 --- a/lib/travis/api/app/endpoint/stats.rb +++ b/lib/travis/api/app/endpoint/stats.rb @@ -3,11 +3,11 @@ require 'travis/api/app' class Travis::Api::App class Endpoint class Stats < Endpoint - get('/repos') do + get '/repos' do { :stats => service(:daily_repos) } end - get('/tests') do + get '/tests' do { :stats => service(:daily_tests) } end end diff --git a/lib/travis/api/app/endpoint/workers.rb b/lib/travis/api/app/endpoint/workers.rb index ea4c7729..93d8796a 100644 --- a/lib/travis/api/app/endpoint/workers.rb +++ b/lib/travis/api/app/endpoint/workers.rb @@ -3,7 +3,7 @@ require 'travis/api/app' class Travis::Api::App class Endpoint class Workers < Endpoint - get('/') do + get '/' do body all(params).run end end diff --git a/lib/travis/api/app/helpers/result_image.rb b/lib/travis/api/app/helpers/result_image.rb new file mode 100644 index 00000000..3ddbef18 --- /dev/null +++ b/lib/travis/api/app/helpers/result_image.rb @@ -0,0 +1,27 @@ +require 'travis/api/app' +require 'cgi' + +module Travis::Api::App::Helpers + module ResultImage + RESULT_NAMES = { nil => 'unknown', 0 => 'passing', 1 => 'failing' } + + def result_image(resource) + headers['Expires'] = CGI.rfc1123_date(Time.now.utc) + filename = filename(resource) + env['travis.sending-file'] = filename + send_file filename, type: :png, disposition: :inline + end + + protected + + def filename(resource) + root = File.expand_path("#{settings.root}/../../../../../") # TODO wat. + "#{root}/public/images/result/#{result(resource)}.png" + end + + def result(resource) + RESULT_NAMES[resource.try(:last_build_result_on, branch: params[:branch])] + end + end +end + diff --git a/lib/travis/api/app/responder.rb b/lib/travis/api/app/responder.rb index 36e3a5c4..8b8f0785 100644 --- a/lib/travis/api/app/responder.rb +++ b/lib/travis/api/app/responder.rb @@ -23,7 +23,7 @@ class Travis::Api::App enable :raise_errors # disable :dump_errors register :subclass_tracker - helpers :json_renderer + helpers :json_renderer, :result_image end configure :development do diff --git a/public/images/result/failing.png b/public/images/result/failing.png new file mode 100644 index 00000000..46eda84e Binary files /dev/null and b/public/images/result/failing.png differ diff --git a/public/images/result/passing.png b/public/images/result/passing.png new file mode 100644 index 00000000..1d1bbe39 Binary files /dev/null and b/public/images/result/passing.png differ diff --git a/public/images/result/unknown.png b/public/images/result/unknown.png new file mode 100644 index 00000000..cb7abbda Binary files /dev/null and b/public/images/result/unknown.png differ diff --git a/spec/integration/result_image_spec.rb b/spec/integration/result_image_spec.rb new file mode 100644 index 00000000..965d9091 --- /dev/null +++ b/spec/integration/result_image_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' + +describe 'Result images' do + let!(:repo) { Factory(:repository, owner_name: 'svenfuchs', name: 'minimal') } + + describe 'GET /svenfuchs/minimal.png' do + it '"unknown" when the repository does not exist' do + get('/svenfuchs/does-not-exist.png').should deliver_result_image_for('unknown') + end + + it '"unknown" when it only has one build that is not finished' do + repo.update_attributes!(last_build_result: nil) + get('/svenfuchs/minimal.png').should deliver_result_image_for('unknown') + end + + it '"failing" when the last build has failed' do + repo.update_attributes!(last_build_result: 1) + get('/svenfuchs/minimal.png').should deliver_result_image_for('failing') + end + + it '"passing" when the last build has passed' do + repo.update_attributes!(last_build_result: 0) + get('/svenfuchs/minimal.png').should deliver_result_image_for('passing') + end + + it '"passing" when there is a running build but the previous one has passed' do + Factory(:build, repository: repo, state: :finished, result: nil, previous_result: 0) + repo.update_attributes!(last_build_result: nil) + get('/svenfuchs/minimal.png').should deliver_result_image_for('passing') + end + end + + describe 'GET /svenfuchs/minimal.png' do + let(:commit) { Factory(:commit, branch: 'dev') } + + it '"unknown" when the repository does not exist' do + get('/svenfuchs/does-not-exist.png?branch=dev').should deliver_result_image_for('unknown') + end + + it '"unknown" when it only has a build that is not finished' do + Factory(:build, repository: repo, state: :started, result: nil, commit: commit) + get('/svenfuchs/minimal.png?branch=dev').should deliver_result_image_for('unknown') + end + + it '"failing" when the last build has failed' do + Factory(:build, repository: repo, state: :finished, result: 1, commit: commit) + get('/svenfuchs/minimal.png?branch=dev').should deliver_result_image_for('failing') + end + + it '"passing" when the last build has passed' do + Factory(:build, repository: repo, state: :finished, result: 0, commit: commit) + get('/svenfuchs/minimal.png?branch=dev').should deliver_result_image_for('passing') + end + + it '"passing" when there is a running build but the previous one has passed' do + Factory(:build, repository: repo, state: :finished, result: 0, commit: commit) + Factory(:build, repository: repo, state: :started, result: nil, commit: commit) + repo.update_attributes!(last_build_result: nil) + get('/svenfuchs/minimal.png?branch=dev').should deliver_result_image_for('passing') + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 074ec5cb..f4977e8a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -28,6 +28,27 @@ RSpec::Matchers.define :deliver_json_for do |resource, options = {}| end end +RSpec::Matchers.define :deliver_result_image_for do |name| + match do |response| + actual = files.detect do |(name, content)| + response.body.force_encoding('ascii') == content.force_encoding('ascii') # TODO ummmmmmmm? + end + actual = actual && actual[0] + + failure_message_for_should do + "expected #{actual.inspect} to equal #{name.inspect}" + end + + actual == name + end + + def files + files = Hash[*Dir['public/images/result/*.png'].map do |file| + [File.basename(file, '.png'), File.read(file)] + end.flatten] + end +end + Travis.logger = Logger.new(StringIO.new) Travis::Api::App.setup