diff options
| author | Xinhui | 2017-08-08 12:04:50 +0200 |
|---|---|---|
| committer | Xinhui | 2017-08-08 12:44:39 +0200 |
| commit | 117954f2666744b5301a7ffefb0b7d494fd49514 (patch) | |
| tree | 8bd03f0c5b33d3842ae07aa252e194e7d33044da | |
| parent | 2cf8146cdb4a28fe247108f98c5bc7eb05940e05 (diff) | |
| parent | d524e5474a913df296d4f4586eba4b879bad8b6f (diff) | |
| download | chouette-core-117954f2666744b5301a7ffefb0b7d494fd49514.tar.bz2 | |
Merge branch 'checksum'
29 files changed, 294 insertions, 287 deletions
diff --git a/app/models/chouette/footnote.rb b/app/models/chouette/footnote.rb index de427b249..1664faf23 100644 --- a/app/models/chouette/footnote.rb +++ b/app/models/chouette/footnote.rb @@ -1,6 +1,13 @@ class Chouette::Footnote < Chouette::ActiveRecord + include ChecksumSupport + belongs_to :line, inverse_of: :footnotes has_and_belongs_to_many :vehicle_journeys, :class_name => 'Chouette::VehicleJourney' validates_presence_of :line + + def checksum_attributes + attrs = ['code', 'label'] + self.slice(*attrs).values + end end diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb index f238d7339..fa5fba26d 100644 --- a/app/models/chouette/journey_pattern.rb +++ b/app/models/chouette/journey_pattern.rb @@ -1,4 +1,5 @@ class Chouette::JourneyPattern < Chouette::TridentActiveRecord + include ChecksumSupport include JourneyPatternRestrictions # FIXME http://jira.codehaus.org/browse/JRUBY-6358 self.primary_key = "id" @@ -20,6 +21,12 @@ class Chouette::JourneyPattern < Chouette::TridentActiveRecord attr_accessor :control_checked after_update :control_route_sections, :unless => "control_checked" + def checksum_attributes + values = self.slice(*['name', 'published_name', 'registration_number']).values + values << self.stop_points.map(&:stop_area).map(&:user_objectid) + values.flatten + end + def self.state_update route, state transaction do state.each do |item| diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 76905bf2b..6774e8a86 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -1,5 +1,6 @@ class Chouette::Route < Chouette::TridentActiveRecord include RouteRestrictions + include ChecksumSupport extend Enumerize extend ActiveModel::Naming @@ -99,6 +100,14 @@ class Chouette::Route < Chouette::TridentActiveRecord end end + def checksum_attributes + values = self.slice(*['name', 'published_name', 'wayback']).values + values.tap do |attrs| + attrs << self.stop_points.map{|sp| "#{sp.stop_area.user_objectid}#{sp.for_boarding}#{sp.for_alighting}" }.join + attrs << self.routing_constraint_zones.map(&:checksum) + end + end + def geometry points = stop_areas.map(&:to_lat_lng).compact.map do |loc| [loc.lng, loc.lat] diff --git a/app/models/chouette/routing_constraint_zone.rb b/app/models/chouette/routing_constraint_zone.rb index a649b0b8e..9931748b2 100644 --- a/app/models/chouette/routing_constraint_zone.rb +++ b/app/models/chouette/routing_constraint_zone.rb @@ -1,4 +1,6 @@ class Chouette::RoutingConstraintZone < Chouette::TridentActiveRecord + include ChecksumSupport + belongs_to :route has_array_of :stop_points, class_name: 'Chouette::StopPoint' @@ -15,6 +17,10 @@ class Chouette::RoutingConstraintZone < Chouette::TridentActiveRecord .order("routes.name #{direction}") end + def checksum_attributes + self.stop_points.map(&:stop_area).map(&:user_objectid) + end + def stop_points_belong_to_route errors.add(:stop_point_ids, I18n.t('activerecord.errors.models.routing_constraint_zone.attributes.stop_points.stop_points_not_from_route')) unless stop_points.all? { |sp| route.stop_points.include? sp } end diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb index 1753cbed5..97d2e7556 100644 --- a/app/models/chouette/time_table.rb +++ b/app/models/chouette/time_table.rb @@ -1,4 +1,5 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord + include ChecksumSupport include TimeTableRestrictions # FIXME http://jira.codehaus.org/browse/JRUBY-6358 self.primary_key = "id" @@ -26,6 +27,14 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord after_save :save_shortcuts + def checksum_attributes + [].tap do |attrs| + attrs << self.int_day_types + attrs << self.dates.map(&:checksum).map(&:to_s).sort + attrs << self.periods.map(&:checksum).map(&:to_s).sort + end + end + def self.object_id_key "Timetable" end diff --git a/app/models/chouette/time_table_date.rb b/app/models/chouette/time_table_date.rb index b881c9a5d..1893eae91 100644 --- a/app/models/chouette/time_table_date.rb +++ b/app/models/chouette/time_table_date.rb @@ -1,4 +1,6 @@ class Chouette::TimeTableDate < Chouette::ActiveRecord + include ChecksumSupport + self.primary_key = "id" belongs_to :time_table, inverse_of: :dates acts_as_list :scope => 'time_table_id = #{time_table_id}',:top_of_list => 0 @@ -12,5 +14,9 @@ class Chouette::TimeTableDate < Chouette::ActiveRecord ActiveModel::Name.new Chouette::TimeTableDate, Chouette, "TimeTableDate" end + def checksum_attributes + attrs = ['date', 'in_out'] + self.slice(*attrs).values + end end diff --git a/app/models/chouette/time_table_period.rb b/app/models/chouette/time_table_period.rb index 6d3486bb6..ed136f3b9 100644 --- a/app/models/chouette/time_table_period.rb +++ b/app/models/chouette/time_table_period.rb @@ -1,4 +1,6 @@ class Chouette::TimeTablePeriod < Chouette::ActiveRecord + include ChecksumSupport + self.primary_key = "id" belongs_to :time_table, inverse_of: :periods acts_as_list :scope => 'time_table_id = #{time_table_id}',:top_of_list => 0 @@ -7,6 +9,10 @@ class Chouette::TimeTablePeriod < Chouette::ActiveRecord validate :start_must_be_before_end + def checksum_attributes + attrs = ['period_start', 'period_end'] + self.slice(*attrs).values + end def self.model_name ActiveModel::Name.new Chouette::TimeTablePeriod, Chouette, "TimeTablePeriod" diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb index 5e86a4897..d5ca58959 100644 --- a/app/models/chouette/vehicle_journey.rb +++ b/app/models/chouette/vehicle_journey.rb @@ -1,5 +1,6 @@ module Chouette class VehicleJourney < TridentActiveRecord + include ChecksumSupport include VehicleJourneyRestrictions include StifTransportModeEnumerations # FIXME http://jira.codehaus.org/browse/JRUBY-6358 @@ -55,6 +56,16 @@ module Chouette end end + def checksum_attributes + [].tap do |attrs| + attrs << self.published_journey_name + attrs << self.published_journey_identifier + attrs << self.try(:company).try(:objectid).try(:local_id) + attrs << self.footnotes.map(&:checksum).sort + attrs << self.vehicle_journey_at_stops.map(&:checksum).sort + end + end + def set_default_values if number.nil? self.number = 0 diff --git a/app/models/chouette/vehicle_journey_at_stop.rb b/app/models/chouette/vehicle_journey_at_stop.rb index 35d94aa75..156cc761f 100644 --- a/app/models/chouette/vehicle_journey_at_stop.rb +++ b/app/models/chouette/vehicle_journey_at_stop.rb @@ -2,6 +2,7 @@ module Chouette class VehicleJourneyAtStop < ActiveRecord include ForBoardingEnumerations include ForAlightingEnumerations + include ChecksumSupport DAY_OFFSET_MAX = 1 @@ -66,6 +67,13 @@ module Chouette offset < 0 || offset > DAY_OFFSET_MAX end - + def checksum_attributes + [].tap do |attrs| + attrs << self.departure_time.try(:to_s, :time) + attrs << self.arrival_time.try(:to_s, :time) + attrs << self.departure_day_offset.to_s + attrs << self.arrival_day_offset.to_s + end + end end end diff --git a/app/models/concerns/checksum_support.rb b/app/models/concerns/checksum_support.rb new file mode 100644 index 000000000..c95e23bcf --- /dev/null +++ b/app/models/concerns/checksum_support.rb @@ -0,0 +1,29 @@ +module ChecksumSupport + extend ActiveSupport::Concern + SEPARATOR = '|' + VALUE_FOR_NIL_ATTRIBUTE = '-' + + included do + before_save :set_current_checksum_source, :update_checksum + end + + def checksum_attributes + self.attributes.values + end + + def current_checksum_source + source = self.checksum_attributes.map{ |x| x unless x.try(:empty?) } + source = source.map{ |x| x || VALUE_FOR_NIL_ATTRIBUTE } + source.map(&:to_s).join(SEPARATOR) + end + + def set_current_checksum_source + self.checksum_source = self.current_checksum_source + end + + def update_checksum + if self.checksum_source_changed? + self.checksum = Digest::SHA256.new.hexdigest(self.checksum_source) + end + end +end diff --git a/db/migrate/20170710125809_add_check_sum.rb b/db/migrate/20170710125809_add_check_sum.rb new file mode 100644 index 000000000..b91ddb74d --- /dev/null +++ b/db/migrate/20170710125809_add_check_sum.rb @@ -0,0 +1,13 @@ +class AddCheckSum < ActiveRecord::Migration + def change + add_column :vehicle_journey_at_stops, :checksum, :string + add_column :footnotes, :checksum, :string + add_column :routing_constraint_zones, :checksum, :string + add_column :routes, :checksum, :string + add_column :journey_patterns, :checksum, :string + add_column :vehicle_journeys, :checksum, :string + add_column :time_table_dates, :checksum, :string + add_column :time_table_periods, :checksum, :string + add_column :time_tables, :checksum, :string + end +end diff --git a/db/migrate/20170710130230_add_check_sum_source.rb b/db/migrate/20170710130230_add_check_sum_source.rb new file mode 100644 index 000000000..b8e36e954 --- /dev/null +++ b/db/migrate/20170710130230_add_check_sum_source.rb @@ -0,0 +1,13 @@ +class AddCheckSumSource < ActiveRecord::Migration + def change + add_column :vehicle_journey_at_stops, :checksum_source, :string + add_column :footnotes, :checksum_source, :string + add_column :routing_constraint_zones, :checksum_source, :string + add_column :routes, :checksum_source, :string + add_column :journey_patterns, :checksum_source, :string + add_column :vehicle_journeys, :checksum_source, :string + add_column :time_table_dates, :checksum_source, :string + add_column :time_table_periods, :checksum_source, :string + add_column :time_tables, :checksum_source, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 799283993..97f2b26d1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -211,11 +211,13 @@ ActiveRecord::Schema.define(version: 20170802141224) do end create_table "footnotes", id: :bigserial, force: :cascade do |t| - t.integer "line_id", limit: 8 + t.integer "line_id", limit: 8 t.string "code" t.string "label" t.datetime "created_at" t.datetime "updated_at" + t.string "checksum" + t.string "checksum_source" end create_table "footnotes_vehicle_journeys", id: false, force: :cascade do |t| @@ -284,12 +286,12 @@ ActiveRecord::Schema.define(version: 20170802141224) do t.datetime "started_at" t.datetime "ended_at" t.string "token_download" - t.string "type", limit: 255 + t.string "type" t.integer "parent_id", limit: 8 t.string "parent_type" - t.integer "current_step", default: 0 - t.integer "total_steps", default: 0 t.datetime "notified_parent_at" + t.integer "current_step", default: 0 + t.integer "total_steps", default: 0 end add_index "imports", ["referential_id"], name: "index_imports_on_referential_id", using: :btree @@ -335,6 +337,8 @@ ActiveRecord::Schema.define(version: 20170802141224) do t.integer "section_status", default: 0, null: false t.datetime "created_at" t.datetime "updated_at" + t.string "checksum" + t.string "checksum_source" end add_index "journey_patterns", ["objectid"], name: "journey_patterns_objectid_key", unique: true, using: :btree @@ -543,6 +547,8 @@ ActiveRecord::Schema.define(version: 20170802141224) do t.string "wayback" t.datetime "created_at" t.datetime "updated_at" + t.string "checksum" + t.string "checksum_source" end add_index "routes", ["objectid"], name: "routes_objectid_key", unique: true, using: :btree @@ -551,11 +557,13 @@ ActiveRecord::Schema.define(version: 20170802141224) do t.string "name" t.datetime "created_at" t.datetime "updated_at" - t.string "objectid", null: false - t.integer "object_version", limit: 8 + t.string "objectid", null: false + t.integer "object_version", limit: 8 t.string "creator_id" - t.integer "route_id", limit: 8 - t.integer "stop_point_ids", limit: 8, array: true + t.integer "route_id", limit: 8 + t.integer "stop_point_ids", limit: 8, array: true + t.string "checksum" + t.string "checksum_source" end create_table "routing_constraints_lines", id: false, force: :cascade do |t| @@ -607,7 +615,7 @@ ActiveRecord::Schema.define(version: 20170802141224) do create_table "stop_areas", id: :bigserial, force: :cascade do |t| t.integer "parent_id", limit: 8 - t.string "objectid", null: false + t.string "objectid", null: false t.integer "object_version", limit: 8 t.string "creator_id" t.string "name" @@ -616,8 +624,8 @@ ActiveRecord::Schema.define(version: 20170802141224) do t.string "registration_number" t.string "nearest_topic_name" t.integer "fare_code" - t.decimal "longitude", precision: 19, scale: 16 - t.decimal "latitude", precision: 19, scale: 16 + t.decimal "longitude", precision: 19, scale: 16 + t.decimal "latitude", precision: 19, scale: 16 t.string "long_lat_type" t.string "country_code" t.string "street_name" @@ -635,7 +643,7 @@ ActiveRecord::Schema.define(version: 20170802141224) do t.datetime "deleted_at" t.datetime "created_at" t.datetime "updated_at" - t.string "stif_type", limit: 255 + t.string "stif_type" end add_index "stop_areas", ["name"], name: "index_stop_areas_on_name", using: :btree @@ -684,37 +692,43 @@ ActiveRecord::Schema.define(version: 20170802141224) do add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree create_table "time_table_dates", id: :bigserial, force: :cascade do |t| - t.integer "time_table_id", limit: 8, null: false + t.integer "time_table_id", limit: 8, null: false t.date "date" - t.integer "position", null: false + t.integer "position", null: false t.boolean "in_out" + t.string "checksum" + t.string "checksum_source" end add_index "time_table_dates", ["time_table_id"], name: "index_time_table_dates_on_time_table_id", using: :btree create_table "time_table_periods", id: :bigserial, force: :cascade do |t| - t.integer "time_table_id", limit: 8, null: false + t.integer "time_table_id", limit: 8, null: false t.date "period_start" t.date "period_end" - t.integer "position", null: false + t.integer "position", null: false + t.string "checksum" + t.string "checksum_source" end add_index "time_table_periods", ["time_table_id"], name: "index_time_table_periods_on_time_table_id", using: :btree create_table "time_tables", id: :bigserial, force: :cascade do |t| - t.string "objectid", null: false - t.integer "object_version", limit: 8, default: 1 + t.string "objectid", null: false + t.integer "object_version", limit: 8, default: 1 t.string "creator_id" t.string "version" t.string "comment" - t.integer "int_day_types", default: 0 + t.integer "int_day_types", default: 0 t.date "start_date" t.date "end_date" t.integer "calendar_id", limit: 8 t.datetime "created_at" t.datetime "updated_at" - t.string "color", limit: 255 + t.string "color" t.integer "created_from_id" + t.string "checksum" + t.string "checksum_source" end add_index "time_tables", ["calendar_id"], name: "index_time_tables_on_calendar_id", using: :btree @@ -791,6 +805,8 @@ ActiveRecord::Schema.define(version: 20170802141224) do t.string "for_alighting" t.integer "departure_day_offset", default: 0 t.integer "arrival_day_offset", default: 0 + t.string "checksum" + t.string "checksum_source" end add_index "vehicle_journey_at_stops", ["stop_point_id"], name: "index_vehicle_journey_at_stops_on_stop_pointid", using: :btree @@ -816,6 +832,8 @@ ActiveRecord::Schema.define(version: 20170802141224) do t.integer "journey_category", default: 0, null: false t.datetime "created_at" t.datetime "updated_at" + t.string "checksum" + t.string "checksum_source" end add_index "vehicle_journeys", ["objectid"], name: "vehicle_journeys_objectid_key", unique: true, using: :btree diff --git a/spec/factories/chouette_journey_pattern.rb b/spec/factories/chouette_journey_pattern.rb index bf55b286f..62241f313 100644 --- a/spec/factories/chouette_journey_pattern.rb +++ b/spec/factories/chouette_journey_pattern.rb @@ -1,14 +1,14 @@ FactoryGirl.define do - + factory :journey_pattern_common, :class => Chouette::JourneyPattern do sequence(:name) { |n| "jp name #{n}" } sequence(:published_name) { |n| "jp publishedname #{n}" } sequence(:comment) { |n| "jp comment #{n}" } sequence(:registration_number) { |n| "jp registration_number #{n}" } sequence(:objectid) { |n| "test:JourneyPattern:#{n}" } - + association :route, :factory => :route - + factory :journey_pattern do after(:create) do |j| j.stop_point_ids = j.route.stop_points.map(&:id) @@ -16,7 +16,7 @@ FactoryGirl.define do j.arrival_stop_point_id = j.route.stop_points.last.id end end - + factory :journey_pattern_odd do after(:create) do |j| j.stop_point_ids = j.route.stop_points.select { |sp| sp.position%2==0}.map(&:id) @@ -24,7 +24,7 @@ FactoryGirl.define do j.arrival_stop_point_id = j.stop_point_ids.last end end - + factory :journey_pattern_even do after(:create) do |j| j.stop_point_ids = j.route.stop_points.select { |sp| sp.position%2==1}.map(&:id) diff --git a/spec/factories/chouette_routes.rb b/spec/factories/chouette_routes.rb index c1a9423c5..a707bcbf6 100644 --- a/spec/factories/chouette_routes.rb +++ b/spec/factories/chouette_routes.rb @@ -18,6 +18,7 @@ FactoryGirl.define do after(:create) do |route, evaluator| create_list(:stop_point, evaluator.stop_points_count, route: route) + route.reload end factory :route_with_journey_patterns do diff --git a/spec/factories/chouette_time_table.rb b/spec/factories/chouette_time_table.rb index 6480df79d..b410d4ab8 100644 --- a/spec/factories/chouette_time_table.rb +++ b/spec/factories/chouette_time_table.rb @@ -1,12 +1,4 @@ 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 - end - factory :time_table, :class => Chouette::TimeTable do sequence(:comment) { |n| "Timetable #{n}" } sequence(:objectid) { |n| "test:Timetable:#{n}" } diff --git a/spec/factories/chouette_time_table_dates.rb b/spec/factories/chouette_time_table_dates.rb new file mode 100644 index 000000000..62fdb3917 --- /dev/null +++ b/spec/factories/chouette_time_table_dates.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :time_table_date, class: Chouette::TimeTableDate do + association :time_table + end +end diff --git a/spec/factories/chouette_time_table_periods.rb b/spec/factories/chouette_time_table_periods.rb new file mode 100644 index 000000000..66640bbcc --- /dev/null +++ b/spec/factories/chouette_time_table_periods.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :time_table_period, class: Chouette::TimeTablePeriod do + association :time_table + period_start { Date.today } + period_end { Date.today + 1.month } + end +end diff --git a/spec/factories/chouette_vehicle_journey.rb b/spec/factories/chouette_vehicle_journey.rb index e7ecb79ac..d1e00cd1d 100644 --- a/spec/factories/chouette_vehicle_journey.rb +++ b/spec/factories/chouette_vehicle_journey.rb @@ -11,6 +11,7 @@ FactoryGirl.define do end factory :vehicle_journey do + association :company, factory: :company transient do stop_arrival_time '01:00:00' stop_departure_time '03:00:00' diff --git a/spec/factories/chouette_vehicle_journey_at_stop.rb b/spec/factories/chouette_vehicle_journey_at_stop.rb index c452a1317..831e347d4 100644 --- a/spec/factories/chouette_vehicle_journey_at_stop.rb +++ b/spec/factories/chouette_vehicle_journey_at_stop.rb @@ -1,8 +1,9 @@ FactoryGirl.define do - factory :vehicle_journey_at_stop, :class => Chouette::VehicleJourneyAtStop do association :vehicle_journey, :factory => :vehicle_journey + departure_day_offset { 0 } + departure_time { Time.now } + arrival_time { Time.now - 1.hour } end - end diff --git a/spec/models/chouette/footnote_spec.rb b/spec/models/chouette/footnote_spec.rb index 5c09e3931..98d751499 100644 --- a/spec/models/chouette/footnote_spec.rb +++ b/spec/models/chouette/footnote_spec.rb @@ -1,9 +1,22 @@ require 'spec_helper' -describe Chouette::Footnote do - - subject { build(:footnote) } +describe Chouette::Footnote, type: :model do + let(:footnote) { create(:footnote) } it { should validate_presence_of :line } + describe 'checksum' do + it_behaves_like 'checksum support', :footnote + + context '#checksum_attributes' do + it 'should return code and label' do + expected = [footnote.code, footnote.label] + expect(footnote.checksum_attributes).to include(*expected) + end + + it 'should not return other atrributes' do + expect(footnote.checksum_attributes).to_not include(footnote.updated_at) + end + end + end end diff --git a/spec/models/chouette/journey_pattern_spec.rb b/spec/models/chouette/journey_pattern_spec.rb index 26d220056..047022ade 100644 --- a/spec/models/chouette/journey_pattern_spec.rb +++ b/spec/models/chouette/journey_pattern_spec.rb @@ -1,6 +1,9 @@ require 'spec_helper' describe Chouette::JourneyPattern, :type => :model do + describe 'checksum' do + it_behaves_like 'checksum support', :journey_pattern + end # context 'validate minimum stop_points size' do # let(:journey_pattern) { create :journey_pattern } diff --git a/spec/models/chouette/route/route_base_spec.rb b/spec/models/chouette/route/route_base_spec.rb index 08f201022..c93b311ff 100644 --- a/spec/models/chouette/route/route_base_spec.rb +++ b/spec/models/chouette/route/route_base_spec.rb @@ -1,6 +1,9 @@ RSpec.describe Chouette::Route, :type => :model do subject { create(:route) } + describe 'checksum' do + it_behaves_like 'checksum support', :route + end describe '#objectid' do subject { super().objectid } @@ -62,8 +65,4 @@ RSpec.describe Chouette::Route, :type => :model do end end end - end - - - diff --git a/spec/models/chouette/routing_constraint_zone_spec.rb b/spec/models/chouette/routing_constraint_zone_spec.rb index 0165c369d..054cfb9e6 100644 --- a/spec/models/chouette/routing_constraint_zone_spec.rb +++ b/spec/models/chouette/routing_constraint_zone_spec.rb @@ -9,6 +9,10 @@ describe Chouette::RoutingConstraintZone, type: :model do # shoulda matcher to validate length of array ? xit { is_expected.to validate_length_of(:stop_point_ids).is_at_least(2) } + describe 'checksum' do + it_behaves_like 'checksum support', :routing_constraint_zone + end + describe 'validations' do it 'validates the presence of route_id' do expect { diff --git a/spec/models/chouette/time_table_period_spec.rb b/spec/models/chouette/time_table_period_spec.rb index 07dc602cb..cc1a3ae09 100644 --- a/spec/models/chouette/time_table_period_spec.rb +++ b/spec/models/chouette/time_table_period_spec.rb @@ -4,11 +4,15 @@ describe Chouette::TimeTablePeriod, :type => :model do let!(:time_table) { create(:time_table)} subject { create(:time_table_period ,:time_table => time_table, :period_start => Date.new(2014,6,30), :period_end => Date.new(2014,7,6) ) } - let!(:p2) {create(:time_table_period ,:time_table => time_table, :period_start => Date.new(2014,7,6), :period_end => Date.new(2014,7,14) ) } + let!(:p2) {create(:time_table_period ,:time_table => time_table, :period_start => Date.new(2014,7,6), :period_end => Date.new(2014,7,14) ) } it { is_expected.to validate_presence_of :period_start } it { is_expected.to validate_presence_of :period_end } - + + describe 'checksum' do + it_behaves_like 'checksum support', :time_table_period + end + describe "#overlap" do context "when periods intersect, " do it "should detect period overlap" do diff --git a/spec/models/chouette/time_table_spec.rb b/spec/models/chouette/time_table_spec.rb index f13e13d52..c4eaeaaf0 100644 --- a/spec/models/chouette/time_table_spec.rb +++ b/spec/models/chouette/time_table_spec.rb @@ -840,252 +840,15 @@ end :period_end => Date.new(2013, 05, 30)) expect(time_table.intersects([ Date.new(2013, 05, 27), Date.new(2013, 05, 28)])).to eq([ Date.new(2013, 05, 27), Date.new(2013, 05, 28)]) end - - - end - - describe "#include_day?" do - it "should return true if a date equal day" do - time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1") - time_table.dates << Chouette::TimeTableDate.new( :date => Date.today, :in_out => true) - expect(time_table.include_day?(Date.today)).to eq(true) - end - - it "should return true if a period include day" do - time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1", :int_day_types => 12) # Day type monday and tuesday - time_table.periods << Chouette::TimeTablePeriod.new( - :period_start => Date.new(2013, 05, 27), - :period_end => Date.new(2013, 05, 29)) - expect(time_table.include_day?( Date.new(2013, 05, 27))).to eq(true) - end - end - - describe "#include_in_dates?" do - it "should return true if a date equal day" do - time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1") - time_table.dates << Chouette::TimeTableDate.new( :date => Date.today, :in_out => true) - expect(time_table.include_in_dates?(Date.today)).to eq(true) - end - - it "should return false if a period include day but that is exclued" do - time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1", :int_day_types => 12) # Day type monday and tuesday - excluded_date = Date.new(2013, 05, 27) - time_table.dates << Chouette::TimeTableDate.new( :date => excluded_date, :in_out => false) - expect(time_table.include_in_dates?( excluded_date)).to be_falsey - end - end - - describe "#include_in_periods?" do - it "should return true if a period include day" do - time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1", :int_day_types => 4) - time_table.periods << Chouette::TimeTablePeriod.new( - :period_start => Date.new(2012, 1, 1), - :period_end => Date.new(2012, 01, 30)) - expect(time_table.include_in_periods?(Date.new(2012, 1, 2))).to eq(true) - end - - it "should return false if a period include day but that is exclued" do - time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1", :int_day_types => 12) # Day type monday and tuesday - excluded_date = Date.new(2013, 05, 27) - time_table.dates << Chouette::TimeTableDate.new( :date => excluded_date, :in_out => false) - time_table.periods << Chouette::TimeTablePeriod.new( - :period_start => Date.new(2013, 05, 27), - :period_end => Date.new(2013, 05, 29)) - expect(time_table.include_in_periods?( excluded_date)).to be_falsey - end - end - - describe "#include_in_overlap_dates?" do - it "should return true if a day is included in overlap dates" do - time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1", :int_day_types => 4) - time_table.periods << Chouette::TimeTablePeriod.new( - :period_start => Date.new(2012, 1, 1), - :period_end => Date.new(2012, 01, 30)) - time_table.dates << Chouette::TimeTableDate.new( :date => Date.new(2012, 1, 2), :in_out => true) - expect(time_table.include_in_overlap_dates?(Date.new(2012, 1, 2))).to eq(true) - end - it "should return false if the day is excluded" do - time_table = Chouette::TimeTable.create!(:comment => "Test", :objectid => "test:Timetable:1", :int_day_types => 4) - time_table.periods << Chouette::TimeTablePeriod.new( - :period_start => Date.new(2012, 1, 1), - :period_end => Date.new(2012, 01, 30)) - time_table.dates << Chouette::TimeTableDate.new( :date => Date.new(2012, 1, 2), :in_out => false) - expect(time_table.include_in_overlap_dates?(Date.new(2012, 1, 2))).to be_falsey - end - end - - describe "#dates" do - it "should have with position 0" do - expect(subject.dates.first.position).to eq(0) - end - context "when first date has been removed" do - before do - subject.dates.first.destroy - end - it "should begin with position 0" do - expect(subject.dates.first.position).to eq(0) - end - end - end - describe "#validity_out_between?" do - let(:empty_tm) {build(:time_table)} - it "should be false if empty calendar" do - expect(empty_tm.validity_out_between?( Date.today, Date.today + 7.day)).to be_falsey - end - it "should be true if caldendar is out during start_date and end_date period" do - start_date = subject.bounding_dates.max - 2.day - end_date = subject.bounding_dates.max + 2.day - expect(subject.validity_out_between?( start_date, end_date)).to be_truthy - end - it "should be false if calendar is out on start date" do - start_date = subject.bounding_dates.max - end_date = subject.bounding_dates.max + 2.day - expect(subject.validity_out_between?( start_date, end_date)).to be_falsey - end - it "should be false if calendar is out on end date" do - start_date = subject.bounding_dates.max - 2.day - end_date = subject.bounding_dates.max - expect(subject.validity_out_between?( start_date, end_date)).to be_truthy - end - it "should be false if calendar is out after start_date" do - start_date = subject.bounding_dates.max + 2.day - end_date = subject.bounding_dates.max + 4.day - expect(subject.validity_out_between?( start_date, end_date)).to be_falsey - end - end - describe "#validity_out_from_on?" do - let(:empty_tm) {build(:time_table)} - it "should be false if empty calendar" do - expect(empty_tm.validity_out_from_on?( Date.today)).to be_falsey - end - it "should be true if caldendar ends on expected date" do - expected_date = subject.bounding_dates.max - expect(subject.validity_out_from_on?( expected_date)).to be_truthy - end - it "should be true if calendar ends before expected date" do - expected_date = subject.bounding_dates.max + 30.day - expect(subject.validity_out_from_on?( expected_date)).to be_truthy - end - it "should be false if calendars ends after expected date" do - expected_date = subject.bounding_dates.max - 30.day - expect(subject.validity_out_from_on?( expected_date)).to be_falsey - end - end - describe "#bounding_dates" do - context "when timetable contains only periods" do - before do - subject.dates = [] - subject.save - end - it "should retreive periods.period_start.min and periods.period_end.max" do - expect(subject.bounding_dates.min).to eq(subject.periods.map(&:period_start).min) - expect(subject.bounding_dates.max).to eq(subject.periods.map(&:period_end).max) - end - end - context "when timetable contains only dates" do - before do - subject.periods = [] - subject.save - end - it "should retreive dates.min and dates.max" do - expect(subject.bounding_dates.min).to eq(subject.dates.map(&:date).min) - expect(subject.bounding_dates.max).to eq(subject.dates.map(&:date).max) - end - end - it "should contains min date" do - min_date = subject.bounding_dates.min - subject.dates.each do |tm_date| - expect(min_date <= tm_date.date).to be_truthy - end - subject.periods.each do |tm_period| - expect(min_date <= tm_period.period_start).to be_truthy - end - - end - it "should contains max date" do - max_date = subject.bounding_dates.max - subject.dates.each do |tm_date| - expect(tm_date.date <= max_date).to be_truthy - end - subject.periods.each do |tm_period| - expect(tm_period.period_end <= max_date).to be_truthy - end - - end - end - describe "#periods" do - it "should begin with position 0" do - expect(subject.periods.first.position).to eq(0) - end - context "when first period has been removed" do - before do - subject.periods.first.destroy - end - it "should begin with position 0" do - expect(subject.periods.first.position).to eq(0) - end - end - it "should have period_start before period_end" do - period = Chouette::TimeTablePeriod.new - period.period_start = Date.today - period.period_end = Date.today + 10 - expect(period.valid?).to be_truthy - end - it "should not have period_start after period_end" do - period = Chouette::TimeTablePeriod.new - period.period_start = Date.today - period.period_end = Date.today - 10 - expect(period.valid?).to be_falsey - end - it "should not have period_start equal to period_end" do - period = Chouette::TimeTablePeriod.new - period.period_start = Date.today - period.period_end = Date.today - expect(period.valid?).to be_falsey - end end - describe "#effective_days_of_periods" do - before do - subject.periods.clear - subject.periods << Chouette::TimeTablePeriod.new( - :period_start => Date.new(2014, 6, 30), - :period_end => Date.new(2014, 7, 6)) - subject.int_day_types = 4|8|16 - end - it "should return monday to wednesday" do - expect(subject.effective_days_of_periods.size).to eq(3) - expect(subject.effective_days_of_periods[0]).to eq(Date.new(2014, 6, 30)) - expect(subject.effective_days_of_periods[1]).to eq(Date.new(2014, 7, 1)) - expect(subject.effective_days_of_periods[2]).to eq(Date.new(2014, 7, 2)) - end - it "should return thursday" do - expect(subject.effective_days_of_periods(Chouette::TimeTable.valid_days(32)).size).to eq(1) - expect(subject.effective_days_of_periods(Chouette::TimeTable.valid_days(32))[0]).to eq(Date.new(2014, 7, 3)) - end - - end + # it { is_expected.to validate_presence_of :comment } + # it { is_expected.to validate_uniqueness_of :objectid } - describe "#included_days" do - before do - subject.dates.clear - subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,16), :in_out => true) - subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,17), :in_out => false) - subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,18), :in_out => true) - subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,19), :in_out => false) - subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,20), :in_out => true) - end - it "should return 3 dates" do - days = subject.included_days - expect(days.size).to eq(3) - expect(days[0]).to eq(Date.new(2014, 7, 16)) - expect(days[1]).to eq(Date.new(2014,7, 18)) - expect(days[2]).to eq(Date.new(2014, 7,20)) - end + describe 'checksum' do + it_behaves_like 'checksum support', :time_table end - - describe "#excluded_days" do before do subject.dates.clear @@ -1223,5 +986,4 @@ end expect(subject.tag_list.size).to eq(2) end end - end diff --git a/spec/models/chouette/vehicle_journey_at_stop_spec.rb b/spec/models/chouette/vehicle_journey_at_stop_spec.rb index d999ed1a8..4f9d12730 100644 --- a/spec/models/chouette/vehicle_journey_at_stop_spec.rb +++ b/spec/models/chouette/vehicle_journey_at_stop_spec.rb @@ -1,6 +1,21 @@ require 'spec_helper' RSpec.describe Chouette::VehicleJourneyAtStop, type: :model do + describe 'checksum' do + let(:at_stop) { build_stubbed(:vehicle_journey_at_stop) } + + it_behaves_like 'checksum support', :vehicle_journey_at_stop + + context '#checksum_attributes' do + it 'should return attributes' do + expected = [at_stop.departure_time.to_s(:time), at_stop.arrival_time.to_s(:time)] + expected << at_stop.departure_day_offset.to_s + expected << at_stop.arrival_day_offset.to_s + expect(at_stop.checksum_attributes).to include(*expected) + end + end + end + describe "#day_offset_outside_range?" do let (:at_stop) { build_stubbed(:vehicle_journey_at_stop) } diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb index 3c04a77cc..52f2ab42d 100644 --- a/spec/models/chouette/vehicle_journey_spec.rb +++ b/spec/models/chouette/vehicle_journey_spec.rb @@ -17,8 +17,13 @@ describe Chouette::VehicleJourney, :type => :model do expect(vehicle_journey).to be_valid end + describe 'checksum' do + it_behaves_like 'checksum support', :vehicle_journey + end + describe "vjas_departure_time_must_be_before_next_stop_arrival_time", skip: "Validation currently commented out because it interferes with day offsets" do + let(:vehicle_journey) { create :vehicle_journey } let(:vjas) { vehicle_journey.vehicle_journey_at_stops } diff --git a/spec/support/checksum_support.rb b/spec/support/checksum_support.rb new file mode 100644 index 000000000..14ea3c55e --- /dev/null +++ b/spec/support/checksum_support.rb @@ -0,0 +1,53 @@ +shared_examples 'checksum support' do |factory_name| + let(:instance) { create(factory_name) } + + describe '#current_checksum_source' do + let(:attributes) { ['code_value', 'label_value'] } + let(:seperator) { ChecksumSupport::SEPARATOR } + let(:nil_value) { ChecksumSupport::VALUE_FOR_NIL_ATTRIBUTE } + + before do + allow_any_instance_of(instance.class).to receive(:checksum_attributes).and_return(attributes) + end + + it 'should separate attribute by seperator' do + expect(instance.current_checksum_source).to eq("code_value#{seperator}label_value") + end + + context 'nil value' do + let(:attributes) { ['code_value', nil] } + + it 'should replace nil attributes by default value' do + source = "code_value#{seperator}#{nil_value}" + expect(instance.current_checksum_source).to eq(source) + end + end + + context 'empty array' do + let(:attributes) { ['code_value', []] } + + it 'should convert to nil' do + source = "code_value#{seperator}#{nil_value}" + expect(instance.current_checksum_source).to eq(source) + end + end + end + + it 'should save checksum on create' do + expect(instance.checksum).to_not be_nil + end + + it 'should save checksum_source' do + expect(instance.checksum_source).to_not be_nil + end + + it 'should trigger set_current_checksum_source on save' do + expect(instance).to receive(:set_current_checksum_source) + instance.save + end + + it 'should trigger update_checksum on save' do + expect(instance).to receive(:update_checksum) + instance.save + end +end |
