magi 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +12 -3
- data/Procfile +4 -0
- data/README.md +25 -1
- data/app/assets/stylesheets/application.css +1 -0
- data/app/assets/stylesheets/builds.scss +35 -0
- data/app/assets/stylesheets/common.scss +69 -0
- data/app/assets/stylesheets/jobs.scss +121 -0
- data/app/assets/stylesheets/layout.scss +19 -0
- data/app/assets/stylesheets/mixin.scss +6 -0
- data/app/controllers/application_controller.rb +16 -0
- data/app/controllers/builds_controller.rb +45 -0
- data/app/controllers/jobs_controller.rb +43 -0
- data/app/models/build.rb +39 -0
- data/app/models/job.rb +88 -0
- data/app/views/builds/show.html.slim +36 -0
- data/app/views/jobs/_form.html.slim +27 -0
- data/app/views/jobs/edit.html.slim +9 -0
- data/app/views/jobs/index.html.slim +19 -0
- data/app/views/jobs/new.html.slim +7 -0
- data/app/views/jobs/show.html.slim +24 -0
- data/app/views/layouts/application.html.slim +10 -0
- data/app/workers/build_worker.rb +8 -0
- data/bin/magi +6 -0
- data/config/application.rb +1 -1
- data/config/database.yml +21 -17
- data/config/routes.rb +4 -55
- data/db/migrate/20130531143239_create_jobs.rb +10 -0
- data/db/migrate/20130531155155_create_builds.rb +14 -0
- data/db/schema.rb +35 -0
- data/lib/magi/command.rb +53 -0
- data/lib/magi/executer.rb +31 -0
- data/lib/magi/scheduler.rb +55 -0
- data/lib/magi/version.rb +1 -1
- data/lib/magi.rb +1 -4
- data/magi.gemspec +29 -1
- data/script/clock.rb +5 -0
- data/spec/factories/build.rb +6 -0
- data/spec/factories/job.rb +7 -0
- data/spec/models/build_spec.rb +35 -0
- data/spec/models/job_spec.rb +54 -0
- data/spec/requests/builds_spec.rb +68 -0
- data/spec/requests/jobs_spec.rb +93 -0
- data/spec/spec_helper.rb +28 -0
- metadata +324 -50
- data/.gitignore +0 -19
- data/app/mailers/.gitkeep +0 -0
- data/app/models/.gitkeep +0 -0
- data/app/views/layouts/application.html.erb +0 -14
- data/doc/README_FOR_APP +0 -2
- data/lib/assets/.gitkeep +0 -0
- data/lib/tasks/.gitkeep +0 -0
- data/log/.gitkeep +0 -0
- data/public/index.html +0 -241
- data/test/fixtures/.gitkeep +0 -0
- data/test/functional/.gitkeep +0 -0
- data/test/integration/.gitkeep +0 -0
- data/test/performance/browsing_test.rb +0 -12
- data/test/test_helper.rb +0 -13
- data/test/unit/.gitkeep +0 -0
- data/vendor/assets/javascripts/.gitkeep +0 -0
- data/vendor/assets/stylesheets/.gitkeep +0 -0
- data/vendor/plugins/.gitkeep +0 -0
data/bin/magi
ADDED
data/config/application.rb
CHANGED
@@ -16,7 +16,7 @@ module Magi
|
|
16
16
|
# -- all .rb files in that directory are automatically loaded.
|
17
17
|
|
18
18
|
# Custom directories with classes and modules you want to be autoloadable.
|
19
|
-
|
19
|
+
config.autoload_paths += %W(#{config.root}/lib)
|
20
20
|
|
21
21
|
# Only load the plugins named here, in the order given (default is alphabetical).
|
22
22
|
# :all can be used as a placeholder for all plugins not explicitly named.
|
data/config/database.yml
CHANGED
@@ -1,25 +1,29 @@
|
|
1
|
-
# SQLite version 3.x
|
2
|
-
# gem install sqlite3
|
3
|
-
#
|
4
|
-
# Ensure the SQLite 3 gem is defined in your Gemfile
|
5
|
-
# gem 'sqlite3'
|
6
1
|
development:
|
7
|
-
adapter:
|
8
|
-
|
2
|
+
adapter: mysql2
|
3
|
+
encoding: utf8
|
4
|
+
reconnect: false
|
5
|
+
database: magi_development
|
9
6
|
pool: 5
|
10
|
-
|
7
|
+
username: root
|
8
|
+
password:
|
9
|
+
host: localhost
|
11
10
|
|
12
|
-
# Warning: The database defined as "test" will be erased and
|
13
|
-
# re-generated from your development database when you run "rake".
|
14
|
-
# Do not set this db to the same as development or production.
|
15
11
|
test:
|
16
|
-
adapter:
|
17
|
-
|
12
|
+
adapter: mysql2
|
13
|
+
encoding: utf8
|
14
|
+
reconnect: false
|
15
|
+
database: magi_test
|
18
16
|
pool: 5
|
19
|
-
|
17
|
+
username: root
|
18
|
+
password:
|
19
|
+
host: localhost
|
20
20
|
|
21
21
|
production:
|
22
|
-
adapter:
|
23
|
-
|
22
|
+
adapter: mysql2
|
23
|
+
encoding: utf8
|
24
|
+
reconnect: false
|
25
|
+
database: magi_production
|
24
26
|
pool: 5
|
25
|
-
|
27
|
+
username: root
|
28
|
+
password:
|
29
|
+
host: localhost
|
data/config/routes.rb
CHANGED
@@ -1,58 +1,7 @@
|
|
1
1
|
Magi::Application.routes.draw do
|
2
|
-
|
3
|
-
# first created -> highest priority.
|
2
|
+
root to: "jobs#index"
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# Sample of named route:
|
10
|
-
# match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
|
11
|
-
# This route can be invoked with purchase_url(:id => product.id)
|
12
|
-
|
13
|
-
# Sample resource route (maps HTTP verbs to controller actions automatically):
|
14
|
-
# resources :products
|
15
|
-
|
16
|
-
# Sample resource route with options:
|
17
|
-
# resources :products do
|
18
|
-
# member do
|
19
|
-
# get 'short'
|
20
|
-
# post 'toggle'
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# collection do
|
24
|
-
# get 'sold'
|
25
|
-
# end
|
26
|
-
# end
|
27
|
-
|
28
|
-
# Sample resource route with sub-resources:
|
29
|
-
# resources :products do
|
30
|
-
# resources :comments, :sales
|
31
|
-
# resource :seller
|
32
|
-
# end
|
33
|
-
|
34
|
-
# Sample resource route with more complex sub-resources
|
35
|
-
# resources :products do
|
36
|
-
# resources :comments
|
37
|
-
# resources :sales do
|
38
|
-
# get 'recent', :on => :collection
|
39
|
-
# end
|
40
|
-
# end
|
41
|
-
|
42
|
-
# Sample resource route within a namespace:
|
43
|
-
# namespace :admin do
|
44
|
-
# # Directs /admin/products/* to Admin::ProductsController
|
45
|
-
# # (app/controllers/admin/products_controller.rb)
|
46
|
-
# resources :products
|
47
|
-
# end
|
48
|
-
|
49
|
-
# You can have the root of your site routed with "root"
|
50
|
-
# just remember to delete public/index.html.
|
51
|
-
# root :to => 'welcome#index'
|
52
|
-
|
53
|
-
# See how all your routes lay out with "rake routes"
|
54
|
-
|
55
|
-
# This is a legacy wild controller route that's not recommended for RESTful applications.
|
56
|
-
# Note: This route will make all actions in every controller accessible via GET requests.
|
57
|
-
# match ':controller(/:action(/:id))(.:format)'
|
4
|
+
resources :jobs do
|
5
|
+
resources :builds, only: [:index, :show, :create, :update, :destroy]
|
6
|
+
end
|
58
7
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateBuilds < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :builds do |t|
|
4
|
+
t.boolean :status
|
5
|
+
t.datetime :started_at
|
6
|
+
t.datetime :finished_at
|
7
|
+
t.references :job
|
8
|
+
t.text :output
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
add_index :builds, :job_id
|
13
|
+
end
|
14
|
+
end
|
data/db/schema.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# This file is auto-generated from the current state of the database. Instead
|
3
|
+
# of editing this file, please use the migrations feature of Active Record to
|
4
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
5
|
+
#
|
6
|
+
# Note that this schema.rb definition is the authoritative source for your
|
7
|
+
# database schema. If you need to create the application database on another
|
8
|
+
# system, you should be using db:schema:load, not running all the migrations
|
9
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
|
+
#
|
12
|
+
# It's strongly recommended to check this file into your version control system.
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define(:version => 20130531155155) do
|
15
|
+
|
16
|
+
create_table "builds", :force => true do |t|
|
17
|
+
t.boolean "status"
|
18
|
+
t.datetime "started_at"
|
19
|
+
t.datetime "finished_at"
|
20
|
+
t.integer "job_id"
|
21
|
+
t.text "output"
|
22
|
+
t.datetime "created_at", :null => false
|
23
|
+
t.datetime "updated_at", :null => false
|
24
|
+
end
|
25
|
+
|
26
|
+
add_index "builds", ["job_id"], :name => "index_builds_on_job_id"
|
27
|
+
|
28
|
+
create_table "jobs", :force => true do |t|
|
29
|
+
t.string "name"
|
30
|
+
t.text "config"
|
31
|
+
t.datetime "created_at", :null => false
|
32
|
+
t.datetime "updated_at", :null => false
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/lib/magi/command.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Provides command line interface for Magi.
|
2
|
+
#
|
3
|
+
# Examples
|
4
|
+
#
|
5
|
+
# # Takes ARGV and invokes a job.
|
6
|
+
# Magi::Command.call(ARGV)
|
7
|
+
#
|
8
|
+
# # Invokes "setup" command to set up your database.
|
9
|
+
# Magi::Command.call(["setup"])
|
10
|
+
#
|
11
|
+
# # Invokes "start" command to start redis, rails, and sidekiq processes.
|
12
|
+
# Magi::Command.call(["start"])
|
13
|
+
#
|
14
|
+
module Magi
|
15
|
+
class Command
|
16
|
+
def self.call(*args)
|
17
|
+
new(*args).call
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(argv)
|
21
|
+
@argv = argv
|
22
|
+
end
|
23
|
+
|
24
|
+
def call
|
25
|
+
case name
|
26
|
+
when "setup"
|
27
|
+
setup
|
28
|
+
when "start"
|
29
|
+
start
|
30
|
+
else
|
31
|
+
puts "Usage: magi {setup|start}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def name
|
38
|
+
@argv[0]
|
39
|
+
end
|
40
|
+
|
41
|
+
def setup
|
42
|
+
system("cd #{root_path} && bundle exec rake db:create db:migrate")
|
43
|
+
end
|
44
|
+
|
45
|
+
def start
|
46
|
+
system("cd #{root_path} && bundle exec foreman start")
|
47
|
+
end
|
48
|
+
|
49
|
+
def root_path
|
50
|
+
File.expand_path("../../..", __FILE__)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "tempfile"
|
2
|
+
|
3
|
+
module Magi
|
4
|
+
class Executer
|
5
|
+
def self.execute(*args)
|
6
|
+
new(*args).execute
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(script)
|
10
|
+
@script = script
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute
|
14
|
+
{ status: status, output: output }
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def tempfile
|
20
|
+
@tempfile ||= Tempfile.new("")
|
21
|
+
end
|
22
|
+
|
23
|
+
def status
|
24
|
+
system(@script, out: tempfile, err: tempfile)
|
25
|
+
end
|
26
|
+
|
27
|
+
def output
|
28
|
+
tempfile.tap(&:close).open.read
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Magi
|
2
|
+
class Scheduler
|
3
|
+
CRON_REGEXP = /\A(\d+|\*) (\d+|\*) (\d+|\*) (\d+|\*) (\d+|\*)\s*\z/
|
4
|
+
|
5
|
+
# Takes a schedule as a String.
|
6
|
+
def initialize(schedule)
|
7
|
+
@result, @min, @hour, @day, @month, @wday = *schedule.match(CRON_REGEXP)
|
8
|
+
validate
|
9
|
+
end
|
10
|
+
|
11
|
+
def scheduled?
|
12
|
+
[:min, :hour, :day, :month, :wday].all? do |key|
|
13
|
+
send(key).nil? || send(key) == now.send(key)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def min
|
20
|
+
@min.to_i if @min != "*"
|
21
|
+
end
|
22
|
+
|
23
|
+
def hour
|
24
|
+
@hour.to_i if @hour != "*"
|
25
|
+
end
|
26
|
+
|
27
|
+
def day
|
28
|
+
@day.to_i if @day != "*"
|
29
|
+
end
|
30
|
+
|
31
|
+
def month
|
32
|
+
@month.to_i if @month != "*"
|
33
|
+
end
|
34
|
+
|
35
|
+
def wday
|
36
|
+
@wday.to_i if @wday != "*"
|
37
|
+
end
|
38
|
+
|
39
|
+
def now
|
40
|
+
@now ||= Time.now
|
41
|
+
end
|
42
|
+
|
43
|
+
def validate
|
44
|
+
raise_argument_error unless valid?
|
45
|
+
end
|
46
|
+
|
47
|
+
def valid?
|
48
|
+
!!@result
|
49
|
+
end
|
50
|
+
|
51
|
+
def raise_argument_error
|
52
|
+
raise ArgumentError, "Input must match with #{CRON_REGEXP}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/magi/version.rb
CHANGED
data/lib/magi.rb
CHANGED
data/magi.gemspec
CHANGED
@@ -12,11 +12,39 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.homepage = "https://github.com/r7kamura/magi"
|
13
13
|
spec.license = "MIT"
|
14
14
|
|
15
|
-
spec.files =
|
15
|
+
spec.files = Dir["{app,bin,config,db,lib,public,script,spec}/**/*"]
|
16
|
+
spec.files += %w[
|
17
|
+
Gemfile
|
18
|
+
LICENSE.txt
|
19
|
+
Procfile
|
20
|
+
README.md
|
21
|
+
Rakefile
|
22
|
+
config.ru
|
23
|
+
magi.gemspec
|
24
|
+
]
|
16
25
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
26
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
27
|
spec.require_paths = ["lib"]
|
19
28
|
|
29
|
+
spec.add_dependency "clockwork"
|
30
|
+
spec.add_dependency "coffee-rails", "~> 3.2.1"
|
31
|
+
spec.add_dependency "font-awesome-rails"
|
32
|
+
spec.add_dependency "foreman"
|
33
|
+
spec.add_dependency "jquery-rails"
|
34
|
+
spec.add_dependency "mysql2"
|
35
|
+
spec.add_dependency "quiet_assets"
|
36
|
+
spec.add_dependency "rails", "3.2.13"
|
37
|
+
spec.add_dependency "sass-rails", "~> 3.2.3"
|
38
|
+
spec.add_dependency "sidekiq"
|
39
|
+
spec.add_dependency "slim"
|
40
|
+
spec.add_dependency "uglifier", ">= 1.0.3"
|
20
41
|
spec.add_development_dependency "bundler", "~> 1.3"
|
42
|
+
spec.add_development_dependency "factory_girl_rails"
|
43
|
+
spec.add_development_dependency "pry-rails"
|
21
44
|
spec.add_development_dependency "rake"
|
45
|
+
spec.add_development_dependency "response_code_matchers"
|
46
|
+
spec.add_development_dependency "rspec-json_matcher"
|
47
|
+
spec.add_development_dependency "rspec-rails"
|
48
|
+
spec.add_development_dependency "simplecov"
|
49
|
+
spec.add_development_dependency "thin"
|
22
50
|
end
|
data/script/clock.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Build do
|
4
|
+
let(:build) do
|
5
|
+
FactoryGirl.create(:build, job: job)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:job) do
|
9
|
+
FactoryGirl.create(:job, config: { "script" => "true" })
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#start" do
|
13
|
+
context "with success" do
|
14
|
+
it "starts its job and sets status with true" do
|
15
|
+
build.start
|
16
|
+
build.started_at.should be_present
|
17
|
+
build.finished_at.should be_present
|
18
|
+
build.status.should == true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with failure" do
|
23
|
+
before do
|
24
|
+
build.job.config["script"] = "false"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "starts its job and sets status with false" do
|
28
|
+
build.start
|
29
|
+
build.started_at.should be_present
|
30
|
+
build.finished_at.should be_present
|
31
|
+
build.status.should == false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Job do
|
4
|
+
let(:job) do
|
5
|
+
FactoryGirl.create(:job)
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#start" do
|
9
|
+
context "without script" do
|
10
|
+
it "raises Job::ScriptNotFound" do
|
11
|
+
expect { job.start }.to raise_error(Job::ScriptNotFound)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "with script" do
|
16
|
+
before do
|
17
|
+
job.config["script"] = "true"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "starts its job" do
|
21
|
+
Magi::Executer.should_receive(:execute).with("true")
|
22
|
+
job.start
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#scheduled?" do
|
28
|
+
context "without schedule" do
|
29
|
+
it "returns false" do
|
30
|
+
job.should_not be_scheduled
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "with matched schedule" do
|
35
|
+
before do
|
36
|
+
job.config["schedule"] = "* * * * *"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns true" do
|
40
|
+
job.should be_scheduled
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "without matched schedule" do
|
45
|
+
before do
|
46
|
+
job.config["schedule"] = "0 0 0 0 0"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "returns false" do
|
50
|
+
job.should_not be_scheduled
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Builds" do
|
4
|
+
let(:params) do
|
5
|
+
{}
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:env) do
|
9
|
+
{ "HTTP_ACCEPT" => "application/json" }
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:job) do
|
13
|
+
FactoryGirl.create(:job)
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:build) do
|
17
|
+
job.builds.create(id: 1)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "GET /jobs/:job_id/builds" do
|
21
|
+
before do
|
22
|
+
build
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns builds of the job" do
|
26
|
+
get "/jobs/#{job.id}/builds", params, env
|
27
|
+
response.status.should == 200
|
28
|
+
response.body.should be_json([Hash])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "GET /jobs/:job_id/builds/:id" do
|
33
|
+
it "returns the build" do
|
34
|
+
get "/jobs/#{job.id}/builds/#{build.id}", params, env
|
35
|
+
response.status.should == 200
|
36
|
+
response.body.should be_json(Hash)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "POST /jobs/:job_id/builds" do
|
41
|
+
it "creates a new build and queue it" do
|
42
|
+
post "/jobs/#{job.id}/builds", params, env
|
43
|
+
response.status.should == 201
|
44
|
+
response.body.should be_json(Hash)
|
45
|
+
BuildWorker.jobs.should have(1).queue
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "PUT /jobs/:job_id/builds/:id" do
|
50
|
+
before do
|
51
|
+
params[:build] = { status: true }
|
52
|
+
end
|
53
|
+
|
54
|
+
it "updates the build" do
|
55
|
+
put "/jobs/#{job.id}/builds/#{build.id}", params, env
|
56
|
+
response.status.should == 204
|
57
|
+
build.reload.status.should == true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "DELETE /jobs/:job_id/builds/:id" do
|
62
|
+
it "deletes the build" do
|
63
|
+
delete "/jobs/#{job.id}/builds/#{build.id}", params, env
|
64
|
+
response.status.should == 204
|
65
|
+
Build.should have(0).build
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Jobs" do
|
4
|
+
let(:params) do
|
5
|
+
{}
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:env) do
|
9
|
+
{ "HTTP_ACCEPT" => "application/json" }
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:job) do
|
13
|
+
FactoryGirl.create(:job)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "GET /jobs" do
|
17
|
+
before do
|
18
|
+
job
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns jobs" do
|
22
|
+
get "/jobs", params, env
|
23
|
+
response.status.should == 200
|
24
|
+
response.body.should be_json([Hash])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "GET /jobs/:id" do
|
29
|
+
it "returns the job" do
|
30
|
+
get "/jobs/#{job.id}", params, env
|
31
|
+
response.status.should == 200
|
32
|
+
response.body.should be_json(Hash)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "POST /jobs" do
|
37
|
+
before do
|
38
|
+
params[:job] = { name: "name" }
|
39
|
+
end
|
40
|
+
|
41
|
+
context "with invalid params" do
|
42
|
+
before do
|
43
|
+
params.delete(:job)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns 400" do
|
47
|
+
post "/jobs", params, env
|
48
|
+
response.status.should == 400
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with valid condition" do
|
53
|
+
it "creates a new job" do
|
54
|
+
post "/jobs", params, env
|
55
|
+
response.status.should == 201
|
56
|
+
Job.should have(1).job
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "PUT /jobs/:id" do
|
62
|
+
before do
|
63
|
+
params[:job] = { name: "name" }
|
64
|
+
end
|
65
|
+
|
66
|
+
context "with invalid params" do
|
67
|
+
before do
|
68
|
+
params.delete(:job)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "returns 400" do
|
72
|
+
put "/jobs/#{job.id}", params, env
|
73
|
+
response.status.should == 400
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "with valid condition" do
|
78
|
+
it "updates the job" do
|
79
|
+
put "/jobs/#{job.id}", params, env
|
80
|
+
response.status.should == 204
|
81
|
+
job.reload.name.should == "name"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "DELETE /jobs/:id" do
|
87
|
+
it "deletes the job" do
|
88
|
+
delete "/jobs/#{job.id}", params, env
|
89
|
+
response.status.should == 204
|
90
|
+
Job.should_not be_exist(job.id)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|