Commit 1be3e32c8fa30dc0c990efbb0cee829546733a22
Committed by
Robert Lail
1 parent
6a9f6310
Exists in
master
and in
1 other branch
Add a simple API for returning XML or JSON of problems
- Use RABL to render response - Use Devise's token authentication
Showing
8 changed files
with
127 additions
and
0 deletions
Show diff stats
Gemfile
| ... | ... | @@ -38,6 +38,7 @@ platform :ruby do |
| 38 | 38 | end |
| 39 | 39 | |
| 40 | 40 | gem 'ri_cal' |
| 41 | +gem 'rabl' | |
| 41 | 42 | gem 'yajl-ruby' |
| 42 | 43 | |
| 43 | 44 | group :development, :test do |
| ... | ... | @@ -46,6 +47,7 @@ group :development, :test do |
| 46 | 47 | unless ENV["CI"] |
| 47 | 48 | gem 'ruby-debug', :platform => :mri_18 |
| 48 | 49 | gem 'debugger', :platform => :mri_19 |
| 50 | + gem 'pry' | |
| 49 | 51 | end |
| 50 | 52 | # gem 'rpm_contrib' |
| 51 | 53 | # gem 'newrelic_rpm' | ... | ... |
Gemfile.lock
| ... | ... | @@ -55,6 +55,7 @@ GEM |
| 55 | 55 | xpath (~> 0.1.4) |
| 56 | 56 | childprocess (0.3.5) |
| 57 | 57 | ffi (~> 1.0, >= 1.0.6) |
| 58 | + coderay (1.0.6) | |
| 58 | 59 | columnize (0.3.6) |
| 59 | 60 | crack (0.3.1) |
| 60 | 61 | css_parser (1.2.6) |
| ... | ... | @@ -127,6 +128,7 @@ GEM |
| 127 | 128 | i18n (>= 0.4.0) |
| 128 | 129 | mime-types (~> 1.16) |
| 129 | 130 | treetop (~> 1.4.8) |
| 131 | + method_source (0.7.1) | |
| 130 | 132 | mime-types (1.19) |
| 131 | 133 | mongo (1.6.2) |
| 132 | 134 | bson (~> 1.6.2) |
| ... | ... | @@ -187,6 +189,13 @@ GEM |
| 187 | 189 | premailer (1.7.3) |
| 188 | 190 | css_parser (>= 1.1.9) |
| 189 | 191 | htmlentities (>= 4.0.0) |
| 192 | + pry (0.9.9.6) | |
| 193 | + coderay (~> 1.0.5) | |
| 194 | + method_source (~> 0.7.1) | |
| 195 | + slop (>= 2.4.4, < 3) | |
| 196 | + rabl (0.6.13) | |
| 197 | + activesupport (>= 2.3.14) | |
| 198 | + multi_json (~> 1.0) | |
| 190 | 199 | rack (1.4.1) |
| 191 | 200 | rack-cache (1.2) |
| 192 | 201 | rack (>= 0.4) |
| ... | ... | @@ -248,6 +257,7 @@ GEM |
| 248 | 257 | libwebsocket (~> 0.1.3) |
| 249 | 258 | multi_json (~> 1.0) |
| 250 | 259 | rubyzip |
| 260 | + slop (2.4.4) | |
| 251 | 261 | sprockets (2.1.3) |
| 252 | 262 | hike (~> 1.2) |
| 253 | 263 | rack (~> 1.0) |
| ... | ... | @@ -314,6 +324,8 @@ DEPENDENCIES |
| 314 | 324 | omniauth-github |
| 315 | 325 | oruen_redmine_client |
| 316 | 326 | pivotal-tracker |
| 327 | + pry | |
| 328 | + rabl | |
| 317 | 329 | rack-ssl-enforcer |
| 318 | 330 | rails (= 3.2.6) |
| 319 | 331 | rails_autolink (~> 1.0.9) | ... | ... |
| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | +class Api::V1::ProblemsController < ApplicationController | |
| 2 | + | |
| 3 | + def index | |
| 4 | + if params.key?(:start_date) && params.key?(:end_date) | |
| 5 | + start_date = Date.parse(params[:start_date]) | |
| 6 | + end_date = Date.parse(params[:end_date]) | |
| 7 | + @problems = Problem.in_date_range(start_date..end_date) | |
| 8 | + else | |
| 9 | + @problems = Problem.all | |
| 10 | + end | |
| 11 | + end | |
| 12 | + | |
| 13 | +end | ... | ... |
app/models/problem.rb
| ... | ... | @@ -32,6 +32,7 @@ class Problem |
| 32 | 32 | index :last_notice_at |
| 33 | 33 | index :first_notice_at |
| 34 | 34 | index :last_deploy_at |
| 35 | + index :resolved_at | |
| 35 | 36 | index :notices_count |
| 36 | 37 | |
| 37 | 38 | belongs_to :app |
| ... | ... | @@ -106,6 +107,10 @@ class Problem |
| 106 | 107 | else raise("\"#{sort}\" is not a recognized sort") |
| 107 | 108 | end |
| 108 | 109 | end |
| 110 | + | |
| 111 | + def self.in_date_range(date_range) | |
| 112 | + where(:first_notice_at.lte => date_range.end).where("$or" => [{:resolved_at => nil}, {:resolved_at.gte => date_range.begin}]) | |
| 113 | + end | |
| 109 | 114 | |
| 110 | 115 | |
| 111 | 116 | def reset_cached_attributes | ... | ... |
| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | +Rabl.configure do |config| | |
| 2 | + # Commented as these are defaults | |
| 3 | + # config.cache_all_output = false | |
| 4 | + # config.cache_sources = Rails.env != 'development' # Defaults to false | |
| 5 | + # config.cache_engine = Rabl::CacheEngine.new # Defaults to Rails cache | |
| 6 | + # config.escape_all_output = false | |
| 7 | + # config.json_engine = nil # Any multi\_json engines | |
| 8 | + # config.msgpack_engine = nil # Defaults to ::MessagePack | |
| 9 | + # config.bson_engine = nil # Defaults to ::BSON | |
| 10 | + # config.plist_engine = nil # Defaults to ::Plist::Emit | |
| 11 | + # config.include_json_root = true | |
| 12 | + # config.include_msgpack_root = true | |
| 13 | + # config.include_bson_root = true | |
| 14 | + # config.include_plist_root = true | |
| 15 | + # config.include_xml_root = false | |
| 16 | + # config.include_child_root = true | |
| 17 | + # config.enable_json_callbacks = false | |
| 18 | + # config.xml_options = { :dasherize => true, :skip_types => false } | |
| 19 | + # config.view_paths = [] | |
| 20 | +end | ... | ... |
config/routes.rb
| ... | ... | @@ -0,0 +1,58 @@ |
| 1 | +require 'spec_helper' | |
| 2 | + | |
| 3 | +describe Api::V1::ProblemsController do | |
| 4 | + | |
| 5 | + context "when logged in" do | |
| 6 | + before do | |
| 7 | + @user = Fabricate(:user) | |
| 8 | + end | |
| 9 | + | |
| 10 | + describe "GET /api/v1/problems" do | |
| 11 | + before do | |
| 12 | + Fabricate(:problem, first_notice_at: Date.new(2012, 8, 01), resolved_at: Date.new(2012, 8, 02)) | |
| 13 | + Fabricate(:problem, first_notice_at: Date.new(2012, 8, 01), resolved_at: Date.new(2012, 8, 21)) | |
| 14 | + Fabricate(:problem, first_notice_at: Date.new(2012, 8, 21)) | |
| 15 | + Fabricate(:problem, first_notice_at: Date.new(2012, 8, 30)) | |
| 16 | + end | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + it "should return JSON if JSON is requested" do | |
| 21 | + get :index, auth_token: @user.authentication_token, format: "json" | |
| 22 | + lambda { JSON.load(response.body) }.should_not raise_error(JSON::ParserError) | |
| 23 | + end | |
| 24 | + | |
| 25 | + it "should return XML if XML is requested" do | |
| 26 | + get :index, auth_token: @user.authentication_token, format: "xml" | |
| 27 | + lambda { XML::Parser.string(response.body).parse }.should_not raise_error | |
| 28 | + end | |
| 29 | + | |
| 30 | + it "should return JSON by default" do | |
| 31 | + get :index, auth_token: @user.authentication_token | |
| 32 | + lambda { JSON.load(response.body) }.should_not raise_error(JSON::ParserError) | |
| 33 | + end | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + describe "given a date range" do | |
| 38 | + | |
| 39 | + it "should return only the problems open during the date range" do | |
| 40 | + get :index, {auth_token: @user.authentication_token, start_date: "2012-08-20", end_date: "2012-08-27"} | |
| 41 | + response.should be_success | |
| 42 | + problems = JSON.load response.body | |
| 43 | + problems.length.should == 2 | |
| 44 | + end | |
| 45 | + | |
| 46 | + end | |
| 47 | + | |
| 48 | + it "should return all problems" do | |
| 49 | + get :index, {auth_token: @user.authentication_token} | |
| 50 | + response.should be_success | |
| 51 | + problems = JSON.load response.body | |
| 52 | + problems.length.should == 4 | |
| 53 | + end | |
| 54 | + | |
| 55 | + end | |
| 56 | + end | |
| 57 | + | |
| 58 | +end | ... | ... |