<%= name %> |
@@ -21,6 +22,9 @@
|
|
+
+
+ |
<%= turn_around ? "#{turn_around} #{'day'.pluralize(turn_around)}" : 'None' %>
|
diff --git a/app/views/admin/_new_workflow.erb b/app/views/admin/_new_workflow.erb
index 198e9bb1..96252069 100644
--- a/app/views/admin/_new_workflow.erb
+++ b/app/views/admin/_new_workflow.erb
@@ -24,6 +24,11 @@
Reportable
+
diff --git a/app/views/assets/_asset_group.erb b/app/views/assets/_asset_group.erb
index e8a7e172..d9022886 100644
--- a/app/views/assets/_asset_group.erb
+++ b/app/views/assets/_asset_group.erb
@@ -22,11 +22,9 @@
<% else %>
<% if ((asset_field == :identifier) && (!presenter.is_search?)) %>
- <% presenter.action do |action|%>
-
-
-
- <% end %>
+
+
+
<% end %>
<%= asset.send(asset_field) %>
|
diff --git a/app/views/assets/index.erb b/app/views/assets/index.erb
index 2883c395..0d4deb9a 100644
--- a/app/views/assets/index.erb
+++ b/app/views/assets/index.erb
@@ -68,6 +68,7 @@
<% end %>
+ >
<% presenter.action_button do |button_text| %>
diff --git a/config/states.rb b/config/states.rb
new file mode 100644
index 00000000..22ee68e7
--- /dev/null
+++ b/config/states.rb
@@ -0,0 +1,26 @@
+module StateFactory
+ def self.states
+ [
+ {name: 'in_progress'},
+ {name: 'volume_check'},
+ {name: 'quant'},
+ {name: 'completed'},
+ {name: 'report_required'},
+ {name: 'reported'}
+ ]
+ end
+
+ def self.seed
+ State.create!(states)
+ end
+
+ def self.update
+ ActiveRecord::Base.transaction do
+ states.each do |at|
+ State.find_or_initialize_by(name:at[:name]).tap do |s|
+ s.update_attributes(at)
+ end.save!
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/config/workflows.rb b/config/workflows.rb
index a9c5fbfc..051ed9ab 100644
--- a/config/workflows.rb
+++ b/config/workflows.rb
@@ -2,29 +2,29 @@ module WorkflowFactory
def self.workflows
[
- {:name=>'Arrival and issue', :has_comment=>false, :reportable=>false},
- {:name=>'DNA and RNA Extraction Q3', :has_comment=>false, :reportable=>false},
- {:name=>'DNA Extraction Q3', :has_comment=>false, :reportable=>false},
- {:name=>'RNA Extraction Q3', :has_comment=>false, :reportable=>false},
- {:name=>'DNA Extraction BioRobot', :has_comment=>false, :reportable=>false},
- {:name=>'FP lysis', :has_comment=>false, :reportable=>false},
- {:name=>'Human DNA QC', :has_comment=>false, :reportable=>true},
- {:name=>'Model DNA QC', :has_comment=>false, :reportable=>true},
- {:name=>'Viral/Bacterial DNA QC', :has_comment=>false, :reportable=>true},
- {:name=>'RNA QC', :has_comment=>false, :reportable=>true},
- {:name=>'Formatting', :has_comment=>false, :reportable=>false},
- {:name=>'Formatting and 2ndry std QC', :has_comment=>false, :reportable=>false},
- {:name=>'Formatting and CGP 2ndry QC', :has_comment=>false, :reportable=>false},
- {:name=>'Quantification and Normalisation', :has_comment=>false, :reportable=>false},
- {:name=>'Fluidigm STD 192:24', :has_comment=>false, :reportable=>false},
- {:name=>'Fluidigm CGP 96:96', :has_comment=>false, :reportable=>false},
- {:name=>'Storage', :has_comment=>false, :reportable=>false},
- {:name=>'Sequenom prep (Independent)', :has_comment=>false, :reportable=>false},
- {:name=>'Sequenom prep (QC)', :has_comment=>false, :reportable=>false},
- {:name=>'Other', :has_comment=>true, :reportable=>false},
- {:name=>'Volume Check', :has_comment=>false, :reportable=>false},
- {:name=>'Fluidigm DDD 96:96', :has_comment=>false, :reportable=>false},
- {:name=>'DNA extraction QS', :has_comment=>false, :reportable=>false}
+ {name: 'Arrival and issue', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'DNA and RNA Extraction Q3', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'DNA Extraction Q3', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'RNA Extraction Q3', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'DNA Extraction BioRobot', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'FP lysis', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'Human DNA QC', has_comment: false, reportable: true, initial_state_name: 'in_progress' },
+ {name: 'Model DNA QC', has_comment: false, reportable: true, initial_state_name: 'in_progress' },
+ {name: 'Viral/Bacterial DNA QC', has_comment: false, reportable: true, initial_state_name: 'in_progress' },
+ {name: 'RNA QC', has_comment: false, reportable: true, initial_state_name: 'in_progress' },
+ {name: 'Formatting', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'Formatting and 2ndry std QC', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'Formatting and CGP 2ndry QC', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'Quantification and Normalisation', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'Fluidigm STD 192:24', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'Fluidigm CGP 96:96', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'Storage', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'Sequenom prep (Independent)', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'Sequenom prep (QC)', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'Other', has_comment: true, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'Volume Check', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'Fluidigm DDD 96:96', has_comment: false, reportable: false, initial_state_name: 'in_progress' },
+ {name: 'DNA extraction QS', has_comment: false, reportable: false, initial_state_name: 'in_progress' }
]
end
diff --git a/db/migrate/20170302110500_create_state_table.rb b/db/migrate/20170302110500_create_state_table.rb
new file mode 100644
index 00000000..410763dd
--- /dev/null
+++ b/db/migrate/20170302110500_create_state_table.rb
@@ -0,0 +1,9 @@
+class CreateStateTable < ActiveRecord::Migration
+ def change
+ create_table(:states) do |t|
+ # id
+ t.string :name, null: false
+ t.timestamps
+ end
+ end
+end
\ No newline at end of file
diff --git a/db/migrate/20170303130800_create_event_table.rb b/db/migrate/20170303130800_create_event_table.rb
new file mode 100644
index 00000000..22384ae6
--- /dev/null
+++ b/db/migrate/20170303130800_create_event_table.rb
@@ -0,0 +1,10 @@
+class CreateEventTable < ActiveRecord::Migration
+ def change
+ create_table(:events) do |t|
+ # id
+ t.references :asset, null: false
+ t.references :state, null: false
+ t.timestamps
+ end
+ end
+end
\ No newline at end of file
diff --git a/db/migrate/20170305144300_add_initial_state_to_workflows.rb b/db/migrate/20170305144300_add_initial_state_to_workflows.rb
new file mode 100644
index 00000000..d189f19b
--- /dev/null
+++ b/db/migrate/20170305144300_add_initial_state_to_workflows.rb
@@ -0,0 +1,6 @@
+class AddInitialStateToWorkflows < ActiveRecord::Migration
+ def change
+ add_reference :workflows, :initial_state
+ add_foreign_key :workflows, :states, column: :initial_state_id
+ end
+end
\ No newline at end of file
diff --git a/db/migrate/20170306102500_update_states_and_workflows.rb b/db/migrate/20170306102500_update_states_and_workflows.rb
new file mode 100644
index 00000000..6db1c7a8
--- /dev/null
+++ b/db/migrate/20170306102500_update_states_and_workflows.rb
@@ -0,0 +1,12 @@
+class UpdateStatesAndWorkflows < ActiveRecord::Migration
+ def change
+ ActiveRecord::Base.transaction do
+ require './config/states'
+ StateFactory.update
+
+ Workflow.where(initial_state: nil).each do |workflow|
+ workflow.update_attributes!(initial_state_name: 'in_progress')
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/db/schema.rb b/db/schema.rb
index 4fc599c8..84f6606f 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,12 +11,12 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20150630102003) do
+ActiveRecord::Schema.define(version: 20170306102500) do
create_table "asset_types", force: :cascade do |t|
t.string "name", limit: 255, null: false
t.string "identifier_type", limit: 255, null: false
- t.boolean "has_sample_count", limit: 1, default: false, null: false
+ t.boolean "has_sample_count", default: false, null: false
t.datetime "created_at"
t.datetime "updated_at"
t.string "identifier_data_type", limit: 255, default: "alphanumeric", null: false
@@ -61,17 +61,34 @@
t.string "name", limit: 255, null: false
end
+ create_table "events", force: :cascade do |t|
+ t.integer "asset_id", limit: 4, null: false
+ t.integer "state_id", limit: 4, null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
create_table "pipeline_destinations", force: :cascade do |t|
t.string "name", limit: 255
end
+ create_table "states", force: :cascade do |t|
+ t.string "name", limit: 255, null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
create_table "workflows", force: :cascade do |t|
t.string "name", limit: 255, null: false
- t.boolean "has_comment", limit: 1, default: false, null: false
+ t.boolean "has_comment", default: false, null: false
t.datetime "created_at"
t.datetime "updated_at"
- t.boolean "reportable", limit: 1, default: false, null: false
+ t.boolean "reportable", default: false, null: false
t.integer "turn_around_days", limit: 4
+ t.integer "initial_state_id", limit: 4
end
+ add_index "workflows", ["initial_state_id"], name: "fk_rails_e3fad0d986", using: :btree
+
+ add_foreign_key "workflows", "states", column: "initial_state_id"
end
diff --git a/db/seeds.rb b/db/seeds.rb
index 42c61343..a70cc721 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -1,7 +1,9 @@
require './config/asset_types'
+require './config/states'
require './config/workflows'
require './config/pipeline_destinations'
AssetTypeFactory.seed
-WorkflowFactory.seed
PipelineDestinationFactory.seed
+StateFactory.seed
+WorkflowFactory.seed
diff --git a/lib/state_scoping.rb b/lib/state_scoping.rb
deleted file mode 100644
index b47ff3a8..00000000
--- a/lib/state_scoping.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-module StateScoping
- def add_state(state,scope)
- states[state] = scope
- end
-
- def states
- @states ||= Hash.new(:none)
- end
-
- def scope_for(state)
- send(states[state])
- end
-
- def valid_state(state)
- states[:state] != :none
- end
-end
diff --git a/lib/tasks/update_old_assets_and_workflows.rb b/lib/tasks/update_old_assets_and_workflows.rb
new file mode 100644
index 00000000..3cc3ed12
--- /dev/null
+++ b/lib/tasks/update_old_assets_and_workflows.rb
@@ -0,0 +1,47 @@
+require "./app"
+
+namespace :old do
+ task :update do
+
+ def update_in_progress_assets
+ Asset.in_progress.find_each do |asset|
+ if asset.events.empty?
+ asset.events.create!(state_name: 'in_progress', created_at: asset.begun_at)
+ end
+ end
+ end
+
+ def update_completed_assets
+ Asset.completed.find_each do |asset|
+ if asset.events.empty?
+ asset.events.create!(state_name: 'in_progress', created_at: asset.begun_at)
+ asset.events.create!(state_name: 'completed', created_at: asset.completed_at)
+ end
+ end
+ end
+
+ def update_report_required_assets
+ Asset.report_required.find_each do |asset|
+ asset.events.create!(state_name: 'report_required', created_at: asset.completed_at)
+ end
+ end
+
+ def update_reported_assets
+ Asset.reported.find_each do |asset|
+ asset.events.create!(state_name: 'report_required', created_at: asset.completed_at)
+ asset.events.create!(state_name: 'reported', created_at: asset.reported_at)
+ end
+ end
+
+ puts "Updating in_progress assets"
+ update_in_progress_assets
+ puts "Updating completed assets"
+ update_completed_assets
+ puts "Updating report_required assets"
+ update_report_required_assets
+ puts "Updating reported assets"
+ update_reported_assets
+
+ end
+end
+
diff --git a/public/images/.gitignore b/public/images/.gitignore
new file mode 100644
index 00000000..e69de29b
diff --git a/public/javascripts/.gitignore b/public/javascripts/.gitignore
new file mode 100644
index 00000000..e69de29b
diff --git a/public/stylesheets/.gitignore b/public/stylesheets/.gitignore
new file mode 100644
index 00000000..e69de29b
diff --git a/spec/controllers/assets_controller_spec.rb b/spec/controllers/assets_controller_spec.rb
index 8a025f14..7c34c9ac 100644
--- a/spec/controllers/assets_controller_spec.rb
+++ b/spec/controllers/assets_controller_spec.rb
@@ -4,7 +4,7 @@
describe AssetsController do
let(:mock_asset) {
- double('asset',identifier:'fake',asset_type:double('asset_type',name:'type'))
+ double('asset', identifier:'fake', current_state: 'volume_check', asset_type:double('asset_type',name:'type'))
}
let(:searchless) { double('scope').tap {|s| s.should_receive(:with_identifier).with(nil).and_return([mock_asset]) }}
@@ -13,20 +13,20 @@
let(:request) { AssetsController.new(params).get_index }
let(:params) { {} }
- it "should look up all in progress assets" do
- Asset.should_receive(:in_progress).and_return(searchless)
+ it "state should be nil by default" do
+ Asset.should_receive(:in_state).with(nil).and_return(searchless)
request
end
it "should return an assets index presenter" do
- Asset.stub(:in_progress).and_return(searchless)
+ Asset.stub(:in_state).and_return(searchless)
Presenter::AssetPresenter::Index.should_receive(:new).and_return('presenter')
request.should eq('presenter')
end
it "should pass a nil search parameter and assets to the presenter" do
- Asset.stub(:in_progress).and_return(searchless)
- Presenter::AssetPresenter::Index.should_receive(:new).with([mock_asset],nil,'in_progress')
+ Asset.stub(:in_state).and_return(searchless)
+ Presenter::AssetPresenter::Index.should_receive(:new).with([mock_asset],nil,nil)
request
end
@@ -37,7 +37,9 @@
# We'll shift to the join
let(:request) { AssetsController.new(params).get_index }
- let(:params) { {identifier:'Test',state:'all'} }
+ let!(:state_name) { 'volume_check' }
+ let(:params) { {identifier:'Test',state: state_name} }
+ let(:state) { create :state, name: state_name}
it "should look up all assets with an identifier" do
Asset.should_receive(:with_identifier).with('Test').and_return([mock_asset])
@@ -52,7 +54,7 @@
it "should pass a search parameter and assets to the presenter" do
Asset.stub(:with_identifier).and_return([mock_asset])
- Presenter::AssetPresenter::Index.should_receive(:new).with([mock_asset],"identifier matches 'Test'",'all')
+ Presenter::AssetPresenter::Index.should_receive(:new).with([mock_asset], "identifier matches 'Test'", state)
request
end
@@ -63,10 +65,11 @@
# We'll shift to the join
let(:request) { AssetsController.new(params).get_index }
- let(:params) { {:state=>'report_required'} }
+ let(:params) { { state: 'report_required'} }
+ let!(:state) { create :state, name: 'report_required' }
it "should look up all in report_required assets" do
- Asset.should_receive(:in_state).with('report_required').and_return(searchless)
+ Asset.should_receive(:in_state).with(state).and_return(searchless)
request
end
@@ -78,7 +81,7 @@
it "should pass a nil search parameter and assets to the presenter" do
Asset.stub(:in_state).and_return(searchless)
- Presenter::AssetPresenter::Index.should_receive(:new).with([mock_asset],nil,'report_required')
+ Presenter::AssetPresenter::Index.should_receive(:new).with([mock_asset], nil, state)
request
end
@@ -97,70 +100,30 @@
end
end
- context "with complete" do
- let(:params) { {:complete=>{1=>1,2=>1,3=>1}} }
- let(:time) { DateTime.parse('01-02-2012 13:15') }
- let(:mock_asset) {
- double('asset',identifier:'fake',asset_type:double('asset_type',name:'type'))
- }
-
- it "should pass the assets and the current time to the asset completer" do
- DateTime.stub(:now).and_return { time }
-
- Asset.should_receive(:find).with([1,2,3]).and_return([mock_asset])
- Asset::Completer.should_receive(:create!).with(
- assets: [mock_asset],
- time: time
- )
- request
- end
- it "should return a result object with accurate information" do
- Asset.should_receive(:find).with([1,2,3]).and_return([mock_asset])
- Asset::Completer.stub(:create!).and_return(double('mock_completer',state:'success',message:'Your stuff worked'))
- result = request
- result.state.should eq('success')
- result.message.should eq('Your stuff worked')
- end
- end
-
- context "with report" do
- let(:params) { {:report=>{1=>1,2=>1,3=>1}} }
- let(:time) { DateTime.parse('01-02-2012 13:15') }
+ context "with update" do
+ let(:params) { {:assets=>{1=>1,2=>1,3=>1}, action: 'action'} }
let(:mock_asset) {
double('asset',identifier:'fake',asset_type:double('asset_type',name:'type'))
}
- it "should pass the assets and the current time to the asset reporter" do
+ it "should pass the assets and the current time to the asset updater" do
DateTime.stub(:now).and_return { time }
Asset.should_receive(:find).with([1,2,3]).and_return([mock_asset])
- Asset::Reporter.should_receive(:create!).with(
+ Asset::Updater.should_receive(:create!).with(
assets: [mock_asset],
- time: time
+ action: 'action'
)
request
end
it "should return a result object with accurate information" do
Asset.should_receive(:find).with([1,2,3]).and_return([mock_asset])
- Asset::Reporter.stub(:create!).and_return(double('mock_completer',state:'success',message:'Your stuff worked'))
+ Asset::Updater.stub(:create!).and_return(double('mock_updater',state:'success',message:'Your stuff worked'))
result = request
result.state.should eq('success')
result.message.should eq('Your stuff worked')
end
end
-
- context "with both" do
- let(:params) { {:report=>{1=>1,2=>1},:complete=>{3=>1}} }
- let(:time) { DateTime.parse('01-02-2012 13:15') }
- let(:mock_asset) {
- double('asset',identifier:'fake',asset_type:double('asset_type',name:'type'))
- }
-
- it "should reject the request" do
- # We shouldn't actually have anyone trying to do this through the interface
- expect { request }.to raise_error(Controller::ParameterError,'You cannot complete and report assets at the same time')
- end
- end
end
context "show" do
@@ -175,6 +138,4 @@
end
end
-
-
end
diff --git a/spec/controllers/batches_controller_spec.rb b/spec/controllers/batches_controller_spec.rb
index 29716059..a2ebd895 100644
--- a/spec/controllers/batches_controller_spec.rb
+++ b/spec/controllers/batches_controller_spec.rb
@@ -92,10 +92,11 @@
end
context "with an existing cost code" do
- let(:params) { {:workflow_id=>3,:asset_type_id=>3,:study=>'test', :cost_code => 'S12345', :assets=>{
- 1=>{identifier:'a',sample_count:1},
- 2=>{identifier:'b',sample_count:1}
- }, :comment => 'comment' } }
+ let!(:cost_code) { create :cost_code }
+ let(:params) { { workflow_id: 3, asset_type_id: 3, study: 'test', cost_code: cost_code.name, assets: {
+ 1=>{ identifier:'a', sample_count:1 },
+ 2=>{ identifier:'b', sample_count:1 }
+ }, comment: 'comment' } }
it "should reuse the cost code without creating a new one" do
mocked_lookups
CostCode.all.length.should eq(1)
@@ -104,7 +105,7 @@
study:'test',
workflow:'wf',
pipeline_destination: nil,
- cost_code: CostCode.new({ :id => 1, :name => "S12345"}),
+ cost_code: CostCode.new({ id: cost_code.id, name: cost_code.name}),
asset_type:'at',
begun_at: nil,
assets:[
diff --git a/spec/controllers/workflows_controller_spec.rb b/spec/controllers/workflows_controller_spec.rb
index 749d0659..b2f8afad 100644
--- a/spec/controllers/workflows_controller_spec.rb
+++ b/spec/controllers/workflows_controller_spec.rb
@@ -47,9 +47,10 @@
context "with full parameters" do
let(:params) { {
- :name => 'Test',
- :hasComment => true,
- :turn_around_days => "30"
+ name: 'Test',
+ hasComment: true,
+ initial_state_name: 'in_progress',
+ turn_around_days: "30"
} }
@@ -62,6 +63,7 @@
name: 'Test',
has_comment: true,
reportable: false,
+ initial_state_name: 'in_progress',
turn_around_days: "30"
)
@@ -88,7 +90,7 @@
context "with full parameters" do
- let(:params) { {:workflow_id=>3,:name=>'New Name',hasComment:true,turn_around_days:'30' } }
+ let(:params) { {workflow_id: 3, name: 'New Name', hasComment:true, turn_around_days:'30', initial_state_name: 'in_progress' } }
it "should pass the options to a workflow updater" do
mocked_lookups
@@ -97,6 +99,7 @@
name: 'New Name',
has_comment: true,
reportable: false,
+ initial_state_name: 'in_progress',
turn_around_days: 30
)
request
diff --git a/spec/factories/asset_factories.rb b/spec/factories/asset_factories.rb
new file mode 100644
index 00000000..0c97b4af
--- /dev/null
+++ b/spec/factories/asset_factories.rb
@@ -0,0 +1,19 @@
+FactoryGirl.define do
+
+ sequence :asset_identifier do |n|
+ "Asset #{n}"
+ end
+
+ sequence :asset_study do |n|
+ "Study#{n}"
+ end
+
+ factory :asset do
+ identifier { generate :asset_identifier }
+ study { generate :asset_study }
+ workflow
+ batch
+ asset_type
+ end
+
+end
\ No newline at end of file
diff --git a/spec/factories/asset_type_factories.rb b/spec/factories/asset_type_factories.rb
new file mode 100644
index 00000000..f28cf426
--- /dev/null
+++ b/spec/factories/asset_type_factories.rb
@@ -0,0 +1,20 @@
+FactoryGirl.define do
+
+ sequence :asset_type_name do |n|
+ "Asset type #{n}"
+ end
+
+ sequence :asset_type_identifier do |n|
+ "Identifier #{n}"
+ end
+
+ factory :asset_type do
+ name { generate :asset_type_name }
+ identifier_type { generate :asset_type_identifier }
+
+ factory :asset_type_has_sample_count do
+ has_sample_count true
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/spec/factories/batch_factories.rb b/spec/factories/batch_factories.rb
new file mode 100644
index 00000000..b84a7df9
--- /dev/null
+++ b/spec/factories/batch_factories.rb
@@ -0,0 +1,6 @@
+FactoryGirl.define do
+
+ factory :batch do
+ end
+
+end
\ No newline at end of file
diff --git a/spec/factories/cost_code_factories.rb b/spec/factories/cost_code_factories.rb
new file mode 100644
index 00000000..cd7b0ffd
--- /dev/null
+++ b/spec/factories/cost_code_factories.rb
@@ -0,0 +1,11 @@
+FactoryGirl.define do
+
+ sequence :cost_code_name do |n|
+ "A#{n}"
+ end
+
+ factory :cost_code do
+ name { generate :cost_code_name }
+ end
+
+end
\ No newline at end of file
diff --git a/spec/factories/event_factories.rb b/spec/factories/event_factories.rb
new file mode 100644
index 00000000..764b54ba
--- /dev/null
+++ b/spec/factories/event_factories.rb
@@ -0,0 +1,8 @@
+FactoryGirl.define do
+
+ factory :event do
+ asset
+ state
+ end
+
+end
\ No newline at end of file
diff --git a/spec/factories/pipeline_destination_factories.rb b/spec/factories/pipeline_destination_factories.rb
new file mode 100644
index 00000000..796b97e8
--- /dev/null
+++ b/spec/factories/pipeline_destination_factories.rb
@@ -0,0 +1,11 @@
+FactoryGirl.define do
+
+ sequence :pipeline_destination_name do |n|
+ "Pipeline destination #{n}"
+ end
+
+ factory :pipeline_destination do
+ name { generate :pipeline_destination_name }
+ end
+
+end
\ No newline at end of file
diff --git a/spec/factories/state_factories.rb b/spec/factories/state_factories.rb
new file mode 100644
index 00000000..23e3fea3
--- /dev/null
+++ b/spec/factories/state_factories.rb
@@ -0,0 +1,12 @@
+FactoryGirl.define do
+
+ sequence :state_name do |n|
+ "State #{n}"
+ end
+
+ factory :state do
+ name { generate :state_name }
+ initialize_with { State.find_or_create_by(name: name) }
+ end
+
+end
\ No newline at end of file
diff --git a/spec/factories/workflow_factories.rb b/spec/factories/workflow_factories.rb
new file mode 100644
index 00000000..119a0746
--- /dev/null
+++ b/spec/factories/workflow_factories.rb
@@ -0,0 +1,30 @@
+FactoryGirl.define do
+
+ sequence :workflow_name do |n|
+ "Workflow #{n}"
+ end
+
+ factory :workflow do
+ name { generate :workflow_name }
+ association :initial_state, factory: :state, name: 'in_progress'
+
+ trait :has_comment do
+ has_comment true
+ end
+
+ trait :reportable do
+ reportable true
+ end
+
+ factory :workflow_reportable, traits: [:reportable]
+ factory :workflow_with_comment, traits: [:has_comment]
+
+ factory :multi_team_workflow do
+
+ association :initial_state, factory: :state, name: 'volume_check'
+ factory :multi_team_workflow_reportable, traits: [:reportable]
+
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/spec/features/can_create_workflow_spec.rb b/spec/features/can_create_workflow_spec.rb
new file mode 100644
index 00000000..9827436a
--- /dev/null
+++ b/spec/features/can_create_workflow_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+feature 'can create workflow', js: true do
+
+ scenario 'can create workflow' do
+ create :state, name: 'in_progress'
+ visit '/'
+ click_on 'Admin'
+ find("a", text: "Create a new workflow").click
+
+ within("#add-workflow-modal") do
+ fill_in 'Name', with: 'New workflow'
+ # find('#hasComment', visible: :all).trigger('click')
+ # find('#reportable', visible: :all).trigger('click')
+ # find('#multi_team_quant_essential', visible: :all).trigger('click')
+ find("button", text: "Create").click
+ end
+ expect(page).to have_content("The workflow was created.")
+ expect(Workflow.count).to eq 1
+ end
+
+end
\ No newline at end of file
diff --git a/spec/features/create_complete_and_report_asset_standard_flow_spec.rb b/spec/features/create_complete_and_report_asset_standard_flow_spec.rb
new file mode 100644
index 00000000..85090867
--- /dev/null
+++ b/spec/features/create_complete_and_report_asset_standard_flow_spec.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+feature 'create complete and report assets within standard flow', js: true do
+
+ let!(:asset_type) { create(:asset_type, name: 'Tube', identifier_type: 'ID') }
+ let!(:workflow1) { create(:workflow, name: 'Workflow') }
+ let!(:workflow2) { create(:workflow_reportable, name: 'Reportable workflow') }
+ let!(:in_progress) { create :state, name: 'in_progress' }
+ let!(:volume_check) { create :state, name: 'volume_check' }
+ let!(:quant) { create :state, name: 'quant' }
+ let!(:report_required) { create :state, name: 'report_required' }
+ let!(:completed) { create :state, name: 'completed' }
+ let!(:reported) { create :state, name: 'reported' }
+
+ scenario 'can create and complete a non-reportable asset' do
+ visit '/'
+ click_link 'New Batch'
+ click_on 'Tube'
+ click_on 'Append to batch'
+ expect(page).to have_content "The entry can't be created as the form contains some errors."
+ within("div#tube-template") do
+ fill_in 'identifier', with: 123
+ end
+ click_on 'Append to batch'
+ expect(page).to have_content "Asset added to the batch"
+ fill_in 'Study', with: 'STDY'
+ select('Workflow', from: 'Workflow')
+ click_on 'Save'
+ expect(page).to have_content "The batch was created."
+ click_on 'In Progress'
+ expect(page).to have_selector('table tr', count: 2)
+ check 'assets[1]'
+ click_on 'Completed selected'
+ expect(page).to have_content "In progress is done for 123"
+ expect(page).not_to have_selector('table tr')
+ click_on 'Volume check'
+ expect(page).not_to have_selector('table tr')
+ click_on 'Quant'
+ expect(page).not_to have_selector('table tr')
+ click_on 'Report Required'
+ expect(page).not_to have_selector('table tr')
+ end
+
+ scenario 'can create, complete and report a reportable asset' do
+ visit '/'
+ click_link 'New Batch'
+ click_on 'Tube'
+ within("div#tube-template") do
+ fill_in 'identifier', with: 123
+ end
+ click_on 'Append to batch'
+ expect(page).to have_content "Asset added to the batch"
+ within("div#tube-template") do
+ fill_in 'identifier', with: 456
+ end
+ click_on 'Append to batch'
+ within("div#tube-template") do
+ fill_in 'identifier', with: 789
+ end
+ click_on 'Append to batch'
+ expect(page).to have_content "Asset added to the batch"
+ fill_in 'Study', with: 'STDY'
+ select('Reportable workflow', from: 'Workflow')
+ click_on 'Save'
+ expect(page).to have_content "The batch was created."
+ click_on 'In Progress'
+ expect(page).to have_selector('table tr', count: 4)
+ check 'assets[2]'
+ click_on 'Completed selected'
+ expect(page).to have_content "In progress is done for 456"
+ expect(page).to have_selector('table tr', count: 3)
+ click_on 'Volume check'
+ expect(page).not_to have_selector('table tr')
+ click_on 'Quant'
+ expect(page).not_to have_selector('table tr')
+ click_on 'Report Required'
+ expect(page).to have_selector('table tr', count: 2)
+ check 'assets[2]'
+ click_on 'Reported selected'
+ expect(page).to have_content "Report required is done for 456"
+ end
+
+end
\ No newline at end of file
diff --git a/spec/features/create_complete_and_report_assets_multiteam_flow_spec.rb b/spec/features/create_complete_and_report_assets_multiteam_flow_spec.rb
new file mode 100644
index 00000000..7649aa48
--- /dev/null
+++ b/spec/features/create_complete_and_report_assets_multiteam_flow_spec.rb
@@ -0,0 +1,95 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+feature 'create complete and report assets within multi team flow', js: true do
+
+ let!(:asset_type) { create(:asset_type, name: 'Tube', identifier_type: 'ID') }
+ let!(:workflow1) { create(:multi_team_workflow, name: 'Multi team workflow') }
+ let!(:workflow2) { create(:multi_team_workflow_reportable, name: 'Reportable multi team workflow') }
+ let!(:in_progress) { create :state, name: 'in_progress' }
+ let!(:volume_check) { create :state, name: 'volume_check' }
+ let!(:quant) { create :state, name: 'quant' }
+ let!(:report_required) { create :state, name: 'report_required' }
+ let!(:completed) { create :state, name: 'completed' }
+ let!(:reported) { create :state, name: 'reported' }
+
+ scenario 'can create and complete a non-reportable asset' do
+ visit '/'
+ click_link 'New Batch'
+ click_on 'Tube'
+ within("div#tube-template") do
+ fill_in 'identifier', with: 123
+ end
+ click_on 'Append to batch'
+ within("div#tube-template") do
+ fill_in 'identifier', with: 456
+ end
+ click_on 'Append to batch'
+ expect(page).to have_content "Asset added to the batch"
+ fill_in 'Study', with: 'STDY'
+ select('Multi team workflow', from: 'Workflow')
+ click_on 'Save'
+ expect(page).to have_content "The batch was created."
+ click_on 'In Progress'
+ expect(page).not_to have_selector('table tr')
+ click_on 'Volume check'
+ expect(page).to have_selector('table tr', count: 3)
+ check 'assets[1]'
+ click_on 'Volume checked selected'
+ expect(page).to have_content "Volume check is done for 123"
+ expect(page).to have_selector('table tr', count: 2)
+ click_on 'Quant'
+ expect(page).to have_selector('table tr', count: 2)
+ check 'assets[1]'
+ click_on 'Completed selected'
+ expect(page).to have_content "Quant is done for 123"
+ expect(page).not_to have_selector('table tr')
+ click_on 'Report Required'
+ expect(page).not_to have_selector('table tr')
+ end
+
+ scenario 'can create, complete and report a reportable asset' do
+ visit '/'
+ click_link 'New Batch'
+ click_on 'Tube'
+ within("div#tube-template") do
+ fill_in 'identifier', with: 123
+ end
+ click_on 'Append to batch'
+ within("div#tube-template") do
+ fill_in 'identifier', with: 456
+ end
+ click_on 'Append to batch'
+ within("div#tube-template") do
+ fill_in 'identifier', with: 789
+ end
+ click_on 'Append to batch'
+ expect(page).to have_content "Asset added to the batch"
+ fill_in 'Study', with: 'STDY'
+ select('Reportable multi team workflow', from: 'Workflow')
+ click_on 'Save'
+ expect(page).to have_content "The batch was created."
+ click_on 'In Progress'
+ expect(page).not_to have_selector('table tr')
+ click_on 'Volume check'
+ expect(page).to have_selector('table tr', count: 4)
+ check 'assets[1]'
+ check 'assets[3]'
+ click_on 'Volume checked selected'
+ expect(page).to have_content "Volume check is done for 123 and 789"
+ expect(page).to have_selector('table tr', count: 2)
+ click_on 'Quant'
+ expect(page).to have_selector('table tr', count: 3)
+ check 'assets[3]'
+ click_on 'Completed selected'
+ expect(page).to have_content "Quant is done for 789"
+ expect(page).to have_selector('table tr', count: 2)
+ click_on 'Report Required'
+ expect(page).to have_selector('table tr', count: 2)
+ check 'assets[3]'
+ click_on 'Reported selected'
+ expect(page).to have_content "Report required is done for 789"
+ expect(page).not_to have_selector('table tr')
+ end
+
+end
\ No newline at end of file
diff --git a/spec/models/asset_spec.rb b/spec/models/asset_spec.rb
index da83ea39..626b3798 100644
--- a/spec/models/asset_spec.rb
+++ b/spec/models/asset_spec.rb
@@ -1,26 +1,29 @@
require 'spec_helper'
require './app/models/asset'
+require './app/models/event'
describe Asset do
context "with valid parameters" do
- let(:asset_type) { AssetType.new(:identifier_type=>'example',:name=>'test') }
- let(:identifier) { 'name' }
- let(:study) { 'study_A'}
- let(:batch) { Batch.new }
- let(:workflow) { Workflow.new }
- let(:comment) { Comment.new }
+ let!(:asset_type) { AssetType.new(:identifier_type=>'example',:name=>'test') }
+ let!(:identifier) { 'name' }
+ let!(:study) { 'study_A'}
+ let!(:batch) { Batch.new }
+ let!(:workflow) { create :workflow }
+ let!(:comment) { Comment.new }
+ let!(:state) { create :state, name: 'in_progress'}
+ let!(:completed) { create :state, name: 'completed'}
+ let!(:asset) { Asset.new(
+ identifier: identifier,
+ batch: batch,
+ study: study,
+ asset_type: asset_type,
+ workflow: workflow,
+ comment: comment) }
it 'can be created' do
- asset = Asset.new(
- :identifier => identifier,
- :batch => batch,
- :study => study,
- :asset_type => asset_type,
- :workflow => workflow,
- :comment => comment
- )
+
expect(asset).to have(0).errors_on(:identifier)
expect(asset).to have(0).errors_on(:batch)
expect(asset).to have(0).errors_on(:study)
@@ -30,27 +33,37 @@
expect(asset).to have(0).errors_on(:begun_at)
- asset.valid?.should eq(true)
+ expect(asset.valid?).to eq(true)
+ expect(asset.save).to eq(true)
- asset.identifier.should eq(identifier)
- asset.batch.should eq(batch)
- asset.asset_type.should eq(asset_type)
- asset.workflow.should eq(workflow)
+ expect(asset.identifier).to eq(identifier)
+ expect(asset.batch).to eq(batch)
+ expect(asset.asset_type).to eq(asset_type)
+ expect(asset.workflow).to eq(workflow)
+ expect(asset.current_state).to eq 'in_progress'
asset.begun_at.should eq(asset.created_at)
end
it 'should delegate identifier_type to asset_type' do
-
- asset = Asset.new(
- :identifier=>identifier,
- :batch=>batch,
- :asset_type=>asset_type,
- :workflow=>workflow
- )
asset.identifier_type.should eq('example')
end
+ it 'can have events' do
+ expect(asset.events.count).to eq 0
+ asset.save
+ expect(asset.events.count).to eq 1
+ create_list(:event, 3, asset: asset)
+ expect(asset.events.count).to eq 4
+ end
+
+ it 'should know if it is completed' do
+ asset.save
+ expect(asset.completed?).to be_false
+ create :event, asset: asset, state: completed
+ expect(asset.completed?).to be_true
+ end
+
context "with a defined begun time" do
@@ -118,10 +131,12 @@
context 'scopes' do
- let(:reportable_workflow) { Workflow.create!(name:'reportable', reportable:true ) }
- let(:nonreportable_workflow) { Workflow.create!(name:'nonreportable', reportable:false) }
+ let!(:state) { create :state, name: 'in_progress' }
+ let!(:reportable_workflow) { Workflow.create!(name:'reportable', reportable:true, initial_state_name: 'in_progress' ) }
+ let!(:nonreportable_workflow) { Workflow.create!(name:'nonreportable', reportable:false, initial_state_name: 'in_progress' ) }
+ let!(:in_progress) { create :state, name: 'in_progress' }
- let(:basics) { {identifier:'one',asset_type_id:1,batch_id:1,workflow_id:1} }
+ let(:basics) { { identifier:'one', asset_type_id:1, batch_id:1, workflow_id: reportable_workflow.id } }
let(:completed) { basics.merge(completed_at:Time.now) }
let(:created_last) { basics.merge(begun_at:Time.at(1000)) }
let(:created_first) { basics.merge(begun_at:Time.at(10)) }
@@ -135,7 +150,6 @@
incomplete = Asset.new(basics)
complete = Asset.new(completed)
-
incomplete.save!(validate: false)
complete.save!(validate: false)
@@ -143,23 +157,8 @@
Asset.in_progress.should_not include(complete)
end
- it 'should scope all' do
- Asset.in_state('all').should eq(Asset.all)
- end
-
- it 'should scope report_required' do
- Asset.should_receive(:report_required).and_return('valid')
- Asset.in_state('report_required').should eq('valid')
- end
-
- it 'should scope in_progress' do
- Asset.should_receive(:in_progress).and_return('valid')
- Asset.in_state('in_progress').should eq('valid')
- end
-
- it 'should scope invalid_states' do
- Asset.should_receive(:none).and_return('nothing')
- Asset.in_state('invalid_state').should eq('nothing')
+ it 'should return all if scope nil' do
+ expect(Asset.in_state(nil)).to eq(Asset.all)
end
it 'reporting_required lists appropriate assets' do
@@ -229,4 +228,34 @@
end
end
+ context 'state machine' do
+ let!(:state1) { create :state, name: 'in_progress' }
+ let!(:state2) { create :state, name: 'completed' }
+ let!(:state3) { create :state, name: 'report_required' }
+ let(:asset) { create :asset }
+ let(:reportable_asset) { create :asset, workflow: (create :workflow_reportable) }
+
+ it 'should know the current state' do
+ expect(asset.in_progress?).to be_true
+ expect(asset.reported?).to be_false
+ end
+
+ it 'should create the right events' do
+ expect(asset.events.count).to eq 1
+ asset.complete
+ expect(asset.events.count).to eq 2
+ expect(asset.completed?).to be_true
+
+ expect(reportable_asset.events.count).to eq 1
+ reportable_asset.complete
+ expect(reportable_asset.events.count).to eq 3
+ expect(reportable_asset.report_required?).to be_true
+ end
+
+ it 'should not perform actions that are not valid' do
+ expect { asset.perform_action('complete') }.to_not raise_error
+ expect { asset.perform_action('some_action') }.to raise_error(StateMachine::StateMachineError)
+ end
+ end
+
end
diff --git a/spec/models/batch_spec.rb b/spec/models/batch_spec.rb
index 0763119b..b76606e9 100644
--- a/spec/models/batch_spec.rb
+++ b/spec/models/batch_spec.rb
@@ -9,15 +9,41 @@
batch.assets.size.should eq(1)
batch.assets.first.identifier.should eq('test')
end
-
+
it 'destroy assets when destroyed' do
batch = Batch.new
batch.assets.new(:identifier=>'test')
batch.assets.new(:identifier=>'test2')
assets = batch.assets
-
+
batch.destroy!
assets.map(&:destroyed?).all?.should eq(true)
end
end
+
+describe Batch::Creator do
+
+ it 'should create the right batch and the right assets' do
+ state = create :state, name: 'in_progress'
+ assets = [{type: "Plate", identifier: "test", sample_count: "25"},
+ {type: "Plate", identifier: "test2", sample_count: "10"},
+ {type: "Plate", identifier: "test3", sample_count: "96"}]
+ workflow = create :workflow
+
+ batch_creator = Batch::Creator.new(
+ study: 'study',
+ assets: assets,
+ asset_type: (create :asset_type_has_sample_count),
+ workflow: workflow,
+ pipeline_destination: (create :pipeline_destination),
+ cost_code: (create :cost_code),
+ comment: 'some comment'
+ )
+ expect(Asset.count).to eq 0
+ batch_creator.do!
+ expect(Asset.count).to eq 3
+ expect(Asset.last.current_state). to eq state.name
+ end
+
+end
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
new file mode 100644
index 00000000..fd779e59
--- /dev/null
+++ b/spec/models/event_spec.rb
@@ -0,0 +1,32 @@
+require 'spec_helper'
+require './app/models/event'
+
+describe Event do
+
+ let(:event) { Event.new }
+ let(:asset) { create :asset }
+ let!(:in_progress) { create :state, name: 'in_progress'}
+
+ it 'should have name' do
+ expect(event.valid?).to be false
+ event.state_name = 'in_progress'
+ event.asset = asset
+ expect(event.valid?).to be true
+ end
+
+ it 'should know the date for particular state' do
+ in_progress_event = Event.create!(state: in_progress, asset: asset)
+ expect(Event.date('reported')).to be_false
+ expect(Event.date('in_progress')).to be_true
+ end
+
+ it 'should know ids for latest events per asset' do
+ report_required = create :state, name: 'report_required'
+ in_progress_event_first_asset = Event.create!(state: in_progress, asset: asset)
+ report_required_event_first_asset = Event.create!(state: report_required, asset: asset)
+ in_progress_event_second_asset = Event.create!(state: report_required, asset: (create :asset))
+ expect(Event.latest_per_asset).to eq [report_required_event_first_asset.id, in_progress_event_second_asset.id]
+ end
+
+
+end
\ No newline at end of file
diff --git a/spec/models/state_spec.rb b/spec/models/state_spec.rb
new file mode 100644
index 00000000..b1d985a7
--- /dev/null
+++ b/spec/models/state_spec.rb
@@ -0,0 +1,19 @@
+require 'spec_helper'
+require './app/models/state'
+
+describe State do
+
+ let(:state) { State.new }
+
+ it 'should have name' do
+ expect(state.valid?).to be false
+ state.name = 'name'
+ expect(state.valid?).to be true
+ end
+
+ it 'should know if it is default' do
+ expect(state.default?).to be_false
+ end
+
+
+end
\ No newline at end of file
diff --git a/spec/models/workflow_spec.rb b/spec/models/workflow_spec.rb
index 278c8379..74465a59 100644
--- a/spec/models/workflow_spec.rb
+++ b/spec/models/workflow_spec.rb
@@ -1,14 +1,19 @@
require 'spec_helper'
+require './app/models/state'
require './app/models/workflow'
+
describe Workflow do
+ let!(:volume_check) { create :state, name: 'volume_check' }
+
context "with valid parameters" do
- let(:test_name) { 'test' }
- let(:has_comment) { true }
+ let!(:test_name) { 'test' }
+ let!(:has_comment) { true }
+ let(:workflow) { Workflow.new(name: test_name, has_comment: has_comment, initial_state_name: 'volume_check') }
it 'can be created' do
- workflow = Workflow.new(:name=>test_name,:has_comment=>has_comment,:turn_around_days=>2)
+ workflow = Workflow.new(:name=>test_name,:has_comment=>has_comment,:turn_around_days=>2, initial_state: volume_check)
workflow.valid?.should eq(true)
expect(workflow).to have(0).errors_on(:name)
expect(workflow).to have(0).errors_on(:has_comment)
@@ -18,12 +23,15 @@
end
it 'has many assets' do
- workflow = Workflow.new(:name=>test_name,:has_comment=>has_comment)
workflow.assets.new(:identifier=>'test')
workflow.assets.size.should eq(1)
workflow.assets.first.identifier.should eq('test')
end
+ it 'should know its initial state' do
+ expect(workflow.initial_state).to eq volume_check
+ end
+
end
context "with invalid parameters" do
@@ -35,7 +43,7 @@
end
it 'requires a unique name' do
- workflow = Workflow.create!(:name=>'test1')
+ workflow = Workflow.create!(:name=>'test1', initial_state: volume_check)
workflow = Workflow.create(:name=>'test1')
expect(workflow).to have(1).errors_on(:name)
workflow.valid?.should eq(false)
@@ -50,3 +58,4 @@
end
end
+
diff --git a/spec/presenters/asset_index_presenter_spec.rb b/spec/presenters/asset_index_presenter_spec.rb
index cbd5fc4a..c259e83c 100644
--- a/spec/presenters/asset_index_presenter_spec.rb
+++ b/spec/presenters/asset_index_presenter_spec.rb
@@ -10,9 +10,8 @@
let(:mock_workflow) { double('mock_wf', name:'Work',has_comment:true)}
let(:asset1) { double('asset_1',identifier:'asset_1',asset_type:mock_type,workflow:mock_workflow,study:'study') }
let(:asset2) { double('asset_2',identifier:'asset_2',asset_type:mock_type2,workflow:mock_workflow,study:'study') }
-
let(:assets) { [asset1,asset2] }
-
+ let!(:state) { create :state, name: 'in_progress'}
let(:presenter) { Presenter::AssetPresenter::Index.new(assets,search,state)}
end
@@ -36,7 +35,6 @@
include_examples "standard behaviour"
let(:search) {"identifier matches 'Type'"}
- let(:state) {'all'}
it "should yield the search parameters on search_parameters" do
expect { |b| presenter.search_parameters(&b) }.to yield_with_args(search)
@@ -54,7 +52,6 @@
include_examples "standard behaviour"
let(:search) {nil}
- let(:state) {'in_progress'}
it "should not yield on search_parameters" do
expect { |b| presenter.search_parameters(&b) }.to yield_successive_args()
@@ -72,27 +69,42 @@
let(:search) {nil}
context 'all' do
- let(:state) {'all'}
+ let(:state) { nil }
- it "should have no actions" do
+ it "should have no action button" do
expect { |b| presenter.action_button(&b) }.not_to yield_control
- expect { |b| presenter.action(&b) }.not_to yield_control
end
end
context 'in_progress' do
- let(:state) {'in_progress'}
+ let(:state) { create :state, name: 'in_progress'}
it "should have complete actions" do
expect { |b| presenter.action_button(&b) }.to yield_with_args('Completed selected')
- expect { |b| presenter.action(&b) }.to yield_with_args('complete')
+ expect(presenter.action).to eq ('complete')
+ end
+ end
+ context 'volume_check' do
+ let(:state) { create :state, name: 'volume_check'}
+
+ it "should have volume_check actions" do
+ expect { |b| presenter.action_button(&b) }.to yield_with_args('Volume checked selected')
+ expect(presenter.action).to eq ('check_volume')
+ end
+ end
+ context 'quant' do
+ let(:state) { create :state, name: 'quant'}
+
+ it "should have quant actions" do
+ expect { |b| presenter.action_button(&b) }.to yield_with_args('Completed selected')
+ expect(presenter.action).to eq ('complete')
end
end
context 'report_required' do
- let(:state) {'report_required'}
+ let(:state) { create :state, name: 'report_required'}
it "should have reporting actions" do
expect { |b| presenter.action_button(&b) }.to yield_with_args('Reported selected')
- expect { |b| presenter.action(&b) }.to yield_with_args('report')
+ expect(presenter.action).to eq ('report')
end
end
end
diff --git a/spec/presenters/shared_presenter_behaviour.rb b/spec/presenters/shared_presenter_behaviour.rb
index 3794f444..84b03872 100644
--- a/spec/presenters/shared_presenter_behaviour.rb
+++ b/spec/presenters/shared_presenter_behaviour.rb
@@ -9,10 +9,11 @@
end
it "should yield each workflow and its comment_requirement in turn for each_workflow" do
- workflow_1 = double("workflow_1", :name=>'wf1', :has_comment=>true, :id=>1, :reportable => true, :turn_around_days=>1 )
- workflow_2 = double("workflow_2", :name=>'wf2', :has_comment=>false, :id=>2, :reportable => false, :turn_around_days=>nil)
+ flow = double("flow", name: 'flow_name')
+ workflow_1 = double("workflow_1", :name=>'wf1', :has_comment=>true, :id=>1, :reportable => true, multi_team_quant_essential: false, :turn_around_days=>1 )
+ workflow_2 = double("workflow_2", :name=>'wf2', :has_comment=>false, :id=>2, :reportable => false, multi_team_quant_essential: false, :turn_around_days=>nil)
Workflow.stub(:all) {[workflow_1,workflow_2]}
- expect { |b| presenter.each_workflow(&b) }.to yield_successive_args(['wf1', true,1, true,1], ['wf2', false,2, false,nil])
+ expect { |b| presenter.each_workflow(&b) }.to yield_successive_args(['wf1', true,1, true, false, 1], ['wf2', false,2, false, false, nil])
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index e69de29b..f4e2a5e9 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -0,0 +1,43 @@
+require './spec/support/active_record'
+require 'database_cleaner'
+require 'factory_girl'
+require 'capybara/rspec'
+require 'capybara/poltergeist'
+require 'sinatra'
+require 'timecop'
+require File.expand_path '../../app.rb', __FILE__
+
+ActiveRecord::Base.logger = nil
+
+Capybara.app = SmWorkflowLims
+
+Capybara.javascript_driver = :poltergeist
+
+RSpec.configure do |config|
+
+ config.include FactoryGirl::Syntax::Methods
+
+ config.before(:suite) do
+ FactoryGirl.find_definitions
+ end
+
+ config.before(:suite) do
+ DatabaseCleaner.clean_with(:truncation)
+ end
+
+ config.before(:each) do
+ DatabaseCleaner.strategy = :transaction
+ end
+
+ config.before(:each, js: true) do
+ DatabaseCleaner.strategy = :truncation
+ end
+
+ config.before(:each) do
+ DatabaseCleaner.start
+ end
+
+ config.after(:each) do
+ DatabaseCleaner.clean
+ end
+end
\ No newline at end of file
diff --git a/spec/unit/asset_completer_spec.rb b/spec/unit/asset_completer_spec.rb
deleted file mode 100644
index 826d2b0c..00000000
--- a/spec/unit/asset_completer_spec.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-require 'spec_helper'
-require './app/models/asset'
-
-describe Asset::Completer do
-
- context "with an array of assets" do
-
- let(:time) { DateTime.parse('01-02-2012 13:15') }
- let(:assets) { [asset1,asset2]}
- let(:asset1) { double(:asset1,identifier:'a') }
- let(:asset2) { double(:asset2,identifier:'b') }
- let(:message) {"a and b were marked as completed."}
-
- it "should flag the assets as completed" do
- asset1.should_receive(:update_attributes!).with(completed_at:time)
- asset2.should_receive(:update_attributes!).with(completed_at:time)
- Asset::Completer.create!(assets:[asset1,asset2],time:time)
- end
-
- it "should have a success state if successful" do
- asset1.should_receive(:update_attributes!).with(completed_at:time)
- asset2.should_receive(:update_attributes!).with(completed_at:time)
- Asset::Completer.create!(assets:[asset1,asset2],time:time).state.should eq('success')
- end
-
- it "should summarise updated assets" do
- asset1.should_receive(:update_attributes!).with(completed_at:time)
- asset2.should_receive(:update_attributes!).with(completed_at:time)
- Asset::Completer.create!(assets:[asset1,asset2],time:time).message.should eq(message)
- end
-
- end
-
-end
diff --git a/spec/unit/asset_reporter_spec.rb b/spec/unit/asset_reporter_spec.rb
deleted file mode 100644
index 3d44258e..00000000
--- a/spec/unit/asset_reporter_spec.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-require 'spec_helper'
-require './app/models/asset'
-
-describe Asset::Reporter do
-
- context "with an array of reportable assets" do
-
- let(:time) { DateTime.parse('01-02-2012 13:15') }
- let(:assets) { [asset1,asset2]}
- let(:workflow) { double(:workflow,name:'test workflow')}
- let(:asset1) { double(:asset1,identifier:'a',reportable?:true,completed?:true,workflow:workflow) }
- let(:asset2) { double(:asset2,identifier:'b',reportable?:true,completed?:true,workflow:workflow) }
- let(:message) {"a and b were marked as reported."}
-
- it "should flag the assets as reported" do
- asset1.should_receive(:update_attributes!).with(reported_at:time)
- asset2.should_receive(:update_attributes!).with(reported_at:time)
- Asset::Reporter.create!(assets:[asset1,asset2],time:time)
- end
-
- it "should have a success state if successful" do
- asset1.should_receive(:update_attributes!).with(reported_at:time)
- asset2.should_receive(:update_attributes!).with(reported_at:time)
- Asset::Reporter.create!(assets:[asset1,asset2],time:time).state.should eq('success')
- end
-
- it "should summarise updated assets" do
- asset1.should_receive(:update_attributes!).with(reported_at:time)
- asset2.should_receive(:update_attributes!).with(reported_at:time)
- Asset::Reporter.create!(assets:[asset1,asset2],time:time).message.should eq(message)
- end
-
- end
-
- context "with an array of unreportable assets" do
-
- let(:time) { DateTime.parse('01-02-2012 13:15') }
- let(:assets) { [asset1,asset2]}
- let(:workflow) { double(:workflow,name:'test workflow')}
- let(:asset1) { double(:asset1,identifier:'a',reportable?:false,completed?:true,workflow:workflow) }
- let(:asset2) { double(:asset2,identifier:'b',reportable?:false,completed?:true,workflow:workflow) }
- let(:message) {"a is in test workflow, which does not need a report.\nb is in test workflow, which does not need a report."}
-
- it "should not flag the assets as reported" do
- asset1.should_not_receive(:update_attributes!)
- asset2.should_not_receive(:update_attributes!)
- Asset::Reporter.create!(assets:[asset1,asset2],time:time)
- end
-
- it "should have a danger state" do
- asset1.should_not_receive(:update_attributes!)
- asset2.should_not_receive(:update_attributes!)
- Asset::Reporter.create!(assets:[asset1,asset2],time:time).state.should eq('danger')
- end
-
- it "should summarise updated assets" do
- asset1.should_not_receive(:update_attributes!)
- asset2.should_not_receive(:update_attributes!)
- Asset::Reporter.create!(assets:[asset1,asset2],time:time).message.should eq(message)
- end
-
- end
-
- context "with an array of uncompletes assets" do
-
- let(:time) { DateTime.parse('01-02-2012 13:15') }
- let(:assets) { [asset1,asset2]}
- let(:workflow) { double(:workflow,name:'test workflow')}
- let(:asset1) { double(:asset1,identifier:'a',reportable?:true,completed?:false,workflow:workflow) }
- let(:asset2) { double(:asset2,identifier:'b',reportable?:true,completed?:false,workflow:workflow) }
- let(:message) {"a can not be reported on before it is completed.\nb can not be reported on before it is completed."}
-
- it "should not flag the assets as reported" do
- asset1.should_not_receive(:update_attributes!)
- asset2.should_not_receive(:update_attributes!)
- Asset::Reporter.create!(assets:[asset1,asset2],time:time)
- end
-
- it "should have a danger state" do
- asset1.should_not_receive(:update_attributes!)
- asset2.should_not_receive(:update_attributes!)
- Asset::Reporter.create!(assets:[asset1,asset2],time:time).state.should eq('danger')
- end
-
- it "should summarise updated assets" do
- asset1.should_not_receive(:update_attributes!)
- asset2.should_not_receive(:update_attributes!)
- Asset::Reporter.create!(assets:[asset1,asset2],time:time).message.should eq(message)
- end
-
- end
-
-end
diff --git a/spec/unit/asset_updater_spec.rb b/spec/unit/asset_updater_spec.rb
new file mode 100644
index 00000000..3b98b650
--- /dev/null
+++ b/spec/unit/asset_updater_spec.rb
@@ -0,0 +1,37 @@
+require 'spec_helper'
+require './app/models/asset'
+
+describe Asset::Updater do
+
+ context "with an array of assets" do
+
+ let(:time) { DateTime.parse('01-02-2012 13:15') }
+ let(:assets) { [asset1,asset2]}
+ let(:asset1) { double(:asset1,identifier:'a', current_state:'in_progress') }
+ let(:asset2) { double(:asset2,identifier:'b', current_state:'in_progress') }
+ let(:message) {"In progress is done for a and b"}
+
+ it "should flag the assets as completed" do
+ asset1.should_receive(:current_state)
+ asset1.should_receive(:perform_action).with('complete')
+ asset2.should_receive(:perform_action).with('complete')
+ Asset::Updater.create!(assets:[asset1,asset2], action:'complete')
+ end
+
+ it "should have a success state if successful" do
+ asset1.should_receive(:current_state)
+ asset1.should_receive(:perform_action).with('report')
+ asset2.should_receive(:perform_action).with('report')
+ Asset::Updater.create!(assets:[asset1,asset2], action: 'report').state.should eq('success')
+ end
+
+ it "should summarise updated assets" do
+ asset1.should_receive(:current_state)
+ asset1.should_receive(:perform_action).with('complete')
+ asset2.should_receive(:perform_action).with('complete')
+ Asset::Updater.create!(assets:[asset1,asset2], action: 'complete').message.should eq(message)
+ end
+
+ end
+
+end
\ No newline at end of file
diff --git a/spec/unit/batch_creator_spec.rb b/spec/unit/batch_creator_spec.rb
index d0ece541..5a093311 100644
--- a/spec/unit/batch_creator_spec.rb
+++ b/spec/unit/batch_creator_spec.rb
@@ -42,10 +42,12 @@
let(:mock_comment) { double('mock_comment') }
let(:asset_association) { double('asset_association')}
+ let!(:state) { create :state, name: 'in_progress' }
+
context "With comments and date" do
let(:workflow) {
- double('mock_workflow',has_comment?:true)
+ create :workflow_with_comment
}
let(:time) { DateTime.parse('01-02-2003 00:00') }
@@ -79,9 +81,7 @@
context "Without comments or date" do
let(:workflow) {
- wf = double('mock_workflow')
- wf.stub(:has_comment?) {false}
- wf
+ create :workflow
}
it "should create the batch and assets" do
@@ -106,6 +106,26 @@
comment:comment
)
end
+
+ it 'should create the right batch and the right assets' do
+ assets = [{type: "Plate", identifier: "test", sample_count: "25"},
+ {type: "Plate", identifier: "test2", sample_count: "10"},
+ {type: "Plate", identifier: "test3", sample_count: "96"}]
+ workflow = create :workflow
+
+ batch_creator = Batch::Creator.new(
+ study: 'study',
+ assets: assets,
+ asset_type: (create :asset_type_has_sample_count),
+ workflow: workflow,
+ pipeline_destination: (create :pipeline_destination),
+ cost_code: (create :cost_code)
+ )
+ expect(Asset.count).to eq 0
+ batch_creator.do!
+ expect(Asset.count).to eq 3
+ expect(Asset.last.current_state). to eq 'in_progress'
+ end
end
end
diff --git a/spec/unit/workflow_updater_spec.rb b/spec/unit/workflow_updater_spec.rb
index e4ab3855..111fcf29 100644
--- a/spec/unit/workflow_updater_spec.rb
+++ b/spec/unit/workflow_updater_spec.rb
@@ -15,6 +15,7 @@
let(:new_has_comment) { true }
let(:new_reportable) { false }
let(:new_turn_around) { 5 }
+ let(:new_multi_team_quant_essential) { false }
let(:mock_workflow) { double('workflow').tap do |wf|
@@ -23,6 +24,7 @@
name: new_name,
has_comment: new_has_comment,
reportable: new_reportable,
+ initial_state_name: 'in_progress',
turn_around_days: new_turn_around
)
@@ -35,6 +37,7 @@
name: new_name,
has_comment: new_has_comment,
reportable: new_reportable,
+ initial_state_name: 'in_progress',
turn_around_days: new_turn_around
)
end