aboutsummaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
authorXinhui2017-06-16 17:58:08 +0200
committerXinhui2017-06-16 17:58:08 +0200
commit641b1458236d2718a76ffaf0c04a5998623276bf (patch)
treedb738af25bcdd7b3b400a0f8db5e6350ef373c51 /spec
parent6886441ce86bcd720b27cdd089567def5b9d771a (diff)
parent9ef3d205aa091d509455b3607d5ecc74431c6196 (diff)
downloadchouette-core-641b1458236d2718a76ffaf0c04a5998623276bf.tar.bz2
Merge branch 'master' into staging
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/devise/cas_sessions_controller_spec.rb27
-rw-r--r--spec/controllers/imports_controller_spec.rb2
-rw-r--r--spec/controllers/route_stop_points_controller_spec.rb4
-rw-r--r--spec/factories/chouette_time_table.rb1
-rw-r--r--spec/factories/chouette_vehicle_journey.rb9
-rw-r--r--spec/factories/clean_ups.rb13
-rw-r--r--spec/features/calendars_spec.rb10
-rw-r--r--spec/features/lines_spec.rb5
-rw-r--r--spec/features/referentials_permissions_spec.rb54
-rw-r--r--spec/features/referentials_spec.rb6
-rw-r--r--spec/features/routes_spec.rb3
-rw-r--r--spec/features/routing_constraint_zones_spec.rb4
-rw-r--r--spec/features/users/connection_spec.rb0
-rw-r--r--spec/features/workbenches_spec.rb2
-rw-r--r--spec/javascripts/time_table/reducers/pagination_spec.js7
-rw-r--r--spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js4
-rw-r--r--spec/lib/af83/cloning/clone_schema_spec.rb113
-rw-r--r--spec/lib/af83/stored_procedure_spec.rb20
-rw-r--r--spec/lib/af83/stored_procedures/clone_schema_spec.rb167
-rw-r--r--spec/lib/time_duration_spec.rb14
-rw-r--r--spec/models/chouette/time_table_spec.rb82
-rw-r--r--spec/models/chouette/vehicle_journey_at_stops_day_offset_spec.rb90
-rw-r--r--spec/models/chouette/vehicle_journey_spec.rb63
-rw-r--r--spec/models/clean_up_spec.rb225
-rw-r--r--spec/models/referential_cloning_spec.rb10
-rw-r--r--spec/models/time_table_combination_spec.rb4
-rw-r--r--spec/models/user_spec.rb2
-rw-r--r--spec/policies/boiv_policy_spec.rb1
-rw-r--r--spec/policies/login_policy_spec.rb15
-rw-r--r--spec/support/bare_sql.rb58
-rw-r--r--spec/support/custom_matchers.rb7
-rw-r--r--spec/support/devise.rb9
-rw-r--r--spec/support/hash.rb6
-rw-r--r--spec/support/pg_catalog.rb57
-rw-r--r--spec/support/pundit/policies.rb7
-rw-r--r--spec/views/referentials/new.html.erb_spec.rb8
-rw-r--r--spec/workers/referential_cloning_worker_spec.rb30
37 files changed, 780 insertions, 359 deletions
diff --git a/spec/controllers/devise/cas_sessions_controller_spec.rb b/spec/controllers/devise/cas_sessions_controller_spec.rb
new file mode 100644
index 000000000..950d141fd
--- /dev/null
+++ b/spec/controllers/devise/cas_sessions_controller_spec.rb
@@ -0,0 +1,27 @@
+RSpec.describe Devise::CasSessionsController, type: :controller do
+
+ login_user
+
+ context 'login is correctly redirected' do
+ it 'to #service' do
+ get :new
+ expect(response).to redirect_to(unauthenticated_root_path)
+ end
+ end
+
+ context 'user does not have any boiv:.+ permission' do
+ xit 'cannot login and will be redirected to the login page, with a corresponding message' do
+ get :service
+ expect(controller).to set_flash[:alert].to(%r{IBOO})
+ expect(response).to redirect_to("http://stif-portail-dev.af83.priv/sessions/login?service=http%3A%2F%2Ftest.host%2Fusers%2Fservice")
+ end
+ end
+
+ context 'user does have a boiv:.+ permission' do
+ it 'can login and will be redirected to the referentials page' do
+ @user.update_attribute :permissions, (@user.permissions << 'boiv:UnameIt')
+ get :service
+ expect(response).to redirect_to(authenticated_root_path)
+ end
+ end
+end
diff --git a/spec/controllers/imports_controller_spec.rb b/spec/controllers/imports_controller_spec.rb
index bffb89338..7b575ab61 100644
--- a/spec/controllers/imports_controller_spec.rb
+++ b/spec/controllers/imports_controller_spec.rb
@@ -1,5 +1,3 @@
-require 'rails_helper'
-
RSpec.describe ImportsController, :type => :controller do
login_user
diff --git a/spec/controllers/route_stop_points_controller_spec.rb b/spec/controllers/route_stop_points_controller_spec.rb
index 2f5fa41c7..ac9e2f11b 100644
--- a/spec/controllers/route_stop_points_controller_spec.rb
+++ b/spec/controllers/route_stop_points_controller_spec.rb
@@ -15,9 +15,7 @@ RSpec.describe RouteStopPointsController, type: :controller do
end
it 'returns a JSON of stop areas' do
- expect(response.body).to eq(route.stop_points.map { |sp| { id: sp.id, name: sp.name } }.to_json)
+ expect(response.body).to eq(route.stop_points.map { |sp| { id: sp.id, stop_area_id: sp.stop_area.id, name: sp.name, zip_code: sp.stop_area.zip_code, city_name: sp.stop_area.city_name } }.to_json)
end
end
end
-
-
diff --git a/spec/factories/chouette_time_table.rb b/spec/factories/chouette_time_table.rb
index f462349cf..6480df79d 100644
--- a/spec/factories/chouette_time_table.rb
+++ b/spec/factories/chouette_time_table.rb
@@ -1,6 +1,7 @@
FactoryGirl.define do
factory :time_table_date, :class => Chouette::TimeTableDate do
+ association :time_table, :factory => :time_table
end
factory :time_table_period, :class => Chouette::TimeTablePeriod do
diff --git a/spec/factories/chouette_vehicle_journey.rb b/spec/factories/chouette_vehicle_journey.rb
index 452909f23..e7ecb79ac 100644
--- a/spec/factories/chouette_vehicle_journey.rb
+++ b/spec/factories/chouette_vehicle_journey.rb
@@ -18,11 +18,16 @@ FactoryGirl.define do
after(:create) do |vehicle_journey, evaluator|
vehicle_journey.journey_pattern.stop_points.each_with_index do |stop_point, index|
+ prev_stop = vehicle_journey.vehicle_journey_at_stops[index - 1]
+
+ arrival_time = prev_stop ? prev_stop[:departure_time] + 1.minute : evaluator.stop_arrival_time
+ departure_time = prev_stop ? arrival_time + 1.minute : evaluator.stop_departure_time
+
vehicle_journey.vehicle_journey_at_stops << create(:vehicle_journey_at_stop,
:vehicle_journey => vehicle_journey,
:stop_point => stop_point,
- :arrival_time => "2000-01-01 #{evaluator.stop_arrival_time} UTC",
- :departure_time => "2000-01-01 #{evaluator.stop_departure_time} UTC")
+ :arrival_time => "2000-01-01 #{arrival_time} UTC",
+ :departure_time => "2000-01-01 #{departure_time} UTC")
end
end
diff --git a/spec/factories/clean_ups.rb b/spec/factories/clean_ups.rb
index 41165ac16..d3746c3b2 100644
--- a/spec/factories/clean_ups.rb
+++ b/spec/factories/clean_ups.rb
@@ -1,15 +1,6 @@
FactoryGirl.define do
factory :clean_up do
- status "MyString"
-started_at "2016-11-14 14:45:18"
-ended_at "2016-11-14 14:45:18"
-referential nil
-keep_lines false
-keep_stops false
-keep_companies false
-keep_networks false
-keep_group_of_lines false
-expected_date "2016-11-14 14:45:18"
+ begin_date { Date.today}
+ end_date { Date.today + 1.month }
end
-
end
diff --git a/spec/features/calendars_spec.rb b/spec/features/calendars_spec.rb
index 2089939bb..e15624295 100644
--- a/spec/features/calendars_spec.rb
+++ b/spec/features/calendars_spec.rb
@@ -19,12 +19,20 @@ describe 'Calendars', type: :feature do
context 'filtering' do
it 'supports filtering by short name' do
- fill_in 'q[short_name_cont]', with: calendars.first.short_name
+ fill_in 'q[name_or_short_name_cont]', with: calendars.first.short_name
click_button 'search_btn'
expect(page).to have_content(calendars.first.short_name)
expect(page).not_to have_content(calendars.last.short_name)
end
+ it 'supports filtering by name' do
+ fill_in 'q[name_or_short_name_cont]', with: calendars.first.name
+ click_button 'search_btn'
+ expect(page).to have_content(calendars.first.name)
+ expect(page).not_to have_content(calendars.last.name)
+ end
+
+
it 'supports filtering by shared' do
shared_calendar = create :calendar, organisation_id: 1, shared: true
visit calendars_path
diff --git a/spec/features/lines_spec.rb b/spec/features/lines_spec.rb
index e7e1e601c..a55f30ebc 100644
--- a/spec/features/lines_spec.rb
+++ b/spec/features/lines_spec.rb
@@ -1,7 +1,4 @@
-# -*- coding: utf-8 -*-
-require 'spec_helper'
-
-describe "Lines", :type => :feature do
+describe "Lines", type: :feature do
login_user
let(:line_referential) { create :line_referential }
diff --git a/spec/features/referentials_permissions_spec.rb b/spec/features/referentials_permissions_spec.rb
new file mode 100644
index 000000000..0216eeeb0
--- /dev/null
+++ b/spec/features/referentials_permissions_spec.rb
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+
+describe "Referentials", :type => :feature do
+
+ login_user
+ let(:referential) { Referential.first }
+
+ let( :edit_link_text ){ I18n.t('actions.edit') }
+ let( :destroy_link_text ){ I18n.t('actions.destroy') }
+
+
+ context 'permissions' do
+ before do
+ allow_any_instance_of(ReferentialPolicy).to receive(:organisation_match?).and_return organisation_match
+ visit path
+ end
+
+ context 'on show view with common lines' do
+ let( :path ){ referential_path(referential) }
+ before do
+ allow_any_instance_of(ReferentialPolicy).to receive(:common_lines?).and_return common_lines
+ end
+
+ context 'if organisations match →' do
+ let( :organisation_match ){ true }
+ let( :common_lines ){ false }
+
+ it 'shows the edit button' do
+ expected_href = edit_referential_path(referential)
+ expect( page ).to have_link(edit_link_text, href: expected_href)
+ end
+ it 'shows the delete button' do
+ expected_href = referential_path(referential)
+ expect( page ).to have_css(%{a[href=#{expected_href.inspect}] span}, text: destroy_link_text)
+ end
+ end
+
+ context 'if organisations do not match →' do
+ let( :organisation_match ){ false }
+ let( :common_lines ){ true }
+
+ it 'does not show the delete button' do
+ expected_href = edit_referential_path(referential)
+ expect( page ).not_to have_link(edit_link_text, href: expected_href)
+ end
+ it 'does not show the delete button' do
+ expected_href = referential_path(referential)
+ expect( page ).not_to have_css(%{a[href=#{expected_href.inspect}] span}, text: destroy_link_text)
+ end
+ end
+ end
+
+ end
+end
diff --git a/spec/features/referentials_spec.rb b/spec/features/referentials_spec.rb
index 3c2258a3a..337271fea 100644
--- a/spec/features/referentials_spec.rb
+++ b/spec/features/referentials_spec.rb
@@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
-require 'spec_helper'
-
describe "Referentials", :type => :feature do
login_user
@@ -111,13 +109,9 @@ describe "Referentials", :type => :feature do
end
describe "create" do
-
it "should" do
visit new_referential_path
fill_in "Nom", :with => "Test"
- fill_in "Code", :with => "test"
- fill_in "Point haut/droite de l'emprise par défaut", :with => "0.0, 0.0"
- fill_in "Point bas/gauche de l'emprise par défaut", :with => "1.0, 1.0"
click_button "Valider"
expect(Referential.where(:name => "Test")).not_to be_nil
diff --git a/spec/features/routes_spec.rb b/spec/features/routes_spec.rb
index 6d9ba990d..28015f011 100644
--- a/spec/features/routes_spec.rb
+++ b/spec/features/routes_spec.rb
@@ -36,10 +36,13 @@ describe "Routes", :type => :feature do
visit referential_line_path(referential, line)
click_link "Ajouter un itinéraire"
fill_in "route_name", :with => "A to B"
+ fill_in "route_published_name", :with => "Published A to B"
# select 'Aller', :from => "route_direction"
check('route[wayback]')
click_button("Valider")
expect(page).to have_content("A to B")
+ expect(page).to have_content("Published A to B")
+
end
end
diff --git a/spec/features/routing_constraint_zones_spec.rb b/spec/features/routing_constraint_zones_spec.rb
index 9e8c7dad4..b116b38bd 100644
--- a/spec/features/routing_constraint_zones_spec.rb
+++ b/spec/features/routing_constraint_zones_spec.rb
@@ -20,7 +20,7 @@ describe 'RoutingConstraintZones', type: :feature do
context 'user has permission to create routing_constraint_zones' do
it 'shows a create link for routing_constraint_zones' do
- expect(page).to have_content(I18n.t('routing_constraint_zones.actions.new'))
+ expect(page).to have_content(I18n.t('actions.new'))
end
end
@@ -28,7 +28,7 @@ describe 'RoutingConstraintZones', type: :feature do
it 'does not show a create link for routing_constraint_zones' do
@user.update_attribute(:permissions, [])
visit referential_line_routing_constraint_zones_path(referential, line)
- expect(page).not_to have_content(I18n.t('routing_constraint_zones.actions.new'))
+ expect(page).not_to have_content(I18n.t('actions.new'))
end
end
diff --git a/spec/features/users/connection_spec.rb b/spec/features/users/connection_spec.rb
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/spec/features/users/connection_spec.rb
diff --git a/spec/features/workbenches_spec.rb b/spec/features/workbenches_spec.rb
index c11fbd03d..953eb2bf5 100644
--- a/spec/features/workbenches_spec.rb
+++ b/spec/features/workbenches_spec.rb
@@ -46,8 +46,6 @@ describe 'Workbenches', type: :feature do
click_link I18n.t('actions.add')
fill_in "referential[name]", with: "Referential to test creation" # Nom du JDD
- fill_in "referential[slug]", with: "test" # Code
- fill_in "referential[prefix]", with: "test" # Prefix Neptune
select workbench.lines.first.id, from: 'referential[metadatas_attributes][0][lines][]' # Lignes
click_button "Valider"
diff --git a/spec/javascripts/time_table/reducers/pagination_spec.js b/spec/javascripts/time_table/reducers/pagination_spec.js
index 740ded3ac..5da58427e 100644
--- a/spec/javascripts/time_table/reducers/pagination_spec.js
+++ b/spec/javascripts/time_table/reducers/pagination_spec.js
@@ -118,11 +118,4 @@ describe('pagination reducer', () => {
})
).toEqual(Object.assign({}, state, {stateChanged: true}))
})
- it('should handle UPDATE_DAY_TYPES', () => {
- expect(
- paginationReducer(state, {
- type: 'UPDATE_DAY_TYPES'
- })
- ).toEqual(Object.assign({}, state, {stateChanged: true}))
- })
})
diff --git a/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js b/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js
index 662c3d82f..23ebc3d9f 100644
--- a/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js
+++ b/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js
@@ -111,7 +111,9 @@ describe('vehicleJourneys reducer', () => {
time_tables: [],
vehicle_journey_at_stops: pristineVjasList,
selected: false,
- deletable: false
+ deletable: false,
+ transport_mode: 'undefined',
+ transport_submode: 'undefined'
}, ...state])
})
diff --git a/spec/lib/af83/cloning/clone_schema_spec.rb b/spec/lib/af83/cloning/clone_schema_spec.rb
new file mode 100644
index 000000000..3d541f3e9
--- /dev/null
+++ b/spec/lib/af83/cloning/clone_schema_spec.rb
@@ -0,0 +1,113 @@
+RSpec.describe AF83::SchemaCloner, type: :pg_catalog do
+ let( :source_schema ){ "source_schema" }
+ let( :target_schema ){ "target_schema" }
+ let( :child_table ){ "children" }
+ let( :parent_table ){ "parents" }
+
+ subject { described_class.new source_schema, target_schema }
+
+ context "after cloning" do
+ before do
+ create_schema_with_tables
+ subject.clone_schema
+ end
+
+ it "table information is correctly duplicated" do
+ expect(get_table_information(source_schema, child_table))
+ .to eq([{"table_schema"=>"source_schema",
+ "table_name"=>"children",
+ "table_type"=>"BASE TABLE",
+ "self_referencing_column_name"=>nil,
+ "reference_generation"=>nil,
+ "user_defined_type_catalog"=>nil,
+ "user_defined_type_schema"=>nil,
+ "user_defined_type_name"=>nil,
+ "is_insertable_into"=>"YES",
+ "is_typed"=>"NO",
+ "commit_action"=>nil}])
+
+ expect( get_table_information(target_schema, child_table))
+ .to eq([{"table_schema"=>"target_schema",
+ "table_name"=>"children",
+ "table_type"=>"BASE TABLE",
+ "self_referencing_column_name"=>nil,
+ "reference_generation"=>nil,
+ "user_defined_type_catalog"=>nil,
+ "user_defined_type_schema"=>nil,
+ "user_defined_type_name"=>nil,
+ "is_insertable_into"=>"YES",
+ "is_typed"=>"NO",
+ "commit_action"=>nil}])
+ end
+
+ it "table content is the same and sequences are synchronized" do
+ expect_same_content(parent_table)
+ expect_same_content(child_table)
+
+ expect_same_sequence_params("#{parent_table}_id_seq")
+ expect_same_sequence_params("#{child_table}_id_seq")
+ end
+
+ it "has correctly updated default values" do
+ child_table_pk_default = get_columns(target_schema, child_table)
+ .find{ |col| col["column_name"] == "id" }["column_default"]
+ expect( child_table_pk_default ).to eq("nextval('#{target_schema}.children_id_seq'::regclass)")
+ end
+
+ it "has the correct foreign keys" do
+ expect( get_foreign_keys(target_schema, child_table) )
+ .to eq([{
+ "constraint_name" => "children_parents",
+ "constraint_def" => "FOREIGN KEY (parents_id) REFERENCES target_schema.parents(id)"}])
+ end
+
+ xit "it has the correct unique keys UNTESTABLE SO FAR" do
+ insert source_schema, child_table, "#{parent_table}_id" => 1, some_key: 400
+ insert target_schema, child_table, "#{parent_table}_id" => 1, some_key: 400
+ reinsert_sql = "INSERT INTO #{source_schema}.#{child_table} (#{parent_table}_id, some_key) VALUES (1, 400)"
+ expect{ execute(reinsert_sql) rescue nil}.not_to change{ execute("SELECT COUNT(*) FROM #{source_schema}.#{child_table}") }
+
+ # expect{ insert(target_schema, child_table, "#{parent_table}_id" => 1, some_key: 400) }.to raise_error(ActiveRecord::RecordNotUnique)
+ end
+
+ it "inserts are independent" do
+ insert source_schema, child_table, "#{parent_table}_id" => 1, some_key: 400
+ insert target_schema, child_table, "#{parent_table}_id" => 1, some_key: 400
+ last_source = get_content(source_schema, child_table).last
+ last_target = get_content(target_schema, child_table).last
+
+ expect( last_source ).to eq("id"=>"3", "parents_id"=>"1", "some_key"=>"400", "is_orphan"=>"f")
+ expect( last_target ).to eq("id"=>"3", "parents_id"=>"1", "some_key"=>"400", "is_orphan"=>"f")
+ end
+
+ end
+
+ def create_schema_with_tables
+ execute <<-EOSQL
+ DROP SCHEMA IF EXISTS #{source_schema} CASCADE;
+ CREATE SCHEMA #{source_schema};
+
+ CREATE TABLE #{source_schema}.#{parent_table} (
+ id bigserial PRIMARY KEY
+ );
+ CREATE TABLE #{source_schema}.#{child_table} (
+ id bigserial PRIMARY KEY,
+ #{parent_table}_id bigint,
+ some_key bigint NOT NULL,
+ is_orphan boolean DEFAULT false
+ );
+
+ CREATE UNIQUE INDEX #{child_table}_some_key_idx ON #{source_schema}.#{child_table} (some_key);
+
+ ALTER TABLE #{source_schema}.#{child_table}
+ ADD CONSTRAINT #{child_table}_#{parent_table}
+ FOREIGN KEY( #{parent_table}_id ) REFERENCES #{source_schema}.#{parent_table}(id);
+
+ INSERT INTO #{source_schema}.#{parent_table} VALUES (DEFAULT);
+ INSERT INTO #{source_schema}.#{parent_table} VALUES (DEFAULT);
+ EOSQL
+ insert source_schema, child_table, "#{parent_table}_id" => 1, some_key: 200
+ insert source_schema, child_table, "#{parent_table}_id" => 2, some_key: 300, is_orphan: true
+ end
+
+end
diff --git a/spec/lib/af83/stored_procedure_spec.rb b/spec/lib/af83/stored_procedure_spec.rb
deleted file mode 100644
index 2530d7fc1..000000000
--- a/spec/lib/af83/stored_procedure_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe StoredProcedures do
-
-
- before do
- described_class.create_stored_procedure(:clone_schema)
- end
-
- let( :source_schema_name ){ "parissudest201604" }
- let( :dest_schema_name ){ "#{source_schema_name}_v1"}
-
- context "Error cases" do
- it "raises an error if stored procedure does not exist" do
- expect{ described_class.invoke_stored_procedure(:idonotexist) }
- .to raise_error(ArgumentError, %r{no such stored procedure "idonotexist"})
- end
- end
-
-end
diff --git a/spec/lib/af83/stored_procedures/clone_schema_spec.rb b/spec/lib/af83/stored_procedures/clone_schema_spec.rb
deleted file mode 100644
index c387ddc7d..000000000
--- a/spec/lib/af83/stored_procedures/clone_schema_spec.rb
+++ /dev/null
@@ -1,167 +0,0 @@
-require 'spec_helper'
-
-include Support::PGCatalog
-
-RSpec.describe StoredProcedures do
- let( :source_schema ){ "source_schema" }
- let( :target_schema ){ "target_schema" }
- let( :child_table ){ "children" }
- let( :parent_table ){ "parents" }
-
- before do
- create_schema_with_tables
- StoredProcedures.create_stored_procedure :clone_schema
- end
-
- # :meta specs are not run, as the describe the testing methd and not the application
- context "meta specs describe source schema's introspection", :meta do
- it "table information is correctly read" do
- expect(get_table_information(source_schema, child_table))
- .to eq([{"table_schema"=>"source_schema",
- "table_name"=>"children",
- "table_type"=>"BASE TABLE",
- "self_referencing_column_name"=>nil,
- "reference_generation"=>nil,
- "user_defined_type_catalog"=>nil,
- "user_defined_type_schema"=>nil,
- "user_defined_type_name"=>nil,
- "is_insertable_into"=>"YES",
- "is_typed"=>"NO",
- "commit_action"=>nil}])
-
- expect( get_table_information(target_schema, child_table) ).to be_empty
- end
-
- it "sequences are correctly read" do
- expect(get_sequences(source_schema, child_table))
- .to eq([{"sequence_name"=>"#{child_table}_id_seq",
- "last_value"=>"1",
- "start_value"=>"1",
- "increment_by"=>"1",
- "max_value"=>"9223372036854775807",
- "min_value"=>"1",
- "cache_value"=>"1",
- "log_cnt"=>"0",
- "is_cycled"=>"f",
- "is_called"=>"f"}])
-
- expect(get_sequences(source_schema, parent_table))
- .to eq([{"sequence_name"=>"#{parent_table}_id_seq",
- "last_value"=>"1",
- "start_value"=>"1",
- "increment_by"=>"1",
- "max_value"=>"9223372036854775807",
- "min_value"=>"1",
- "cache_value"=>"1",
- "log_cnt"=>"0",
- "is_cycled"=>"f",
- "is_called"=>"f"}])
- end
-
- it "shows foreign key constraints are correctly read" do
- expect( get_foreign_keys(source_schema, child_table) )
- .to eq([{
- "constraint_name" => "children_parents",
- "constraint_def" => "FOREIGN KEY (parents_id) REFERENCES source_schema.parents(id)"}])
- end
- end
-
- context "before cloning" do
- it "target schema does not exist" do
- expect( get_schema_oid(target_schema) ).to be_nil
- end
- end
-
- context "after cloning" do
- before do
- described_class.invoke_stored_procedure(:clone_schema, source_schema, target_schema, false)
- end
-
- it "target schema does exist" do
- expect( get_schema_oid(target_schema) ).not_to be_nil
- end
-
- it "table information is correctly read" do
- expect(get_table_information(source_schema, child_table))
- .to eq([{"table_schema"=>"source_schema",
- "table_name"=>"children",
- "table_type"=>"BASE TABLE",
- "self_referencing_column_name"=>nil,
- "reference_generation"=>nil,
- "user_defined_type_catalog"=>nil,
- "user_defined_type_schema"=>nil,
- "user_defined_type_name"=>nil,
- "is_insertable_into"=>"YES",
- "is_typed"=>"NO",
- "commit_action"=>nil}])
-
- expect( get_table_information(target_schema, child_table))
- .to eq([{"table_schema"=>"target_schema",
- "table_name"=>"children",
- "table_type"=>"BASE TABLE",
- "self_referencing_column_name"=>nil,
- "reference_generation"=>nil,
- "user_defined_type_catalog"=>nil,
- "user_defined_type_schema"=>nil,
- "user_defined_type_name"=>nil,
- "is_insertable_into"=>"YES",
- "is_typed"=>"NO",
- "commit_action"=>nil}])
- end
-
- it "has the correct sequences" do
- expect(get_sequences(target_schema, child_table))
- .to eq([{"sequence_name"=>"#{child_table}_id_seq",
- "last_value"=>"1",
- "start_value"=>"1",
- "increment_by"=>"1",
- "max_value"=>"9223372036854775807",
- "min_value"=>"1",
- "cache_value"=>"1",
- "log_cnt"=>"0",
- "is_cycled"=>"f",
- "is_called"=>"f"}])
-
- expect(get_sequences(target_schema, parent_table))
- .to eq([{"sequence_name"=>"#{parent_table}_id_seq",
- "last_value"=>"1",
- "start_value"=>"1",
- "increment_by"=>"1",
- "max_value"=>"9223372036854775807",
- "min_value"=>"1",
- "cache_value"=>"1",
- "log_cnt"=>"0",
- "is_cycled"=>"f",
- "is_called"=>"f"}])
- end
-
- it "has the correct foreign keys" do
- expect( get_foreign_keys(target_schema, child_table) )
- .to eq([{
- "constraint_name" => "children_parents",
- "constraint_def" => "FOREIGN KEY (parents_id) REFERENCES target_schema.parents(id)"}])
- end
-
- end
-
-end
-
-def create_schema_with_tables
- execute("CREATE SCHEMA IF NOT EXISTS #{source_schema}")
- execute <<-EOSQL
- DROP SCHEMA IF EXISTS #{source_schema} CASCADE;
- CREATE SCHEMA #{source_schema};
-
- CREATE TABLE #{source_schema}.#{parent_table} (
- id bigserial PRIMARY KEY
- );
- CREATE TABLE #{source_schema}.#{child_table} (
- id bigserial PRIMARY KEY,
- #{parent_table}_id bigint
- );
- ALTER TABLE #{source_schema}.#{child_table}
- ADD CONSTRAINT #{child_table}_#{parent_table}
- FOREIGN KEY( #{parent_table}_id ) REFERENCES #{source_schema}.#{parent_table}(id);
- EOSQL
-end
-
diff --git a/spec/lib/time_duration_spec.rb b/spec/lib/time_duration_spec.rb
index 1cba1f6d5..bf23f7ba6 100644
--- a/spec/lib/time_duration_spec.rb
+++ b/spec/lib/time_duration_spec.rb
@@ -4,15 +4,17 @@ describe TimeDuration do
describe ".exceeds_gap?" do
context "when duration is 4.hours" do
it "should return false if gap < 1.hour" do
- t1 = Time.now
- t2 = Time.now + 3.minutes
- expect(TimeDuration.exceeds_gap?(4.hours, t1, t2)).to be_falsey
+ earlier = Time.now
+ later = Time.now + 3.minutes
+
+ expect(TimeDuration.exceeds_gap?(4.hours, earlier, later)).to be false
end
it "should return true if gap > 4.hour" do
- t1 = Time.now
- t2 = Time.now + (4.hours + 1.minutes)
- expect(TimeDuration.exceeds_gap?(4.hours, t1, t2)).to be_truthy
+ earlier = Time.now
+ later = Time.now + (4.hours + 1.minutes)
+
+ expect(TimeDuration.exceeds_gap?(4.hours, earlier, later)).to be true
end
it "returns true when `earlier` is later than `later`" do
diff --git a/spec/models/chouette/time_table_spec.rb b/spec/models/chouette/time_table_spec.rb
index 3d45bd346..7a8863cb3 100644
--- a/spec/models/chouette/time_table_spec.rb
+++ b/spec/models/chouette/time_table_spec.rb
@@ -1,12 +1,47 @@
require 'spec_helper'
describe Chouette::TimeTable, :type => :model do
-
subject { create(:time_table) }
it { is_expected.to validate_presence_of :comment }
it { is_expected.to validate_uniqueness_of :objectid }
+ context "merge with calendar" do
+ let(:calendar) { create(:calendar) }
+
+ it 'should add calendar dates to time_table' do
+ subject.dates.clear
+ subject.merge!(calendar.convert_to_time_table)
+ expect(subject.dates.map(&:date)).to include(*calendar.dates)
+ end
+ end
+
+ describe "actualize" do
+ let(:calendar) { create(:calendar) }
+ let(:int_day_types) { 508 }
+
+ before do
+ subject.int_day_types = int_day_types
+ subject.calendar = calendar
+ subject.save
+ subject.actualize
+ end
+
+ it 'should override dates' do
+ expect(subject.dates.map(&:date)).to match_array calendar.dates
+ end
+
+ it 'should override periods' do
+ [:period_start, :period_end].each do |key|
+ expect(subject.periods.map(&key)).to match_array calendar.convert_to_time_table.periods.map(&key)
+ end
+ end
+
+ it 'should not change int_day_types' do
+ expect(subject.int_day_types).to eq(int_day_types)
+ end
+ end
+
describe "Update state" do
def time_table_to_state time_table
time_table.slice('id', 'comment').tap do |item|
@@ -119,7 +154,7 @@ describe Chouette::TimeTable, :type => :model do
end
it 'should create new include date' do
- day = state['current_month'].first
+ day = state['current_month'].find{|d| !d['excluded_date'] && !d['include_date'] }
date = Date.parse(day['date'])
day['include_date'] = true
expect(subject.included_days).not_to include(date)
@@ -131,7 +166,7 @@ describe Chouette::TimeTable, :type => :model do
end
it 'should create new exclude date' do
- day = state['current_month'].first
+ day = state['current_month'].find{|d| !d['excluded_date'] && !d['include_date']}
date = Date.parse(day['date'])
day['excluded_date'] = true
expect(subject.excluded_days).not_to include(date)
@@ -973,7 +1008,7 @@ end
expect(subject.periods[2].period_start).to eq(Date.new(2014, 8, 1))
expect(subject.periods[2].period_end).to eq(Date.new(2014, 8, 12))
end
- it "should have common day_types" do
+ it "should not modify day_types" do
expect(subject.int_day_types).to eq(4|16|128)
end
it "should have dates for thursdays and fridays" do
@@ -1007,9 +1042,6 @@ end
it "should have no period" do
expect(subject.periods.size).to eq(0)
end
- it "should have no day_types" do
- expect(subject.int_day_types).to eq(0)
- end
it "should have date all common days" do
expect(subject.dates.size).to eq(3)
expect(subject.dates[0].date).to eq(Date.new(2014,7,16))
@@ -1038,7 +1070,7 @@ end
it "should have 0 period" do
expect(subject.periods.size).to eq(0)
end
- it "should have no day_types" do
+ it "should not modify day_types" do
expect(subject.int_day_types).to eq(0)
end
it "should have date reduced for period" do
@@ -1063,8 +1095,8 @@ end
it "should have 0 result periods" do
expect(subject.periods.size).to eq(0)
end
- it "should have no day_types" do
- expect(subject.int_day_types).to eq(0)
+ it "should not modify day_types" do
+ expect(subject.int_day_types).to eq(4|8|16)
end
it "should have 1 date " do
expect(subject.dates.size).to eq(1)
@@ -1093,9 +1125,6 @@ end
it "should have 0 periods" do
expect(subject.periods.size).to eq(0)
end
- it "should have 0 day_types" do
- expect(subject.int_day_types).to eq(0)
- end
it "should have only dates " do
expect(subject.dates.size).to eq(11)
expect(subject.dates[0].date).to eq(Date.new(2014,6,30))
@@ -1134,7 +1163,7 @@ end
it "should have 0 period" do
expect(subject.periods.size).to eq(0)
end
- it "should have no remained day_types" do
+ it "should not modify day_types" do
expect(subject.int_day_types).to eq(0)
end
it "should have date reduced for period" do
@@ -1163,9 +1192,6 @@ end
it "should have 0 result periods" do
expect(subject.periods.size).to eq(0)
end
- it "should have no remained day_types" do
- expect(subject.int_day_types).to eq(0)
- end
it "should have dates for period reduced" do
expect(subject.dates.size).to eq(4)
expect(subject.dates[0].date).to eq(Date.new(2014,7,3))
@@ -1197,9 +1223,6 @@ end
it "should have 0 result periods" do
expect(subject.periods.size).to eq(0)
end
- it "should have no remained day_types" do
- subject.int_day_types == 0
- end
it "should have 3 dates left" do
expect(subject.dates.size).to eq(3)
expect(subject.dates[0].date).to eq(Date.new(2014,7,16))
@@ -1233,10 +1256,6 @@ end
expect(subject.periods.size).to eq(0)
end
- it "should have no remained day_types" do
- subject.int_day_types == 0
- end
-
it "should have 0 dates left" do
expect(subject.dates.size).to eq(0)
end
@@ -1261,10 +1280,6 @@ end
expect(subject.periods.size).to eq(0)
end
- it "should have 0 day_types" do
- expect(subject.int_day_types).to eq(0)
- end
-
it "should have 6 dates " do
expect(subject.dates.size).to eq(6)
expect(subject.dates[0].date).to eq(Date.new(2014,8,11))
@@ -1303,8 +1318,8 @@ end
end
end
- it "should have 0 day_types" do
- expect(subject.int_day_types).to eq(0)
+ it "should not modify day_types" do
+ expect(subject.int_day_types).to eq(4|8|16)
end
it "should have 1 dates " do
@@ -1342,8 +1357,8 @@ end
end
end
- it "should have 0 day_types" do
- expect(subject.int_day_types).to eq(0)
+ it "should not modify day_types" do
+ expect(subject.int_day_types).to eq(4|8|16)
end
it "should have only 1 dates " do
@@ -1373,9 +1388,6 @@ end
it "should have same 0 result periods" do
expect(subject.periods.size).to eq(0)
end
- it "should have 0 day_types" do
- expect(subject.int_day_types).to eq(0)
- end
it "should have 0 dates " do
expect(subject.dates.size).to eq(0)
end
diff --git a/spec/models/chouette/vehicle_journey_at_stops_day_offset_spec.rb b/spec/models/chouette/vehicle_journey_at_stops_day_offset_spec.rb
new file mode 100644
index 000000000..69a2d5cb9
--- /dev/null
+++ b/spec/models/chouette/vehicle_journey_at_stops_day_offset_spec.rb
@@ -0,0 +1,90 @@
+require 'spec_helper'
+
+describe Chouette::VehicleJourneyAtStop do
+ describe "#calculate" do
+ it "increments day offset when departure & arrival are on different sides
+ of midnight" do
+ at_stops = []
+ [
+ ['22:30', '22:35'],
+ ['23:50', '00:05'],
+ ['00:30', '00:35'],
+ ].each do |arrival_time, departure_time|
+ at_stops << build_stubbed(
+ :vehicle_journey_at_stop,
+ arrival_time: arrival_time,
+ departure_time: departure_time
+ )
+ end
+
+ offsetter = Chouette::VehicleJourneyAtStopsDayOffset.new(at_stops)
+
+ offsetter.calculate!
+
+ expect(at_stops[0].arrival_day_offset).to eq(0)
+ expect(at_stops[0].departure_day_offset).to eq(0)
+
+ expect(at_stops[1].arrival_day_offset).to eq(0)
+ expect(at_stops[1].departure_day_offset).to eq(1)
+
+ expect(at_stops[2].arrival_day_offset).to eq(1)
+ expect(at_stops[2].departure_day_offset).to eq(1)
+ end
+
+ it "increments day offset when an at_stop passes midnight the next day" do
+ at_stops = []
+ [
+ ['22:30', '22:35'],
+ ['01:02', '01:14'],
+ ].each do |arrival_time, departure_time|
+ at_stops << build_stubbed(
+ :vehicle_journey_at_stop,
+ arrival_time: arrival_time,
+ departure_time: departure_time
+ )
+ end
+
+ offsetter = Chouette::VehicleJourneyAtStopsDayOffset.new(at_stops)
+
+ offsetter.calculate!
+
+ expect(at_stops[0].arrival_day_offset).to eq(0)
+ expect(at_stops[0].departure_day_offset).to eq(0)
+
+ expect(at_stops[1].arrival_day_offset).to eq(1)
+ expect(at_stops[1].departure_day_offset).to eq(1)
+ end
+
+ it "increments day offset for multi-day offsets" do
+ at_stops = []
+ [
+ ['22:30', '22:35'],
+ ['01:02', '01:14'],
+ ['04:30', '04:35'],
+ ['00:00', '00:04'],
+ ].each do |arrival_time, departure_time|
+ at_stops << build_stubbed(
+ :vehicle_journey_at_stop,
+ arrival_time: arrival_time,
+ departure_time: departure_time
+ )
+ end
+
+ offsetter = Chouette::VehicleJourneyAtStopsDayOffset.new(at_stops)
+
+ offsetter.calculate!
+
+ expect(at_stops[0].arrival_day_offset).to eq(0)
+ expect(at_stops[0].departure_day_offset).to eq(0)
+
+ expect(at_stops[1].arrival_day_offset).to eq(1)
+ expect(at_stops[1].departure_day_offset).to eq(1)
+
+ expect(at_stops[2].arrival_day_offset).to eq(1)
+ expect(at_stops[2].departure_day_offset).to eq(1)
+
+ expect(at_stops[3].arrival_day_offset).to eq(2)
+ expect(at_stops[3].departure_day_offset).to eq(2)
+ end
+ end
+end
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index 4a108d7c0..8f9080b99 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -1,7 +1,38 @@
require 'spec_helper'
+
describe Chouette::VehicleJourney, :type => :model do
- describe "state_update" do
+ describe "vjas_departure_time_must_be_before_next_stop_arrival_time" do
+ let(:vehicle_journey) { create :vehicle_journey }
+ let(:vjas) { vehicle_journey.vehicle_journey_at_stops }
+
+ it 'should add errors a stop departure_time is greater then next stop arrival time' do
+ vjas[0][:departure_time] = vjas[1][:arrival_time] + 1.minute
+ vehicle_journey.validate
+
+ expect(vjas[0].errors[:departure_time]).not_to be_blank
+ expect(vehicle_journey.errors[:vehicle_journey_at_stops].count).to eq(1)
+ expect(vehicle_journey).not_to be_valid
+ end
+
+ it 'should consider valid to have departure_time equal to next stop arrival time' do
+ vjas[0][:departure_time] = vjas[1][:arrival_time]
+ vehicle_journey.validate
+
+ expect(vjas[0].errors[:departure_time]).to be_blank
+ expect(vehicle_journey.errors[:vehicle_journey_at_stops]).to be_empty
+ expect(vehicle_journey).to be_valid
+ end
+
+ it 'should not add errors when departure_time is less then next stop arrival time' do
+ vehicle_journey.validate
+ vjas.each do |stop|
+ expect(stop.errors).to be_empty
+ end
+ expect(vehicle_journey).to be_valid
+ end
+ end
+ describe "state_update" do
def vehicle_journey_at_stop_to_state vjas
at_stop = {'stop_area_object_id' => vjas.stop_point.stop_area.objectid }
[:id, :connecting_service_id, :boarding_alighting_possibility].map do |att|
@@ -136,16 +167,12 @@ describe Chouette::VehicleJourney, :type => :model do
it 'should return errors when validation failed' do
state['published_journey_name'] = 'edited_name'
- # Exceeds_gap departure time validation failed
- prev = state['vehicle_journey_at_stops'].last(2).first
- last = state['vehicle_journey_at_stops'].last
- prev['departure_time']['hour'] = '01'
- last['departure_time']['hour'] = '23'
+ state['vehicle_journey_at_stops'].last['departure_time']['hour'] = '23'
expect {
Chouette::VehicleJourney.state_update(route, collection)
}.not_to change(vehicle_journey, :published_journey_name)
- expect(state['errors'][:vehicle_journey_at_stops].size).to eq 1
+ expect(state['vehicle_journey_at_stops'].last['errors']).not_to be_empty
end
it 'should delete vj with deletable set to true from state' do
@@ -190,8 +217,8 @@ describe Chouette::VehicleJourney, :type => :model do
end
end
- describe '.vehicle_journey_at_stops_matrix' do
- it 'should fill missing VehicleJourneyAtStop with dummy' do
+ describe '#vehicle_journey_at_stops_matrix' do
+ it 'should fill missing vjas with dummy vjas' do
vehicle_journey.journey_pattern.stop_points.delete_all
vehicle_journey.vehicle_journey_at_stops.delete_all
@@ -201,14 +228,28 @@ describe Chouette::VehicleJourney, :type => :model do
expect(at_stops.count).to eq route.stop_points.count
end
- it 'should fill VehicleJourneyAtStop with new vjas when vj has been save without departure time' do
+ it 'should set dummy to false for active stop_points vjas' do
+ # Destroy vjas but stop_points is still active
+ # it should fill a new vjas without dummy flag
+ vehicle_journey.vehicle_journey_at_stops[3].destroy
+ at_stops = vehicle_journey.reload.vehicle_journey_at_stops_matrix
+ expect(at_stops[3].dummy).to be false
+ end
+
+ it 'should set dummy to true for deactivated stop_points vjas' do
+ vehicle_journey.journey_pattern.stop_points.delete(vehicle_journey.journey_pattern.stop_points.first)
+ at_stops = vehicle_journey.reload.vehicle_journey_at_stops_matrix
+ expect(at_stops.first.dummy).to be true
+ end
+
+ it 'should fill vjas for active stop_points without vjas yet' do
vehicle_journey.vehicle_journey_at_stops.destroy_all
at_stops = vehicle_journey.reload.vehicle_journey_at_stops_matrix
expect(at_stops.map(&:stop_point_id)).to eq vehicle_journey.journey_pattern.stop_points.map(&:id)
end
- it 'should keep index order of VehicleJourneyAtStop' do
+ it 'should keep index order of vjas' do
vehicle_journey.vehicle_journey_at_stops[3].destroy
at_stops = vehicle_journey.reload.vehicle_journey_at_stops_matrix
diff --git a/spec/models/clean_up_spec.rb b/spec/models/clean_up_spec.rb
index c495abdfe..4b1bf4da9 100644
--- a/spec/models/clean_up_spec.rb
+++ b/spec/models/clean_up_spec.rb
@@ -1,20 +1,227 @@
require 'rails_helper'
RSpec.describe CleanUp, :type => :model do
- let(:cleaner) { CleanUp.new }
it { should validate_presence_of(:begin_date) }
+ it { should validate_presence_of(:date_type) }
it { should belong_to(:referential) }
- it 'should delete vehiclejourneys without timetables' do
- create_list(:vehicle_journey, 2)
- create_list(:vehicle_journey, 2, time_tables:[create(:time_table)])
- expect(cleaner.clean_vehicle_journeys).to eq 2
+ context '#exclude_dates_in_overlapping_period with :before date_type' do
+ let(:time_table) { create(:time_table) }
+ let(:period) { time_table.periods[0] }
+ let(:cleaner) { create(:clean_up, date_type: :before) }
+
+ it 'should add exclude date into period for overlapping period' do
+ days_in_period = (period.period_start..period.period_end).count
+ cleaner.begin_date = period.period_end
+
+ expect { cleaner.exclude_dates_in_overlapping_period(period) }.to change {
+ time_table.dates.where(in_out: false).count
+ }.by(days_in_period - 1)
+ end
+
+ it 'should not add exclude date if no overlapping found' do
+ cleaner.begin_date = period.period_start
+ expect { cleaner.exclude_dates_in_overlapping_period(period) }.to_not change {
+ time_table.dates.where(in_out: false).count
+ }
+ end
+ end
+
+ context '#exclude_dates_in_overlapping_period with :after date_type' do
+ let(:time_table) { create(:time_table) }
+ let(:period) { time_table.periods[0] }
+ let(:cleaner) { create(:clean_up, date_type: :after) }
+
+ it 'should add exclude date into period for overlapping period' do
+ days_in_period = (period.period_start..period.period_end).count
+ cleaner.begin_date = period.period_start + 1.day
+ expect { cleaner.exclude_dates_in_overlapping_period(period) }.to change {
+ time_table.dates.where(in_out: false).count
+ }.by(days_in_period - 2)
+ end
+
+ it 'should not add exclude date if no overlapping found' do
+ cleaner.begin_date = period.period_end
+ expect { cleaner.exclude_dates_in_overlapping_period(period) }.to_not change {
+ time_table.dates.where(in_out: false).count
+ }
+ end
+ end
+
+ context '#exclude_dates_in_overlapping_period with :between date_type' do
+ let(:time_table) { create(:time_table) }
+ let(:period) { time_table.periods[0] }
+ let(:cleaner) { create(:clean_up, date_type: :between, begin_date: period.period_start + 3.day, end_date: period.period_end) }
+
+ it 'should add exclude date into period for overlapping period' do
+ expected_day_out = (cleaner.begin_date..cleaner.end_date).count
+ expect { cleaner.exclude_dates_in_overlapping_period(period) }.to change {
+ time_table.dates.where(in_out: false).count
+ }.by(expected_day_out)
+ end
+
+ it 'should not add exclude date if no overlapping found' do
+ cleaner.begin_date = period.period_end + 1.day
+ cleaner.end_date = cleaner.begin_date + 1.day
+
+ expect { cleaner.exclude_dates_in_overlapping_period(period) }.to_not change {
+ time_table.dates.where(in_out: false).count
+ }
+ end
+ end
+
+ context '#overlapping_periods' do
+ let(:cleaner) { create(:clean_up, date_type: :before, end_date: nil) }
+ let(:time_table) { create(:time_table) }
+
+ it 'should detect overlapping periods' do
+ cleaner.begin_date = time_table.periods[0].period_start
+ expect(cleaner.overlapping_periods).to include(time_table.periods[0])
+ end
+
+ it 'should not return none overlapping periods' do
+ cleaner.begin_date = time_table.periods[0].period_start - 1.day
+ expect(cleaner.overlapping_periods).to_not include(time_table.periods[0])
+ end
+ end
+
+ context '#clean' do
+ let(:cleaner) { create(:clean_up, date_type: :before) }
+
+ it 'should call destroy_time_tables_before' do
+ cleaner.date_type = :before
+ expect(cleaner).to receive(:destroy_time_tables_before)
+ expect(cleaner).to receive(:destroy_time_tables_dates_before)
+ expect(cleaner).to receive(:destroy_time_tables_periods_before)
+ cleaner.clean
+ end
+
+ it 'should call destroy_time_tables_after' do
+ cleaner.date_type = :after
+ expect(cleaner).to receive(:destroy_time_tables_after)
+ expect(cleaner).to receive(:destroy_time_tables_dates_after)
+ expect(cleaner).to receive(:destroy_time_tables_periods_after)
+ cleaner.clean
+ end
+
+ it 'should call destroy_time_tables_between' do
+ cleaner.date_type = :between
+ expect(cleaner).to receive(:destroy_time_tables_between)
+ expect(cleaner).to receive(:destroy_time_tables_dates_between)
+ expect(cleaner).to receive(:destroy_time_tables_periods_between)
+ cleaner.clean
+ end
+ end
+
+ context '#destroy_time_tables_dates_between' do
+ let!(:time_table) { create(:time_table) }
+ let(:cleaner) { create(:clean_up, date_type: :between) }
+
+ before do
+ time_table.periods.clear
+ time_table.save
+ cleaner.begin_date = time_table.start_date
+ cleaner.end_date = time_table.end_date
+ end
+
+ it 'should destroy record' do
+ expect{ cleaner.destroy_time_tables_dates_between }.to change {
+ Chouette::TimeTableDate.count
+ }.by(-time_table.dates.count)
+ end
+
+ it 'should not destroy record not in range' do
+ cleaner.begin_date = time_table.end_date + 1.day
+ cleaner.end_date = cleaner.begin_date + 1.day
+
+ expect{ cleaner.destroy_time_tables_dates_between }.to_not change {
+ Chouette::TimeTableDate.count
+ }
+ end
+ end
+
+ context '#destroy_time_tables_dates_after' do
+ let!(:time_table_date) { create(:time_table_date, date: Date.yesterday, in_out: true) }
+ let(:cleaner) { create(:clean_up, date_type: :after, begin_date: time_table_date.date) }
+
+ it 'should destroy record' do
+ count = Chouette::TimeTableDate.where('date > ?', cleaner.begin_date).count
+ expect{ cleaner.destroy_time_tables_dates_after }.to change {
+ Chouette::TimeTableDate.count
+ }.by(-count)
+ end
+ end
+
+ context '#destroy_time_tables_between' do
+ let!(:time_table) { create(:time_table ) }
+ let(:cleaner) { create(:clean_up, date_type: :after, begin_date: time_table.start_date, end_date: time_table.end_date) }
+
+ it 'should destroy time_tables with validity period in purge range' do
+ expect{ cleaner.destroy_time_tables_between }.to change {
+ Chouette::TimeTable.count
+ }.by(-1)
+ end
+
+ it 'should not destroy time_tables if not totaly inside purge range' do
+ cleaner.begin_date = time_table.start_date + 1.day
+ expect{ cleaner.destroy_time_tables_between }.to_not change {
+ Chouette::TimeTable.count
+ }
+ end
+ end
+
+ context '#destroy_time_tables_after' do
+ let!(:time_table) { create(:time_table ) }
+ let(:cleaner) { create(:clean_up, date_type: :after, begin_date: time_table.start_date - 1.day) }
+
+ it 'should destroy time_tables with start_date > purge begin_date' do
+ expect{ cleaner.destroy_time_tables_after }.to change {
+ Chouette::TimeTable.count
+ }.by(-1)
+ end
+
+ it 'should not destroy time_tables with start_date < purge begin date' do
+ cleaner.begin_date = time_table.end_date
+ expect{ cleaner.destroy_time_tables_after }.to_not change {
+ Chouette::TimeTable.count
+ }
+ end
end
- it 'should delete journeypatterns without vehicle journeys' do
- create_list(:journey_pattern, 2)
- create_list(:vehicle_journey, 2, journey_pattern: create(:journey_pattern))
- expect(cleaner.clean_journey_patterns).to eq 2
+ context '#destroy_time_tables' do
+ let!(:time_table) { create(:time_table) }
+ let(:cleaner) { create(:clean_up, date_type: :before) }
+
+ it 'should destroy all time_tables' do
+ expect{cleaner.destroy_time_tables(Chouette::TimeTable.all)}.to change {
+ Chouette::TimeTable.count
+ }.by(-1)
+ end
+
+ it 'should destroy associated vehicle_journeys' do
+ create(:vehicle_journey, time_tables: [time_table])
+ expect{cleaner.destroy_time_tables(Chouette::TimeTable.all)}.to change {
+ Chouette::VehicleJourney.count
+ }.by(-1)
+ end
+ end
+
+ context '#destroy_time_tables_before' do
+ let!(:time_table) { create(:time_table ) }
+ let(:cleaner) { create(:clean_up, date_type: :before, begin_date: time_table.end_date + 1.day) }
+
+ it 'should destroy time_tables with end_date < purge begin_date' do
+ expect{ cleaner.destroy_time_tables_before }.to change {
+ Chouette::TimeTable.count
+ }.by(-1)
+ end
+
+ it 'should not destroy time_tables with end_date > purge begin date' do
+ cleaner.begin_date = Date.today
+ expect{ cleaner.destroy_time_tables_before }.to_not change {
+ Chouette::TimeTable.count
+ }
+ end
end
end
diff --git a/spec/models/referential_cloning_spec.rb b/spec/models/referential_cloning_spec.rb
index 30391b53e..5acd433ec 100644
--- a/spec/models/referential_cloning_spec.rb
+++ b/spec/models/referential_cloning_spec.rb
@@ -1,4 +1,4 @@
-require 'rails_helper'
+require 'spec_helper'
RSpec.describe ReferentialCloning, :type => :model do
it 'should have a valid factory' do
@@ -7,4 +7,12 @@ RSpec.describe ReferentialCloning, :type => :model do
it { should belong_to :source_referential }
it { should belong_to :target_referential }
+
+ describe "ReferentialCloningWorker" do
+ let(:referential_cloning) { FactoryGirl.create(:referential_cloning) }
+
+ it "should schedule a job in worker" do
+ expect{referential_cloning.run_callbacks(:commit)}.to change {ReferentialCloningWorker.jobs.count}.by(1)
+ end
+ end
end
diff --git a/spec/models/time_table_combination_spec.rb b/spec/models/time_table_combination_spec.rb
index 0a8b3296a..3e60fa444 100644
--- a/spec/models/time_table_combination_spec.rb
+++ b/spec/models/time_table_combination_spec.rb
@@ -87,7 +87,7 @@ describe TimeTableCombination, :type => :model do
end
it "should intersect combined to source" do
- expect(source.int_day_types).to eq(0)
+ expect(source.int_day_types).to eq(508)
expect(source.periods.size).to eq(1)
expect(source.dates.size).to eq(0)
@@ -119,7 +119,7 @@ describe TimeTableCombination, :type => :model do
end
it "should disjoin combined to source" do
- expect(source.int_day_types).to eq(0)
+ expect(source.int_day_types).to eq(508)
expect(source.periods.size).to eq(1)
expect(source.dates.size).to eq(0)
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 5c7aa0b98..6f98e5ce7 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -118,7 +118,7 @@ describe User, :type => :model do
context 'permissions' do
it 'should give edit permissions to user if user has "edit offer" permission in portail' do
User.portail_sync
- expect(User.find_by(username: 'vlatka.pavisic').permissions).not_to be_empty
+ expect(User.find_by(username: 'vlatka.pavisic').permissions).to include_all(User.edit_offer_permissions)
expect(User.find_by(username: 'pierre.vabre').permissions).to be_empty
end
end
diff --git a/spec/policies/boiv_policy_spec.rb b/spec/policies/boiv_policy_spec.rb
index bf09cdcd9..514534adc 100644
--- a/spec/policies/boiv_policy_spec.rb
+++ b/spec/policies/boiv_policy_spec.rb
@@ -11,5 +11,4 @@ RSpec.describe BoivPolicy, type: :policy do
permissions :show? do
it_behaves_like 'permitted policy and same organisation', 'boiv:read-offer'
end
-
end
diff --git a/spec/policies/login_policy_spec.rb b/spec/policies/login_policy_spec.rb
new file mode 100644
index 000000000..132e57433
--- /dev/null
+++ b/spec/policies/login_policy_spec.rb
@@ -0,0 +1,15 @@
+RSpec.describe LoginPolicy, type: :policy do
+ permissions :boiv? do
+ it 'no permission starting with boiv:. → denies' do
+ expect( LoginPolicy.new(user_context.user) ).not_to be_boiv
+ end
+
+ with_user_permission 'boiv:anything' do
+ it { expect( LoginPolicy.new(user_context.user) ).to be_boiv }
+ end
+ with_user_permission 'boiv:' do
+ it { expect( LoginPolicy.new(user_context.user) ).not_to be_boiv }
+ end
+ end
+
+end
diff --git a/spec/support/bare_sql.rb b/spec/support/bare_sql.rb
new file mode 100644
index 000000000..03a50ef77
--- /dev/null
+++ b/spec/support/bare_sql.rb
@@ -0,0 +1,58 @@
+module Support
+ module BareSQL
+
+ def insert(schema, table, values)
+ execute "INSERT INTO #{schema}.#{table} (#{_keys(values)}) VALUES (#{_values values})"
+ end
+
+ def execute(sql)
+ base_connection.execute(sql)
+ end
+
+ def expect_same_content(table_name)
+ expected_content = get_content(source_schema, table_name)
+ actual_content = get_content(target_schema, table_name)
+ expect( actual_content ).to eq(expected_content)
+ end
+
+ def expect_same_sequence_params(sequence_name)
+ expected_seq = Hash.without(get_sequences(source_schema, sequence_name).first, 'log_cnt')
+ actual_seq = Hash.without(get_sequences(target_schema, sequence_name).first, 'log_cnt')
+ expect( actual_seq ).to eq(expected_seq)
+ end
+
+ def get_content(schema_name, table_name)
+ execute("SELECT * FROM #{schema_name}.#{table_name}").to_a
+ end
+
+ private
+
+ def base_connection
+ ActiveRecord::Base.connection
+ end
+
+ def _keys(values)
+ values.keys.map(&:to_s).join(", ")
+ end
+
+ def _values(values)
+ values
+ .values
+ .map(&method(:_format))
+ .join(', ')
+ end
+
+ def _format(val)
+ case val
+ when String
+ "'#{val}'"
+ when TrueClass
+ "'t'"
+ when FalseClass
+ "'f'"
+ else
+ val.to_s
+ end
+ end
+ end
+end
diff --git a/spec/support/custom_matchers.rb b/spec/support/custom_matchers.rb
new file mode 100644
index 000000000..bdc3efaa0
--- /dev/null
+++ b/spec/support/custom_matchers.rb
@@ -0,0 +1,7 @@
+require 'rspec/expectations'
+
+RSpec::Matchers.define :include_all do |expected|
+ match do |actual|
+ ( expected - actual ).empty?
+ end
+end
diff --git a/spec/support/devise.rb b/spec/support/devise.rb
index 14e316bea..d4a279a41 100644
--- a/spec/support/devise.rb
+++ b/spec/support/devise.rb
@@ -36,8 +36,8 @@ module DeviseRequestHelper
end
module DeviseControllerHelper
- def login_user
- before(:each) do
+ def setup_user
+ before do
@request.env["devise.mapping"] = Devise.mappings[:user]
organisation = Organisation.where(:code => "first").first_or_create(attributes_for(:organisation))
@user = create(:user, :organisation => organisation,
@@ -47,6 +47,11 @@ module DeviseControllerHelper
'access_points.create', 'access_points.edit', 'access_points.destroy', 'access_links.create', 'access_links.edit', 'access_links.destroy',
'connection_links.create', 'connection_links.edit', 'connection_links.destroy', 'route_sections.create', 'route_sections.edit', 'route_sections.destroy',
'referentials.create', 'referentials.edit', 'referentials.destroy'])
+ end
+ end
+ def login_user()
+ setup_user
+ before do
sign_in @user
end
end
diff --git a/spec/support/hash.rb b/spec/support/hash.rb
new file mode 100644
index 000000000..ec9a2f895
--- /dev/null
+++ b/spec/support/hash.rb
@@ -0,0 +1,6 @@
+class << Hash
+ def without(hash, *keys)
+ nk = hash.keys - keys
+ Hash[*nk.zip(hash.values_at(*nk)).flatten]
+ end
+end
diff --git a/spec/support/pg_catalog.rb b/spec/support/pg_catalog.rb
index bb61adba5..ca02f2550 100644
--- a/spec/support/pg_catalog.rb
+++ b/spec/support/pg_catalog.rb
@@ -1,11 +1,12 @@
+require_relative 'bare_sql'
module Support
module PGCatalog
- # TODO: Check what of the follwowing can be done with ActiveRecord. E.g.
- # @connection.foreign_keys(table)...
+ include Support::BareSQL
def get_columns(schema_name, table_name)
- execute("SELECT * from information_schema.columns WHERE table_name = '#{table_name}' AND table_schema = '#{schema_name}'")
+ execute("SELECT column_name, column_default FROM information_schema.columns WHERE table_name = '#{table_name}' AND table_schema = '#{schema_name}'").to_a
end
+
def get_foreign_keys(schema_oid, table_name)
schema_oid = get_schema_oid(schema_oid) unless Integer === schema_oid
return [] unless schema_oid
@@ -20,11 +21,8 @@ module Support
.first
end
- def get_sequences(schema_name, table_name)
- sequences = execute <<-EOSQL
- SELECT sequence_name FROM information_schema.sequences
- WHERE sequence_schema = '#{schema_name}' AND sequence_name LIKE '#{table_name}%'
- EOSQL
+ def get_sequences(schema_name, sequence_name)
+ sequences = execute(sequence_query(schema_name, sequence_name))
sequences.values.flatten.map do | sequence |
execute "SELECT * from #{schema_name}.#{sequence}"
end.flat_map(&:to_a)
@@ -38,39 +36,20 @@ module Support
private
- def base_connection
- ActiveRecord::Base.connection
- end
-
- def execute(sql)
- base_connection.execute(sql)
- end
def foreign_key_query(schema_oid, table_name)
- key = [:foreign_key_query, schema_oid, table_name]
- get_or_create_query(key){ <<-EOQ
- SELECT ct.conname AS constraint_name, pg_get_constraintdef(ct.oid) AS constraint_def
- FROM pg_constraint ct JOIN pg_class rn ON rn.oid = ct.conrelid
- WHERE connamespace = #{schema_oid} AND rn.relname = '#{table_name}' AND rn.relkind = 'r' AND ct.contype = 'f'
- EOQ
- }
- end
-
- def sequence_properties_query(schema_name, sequence_name)
- key = [:sequence_properies_query, schema_name, sequence_name]
- get_or_create_query(key){ <<-EOQ
- Coming Soon
- EOQ
- }
-
- end
-
- def get_or_create_query(query_key, &query_value)
- queries.fetch(query_key){ queries[query_key] = query_value.() }
+ <<-EOQ
+ SELECT ct.conname AS constraint_name, pg_get_constraintdef(ct.oid) AS constraint_def
+ FROM pg_constraint ct JOIN pg_class rn ON rn.oid = ct.conrelid
+ WHERE connamespace = #{schema_oid} AND rn.relname = '#{table_name}' AND rn.relkind = 'r' AND ct.contype = 'f'
+ EOQ
end
- def queries
- @__queries__ ||= {}
+ def sequence_query(schema_name, sequence_name)
+ <<-EOQ
+ SELECT sequence_name FROM information_schema.sequences
+ WHERE sequence_schema = '#{schema_name}' AND sequence_name = '#{sequence_name}'
+ EOQ
end
def without_keys(*keys)
@@ -82,3 +61,7 @@ module Support
end
end
end
+
+RSpec.configure do | conf |
+ conf.include Support::PGCatalog, type: :pg_catalog
+end
diff --git a/spec/support/pundit/policies.rb b/spec/support/pundit/policies.rb
index 637a2a528..e18309226 100644
--- a/spec/support/pundit/policies.rb
+++ b/spec/support/pundit/policies.rb
@@ -16,6 +16,7 @@ module Support
for_user.permissions ||= []
for_user.permissions += permissions.flatten
end
+
end
module PoliciesMacros
@@ -27,6 +28,12 @@ module Support
let( :user ) { create :user }
end
end
+ def with_user_permission(permission, &blk)
+ it "with user permission #{permission.inspect}" do
+ add_permissions(permission, for_user: user)
+ blk.()
+ end
+ end
end
end
end
diff --git a/spec/views/referentials/new.html.erb_spec.rb b/spec/views/referentials/new.html.erb_spec.rb
index 0673b4578..554e71d29 100644
--- a/spec/views/referentials/new.html.erb_spec.rb
+++ b/spec/views/referentials/new.html.erb_spec.rb
@@ -5,15 +5,9 @@ describe "referentials/new", :type => :view do
before(:each) do
assign(:referential, Referential.new)
end
-
+
it "should have a textfield for name" do
render
expect(rendered).to have_field("referential[name]")
end
-
- it "should have a textfield for slug" do
- render
- expect(rendered).to have_field("referential[slug]")
- end
-
end
diff --git a/spec/workers/referential_cloning_worker_spec.rb b/spec/workers/referential_cloning_worker_spec.rb
index 85d771742..52ed8913b 100644
--- a/spec/workers/referential_cloning_worker_spec.rb
+++ b/spec/workers/referential_cloning_worker_spec.rb
@@ -9,37 +9,29 @@ RSpec.describe ReferentialCloningWorker do
let( :worker ){ described_class.new }
+ def make_referential(schema_name)
+ return OpenStruct.new( slug: schema_name )
+ end
let( :source_schema ){ "source_schema" }
- let( :target_schema ){ "#{source_schema}_tmp" }
- let( :referential_cloning ){ OpenStruct.new(source_referential: OpenStruct.new(slug: source_schema)) }
+ let( :target_schema ){ "target_schema" }
+ let( :referential_cloning ){ OpenStruct.new(source_referential: make_referential(source_schema),
+ target_referential: make_referential(target_schema)) }
+ let( :cloner ){ 'cloner' }
+
before do
expect( ReferentialCloning ).to receive(:find).with(id).and_return(referential_cloning)
- expect( StoredProcedures )
- .to receive(:invoke_stored_procedure)
- .with(:clone_schema, source_schema, target_schema, true)
-
- expect( worker ).to receive(:execute_sql).with( "DROP SCHEMA #{source_schema} CASCADE;" )
+ expect( AF83::SchemaCloner ).to receive(:new).with( source_schema, target_schema ).and_return(cloner)
+ expect( cloner ).to receive(:clone_schema)
expect( referential_cloning ).to receive(:run!)
end
it "invokes the correct stored procedure, updates the database and the AASM" do
- expect( worker ).to receive(:execute_sql).with( "ALTER SCHEMA #{target_schema} RENAME TO #{source_schema};" )
expect( referential_cloning ).to receive(:successful!)
worker.perform(id)
end
-
- it "handles failure correctly" do
- expect( worker )
- .to receive(:execute_sql)
- .with( "ALTER SCHEMA #{target_schema} RENAME TO #{source_schema};" )
- .and_raise(RuntimeError)
-
- expect( referential_cloning ).to receive(:failed!)
- worker.perform(id)
- end
end
-
+
end