aboutsummaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
authorLuc Donnet2018-02-19 11:04:29 +0100
committerLuc Donnet2018-02-19 11:04:29 +0100
commit7b17deff51545358009cb417cbb9d796565e7540 (patch)
treea43a5586ad39d838dd607e600dbc15ff18a58ab3 /spec
parent89428163fc93a7e09ebb0ca47939f8558afeb5eb (diff)
parent5f6008d165df4499319a2121a71842657d6ac3c9 (diff)
downloadchouette-core-7b17deff51545358009cb417cbb9d796565e7540.tar.bz2
Merge branch 'master' into 0000-docker
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/api/v1/stop_area_controller_spec.rb9
-rw-r--r--spec/controllers/autocomplete_purchase_windows_controller_spec.rb33
-rw-r--r--spec/controllers/autocomplete_stop_areas_controller_spec.rb61
-rw-r--r--spec/controllers/concerns/feature_checker_spec.rb37
-rw-r--r--spec/controllers/imports_controller_spec.rb14
-rw-r--r--spec/controllers/journey_patterns_collections_controller_spec.rb17
-rw-r--r--spec/controllers/line_referentials_controller_spec.rb16
-rw-r--r--spec/controllers/lines_controller_spec.rb38
-rw-r--r--spec/controllers/referential_vehicle_journeys_controller_spec.rb98
-rw-r--r--spec/controllers/referentials_controller_spec.rb29
-rw-r--r--spec/controllers/statuses_controller_spec.rb50
-rw-r--r--spec/controllers/stop_area_referentials_controller_spec.rb17
-rw-r--r--spec/controllers/stop_areas_controller_spec.rb38
-rw-r--r--spec/controllers/time_tables_controller_spec.rb29
-rw-r--r--spec/controllers/vehicle_journeys_controller_spec.rb25
-rw-r--r--spec/db/schema_spec.rb2
-rw-r--r--spec/decorators/api_key_decorator_spec.rb4
-rw-r--r--spec/decorators/referential_decorator_spec.rb54
-rw-r--r--spec/decorators/stop_area_decorator_spec.rb25
-rw-r--r--spec/factories/calendars.rb1
-rw-r--r--spec/factories/chouette_journey_pattern.rb8
-rw-r--r--spec/factories/chouette_lines.rb4
-rw-r--r--spec/factories/chouette_purchase_windows.rb12
-rw-r--r--spec/factories/chouette_routes.rb8
-rw-r--r--spec/factories/chouette_stop_areas.rb15
-rw-r--r--spec/factories/chouette_stop_points.rb2
-rw-r--r--spec/factories/chouette_time_table.rb18
-rw-r--r--spec/factories/chouette_vehicle_journey.rb1
-rw-r--r--spec/factories/chouette_vehicle_journey_at_stop.rb2
-rw-r--r--spec/factories/compliance_controls/generic_factories.rb2
-rw-r--r--spec/factories/compliance_controls/vehicle_journey_control_factories.rb4
-rw-r--r--spec/factories/custom_fields.rb9
-rw-r--r--spec/factories/import_messages.rb12
-rw-r--r--spec/factories/line_referentials.rb9
-rw-r--r--spec/factories/organisations.rb3
-rw-r--r--spec/factories/stop_area_referentials.rb9
-rw-r--r--spec/factories/workbenches.rb1
-rw-r--r--spec/factories/workgroups.rb7
-rw-r--r--spec/features/access_points_spec.rb2
-rw-r--r--spec/features/calendars_permissions_spec.rb7
-rw-r--r--spec/features/companies_spec.rb2
-rw-r--r--spec/features/compliance_check_sets_spec.rb22
-rw-r--r--spec/features/group_of_lines_permissions_spec.rb4
-rw-r--r--spec/features/group_of_lines_spec.rb2
-rw-r--r--spec/features/lines_spec.rb23
-rw-r--r--spec/features/networks_spec.rb16
-rw-r--r--spec/features/purchase_windows_permission_spec.rb59
-rw-r--r--spec/features/purchase_windows_spec.rb69
-rw-r--r--spec/features/referential_stop_areas_spec.rb2
-rw-r--r--spec/features/safe_submit_spec.rb9
-rw-r--r--spec/features/stop_areas_spec.rb2
-rw-r--r--spec/features/users/user_delete_spec.rb2
-rw-r--r--spec/features/workbenches/workbenches_show_spec.rb72
-rw-r--r--spec/fixtures/OFFRE_WITH_EXTRA.zipbin5586 -> 0 bytes
-rw-r--r--spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/SPURIOUS/spurious.xml1
-rw-r--r--spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/calendriers.xml (renamed from spec/fixtures/source_OFFRE_TRANSDEV_20170301122517/calendriers.xml)0
-rw-r--r--spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/commun.xml (renamed from spec/fixtures/source_OFFRE_TRANSDEV_20170301122517/commun.xml)0
-rw-r--r--spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/offre_C00108_9.xml (renamed from spec/fixtures/source_OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml)0
-rw-r--r--spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/offre_C00109_10.xml (renamed from spec/fixtures/source_OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml)0
-rw-r--r--spec/fixtures/foreign_and_spurious/FOREIGN_LINE/calendriers.xml86
-rw-r--r--spec/fixtures/foreign_and_spurious/FOREIGN_LINE/commun.xml33
-rw-r--r--spec/fixtures/foreign_and_spurious/FOREIGN_LINE/offre_C00107_10.xml204
-rw-r--r--spec/fixtures/foreign_and_spurious/FOREIGN_LINE/offre_C00108_9.xml202
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/calendriers.xml86
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/commun.xml33
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml202
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml204
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122519/calendriers.xml (renamed from spec/fixtures/source_OFFRE_TRANSDEV_20170301122519/calendriers.xml)0
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122519/commun.xml (renamed from spec/fixtures/source_OFFRE_TRANSDEV_20170301122519/commun.xml)0
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml (renamed from spec/fixtures/source_OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml)0
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml (renamed from spec/fixtures/source_OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml)0
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/SPURIOUS/spurious.xml1
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/calendriers.xml86
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/commun.xml33
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/offre_C00108_9.xml202
-rw-r--r--spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/offre_C00109_10.xml204
-rw-r--r--spec/fixtures/meta_zip/one/alpha1
-rw-r--r--spec/fixtures/meta_zip/two/beta1
-rw-r--r--spec/fixtures/meta_zip/two/subdir/gamma1
-rw-r--r--spec/fixtures/nozip.zip1
-rw-r--r--spec/fixtures/regression-5281.zipbin0 -> 21642 bytes
-rw-r--r--spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/calendriers.xml145
-rw-r--r--spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/commun.xml30
-rw-r--r--spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/offre_C00166_05.xml459
-rw-r--r--spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/offre_C00168_08.xml667
-rw-r--r--spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/offre_C00171_11.xml473
-rw-r--r--spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/calendriers.xml145
-rw-r--r--spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/commun.xml30
-rw-r--r--spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/offre_C00163_01.xml497
-rw-r--r--spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/offre_C00164_03.xml951
-rw-r--r--spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/offre_C00165_04.xml803
-rw-r--r--spec/fixtures/some_foreign_mixed/FOREIGN_LINE/calendriers.xml86
-rw-r--r--spec/fixtures/some_foreign_mixed/FOREIGN_LINE/commun.xml33
-rw-r--r--spec/fixtures/some_foreign_mixed/FOREIGN_LINE/offre_C00107_10.xml204
-rw-r--r--spec/fixtures/some_foreign_mixed/FOREIGN_LINE/offre_C00108_9.xml202
-rw-r--r--spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/calendriers.xml86
-rw-r--r--spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/commun.xml33
-rw-r--r--spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml202
-rw-r--r--spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml204
-rw-r--r--spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/calendriers.xml80
-rw-r--r--spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/commun.xml32
-rw-r--r--spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml172
-rw-r--r--spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml172
-rw-r--r--spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/calendriers.xml86
-rw-r--r--spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/commun.xml33
-rw-r--r--spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml202
-rw-r--r--spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml204
-rw-r--r--spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/calendriers.xml80
-rw-r--r--spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/commun.xml32
-rw-r--r--spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml172
-rw-r--r--spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml172
-rw-r--r--spec/helpers/table_builder_helper_spec.rb156
-rw-r--r--spec/javascript/journey_patterns/actions_spec.js16
-rw-r--r--spec/javascript/journey_patterns/components/JourneyPattern_spec.js63
-rw-r--r--spec/javascript/journey_patterns/components/JourneyPatterns_spec.js77
-rw-r--r--spec/javascript/journey_patterns/components/__snapshots__/JourneyPattern_spec.js.snap143
-rw-r--r--spec/javascript/journey_patterns/components/__snapshots__/JourneyPatterns_spec.js.snap169
-rw-r--r--spec/javascript/journey_patterns/reducers/journey_patterns_spec.js38
-rw-r--r--spec/javascript/preprocessor.js15
-rw-r--r--spec/javascript/routes/reducers/stop_points_spec.js588
-rw-r--r--spec/javascript/time_table/reducers/timetable_spec.js3
-rw-r--r--spec/javascript/vehicle_journeys/actions_spec.js274
-rw-r--r--spec/javascript/vehicle_journeys/components/CustomFieldsInputs_spec.js41
-rw-r--r--spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js87
-rw-r--r--spec/javascript/vehicle_journeys/components/__snapshots__/CustomFieldsInputs_spec.js.snap3
-rw-r--r--spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap181
-rw-r--r--spec/javascript/vehicle_journeys/reducers/modal_spec.js91
-rw-r--r--spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js (renamed from spec/javascript/vehicle_journeys/reducers/vehicle_journeys_spec.js)233
-rw-r--r--spec/lib/af83/decorator/decorator_link_spec.rb79
-rw-r--r--spec/lib/af83/decorator/decorator_spec.rb824
-rw-r--r--spec/lib/range_ext_spec.rb51
-rw-r--r--spec/lib/stif/netex_file/frame_spec.rb13
-rw-r--r--spec/lib/stif/netex_file_spec.rb4
-rw-r--r--spec/lib/stif/permission_translator_spec.rb16
-rw-r--r--spec/mailers/calendar_mailer_spec.rb2
-rw-r--r--spec/models/calendar_spec.rb122
-rw-r--r--spec/models/chouette/access_point_spec.rb2
-rw-r--r--spec/models/chouette/area_type_spec.rb43
-rw-r--r--spec/models/chouette/footnote_spec.rb12
-rw-r--r--spec/models/chouette/journey_pattern_spec.rb50
-rw-r--r--spec/models/chouette/purchase_window_spec.rb27
-rw-r--r--spec/models/chouette/route/route_base_spec.rb4
-rw-r--r--spec/models/chouette/route/route_duplication_spec.rb11
-rw-r--r--spec/models/chouette/routing_constraint_zone_spec.rb9
-rw-r--r--spec/models/chouette/stop_area_spec.rb80
-rw-r--r--spec/models/chouette/time_table_period_spec.rb2
-rw-r--r--spec/models/chouette/time_table_spec.rb134
-rw-r--r--spec/models/chouette/vehicle_journey_at_stop_spec.rb39
-rw-r--r--spec/models/chouette/vehicle_journey_spec.rb256
-rw-r--r--spec/models/compliance_check_spec.rb32
-rw-r--r--spec/models/compliance_control_class_level_defaults/generic_attribute_control/pattern_cccld_spec.rb3
-rw-r--r--spec/models/compliance_control_class_level_defaults/generic_attribute_control/uniqueness_cccld_spec.rb1
-rw-r--r--spec/models/compliance_control_spec.rb10
-rw-r--r--spec/models/compliance_control_validations/genric_attribute_validation/min_max_validation_spec.rb1
-rw-r--r--spec/models/custom_field_spec.rb35
-rw-r--r--spec/models/import_spec.rb57
-rw-r--r--spec/models/merge_spec.rb58
-rw-r--r--spec/models/organisation_spec.rb37
-rw-r--r--spec/models/referential/referential_lock_during_creation_spec.rb198
-rw-r--r--spec/models/referential_cloning_spec.rb73
-rw-r--r--spec/models/referential_spec.rb43
-rw-r--r--spec/models/workbench_spec.rb3
-rw-r--r--spec/models/workgroup_spec.rb30
-rw-r--r--spec/policies/access_link_policy_spec.rb10
-rw-r--r--spec/policies/access_point_policy_spec.rb10
-rw-r--r--spec/policies/calendar_policy_spec.rb16
-rw-r--r--spec/policies/company_policy_spec.rb5
-rw-r--r--spec/policies/connection_link_policy_spec.rb10
-rw-r--r--spec/policies/group_of_line_policy_spec.rb14
-rw-r--r--spec/policies/journey_pattern_policy_spec.rb10
-rw-r--r--spec/policies/line_policy_spec.rb11
-rw-r--r--spec/policies/line_referential_policy_spec.rb9
-rw-r--r--spec/policies/network_policy_spec.rb14
-rw-r--r--spec/policies/purchase_window_policy_spec.rb15
-rw-r--r--spec/policies/referential_policy_spec.rb13
-rw-r--r--spec/policies/route_policy_spec.rb12
-rw-r--r--spec/policies/routing_constraint_zone_policy_spec.rb10
-rw-r--r--spec/policies/sto_area_referential_policy_spec.rb9
-rw-r--r--spec/policies/stop_area_policy_spec.rb4
-rw-r--r--spec/policies/time_table_policy_spec.rb10
-rw-r--r--spec/rails_helper.rb5
-rw-r--r--spec/requests/api/v1/netex_import_spec.rb47
-rw-r--r--spec/services/meta_zip_data_spec.rb55
-rw-r--r--spec/services/parent_notifier_spec.rb (renamed from spec/services/parent_import_notifier_spec.rb)16
-rw-r--r--spec/services/referential_overview_spec.rb154
-rw-r--r--spec/services/zip_service_spec.rb185
-rw-r--r--spec/spec_helper.rb11
-rw-r--r--spec/support/checksum_support.rb67
-rw-r--r--spec/support/controller_spec_helper.rb33
-rw-r--r--spec/support/decorator_helpers.rb28
-rw-r--r--spec/support/helpers/tree_walker.rb15
-rw-r--r--spec/support/integration_spec_helper.rb78
-rw-r--r--spec/support/journey_pattern_helper.rb19
-rw-r--r--spec/support/permissions.rb1
-rw-r--r--spec/support/pundit/policies.rb5
-rw-r--r--spec/support/pundit/pundit_view_policy.rb27
-rw-r--r--spec/support/pundit/shared_examples.rb51
-rw-r--r--spec/support/referential.rb7
-rw-r--r--spec/support/shared_examples/compliance_control_validation.rb55
-rw-r--r--spec/support/snapshot_support.rb60
-rw-r--r--spec/support/zip_support.rb25
-rw-r--r--spec/support/zip_support/create_zip_data.rb70
-rw-r--r--spec/views/companies/__snapshots__/companies/index.snap4
-rw-r--r--spec/views/companies/__snapshots__/companies/index_create.snap4
-rw-r--r--spec/views/companies/__snapshots__/companies/index_destroy.snap4
-rw-r--r--spec/views/companies/__snapshots__/companies/index_update.snap4
-rw-r--r--spec/views/companies/__snapshots__/companies/show.snap4
-rw-r--r--spec/views/companies/__snapshots__/companies/show_create.snap4
-rw-r--r--spec/views/companies/__snapshots__/companies/show_destroy.snap7
-rw-r--r--spec/views/companies/__snapshots__/companies/show_update.snap7
-rw-r--r--spec/views/companies/index.html.erb_spec.rb29
-rw-r--r--spec/views/companies/show.html.erb_spec.rb29
-rw-r--r--spec/views/connection_links/index.html.erb_spec.rb8
-rw-r--r--spec/views/connection_links/show.html.erb_spec.rb35
-rw-r--r--spec/views/connection_links/show.html.slim_spec.rb32
-rw-r--r--spec/views/imports/show.html.slim_spec.rb35
-rw-r--r--spec/views/line_referentials/show.html.slim_spec.rb22
-rw-r--r--spec/views/line_referentials/stop_area_referentials/show.html.slim_spec.rb22
-rw-r--r--spec/views/lines/__snapshots__/lines/index.snap4
-rw-r--r--spec/views/lines/__snapshots__/lines/index_create.snap4
-rw-r--r--spec/views/lines/__snapshots__/lines/index_destroy.snap4
-rw-r--r--spec/views/lines/__snapshots__/lines/index_update.snap4
-rw-r--r--spec/views/lines/__snapshots__/lines/show.snap9
-rw-r--r--spec/views/lines/__snapshots__/lines/show_create.snap9
-rw-r--r--spec/views/lines/__snapshots__/lines/show_destroy.snap9
-rw-r--r--spec/views/lines/__snapshots__/lines/show_update.snap9
-rw-r--r--spec/views/lines/index.html.erb_spec.rb27
-rw-r--r--spec/views/lines/index.html.slim_spec.rb93
-rw-r--r--spec/views/lines/show.html.erb_spec.rb26
-rw-r--r--spec/views/networks/__snapshots__/networks/index.snap4
-rw-r--r--spec/views/networks/__snapshots__/networks/index_create.snap4
-rw-r--r--spec/views/networks/__snapshots__/networks/index_destroy.snap4
-rw-r--r--spec/views/networks/__snapshots__/networks/index_update.snap4
-rw-r--r--spec/views/networks/__snapshots__/networks/show.snap4
-rw-r--r--spec/views/networks/__snapshots__/networks/show_create.snap4
-rw-r--r--spec/views/networks/__snapshots__/networks/show_destroy.snap7
-rw-r--r--spec/views/networks/__snapshots__/networks/show_update.snap7
-rw-r--r--spec/views/networks/index.html.erb_spec.rb28
-rw-r--r--spec/views/networks/show.html.erb_spec.rb30
-rw-r--r--spec/views/offer_workbenches/show.html.erb_spec.rb61
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_create.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_destroy.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_purchase_windows.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_purchase_windows_create.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_purchase_windows_destroy.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_purchase_windows_update.snap12
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_readonly.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_readonly_create.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_readonly_destroy.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_readonly_update.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_create.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_destroy.snap9
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_update.snap12
-rw-r--r--spec/views/referentials/__snapshots__/referentials/show_update.snap12
-rw-r--r--spec/views/referentials/show.html.erb_spec.rb69
-rw-r--r--spec/views/stop_areas/edit.html.erb_spec.rb5
-rw-r--r--spec/views/stop_areas/index.html.erb_spec.rb25
-rw-r--r--spec/views/stop_areas/index.html.slim_spec.rb77
-rw-r--r--spec/views/stop_areas/new.html.erb_spec.rb4
-rw-r--r--spec/views/vehicle_journeys/index.html.slim_spec.rb31
-rw-r--r--spec/views/vehicle_journeys/new.html.erb_spec.rb3
-rw-r--r--spec/workers/referential_cloning_worker_spec.rb53
-rw-r--r--spec/workers/workbench_import/workbench_import_with_corrupt_zip_spec.rb47
-rw-r--r--spec/workers/workbench_import/workbench_import_worker_spec.rb169
-rw-r--r--spec/workers/workbench_import_worker_spec.rb102
267 files changed, 15136 insertions, 1226 deletions
diff --git a/spec/controllers/api/v1/stop_area_controller_spec.rb b/spec/controllers/api/v1/stop_area_controller_spec.rb
index eb0c87661..1ad71a95a 100644
--- a/spec/controllers/api/v1/stop_area_controller_spec.rb
+++ b/spec/controllers/api/v1/stop_area_controller_spec.rb
@@ -18,16 +18,15 @@ describe Api::V1::StopAreasController, :type => :controller do
end
end
describe "GET #index, :q => { :name_cont => 'aa'}" do
- let!(:sa1) { create(:stop_area, :name => "aaa") }
- let!(:sa2) { create(:stop_area, :name => "aab") }
- let!(:sa3) { create(:stop_area, :name => "abb") }
+ let!(:sa1) { create(:stop_area, :name => "aaa", stop_area_referential: referential.stop_area_referential) }
+ let!(:sa2) { create(:stop_area, :name => "aab", stop_area_referential: referential.stop_area_referential) }
+ let!(:sa3) { create(:stop_area, :name => "abb", stop_area_referential: referential.stop_area_referential) }
before :each do
config_formatted_request_with_authorization( "application/json")
- get :index, :q => { :name_cont => "aa"}
+ get :index, :q => { :name_cont => "aa"}
end
it "should assign expected stop_areas" do
expect(assigns[:stop_areas].map(&:name).sort).to eq([ sa1.name, sa2.name])
end
end
end
-
diff --git a/spec/controllers/autocomplete_purchase_windows_controller_spec.rb b/spec/controllers/autocomplete_purchase_windows_controller_spec.rb
new file mode 100644
index 000000000..cea600ea8
--- /dev/null
+++ b/spec/controllers/autocomplete_purchase_windows_controller_spec.rb
@@ -0,0 +1,33 @@
+require 'rails_helper'
+
+RSpec.describe AutocompletePurchaseWindowsController, type: :controller do
+ login_user
+
+ let(:referential) { Referential.first }
+ let!(:window) { create :purchase_window, referential: referential, name: 'écolà militaire' }
+
+ describe 'GET #index' do
+ it 'should be unauthorized' do
+ expect { get(:index, referential_id: referential.id) }.to raise_error(FeatureChecker::NotAuthorizedError)
+ end
+
+ with_feature "purchase_windows" do
+ let(:request){ get(:index, referential_id: referential.id) }
+ before do
+ request
+ end
+
+ it 'should be successful' do
+ expect(response).to be_success
+ end
+
+ context 'search by name' do
+ let(:request){ get :index, referential_id: referential.id, q: {name_or_objectid_cont_any: 'écolà'}, :format => :json }
+ it 'should be successful' do
+ expect(response).to be_success
+ expect(assigns(:purchase_windows)).to eq([window])
+ end
+ end
+ end
+ end
+end
diff --git a/spec/controllers/autocomplete_stop_areas_controller_spec.rb b/spec/controllers/autocomplete_stop_areas_controller_spec.rb
new file mode 100644
index 000000000..e0d1cd714
--- /dev/null
+++ b/spec/controllers/autocomplete_stop_areas_controller_spec.rb
@@ -0,0 +1,61 @@
+require 'rails_helper'
+
+RSpec.describe AutocompleteStopAreasController, type: :controller do
+ login_user
+
+ let(:referential) { Referential.first }
+ let(:other_referential) { create :referential }
+ let!(:stop_area) { create :stop_area, name: 'écolà militaire', referential: referential }
+ let!(:other_referential_stop_area) { create :stop_area, name: 'écolà militaire', referential: other_referential }
+ let!(:zdep_stop_area) { create :stop_area, area_type: "zdep", referential: referential }
+ let!(:not_zdep_stop_area) { create :stop_area, area_type: "lda", referential: referential }
+
+ describe 'GET #index' do
+ it 'should be successful' do
+ get :index, referential_id: referential.id
+ expect(response).to be_success
+ end
+
+ it "should filter stop areas based on referential" do
+ get :index, referential_id: referential.id
+ expect(assigns(:stop_areas)).to include(stop_area)
+ expect(assigns(:stop_areas)).to_not include(other_referential_stop_area)
+ end
+
+ context 'search by name' do
+ it 'should be successful' do
+ get :index, referential_id: referential.id, q: 'écolà', :format => :json
+ expect(response).to be_success
+ expect(assigns(:stop_areas)).to eq([stop_area])
+ end
+
+ it 'should be accent insensitive' do
+ get :index, referential_id: referential.id, q: 'ecola', :format => :json
+ expect(response).to be_success
+ expect(assigns(:stop_areas)).to eq([stop_area])
+ end
+ end
+ end
+
+ context "when searching from the route editor" do
+ let(:scope) { :route_editor }
+ let(:request){
+ get :index, referential_id: referential.id, scope: scope
+ }
+ it "should filter stop areas based on type" do
+ request
+ expect(assigns(:stop_areas)).to include(zdep_stop_area)
+ expect(assigns(:stop_areas)).to_not include(not_zdep_stop_area)
+ end
+
+ with_feature :route_stop_areas_all_types do
+ it "should not filter stop areas based on type" do
+ request
+ expect(assigns(:stop_areas)).to include(zdep_stop_area)
+ expect(assigns(:stop_areas)).to include(not_zdep_stop_area)
+ end
+ end
+ end
+
+
+end
diff --git a/spec/controllers/concerns/feature_checker_spec.rb b/spec/controllers/concerns/feature_checker_spec.rb
new file mode 100644
index 000000000..1d289bb15
--- /dev/null
+++ b/spec/controllers/concerns/feature_checker_spec.rb
@@ -0,0 +1,37 @@
+require "rails_helper"
+
+RSpec.describe "FeatureChecker", type: :controller do
+ login_user
+
+ controller do
+ include FeatureChecker
+ requires_feature :test, only: :protected
+
+ def protected; render text: "protected"; end
+ def not_protected; render text: "not protected"; end
+
+ def current_organisation
+ @organisation ||= Organisation.new
+ end
+ end
+
+ before do
+ routes.draw do
+ get "protected" => "anonymous#protected"
+ get "not_protected" => "anonymous#not_protected"
+ end
+ end
+
+ it "refuse access when organisation does not have the feature" do
+ expect{ get(:protected) }.to raise_error(FeatureChecker::NotAuthorizedError)
+ end
+
+ it "accept access on unprotected action" do
+ get :not_protected
+ end
+
+ it 'accept access when organisation has feature' do
+ controller.current_organisation.features << "test"
+ get :protected
+ end
+end
diff --git a/spec/controllers/imports_controller_spec.rb b/spec/controllers/imports_controller_spec.rb
index 22be9f6ed..08495ff47 100644
--- a/spec/controllers/imports_controller_spec.rb
+++ b/spec/controllers/imports_controller_spec.rb
@@ -17,6 +17,20 @@ RSpec.describe ImportsController, :type => :controller do
end
end
+ describe "POST #create" do
+ it "displays a flash message" do
+ post :create, workbench_id: workbench.id,
+ import: {
+ name: 'Offre',
+ file: fixture_file_upload('nozip.zip')
+ }
+
+ expect(controller).to set_flash[:notice].to(
+ I18n.t('flash.imports.create.notice')
+ )
+ end
+ end
+
describe 'GET #download' do
it 'should be successful' do
get :download, workbench_id: workbench.id, id: import.id, token: import.token_download
diff --git a/spec/controllers/journey_patterns_collections_controller_spec.rb b/spec/controllers/journey_patterns_collections_controller_spec.rb
index 7015bfe98..e2adc59f4 100644
--- a/spec/controllers/journey_patterns_collections_controller_spec.rb
+++ b/spec/controllers/journey_patterns_collections_controller_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe JourneyPatternsCollectionsController, :type => :controller do
before do
allow(controller).to receive(:pundit_user).and_return(user_context)
+ allow(controller).to receive(:current_organisation).and_return(@user.organisation)
end
it 'computes them correctly if not authorized' do
@@ -24,4 +25,20 @@ RSpec.describe JourneyPatternsCollectionsController, :type => :controller do
'journey_patterns.update' => true }.to_json)
end
end
+
+ context "get show" do
+ login_user
+
+ let( :referential ){ Referential.first }
+ let( :line ){ create(:line) }
+ let( :route ){ create(:route, line: line) }
+
+ let(:request){
+ get :show, referential_id: referential.id, line_id: line.id, route_id: route.id, format: :json
+ }
+ it 'should be successful' do
+ request
+ expect(response).to be_success
+ end
+ end
end
diff --git a/spec/controllers/line_referentials_controller_spec.rb b/spec/controllers/line_referentials_controller_spec.rb
index aee24b0fa..17ffb670d 100644
--- a/spec/controllers/line_referentials_controller_spec.rb
+++ b/spec/controllers/line_referentials_controller_spec.rb
@@ -1,3 +1,19 @@
RSpec.describe LineReferentialsController, :type => :controller do
+ login_user
+ let(:line_referential) { create :line_referential }
+
+ describe 'PUT sync' do
+ let(:request){ put :sync, id: line_referential.id }
+
+ it 'should redirect to 403' do
+ expect(request).to redirect_to "/403"
+ end
+
+ with_permission "line_referentials.synchronize" do
+ it 'returns HTTP success' do
+ expect(request).to redirect_to [line_referential]
+ end
+ end
+ end
end
diff --git a/spec/controllers/lines_controller_spec.rb b/spec/controllers/lines_controller_spec.rb
new file mode 100644
index 000000000..65fe88b96
--- /dev/null
+++ b/spec/controllers/lines_controller_spec.rb
@@ -0,0 +1,38 @@
+RSpec.describe LinesController, :type => :controller do
+ login_user
+
+ let(:line_referential) { create :line_referential, member: @user.organisation }
+ let(:line) { create :line, line_referential: line_referential }
+
+ describe 'PUT deactivate' do
+ let(:request){ put :deactivate, id: line.id, line_referential_id: line_referential.id }
+
+ it 'should redirect to 403' do
+ expect(request).to redirect_to "/403"
+ end
+
+ with_permission "lines.change_status" do
+ it 'returns HTTP success' do
+ expect(request).to redirect_to [line_referential, line]
+ expect(line.reload).to be_deactivated
+ end
+ end
+ end
+
+ describe 'PUT activate' do
+ let(:request){ put :activate, id: line.id, line_referential_id: line_referential.id }
+ before(:each){
+ line.deactivate!
+ }
+ it 'should redirect to 403' do
+ expect(request).to redirect_to "/403"
+ end
+
+ with_permission "lines.change_status" do
+ it 'returns HTTP success' do
+ expect(request).to redirect_to [line_referential, line]
+ expect(line.reload).to be_activated
+ end
+ end
+ end
+end
diff --git a/spec/controllers/referential_vehicle_journeys_controller_spec.rb b/spec/controllers/referential_vehicle_journeys_controller_spec.rb
new file mode 100644
index 000000000..cc6b44b9d
--- /dev/null
+++ b/spec/controllers/referential_vehicle_journeys_controller_spec.rb
@@ -0,0 +1,98 @@
+require "rails_helper"
+
+RSpec.describe ReferentialVehicleJourneysController, type: :controller do
+ login_user
+
+ before do
+ @user.organisation.update features: %w{referential_vehicle_journeys}
+ end
+
+ describe 'GET #index' do
+ it 'should be successful' do
+ get :index, referential_id: referential
+ expect(response).to be_success
+ end
+
+ it "refuse access when organisation does not have the feature 'referential_vehicle_journeys'" do
+ @user.organisation.update features: []
+
+ expect do
+ get :index, referential_id: referential
+ end.to raise_error(FeatureChecker::NotAuthorizedError)
+ end
+
+ it 'define Ransack search (alias @q)' do
+ get :index, referential_id: referential
+ expect(assigns[:q]).to be_an_instance_of(Ransack::Search)
+ end
+
+ it 'define @vehicle_journeys collection' do
+ vehicle_journey = FactoryGirl.create :vehicle_journey
+ get :index, referential_id: referential
+ expect(assigns[:vehicle_journeys]).to include(vehicle_journey)
+ end
+
+ it 'paginage @vehicle_journeys collection' do
+ FactoryGirl.create :vehicle_journey
+
+ get :index, referential_id: referential
+ expect(assigns[:vehicle_journeys].total_entries).to be(1)
+ end
+
+ context "when filtered on stop areas" do
+ let!(:request){
+ get :index, referential_id: referential, q: q
+ }
+
+ let(:stop_area_ids){ [] }
+
+ def create_journey_pattern_with_stop_areas(*stop_areas)
+ j = create(:journey_pattern)
+ stop_areas.each do |area|
+ sp = create(:stop_point, stop_area: area)
+ j.stop_points << sp
+ end
+ j.save
+ j
+ end
+
+ let(:q){ {stop_area_ids: stop_area_ids}}
+ let(:stop_area_1){ create :stop_area }
+ let(:stop_area_2){ create :stop_area }
+ let!(:journey_1){ create_journey_pattern_with_stop_areas(stop_area_1)}
+ let!(:journey_2){ create_journey_pattern_with_stop_areas(stop_area_2)}
+ let!(:journey_1_and_2){ create_journey_pattern_with_stop_areas(stop_area_1, stop_area_2)}
+ let!(:vehicle_journey_1){ create(:vehicle_journey, journey_pattern: journey_1)}
+ let!(:vehicle_journey_2){ create(:vehicle_journey, journey_pattern: journey_2)}
+ let!(:vehicle_journey_1_and_2){ create(:vehicle_journey, journey_pattern: journey_1_and_2)}
+
+ context "with one stop" do
+ let(:stop_area_ids){[stop_area_1.id]}
+ it "should apply filters" do
+ expect(vehicle_journey_1.stop_areas).to include stop_area_1
+ expect(vehicle_journey_2.stop_areas).to_not include stop_area_1
+ expect(vehicle_journey_1_and_2.stop_areas).to include stop_area_1
+ expect(assigns[:vehicle_journeys]).to include(vehicle_journey_1)
+ expect(assigns[:vehicle_journeys]).to_not include(vehicle_journey_2)
+ expect(assigns[:vehicle_journeys]).to include(vehicle_journey_1_and_2)
+ end
+ end
+
+ context "with 2 stops" do
+ let(:stop_area_ids){[stop_area_1.id, stop_area_2.id]}
+ it "should apply filters" do
+ expect(vehicle_journey_1.stop_areas).to include stop_area_1
+ expect(vehicle_journey_1.stop_areas).to_not include stop_area_2
+ expect(vehicle_journey_2.stop_areas).to include stop_area_2
+ expect(vehicle_journey_2.stop_areas).to_not include stop_area_1
+ expect(vehicle_journey_1_and_2.stop_areas).to include stop_area_1
+ expect(vehicle_journey_1_and_2.stop_areas).to include stop_area_2
+ expect(assigns[:vehicle_journeys]).to_not include(vehicle_journey_1)
+ expect(assigns[:vehicle_journeys]).to_not include(vehicle_journey_2)
+ expect(assigns[:vehicle_journeys]).to include(vehicle_journey_1_and_2)
+ end
+ end
+ end
+ end
+
+end
diff --git a/spec/controllers/referentials_controller_spec.rb b/spec/controllers/referentials_controller_spec.rb
index fba063085..f97480600 100644
--- a/spec/controllers/referentials_controller_spec.rb
+++ b/spec/controllers/referentials_controller_spec.rb
@@ -30,4 +30,33 @@ describe ReferentialsController, :type => :controller do
expect(assigns[:compliance_control_sets]).to eq([compliance_control_set])
end
end
+
+ describe "POST #validate" do
+ it "displays a flash message" do
+ post :validate, id: referential.id, params: {
+ compliance_control_set: create(:compliance_control_set).id
+ }
+
+ expect(controller).to set_flash[:notice].to(
+ I18n.t('notice.referentials.validate')
+ )
+ end
+ end
+
+ describe "POST #create" do
+ context "when duplicating" do
+ it "displays a flash message", pending: 'requires more params to create a valid Referential' do
+ post :create,
+ from: referential.id,
+ current_workbench_id: referential.workbench_id,
+ referential: {
+ name: 'Duplicated'
+ }
+
+ expect(controller).to set_flash[:notice].to(
+ I18n.t('notice.referentials.duplicate')
+ )
+ end
+ end
+ end
end
diff --git a/spec/controllers/statuses_controller_spec.rb b/spec/controllers/statuses_controller_spec.rb
new file mode 100644
index 000000000..8a6db8e28
--- /dev/null
+++ b/spec/controllers/statuses_controller_spec.rb
@@ -0,0 +1,50 @@
+RSpec.describe StatusesController, :type => :controller do
+
+ describe "GET index" do
+ login_user
+ render_views
+
+
+ let(:request){ get :index}
+ let(:parsed_response){ JSON.parse response.body }
+ it "should be ok" do
+ request
+ expect(response).to have_http_status 200
+ expect(parsed_response["status"]).to eq "ok"
+ end
+ context "without blocked object" do
+ before do
+ create :referential
+ create :import
+ create :compliance_check_set
+ request
+ end
+
+ it "should be ok" do
+ expect(response).to have_http_status 200
+ expect(parsed_response["status"]).to eq "ok"
+ expect(parsed_response["referentials_blocked"]).to eq 0
+ expect(parsed_response["imports_blocked"]).to eq 0
+ expect(parsed_response["imports_blocked"]).to eq 0
+ end
+ end
+
+ context "with a blocked object" do
+ before do
+ create :referential, created_at: 5.hours.ago, ready: false
+ create :import
+ create :compliance_check_set
+ request
+ end
+
+ it "should be ko" do
+ expect(Referential.blocked.count).to eq 1
+ expect(response).to have_http_status 200
+ expect(parsed_response["status"]).to eq "ko"
+ expect(parsed_response["referentials_blocked"]).to eq 1
+ expect(parsed_response["imports_blocked"]).to eq 0
+ expect(parsed_response["imports_blocked"]).to eq 0
+ end
+ end
+ end
+end
diff --git a/spec/controllers/stop_area_referentials_controller_spec.rb b/spec/controllers/stop_area_referentials_controller_spec.rb
new file mode 100644
index 000000000..384323334
--- /dev/null
+++ b/spec/controllers/stop_area_referentials_controller_spec.rb
@@ -0,0 +1,17 @@
+RSpec.describe StopAreaReferentialsController, :type => :controller do
+ login_user
+
+ let(:stop_area_referential) { create :stop_area_referential }
+
+ describe 'PUT sync' do
+ let(:request){ put :sync, id: stop_area_referential.id }
+
+ it { expect(request).to redirect_to "/403" }
+
+ with_permission "stop_area_referentials.synchronize" do
+ it 'returns HTTP success' do
+ expect(request).to redirect_to [stop_area_referential]
+ end
+ end
+ end
+end
diff --git a/spec/controllers/stop_areas_controller_spec.rb b/spec/controllers/stop_areas_controller_spec.rb
new file mode 100644
index 000000000..23bca3c36
--- /dev/null
+++ b/spec/controllers/stop_areas_controller_spec.rb
@@ -0,0 +1,38 @@
+RSpec.describe StopAreasController, :type => :controller do
+ login_user
+
+ let(:stop_area_referential) { create :stop_area_referential, member: @user.organisation }
+ let(:stop_area) { create :stop_area, stop_area_referential: stop_area_referential }
+
+ describe 'PUT deactivate' do
+ let(:request){ put :deactivate, id: stop_area.id, stop_area_referential_id: stop_area_referential.id }
+
+ it 'should redirect to 403' do
+ expect(request).to redirect_to "/403"
+ end
+
+ with_permission "stop_areas.change_status" do
+ it 'returns HTTP success' do
+ expect(request).to redirect_to [stop_area_referential, stop_area]
+ expect(stop_area.reload).to be_deactivated
+ end
+ end
+ end
+
+ describe 'PUT activate' do
+ let(:request){ put :activate, id: stop_area.id, stop_area_referential_id: stop_area_referential.id }
+ before(:each){
+ stop_area.deactivate!
+ }
+ it 'should redirect to 403' do
+ expect(request).to redirect_to "/403"
+ end
+
+ with_permission "stop_areas.change_status" do
+ it 'returns HTTP success' do
+ expect(request).to redirect_to [stop_area_referential, stop_area]
+ expect(stop_area.reload).to be_activated
+ end
+ end
+ end
+end
diff --git a/spec/controllers/time_tables_controller_spec.rb b/spec/controllers/time_tables_controller_spec.rb
new file mode 100644
index 000000000..85f2c10e4
--- /dev/null
+++ b/spec/controllers/time_tables_controller_spec.rb
@@ -0,0 +1,29 @@
+RSpec.describe TimeTablesController, :type => :controller do
+ login_user
+
+ describe 'POST create' do
+ let(:request){ post :create, referential_id: referential.id, time_table: time_table_params }
+ let(:time_table_params){{comment: "test"}}
+
+ it "should create a timetable" do
+ expect{request}.to change{ Chouette::TimeTable.count }.by 1
+ expect(Chouette::TimeTable.last.comment).to eq "test"
+ %i(monday tuesday wednesday thursday friday saturday sunday).each do |d|
+ expect(Chouette::TimeTable.last.send(d)).to be_falsy
+ end
+ end
+
+ context "when given a calendar" do
+ let(:calendar){ create :calendar, int_day_types: Calendar::MONDAY | Calendar::SUNDAY }
+ let(:time_table_params){{comment: "test", calendar_id: calendar.id}}
+ it "should create a timetable" do
+ expect{request}.to change{ Chouette::TimeTable.count }.by 1
+ expect(Chouette::TimeTable.last.comment).to eq "test"
+ expect(Chouette::TimeTable.last.calendar).to eq calendar
+ %i(monday tuesday wednesday thursday friday saturday sunday).each do |d|
+ expect(Chouette::TimeTable.last.send(d)).to eq calendar.send(d)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/controllers/vehicle_journeys_controller_spec.rb b/spec/controllers/vehicle_journeys_controller_spec.rb
index c9356fffa..300684532 100644
--- a/spec/controllers/vehicle_journeys_controller_spec.rb
+++ b/spec/controllers/vehicle_journeys_controller_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe VehicleJourneysController, :type => :controller do
before do
allow(controller).to receive(:pundit_user).and_return(user_context)
+ allow(controller).to receive(:current_organisation).and_return(@user.organisation)
end
it 'computes them correctly if not authorized' do
@@ -25,4 +26,28 @@ RSpec.describe VehicleJourneysController, :type => :controller do
end
end
+ describe "GET index" do
+ login_user
+ render_views
+
+ context "in JSON" do
+ let(:vehicle_journey){ create :vehicle_journey }
+ let(:route){ vehicle_journey.route }
+ let(:line){ route.line }
+ let!(:request){ get :index, referential_id: referential.id, line_id: line.id, route_id: route.id, format: :json}
+ let(:parsed_response){ JSON.parse response.body }
+ it "should have all the attributes" do
+ expect(response).to have_http_status 200
+ vehicle_journey = parsed_response["vehicle_journeys"].first
+ vehicle_journey_at_stops_matrix = vehicle_journey["vehicle_journey_at_stops"]
+ vehicle_journey_at_stops_matrix.each do |received_vjas|
+ expect(received_vjas).to have_key("id")
+ vjas = Chouette::VehicleJourneyAtStop.find received_vjas["id"]
+ [:connecting_service_id, :boarding_alighting_possibility].each do |att|
+ expect(received_vjas[att]).to eq vjas.send(att)
+ end
+ end
+ end
+ end
+ end
end
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb
index 585636124..a7fe0a162 100644
--- a/spec/db/schema_spec.rb
+++ b/spec/db/schema_spec.rb
@@ -44,6 +44,6 @@ Diff: #{diff}
def diff
RSpec::Support::Differ.new(
color: RSpec::Matchers.configuration.color?
- ).diff_as_string(@expected, @original)
+ ).diff_as_string(@original, @expected)
end
end
diff --git a/spec/decorators/api_key_decorator_spec.rb b/spec/decorators/api_key_decorator_spec.rb
deleted file mode 100644
index 9451a3974..000000000
--- a/spec/decorators/api_key_decorator_spec.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-require 'spec_helper'
-
-describe ApiKeyDecorator do
-end
diff --git a/spec/decorators/referential_decorator_spec.rb b/spec/decorators/referential_decorator_spec.rb
index cbeaf2407..efc438132 100644
--- a/spec/decorators/referential_decorator_spec.rb
+++ b/spec/decorators/referential_decorator_spec.rb
@@ -1,4 +1,5 @@
RSpec.describe ReferentialDecorator, type: [:helper, :decorator] do
+ include Support::DecoratorHelpers
let( :object ){ build_stubbed :referential }
let( :referential ){ object }
@@ -20,8 +21,8 @@ RSpec.describe ReferentialDecorator, type: [:helper, :decorator] do
context 'unarchived referential' do
context 'no rights' do
- it 'has only a Calendar action' do
- expect_action_link_hrefs.to eq([referential_time_tables_path(object)])
+ it 'has only show and Calendar actions' do
+ expect_action_link_hrefs.to eq([[object], referential_time_tables_path(object)])
end
end
@@ -30,8 +31,9 @@ RSpec.describe ReferentialDecorator, type: [:helper, :decorator] do
let( :user ){ build_stubbed :allmighty_user }
it 'has only default actions' do
- expect_action_link_elements.to be_empty
+ expect_action_link_elements.to eq ["Consulter", "Calendriers", "Dupliquer"]
expect_action_link_hrefs.to eq([
+ [object],
referential_time_tables_path(object),
new_referential_path(from: object)
])
@@ -40,16 +42,36 @@ RSpec.describe ReferentialDecorator, type: [:helper, :decorator] do
context 'all rights and same organisation' do
let( :user ){ build_stubbed :allmighty_user, organisation: referential.organisation }
+ let( :action){ :index }
+ context "on index" do
+ it 'has corresponding actions' do
+ expect_action_link_elements(action).to eq ["Consulter", "Editer", "Calendriers", "Dupliquer", "Valider", "Conserver","<span class=\"fa fa-trash mr-xs\"></span>Supprimer"]
+ expect_action_link_hrefs(action).to eq([
+ [object],
+ [:edit, object],
+ referential_time_tables_path(object),
+ new_referential_path(from: object),
+ referential_select_compliance_control_set_path(object),
+ archive_referential_path(object),
+ referential_path(object)
+ ])
+ end
+ end
- it 'has all actions' do
- expect_action_link_elements.to eq(%w{Purger})
- expect_action_link_hrefs.to eq([
- referential_time_tables_path(object),
- new_referential_path(from: object),
- referential_select_compliance_control_set_path(object),
- archive_referential_path(object),
- referential_path(object)
- ])
+ context "on show" do
+ let( :action){ :show }
+ it 'has corresponding actions' do
+ expect_action_link_elements(action).to eq ["Editer", "Calendriers", "Dupliquer", "Valider", "Conserver", "Purger", "<span class=\"fa fa-trash mr-xs\"></span>Supprimer"]
+ expect_action_link_hrefs(action).to eq([
+ [:edit, object],
+ referential_time_tables_path(object),
+ new_referential_path(from: object),
+ referential_select_compliance_control_set_path(object),
+ archive_referential_path(object),
+ "#",
+ referential_path(object)
+ ])
+ end
end
end
end
@@ -57,17 +79,19 @@ RSpec.describe ReferentialDecorator, type: [:helper, :decorator] do
context 'archived referential' do
before { referential.archived_at = 42.seconds.ago }
context 'no rights' do
- it 'has only a Calendar action' do
- expect_action_link_hrefs.to eq([referential_time_tables_path(object)])
+ it 'has only ahow and calendar actions' do
+ expect_action_link_hrefs.to eq([[object], referential_time_tables_path(object)])
end
end
context 'all rights and different organisation' do
let( :user ){ build_stubbed :allmighty_user }
it 'has only default actions' do
- expect_action_link_elements.to be_empty
+ expect_action_link_elements.to eq ["Consulter", "Calendriers", "Dupliquer"]
expect_action_link_hrefs.to eq([
+ [object],
referential_time_tables_path(object),
+ new_referential_path(from: object)
])
end
end
diff --git a/spec/decorators/stop_area_decorator_spec.rb b/spec/decorators/stop_area_decorator_spec.rb
new file mode 100644
index 000000000..fd6aa207a
--- /dev/null
+++ b/spec/decorators/stop_area_decorator_spec.rb
@@ -0,0 +1,25 @@
+require "rails_helper"
+
+RSpec.describe StopAreaDecorator do
+
+ let(:stop_area) { Chouette::StopArea.new }
+ let(:decorator) { stop_area.decorate }
+
+ describe '#waiting_time_text' do
+ it "returns '-' when waiting_time is nil" do
+ stop_area.waiting_time = nil
+ expect(decorator.waiting_time_text).to eq('-')
+ end
+
+ it "returns '-' when waiting_time is zero" do
+ stop_area.waiting_time = 0
+ expect(decorator.waiting_time_text).to eq('-')
+ end
+
+ it "returns '120 minutes' when waiting_time is 120" do
+ stop_area.waiting_time = 120
+ expect(decorator.waiting_time_text).to eq('120 minutes')
+ end
+ end
+
+end
diff --git a/spec/factories/calendars.rb b/spec/factories/calendars.rb
index 5f3188bee..d9fd242d1 100644
--- a/spec/factories/calendars.rb
+++ b/spec/factories/calendars.rb
@@ -6,6 +6,7 @@ FactoryGirl.define do
sequence(:dates) { |n| [ Date.yesterday - n, Date.yesterday - 2*n ] }
shared false
organisation
+ workgroup
end
sequence :date_range do |n|
diff --git a/spec/factories/chouette_journey_pattern.rb b/spec/factories/chouette_journey_pattern.rb
index 05d8d536a..d96302e7f 100644
--- a/spec/factories/chouette_journey_pattern.rb
+++ b/spec/factories/chouette_journey_pattern.rb
@@ -13,6 +13,12 @@ FactoryGirl.define do
j.stop_point_ids = j.route.stop_points.map(&:id)
j.departure_stop_point_id = j.route.stop_points.first.id
j.arrival_stop_point_id = j.route.stop_points.last.id
+ j.costs = {
+ "1-2": {
+ distance: 10,
+ time: 10
+ }
+ }
end
end
@@ -35,5 +41,3 @@ FactoryGirl.define do
end
end
-
-
diff --git a/spec/factories/chouette_lines.rb b/spec/factories/chouette_lines.rb
index 95f760174..c013b9d2b 100644
--- a/spec/factories/chouette_lines.rb
+++ b/spec/factories/chouette_lines.rb
@@ -8,7 +8,7 @@ FactoryGirl.define do
association :network, :factory => :network
association :company, :factory => :company
-
+
before(:create) do |line|
line.line_referential ||= LineReferential.find_by! name: "first"
end
@@ -35,7 +35,7 @@ FactoryGirl.define do
after(:create) do |line|
line.routes.each do |route|
route.stop_points.each do |stop_point|
- comm = create(:stop_area, :area_type => "lda")
+ comm = create(:stop_area, :area_type => "gdl")
stop_point.stop_area.update_attributes(:parent_id => comm.id)
end
end
diff --git a/spec/factories/chouette_purchase_windows.rb b/spec/factories/chouette_purchase_windows.rb
new file mode 100644
index 000000000..2e2faf4d8
--- /dev/null
+++ b/spec/factories/chouette_purchase_windows.rb
@@ -0,0 +1,12 @@
+FactoryGirl.define do
+ factory :purchase_window, class: Chouette::PurchaseWindow do
+ sequence(:name) { |n| "Purchase Window #{n}" }
+ sequence(:objectid) { |n| "organisation:PurchaseWindow:#{n}:LOC" }
+ date_ranges { [generate(:periods)] }
+ end
+
+ sequence :periods do |n|
+ date = Date.today + 2*n
+ date..(date+1)
+ end
+end
diff --git a/spec/factories/chouette_routes.rb b/spec/factories/chouette_routes.rb
index 4e20059fe..92a50b924 100644
--- a/spec/factories/chouette_routes.rb
+++ b/spec/factories/chouette_routes.rb
@@ -19,6 +19,7 @@ FactoryGirl.define do
after(:create) do |route, evaluator|
create_list(:stop_point, evaluator.stop_points_count, route: route)
route.reload
+ route.update_checksum!
end
factory :route_with_journey_patterns do
@@ -31,6 +32,13 @@ FactoryGirl.define do
end
end
+
+ trait :with_opposite do
+ after(:create) do |route|
+ opposite = create :route
+ route.opposite_route = opposite
+ end
+ end
end
factory :route_with_after_commit do
diff --git a/spec/factories/chouette_stop_areas.rb b/spec/factories/chouette_stop_areas.rb
index 8b64c227b..dab135ca6 100644
--- a/spec/factories/chouette_stop_areas.rb
+++ b/spec/factories/chouette_stop_areas.rb
@@ -3,10 +3,23 @@ FactoryGirl.define do
sequence(:objectid) { |n| "FR:#{n}:ZDE:#{n}:STIF" }
sequence(:name) { |n| "stop_area_#{n}" }
sequence(:registration_number) { |n| "test-#{n}" }
- area_type { Chouette::StopArea.area_type.values.sample }
+ area_type { Chouette::AreaType.commercial.sample }
latitude {10.0 * rand}
longitude {10.0 * rand}
+ kind "commercial"
association :stop_area_referential
+
+ transient do
+ referential nil
+ end
+
+ before(:create) do |stop_area, evaluator|
+ stop_area.stop_area_referential = evaluator.referential.stop_area_referential if evaluator.referential
+ end
+
+ trait :deactivated do
+ deleted_at { 1.hour.ago }
+ end
end
end
diff --git a/spec/factories/chouette_stop_points.rb b/spec/factories/chouette_stop_points.rb
index 14e08b1ac..97baae2fd 100644
--- a/spec/factories/chouette_stop_points.rb
+++ b/spec/factories/chouette_stop_points.rb
@@ -2,7 +2,7 @@ FactoryGirl.define do
factory :stop_point, :class => Chouette::StopPoint do
sequence(:objectid) { |n| "test:StopPoint:#{n}:loc" }
- association :stop_area, :factory => :stop_area
+ association :stop_area, :factory => :stop_area, area_type: "zdep"
end
end
diff --git a/spec/factories/chouette_time_table.rb b/spec/factories/chouette_time_table.rb
index a3ff63b2f..af48e1b42 100644
--- a/spec/factories/chouette_time_table.rb
+++ b/spec/factories/chouette_time_table.rb
@@ -11,20 +11,24 @@ FactoryGirl.define do
end
after(:create) do |time_table, evaluator|
-
- 0.upto(4) do |i|
- time_table.dates << create(:time_table_date, :time_table => time_table, :date => i.days.since.to_date, :in_out => true)
+ unless time_table.dates.any?
+ evaluator.dates_count.times do |i|
+ time_table.dates << create(:time_table_date, :time_table => time_table, :date => i.days.since.to_date, :in_out => true)
+ end
end
start_date = Date.today
end_date = start_date + 10
- 0.upto(4) do |i|
- time_table.periods << create(:time_table_period, :time_table => time_table, :period_start => start_date, :period_end => end_date)
- start_date = start_date + 20
- end_date = start_date + 10
+ unless time_table.periods.any?
+ evaluator.periods_count.times do |i|
+ time_table.periods << create(:time_table_period, :time_table => time_table, :period_start => start_date, :period_end => end_date)
+ start_date = start_date + 20
+ end_date = start_date + 10
+ end
end
time_table.save_shortcuts
+ time_table.update_checksum!
end
end
diff --git a/spec/factories/chouette_vehicle_journey.rb b/spec/factories/chouette_vehicle_journey.rb
index 5f64bd502..7d63a2e58 100644
--- a/spec/factories/chouette_vehicle_journey.rb
+++ b/spec/factories/chouette_vehicle_journey.rb
@@ -30,6 +30,7 @@ FactoryGirl.define do
:arrival_time => "2000-01-01 #{arrival_time} UTC",
:departure_time => "2000-01-01 #{departure_time} UTC")
end
+ vehicle_journey.update_checksum!
end
factory :vehicle_journey_odd do
diff --git a/spec/factories/chouette_vehicle_journey_at_stop.rb b/spec/factories/chouette_vehicle_journey_at_stop.rb
index 831e347d4..07a4ec557 100644
--- a/spec/factories/chouette_vehicle_journey_at_stop.rb
+++ b/spec/factories/chouette_vehicle_journey_at_stop.rb
@@ -1,9 +1,9 @@
FactoryGirl.define do
factory :vehicle_journey_at_stop, :class => Chouette::VehicleJourneyAtStop do
association :vehicle_journey, :factory => :vehicle_journey
+ association :stop_point, :factory => :stop_point
departure_day_offset { 0 }
departure_time { Time.now }
arrival_time { Time.now - 1.hour }
end
end
-
diff --git a/spec/factories/compliance_controls/generic_factories.rb b/spec/factories/compliance_controls/generic_factories.rb
index ddcf6c116..fd22b4c94 100644
--- a/spec/factories/compliance_controls/generic_factories.rb
+++ b/spec/factories/compliance_controls/generic_factories.rb
@@ -2,6 +2,8 @@ FactoryGirl.define do
factory :generic_attribute_control_min_max, class: 'GenericAttributeControl::MinMax' do
sequence(:name) { |n| "MinMax control #{n}" }
association :compliance_control_set
+ minimum 90
+ maximum 120
target "route#name"
end
diff --git a/spec/factories/compliance_controls/vehicle_journey_control_factories.rb b/spec/factories/compliance_controls/vehicle_journey_control_factories.rb
index b9da530fb..86a335aba 100644
--- a/spec/factories/compliance_controls/vehicle_journey_control_factories.rb
+++ b/spec/factories/compliance_controls/vehicle_journey_control_factories.rb
@@ -1,15 +1,19 @@
FactoryGirl.define do
factory :vehicle_journey_control_wating_time, class: 'VehicleJourneyControl::WaitingTime' do
+ maximum 10
association :compliance_control_set
end
factory :vehicle_journey_control_delta, class: 'VehicleJourneyControl::Delta' do
+ maximum 10
association :compliance_control_set
end
factory :vehicle_journey_control_speed, class: 'VehicleJourneyControl::Speed' do
association :compliance_control_set
+ minimum 200
+ maximum 300
end
factory :vehicle_journey_control_time_table, class: 'VehicleJourneyControl::TimeTable' do
diff --git a/spec/factories/custom_fields.rb b/spec/factories/custom_fields.rb
new file mode 100644
index 000000000..2f5fae555
--- /dev/null
+++ b/spec/factories/custom_fields.rb
@@ -0,0 +1,9 @@
+FactoryGirl.define do
+ factory :custom_field do
+ code "code"
+ resource_type "VehicleJourney"
+ sequence(:name){|n| "custom field ##{n}"}
+ field_type "list"
+ options( { "capacity" => "0" } )
+ end
+end
diff --git a/spec/factories/import_messages.rb b/spec/factories/import_messages.rb
index 75f80566c..5d936679a 100644
--- a/spec/factories/import_messages.rb
+++ b/spec/factories/import_messages.rb
@@ -3,5 +3,17 @@ FactoryGirl.define do
association :import
association :resource, factory: :import_resource
criticity :info
+
+ factory :corrupt_zip_file do
+ message_key 'corrupt_zip_file'
+ message_attributes({ source_filename: 'political file' })
+ criticity :error
+ end
+
+ factory :inconsistent_zip_file do
+ message_key 'inconsistent_zip_file'
+ message_attributes({ source_filename: 'robert talking', spurious_dirs: %w{dogs and cats}.join })
+ criticity :warning
+ end
end
end
diff --git a/spec/factories/line_referentials.rb b/spec/factories/line_referentials.rb
index e9e6dce5a..8c2aad646 100644
--- a/spec/factories/line_referentials.rb
+++ b/spec/factories/line_referentials.rb
@@ -2,5 +2,14 @@ FactoryGirl.define do
factory :line_referential do
sequence(:name) { |n| "Line Referential #{n}" }
objectid_format 'stif_codifligne'
+
+ transient do
+ member nil
+ end
+
+ after(:create) do |line_referential, evaluator|
+ line_referential.add_member evaluator.member if evaluator.member
+ line_referential.save
+ end
end
end
diff --git a/spec/factories/organisations.rb b/spec/factories/organisations.rb
index 239557a0e..2914c30cb 100644
--- a/spec/factories/organisations.rb
+++ b/spec/factories/organisations.rb
@@ -2,5 +2,8 @@ FactoryGirl.define do
factory :organisation do
sequence(:name) { |n| "Organisation #{n}" }
sequence(:code) { |n| "000#{n}" }
+ factory :org_with_lines do
+ sso_attributes { { 'functional_scope' => %w{STIF:CODIFLIGNE:Line:C00108 STIF:CODIFLIGNE:Line:C00109}.to_json } }
+ end
end
end
diff --git a/spec/factories/stop_area_referentials.rb b/spec/factories/stop_area_referentials.rb
index fcba996e4..bdac050b1 100644
--- a/spec/factories/stop_area_referentials.rb
+++ b/spec/factories/stop_area_referentials.rb
@@ -2,5 +2,14 @@ FactoryGirl.define do
factory :stop_area_referential, :class => StopAreaReferential do
sequence(:name) { |n| "StopArea Referential #{n}" }
objectid_format 'stif_reflex'
+
+ transient do
+ member nil
+ end
+
+ after(:create) do |stop_area_referential, evaluator|
+ stop_area_referential.add_member evaluator.member if evaluator.member
+ stop_area_referential.save
+ end
end
end
diff --git a/spec/factories/workbenches.rb b/spec/factories/workbenches.rb
index 0f26559d8..98fdd6ad9 100644
--- a/spec/factories/workbenches.rb
+++ b/spec/factories/workbenches.rb
@@ -7,5 +7,6 @@ FactoryGirl.define do
association :line_referential
association :stop_area_referential
association :output, factory: :referential_suite
+ association :workgroup
end
end
diff --git a/spec/factories/workgroups.rb b/spec/factories/workgroups.rb
new file mode 100644
index 000000000..792deddf8
--- /dev/null
+++ b/spec/factories/workgroups.rb
@@ -0,0 +1,7 @@
+FactoryGirl.define do
+ factory :workgroup do
+ sequence(:name) { |n| "Workgroup ##{n}" }
+ association :line_referential
+ association :stop_area_referential
+ end
+end
diff --git a/spec/features/access_points_spec.rb b/spec/features/access_points_spec.rb
index c16039d67..890906de7 100644
--- a/spec/features/access_points_spec.rb
+++ b/spec/features/access_points_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
describe "Access points", :type => :feature do
login_user
- let!(:stop_area) { create(:stop_area) }
+ let!(:stop_area) { create(:stop_area, stop_area_referential: referential.stop_area_referential) }
let!(:access_points) { Array.new(2) { create(:access_point, :stop_area => stop_area) } }
subject { access_points.first }
diff --git a/spec/features/calendars_permissions_spec.rb b/spec/features/calendars_permissions_spec.rb
index 9b47ab2bb..4857592d5 100644
--- a/spec/features/calendars_permissions_spec.rb
+++ b/spec/features/calendars_permissions_spec.rb
@@ -2,6 +2,7 @@ RSpec.describe 'Calendars', type: :feature do
login_user
let(:calendar) { create :calendar, organisation_id: 1 }
+ let(:workgroup) { calendar.workgroup }
describe 'permissions' do
before do
@@ -13,7 +14,7 @@ RSpec.describe 'Calendars', type: :feature do
end
context 'on show view' do
- let( :path ){ calendar_path(calendar) }
+ let( :path ){ workgroup_calendar_path(workgroup, calendar) }
context 'if present → ' do
let( :permission ){ true }
@@ -33,7 +34,7 @@ RSpec.describe 'Calendars', type: :feature do
end
context 'on edit view' do
- let( :path ){ edit_calendar_path(calendar) }
+ let( :path ){ edit_workgroup_calendar_path(workgroup, calendar) }
context 'if present → ' do
let( :permission ){ true }
@@ -51,7 +52,7 @@ RSpec.describe 'Calendars', type: :feature do
end
context 'on index view' do
- let( :path ){ calendars_path }
+ let( :path ){ workgroup_calendars_path(workgroup) }
context 'if present → ' do
let( :permission ){ true }
diff --git a/spec/features/companies_spec.rb b/spec/features/companies_spec.rb
index 1b9dae56f..4e778b3a0 100644
--- a/spec/features/companies_spec.rb
+++ b/spec/features/companies_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
describe "Companies", :type => :feature do
login_user
- let(:line_referential) { create :line_referential }
+ let(:line_referential) { create :line_referential, member: @user.organisation }
let!(:companies) { Array.new(2) { create :company, line_referential: line_referential } }
subject { companies.first }
diff --git a/spec/features/compliance_check_sets_spec.rb b/spec/features/compliance_check_sets_spec.rb
index 7ba64b6b8..5cace04d4 100644
--- a/spec/features/compliance_check_sets_spec.rb
+++ b/spec/features/compliance_check_sets_spec.rb
@@ -29,10 +29,10 @@ RSpec.describe "ComplianceCheckSets", type: :feature do
it 'we can see the expected content' do
# Breadcrumbs
- expect_breadcrumb_links "Accueil", "Gestion de l'offre", "Liste des jeux de contrôles"
+ expect_breadcrumb_links "Accueil", "Gestion de l'offre", "Liste des rapports de contrôles"
# Headline
- expect( page ).to have_content("Jeu de contrôles exécutés #{compliance_check_set.name}")
+ expect( page ).to have_content(I18n.t("compliance_check_sets.executed.title", name: compliance_check_set.name))
# Information Definition List
expect( page.first('.dl-term') ).to have_content("Nom")
@@ -49,10 +49,10 @@ RSpec.describe "ComplianceCheckSets", type: :feature do
# Direct Children
within(:xpath, xpath_for_div_of_block) do
direct_checks.each do | direct_check |
- expect( page ).to have_content( direct_check.code )
- expect( page ).to have_content( direct_check.name )
- expect( page ).to have_content( direct_check.criticity )
- expect( page ).to have_content( direct_check.comment )
+ expect( page ).to have_content( direct_check.code )
+ expect( page ).to have_content( direct_check.name )
+ expect( page ).to have_content( direct_check.criticity )
+ expect( page ).to have_content( direct_check.comment )
end
end
@@ -60,10 +60,10 @@ RSpec.describe "ComplianceCheckSets", type: :feature do
compliance_check_set.compliance_check_blocks.each do | block |
within(:xpath, xpath_for_div_of_block(block)) do
block.compliance_checks.each do | check |
- expect( page ).to have_content( check.code )
- expect( page ).to have_content( check.name )
- expect( page ).to have_content( check.criticity )
- expect( page ).to have_content( check.comment )
+ expect( page ).to have_content( check.code )
+ expect( page ).to have_content( check.name )
+ expect( page ).to have_content( check.criticity )
+ expect( page ).to have_content( check.comment )
end
end
end
@@ -86,7 +86,7 @@ RSpec.describe "ComplianceCheckSets", type: :feature do
all_checks.each do | check |
expect( page ).to have_content(check.code)
end
-
+
end
end
diff --git a/spec/features/group_of_lines_permissions_spec.rb b/spec/features/group_of_lines_permissions_spec.rb
index 5c03481ec..33d78c0dd 100644
--- a/spec/features/group_of_lines_permissions_spec.rb
+++ b/spec/features/group_of_lines_permissions_spec.rb
@@ -22,7 +22,7 @@ describe "Group of lines", :type => :feature do
context 'on show view' do
let( :path ){ line_referential_group_of_line_path(line_referential, group_of_line, delete: true) }
- context 'if permissions present → ' do
+ context 'if permissions present → ' do
let( :permission ){ true }
it 'shows the appropriate buttons' do
@@ -30,7 +30,7 @@ describe "Group of lines", :type => :feature do
expect( page ).to have_link('Supprimer', href: expected_url)
end
end
- context 'if permissions absent → ' do
+ context 'if permissions absent → ' do
let( :permission ){ false }
it 'shows the appropriate buttons' do
diff --git a/spec/features/group_of_lines_spec.rb b/spec/features/group_of_lines_spec.rb
index 59101ccd5..8b88e6e9e 100644
--- a/spec/features/group_of_lines_spec.rb
+++ b/spec/features/group_of_lines_spec.rb
@@ -10,7 +10,7 @@ describe "Group of lines", :type => :feature do
let!(:group_of_lines) { Array.new(2) { create(:group_of_line, line_referential: line_referential) } }
subject { group_of_lines.first }
- let(:line_referential) { create :line_referential }
+ let(:line_referential) { create :line_referential, member: @user.organisation }
before :each do
subject.lines << line
diff --git a/spec/features/lines_spec.rb b/spec/features/lines_spec.rb
index 2a442bd2f..f176e34fe 100644
--- a/spec/features/lines_spec.rb
+++ b/spec/features/lines_spec.rb
@@ -1,7 +1,8 @@
+# coding: utf-8
describe "Lines", type: :feature do
login_user
- let(:line_referential) { create :line_referential }
+ let(:line_referential) { create :line_referential, member: @user.organisation }
let!(:network) { create(:network) }
let!(:company) { create(:company) }
let!(:lines) { Array.new(2) { create :line_with_stop_areas, network: network, company: company, line_referential: line_referential } }
@@ -60,22 +61,22 @@ describe "Lines", type: :feature do
# it "creates line and return to show" do
# visit line_referential_lines_path(line_referential)
# click_link "Ajouter une ligne"
- # fill_in "line_name", :with => "Line 1"
- # fill_in "Numéro d'enregistrement", :with => "1"
- # fill_in "Identifiant Neptune", :with => "chouette:test:Line:999"
+ # fill_in "line_name", with: "Line 1"
+ # fill_in "Numéro d'enregistrement", with: "1"
+ # fill_in "Identifiant Neptune", with: "chouette:test:Line:999"
# click_button("Créer ligne")
# expect(page).to have_content("Line 1")
# end
# end
# Fixme #1780
- # describe "new with group of line", :js => true do
+ # describe "new with group of line", truncation: true do
# it "creates line and return to show" do
# visit new_line_referential_line_path(line_referential)
- # fill_in "line_name", :with => "Line 1"
- # fill_in "Numéro d'enregistrement", :with => "1"
- # fill_in "Identifiant Neptune", :with => "test:Line:999"
- # fill_in_token_input('line_group_of_line_tokens', :with => "#{group_of_line.name}")
+ # fill_in "line_name", with: "Line 1"
+ # fill_in "Numéro d'enregistrement", with: "1"
+ # fill_in "Identifiant Neptune", with: "test:Line:999"
+ # fill_in_token_input('line_group_of_line_tokens', with: "#{group_of_line.name}")
# find_button("Créer ligne").trigger("click")
# expect(page).to have_text("Line 1")
# expect(page).to have_text("#{group_of_line.name}")
@@ -87,8 +88,8 @@ describe "Lines", type: :feature do
# it "edit line" do
# visit line_referential_line_path(line_referential, subject)
# click_link "Editer cette ligne"
- # fill_in "line_name", :with => "Line Modified"
- # fill_in "Numéro d'enregistrement", :with => "test-1"
+ # fill_in "line_name", with: "Line Modified"
+ # fill_in "Numéro d'enregistrement", with: "test-1"
# click_button("Editer ligne")
# expect(page).to have_content("Line Modified")
# end
diff --git a/spec/features/networks_spec.rb b/spec/features/networks_spec.rb
index 75070e7fa..8586b2a16 100644
--- a/spec/features/networks_spec.rb
+++ b/spec/features/networks_spec.rb
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
require 'spec_helper'
-describe "Networks", :type => :feature do
+describe "Networks", type: :feature do
login_user
- let(:line_referential) { create :line_referential }
+ let(:line_referential) { create :line_referential, member: @user.organisation }
let!(:networks) { Array.new(2) { create(:network, line_referential: line_referential) } }
subject { networks.first }
@@ -54,9 +54,9 @@ describe "Networks", :type => :feature do
# # allow(subject).to receive(:stop_areas).and_return(Array.new(2) { create(:stop_area) })
# visit line_referential_networks_path(line_referential)
# click_link "Ajouter un réseau"
- # fill_in "network_name", :with => "Network 1"
- # fill_in "Numéro d'enregistrement", :with => "test-1"
- # fill_in "Identifiant Neptune", :with => "chouette:test:GroupOfLine:1"
+ # fill_in "network_name", with: "Network 1"
+ # fill_in "Numéro d'enregistrement", with: "test-1"
+ # fill_in "Identifiant Neptune", with: "chouette:test:GroupOfLine:1"
# click_button("Créer réseau")
# expect(page).to have_content("Network 1")
# end
@@ -67,14 +67,14 @@ describe "Networks", :type => :feature do
# # allow(subject).to receive(:stop_areas).and_return(Array.new(2) { create(:stop_area) })
# visit line_referential_network_path(line_referential, subject)
# click_link "Editer ce réseau"
- # fill_in "network_name", :with => "Network Modified"
- # fill_in "Numéro d'enregistrement", :with => "test-1"
+ # fill_in "network_name", with: "Network Modified"
+ # fill_in "Numéro d'enregistrement", with: "test-1"
# click_button("Editer réseau")
# expect(page).to have_content("Network Modified")
# end
# end
- # describe "delete", :js => true do
+ # describe "delete", truncation: true do
# it "delete network and return to the list" do
# subject.stub(:stop_areas).and_return(Array.new(2) { create(:stop_area) })
# visit line_referential_network_path(line_referential, subject)
diff --git a/spec/features/purchase_windows_permission_spec.rb b/spec/features/purchase_windows_permission_spec.rb
new file mode 100644
index 000000000..9f155a1e8
--- /dev/null
+++ b/spec/features/purchase_windows_permission_spec.rb
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+require 'spec_helper'
+
+describe "PurchaseWindows", :type => :feature do
+ login_user
+
+ before do
+ @user.organisation.update features: %w{purchase_windows}
+ end
+
+ let(:purchase_window) { create :purchase_window, referential: first_referential}
+
+ describe 'permissions' do
+ before do
+ allow_any_instance_of(PurchaseWindowPolicy).to receive(:create?).and_return permission
+ allow_any_instance_of(PurchaseWindowPolicy).to receive(:destroy?).and_return permission
+ allow_any_instance_of(PurchaseWindowPolicy).to receive(:update?).and_return permission
+ visit path
+ end
+
+ context 'on show view' do
+ let( :path ){ referential_purchase_window_path(first_referential, purchase_window) }
+
+ context 'if present → ' do
+ let( :permission ){ true }
+ it 'view shows the corresponding buttons' do
+ expect(page).to have_content(I18n.t('purchase_windows.actions.edit'))
+ expect(page).to have_content(I18n.t('purchase_windows.actions.destroy'))
+ end
+ end
+
+ context 'if absent → ' do
+ let( :permission ){ false }
+ it 'view does not show the corresponding buttons' do
+ expect(page).not_to have_content(I18n.t('purchase_windows.actions.edit'))
+ expect(page).not_to have_content(I18n.t('purchase_windows.actions.destroy'))
+ end
+ end
+ end
+
+ context 'on index view' do
+ let( :path ){ referential_purchase_windows_path(first_referential) }
+
+ context 'if present → ' do
+ let( :permission ){ true }
+ it 'index shows an edit button' do
+ expect(page).to have_content(I18n.t('purchase_windows.actions.new'))
+ end
+ end
+
+ context 'if absent → ' do
+ let( :permission ){ false }
+ it 'index does not show any edit button' do
+ expect(page).not_to have_content(I18n.t('purchase_windows.actions.new'))
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/purchase_windows_spec.rb b/spec/features/purchase_windows_spec.rb
new file mode 100644
index 000000000..f797594b7
--- /dev/null
+++ b/spec/features/purchase_windows_spec.rb
@@ -0,0 +1,69 @@
+describe "PurchaseWindows", type: :feature do
+ login_user
+
+ before do
+ @user.organisation.update features: %w{purchase_windows}
+ end
+
+ describe "#index" do
+ with_permissions('purchase_windows.create') do
+ it "allows users to create new purchase windows" do
+ name = 'Test purchase window create'
+
+ visit(referential_purchase_windows_path(first_referential.id))
+
+ click_link(I18n.t('purchase_windows.actions.new'))
+
+ fill_in('purchase_window[name]', with: name)
+ # select('#DD2DAA', from: 'purchase_window[color]')
+
+ click_link(I18n.t('simple_form.labels.purchase_window.add_a_date_range'))
+ click_button(I18n.t('actions.submit'))
+
+ expect(page).to have_content(name)
+ end
+ end
+
+ with_permissions('purchase_windows.update') do
+ it "allows users to update purchase windows" do
+ actual_name = 'Existing purchase window'
+ expected_name = 'Updated purchase window'
+ create(
+ :purchase_window,
+ referential: first_referential,
+ name: actual_name
+ )
+
+ visit(referential_purchase_windows_path(first_referential.id))
+
+ click_link(actual_name)
+
+ click_link(I18n.t('purchase_windows.actions.edit'))
+ fill_in('purchase_window[name]', with: expected_name)
+
+ click_button(I18n.t('actions.submit'))
+
+ expect(page).to have_content(expected_name)
+ end
+ end
+
+ with_permissions('purchase_windows.destroy') do
+ it "allows users to destroy purchase windows" do
+ name = 'Existing purchase window'
+ create(
+ :purchase_window,
+ referential: first_referential,
+ name: name
+ )
+
+ visit(referential_purchase_windows_path(first_referential.id))
+
+ click_link(name)
+
+ click_link(I18n.t('purchase_windows.actions.destroy'))
+
+ expect(page).to_not have_content(name)
+ end
+ end
+ end
+end
diff --git a/spec/features/referential_stop_areas_spec.rb b/spec/features/referential_stop_areas_spec.rb
index 0dc7951a7..5e70857e7 100644
--- a/spec/features/referential_stop_areas_spec.rb
+++ b/spec/features/referential_stop_areas_spec.rb
@@ -5,7 +5,7 @@ describe 'ReferentialStopAreas', type: :feature do
login_user
let(:referential) { Referential.first }
- let(:stop_area_referential) { create :stop_area_referential }
+ let(:stop_area_referential) { referential.stop_area_referential }
let!(:stop_areas) { Array.new(2) { create :stop_area, stop_area_referential: stop_area_referential } }
describe 'index' do
diff --git a/spec/features/safe_submit_spec.rb b/spec/features/safe_submit_spec.rb
new file mode 100644
index 000000000..9968d4310
--- /dev/null
+++ b/spec/features/safe_submit_spec.rb
@@ -0,0 +1,9 @@
+RSpec.describe 'SafeSubmit', type: :feature do
+ login_user
+
+ let( :path ){ new_api_key_path() }
+ it 'view shows the corresponding buttons' do
+ visit path
+ expect(page).to have_css('input[type=submit][data-disable-with]')
+ end
+end
diff --git a/spec/features/stop_areas_spec.rb b/spec/features/stop_areas_spec.rb
index 6afb22bc6..668eb2fa3 100644
--- a/spec/features/stop_areas_spec.rb
+++ b/spec/features/stop_areas_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
describe "StopAreas", :type => :feature do
login_user
- let(:stop_area_referential) { create :stop_area_referential }
+ let(:stop_area_referential) { create :stop_area_referential, member: @user.organisation }
let!(:stop_areas) { Array.new(2) { create :stop_area, stop_area_referential: stop_area_referential } }
subject { stop_areas.first }
diff --git a/spec/features/users/user_delete_spec.rb b/spec/features/users/user_delete_spec.rb
index 48f4e35d1..8b2ffcbe5 100644
--- a/spec/features/users/user_delete_spec.rb
+++ b/spec/features/users/user_delete_spec.rb
@@ -7,7 +7,7 @@ Warden.test_mode!
# As a user
# I want to delete my user profile
# So I can close my account
-feature 'User delete', :devise, :js do
+feature 'User delete', :devise, :truncation do
after(:each) do
Warden.test_reset!
diff --git a/spec/features/workbenches/workbenches_show_spec.rb b/spec/features/workbenches/workbenches_show_spec.rb
index f1151a67b..7be813b94 100644
--- a/spec/features/workbenches/workbenches_show_spec.rb
+++ b/spec/features/workbenches/workbenches_show_spec.rb
@@ -22,11 +22,69 @@ RSpec.describe 'Workbenches', type: :feature do
end
end
+ it 'lists referentials in the current workgroup' do
+ other_workbench = create(
+ :workbench,
+ line_referential: line_ref,
+ workgroup: workbench.workgroup
+ )
+ other_referential = create(
+ :workbench_referential,
+ workbench: other_workbench,
+ organisation: other_workbench.organisation,
+ metadatas: [
+ create(
+ :referential_metadata,
+ lines: [create(:line, line_referential: line_ref)]
+ )
+ ]
+ )
+
+ hidden_referential = create(
+ :workbench_referential,
+ workbench: create(
+ :workbench,
+ line_referential: line_ref
+ ),
+ metadatas: [
+ create(
+ :referential_metadata,
+ lines: [create(:line, line_referential: line_ref)]
+ )
+ ]
+ )
+
+ visit workbench_path(workbench)
+
+ expect(page).to have_content(referential.name),
+ "Couldn't find `referential`: `#{referential.inspect}`"
+ expect(page).to have_content(other_referential.name),
+ "Couldn't find `other_referential`: `#{other_referential.inspect}`"
+ expect(page).to_not have_content(hidden_referential.name),
+ "Couldn't find `hidden_referential`: `#{hidden_referential.inspect}`"
+ end
+
context 'filtering' do
let!(:another_organisation) { create :organisation }
let(:another_line) { create :line, line_referential: line_ref }
let(:another_ref_metadata) { create(:referential_metadata, lines: [another_line]) }
- let!(:other_referential) { create :workbench_referential, workbench: workbench, metadatas: [another_ref_metadata] }
+ let(:other_workbench) do
+ create(
+ :workbench,
+ line_referential: line_ref,
+ organisation: another_organisation,
+ workgroup: workbench.workgroup
+ )
+ end
+ let!(:other_referential) do
+ create(
+ :workbench_referential,
+ workbench: other_workbench,
+ metadatas: [another_ref_metadata],
+ organisation: other_workbench.organisation
+ )
+ end
+
before(:each) do
visit workbench_path(workbench)
@@ -64,6 +122,18 @@ RSpec.describe 'Workbenches', type: :feature do
click_button I18n.t('actions.filter')
expect(find(box)).to be_checked
end
+
+ it 'only lists organisations in the current workgroup' do
+ unaffiliated_workbench = workbench.dup
+ unaffiliated_workbench.update(organisation: create(:organisation))
+
+ expect(page).to have_selector(
+ "#q_organisation_name_eq_any_#{@user.organisation.name.parameterize.underscore}"
+ )
+ expect(page).to_not have_selector(
+ "#q_organisation_name_eq_any_#{unaffiliated_workbench.name.parameterize.underscore}"
+ )
+ end
end
context 'filter by status' do
diff --git a/spec/fixtures/OFFRE_WITH_EXTRA.zip b/spec/fixtures/OFFRE_WITH_EXTRA.zip
deleted file mode 100644
index 97ea3f513..000000000
--- a/spec/fixtures/OFFRE_WITH_EXTRA.zip
+++ /dev/null
Binary files differ
diff --git a/spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/SPURIOUS/spurious.xml b/spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/SPURIOUS/spurious.xml
new file mode 100644
index 000000000..a6204cd5c
--- /dev/null
+++ b/spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/SPURIOUS/spurious.xml
@@ -0,0 +1 @@
+spurious
diff --git a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122517/calendriers.xml b/spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/calendriers.xml
index bfbd0aea1..bfbd0aea1 100644
--- a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122517/calendriers.xml
+++ b/spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/calendriers.xml
diff --git a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122517/commun.xml b/spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/commun.xml
index 266c8a598..266c8a598 100644
--- a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122517/commun.xml
+++ b/spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/commun.xml
diff --git a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml b/spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/offre_C00108_9.xml
index 832793036..832793036 100644
--- a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml
+++ b/spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/offre_C00108_9.xml
diff --git a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml b/spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/offre_C00109_10.xml
index 9dff0d850..9dff0d850 100644
--- a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml
+++ b/spec/fixtures/extra_file_nok/OFFRE_WITH_EXTRA/offre_C00109_10.xml
diff --git a/spec/fixtures/foreign_and_spurious/FOREIGN_LINE/calendriers.xml b/spec/fixtures/foreign_and_spurious/FOREIGN_LINE/calendriers.xml
new file mode 100644
index 000000000..bfbd0aea1
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/FOREIGN_LINE/calendriers.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:siri="http://www.siri.org.uk/siri" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_CALENDRIER-1_20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_CALENDRIER"/>
+ <netex:ValidBetween>
+ <netex:FromDate>2017-03-01</netex:FromDate>
+ <netex:ToDate>2017-03-31</netex:ToDate>
+ </netex:ValidBetween>
+ <netex:members>
+ <netex:dayTypes>
+ <netex:DayType id="CITYWAY:DayType:1:LOC" version="any" >
+ <netex:Name>Semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Monday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Tuesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Wednesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Thursday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Friday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:2:LOC" version="any" >
+ <netex:Name>Fin de semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Saturday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Sunday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:3:LOC" version="any" >
+ <netex:Name>Service spécial</netex:Name>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:4:LOC" version="any" >
+ <netex:Name>Restriction</netex:Name>
+ </netex:DayType>
+ </netex:dayTypes>
+ <netex:dayTypeAssignments>
+ <netex:DayTypeAssignment version="any" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:3:LOC" version="any"/>
+ <netex:isAvailable>true</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ </netex:dayTypeAssignments>
+ <netex:operatingPeriods>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:1:LOC" version="any" >
+ <netex:FromDate>2017-01-01</netex:FromDate>
+ <netex:ToDate>2017-12-31</netex:ToDate>
+ </netex:OperatingPeriod>
+ </netex:operatingPeriods>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/foreign_and_spurious/FOREIGN_LINE/commun.xml b/spec/fixtures/foreign_and_spurious/FOREIGN_LINE/commun.xml
new file mode 100644
index 000000000..266c8a598
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/FOREIGN_LINE/commun.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:siri="http://www.siri.org.uk/siri" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_COMMUN-1_20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_COMMUN"/>
+ <netex:members>
+ <netex:notices>
+ <netex:Notice id="CITYWAY:Notice:1:LOC" version="any">
+ <netex:Text>Notice 1</netex:Text>
+ <netex:PublicCode>1</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:2:LOC" version="any">
+ <netex:Text>Notice 2</netex:Text>
+ <netex:PublicCode>2</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:3:LOC" version="any">
+ <netex:Text>Notice 3</netex:Text>
+ <netex:PublicCode>3</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ </netex:notices>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/foreign_and_spurious/FOREIGN_LINE/offre_C00107_10.xml b/spec/fixtures/foreign_and_spurious/FOREIGN_LINE/offre_C00107_10.xml
new file mode 100644
index 000000000..9dff0d850
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/FOREIGN_LINE/offre_C00107_10.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd"
+ xmlns:netex="http://www.netex.org.uk/netex" xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:routes>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ </netex:routes>
+ <netex:directions>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici aussi</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là aussi</netex:Name>
+ </netex:Direction>
+ </netex:directions>
+ <netex:serviceJourneyPatterns>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any">
+ <netex:Name>Par ici itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC"
+ version="any">
+ <netex:Name>Par là itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ </netex:serviceJourneyPatterns>
+ <netex:destinationDisplays>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC"
+ version="any">
+ <netex:FrontText>Mission 1 bis</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC"
+ version="any">
+ <netex:FrontText>Mission 2 bis</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ </netex:destinationDisplays>
+ <netex:scheduledStopPoints>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC"
+ version="any"/>
+ </netex:scheduledStopPoints>
+ <netex:passengerStopAssignments>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000918:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000917:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ </netex:passengerStopAssignments>
+ <netex:routingConstraintZones>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC"
+ version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:routingConstraintZones>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:serviceJourneys>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici aussi</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment>
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:212">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>23:58:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>23:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>00:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>1</netex:ArrivalDayOffset>
+ <netex:DepartureTime>00:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>1</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:serviceJourneys>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/foreign_and_spurious/FOREIGN_LINE/offre_C00108_9.xml b/spec/fixtures/foreign_and_spurious/FOREIGN_LINE/offre_C00108_9.xml
new file mode 100644
index 000000000..832793036
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/FOREIGN_LINE/offre_C00108_9.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd"
+ xmlns:netex="http://www.netex.org.uk/netex" xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:routes>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ </netex:routes>
+ <netex:directions>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là</netex:Name>
+ </netex:Direction>
+ </netex:directions>
+ <netex:serviceJourneyPatterns>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any">
+ <netex:Name>Par ici</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC"
+ version="any">
+ <netex:Name>Par là</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ </netex:serviceJourneyPatterns>
+ <netex:destinationDisplays>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC"
+ version="any">
+ <netex:FrontText>Mission 1</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC"
+ version="any">
+ <netex:FrontText>Mission 2</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ </netex:destinationDisplays>
+ <netex:scheduledStopPoints>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC"
+ version="any"/>
+ </netex:scheduledStopPoints>
+ <netex:passengerStopAssignments>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009052:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009053:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ </netex:passengerStopAssignments>
+ <netex:routingConstraintZones>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC"
+ version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:routingConstraintZones>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:serviceJourneys>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment>
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:011">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:05:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:05:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:serviceJourneys>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/calendriers.xml b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/calendriers.xml
new file mode 100644
index 000000000..bfbd0aea1
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/calendriers.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:siri="http://www.siri.org.uk/siri" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_CALENDRIER-1_20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_CALENDRIER"/>
+ <netex:ValidBetween>
+ <netex:FromDate>2017-03-01</netex:FromDate>
+ <netex:ToDate>2017-03-31</netex:ToDate>
+ </netex:ValidBetween>
+ <netex:members>
+ <netex:dayTypes>
+ <netex:DayType id="CITYWAY:DayType:1:LOC" version="any" >
+ <netex:Name>Semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Monday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Tuesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Wednesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Thursday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Friday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:2:LOC" version="any" >
+ <netex:Name>Fin de semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Saturday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Sunday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:3:LOC" version="any" >
+ <netex:Name>Service spécial</netex:Name>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:4:LOC" version="any" >
+ <netex:Name>Restriction</netex:Name>
+ </netex:DayType>
+ </netex:dayTypes>
+ <netex:dayTypeAssignments>
+ <netex:DayTypeAssignment version="any" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:3:LOC" version="any"/>
+ <netex:isAvailable>true</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ </netex:dayTypeAssignments>
+ <netex:operatingPeriods>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:1:LOC" version="any" >
+ <netex:FromDate>2017-01-01</netex:FromDate>
+ <netex:ToDate>2017-12-31</netex:ToDate>
+ </netex:OperatingPeriod>
+ </netex:operatingPeriods>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/commun.xml b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/commun.xml
new file mode 100644
index 000000000..266c8a598
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/commun.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:siri="http://www.siri.org.uk/siri" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_COMMUN-1_20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_COMMUN"/>
+ <netex:members>
+ <netex:notices>
+ <netex:Notice id="CITYWAY:Notice:1:LOC" version="any">
+ <netex:Text>Notice 1</netex:Text>
+ <netex:PublicCode>1</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:2:LOC" version="any">
+ <netex:Text>Notice 2</netex:Text>
+ <netex:PublicCode>2</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:3:LOC" version="any">
+ <netex:Text>Notice 3</netex:Text>
+ <netex:PublicCode>3</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ </netex:notices>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml
new file mode 100644
index 000000000..832793036
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd"
+ xmlns:netex="http://www.netex.org.uk/netex" xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:routes>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ </netex:routes>
+ <netex:directions>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là</netex:Name>
+ </netex:Direction>
+ </netex:directions>
+ <netex:serviceJourneyPatterns>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any">
+ <netex:Name>Par ici</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC"
+ version="any">
+ <netex:Name>Par là</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ </netex:serviceJourneyPatterns>
+ <netex:destinationDisplays>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC"
+ version="any">
+ <netex:FrontText>Mission 1</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC"
+ version="any">
+ <netex:FrontText>Mission 2</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ </netex:destinationDisplays>
+ <netex:scheduledStopPoints>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC"
+ version="any"/>
+ </netex:scheduledStopPoints>
+ <netex:passengerStopAssignments>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009052:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009053:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ </netex:passengerStopAssignments>
+ <netex:routingConstraintZones>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC"
+ version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:routingConstraintZones>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:serviceJourneys>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment>
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:011">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:05:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:05:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:serviceJourneys>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml
new file mode 100644
index 000000000..9dff0d850
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd"
+ xmlns:netex="http://www.netex.org.uk/netex" xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:routes>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ </netex:routes>
+ <netex:directions>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici aussi</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là aussi</netex:Name>
+ </netex:Direction>
+ </netex:directions>
+ <netex:serviceJourneyPatterns>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any">
+ <netex:Name>Par ici itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC"
+ version="any">
+ <netex:Name>Par là itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ </netex:serviceJourneyPatterns>
+ <netex:destinationDisplays>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC"
+ version="any">
+ <netex:FrontText>Mission 1 bis</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC"
+ version="any">
+ <netex:FrontText>Mission 2 bis</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ </netex:destinationDisplays>
+ <netex:scheduledStopPoints>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC"
+ version="any"/>
+ </netex:scheduledStopPoints>
+ <netex:passengerStopAssignments>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000918:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000917:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ </netex:passengerStopAssignments>
+ <netex:routingConstraintZones>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC"
+ version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:routingConstraintZones>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:serviceJourneys>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici aussi</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment>
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:212">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>23:58:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>23:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>00:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>1</netex:ArrivalDayOffset>
+ <netex:DepartureTime>00:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>1</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:serviceJourneys>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122519/calendriers.xml b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122519/calendriers.xml
index 1043e0cde..1043e0cde 100644
--- a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122519/calendriers.xml
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122519/calendriers.xml
diff --git a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122519/commun.xml b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122519/commun.xml
index f59f8ac2d..f59f8ac2d 100644
--- a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122519/commun.xml
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122519/commun.xml
diff --git a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml
index 9eefeeb43..9eefeeb43 100644
--- a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml
diff --git a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml
index d260ef17e..d260ef17e 100644
--- a/spec/fixtures/source_OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml
diff --git a/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/SPURIOUS/spurious.xml b/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/SPURIOUS/spurious.xml
new file mode 100644
index 000000000..a6204cd5c
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/SPURIOUS/spurious.xml
@@ -0,0 +1 @@
+spurious
diff --git a/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/calendriers.xml b/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/calendriers.xml
new file mode 100644
index 000000000..bfbd0aea1
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/calendriers.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:siri="http://www.siri.org.uk/siri" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_CALENDRIER-1_20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_CALENDRIER"/>
+ <netex:ValidBetween>
+ <netex:FromDate>2017-03-01</netex:FromDate>
+ <netex:ToDate>2017-03-31</netex:ToDate>
+ </netex:ValidBetween>
+ <netex:members>
+ <netex:dayTypes>
+ <netex:DayType id="CITYWAY:DayType:1:LOC" version="any" >
+ <netex:Name>Semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Monday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Tuesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Wednesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Thursday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Friday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:2:LOC" version="any" >
+ <netex:Name>Fin de semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Saturday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Sunday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:3:LOC" version="any" >
+ <netex:Name>Service spécial</netex:Name>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:4:LOC" version="any" >
+ <netex:Name>Restriction</netex:Name>
+ </netex:DayType>
+ </netex:dayTypes>
+ <netex:dayTypeAssignments>
+ <netex:DayTypeAssignment version="any" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:3:LOC" version="any"/>
+ <netex:isAvailable>true</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ </netex:dayTypeAssignments>
+ <netex:operatingPeriods>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:1:LOC" version="any" >
+ <netex:FromDate>2017-01-01</netex:FromDate>
+ <netex:ToDate>2017-12-31</netex:ToDate>
+ </netex:OperatingPeriod>
+ </netex:operatingPeriods>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/commun.xml b/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/commun.xml
new file mode 100644
index 000000000..266c8a598
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/commun.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:siri="http://www.siri.org.uk/siri" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_COMMUN-1_20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_COMMUN"/>
+ <netex:members>
+ <netex:notices>
+ <netex:Notice id="CITYWAY:Notice:1:LOC" version="any">
+ <netex:Text>Notice 1</netex:Text>
+ <netex:PublicCode>1</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:2:LOC" version="any">
+ <netex:Text>Notice 2</netex:Text>
+ <netex:PublicCode>2</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:3:LOC" version="any">
+ <netex:Text>Notice 3</netex:Text>
+ <netex:PublicCode>3</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ </netex:notices>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/offre_C00108_9.xml b/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/offre_C00108_9.xml
new file mode 100644
index 000000000..832793036
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/offre_C00108_9.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd"
+ xmlns:netex="http://www.netex.org.uk/netex" xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:routes>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ </netex:routes>
+ <netex:directions>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là</netex:Name>
+ </netex:Direction>
+ </netex:directions>
+ <netex:serviceJourneyPatterns>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any">
+ <netex:Name>Par ici</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC"
+ version="any">
+ <netex:Name>Par là</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ </netex:serviceJourneyPatterns>
+ <netex:destinationDisplays>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC"
+ version="any">
+ <netex:FrontText>Mission 1</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC"
+ version="any">
+ <netex:FrontText>Mission 2</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ </netex:destinationDisplays>
+ <netex:scheduledStopPoints>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC"
+ version="any"/>
+ </netex:scheduledStopPoints>
+ <netex:passengerStopAssignments>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009052:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009053:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ </netex:passengerStopAssignments>
+ <netex:routingConstraintZones>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC"
+ version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:routingConstraintZones>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:serviceJourneys>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment>
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:011">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:05:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:05:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:serviceJourneys>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/offre_C00109_10.xml b/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/offre_C00109_10.xml
new file mode 100644
index 000000000..9dff0d850
--- /dev/null
+++ b/spec/fixtures/foreign_and_spurious/OFFRE_WITH_EXTRA/offre_C00109_10.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd"
+ xmlns:netex="http://www.netex.org.uk/netex" xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:routes>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ </netex:routes>
+ <netex:directions>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici aussi</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là aussi</netex:Name>
+ </netex:Direction>
+ </netex:directions>
+ <netex:serviceJourneyPatterns>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any">
+ <netex:Name>Par ici itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC"
+ version="any">
+ <netex:Name>Par là itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ </netex:serviceJourneyPatterns>
+ <netex:destinationDisplays>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC"
+ version="any">
+ <netex:FrontText>Mission 1 bis</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC"
+ version="any">
+ <netex:FrontText>Mission 2 bis</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ </netex:destinationDisplays>
+ <netex:scheduledStopPoints>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC"
+ version="any"/>
+ </netex:scheduledStopPoints>
+ <netex:passengerStopAssignments>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000918:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000917:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ </netex:passengerStopAssignments>
+ <netex:routingConstraintZones>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC"
+ version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:routingConstraintZones>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:serviceJourneys>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici aussi</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment>
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:212">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>23:58:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>23:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>00:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>1</netex:ArrivalDayOffset>
+ <netex:DepartureTime>00:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>1</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:serviceJourneys>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/meta_zip/one/alpha b/spec/fixtures/meta_zip/one/alpha
new file mode 100644
index 000000000..4a5800705
--- /dev/null
+++ b/spec/fixtures/meta_zip/one/alpha
@@ -0,0 +1 @@
+alpha
diff --git a/spec/fixtures/meta_zip/two/beta b/spec/fixtures/meta_zip/two/beta
new file mode 100644
index 000000000..65b2df87f
--- /dev/null
+++ b/spec/fixtures/meta_zip/two/beta
@@ -0,0 +1 @@
+beta
diff --git a/spec/fixtures/meta_zip/two/subdir/gamma b/spec/fixtures/meta_zip/two/subdir/gamma
new file mode 100644
index 000000000..af17f6cc8
--- /dev/null
+++ b/spec/fixtures/meta_zip/two/subdir/gamma
@@ -0,0 +1 @@
+gamma
diff --git a/spec/fixtures/nozip.zip b/spec/fixtures/nozip.zip
index 505bd213a..e69de29bb 100644
--- a/spec/fixtures/nozip.zip
+++ b/spec/fixtures/nozip.zip
@@ -1 +0,0 @@
-no zip file
diff --git a/spec/fixtures/regression-5281.zip b/spec/fixtures/regression-5281.zip
new file mode 100644
index 000000000..2ff4ec66d
--- /dev/null
+++ b/spec/fixtures/regression-5281.zip
Binary files differ
diff --git a/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/calendriers.xml b/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/calendriers.xml
new file mode 100644
index 000000000..bc2b63527
--- /dev/null
+++ b/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/calendriers.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:siri="http://www.siri.org.uk/siri"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_CALENDRIER-1_20170214090012:LOC"
+ version="any">
+ <netex:ValidBetween>
+ <netex:FromDate>2017-06-25T00:00:00</netex:FromDate>
+ <netex:ToDate>2017-12-31T00:00:00</netex:ToDate>
+ </netex:ValidBetween>
+ <netex:TypeOfFrameRef ref="NETEX_CALENDRIER"/>
+ <netex:members>
+ <netex:DayType id="CITYWAY:DayType:1:LOC" version="any" >
+ <netex:Name>Semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Monday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Tuesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Wednesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Thursday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Friday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:2:LOC" version="any" >
+ <netex:Name>Fin de semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Saturday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Sunday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:3:LOC" version="any" >
+ <netex:Name>Semaine vacances</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Monday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Tuesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Wednesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Thursday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Friday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:4:LOC" version="any" >
+ <netex:Name>WE vacances</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Saturday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Sunday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:5:LOC" version="any" >
+ <netex:Name>Service spécial</netex:Name>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:6:LOC" version="any" >
+ <netex:Name>Restriction</netex:Name>
+ </netex:DayType>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:1:LOC" version="any" order="0" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:2:LOC" version="any" order="0" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:3:LOC" version="any" order="0" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:3:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:4:LOC" version="any" order="0" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:3:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:5:LOC" version="any" order="0" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:2:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:3:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:6:LOC" version="any" order="0" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:2:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:7:LOC" version="any" order="0" >
+ <netex:Date>2017-07-05</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:5:LOC" version="any"/>
+ <netex:isAvailable>true</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:8:LOC" version="any" order="0" >
+ <netex:Date>2017-08-14</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:6:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:9:LOC" version="any" order="0" >
+ <netex:Date>2017-08-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:6:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:10:LOC" version="any" order="0" >
+ <netex:Date>2017-08-16</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:6:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:1:LOC" version="any" >
+ <netex:FromDate>2017-06-25T00:00:00</netex:FromDate>
+ <netex:ToDate>2017-07-01T00:00:00</netex:ToDate>
+ </netex:OperatingPeriod>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:2:LOC" version="any" >
+ <netex:FromDate>2017-07-10T00:00:00</netex:FromDate>
+ <netex:ToDate>2017-08-31T00:00:00</netex:ToDate>
+ </netex:OperatingPeriod>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:3:LOC" version="any" >
+ <netex:FromDate>2017-09-01T00:00:00</netex:FromDate>
+ <netex:ToDate>2017-12-31T00:00:00</netex:ToDate>
+ </netex:OperatingPeriod>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/commun.xml b/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/commun.xml
new file mode 100644
index 000000000..b6337b65f
--- /dev/null
+++ b/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/commun.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_COMMUN-1_20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_COMMUN"/>
+ <netex:members>
+ <netex:Notice id="CITYWAY:Notice:1:LOC" version="any">
+ <netex:Text>note numéro 1</netex:Text>
+ <netex:PublicCode>1</netex:PublicCode>
+ <netex:TypeOfNoticeRef ref="ServiceJourneyNotice" />
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:2:LOC" version="any">
+ <netex:Text>note numéro 2</netex:Text>
+ <netex:PublicCode>2</netex:PublicCode>
+ <netex:TypeOfNoticeRef ref="ServiceJourneyNotice" />
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:3:LOC" version="any">
+ <netex:Text>note numéro 3</netex:Text>
+ <netex:PublicCode>3</netex:PublicCode>
+ <netex:TypeOfNoticeRef ref="ServiceJourneyNotice" />
+ </netex:Notice>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/offre_C00166_05.xml b/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/offre_C00166_05.xml
new file mode 100644
index 000000000..fac9a3187
--- /dev/null
+++ b/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/offre_C00166_05.xml
@@ -0,0 +1,459 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 5</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>de rambouillet vers orphin</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00166">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>de Orphin vers rambouillet</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00166">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>vers orphin</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>vers rambouillet</netex:Name>
+ </netex:Direction>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC" version="any">
+ <netex:Name>vers orphin</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-3:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-4:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-5:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC" version="any">
+ <netex:Name>Par là</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-3:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-4:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-5:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC" version="any">
+ <netex:FrontText>Mission 1</netex:FrontText>
+ <netex:PublicCode>05011</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC" version="any">
+ <netex:FrontText>Mission 2</netex:FrontText>
+ <netex:PublicCode>05021</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50111663:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78464:ZDE:50016099:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-3:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78464:ZDE:50016096:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-4:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78470:ZDE:50016107:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-5:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78470:ZDE:50016111:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78470:ZDE:50016114:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78470:ZDE:50016108:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-3:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78464:ZDE:50016097:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-4:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78464:ZDE:50016100:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-5:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50111663:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC" version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:2:LOC" version="any">
+ <netex:Name>ITL 2</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 s note 1 </netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:1:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:02:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:10:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:11:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:15:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:16:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:18:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:19:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:22:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-2:LOC" version="any">
+ <netex:Name>Course 1 we not 2 </netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:2:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>09:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>09:02:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>09:10:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>09:11:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>09:15:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>09:16:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>09:18:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>09:19:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>09:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>09:22:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-3:LOC" version="any">
+ <netex:Name>Course 1 exceptionnel note 1 et 2 </netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:3:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:4:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:3:LOC"> version="any"</netex:DayTypeRef>
+ <netex:DayTypeRef ref="CITYWAY:DayType:5:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:02:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:10:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:11:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:15:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:16:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:18:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:19:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:22:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-4:LOC" version="any">
+ <netex:Name>Course 1 semaine en vacances et exclusions note 3 </netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:5:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:6:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:3:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:3:LOC"> version="any"</netex:DayTypeRef>
+ <netex:DayTypeRef ref="CITYWAY:DayType:6:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>11:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>11:02:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>11:10:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>11:11:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>11:15:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>11:16:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>11:18:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>11:19:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>11:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>11:22:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-1:LOC" version="any">
+ <netex:Name>Course 1 semaine note 3 </netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:7:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:3:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:2:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>13:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>13:02:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>13:10:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>13:11:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>13:15:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>13:16:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>13:18:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>13:19:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>13:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>13:22:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/offre_C00168_08.xml b/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/offre_C00168_08.xml
new file mode 100644
index 000000000..77116b8b4
--- /dev/null
+++ b/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/offre_C00168_08.xml
@@ -0,0 +1,667 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 8</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00168">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:3:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00168">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:4:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:3:LOC" version="any">
+ <netex:Name>route 3</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00168">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:3:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:4:LOC" version="any">
+ <netex:Name>route 4</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00168">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:4:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>rambouillet vers auffargis</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>rambouillet vers les essarts</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:3:LOC" version="any">
+ <netex:Name>auffargis vers rambouillet</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:4:LOC" version="any">
+ <netex:Name>les essarts vers rambouillet</netex:Name>
+ </netex:Direction>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC" version="any">
+ <netex:Name>de rambouillet vers auffargis </netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-3:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-4:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-5:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-6:LOC" order="6"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-7:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC" version="any">
+ <netex:Name>de rambouillet aux essarts via le perray</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-3:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-4:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-5:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-6:LOC" order="6"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-8:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-7:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-9:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-8:LOC" order="8"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-10:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:3:LOC" version="any">
+ <netex:Name>auffargis SNCF rambouillet sncf</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:3:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:3:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:3-2-1:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:3-2-2:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:3-2-3:LOC" order="6"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:3-2-4:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:3-2-5:LOC" order="8"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-8:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:3-2-6:LOC" order="9"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-9:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:3-2-7:LOC" order="10"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-10:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:4:LOC" version="any">
+ <netex:Name>les essarts SNCF rambouillet sncf</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:4:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:3:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-3:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-4:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-5:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-6:LOC" order="6"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-8:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-7:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-9:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-8:LOC" order="8"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-10:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC" version="any">
+ <netex:FrontText>Auffargis route du perray</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC" version="any">
+ <netex:FrontText>les essarts sncf</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:3:LOC" version="any">
+ <netex:FrontText>rambouillet</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-8:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-9:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-10:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-8:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-9:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-10:LOC" version="any"/>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78269:ZDE:50111665:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50076501:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-3:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50111663:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-4:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50016341:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-5:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78486:ZDE:50015940:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-6:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78030:ZDE:50015569:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-7:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78030:ZDE:50015577:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-8:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-8:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78486:ZDE:50015930:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-9:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-9:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78486:ZDE:50015937:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-10:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-10:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78220:ZDE:50076444:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78220:ZDE:50076444:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78486:ZDE:50015936:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-3:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78486:ZDE:50015931:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-4:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78030:ZDE:50015576:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-5:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78030:ZDE:50015568:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-6:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78486:ZDE:50015940:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-7:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50016340:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-8:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-8:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50111663:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-9:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-9:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50016206:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-10:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-10:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78269:ZDE:50111664:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC" version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:2:LOC" version="any">
+ <netex:Name>ITL 2</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-8:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 direction auffargis</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:1:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:04:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:06:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:06:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:08:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:08:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:18:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:18:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:21:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:24:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:24:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-1:LOC" version="any">
+ <netex:Name>Course 1 directionles essarts</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:2:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:2:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:04:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:07:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:07:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:08:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:08:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:18:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:18:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:21:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:23:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:23:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:29:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:3-1:LOC" version="any">
+ <netex:Name>Course 1 direction rambouillet</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:3:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:3:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>09:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>09:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>09:04:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>09:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>09:06:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>09:06:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>09:16:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>09:16:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>09:18:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>09:18:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>09:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>09:21:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>09:24:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>09:24:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:4-1:LOC" version="any">
+ <netex:Name>Course 1 les essarts rambouillet</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:4:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:4:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:04:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:07:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:07:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:08:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:08:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:18:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:18:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:21:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:23:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:23:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:29:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/offre_C00171_11.xml b/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/offre_C00171_11.xml
new file mode 100644
index 000000000..9d5309d60
--- /dev/null
+++ b/spec/fixtures/regression-5281/OFFRE_SNTYO_1_20170820120001/offre_C00171_11.xml
@@ -0,0 +1,473 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 11</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00171">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00171">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Rambouillet Auneau </netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Auneau Rambouillet</netex:Name>
+ </netex:Direction>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC" version="any">
+ <netex:Name>orsonville eglise </netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-3:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-4:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC" version="any">
+ <netex:Name>auneau SNCF </netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-2:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-3:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-4:LOC" order="6"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-1-5:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:3:LOC" version="any">
+ <netex:Name>orsonville rambouillet</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:3:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:3-2-1:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:3-2-2:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:3-2-3:LOC" order="6"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:3-2-4:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:4:LOC" version="any">
+ <netex:Name>auneau SNCF rambouillet</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:3:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-3:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-4:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:4-2-5:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC" version="any">
+ <netex:FrontText>Vers orsonville</netex:FrontText>
+ <netex:PublicCode>11011</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC" version="any">
+ <netex:FrontText>vers auneau</netex:FrontText>
+ <netex:PublicCode>11021</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:3:LOC" version="any">
+ <netex:FrontText>vers rambouillet</netex:FrontText>
+ <netex:PublicCode>11031</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50016296:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78003:ZDE:50015543:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-3:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78003:ZDE:50015539:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-4:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78003:ZDE:50015524:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-5:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78472:ZDE:50016121:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-6:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:QuayRef ref="FR:28015:ZDE:50015578:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-7:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:QuayRef ref="FR:28015:ZDE:50015586:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:28015:ZDE:50015587:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:28015:ZDE:50015581:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-3:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78472:ZDE:50016122:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-4:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78003:ZDE:50015523:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-5:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78003:ZDE:50015538:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-6:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78003:ZDE:50015542:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-7:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50016296:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC" version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:2:LOC" version="any">
+ <netex:Name>ITL 2</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 direction orsonville</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:1:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>10:58:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>10:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>11:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>11:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>11:10:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>11:11:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>11:17:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>11:18:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-1:LOC" version="any">
+ <netex:Name>Course 1 direction Auneau sncf</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:2:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:2:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>14:58:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>14:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>15:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>15:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>15:10:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>15:11:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>15:17:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>15:18:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>15:22:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>15:23:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:3-1:LOC" version="any">
+ <netex:Name>direction rambouillet retour</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:3:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:3:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>20:58:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>20:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>21:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>21:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>21:10:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>21:11:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>21:17:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>21:18:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:4-1:LOC" version="any">
+ <netex:Name>de auneau sncf à rambouillet </netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:4:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:4:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>23:58:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>23:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>00:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>1</netex:ArrivalDayOffset>
+ <netex:DepartureTime>00:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>1</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>00:10:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>1</netex:ArrivalDayOffset>
+ <netex:DepartureTime>00:11:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>1</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>00:13:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>1</netex:ArrivalDayOffset>
+ <netex:DepartureTime>00:14:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>1</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>00:17:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>1</netex:ArrivalDayOffset>
+ <netex:DepartureTime>00:18:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>1</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/calendriers.xml b/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/calendriers.xml
new file mode 100644
index 000000000..bc2b63527
--- /dev/null
+++ b/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/calendriers.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:siri="http://www.siri.org.uk/siri"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_CALENDRIER-1_20170214090012:LOC"
+ version="any">
+ <netex:ValidBetween>
+ <netex:FromDate>2017-06-25T00:00:00</netex:FromDate>
+ <netex:ToDate>2017-12-31T00:00:00</netex:ToDate>
+ </netex:ValidBetween>
+ <netex:TypeOfFrameRef ref="NETEX_CALENDRIER"/>
+ <netex:members>
+ <netex:DayType id="CITYWAY:DayType:1:LOC" version="any" >
+ <netex:Name>Semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Monday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Tuesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Wednesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Thursday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Friday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:2:LOC" version="any" >
+ <netex:Name>Fin de semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Saturday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Sunday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:3:LOC" version="any" >
+ <netex:Name>Semaine vacances</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Monday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Tuesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Wednesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Thursday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Friday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:4:LOC" version="any" >
+ <netex:Name>WE vacances</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Saturday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Sunday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:5:LOC" version="any" >
+ <netex:Name>Service spécial</netex:Name>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:6:LOC" version="any" >
+ <netex:Name>Restriction</netex:Name>
+ </netex:DayType>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:1:LOC" version="any" order="0" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:2:LOC" version="any" order="0" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:3:LOC" version="any" order="0" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:3:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:4:LOC" version="any" order="0" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:3:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:5:LOC" version="any" order="0" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:2:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:3:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:6:LOC" version="any" order="0" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:2:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:7:LOC" version="any" order="0" >
+ <netex:Date>2017-07-05</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:5:LOC" version="any"/>
+ <netex:isAvailable>true</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:8:LOC" version="any" order="0" >
+ <netex:Date>2017-08-14</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:6:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:9:LOC" version="any" order="0" >
+ <netex:Date>2017-08-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:6:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="CITYWAY:DayTypeAssignment:10:LOC" version="any" order="0" >
+ <netex:Date>2017-08-16</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:6:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:1:LOC" version="any" >
+ <netex:FromDate>2017-06-25T00:00:00</netex:FromDate>
+ <netex:ToDate>2017-07-01T00:00:00</netex:ToDate>
+ </netex:OperatingPeriod>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:2:LOC" version="any" >
+ <netex:FromDate>2017-07-10T00:00:00</netex:FromDate>
+ <netex:ToDate>2017-08-31T00:00:00</netex:ToDate>
+ </netex:OperatingPeriod>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:3:LOC" version="any" >
+ <netex:FromDate>2017-09-01T00:00:00</netex:FromDate>
+ <netex:ToDate>2017-12-31T00:00:00</netex:ToDate>
+ </netex:OperatingPeriod>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/commun.xml b/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/commun.xml
new file mode 100644
index 000000000..b6337b65f
--- /dev/null
+++ b/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/commun.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_COMMUN-1_20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_COMMUN"/>
+ <netex:members>
+ <netex:Notice id="CITYWAY:Notice:1:LOC" version="any">
+ <netex:Text>note numéro 1</netex:Text>
+ <netex:PublicCode>1</netex:PublicCode>
+ <netex:TypeOfNoticeRef ref="ServiceJourneyNotice" />
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:2:LOC" version="any">
+ <netex:Text>note numéro 2</netex:Text>
+ <netex:PublicCode>2</netex:PublicCode>
+ <netex:TypeOfNoticeRef ref="ServiceJourneyNotice" />
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:3:LOC" version="any">
+ <netex:Text>note numéro 3</netex:Text>
+ <netex:PublicCode>3</netex:PublicCode>
+ <netex:TypeOfNoticeRef ref="ServiceJourneyNotice" />
+ </netex:Notice>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/offre_C00163_01.xml b/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/offre_C00163_01.xml
new file mode 100644
index 000000000..b3bccc74f
--- /dev/null
+++ b/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/offre_C00163_01.xml
@@ -0,0 +1,497 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 01</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name> itinéraire rambouillet vers poigny</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00163">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name> itinéraire poigny vers rambouillet</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00163">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>poigny feuillettes</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>rambouillet SNCF</netex:Name>
+ </netex:Direction>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC" version="any">
+ <netex:Name>rambouillet vers poigny</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-3:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-4:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-5:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC" version="any">
+ <netex:Name>poigny vers rambouillet</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-3:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-4:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-5:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC" version="any">
+ <netex:FrontText>Mission 1</netex:FrontText>
+ <netex:PublicCode>01101</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC" version="any">
+ <netex:FrontText>Mission 2</netex:FrontText>
+ <netex:PublicCode>01201</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50111663:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78497:ZDE:50016141:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78497:ZDE:50016136:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78497:ZDE:50016139:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-3:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78497:ZDE:50016142:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-3:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78497:ZDE:50016143:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-4:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78497:ZDE:50016138:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-4:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78497:ZDE:50016137:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-5:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78497:ZDE:50016140:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-5:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50111663:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC" version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:2:LOC" version="any">
+ <netex:Name>ITL 2</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-01:LOC" version="any">
+ <netex:Name>Course 01 rambouillet vers poigny</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:1:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:01101:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:09:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:09:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:11:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:11:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:13:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:13:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:15:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:15:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-02:LOC" version="any">
+ <netex:Name>Course 02 rambouillet vers poigny</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:2:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:01101:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:09:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:09:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:11:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:11:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:13:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:13:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:15:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:15:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-03:LOC" version="any">
+ <netex:Name>Course 03 rambouillet vers poigny</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:3:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:01101:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:31:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:31:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:39:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:39:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:41:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:41:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:43:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:43:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:45:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:45:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-01:LOC" version="any">
+ <netex:Name>Course 01 poigny vers rambouillet</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:4:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:2:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:01101:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:21:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:29:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:31:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:31:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:33:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:33:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:35:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:35:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-02:LOC" version="any">
+ <netex:Name>Course 02 poigny vers rambouillet</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:5:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:2:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:01101:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:21:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:29:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:31:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:31:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:33:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:33:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:35:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:35:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-03:LOC" version="any">
+ <netex:Name>Course 03 poigny vers rambouillet</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:6:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:2:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:01101:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:51:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:51:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:59:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:03:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:05:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:05:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/offre_C00164_03.xml b/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/offre_C00164_03.xml
new file mode 100644
index 000000000..56d6ce805
--- /dev/null
+++ b/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/offre_C00164_03.xml
@@ -0,0 +1,951 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 03</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00164">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00164">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>rambouillet vers pontevrard</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name> pontevrard vers rambouillet</netex:Name>
+ </netex:Direction>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC" version="any">
+ <netex:Name>omnibus pontevrard</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>false</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-3:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ForAlighting>false</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-4:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-5:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-6:LOC" order="6"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-7:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC" version="any">
+ <netex:Name> omnibus rambouillet</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-3:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-4:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-5:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-6:LOC" order="6"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-7:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:3:LOC" version="any">
+ <netex:Name>semi direct pontevrard</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:3:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-3-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-3-2:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-3-3:LOC" order="6"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-3-4:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:4:LOC" version="any">
+ <netex:Name> semi direct rambouillet</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:4:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-4-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-4-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-4-3:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-4-4:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC" version="any">
+ <netex:FrontText>pontevrard omni</netex:FrontText>
+ <netex:PublicCode>03011</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC" version="any">
+ <netex:FrontText>dourdan omni</netex:FrontText>
+ <netex:PublicCode>03021</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:3:LOC" version="any">
+ <netex:FrontText>pontevrard sd</netex:FrontText>
+ <netex:PublicCode>03012</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:4:LOC" version="any">
+ <netex:FrontText>dourdan sd</netex:FrontText>
+ <netex:PublicCode>03022</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:91200:ZDE:50097554:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:91200:ZDE:50097522:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-3:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78569:ZDE:50016385:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-4:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78569:ZDE:50016381:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-5:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78569:ZDE:50016379:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-6:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78499:ZDE:50016153:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-7:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78499:ZDE:50016155:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78499:ZDE:50016154:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78499:ZDE:50016152:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-3:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78569:ZDE:50016378:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-4:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78569:ZDE:50016380:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-5:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78569:ZDE:50016384:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-6:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:QuayRef ref="FR:91200:ZDE:50097522:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-7:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:QuayRef ref="FR:91200:ZDE:50097554:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC" version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:2:LOC" version="any">
+ <netex:Name>ITL 2</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 omni vers pontevrard</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:1:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:00:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:04:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:08:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:09:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:13:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:13:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:18:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:18:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:22:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:25:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:26:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-2:LOC" version="any">
+ <netex:Name>Course 2 omni vers pontevrard</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:2:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:00:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:04:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:08:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:09:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:13:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:13:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:18:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:18:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:22:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:25:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:26:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-3:LOC" version="any">
+ <netex:Name>Course 3 omni vers pontevrard</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:3:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:00:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:04:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:08:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:09:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:13:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:13:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:18:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:18:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:22:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:25:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:26:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-4:LOC" version="any">
+ <netex:Name>Course 4 sd vers pontevrard</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:4:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:3:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:30:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:31:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:37:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:37:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:40:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:41:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:44:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:45:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-5:LOC" version="any">
+ <netex:Name>Course 5 sd vers pontevrard</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:5:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:3:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:30:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:31:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:37:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:37:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:40:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:41:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:44:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:45:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-6:LOC" version="any">
+
+
+ <netex:Name>Course 6 sd vers pontevrard</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:6:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:3:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:30:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:31:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:37:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:37:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:40:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:41:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:44:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:45:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-1:LOC" version="any">
+ <netex:Name>Course 1 omni vers rambouillet</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:7:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:2:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:20:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:21:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:24:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:24:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:28:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:33:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:33:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:38:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:38:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:41:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:42:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:45:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:46:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-2:LOC" version="any">
+ <netex:Name>Course 2 omni vers rambouillet</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:8:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:2:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:20:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:21:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:24:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:24:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:28:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:33:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:33:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:38:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:38:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:41:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:42:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:45:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:46:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-3:LOC" version="any">
+ <netex:Name>Course 3 omni vers rambouillet</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:9:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:2:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:20:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:21:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:24:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:24:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:28:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:33:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:33:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:38:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:38:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:41:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:42:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:45:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:46:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-4:LOC" version="any">
+ <netex:Name>Course 4 sd vers rambouillet</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:10:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:4:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:40:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:41:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:47:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:47:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:50:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:51:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:54:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:55:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-5:LOC" version="any">
+ <netex:Name>Course 5 sd vers rambouillet</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:11:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:4:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:40:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:41:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:47:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:47:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:50:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:51:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:54:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:55:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-6:LOC" version="any">
+ <netex:Name>Course 6 sd vers rambouillet</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:12:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:4:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:40:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:41:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:47:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:47:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:50:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:51:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:54:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:55:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/offre_C00165_04.xml b/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/offre_C00165_04.xml
new file mode 100644
index 000000000..714e9565f
--- /dev/null
+++ b/spec/fixtures/regression-5281/OFFRE_SNTYO_2_20170820120001/offre_C00165_04.xml
@@ -0,0 +1,803 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 4</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00165">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00165">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>rambouillet vers bullion</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>bullon vers rambouillet</netex:Name>
+ </netex:Direction>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC" version="any">
+ <netex:Name>rambouillet vers bullion</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-3:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-4:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-5:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-6:LOC" order="6"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-7:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-8:LOC" order="8"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-8:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-9:LOC" order="9"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-9:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-10:LOC" order="10"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-10:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC" version="any">
+ <netex:Name>bullion vers rambouillet</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-3:LOC" order="3"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-4:LOC" order="4"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-5:LOC" order="5"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-6:LOC" order="6"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-7:LOC" order="7"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-8:LOC" order="8"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-8:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-9:LOC" order="9"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-9:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-10:LOC" order="10"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-10:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC" version="any">
+ <netex:FrontText>Mission 1</netex:FrontText>
+ <netex:PublicCode>05010</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC" version="any">
+ <netex:FrontText>Mission 2</netex:FrontText>
+ <netex:PublicCode>05021</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-8:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-9:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-10:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-8:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-9:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-10:LOC" version="any"/>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50111663:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50076506:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-3:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78164:ZDE:50015685:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-4:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78164:ZDE:50015683:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-5:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-5:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78164:ZDE:50015687:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-6:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-6:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78125:ZDE:50015678:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-7:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-7:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78125:ZDE:50015676:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-8:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-8:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78125:ZDE:50015672:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-9:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-9:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78120:ZDE:50015671:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-10:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-10:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78120:ZDE:50015667:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78120:ZDE:50015666:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78120:ZDE:50015670:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-3:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-3:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78125:ZDE:50015673:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-4:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-4:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78125:ZDE:50015677:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-5:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-5:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78125:ZDE:50015679:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-6:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-6:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78164:ZDE:50015686:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-7:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78164:ZDE:50015682:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-8:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-8:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78164:ZDE:50015684:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-9:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-9:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50076505:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-10:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-10:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78517:ZDE:50111663:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC" version="any">
+ <netex:Name>ITL RBT clairefontaine </netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-3:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-4:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:2:LOC" version="any">
+ <netex:Name>ITL clairefontaine RBT</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-7:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-8:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-9:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-10:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:3:LOC" version="any">
+ <netex:Name>ITL bullion </netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-9:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-10:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>C1 bullion semaine</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:1:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:05:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:05:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:09:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:09:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:12:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:12:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:15:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:15:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:22:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:25:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:25:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:29:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:31:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:32:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:34:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:35:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-2:LOC" version="any">
+ <netex:Name>C bullion WE</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:2:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:05:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:05:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:09:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:09:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:12:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:12:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:15:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:15:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:22:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:25:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:25:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:29:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:31:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:32:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:34:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:35:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-3:LOC" version="any">
+ <netex:Name>C bullion WE</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:3:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:05:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:05:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:09:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:09:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:12:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:12:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:15:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:15:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:22:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:25:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:25:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:29:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:31:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:32:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>08:34:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>08:35:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-1:LOC" version="any">
+ <netex:Name>C rbt semaine</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:4:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:2:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:21:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:25:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:25:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:29:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:32:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:32:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:35:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:35:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:41:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:42:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:45:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:45:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:49:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:49:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:51:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:52:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>05:54:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>05:55:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-2:LOC" version="any">
+ <netex:Name>C rbt we</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:5:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:2:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:21:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:25:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:25:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:29:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:32:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:32:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:35:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:35:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:41:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:42:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:45:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:45:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:49:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:49:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:51:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:52:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>06:54:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>06:55:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:2-3:LOC" version="any">
+ <netex:Name>C rbt semaine et we</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="CITYWAY:NoticeAssignment:6:LOC" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:2:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:013">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:21:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:21:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:25:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:25:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:29:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:29:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:32:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:32:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:35:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:35:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:41:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:42:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:45:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:45:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:49:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:49:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:51:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:52:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>07:54:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>07:55:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/some_foreign_mixed/FOREIGN_LINE/calendriers.xml b/spec/fixtures/some_foreign_mixed/FOREIGN_LINE/calendriers.xml
new file mode 100644
index 000000000..bfbd0aea1
--- /dev/null
+++ b/spec/fixtures/some_foreign_mixed/FOREIGN_LINE/calendriers.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:siri="http://www.siri.org.uk/siri" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_CALENDRIER-1_20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_CALENDRIER"/>
+ <netex:ValidBetween>
+ <netex:FromDate>2017-03-01</netex:FromDate>
+ <netex:ToDate>2017-03-31</netex:ToDate>
+ </netex:ValidBetween>
+ <netex:members>
+ <netex:dayTypes>
+ <netex:DayType id="CITYWAY:DayType:1:LOC" version="any" >
+ <netex:Name>Semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Monday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Tuesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Wednesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Thursday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Friday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:2:LOC" version="any" >
+ <netex:Name>Fin de semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Saturday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Sunday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:3:LOC" version="any" >
+ <netex:Name>Service spécial</netex:Name>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:4:LOC" version="any" >
+ <netex:Name>Restriction</netex:Name>
+ </netex:DayType>
+ </netex:dayTypes>
+ <netex:dayTypeAssignments>
+ <netex:DayTypeAssignment version="any" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:3:LOC" version="any"/>
+ <netex:isAvailable>true</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ </netex:dayTypeAssignments>
+ <netex:operatingPeriods>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:1:LOC" version="any" >
+ <netex:FromDate>2017-01-01</netex:FromDate>
+ <netex:ToDate>2017-12-31</netex:ToDate>
+ </netex:OperatingPeriod>
+ </netex:operatingPeriods>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/some_foreign_mixed/FOREIGN_LINE/commun.xml b/spec/fixtures/some_foreign_mixed/FOREIGN_LINE/commun.xml
new file mode 100644
index 000000000..266c8a598
--- /dev/null
+++ b/spec/fixtures/some_foreign_mixed/FOREIGN_LINE/commun.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:siri="http://www.siri.org.uk/siri" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_COMMUN-1_20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_COMMUN"/>
+ <netex:members>
+ <netex:notices>
+ <netex:Notice id="CITYWAY:Notice:1:LOC" version="any">
+ <netex:Text>Notice 1</netex:Text>
+ <netex:PublicCode>1</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:2:LOC" version="any">
+ <netex:Text>Notice 2</netex:Text>
+ <netex:PublicCode>2</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:3:LOC" version="any">
+ <netex:Text>Notice 3</netex:Text>
+ <netex:PublicCode>3</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ </netex:notices>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/some_foreign_mixed/FOREIGN_LINE/offre_C00107_10.xml b/spec/fixtures/some_foreign_mixed/FOREIGN_LINE/offre_C00107_10.xml
new file mode 100644
index 000000000..9dff0d850
--- /dev/null
+++ b/spec/fixtures/some_foreign_mixed/FOREIGN_LINE/offre_C00107_10.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd"
+ xmlns:netex="http://www.netex.org.uk/netex" xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:routes>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ </netex:routes>
+ <netex:directions>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici aussi</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là aussi</netex:Name>
+ </netex:Direction>
+ </netex:directions>
+ <netex:serviceJourneyPatterns>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any">
+ <netex:Name>Par ici itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC"
+ version="any">
+ <netex:Name>Par là itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ </netex:serviceJourneyPatterns>
+ <netex:destinationDisplays>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC"
+ version="any">
+ <netex:FrontText>Mission 1 bis</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC"
+ version="any">
+ <netex:FrontText>Mission 2 bis</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ </netex:destinationDisplays>
+ <netex:scheduledStopPoints>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC"
+ version="any"/>
+ </netex:scheduledStopPoints>
+ <netex:passengerStopAssignments>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000918:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000917:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ </netex:passengerStopAssignments>
+ <netex:routingConstraintZones>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC"
+ version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:routingConstraintZones>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:serviceJourneys>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici aussi</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment>
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:212">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>23:58:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>23:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>00:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>1</netex:ArrivalDayOffset>
+ <netex:DepartureTime>00:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>1</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:serviceJourneys>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/some_foreign_mixed/FOREIGN_LINE/offre_C00108_9.xml b/spec/fixtures/some_foreign_mixed/FOREIGN_LINE/offre_C00108_9.xml
new file mode 100644
index 000000000..832793036
--- /dev/null
+++ b/spec/fixtures/some_foreign_mixed/FOREIGN_LINE/offre_C00108_9.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd"
+ xmlns:netex="http://www.netex.org.uk/netex" xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:routes>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ </netex:routes>
+ <netex:directions>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là</netex:Name>
+ </netex:Direction>
+ </netex:directions>
+ <netex:serviceJourneyPatterns>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any">
+ <netex:Name>Par ici</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC"
+ version="any">
+ <netex:Name>Par là</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ </netex:serviceJourneyPatterns>
+ <netex:destinationDisplays>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC"
+ version="any">
+ <netex:FrontText>Mission 1</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC"
+ version="any">
+ <netex:FrontText>Mission 2</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ </netex:destinationDisplays>
+ <netex:scheduledStopPoints>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC"
+ version="any"/>
+ </netex:scheduledStopPoints>
+ <netex:passengerStopAssignments>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009052:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009053:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ </netex:passengerStopAssignments>
+ <netex:routingConstraintZones>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC"
+ version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:routingConstraintZones>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:serviceJourneys>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment>
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:011">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:05:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:05:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:serviceJourneys>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/calendriers.xml b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/calendriers.xml
new file mode 100644
index 000000000..bfbd0aea1
--- /dev/null
+++ b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/calendriers.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:siri="http://www.siri.org.uk/siri" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_CALENDRIER-1_20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_CALENDRIER"/>
+ <netex:ValidBetween>
+ <netex:FromDate>2017-03-01</netex:FromDate>
+ <netex:ToDate>2017-03-31</netex:ToDate>
+ </netex:ValidBetween>
+ <netex:members>
+ <netex:dayTypes>
+ <netex:DayType id="CITYWAY:DayType:1:LOC" version="any" >
+ <netex:Name>Semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Monday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Tuesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Wednesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Thursday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Friday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:2:LOC" version="any" >
+ <netex:Name>Fin de semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Saturday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Sunday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:3:LOC" version="any" >
+ <netex:Name>Service spécial</netex:Name>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:4:LOC" version="any" >
+ <netex:Name>Restriction</netex:Name>
+ </netex:DayType>
+ </netex:dayTypes>
+ <netex:dayTypeAssignments>
+ <netex:DayTypeAssignment version="any" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:3:LOC" version="any"/>
+ <netex:isAvailable>true</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ </netex:dayTypeAssignments>
+ <netex:operatingPeriods>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:1:LOC" version="any" >
+ <netex:FromDate>2017-01-01</netex:FromDate>
+ <netex:ToDate>2017-12-31</netex:ToDate>
+ </netex:OperatingPeriod>
+ </netex:operatingPeriods>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/commun.xml b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/commun.xml
new file mode 100644
index 000000000..266c8a598
--- /dev/null
+++ b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/commun.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:siri="http://www.siri.org.uk/siri" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_COMMUN-1_20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_COMMUN"/>
+ <netex:members>
+ <netex:notices>
+ <netex:Notice id="CITYWAY:Notice:1:LOC" version="any">
+ <netex:Text>Notice 1</netex:Text>
+ <netex:PublicCode>1</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:2:LOC" version="any">
+ <netex:Text>Notice 2</netex:Text>
+ <netex:PublicCode>2</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:3:LOC" version="any">
+ <netex:Text>Notice 3</netex:Text>
+ <netex:PublicCode>3</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ </netex:notices>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml
new file mode 100644
index 000000000..832793036
--- /dev/null
+++ b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd"
+ xmlns:netex="http://www.netex.org.uk/netex" xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:routes>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ </netex:routes>
+ <netex:directions>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là</netex:Name>
+ </netex:Direction>
+ </netex:directions>
+ <netex:serviceJourneyPatterns>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any">
+ <netex:Name>Par ici</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC"
+ version="any">
+ <netex:Name>Par là</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ </netex:serviceJourneyPatterns>
+ <netex:destinationDisplays>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC"
+ version="any">
+ <netex:FrontText>Mission 1</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC"
+ version="any">
+ <netex:FrontText>Mission 2</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ </netex:destinationDisplays>
+ <netex:scheduledStopPoints>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC"
+ version="any"/>
+ </netex:scheduledStopPoints>
+ <netex:passengerStopAssignments>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009052:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009053:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ </netex:passengerStopAssignments>
+ <netex:routingConstraintZones>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC"
+ version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:routingConstraintZones>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:serviceJourneys>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment>
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:011">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:05:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:05:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:serviceJourneys>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml
new file mode 100644
index 000000000..9dff0d850
--- /dev/null
+++ b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd"
+ xmlns:netex="http://www.netex.org.uk/netex" xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:routes>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ </netex:routes>
+ <netex:directions>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici aussi</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là aussi</netex:Name>
+ </netex:Direction>
+ </netex:directions>
+ <netex:serviceJourneyPatterns>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any">
+ <netex:Name>Par ici itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC"
+ version="any">
+ <netex:Name>Par là itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ </netex:serviceJourneyPatterns>
+ <netex:destinationDisplays>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC"
+ version="any">
+ <netex:FrontText>Mission 1 bis</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC"
+ version="any">
+ <netex:FrontText>Mission 2 bis</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ </netex:destinationDisplays>
+ <netex:scheduledStopPoints>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC"
+ version="any"/>
+ </netex:scheduledStopPoints>
+ <netex:passengerStopAssignments>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000918:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000917:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ </netex:passengerStopAssignments>
+ <netex:routingConstraintZones>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC"
+ version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:routingConstraintZones>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:serviceJourneys>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici aussi</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment>
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:212">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>23:58:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>23:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>00:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>1</netex:ArrivalDayOffset>
+ <netex:DepartureTime>00:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>1</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:serviceJourneys>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/calendriers.xml b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/calendriers.xml
new file mode 100644
index 000000000..1043e0cde
--- /dev/null
+++ b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/calendriers.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_CALENDRIER-1_20170214090012:LOC" version="any">
+ <netex:ValidBetween>
+ <netex:FromDate>2017-04-01T00:00:00</netex:FromDate>
+ <netex:ToDate>2017-12-31T00:00:00</netex:ToDate>
+ </netex:ValidBetween>
+ <netex:TypeOfFrameRef ref="NETEX_CALENDRIER"/>
+ <netex:members>
+ <netex:DayType id="CITYWAY:DayType:1:LOC" version="any">
+ <netex:Name>Semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Monday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Tuesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Wednesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Thursday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Friday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:2:LOC" version="any">
+ <netex:Name>Fin de semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Saturday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Sunday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:3:LOC" version="any">
+ <netex:Name>Service spécial</netex:Name>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:4:LOC" version="any">
+ <netex:Name>Restriction</netex:Name>
+ </netex:DayType>
+ <netex:DayTypeAssignment id="dta1" version="any" order="0">
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="dta2" version="any" order="0">
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="dta3" version="any" order="0">
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:3:LOC" version="any"/>
+ <netex:isAvailable>true</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="dta4" version="any" order="0">
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:1:LOC" version="any">
+ <netex:FromDate>2017-01-01T00:00:00</netex:FromDate>
+ <netex:ToDate>2017-12-31T00:00:00</netex:ToDate>
+ </netex:OperatingPeriod>
+
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/commun.xml b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/commun.xml
new file mode 100644
index 000000000..f59f8ac2d
--- /dev/null
+++ b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/commun.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_COMMUN-1_20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_COMMUN"/>
+ <netex:members>
+
+ <netex:Notice id="CITYWAY:Notice:1:LOC" version="any">
+ <netex:Text>Notice 1</netex:Text>
+ <netex:PublicCode>1</netex:PublicCode>
+ <netex:TypeOfNoticeRef ref="ServiceJourneyNotice"/>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:2:LOC" version="any">
+ <netex:Text>Notice 2</netex:Text>
+ <netex:PublicCode>2</netex:PublicCode>
+ <netex:TypeOfNoticeRef ref="ServiceJourneyNotice"/>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:3:LOC" version="any">
+ <netex:Text>Notice 3</netex:Text>
+ <netex:PublicCode>3</netex:PublicCode>
+ <netex:TypeOfNoticeRef ref="ServiceJourneyNotice"/>
+ </netex:Notice>
+
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml
new file mode 100644
index 000000000..9eefeeb43
--- /dev/null
+++ b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+
+
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là</netex:Name>
+ </netex:Direction>
+
+
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC" version="any">
+ <netex:Name>Par ici</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC" version="any">
+ <netex:Name>Par là</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+
+
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC" version="any">
+ <netex:FrontText>Mission 1</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC" version="any">
+ <netex:FrontText>Mission 2</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+
+
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+
+
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009052:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009053:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+
+
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC" version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="ns1" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:011">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:05:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:05:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml
new file mode 100644
index 000000000..d260ef17e
--- /dev/null
+++ b/spec/fixtures/some_foreign_mixed/OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+
+
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici aussi</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là aussi</netex:Name>
+ </netex:Direction>
+
+
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC" version="any">
+ <netex:Name>Par ici itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC" version="any">
+ <netex:Name>Par là itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+
+
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC" version="any">
+ <netex:FrontText>Mission 1 bis</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC" version="any">
+ <netex:FrontText>Mission 2 bis</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+
+
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+
+
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000918:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000917:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+
+
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC" version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici aussi</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="ns1" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:212">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>23:58:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>23:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>00:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>1</netex:ArrivalDayOffset>
+ <netex:DepartureTime>00:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>1</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/calendriers.xml b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/calendriers.xml
new file mode 100644
index 000000000..bfbd0aea1
--- /dev/null
+++ b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/calendriers.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:siri="http://www.siri.org.uk/siri" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_CALENDRIER-1_20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_CALENDRIER"/>
+ <netex:ValidBetween>
+ <netex:FromDate>2017-03-01</netex:FromDate>
+ <netex:ToDate>2017-03-31</netex:ToDate>
+ </netex:ValidBetween>
+ <netex:members>
+ <netex:dayTypes>
+ <netex:DayType id="CITYWAY:DayType:1:LOC" version="any" >
+ <netex:Name>Semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Monday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Tuesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Wednesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Thursday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Friday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:2:LOC" version="any" >
+ <netex:Name>Fin de semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Saturday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Sunday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:3:LOC" version="any" >
+ <netex:Name>Service spécial</netex:Name>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:4:LOC" version="any" >
+ <netex:Name>Restriction</netex:Name>
+ </netex:DayType>
+ </netex:dayTypes>
+ <netex:dayTypeAssignments>
+ <netex:DayTypeAssignment version="any" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:3:LOC" version="any"/>
+ <netex:isAvailable>true</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment version="any" >
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ </netex:dayTypeAssignments>
+ <netex:operatingPeriods>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:1:LOC" version="any" >
+ <netex:FromDate>2017-01-01</netex:FromDate>
+ <netex:ToDate>2017-12-31</netex:ToDate>
+ </netex:OperatingPeriod>
+ </netex:operatingPeriods>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/commun.xml b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/commun.xml
new file mode 100644
index 000000000..266c8a598
--- /dev/null
+++ b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/commun.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:siri="http://www.siri.org.uk/siri" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_COMMUN-1_20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_COMMUN"/>
+ <netex:members>
+ <netex:notices>
+ <netex:Notice id="CITYWAY:Notice:1:LOC" version="any">
+ <netex:Text>Notice 1</netex:Text>
+ <netex:PublicCode>1</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:2:LOC" version="any">
+ <netex:Text>Notice 2</netex:Text>
+ <netex:PublicCode>2</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:3:LOC" version="any">
+ <netex:Text>Notice 3</netex:Text>
+ <netex:PublicCode>3</netex:PublicCode>
+ <netex:TypeOfNoticeRef>ServiceJourneyNotice</netex:TypeOfNoticeRef>
+ </netex:Notice>
+ </netex:notices>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml
new file mode 100644
index 000000000..832793036
--- /dev/null
+++ b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/offre_C00108_9.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd"
+ xmlns:netex="http://www.netex.org.uk/netex" xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:routes>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ </netex:routes>
+ <netex:directions>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là</netex:Name>
+ </netex:Direction>
+ </netex:directions>
+ <netex:serviceJourneyPatterns>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any">
+ <netex:Name>Par ici</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC"
+ version="any">
+ <netex:Name>Par là</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ </netex:serviceJourneyPatterns>
+ <netex:destinationDisplays>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC"
+ version="any">
+ <netex:FrontText>Mission 1</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC"
+ version="any">
+ <netex:FrontText>Mission 2</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ </netex:destinationDisplays>
+ <netex:scheduledStopPoints>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC"
+ version="any"/>
+ </netex:scheduledStopPoints>
+ <netex:passengerStopAssignments>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009052:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009053:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ </netex:passengerStopAssignments>
+ <netex:routingConstraintZones>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC"
+ version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:routingConstraintZones>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:serviceJourneys>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment>
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:011">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:05:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:05:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:serviceJourneys>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml
new file mode 100644
index 000000000..9dff0d850
--- /dev/null
+++ b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122517/offre_C00109_10.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd"
+ xmlns:netex="http://www.netex.org.uk/netex" xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+ <netex:routes>
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+ </netex:routes>
+ <netex:directions>
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici aussi</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là aussi</netex:Name>
+ </netex:Direction>
+ </netex:directions>
+ <netex:serviceJourneyPatterns>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any">
+ <netex:Name>Par ici itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC"
+ version="any">
+ <netex:Name>Par là itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC"
+ version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern
+ id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ </netex:serviceJourneyPatterns>
+ <netex:destinationDisplays>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC"
+ version="any">
+ <netex:FrontText>Mission 1 bis</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC"
+ version="any">
+ <netex:FrontText>Mission 2 bis</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+ </netex:destinationDisplays>
+ <netex:scheduledStopPoints>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC"
+ version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC"
+ version="any"/>
+ </netex:scheduledStopPoints>
+ <netex:passengerStopAssignments>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000918:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000917:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment
+ id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any">
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ </netex:passengerStopAssignments>
+ <netex:routingConstraintZones>
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC"
+ version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef
+ ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+ </netex:routingConstraintZones>
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC"
+ version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+ <netex:serviceJourneys>
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici aussi</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment>
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC">
+ version="any"</netex:DayTypeRef>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC"
+ version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:212">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>23:58:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>23:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>00:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>1</netex:ArrivalDayOffset>
+ <netex:DepartureTime>00:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>1</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+ </netex:serviceJourneys>
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/calendriers.xml b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/calendriers.xml
new file mode 100644
index 000000000..1043e0cde
--- /dev/null
+++ b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/calendriers.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_CALENDRIER-1_20170214090012:LOC" version="any">
+ <netex:ValidBetween>
+ <netex:FromDate>2017-04-01T00:00:00</netex:FromDate>
+ <netex:ToDate>2017-12-31T00:00:00</netex:ToDate>
+ </netex:ValidBetween>
+ <netex:TypeOfFrameRef ref="NETEX_CALENDRIER"/>
+ <netex:members>
+ <netex:DayType id="CITYWAY:DayType:1:LOC" version="any">
+ <netex:Name>Semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Monday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Tuesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Wednesday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Thursday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Friday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:2:LOC" version="any">
+ <netex:Name>Fin de semaine</netex:Name>
+ <netex:properties>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Saturday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ <netex:PropertyOfDay>
+ <netex:DaysOfWeek>Sunday</netex:DaysOfWeek>
+ </netex:PropertyOfDay>
+ </netex:properties>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:3:LOC" version="any">
+ <netex:Name>Service spécial</netex:Name>
+ </netex:DayType>
+ <netex:DayType id="CITYWAY:DayType:4:LOC" version="any">
+ <netex:Name>Restriction</netex:Name>
+ </netex:DayType>
+ <netex:DayTypeAssignment id="dta1" version="any" order="0">
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="dta2" version="any" order="0">
+ <netex:OperatingPeriodRef ref="CITYWAY:OperatingPeriod:1:LOC" version="any"/>
+ <netex:DayTypeRef ref="CITYWAY:DayType:2:LOC" version="any"/>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="dta3" version="any" order="0">
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:3:LOC" version="any"/>
+ <netex:isAvailable>true</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:DayTypeAssignment id="dta4" version="any" order="0">
+ <netex:Date>2017-03-15</netex:Date>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC" version="any"/>
+ <netex:isAvailable>false</netex:isAvailable>
+ </netex:DayTypeAssignment>
+ <netex:OperatingPeriod id="CITYWAY:OperatingPeriod:1:LOC" version="any">
+ <netex:FromDate>2017-01-01T00:00:00</netex:FromDate>
+ <netex:ToDate>2017-12-31T00:00:00</netex:ToDate>
+ </netex:OperatingPeriod>
+
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/commun.xml b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/commun.xml
new file mode 100644
index 000000000..f59f8ac2d
--- /dev/null
+++ b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/commun.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:gml="http://www.opengis.net/gml/3.2"
+ xmlns:core="http://www.govtalk.gov.uk/core" xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_COMMUN-1_20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_COMMUN"/>
+ <netex:members>
+
+ <netex:Notice id="CITYWAY:Notice:1:LOC" version="any">
+ <netex:Text>Notice 1</netex:Text>
+ <netex:PublicCode>1</netex:PublicCode>
+ <netex:TypeOfNoticeRef ref="ServiceJourneyNotice"/>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:2:LOC" version="any">
+ <netex:Text>Notice 2</netex:Text>
+ <netex:PublicCode>2</netex:PublicCode>
+ <netex:TypeOfNoticeRef ref="ServiceJourneyNotice"/>
+ </netex:Notice>
+ <netex:Notice id="CITYWAY:Notice:3:LOC" version="any">
+ <netex:Text>Notice 3</netex:Text>
+ <netex:PublicCode>3</netex:PublicCode>
+ <netex:TypeOfNoticeRef ref="ServiceJourneyNotice"/>
+ </netex:Notice>
+
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml
new file mode 100644
index 000000000..9eefeeb43
--- /dev/null
+++ b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/offre_C00108_9.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00108">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+
+
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là</netex:Name>
+ </netex:Direction>
+
+
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC" version="any">
+ <netex:Name>Par ici</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC" version="any">
+ <netex:Name>Par là</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+
+
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC" version="any">
+ <netex:FrontText>Mission 1</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC" version="any">
+ <netex:FrontText>Mission 2</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+
+
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+
+
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009052:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50009053:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+
+
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC" version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="ns1" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:1:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:011">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:01:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:01:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>01:05:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>01:05:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml
new file mode 100644
index 000000000..d260ef17e
--- /dev/null
+++ b/spec/fixtures/two_referentials_ok/OFFRE_TRANSDEV_20170301122519/offre_C00109_10.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<netex:PublicationDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.netex.org.uk/netex ../../xsd/NeTEx_publication.xsd" xmlns:netex="http://www.netex.org.uk/netex"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ifopt="http://www.ifopt.org.uk/ifopt"
+ xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:core="http://www.govtalk.gov.uk/core"
+ xmlns:siri="http://www.siri.org.uk/siri" version="1.0">
+ <netex:PublicationTimestamp>2017-02-14T09:13:51.0</netex:PublicationTimestamp>
+ <netex:ParticipantRef>CITYWAY</netex:ParticipantRef>
+ <netex:dataObjects>
+ <netex:CompositeFrame id="CITYWAY:CompositeFrame:NETEX_OFFRE_LIGNE-1:LOC" version="any">
+ <netex:Name>Ligne 1</netex:Name>
+ <netex:TypeOfFrameRef ref="NETEX_OFFRE_LIGNE"/>
+ <netex:frames>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_STRUCTURE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_STRUCTURE"/>
+ <netex:members>
+
+ <netex:Route id="CITYWAY:Route:1:LOC" version="any">
+ <netex:Name>route 1</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>outbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:1:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ </netex:Route>
+ <netex:Route id="CITYWAY:Route:2:LOC" version="any">
+ <netex:Name>route 2</netex:Name>
+ <netex:LineRef ref="STIF:CODIFLIGNE:Line:C00109">version="any"</netex:LineRef>
+ <netex:DirectionType>inbound</netex:DirectionType>
+ <netex:DirectionRef ref="CITYWAY:Direction:2:LOC" version="any"/>
+ <netex:InverseRouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ </netex:Route>
+
+
+ <netex:Direction id="CITYWAY:Direction:1:LOC" version="any">
+ <netex:Name>Par ici aussi</netex:Name>
+ </netex:Direction>
+ <netex:Direction id="CITYWAY:Direction:2:LOC" version="any">
+ <netex:Name>Par là aussi</netex:Name>
+ </netex:Direction>
+
+
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:1:LOC" version="any">
+ <netex:Name>Par ici itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:1:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:1:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:1-1-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+ <netex:ServiceJourneyPattern id="CITYWAY:ServiceJourneyPattern:2:LOC" version="any">
+ <netex:Name>Par là itou</netex:Name>
+ <netex:RouteRef ref="CITYWAY:Route:2:LOC" version="any"/>
+ <netex:DestinationDisplayRef ref="CITYWAY:DestinationDisplay:2:LOC" version="any"/>
+ <netex:pointsInSequence>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-1:LOC" order="1"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ <netex:StopPointInJourneyPattern id="CITYWAY:StopPointInJourneyPattern:2-2-2:LOC" order="2"
+ version="any">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:ForAlighting>true</netex:ForAlighting>
+ <netex:ForBoarding>true</netex:ForBoarding>
+ </netex:StopPointInJourneyPattern>
+ </netex:pointsInSequence>
+ <netex:ServiceJourneyPatternType>passenger</netex:ServiceJourneyPatternType>
+ </netex:ServiceJourneyPattern>
+
+
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:1:LOC" version="any">
+ <netex:FrontText>Mission 1 bis</netex:FrontText>
+ <netex:PublicCode>1234</netex:PublicCode>
+ </netex:DestinationDisplay>
+ <netex:DestinationDisplay id="CITYWAY:DestinationDisplay:2:LOC" version="any">
+ <netex:FrontText>Mission 2 bis</netex:FrontText>
+ <netex:PublicCode>2345</netex:PublicCode>
+ </netex:DestinationDisplay>
+
+
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:ScheduledStopPoint id="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+
+
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094817:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-1:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-1:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000918:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:1-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78402:ZDE:50000917:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+ <netex:PassengerStopAssignment id="CITYWAY:PassengerStopAssignment:2-2:LOC" version="any" order="0">
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:2-2:LOC" version="any"/>
+ <netex:QuayRef ref="FR:78217:ZDE:50094816:STIF">version="any"</netex:QuayRef>
+ </netex:PassengerStopAssignment>
+
+
+ <netex:RoutingConstraintZone id="CITYWAY:RoutingConstraintZone:1:LOC" version="any">
+ <netex:Name>ITL 1</netex:Name>
+ <netex:members>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-1:LOC" version="any"/>
+ <netex:ScheduledStopPointRef ref="CITYWAY:ScheduledStopPoint:1-2:LOC" version="any"/>
+ </netex:members>
+ <netex:ZoneUse>cannotBoardAndAlightInSameZone</netex:ZoneUse>
+ </netex:RoutingConstraintZone>
+
+ </netex:members>
+ </netex:GeneralFrame>
+ <netex:GeneralFrame id="CITYWAY:GeneralFrame:NETEX_HORAIRE-20170214090012:LOC" version="any">
+ <netex:TypeOfFrameRef ref="NETEX_HORAIRE"/>
+ <netex:members>
+
+ <netex:ServiceJourney id="CITYWAY:ServiceJourney:1-1:LOC" version="any">
+ <netex:Name>Course 1 par ici aussi</netex:Name>
+ <netex:noticeAssignments>
+ <netex:NoticeAssignment id="ns1" version="any" order="0">
+ <netex:NoticeRef ref="CITYWAY:Notice:2:LOC">
+ version="any"</netex:NoticeRef>
+ </netex:NoticeAssignment>
+ </netex:noticeAssignments>
+ <netex:dayTypes>
+ <netex:DayTypeRef ref="CITYWAY:DayType:1:LOC"> version="any"</netex:DayTypeRef>
+ <netex:DayTypeRef ref="CITYWAY:DayType:4:LOC"> version="any"</netex:DayTypeRef>
+ </netex:dayTypes>
+ <netex:JourneyPatternRef ref="CITYWAY:ServiceJourneyPattern:1:LOC" version="any"/>
+ <netex:OperatorRef ref="STIF:CODIFLIGNE:Operator:212">
+ version="any"</netex:OperatorRef>
+ <netex:trainNumbers>
+ <netex:TrainNumberRef ref="CITYWAY:TrainNumber:1234:LOC">version="any"</netex:TrainNumberRef>
+ </netex:trainNumbers>
+ <netex:passingTimes>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>23:58:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>0</netex:ArrivalDayOffset>
+ <netex:DepartureTime>23:59:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>0</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ <netex:TimetabledPassingTime version="any">
+ <netex:ArrivalTime>00:03:00.000</netex:ArrivalTime>
+ <netex:ArrivalDayOffset>1</netex:ArrivalDayOffset>
+ <netex:DepartureTime>00:04:00.000</netex:DepartureTime>
+ <netex:DepartureDayOffset>1</netex:DepartureDayOffset>
+ </netex:TimetabledPassingTime>
+ </netex:passingTimes>
+ </netex:ServiceJourney>
+
+ </netex:members>
+ </netex:GeneralFrame>
+ </netex:frames>
+ </netex:CompositeFrame>
+ </netex:dataObjects>
+</netex:PublicationDelivery>
diff --git a/spec/helpers/table_builder_helper_spec.rb b/spec/helpers/table_builder_helper_spec.rb
index 3b0a18379..5bddbb16f 100644
--- a/spec/helpers/table_builder_helper_spec.rb
+++ b/spec/helpers/table_builder_helper_spec.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
require 'htmlbeautifier'
module TableBuilderHelper
@@ -5,6 +6,13 @@ module TableBuilderHelper
end
describe TableBuilderHelper, type: :helper do
+ let(:features){ [] }
+ before do
+ allow_any_instance_of(AF83::Decorator::Link).to receive(:check_feature){|f|
+ features.include?(f)
+ }
+ end
+
describe "#table_builder_2" do
it "builds a table" do
referential = build_stubbed(:workbench_referential)
@@ -35,9 +43,8 @@ describe TableBuilderHelper, type: :helper do
id: referentials[0].workbench.id
})
- referentials = ModelDecorator.decorate(
- referentials,
- with: ReferentialDecorator
+ referentials = ReferentialDecorator.decorate(
+ referentials
)
expected = <<-HTML
@@ -54,12 +61,12 @@ describe TableBuilderHelper, type: :helper do
<th><a href="/workbenches/#{workbench.id}?direction=desc&amp;sort=lines">Lignes<span class="orderers"><span class="fa fa-sort-asc active"></span><span class="fa fa-sort-desc "></span></span></a></th>
<th><a href="/workbenches/#{workbench.id}?direction=desc&amp;sort=created_at">Créé le<span class="orderers"><span class="fa fa-sort-asc active"></span><span class="fa fa-sort-desc "></span></span></a></th>
<th><a href="/workbenches/#{workbench.id}?direction=desc&amp;sort=updated_at">Edité le<span class="orderers"><span class="fa fa-sort-asc active"></span><span class="fa fa-sort-desc "></span></span></a></th>
- <th><a href="/workbenches/#{workbench.id}?direction=desc&amp;sort=published_at">Intégré le<span class="orderers"><span class="fa fa-sort-asc active"></span><span class="fa fa-sort-desc "></span></span></a></th>
+ <th><a href="/workbenches/#{workbench.id}?direction=desc&amp;sort=merged_at">Finalisé le<span class="orderers"><span class="fa fa-sort-asc active"></span><span class="fa fa-sort-desc "></span></span></a></th>
<th></th>
</tr>
</thead>
<tbody>
- <tr>
+ <tr class="referential-#{referential.id}">
<td>
<div class="checkbox"><input type="checkbox" name="#{referential.id}" id="#{referential.id}" value="#{referential.id}" /><label for="#{referential.id}"></label></div>
</td>
@@ -76,15 +83,21 @@ describe TableBuilderHelper, type: :helper do
<td class="actions">
<div class="btn-group">
<div class="btn dropdown-toggle" data-toggle="dropdown"><span class="fa fa-cog"></span></div>
- <ul class="dropdown-menu">
- <li><a href="/referentials/#{referential.id}">Consulter</a></li>
- <li><a href="/referentials/#{referential.id}/edit">Editer</a></li>
- <li><a href="/referentials/#{referential.id}/time_tables">Calendriers</a></li>
- <li><a href="/referentials/new?from=#{referential.id}">Dupliquer</a></li>
- <li><a href="/referentials/#{referential.id}/select_compliance_control_set">Valider</a></li>
- <li><a rel="nofollow" data-method="put" href="/referentials/#{referential.id}/archive">Conserver</a></li>
- <li class="delete-action"><a data-confirm="Etes vous sûr de vouloir supprimer ce jeu de données ?" rel="nofollow" data-method="delete" href="/referentials/#{referential.id}"><span class="fa fa-trash mr-xs"></span>Supprimer</a></li>
- </ul>
+ <div class="dropdown-menu">
+ <ul class="primary">
+ <li class=""><a href="/referentials/#{referential.id}">Consulter</a></li>
+ <li class=""><a href="/referentials/#{referential.id}/edit">Editer</a></li>
+ </ul>
+ <ul class="other">
+ <li class=""><a href="/referentials/#{referential.id}/time_tables">Calendriers</a></li>
+ <li class=""><a href="/referentials/new?from=#{referential.id}">Dupliquer</a></li>
+ <li class=""><a href="/referentials/#{referential.id}/select_compliance_control_set">Valider</a></li>
+ <li class=""><a rel="nofollow" data-method="put" href="/referentials/#{referential.id}/archive">Conserver</a></li>
+ </ul>
+ <ul class="footer">
+ <li class=" delete-action"><a data-confirm="Etes vous sûr de vouloir supprimer ce jeu de données ?" rel="nofollow" data-method="delete" href="/referentials/#{referential.id}"><span class="fa fa-trash mr-xs"></span>Supprimer</a></li>
+ </ul>
+ </div>
</div>
</td>
</tr>
@@ -105,7 +118,7 @@ describe TableBuilderHelper, type: :helper do
TableBuilderHelper::Column.new(
key: :status,
attribute: Proc.new do |w|
- if w.archived?
+ if w.referential_read_only?
("<div class='td-block'><span class='fa fa-archive'></span><span>Conservé</span></div>").html_safe
else
("<div class='td-block'><span class='sb sb-lg sb-preparing'></span><span>En préparation</span></div>").html_safe
@@ -143,12 +156,12 @@ describe TableBuilderHelper, type: :helper do
attribute: Proc.new {|w| l(w.updated_at, format: :short)}
),
TableBuilderHelper::Column.new(
- key: :published_at,
+ key: :merged_at,
attribute: ''
)
],
selectable: true,
- links: [:show, :edit],
+ action: :index,
cls: 'table has-filter has-search'
)
@@ -194,9 +207,9 @@ describe TableBuilderHelper, type: :helper do
referential_id: referential.id
})
- companies = ModelDecorator.decorate(
+ companies = CompanyDecorator.decorate(
companies,
- with: CompanyDecorator
+ context: { referential: referential }
)
stub_policy_scope(company)
@@ -213,7 +226,7 @@ describe TableBuilderHelper, type: :helper do
</tr>
</thead>
<tbody>
- <tr>
+ <tr class="company-#{company.id}">
<td>#{company.get_objectid.local_id}</td>
<td title="Voir"><a href="/referentials/#{referential.id}/companies/#{company.id}">#{company.name}</a></td>
<td></td>
@@ -222,9 +235,11 @@ describe TableBuilderHelper, type: :helper do
<td class="actions">
<div class="btn-group">
<div class="btn dropdown-toggle" data-toggle="dropdown"><span class="fa fa-cog"></span></div>
- <ul class="dropdown-menu">
- <li><a href="/referentials/#{referential.id}/companies/#{company.id}">Consulter</a></li>
- </ul>
+ <div class="dropdown-menu">
+ <ul class="primary">
+ <li class=""><a href="/referentials/#{referential.id}/companies/#{company.id}">Consulter</a></li>
+ </ul>
+ </div>
</div>
</td>
</tr>
@@ -306,9 +321,8 @@ describe TableBuilderHelper, type: :helper do
referential_id: referential.id
})
- companies = ModelDecorator.decorate(
+ companies = CompanyDecorator.decorate(
companies,
- with: CompanyDecorator,
context: { referential: line_referential }
)
stub_policy_scope(company)
@@ -326,7 +340,7 @@ describe TableBuilderHelper, type: :helper do
</tr>
</thead>
<tbody>
- <tr>
+ <tr class="company-#{company.id}">
<td>#{company.get_objectid.local_id}</td>
<td title="Voir"><a href="/referentials/#{referential.id}/companies/#{company.id}">#{company.name}</a></td>
<td></td>
@@ -335,9 +349,11 @@ describe TableBuilderHelper, type: :helper do
<td class="actions">
<div class="btn-group">
<div class="btn dropdown-toggle" data-toggle="dropdown"><span class="fa fa-cog"></span></div>
- <ul class="dropdown-menu">
- <li><a href="/referentials/#{referential.id}/companies/#{company.id}">Consulter</a></li>
- </ul>
+ <div class="dropdown-menu">
+ <ul class="primary">
+ <li class=""><a href="/line_referentials/#{line_referential.id}/companies/#{company.id}">Consulter</a></li>
+ </ul>
+ </div>
</div>
</td>
</tr>
@@ -373,7 +389,6 @@ describe TableBuilderHelper, type: :helper do
),
],
sortable: false,
- links: [:show, :edit, :delete],
cls: 'table has-search'
)
@@ -381,5 +396,86 @@ describe TableBuilderHelper, type: :helper do
expect(beautified_html).to eq(expected.chomp)
end
+
+ context "on a single row" do
+ let(:referential){ build_stubbed :referential }
+ let(:other_referential){ build_stubbed :referential }
+ let(:user_context){
+ UserContext.new(
+ build_stubbed(
+ :user,
+ organisation: referential.organisation,
+ permissions: [
+ 'referentials.create',
+ 'referentials.update',
+ 'referentials.destroy',
+ ]
+ ),
+ referential: referential
+ )
+ }
+ let(:columns){
+ [
+ TableBuilderHelper::Column.new(
+ key: :name,
+ attribute: 'name'
+ ),
+ ]
+ }
+ let(:item){ referential.decorate }
+ let(:other_item){ other_referential.decorate }
+ let(:selectable){ false }
+ let(:links){ [:show] }
+ let(:overhead){ [] }
+ let(:model_name){ "referential" }
+ let(:other_tr){ helper.send(:tr, other_item, columns, selectable, links, overhead, model_name) }
+ let(:items){ [item, other_item] }
+
+ before(:each){
+ allow(helper).to receive(:current_user).and_return(user_context)
+ }
+
+ context "with all rows non-selectable" do
+ let(:selectable){ false }
+ it "sets all rows as non selectable" do
+ items.each do |i|
+ tr = helper.send(:tr, i, columns, selectable, links, overhead, model_name, :index)
+ klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{i.id}"
+ selector = "tr.#{klass} [type=checkbox]"
+ expect(tr).to_not have_selector selector
+ end
+ end
+ end
+
+ context "with all rows selectable" do
+ let(:selectable){ true }
+ it "adds a checkbox in all rows" do
+ items.each do |i|
+ tr = helper.send(:tr, i, columns, selectable, links, overhead, model_name, :index)
+ klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{i.id}"
+ selector = "tr.#{klass} [type=checkbox]"
+ expect(tr).to have_selector selector
+ end
+ end
+ end
+
+ context "with THIS row non selectable" do
+ let(:selectable){ ->(i){ i.id != item.id } }
+ it "adds a checkbox in all rows" do
+ items.each do |i|
+ tr = helper.send(:tr, i, columns, selectable, links, overhead, model_name, :index)
+ klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{i.id}"
+ selector = "tr.#{klass} [type=checkbox]"
+ expect(tr).to have_selector selector
+ end
+ end
+ it "disables this rows checkbox" do
+ tr = helper.send(:tr, item, columns, selectable, links, overhead, model_name, :index)
+ klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{item.id}"
+ selector = "tr.#{klass} [type=checkbox][disabled]"
+ expect(tr).to have_selector selector
+ end
+ end
+ end
end
end
diff --git a/spec/javascript/journey_patterns/actions_spec.js b/spec/javascript/journey_patterns/actions_spec.js
index 2542fa2f4..60d6d88bb 100644
--- a/spec/javascript/journey_patterns/actions_spec.js
+++ b/spec/javascript/journey_patterns/actions_spec.js
@@ -112,6 +112,22 @@ describe('when clicking on a journey pattern delete button', () => {
expect(actions.deleteJourneyPattern(index)).toEqual(expectedAction)
})
})
+describe('when changing on a journey pattern costs', () => {
+ it('should create an action to update journey pattern', () => {
+ const index = 1
+ const costs = {
+ "1-2": {
+ distance: 1
+ }
+ }
+ const expectedAction = {
+ type: 'UPDATE_JOURNEYPATTERN_COSTS',
+ index,
+ costs
+ }
+ expect(actions.updateJourneyPatternCosts(index, costs)).toEqual(expectedAction)
+ })
+})
describe('when clicking on validate button inside edit modal', () => {
it('should create an action to save journey pattern modifications', () => {
const index = 1
diff --git a/spec/javascript/journey_patterns/components/JourneyPattern_spec.js b/spec/javascript/journey_patterns/components/JourneyPattern_spec.js
new file mode 100644
index 000000000..0da75ad47
--- /dev/null
+++ b/spec/javascript/journey_patterns/components/JourneyPattern_spec.js
@@ -0,0 +1,63 @@
+import React, { Component } from 'react'
+import JourneyPattern from '../../../../app/javascript/journey_patterns/components/JourneyPattern'
+import renderer from 'react-test-renderer'
+
+describe('the edit button', () => {
+ set('policy', () => {
+ return {}
+ })
+ set('features', () => {
+ return []
+ })
+ set('editMode', () => {
+ return false
+ })
+ set('component', () => {
+ let props = {
+ status: {
+ policy: policy,
+ features: features
+ },
+ onCheckboxChange: ()=>{},
+ onDeleteJourneyPattern: ()=>{},
+ onOpenEditModal: ()=>{},
+ journeyPatterns: {},
+ value: {
+ stop_points: []
+ },
+ index: 0,
+ editMode: editMode
+ }
+ let list = renderer.create(
+ <JourneyPattern
+ status={props.status}
+ journeyPatterns={props.journeyPatterns}
+ value={props.value}
+ index={props.index}
+ onCheckboxChange={props.onCheckboxChange}
+ onDeleteJourneyPattern={props.onDeleteJourneyPattern}
+ onOpenEditModal={props.onOpenEditModal}
+ editMode={props.editMode}
+ />
+ )
+
+ return list
+ })
+
+
+ it('should display the show link', () => {
+ expect(component.toJSON()).toMatchSnapshot()
+ expect(component.root.findByProps({"data-target": "#JourneyPatternModal"})._fiber.stateNode.children[0].text).toEqual("Consulter")
+ })
+
+ context('in edit mode', () => {
+ set('editMode', () => {
+ return true
+ })
+
+ it('should display the edit link', () => {
+ expect(component.toJSON()).toMatchSnapshot()
+ expect(component.root.findByProps({"data-target": "#JourneyPatternModal"})._fiber.stateNode.children[0].text).toEqual("Editer")
+ })
+ })
+})
diff --git a/spec/javascript/journey_patterns/components/JourneyPatterns_spec.js b/spec/javascript/journey_patterns/components/JourneyPatterns_spec.js
new file mode 100644
index 000000000..0c852deff
--- /dev/null
+++ b/spec/javascript/journey_patterns/components/JourneyPatterns_spec.js
@@ -0,0 +1,77 @@
+import React, { Component } from 'react'
+import JourneyPatterns from '../../../../app/javascript/journey_patterns/components/JourneyPatterns'
+import renderer from 'react-test-renderer'
+
+describe('stopPointHeader', () => {
+ set('features', () => {
+ return {}
+ })
+ set('component', () => {
+ let props = {
+ status: {
+ features: features
+ },
+ onCheckboxChange: ()=>{},
+ onLoadFirstPage: ()=>{},
+ onOpenEditModal: ()=>{},
+ stopPointsList: [stop_point, same_city_stop_point, other_country_stop_point],
+ journeyPatterns: []
+ }
+ let list = renderer.create(
+ <JourneyPatterns
+ status={props.status}
+ journeyPatterns={props.journeyPatterns}
+ stopPointsList={props.stopPointsList}
+ onCheckboxChange={props.onCheckboxChange}
+ onLoadFirstPage={props.onLoadFirstPage}
+ onOpenEditModal={props.onOpenEditModal}
+ />
+ ).toJSON()
+
+ return list
+ })
+
+ set('stop_point', () => {
+ return {
+ name: "Stop point",
+ city_name: "City Name",
+ zip_code: "12345",
+ country_code: "FR",
+ country_name: "france",
+ object_id: "sp-FR"
+ }
+ })
+
+ set('same_city_stop_point', () => {
+ return {
+ name: "Antother stop point",
+ city_name: stop_point.city_name,
+ zip_code: stop_point.zip_code,
+ country_code: stop_point.country_code,
+ country_name: stop_point.country_name,
+ object_id: stop_point.object_id + "-2"
+ }
+ })
+
+ set('other_country_stop_point', () => {
+ return {
+ name: "Antother stop point",
+ city_name: "New York",
+ zip_code: "232323",
+ country_code: "US",
+ country_name: "USA",
+ object_id: "sp-USA"
+ }
+ })
+ it('should display the city name', () => {
+ expect(component).toMatchSnapshot()
+ })
+ context('with the "long_distance_routes" feature', () => {
+ set('features', () => {
+ return { long_distance_routes: true }
+ })
+ it('should display the country name', () => {
+ expect(component).toMatchSnapshot()
+ })
+ })
+})
diff --git a/spec/javascript/journey_patterns/components/__snapshots__/JourneyPattern_spec.js.snap b/spec/javascript/journey_patterns/components/__snapshots__/JourneyPattern_spec.js.snap
new file mode 100644
index 000000000..0bedd8d69
--- /dev/null
+++ b/spec/javascript/journey_patterns/components/__snapshots__/JourneyPattern_spec.js.snap
@@ -0,0 +1,143 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`the edit button in edit mode should display the edit link 1`] = `
+<div
+ className="t2e-item to_record"
+>
+ <div
+ className="th"
+ >
+ <div
+ className="strong mb-xs"
+ >
+ -
+ </div>
+ <div />
+ <div>
+ 0
+ arrêt(s)
+ </div>
+ <div
+ className="btn-group"
+ >
+ <div
+ className="btn dropdown-toggle"
+ data-toggle="dropdown"
+ >
+ <span
+ className="fa fa-cog"
+ />
+ </div>
+ <ul
+ className="dropdown-menu"
+ >
+ <li>
+ <button
+ data-target="#JourneyPatternModal"
+ data-toggle="modal"
+ onClick={[Function]}
+ type="button"
+ >
+ Editer
+ </button>
+ </li>
+ <li
+ className="disabled"
+ >
+ <a
+ href="blank/vehicle_journeys?jp=undefined"
+ >
+ Horaires des courses
+ </a>
+ </li>
+ <li
+ className="delete-action disabled"
+ >
+ <button
+ className="disabled"
+ disabled={true}
+ onClick={[Function]}
+ type="button"
+ >
+ <span
+ className="fa fa-trash"
+ />
+ Supprimer
+ </button>
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`the edit button should display the show link 1`] = `
+<div
+ className="t2e-item to_record"
+>
+ <div
+ className="th"
+ >
+ <div
+ className="strong mb-xs"
+ >
+ -
+ </div>
+ <div />
+ <div>
+ 0
+ arrêt(s)
+ </div>
+ <div
+ className="btn-group"
+ >
+ <div
+ className="btn dropdown-toggle"
+ data-toggle="dropdown"
+ >
+ <span
+ className="fa fa-cog"
+ />
+ </div>
+ <ul
+ className="dropdown-menu"
+ >
+ <li>
+ <button
+ data-target="#JourneyPatternModal"
+ data-toggle="modal"
+ onClick={[Function]}
+ type="button"
+ >
+ Consulter
+ </button>
+ </li>
+ <li
+ className="disabled"
+ >
+ <a
+ href="blank/vehicle_journeys?jp=undefined"
+ >
+ Horaires des courses
+ </a>
+ </li>
+ <li
+ className="delete-action disabled"
+ >
+ <button
+ className="disabled"
+ disabled={true}
+ onClick={[Function]}
+ type="button"
+ >
+ <span
+ className="fa fa-trash"
+ />
+ Supprimer
+ </button>
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+`;
diff --git a/spec/javascript/journey_patterns/components/__snapshots__/JourneyPatterns_spec.js.snap b/spec/javascript/journey_patterns/components/__snapshots__/JourneyPatterns_spec.js.snap
new file mode 100644
index 000000000..a332e7d80
--- /dev/null
+++ b/spec/javascript/journey_patterns/components/__snapshots__/JourneyPatterns_spec.js.snap
@@ -0,0 +1,169 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`stopPointHeader should display the city name 1`] = `
+<div
+ className="row"
+>
+ <div
+ className="col-lg-12"
+ >
+ <div
+ className="table table-2entries mt-sm mb-sm no_result"
+ >
+ <div
+ className="t2e-head w20"
+ >
+ <div
+ className="th"
+ >
+ <div
+ className="strong mb-xs"
+ >
+ ID Mission
+ </div>
+ <div>
+ Code mission
+ </div>
+ <div>
+ Nb arrêts
+ </div>
+ </div>
+ <div
+ className="td"
+ >
+ <div
+ className="headlined"
+ data-headline="City Name"
+ title="City Name (12345)"
+ >
+ <span>
+ <span>
+ Stop point
+ </span>
+ </span>
+ </div>
+ </div>
+ <div
+ className="td"
+ >
+ <div
+ className=""
+ data-headline=""
+ title="City Name (12345)"
+ >
+ <span>
+ <span>
+ Antother stop point
+ </span>
+ </span>
+ </div>
+ </div>
+ <div
+ className="td"
+ >
+ <div
+ className="headlined"
+ data-headline="New York"
+ title="New York (232323)"
+ >
+ <span>
+ <span>
+ Antother stop point
+ </span>
+ </span>
+ </div>
+ </div>
+ </div>
+ <div
+ className="t2e-item-list w80"
+ >
+ <div />
+ </div>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`stopPointHeader with the "long_distance_routes" feature should display the country name 1`] = `
+<div
+ className="row"
+>
+ <div
+ className="col-lg-12"
+ >
+ <div
+ className="table table-2entries mt-sm mb-sm no_result"
+ >
+ <div
+ className="t2e-head w20"
+ >
+ <div
+ className="th"
+ >
+ <div
+ className="strong mb-xs"
+ >
+ ID Mission
+ </div>
+ <div>
+ Code mission
+ </div>
+ <div>
+ Nb arrêts
+ </div>
+ </div>
+ <div
+ className="td"
+ >
+ <div
+ className="headlined"
+ data-headline="france"
+ title="City Name (12345)"
+ >
+ <span>
+ <span>
+ Stop point
+ </span>
+ </span>
+ </div>
+ </div>
+ <div
+ className="td"
+ >
+ <div
+ className=""
+ data-headline=""
+ title="City Name (12345)"
+ >
+ <span>
+ <span>
+ Antother stop point
+ </span>
+ </span>
+ </div>
+ </div>
+ <div
+ className="td"
+ >
+ <div
+ className="headlined"
+ data-headline="USA"
+ title="New York (232323)"
+ >
+ <span>
+ <span>
+ Antother stop point
+ </span>
+ </span>
+ </div>
+ </div>
+ </div>
+ <div
+ className="t2e-item-list w80"
+ >
+ <div />
+ </div>
+ </div>
+ </div>
+</div>
+`;
diff --git a/spec/javascript/journey_patterns/reducers/journey_patterns_spec.js b/spec/javascript/journey_patterns/reducers/journey_patterns_spec.js
index 24780ab5a..bfa87d24a 100644
--- a/spec/javascript/journey_patterns/reducers/journey_patterns_spec.js
+++ b/spec/javascript/journey_patterns/reducers/journey_patterns_spec.js
@@ -47,7 +47,10 @@ describe('journeyPatterns reducer', () => {
object_id : 'o1',
published_name: 'M1',
registration_number: '',
- stop_points: fakeStopPoints
+ stop_points: fakeStopPoints,
+ costs: {
+
+ }
},
{
deletable: false,
@@ -55,7 +58,13 @@ describe('journeyPatterns reducer', () => {
object_id : 'o2',
published_name: 'M2',
registration_number: '',
- stop_points: fakeStopPoints
+ stop_points: fakeStopPoints,
+ costs: {
+ "1-2": {
+ distance: 0,
+ time: 10,
+ }
+ }
}
]
})
@@ -83,7 +92,8 @@ describe('journeyPatterns reducer', () => {
published_name: 'M3',
registration_number: '',
deletable: false,
- stop_points: stopPoints
+ stop_points: stopPoints,
+ costs: {}
}, ...state])
})
@@ -100,6 +110,28 @@ describe('journeyPatterns reducer', () => {
).toEqual([newState, state[1]])
})
+ it('should handle UPDATE_JOURNEYPATTERN_COSTS', () => {
+ const costs = {
+ "1-2": {
+ distance: 1
+ }
+ }
+ const new_costs = {
+ "1-2": {
+ distance: 1,
+ time: 10,
+ }
+ }
+ const new_state = Object.assign({}, state[1], {costs: new_costs})
+ expect(
+ jpReducer(state, {
+ type: 'UPDATE_JOURNEYPATTERN_COSTS',
+ index: 1,
+ costs
+ })
+ ).toEqual([state[0], new_state])
+ })
+
it('should handle DELETE_JOURNEYPATTERN', () => {
expect(
jpReducer(state, {
diff --git a/spec/javascript/preprocessor.js b/spec/javascript/preprocessor.js
new file mode 100644
index 000000000..a2de8e4be
--- /dev/null
+++ b/spec/javascript/preprocessor.js
@@ -0,0 +1,15 @@
+'use strict';
+
+var coffee = require('coffeescript');
+
+module.exports = {
+ process: function(src, filename) {
+ if (coffee.helpers.isCoffee(filename)) {
+ return coffee.compile(src, {
+ 'bare': false,
+ 'inlineMap': true
+ })
+ }
+ return src;
+ }
+};
diff --git a/spec/javascript/routes/reducers/stop_points_spec.js b/spec/javascript/routes/reducers/stop_points_spec.js
index b375cdc2c..124618f9d 100644
--- a/spec/javascript/routes/reducers/stop_points_spec.js
+++ b/spec/javascript/routes/reducers/stop_points_spec.js
@@ -1,7 +1,17 @@
import stopPointsReducer from '../../../../app/javascript/routes/reducers/stopPoints'
+import formHelper from '../../../../app/javascript/routes/form_helper'
+import _ from 'lodash'
+
+ // _ _ ___ _ ___ ___ ___ ___
+ // | || | __| | | _ \ __| _ \/ __|
+ // | __ | _|| |__| _/ _|| /\__ \
+ // |_||_|___|____|_| |___|_|_\|___/
+ //
let state = []
+formHelper.addInput = (...args)=>{}
+
let fakeData = {
geometry: undefined,
registration_number: 'rn_test',
@@ -10,34 +20,47 @@ let fakeData = {
user_objectid: 'uoid_test'
}
+let update_stop_point = (stop_point, opts) => {
+ return _.assign({}, stop_point, opts)
+}
+
+let stop_point = (opts) => {
+ return _.assign({},
+ {
+ text: "",
+ index: 0,
+ edit: false,
+ for_boarding: 'normal',
+ for_alighting: 'normal',
+ olMap: { isOpened: false, json: {} }
+ },
+ opts
+ )
+}
+
+let stop_point_1 = stop_point({text: 'first', index: 0, stoppoint_id: 72 })
+let stop_point_2 = stop_point({text: 'second', index: 1, stoppoint_id: 73 })
+let stop_point_3 = stop_point({text: 'third', index: 2, stoppoint_id: 74 })
+
+let it_should_handle = (action, final_state, custom_state=null) => {
+ it("should handle "+ action.type, () => {
+ expect(
+ stopPointsReducer(custom_state || state, action)
+ ).toEqual( final_state )
+ })
+}
+
+
+ // ___ ___ ___ ___ ___
+ // / __| _ \ __/ __/ __|
+ // \__ \ _/ _| (__\__ \
+ // |___/_| |___\___|___/
+ //
+
+
describe('stops reducer', () => {
beforeEach(()=>{
- state = [
- {
- text: 'first',
- index: 0,
- stoppoint_id: 72,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- },
- {
- text: 'second',
- index: 1,
- stoppoint_id: 73,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- }
- ]
+ state = [ stop_point_1, stop_point_2, stop_point_3 ]
})
it('should return the initial state', () => {
@@ -46,441 +69,124 @@ describe('stops reducer', () => {
).toEqual([])
})
- it('should handle ADD_STOP', () => {
- expect(
- stopPointsReducer(state, {
- type: 'ADD_STOP'
- })
- ).toEqual(
- [
- {
- text: 'first',
- index: 0,
- stoppoint_id: 72,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- },
- {
- text: 'second',
- index: 1,
- stoppoint_id: 73,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- },
- {
- text: '',
- index: 2,
- edit: true,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- }
- ]
- )
- })
+ it_should_handle(
+ {type: "ADD_STOP"},
+ [stop_point_1, stop_point_2, stop_point_3, stop_point({index: 3, edit: true})]
+ )
- it('should handle MOVE_UP_STOP', () => {
- expect(
- stopPointsReducer(state, {
- type: 'MOVE_STOP_UP',
- index: 1
- })
- ).toEqual(
- [
- {
- text: 'second',
- index: 1,
- stoppoint_id: 72,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- },
- {
- text: 'first',
- index: 0,
- stoppoint_id: 73,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- }
- ]
- )
- })
+ it_should_handle(
+ {type: 'MOVE_STOP_UP', index: 1},
+ [ update_stop_point(stop_point_2, {index: 0}), update_stop_point(stop_point_1, {index: 1}), stop_point_3 ]
+ )
- it('should handle MOVE_DOWN_STOP', () => {
- expect(
- stopPointsReducer(state, {
- type: 'MOVE_STOP_DOWN',
- index: 0
- })
- ).toEqual(
- [
- {
- text: 'second',
- index: 1,
- stoppoint_id: 72,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- },
- {
- text: 'first',
- index: 0,
- stoppoint_id: 73,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- }
- ]
- )
- })
+ it_should_handle(
+ {type: 'MOVE_STOP_DOWN', index: 0},
+ [ update_stop_point(stop_point_2, {index: 0}), update_stop_point(stop_point_1, {index: 1}), stop_point_3 ]
+ )
- // it('should handle DELETE_STOP', () => {
- // expect(
- // stopPointsReducer(state, {
- // type: 'DELETE_STOP',
- // index: 1
- // })
- // ).toEqual(
- // [
- // {
- // text: 'first',
- // index: 0,
- // stoppoint_id: 72,
- // edit: false,
- // for_boarding: 'normal',
- // for_alighting: 'normal',
- // olMap: {
- // isOpened: false,
- // json: {}
- // }
- // }
- // ]
- // )
- // })
+ it_should_handle(
+ {type: 'DELETE_STOP', index: 1},
+ [stop_point_1, stop_point_3]
+ )
- it('should handle UPDATE_INPUT_VALUE', () => {
- expect(
- stopPointsReducer(state, {
- type: 'UPDATE_INPUT_VALUE',
- index: 0,
- edit: false,
- text: {
- text: "new value",
- name: 'new',
- stoparea_id: 1,
- user_objectid: "1234",
- longitude: 123,
- latitude: 123,
- registration_number: '0',
- city_name: 'city',
- area_type: 'area',
- short_name: 'new',
- comment: 'newcomment'
- }
- })
- ).toEqual(
- [
- {
- text: 'new value',
- name: 'new',
- index: 0,
- stoppoint_id: 72,
- edit: false,
- stoparea_id: 1,
- for_boarding: 'normal',
- for_alighting: 'normal',
- user_objectid: "1234",
- longitude: 123,
- latitude: 123,
- registration_number: '0',
- city_name: 'city',
- area_type: 'area',
- short_name: 'new',
- comment: 'newcomment',
- olMap: {
- isOpened: false,
- json: {}
- }
- },
- {
- text: 'second',
- index: 1,
- stoppoint_id: 73,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- }
- ]
- )
- })
+ let text = {
+ text: "new value",
+ name: 'new',
+ stoparea_id: 1,
+ user_objectid: "1234",
+ longitude: 123,
+ latitude: 123,
+ registration_number: '0',
+ city_name: 'city',
+ area_type: 'area',
+ short_name: 'new',
+ comment: 'newcomment'
+ }
+ it_should_handle(
+ {type: 'UPDATE_INPUT_VALUE', index: 0, text: text},
+ [
+ update_stop_point(stop_point_1, text),
+ stop_point_2,
+ stop_point_3
+ ]
+ )
- it('should handle UPDATE_SELECT_VALUE', () => {
- expect(
- stopPointsReducer(state, {
- type :'UPDATE_SELECT_VALUE',
- select_id: 'for_boarding',
- select_value: 'prohibited',
- index: 0
- })
- ).toEqual(
- [
- {
- text: 'first',
- index: 0,
- stoppoint_id: 72,
- edit: false,
- for_boarding: 'prohibited',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- },
- {
- text: 'second',
- index: 1,
- stoppoint_id: 73,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- }
- ]
- )
- })
+ it_should_handle(
+ {type: 'UPDATE_SELECT_VALUE', index: 0, select_id: 'for_boarding', select_value: 'prohibited'},
+ [
+ update_stop_point(stop_point_1, {for_boarding: 'prohibited'}),
+ stop_point_2,
+ stop_point_3
+ ]
+ )
- it('should handle TOGGLE_MAP', () => {
- expect(
- stopPointsReducer(state, {
- type: 'TOGGLE_MAP',
- index: 0
- })
- ).toEqual(
- [
- {
+ it_should_handle(
+ {type: 'TOGGLE_MAP', index: 0},
+ [
+ update_stop_point(stop_point_1, {olMap: {
+ isOpened: true,
+ json: {
text: 'first',
index: 0,
stoppoint_id: 72,
edit: false,
for_boarding: 'normal',
for_alighting: 'normal',
- olMap: {
- isOpened: true,
- json: {
- text: 'first',
- index: 0,
- stoppoint_id: 72,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: undefined
- }
- }
- },
- {
- text: 'second',
- index: 1,
- stoppoint_id: 73,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
+ olMap: undefined
}
- ]
- )
- })
+ }}),
+ stop_point_2,
+ stop_point_3
+ ]
+ )
- it('should handle TOGGLE_EDIT', () => {
- expect(
- stopPointsReducer(state, {
- type: 'TOGGLE_EDIT',
- index: 0
- })
- ).toEqual(
- [
- {
- text: 'first',
- index: 0,
- stoppoint_id: 72,
- edit: true,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- },
- {
- text: 'second',
- index: 1,
- stoppoint_id: 73,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- }
- ]
- )
- })
+ it_should_handle(
+ {type: 'TOGGLE_EDIT', index: 0},
+ [
+ update_stop_point(stop_point_1, {edit: true}),
+ stop_point_2,
+ stop_point_3
+ ]
+ )
- it('should handle SELECT_MARKER', () => {
- let openedMapState = [
- {
- text: 'first',
- index: 0,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: true,
- json: {}
- }
- },
- {
- text: 'second',
- index: 1,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
+ let openedMapState = [
+ update_stop_point(stop_point_1, {
+ olMap: {
+ isOpened: true,
+ json: {}
}
- ]
- expect(
- stopPointsReducer(openedMapState, {
- type: 'SELECT_MARKER',
- index: 0,
- data: fakeData
- })
- ).toEqual(
- [
- {
- text: 'first',
- index: 0,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: true,
- json: fakeData
- }
- },
- {
- text: 'second',
- index: 1,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- }
- ]
- )
- })
+ }),
+ stop_point_2,
+ stop_point_3
+ ]
- it('should handle UNSELECT_MARKER', () => {
- let openedMapState = [
- {
- text: 'first',
- index: 0,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
+ it_should_handle(
+ {type: 'SELECT_MARKER', index: 0, data: fakeData},
+ [
+ update_stop_point(stop_point_1, {
olMap: {
isOpened: true,
- json: {}
- }
- },
- {
- text: 'second',
- index: 1,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
+ json: fakeData
+ }
+ }),
+ stop_point_2,
+ stop_point_3
+ ],
+ openedMapState
+ )
+
+ it_should_handle(
+ {type: 'UNSELECT_MARKER', index: 0},
+ [
+ update_stop_point(stop_point_1, {
olMap: {
- isOpened: false,
+ isOpened: true,
json: {}
}
- }
- ]
-
- expect(
- stopPointsReducer(openedMapState, {
- type: 'UNSELECT_MARKER',
- index: 0
- })
- ).toEqual(
- [
- {
- text: 'first',
- index: 0,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: true,
- json: {}
- }
- },
- {
- text: 'second',
- index: 1,
- edit: false,
- for_boarding: 'normal',
- for_alighting: 'normal',
- olMap: {
- isOpened: false,
- json: {}
- }
- }
- ]
- )
- })
+ }),
+ stop_point_2,
+ stop_point_3
+ ],
+ openedMapState
+ )
})
diff --git a/spec/javascript/time_table/reducers/timetable_spec.js b/spec/javascript/time_table/reducers/timetable_spec.js
index f0f9eaa8c..926fb2687 100644
--- a/spec/javascript/time_table/reducers/timetable_spec.js
+++ b/spec/javascript/time_table/reducers/timetable_spec.js
@@ -22,8 +22,6 @@ let json = {
time_table_dates: time_table_dates
}
-
-
describe('timetable reducer with empty state', () => {
beforeEach(() => {
state = {
@@ -87,6 +85,7 @@ describe('timetable reducer with filled state', () => {
periode_range: periode_range,
currentPage: current_periode_range
}
+ jsdom.reconfigure({url: "http://example.com/foo/bar"})
expect(
timetableReducer(state, {
type: 'GO_TO_PREVIOUS_PAGE',
diff --git a/spec/javascript/vehicle_journeys/actions_spec.js b/spec/javascript/vehicle_journeys/actions_spec.js
index 74765a7ef..9710d833c 100644
--- a/spec/javascript/vehicle_journeys/actions_spec.js
+++ b/spec/javascript/vehicle_journeys/actions_spec.js
@@ -1,6 +1,7 @@
import actions from '../../../app/javascript/vehicle_journeys/actions/index'
const dispatch = function(){}
+window.fetch = function(){return Promise.resolve()}
const currentPage = 1
describe('when cannot fetch api', () => {
@@ -37,11 +38,53 @@ describe('when clicking on add button', () => {
expect(actions.openCreateModal()).toEqual(expectedAction)
})
})
+describe('when validating the form', () => {
+ it('should check that non-commercial stops have passing time', () => {
+ let state = [{
+ vehicle_journey_at_stops: [{
+ area_kind: "non_commercial",
+ departure_time: {
+ hour: "00",
+ minute: "00"
+ }
+ }]
+ }]
+
+ expect(actions.validate(dispatch, state)).toEqual(true)
+
+ state = [{
+ vehicle_journey_at_stops: [{
+ area_kind: "non_commercial",
+ departure_time: {
+ hour: "00",
+ minute: "01"
+ }
+ }]
+ }]
+
+ expect(actions.validate(dispatch, state)).toEqual(true)
+ })
+
+ it('should not check that commercial stops', () => {
+ let state = [{
+ vehicle_journey_at_stops: [{
+ area_kind: "commercial",
+ departure_time: {
+ hour: "00",
+ minute: "00"
+ }
+ }]
+ }]
+
+ expect(actions.validate(dispatch, state)).toEqual(true)
+ })
+})
describe('when using select2 to pick a journey pattern', () => {
it('should create an action to select a journey pattern inside modal', () => {
let selectedJP = {
id: 1,
object_id: 2,
+ short_id: 2,
name: 'test',
published_name: 'test',
stop_area_short_descriptions: ['test']
@@ -51,6 +94,7 @@ describe('when using select2 to pick a journey pattern', () => {
selectedItem:{
id: selectedJP.id,
objectid: selectedJP.object_id,
+ short_id: selectedJP.object_id,
name: selectedJP.name,
published_name: selectedJP.published_name,
stop_areas: selectedJP.stop_area_short_descriptions
@@ -174,15 +218,55 @@ describe('when clicking on validate button inside shifting modal', () => {
})
})
describe('when clicking on validate button inside editing modal', () => {
- it('should create an action to update a vehiclejourney', () => {
- const data = {}
- const selectedCompany = {}
- const expectedAction = {
- type: 'EDIT_VEHICLEJOURNEY',
- data,
- selectedCompany
- }
- expect(actions.editVehicleJourney(data, selectedCompany)).toEqual(expectedAction)
+ context("with invalid data", () => {
+ it('should not validate the data', () => {
+ const data = {
+ foo: {
+ validity: { valid: false }
+ },
+ bar: {
+ validity: { valid: true }
+ }
+ }
+
+ expect(actions.validateFields(data)).toBeFalsy
+ })
+ })
+
+ context("with data not needing validation", () => {
+ it('should validate the data', () => {
+ const data = {
+ foo: {}
+ }
+
+ expect(actions.validateFields(data)).toBeTruthy
+ })
+ })
+ context("with valid data", () => {
+ it('should validate the data', () => {
+ const data = {
+ foo: {
+ validity: { valid: true }
+ },
+ bar: {
+ validity: { valid: true }
+ }
+ }
+
+ expect(actions.validateFields(data)).toBeTruthy
+ })
+ })
+ context("once the data has been validated", () => {
+ it('should create an action to update a vehiclejourney', () => {
+ const data = {}
+ const selectedCompany = {}
+ const expectedAction = {
+ type: 'EDIT_VEHICLEJOURNEY',
+ data,
+ selectedCompany
+ }
+ expect(actions.editVehicleJourney(data, selectedCompany)).toEqual(expectedAction)
+ })
})
})
describe('when clicking on validate button inside duplicating modal', () => {
@@ -209,6 +293,13 @@ describe('when clicking on edit notes modal', () => {
expect(actions.openNotesEditModal(vehicleJourney)).toEqual(expectedAction)
})
})
+
+ // ___ ___ ___ _____ _ _ ___ _____ ___ ___
+ // | __/ _ \ / _ \_ _| \| |/ _ \_ _| __/ __|
+ // | _| (_) | (_) || | | .` | (_) || | | _|\__ \
+ // |_| \___/ \___/ |_| |_|\_|\___/ |_| |___|___/
+ //
+
describe('when clicking on a footnote button inside footnote modal', () => {
it('should create an action to toggle this footnote', () => {
const footnote = {}, isShown = true
@@ -230,6 +321,13 @@ describe('when clicking on validate button inside footnote modal', () => {
expect(actions.editVehicleJourneyNotes(footnotes)).toEqual(expectedAction)
})
})
+
+ // _____ ___ __ __ ___ _____ _ ___ _ ___ ___
+ // |_ _|_ _| \/ | __|_ _/_\ | _ ) | | __/ __|
+ // | | | || |\/| | _| | |/ _ \| _ \ |__| _|\__ \
+ // |_| |___|_| |_|___| |_/_/ \_\___/____|___|___/
+ //
+
describe('when clicking on calendar button in toolbox', () => {
it('should create an action to open calendar modal', () => {
const vehicleJourneys = []
@@ -288,6 +386,83 @@ describe('when using select2 to pick a timetable', () => {
expect(actions.selectTTCalendarsModal(selectedTT)).toEqual(expectedAction)
})
})
+
+ // ___ _ _ ___ ___ _ _ _ ___ ___
+ // | _ \ | | | _ \/ __| || | /_\ / __| __|
+ // | _/ |_| | / (__| __ |/ _ \\__ \ _|
+ // |_| \___/|_|_\\___|_||_/_/_\_\___/___|__
+ // \ \ / /_ _| \| | \ / _ \ \ / / __|
+ // \ \/\/ / | || .` | |) | (_) \ \/\/ /\__ \
+ // \_/\_/ |___|_|\_|___/ \___/ \_/\_/ |___/
+ //
+
+describe('when clicking on purchase window button in toolbox', () => {
+ it('should create an action to open purchase window modal', () => {
+ const vehicleJourneys = []
+ const expectedAction = {
+ type: 'EDIT_PURCHASE_WINDOWS_VEHICLEJOURNEY_MODAL',
+ vehicleJourneys
+ }
+ expect(actions.openPurchaseWindowsEditModal(vehicleJourneys)).toEqual(expectedAction)
+ })
+})
+describe('when clicking on delete button next to a purchase window inside modal', () => {
+ it('should create an action to delete purchase window from selected vehicle journeys', () => {
+ const purchaseWindow = {}
+ const expectedAction = {
+ type: 'DELETE_PURCHASE_WINDOW_MODAL',
+ purchaseWindow
+ }
+ expect(actions.deletePurchaseWindowsModal(purchaseWindow)).toEqual(expectedAction)
+ })
+})
+describe('when clicking on validate button inside purchase windows modal', () => {
+ it('should create an action to update vj purchase windows', () => {
+ const vehicleJourneys = []
+ const purchase_windows = []
+ const expectedAction = {
+ type: 'EDIT_VEHICLEJOURNEYS_PURCHASE_WINDOWS',
+ vehicleJourneys,
+ purchase_windows
+ }
+ expect(actions.editVehicleJourneyPurchaseWindows(vehicleJourneys, purchase_windows)).toEqual(expectedAction)
+ })
+})
+describe('when clicking on add button inside purchase windows modal', () => {
+ it('should create an action to add the selected purchase window to preselected vjs', () => {
+ const expectedAction = {
+ type: 'ADD_SELECTED_PURCHASE_WINDOW',
+ }
+ expect(actions.addSelectedPurchaseWindow()).toEqual(expectedAction)
+ })
+})
+describe('when using select2 to pick a purchase window', () => {
+ it('should create an action to select a purchase window inside modal', () => {
+ let selectedTT = {
+ id: 1,
+ objectid: 2,
+ name: 'test',
+ color: 'color',
+ }
+ const expectedAction = {
+ type: 'SELECT_PURCHASE_WINDOW_MODAL',
+ selectedItem:{
+ id: selectedTT.id,
+ objectid: selectedTT.objectid,
+ name: selectedTT.name,
+ color: "color"
+ }
+ }
+ expect(actions.selectPurchaseWindowsModal(selectedTT)).toEqual(expectedAction)
+ })
+})
+
+ // ___ ___ _ _____ ___ ___ ___
+ // | __|_ _| ||_ _| __| _ \/ __|
+ // | _| | || |__| | | _|| /\__ \
+ // |_| |___|____|_| |___|_|_\|___/
+ //
+
describe('when clicking on reset button inside query filters', () => {
it('should create an action to reset the query filters', () => {
const expectedAction = {
@@ -447,3 +622,84 @@ describe('when using select2 to unselect a company', () => {
expect(actions.unselect2Company()).toEqual(expectedAction)
})
})
+
+describe('actions.adjustSchedule', () => {
+ set('time', () => {
+ return {
+ hour: 9,
+ minute: 30
+ }
+ })
+ context('when editing the departure time', () => {
+ set('action', () => { return { isDeparture: true } })
+ context('with a positive delta', () => {
+ set('schedule', () => {
+ return {
+ departure_time: time,
+ arrival_time: time
+ }
+ })
+ it('should do nothing', () => {
+ expect(actions.adjustSchedule(action, schedule)).toEqual(schedule)
+ })
+ }),
+ context('with a delta < 0', () => {
+ set('departure_time', () => {
+ return {
+ hour: time.hour,
+ minute: time.minute - 1
+ }
+ })
+ set('schedule', () => {
+ return {
+ departure_time: departure_time,
+ arrival_time: time
+ }
+ })
+ it('should adjust arrival time', () => {
+ let expected = {
+ departure_time: departure_time,
+ arrival_time: departure_time,
+ delta: 0
+ }
+ expect(actions.adjustSchedule(action, schedule)).toEqual(expected)
+ })
+ })
+ }),
+ context('when editing the arrival time', () => {
+ set('action', () => { return { isDeparture: false } })
+ context('with a positive delta', () => {
+ set('schedule', () => {
+ return {
+ departure_time: time,
+ arrival_time: time
+ }
+ })
+ it('should do nothing', () => {
+ expect(actions.adjustSchedule(action, schedule)).toEqual(schedule)
+ })
+ }),
+ context('with a delta < 0', () => {
+ set('arrival_time', () => {
+ return {
+ hour: time.hour,
+ minute: time.minute + 1
+ }
+ })
+ set('schedule', () => {
+ return {
+ departure_time: time,
+ arrival_time: arrival_time
+ }
+ })
+ it('should adjust departure time', () => {
+ let expected = {
+ departure_time: arrival_time,
+ arrival_time: arrival_time,
+ delta: 0
+ }
+ expect(actions.adjustSchedule(action, schedule)).toEqual(expected)
+ })
+ })
+ })
+})
diff --git a/spec/javascript/vehicle_journeys/components/CustomFieldsInputs_spec.js b/spec/javascript/vehicle_journeys/components/CustomFieldsInputs_spec.js
new file mode 100644
index 000000000..4f8d42d2d
--- /dev/null
+++ b/spec/javascript/vehicle_journeys/components/CustomFieldsInputs_spec.js
@@ -0,0 +1,41 @@
+import React, { Component } from 'react'
+import CustomFieldsInputs from '../../../../app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs'
+import renderer from 'react-test-renderer'
+require('select2')
+
+describe('CustomFieldsInputs', () => {
+ set('values', () => {
+ return {}
+ })
+
+ set('component', () => {
+ let inputs = renderer.create(
+ <CustomFieldsInputs
+ values={values}
+ disabled={false}
+ onUpdate={()=>{}}
+ />
+ ).toJSON()
+
+ return inputs
+ })
+
+ it('should match the snapshot', () => {
+ expect(component).toMatchSnapshot()
+ })
+
+ // context('with fields', () => {
+ // set('values', () => {
+ // return {
+ // foo: {
+ // options: { list_values: ["", "1", "2"] },
+ // field_type: "list",
+ // name: "test"
+ // }
+ // }
+ // })
+ // it('should match the snapshot', () => {
+ // expect(component).toMatchSnapshot()
+ // })
+ // })
+})
diff --git a/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js b/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js
new file mode 100644
index 000000000..2a84cb9ca
--- /dev/null
+++ b/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js
@@ -0,0 +1,87 @@
+import React, { Component } from 'react'
+import VehicleJourneys from '../../../../app/javascript/vehicle_journeys/components/VehicleJourneys'
+import renderer from 'react-test-renderer'
+import fs from 'fs'
+
+import I18n from '../../../../public/javascripts/i18n'
+import decorateI18n from '../../../../app/assets/javascripts/i18n/extended.coffee'
+window.I18n = decorateI18n(I18n)
+I18n.locale = "fr"
+eval(fs.readFileSync('./public/javascripts/translations.js')+'')
+
+describe('stopPointHeader', () => {
+ set('features', () => {
+ return {}
+ })
+ set('component', () => {
+ let props = {
+ status: {},
+ filters: {
+ permissions: {},
+ features: features
+ },
+ onLoadFirstPage: ()=>{},
+ onUpdateTime: ()=>{},
+ onSelectVehicleJourney: ()=>{},
+ stopPointsList: [stop_point, same_city_stop_point, other_country_stop_point],
+ vehicleJourneys: []
+ }
+ let list = renderer.create(
+ <VehicleJourneys
+ status={props.status}
+ filters={props.filters}
+ onLoadFirstPage={props.onLoadFirstPage}
+ onUpdateTime={props.onUpdateTime}
+ onSelectVehicleJourney={props.onSelectVehicleJourney}
+ stopPointsList={props.stopPointsList}
+ vehicleJourneys={props.vehicleJourneys}
+ />
+ ).toJSON()
+
+ return list
+ })
+
+ set('stop_point', () => {
+ return {
+ name: "Stop point",
+ city_name: "City Name",
+ zip_code: "12345",
+ country_code: "FR",
+ country_name: "france",
+ object_id: "sp-FR"
+ }
+ })
+
+ set('same_city_stop_point', () => {
+ return {
+ name: "Antother stop point",
+ city_name: stop_point.city_name,
+ zip_code: stop_point.zip_code,
+ country_code: stop_point.country_code,
+ country_name: stop_point.country_name,
+ object_id: stop_point.object_id + "-2"
+ }
+ })
+
+ set('other_country_stop_point', () => {
+ return {
+ name: "Antother stop point",
+ city_name: "New York",
+ zip_code: "232323",
+ country_code: "US",
+ country_name: "USA",
+ object_id: "sp-USA"
+ }
+ })
+ it('should display the city name', () => {
+ expect(component).toMatchSnapshot()
+ })
+ context('with the "long_distance_routes" feature', () => {
+ set('features', () => {
+ return { long_distance_routes: true }
+ })
+ it('should display the country name', () => {
+ expect(component).toMatchSnapshot()
+ })
+ })
+})
diff --git a/spec/javascript/vehicle_journeys/components/__snapshots__/CustomFieldsInputs_spec.js.snap b/spec/javascript/vehicle_journeys/components/__snapshots__/CustomFieldsInputs_spec.js.snap
new file mode 100644
index 000000000..c93ec0097
--- /dev/null
+++ b/spec/javascript/vehicle_journeys/components/__snapshots__/CustomFieldsInputs_spec.js.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`CustomFieldsInputs should match the snapshot 1`] = `<div />`;
diff --git a/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap b/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap
new file mode 100644
index 000000000..cdd34cbbd
--- /dev/null
+++ b/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap
@@ -0,0 +1,181 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`stopPointHeader should display the city name 1`] = `
+<div
+ className="row"
+>
+ <div
+ className="col-lg-12"
+ >
+ <div
+ className="table table-2entries mt-sm mb-sm no_result"
+ >
+ <div
+ className="t2e-head w20"
+ >
+ <div
+ className="th"
+ >
+ <div
+ className="strong mb-xs"
+ >
+ ID Course
+ </div>
+ <div>
+ Nom Course
+ </div>
+ <div>
+ ID Mission
+ </div>
+ <div>
+ transporteur
+ </div>
+ <div>
+ calendrier
+ </div>
+ </div>
+ <div
+ className="td"
+ >
+ <div
+ className="headlined"
+ data-headline="City Name"
+ title="City Name (12345)"
+ >
+ <span>
+ <span>
+ Stop point
+ </span>
+ </span>
+ </div>
+ </div>
+ <div
+ className="td"
+ >
+ <div
+ className=""
+ data-headline=""
+ title="City Name (12345)"
+ >
+ <span>
+ <span>
+ Antother stop point
+ </span>
+ </span>
+ </div>
+ </div>
+ <div
+ className="td"
+ >
+ <div
+ className="headlined"
+ data-headline="New York"
+ title="New York (232323)"
+ >
+ <span>
+ <span>
+ Antother stop point
+ </span>
+ </span>
+ </div>
+ </div>
+ </div>
+ <div
+ className="t2e-item-list w80"
+ >
+ <div />
+ </div>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`stopPointHeader with the "long_distance_routes" feature should display the country name 1`] = `
+<div
+ className="row"
+>
+ <div
+ className="col-lg-12"
+ >
+ <div
+ className="table table-2entries mt-sm mb-sm no_result"
+ >
+ <div
+ className="t2e-head w20"
+ >
+ <div
+ className="th"
+ >
+ <div
+ className="strong mb-xs"
+ >
+ ID Course
+ </div>
+ <div>
+ Nom Course
+ </div>
+ <div>
+ ID Mission
+ </div>
+ <div>
+ transporteur
+ </div>
+ <div>
+ calendrier
+ </div>
+ </div>
+ <div
+ className="td"
+ >
+ <div
+ className="headlined"
+ data-headline="france"
+ title="City Name (12345)"
+ >
+ <span>
+ <span>
+ Stop point
+ </span>
+ </span>
+ </div>
+ </div>
+ <div
+ className="td"
+ >
+ <div
+ className=""
+ data-headline=""
+ title="City Name (12345)"
+ >
+ <span>
+ <span>
+ Antother stop point
+ </span>
+ </span>
+ </div>
+ </div>
+ <div
+ className="td"
+ >
+ <div
+ className="headlined"
+ data-headline="USA"
+ title="New York (232323)"
+ >
+ <span>
+ <span>
+ Antother stop point
+ </span>
+ </span>
+ </div>
+ </div>
+ </div>
+ <div
+ className="t2e-item-list w80"
+ >
+ <div />
+ </div>
+ </div>
+ </div>
+</div>
+`;
diff --git a/spec/javascript/vehicle_journeys/reducers/modal_spec.js b/spec/javascript/vehicle_journeys/reducers/modal_spec.js
index 69de9168b..ee50f091b 100644
--- a/spec/javascript/vehicle_journeys/reducers/modal_spec.js
+++ b/spec/javascript/vehicle_journeys/reducers/modal_spec.js
@@ -91,6 +91,12 @@ describe('modal reducer', () => {
).toEqual(newState)
})
+ // _____ ___ __ __ ___ _____ _ ___ _ ___ ___
+ // |_ _|_ _| \/ | __|_ _/_\ | _ ) | | __/ __|
+ // | | | || |\/| | _| | |/ _ \| _ \ |__| _|\__ \
+ // |_| |___|_| |_|___| |_/_/ \_\___/____|___|___/
+ //
+
it('should handle EDIT_CALENDARS_VEHICLEJOURNEY_MODAL', () => {
let vehicleJourneys = []
let modalPropsResult = {
@@ -158,14 +164,89 @@ describe('modal reducer', () => {
).toEqual(newState)
})
+ // ___ _ _ ___ ___ _ _ _ ___ ___
+ // | _ \ | | | _ \/ __| || | /_\ / __| __|
+ // | _/ |_| | / (__| __ |/ _ \\__ \ _|
+ // |_| \___/|_|_\\___|_||_/_/_\_\___/___|__
+ // \ \ / /_ _| \| | \ / _ \ \ / / __|
+ // \ \/\/ / | || .` | |) | (_) \ \/\/ /\__ \
+ // \_/\_/ |___|_|\_|___/ \___/ \_/\_/ |___/
+ //
+
+ it('should handle EDIT_PURCHASE_WINDOWS_VEHICLEJOURNEY_MODAL', () => {
+ let vehicleJourneys = []
+ let modalPropsResult = {
+ vehicleJourneys: [],
+ purchase_windows: []
+ }
+ expect(
+ modalReducer(state, {
+ type: 'EDIT_PURCHASE_WINDOWS_VEHICLEJOURNEY_MODAL',
+ vehicleJourneys
+ })
+ ).toEqual(Object.assign({}, state, {type: 'purchase_windows_edit', modalProps: modalPropsResult}))
+ })
+
+ it('should handle SELECT_PURCHASE_WINDOW_MODAL', () => {
+ let newModalProps = {selectedPurchaseWindow : {id: 1}}
+ expect(
+ modalReducer(state, {
+ type: 'SELECT_PURCHASE_WINDOW_MODAL',
+ selectedItem: {id: 1}
+ })
+ ).toEqual(Object.assign({}, state, {modalProps: newModalProps}))
+ })
+
+ it('should handle ADD_SELECTED_PURCHASE_WINDOW', () => {
+ let fakeWindows = [{'test': 'test'}, {'test 2': 'test 2'}]
+ let newWindows = [{'test': 'test'}, {'test 2': 'test 2'}, {'add': 'add'}]
+ let fakeVehicleJourneys= [{purchase_windows: fakeWindows}, {purchase_windows: newWindows}]
+ state.modalProps.vehicleJourneys = fakeVehicleJourneys
+ state.modalProps.purchase_windows = fakeWindows
+ state.modalProps.selectedPurchaseWindow = {'add': 'add'}
+ let newState = {
+ type: '',
+ modalProps:{
+ vehicleJourneys: fakeVehicleJourneys,
+ purchase_windows: [{'test': 'test'},{'test 2': 'test 2'},{'add': 'add'}],
+ selectedPurchaseWindow: {'add': 'add'}
+ },
+ confirmModal: {}
+ }
+ expect(
+ modalReducer(state, {
+ type: 'ADD_SELECTED_PURCHASE_WINDOW',
+ })
+ ).toEqual(newState)
+ })
+
+ it('should handle DELETE_PURCHASE_WINDOW_MODAL', () => {
+ let deletableWindow = {'delete': 'delete'}
+ let fakeWindows = [{'test': 'test'}, {'test 2': 'test 2'}, deletableWindow]
+ let newWindows = [{'test': 'test'}, {'test 2': 'test 2'}]
+ let fakeVehicleJourneys= [{purchase_windows: fakeWindows}, {purchase_windows: newWindows}]
+ state.modalProps = Object.assign({}, state.modalProps,{vehicleJourneys : fakeVehicleJourneys, purchase_windows: fakeWindows })
+ let newState = {
+ // for the sake of the test, no need to specify the type
+ type: '',
+ modalProps:{vehicleJourneys: [{purchase_windows: newWindows},{purchase_windows: newWindows}], purchase_windows: newWindows},
+ confirmModal: {}
+ }
+ expect(
+ modalReducer(state, {
+ type: 'DELETE_PURCHASE_WINDOW_MODAL',
+ purchaseWindow: deletableWindow
+ })
+ ).toEqual(newState)
+ })
+
it('should handle SELECT_CP_EDIT_MODAL', () => {
- let newModalProps = {selectedCompany : {name: 'ALBATRANS'}}
expect(
modalReducer(state, {
type: 'SELECT_CP_EDIT_MODAL',
selectedItem: {name: 'ALBATRANS'}
- })
- ).toEqual(Object.assign({}, state, {modalProps: newModalProps}))
+ }).modalProps.vehicleJourney.company
+ ).toEqual({name: 'ALBATRANS'})
})
it('should handle UNSELECT_CP_EDIT_MODAL', () => {
@@ -173,7 +254,7 @@ describe('modal reducer', () => {
expect(
modalReducer(state, {
type: 'UNSELECT_CP_EDIT_MODAL'
- })
- ).toEqual(Object.assign({}, state, {modalProps: newModalProps}))
+ }).modalProps.vehicleJourney.company
+ ).toBe(undefined)
})
})
diff --git a/spec/javascript/vehicle_journeys/reducers/vehicle_journeys_spec.js b/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js
index 1c2cc1577..0d7612a80 100644
--- a/spec/javascript/vehicle_journeys/reducers/vehicle_journeys_spec.js
+++ b/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js
@@ -76,12 +76,12 @@ describe('vehicleJourneys reducer', () => {
let pristineVjasList = [{
delta : 0,
arrival_time : {
- hour: '00',
- minute: '00'
+ hour: "00",
+ minute: "00"
},
departure_time : {
- hour: '00',
- minute: '00'
+ hour: "00",
+ minute: "00"
},
stop_point_objectid: 'test',
stop_area_cityname: 'city',
@@ -89,7 +89,12 @@ describe('vehicleJourneys reducer', () => {
}]
let fakeData = {
published_journey_name: {value: 'test'},
- published_journey_identifier: {value : ''}
+ published_journey_identifier: {value : ''},
+ custom_fields: {
+ foo: {
+ value: 12
+ }
+ }
}
let fakeSelectedJourneyPattern = {id: "1"}
let fakeSelectedCompany = {name: "ALBATRANS"}
@@ -110,10 +115,205 @@ describe('vehicleJourneys reducer', () => {
objectid: '',
footnotes: [],
time_tables: [],
+ purchase_windows: [],
vehicle_journey_at_stops: pristineVjasList,
selected: false,
deletable: false,
transport_mode: 'undefined',
+ transport_submode: 'undefined',
+ custom_fields: {
+ foo: {
+ value: 12
+ }
+ }
+ }, ...state])
+ })
+
+ it('should handle ADD_VEHICLEJOURNEY with a start time and a fully timed JP', () => {
+ let pristineVjasList = [{
+ delta : 0,
+ arrival_time : {
+ hour: 22,
+ minute: 59
+ },
+ departure_time : {
+ hour: 22,
+ minute: 59
+ },
+ stop_point_objectid: 'test-1',
+ stop_area_cityname: 'city',
+ dummy: false
+ },
+ {
+ delta : 0,
+ arrival_time : {
+ hour: 23,
+ minute: 2
+ },
+ departure_time : {
+ hour: 23,
+ minute: 2
+ },
+ departure_day_offset: -1,
+ arrival_day_offset: -1,
+ stop_point_objectid: 'test-2',
+ stop_area_cityname: 'city',
+ dummy: false
+ },
+ {
+ delta : 0,
+ arrival_time : {
+ hour: "00",
+ minute: "00"
+ },
+ departure_time : {
+ hour: "00",
+ minute: "00"
+ },
+ stop_point_objectid: 'test-3',
+ stop_area_cityname: 'city',
+ dummy: true
+ },
+ {
+ delta : 0,
+ arrival_time : {
+ hour: 0,
+ minute: 32
+ },
+ departure_time : {
+ hour: 0,
+ minute: 32
+ },
+ stop_point_objectid: 'test-4',
+ stop_area_cityname: 'city',
+ dummy: false
+ }]
+ let fakeData = {
+ published_journey_name: {value: 'test'},
+ published_journey_identifier: {value : ''},
+ "start_time.hour": {value : '22'},
+ "start_time.minute": {value : '59'}
+ }
+ let fakeSelectedJourneyPattern = {
+ id: "1",
+ full_schedule: true,
+ stop_areas: [
+ {stop_area_short_description: {id: 1}},
+ {stop_area_short_description: {id: 2}},
+ {stop_area_short_description: {id: 4}},
+ ],
+ costs: {
+ "1-2": {
+ distance: 10,
+ time: 63
+ },
+ "2-4": {
+ distance: 10,
+ time: 30
+ }
+ }
+ }
+ let fakeSelectedCompany = {name: "ALBATRANS"}
+ expect(
+ vjReducer(state, {
+ type: 'ADD_VEHICLEJOURNEY',
+ data: fakeData,
+ selectedJourneyPattern: fakeSelectedJourneyPattern,
+ stopPointsList: [{object_id: 'test-1', city_name: 'city', stop_area_id: 1, id: 1, time_zone_offset: 0}, {object_id: 'test-2', city_name: 'city', stop_area_id: 2, id: 2, time_zone_offset: -3600}, {object_id: 'test-3', city_name: 'city', stop_area_id: 3, id: 3, time_zone_offset: 0}, {object_id: 'test-4', city_name: 'city', stop_area_id: 4, id: 4, time_zone_offset: 0}],
+ selectedCompany: fakeSelectedCompany
+ })
+ ).toEqual([{
+ journey_pattern: fakeSelectedJourneyPattern,
+ company: fakeSelectedCompany,
+ published_journey_name: 'test',
+ published_journey_identifier: '',
+ short_id: '',
+ objectid: '',
+ footnotes: [],
+ time_tables: [],
+ purchase_windows: [],
+ vehicle_journey_at_stops: pristineVjasList,
+ selected: false,
+ custom_fields: undefined,
+ deletable: false,
+ transport_mode: 'undefined',
+ transport_submode: 'undefined'
+ }, ...state])
+ })
+
+ it('should handle ADD_VEHICLEJOURNEY with a start time and a fully timed JP but the minutes are not set', () => {
+ let pristineVjasList = [{
+ delta : 0,
+ arrival_time : {
+ hour: 22,
+ minute: 0
+ },
+ departure_time : {
+ hour: 22,
+ minute: 0
+ },
+ stop_point_objectid: 'test-1',
+ stop_area_cityname: 'city',
+ dummy: false
+ },
+ {
+ delta : 0,
+ arrival_time : {
+ hour: 22,
+ minute: 3
+ },
+ departure_time : {
+ hour: 22,
+ minute: 3
+ },
+ stop_point_objectid: 'test-2',
+ stop_area_cityname: 'city',
+ dummy: false
+ }]
+ let fakeData = {
+ published_journey_name: {value: 'test'},
+ published_journey_identifier: {value : ''},
+ "start_time.hour": {value : '22'},
+ "start_time.minute": {value : ''}
+ }
+ let fakeSelectedJourneyPattern = {
+ id: "1",
+ full_schedule: true,
+ stop_areas: [
+ {stop_area_short_description: {id: 1}},
+ {stop_area_short_description: {id: 2}},
+ ],
+ costs: {
+ "1-2": {
+ distance: 10,
+ time: 63
+ },
+ }
+ }
+ let fakeSelectedCompany = {name: "ALBATRANS"}
+ expect(
+ vjReducer(state, {
+ type: 'ADD_VEHICLEJOURNEY',
+ data: fakeData,
+ selectedJourneyPattern: fakeSelectedJourneyPattern,
+ stopPointsList: [{object_id: 'test-1', city_name: 'city', stop_area_id: 1, id: 1, time_zone_offset: 0}, {object_id: 'test-2', city_name: 'city', stop_area_id: 2, id: 2, time_zone_offset: -3600}],
+ selectedCompany: fakeSelectedCompany
+ })
+ ).toEqual([{
+ journey_pattern: fakeSelectedJourneyPattern,
+ company: fakeSelectedCompany,
+ published_journey_name: 'test',
+ published_journey_identifier: '',
+ short_id: '',
+ objectid: '',
+ footnotes: [],
+ time_tables: [],
+ purchase_windows: [],
+ vehicle_journey_at_stops: pristineVjasList,
+ selected: false,
+ custom_fields: undefined,
+ deletable: false,
+ transport_mode: 'undefined',
transport_submode: 'undefined'
}, ...state])
})
@@ -240,12 +440,18 @@ describe('vehicleJourneys reducer', () => {
})
it('should handle EDIT_VEHICLEJOURNEY', () => {
+ let custom_fields = {
+ foo: {
+ value: 12
+ }
+ }
let fakeData = {
published_journey_name: {value : 'test'},
- published_journey_identifier: {value: 'test'}
+ published_journey_identifier: {value: 'test'},
+ custom_fields: {foo: {value: 12}}
}
let fakeSelectedCompany : {name : 'ALBATRANS'}
- let newVJ = Object.assign({}, state[0], {company: fakeSelectedCompany, published_journey_name: fakeData.published_journey_name.value, published_journey_identifier: fakeData.published_journey_identifier.value})
+ let newVJ = Object.assign({}, state[0], {company: fakeSelectedCompany, published_journey_name: fakeData.published_journey_name.value, published_journey_identifier: fakeData.published_journey_identifier.value, custom_fields})
expect(
vjReducer(state, {
type: 'EDIT_VEHICLEJOURNEY',
@@ -254,7 +460,6 @@ describe('vehicleJourneys reducer', () => {
).toEqual([newVJ, state[1]])
})
-
it('should handle EDIT_VEHICLEJOURNEYS_TIMETABLES', () => {
let newState = JSON.parse(JSON.stringify(state))
newState[0].time_tables = [fakeTimeTables[0]]
@@ -266,4 +471,16 @@ describe('vehicleJourneys reducer', () => {
})
).toEqual(newState)
})
+
+ it('should handle EDIT_VEHICLEJOURNEYS_PURCHASE_WINDOWS', () => {
+ let newState = JSON.parse(JSON.stringify(state))
+ newState[0].purchase_windows = [fakeTimeTables[0]]
+ expect(
+ vjReducer(state, {
+ type: 'EDIT_VEHICLEJOURNEYS_PURCHASE_WINDOWS',
+ vehicleJourneys: state,
+ purchase_windows: [fakeTimeTables[0]]
+ })
+ ).toEqual(newState)
+ })
})
diff --git a/spec/lib/af83/decorator/decorator_link_spec.rb b/spec/lib/af83/decorator/decorator_link_spec.rb
new file mode 100644
index 000000000..0b2939421
--- /dev/null
+++ b/spec/lib/af83/decorator/decorator_link_spec.rb
@@ -0,0 +1,79 @@
+RSpec.describe AF83::Decorator::Link, type: :decorator do
+ describe "#complete?" do
+ context "on a imcomplete link" do
+ it "should be false" do
+ expect(AF83::Decorator::Link.new.complete?).to be_falsy
+ expect(AF83::Decorator::Link.new(content: "foo").complete?).to be_falsy
+ expect(AF83::Decorator::Link.new(href: "foo").complete?).to be_falsy
+ end
+ end
+
+ context "on a complete link" do
+ it "should be true" do
+ expect(AF83::Decorator::Link.new(href: "foo", content: "foo").complete?).to be_truthy
+ end
+ end
+ end
+
+ describe "#class" do
+ let(:link){
+ AF83::Decorator::Link.new(href: "foo", content: "foo", class: "initial_class")
+ }
+
+ it "should override exisiting class" do
+ expect(link.html_options[:class]).to eq "initial_class"
+ link.class "new_class"
+ expect(link.html_options[:class]).to eq "new_class"
+ link.class = "another_class"
+ expect(link.html_options[:class]).to eq "another_class"
+ link.class = %w(foo bar)
+ expect(link.html_options[:class]).to eq "foo bar"
+ end
+ end
+
+ describe "#add_class" do
+ let(:link){
+ AF83::Decorator::Link.new(href: "foo", content: "foo", class: "initial_class")
+ }
+
+ it "should add to exisiting class" do
+ expect(link.html_options[:class]).to eq "initial_class"
+ link.add_class "new_class"
+ expect(link.html_options[:class]).to eq "initial_class new_class"
+ link.add_class "another_class"
+ expect(link.html_options[:class]).to eq "initial_class new_class another_class"
+ link.add_class %w(foo bar)
+ expect(link.html_options[:class]).to eq "initial_class new_class another_class foo bar"
+ end
+ end
+
+ describe "#type" do
+
+ let(:link){
+ AF83::Decorator::Link.new(href: "foo", content: "foo")
+ }
+
+ let(:context){
+ Class.new do
+ def h
+ Class.new do
+ def link_to *args
+ HTMLElement.new(:a, 'foo', {}).to_html
+ end
+ end.new
+ end
+ end.new
+ }
+
+ it "should allow for buttons" do
+ link.type = :button
+ expect(link.to_html).to match /\<button.*\<\/button\>/
+ end
+
+ it "should fallback to <a>" do
+ link.type = :spaghetti
+ link.bind_to_context context, :show
+ expect(link.to_html).to match /\<a.*\<\/a\>/
+ end
+ end
+end
diff --git a/spec/lib/af83/decorator/decorator_spec.rb b/spec/lib/af83/decorator/decorator_spec.rb
new file mode 100644
index 000000000..61a849b9d
--- /dev/null
+++ b/spec/lib/af83/decorator/decorator_spec.rb
@@ -0,0 +1,824 @@
+RSpec.describe AF83::Decorator, type: :decorator do
+ describe(:parse_options) do
+ let(:options){
+ {primary: true, secondary: %i(index show), policy: :blublu, weight: 12}
+ }
+ let(:link_options){
+ {foo: :foo, bar: :bar}
+ }
+ let(:args){ options.dup.update(link_options.dup) }
+ it "should separate options from link_options" do
+ _options, _link_options = AF83::Decorator.instance_decorator.send :parse_options, args
+ expect(_options).to eq({weight: 12})
+ link_options.each do |k, v|
+ expect(_link_options[k]).to eq v
+ end
+ expect(_link_options[:_groups][:primary]).to eq true
+ expect(_link_options[:_groups][:secondary]).to eq %i(index show)
+ expect(_link_options[:_policy]).to eq :blublu
+ end
+ end
+
+ link_should_match_options = ->(link, options){
+ options.each do |k, v|
+ expect(link.send(k)).to eq v
+ end
+ }
+
+ context "as an collection decorator" do
+ let(:link_options) do
+ {
+ href: "/foo/bar",
+ content: "Blublu"
+ }
+ end
+
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.action_link link_options
+ klass
+ end
+
+ let(:decorated) do
+ 3.times { create :line }
+ decorator.decorate(Chouette::Line.all)
+ end
+
+ it "should return the links" do
+ links = decorated.action_links
+ instance_exec links.first, link_options, &link_should_match_options
+ end
+ end
+
+ context "as an instance decorator" do
+ describe("with the actual decorator") do
+ before(:each) do
+ Draper::HelperProxy.any_instance.stub(:policy){
+ klass = Class.new do
+ def method_missing *args
+ true
+ end
+ end.new
+ }
+ end
+
+ let(:decorated) do
+ line = create :line
+ line.decorate(context: {line_referential: line.line_referential})
+ end
+
+ it "should return the links" do
+ expect{ decorated.action_links }.to_not raise_error
+ end
+ end
+
+ describe(:action_links) do
+ let(:decorated) do
+ obj = create :line
+ decorator.decorate(obj)
+ end
+
+ context "without links" do
+ let(:decorator) do
+ Class.new(AF83::Decorator)
+ end
+
+ it "should return no link" do
+ links = decorated.action_links
+ expect(links.size).to eq 0
+ end
+ end
+
+ context "with a single link" do
+ let(:link_options) do
+ {
+ href: "/foo/bar",
+ content: "Blublu"
+ }
+ end
+
+ context "incompletetly defined" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link href: "bar"
+ end
+ klass
+ end
+
+ it "should raise an error" do
+ expect{decorator}.to raise_error(AF83::Decorator::IncompleteLinkDefinition)
+ end
+ end
+
+ context "defined inline" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options
+ end
+ klass
+ end
+
+ it "should return the defined link" do
+ links = decorated.action_links
+ expect(links.size).to eq 1
+ instance_exec links.first, link_options, &link_should_match_options
+ end
+ end
+
+ context "defined in a block" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link do |l|
+ l.href link_options[:href]
+ l.content link_options[:content]
+ end
+ end
+ klass
+ end
+
+ it "should return the defined link" do
+ links = decorated.action_links
+ expect(links.size).to eq 1
+ instance_exec links.first, link_options, &link_should_match_options
+ end
+ end
+
+ context "with proc attributes" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link do |l|
+ l.href { context[:href] }
+ l.content "Blublu"
+ end
+ end
+ klass
+ end
+
+ let(:decorated) do
+ obj = create :line
+ decorator.decorate(obj, context: {href: link_options[:href]})
+ end
+
+ it "should return the defined link" do
+ links = decorated.action_links
+ expect(links.size).to eq 1
+ expect(links.first.href).to eq link_options[:href]
+ end
+ end
+
+ context "with a method attributes" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link do |l|
+ l.href "/foo/bar"
+ l.content "Blublu"
+ l.method :put
+ end
+ end
+ klass
+ end
+
+ let(:decorated) do
+ obj = create :line
+ decorator.decorate(obj, context: {href: link_options[:href]})
+ end
+
+ it "should return the defined method" do
+ links = decorated.action_links
+ expect(links.size).to eq 1
+ expect(links.first.method).to eq :put
+ end
+ end
+ end
+
+ context "with 2 links" do
+ let(:link_options_1) do
+ {
+ href: "/foo/bar",
+ content: "Blublu"
+ }
+ end
+
+ let(:link_options_2) do
+ {
+ href: "/foo/bar/baz",
+ content: "Foo"
+ }
+ end
+
+ context "without weight" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options_1
+ instance_decorator.action_link link_options_2
+ end
+ klass
+ end
+
+ it "should return links in the sequence they were defined" do
+ links = decorated.action_links
+ expect(links.size).to eq 2
+ instance_exec links.first, link_options_1, &link_should_match_options
+ instance_exec links.last, link_options_2, &link_should_match_options
+ end
+ end
+
+ context "with weight" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options_1.update(weight: 10)
+ instance_decorator.action_link link_options_2
+ end
+ klass
+ end
+
+ it "should return links in the correct sequence" do
+ links = decorated.action_links
+ expect(links.size).to eq 2
+ instance_exec links.first, link_options_2, &link_should_match_options
+ instance_exec links.last, link_options_1, &link_should_match_options
+ end
+ end
+
+ context "scoped by action" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options_1.update(action: :index)
+ instance_decorator.action_link link_options_2
+ end
+ klass
+ end
+
+ it "should only return links defined for the given action" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 1
+ instance_exec links.first, link_options_2, &link_should_match_options
+ end
+ end
+
+ context "with a policy" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link href: "foo", content: "foo", policy: :edit
+ end
+ klass
+ end
+
+ context "when the policy is not met" do
+ before(:each) do
+ Draper::HelperProxy.any_instance.stub(:policy){
+ klass = Class.new do
+ def edit?
+ false
+ end
+ end.new
+ }
+ end
+
+ it "should not return the link" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 0
+ end
+ end
+
+ context "when the policy is met" do
+ before(:each) do
+ Draper::HelperProxy.any_instance.stub(:policy){
+ klass = Class.new do
+ def edit?
+ true
+ end
+ end.new
+ }
+ end
+
+ it "should not return the link" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 1
+ end
+ end
+ end
+
+ context "with a feature" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link href: "foo", content: "foo", feature: :foo
+ end
+ klass
+ end
+
+ context "when the feature is not present" do
+ before(:each) do
+ Draper::HelperProxy.any_instance.stub(:has_feature?){false}
+ end
+
+ it "should not return the link" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 0
+ end
+ end
+
+ context "when the feature is present" do
+ before(:each) do
+ Draper::HelperProxy.any_instance.stub(:has_feature?){true}
+ end
+
+ it "should not return the link" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 1
+ end
+ end
+ end
+
+ context "with a condition" do
+ context "set with 'with_condition'" do
+ context "as a value" do
+ context "when the condition is true" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.with_condition true do
+ action_link href: "foo", content: "foo"
+ end
+ end
+ klass
+ end
+
+ it "should return the link" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 1
+ end
+ end
+
+ context "when the condition is false" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.with_condition false do
+ action_link href: "foo", content: "foo"
+ end
+ end
+ klass
+ end
+
+ it "should not return the link" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 0
+ end
+ end
+ end
+
+ context "as a Proc" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.with_condition ->{context[:show_link]} do
+ action_link href: "foo", content: "foo"
+ end
+ end
+ klass
+ end
+
+ context "when the condition is true" do
+ let(:decorated) do
+ obj = create :line
+ decorator.decorate(obj, context: {show_link: true})
+ end
+
+ it "should return the link" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 1
+ end
+ end
+
+ context "when the condition is false" do
+ let(:decorated) do
+ obj = create :line
+ decorator.decorate(obj, context: {show_link: false})
+ end
+
+ it "should not return the link" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 0
+ end
+ end
+ end
+ end
+
+ context "set inline" do
+ context "as a value" do
+ context "when the condition is true" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options_1.update(if: true)
+ end
+ klass
+ end
+
+ it "should return the link" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 1
+ end
+ end
+
+ context "when the condition is false" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options_1.update(if: false)
+ end
+ klass
+ end
+
+ it "should not return the link" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 0
+ end
+ end
+ end
+
+ context "as a Proc" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options_1.update(if: ->{context[:show_link]})
+ end
+ klass
+ end
+
+ context "when the condition is true" do
+ let(:decorated) do
+ obj = create :line
+ decorator.decorate(obj, context: {show_link: true})
+ end
+
+ it "should return the link" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 1
+ end
+ end
+
+ context "when the condition is false" do
+ let(:decorated) do
+ obj = create :line
+ decorator.decorate(obj, context: {show_link: false})
+ end
+
+ it "should not return the link" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 0
+ end
+ end
+ end
+ end
+ end
+
+ context "scoped by action" do
+ context "with a single action" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options_1.update(action: :index)
+ instance_decorator.action_link link_options_2
+ end
+ klass
+ end
+
+ it "should only return links defined for the given action" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 1
+ instance_exec links.first, link_options_2, &link_should_match_options
+ end
+ end
+
+ context "with several actions" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options_1.update(actions: %i(index edit))
+ instance_decorator.action_link link_options_2.update(actions: %i(show edit))
+ end
+ klass
+ end
+
+ it "should only return links defined for the given action" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 1
+ instance_exec links.first, link_options_2, &link_should_match_options
+ end
+ end
+
+ context "with the keyword 'on'" do
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options_1.update(on: %i(index edit))
+ instance_decorator.action_link link_options_2.update(on: :show)
+ end
+ klass
+ end
+
+ it "should only return links defined for the given action" do
+ links = decorated.action_links(:show)
+ expect(links.size).to eq 1
+ instance_exec links.first, link_options_2, &link_should_match_options
+ end
+ end
+ end
+ end
+ end
+
+ describe '#primary' do
+ let(:decorator) do
+ Class.new(AF83::Decorator)
+ end
+
+ let(:decorated) do
+ obj = create :line
+ decorator.decorate(obj)
+ end
+
+ it "should return a new object everytime" do
+ actions = decorated.action_links
+ primary = actions.primary
+ expect(actions.options[:groups]).to be_nil
+ expect(primary.options[:groups]).to_not be_nil
+ end
+ end
+
+ describe(:primary_links) do
+ let(:decorated) do
+ obj = create :line
+ decorator.decorate(obj)
+ end
+
+ context "without links" do
+ let(:decorator) do
+ Class.new(AF83::Decorator)
+ end
+
+ it "should return no link" do
+ links = decorated.action_links
+ expect(links.size).to eq 0
+ end
+ end
+
+ context "with a single link" do
+ let(:link_options) do
+ {
+ href: "/foo/bar/baz",
+ content: "Blublu",
+ primary: primary
+ }
+ end
+
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options
+ end
+ klass
+ end
+
+ context "always primary" do
+ let(:primary){ true }
+
+ it "should return the link" do
+ links = decorated.primary_links(:show)
+ expect(links.size).to eq 1
+ end
+ end
+
+ context "primary on this action" do
+ let(:primary){ :show }
+
+ it "should return the link" do
+ links = decorated.primary_links(:show)
+ expect(links.size).to eq 1
+ end
+ end
+
+ context "primary on this action among others" do
+ let(:primary){ %i(show edit) }
+
+ it "should return the link" do
+ links = decorated.action_links(:show, group: :primary)
+ expect(links.size).to eq 1
+ end
+ end
+
+ context "primary on other actions" do
+ let(:primary){ %i(index edit) }
+
+ it "should not return the link" do
+ links = decorated.action_links(:show, group: :primary)
+ expect(links.size).to eq 0
+ end
+ end
+
+ context "primary on another action" do
+ let(:primary){ :index }
+
+ it "should not return the link" do
+ links = decorated.primary_links(:show)
+ expect(links.size).to eq 0
+ end
+ end
+
+ context "never primary" do
+ let(:primary){ nil }
+
+ it "should not return the link" do
+ links = decorated.primary_links(:show)
+ expect(links.size).to eq 0
+ end
+ end
+ end
+ end
+
+ describe("in a group") do
+ let(:decorated) do
+ obj = create :line
+ decorator.decorate(obj)
+ end
+
+ context "without links" do
+ let(:decorator) do
+ Class.new(AF83::Decorator)
+ end
+
+ it "should return no link" do
+ links = decorated.action_links
+ expect(links.size).to eq 0
+ end
+ end
+
+
+ context "with a single link" do
+ let(:link_options) do
+ {
+ href: "/foo/bar/baz",
+ content: "Blublu",
+ groups: {foo: group}
+ }
+ end
+
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options
+ end
+ klass
+ end
+
+ context "always in" do
+ let(:group){ true }
+
+ it "should return the link" do
+ links = decorated.action_links(:show, group: :foo)
+ expect(links.size).to eq 1
+ end
+
+ context "define with group" do
+ let(:link_options) do
+ {
+ href: "/foo/bar/baz",
+ content: "Blublu",
+ group: :foo
+ }
+ end
+
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options
+ end
+ klass
+ end
+
+ it "should return the link" do
+ links = decorated.action_links(:show, group: :foo)
+ expect(links.size).to eq 1
+ end
+
+ it "should not return the link" do
+ links = decorated.action_links(:show, group: :bar)
+ expect(links.size).to eq 0
+ end
+ end
+ end
+
+ context "primary on this action" do
+ let(:group){ :show }
+
+ it "should return the link" do
+ links = decorated.action_links(:show, group: :foo)
+ expect(links.size).to eq 1
+ end
+ end
+
+ context "in this action among others" do
+ let(:group){ %i(show edit) }
+
+ it "should return the link" do
+ links = decorated.action_links(:show, group: :foo)
+ expect(links.size).to eq 1
+ end
+ end
+
+ context "in other actions" do
+ let(:group){ %i(index edit) }
+
+ it "should not return the link" do
+ links = decorated.action_links(:show, group: :foo)
+ expect(links.size).to eq 0
+ end
+ end
+
+ context "in another action" do
+ let(:group){ :index }
+
+ it "should not return the link" do
+ links = decorated.action_links(:show, group: :foo)
+ expect(links.size).to eq 0
+ end
+ end
+
+ context "never" do
+ let(:group){ nil }
+
+ it "should not return the link" do
+ links = decorated.action_links(:show, group: :foo)
+ expect(links.size).to eq 0
+ end
+ end
+ end
+
+ describe(:grouped_by) do
+ let(:link_options_1) do
+ {
+ href: "/foo/bar",
+ content: "Blublu",
+ primary: true
+ }
+ end
+
+ let(:link_options_2) do
+ {
+ href: "/foo/bar/baz",
+ content: "Foo",
+ groups: {secondary: :show}
+ }
+ end
+
+ let(:link_options_3) do
+ {
+ href: "/foo/bar/baz/bat",
+ content: "Foo",
+ groups: {foo: :show}
+ }
+ end
+
+ let(:link_options_4) do
+ {
+ href: "/footer",
+ content: "Foo",
+ footer: true
+ }
+ end
+
+ let(:decorator) do
+ klass = Class.new(AF83::Decorator)
+ klass.with_instance_decorator do |instance_decorator|
+ instance_decorator.action_link link_options_1
+ instance_decorator.action_link link_options_2
+ instance_decorator.action_link link_options_3
+ instance_decorator.action_link link_options_4
+ end
+ klass
+ end
+
+ it "should return links in their groups" do
+ links = decorated.action_links(:show).grouped_by(:primary, :secondary, :blu, :footer)
+ expect(links.size).to eq 5
+ instance_exec links[:primary].first, link_options_1, &link_should_match_options
+ instance_exec links[:secondary].first, link_options_2, &link_should_match_options
+ expect(links[:blu].size).to eq 0
+ instance_exec links[:other].first, link_options_3, &link_should_match_options
+ instance_exec links[:footer].first, link_options_4, &link_should_match_options
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/range_ext_spec.rb b/spec/lib/range_ext_spec.rb
index 9c44608b9..eee488c91 100644
--- a/spec/lib/range_ext_spec.rb
+++ b/spec/lib/range_ext_spec.rb
@@ -1,6 +1,6 @@
require 'range_ext'
RSpec.describe Range do
- context "intersection" do
+ describe "#intersection" do
it "is nil (sic) for two distinct ranges" do
expect( (1..2).intersection(3..4) ).to be_nil
end
@@ -15,4 +15,53 @@ RSpec.describe Range do
expect( (2..4) & (1..3) ).to eq 2..3
end
end
+
+ describe "intersect?" do
+ it 'is true when the given range includes begin' do
+ expect( (2..4).intersect? (1..3) ).to be_truthy
+ end
+
+ it 'is true when the given range includes end' do
+ expect( (2..4).intersect? (3..5) ).to be_truthy
+ end
+
+ it 'is true when the given range includes both begin and end' do
+ expect( (2..4).intersect? (1..5) ).to be_truthy
+ end
+
+ it 'is true when the given range is the same' do
+ expect( (2..4).intersect? (2..4) ).to be_truthy
+ end
+
+ it 'is false when the given range is after' do
+ expect( (2..4).intersect? (5..7) ).to be_falsey
+ end
+
+ it 'is false when the given range is before' do
+ expect( (2..4).intersect? (0..2) ).to be_falsey
+ end
+ end
+
+ context "remove" do
+ it "is unchanged when the given range has no intersection" do
+ expect( (1..2).remove(3..4) ).to eq 1..2
+ expect( (3..4).remove(1..2) ).to eq 3..4
+ end
+
+ it "is nil for two equal ranges" do
+ expect( (1..2).remove(1..2) ).to be_empty
+ end
+
+ it "is the begin of the range when given range intersect the end" do
+ expect( (5..10).remove(8..15) ).to eq [5..7]
+ end
+
+ it "is the end of the range when given range intersect the begin" do
+ expect( (5..10).remove(1..6) ).to eq [7..10]
+ end
+
+ it "is the two remaing ranges when given range is the middle" do
+ expect( (1..10).remove(4..6) ).to eq [1..3, 7..10]
+ end
+ end
end
diff --git a/spec/lib/stif/netex_file/frame_spec.rb b/spec/lib/stif/netex_file/frame_spec.rb
new file mode 100644
index 000000000..506da2148
--- /dev/null
+++ b/spec/lib/stif/netex_file/frame_spec.rb
@@ -0,0 +1,13 @@
+require 'stif/netex_file'
+RSpec.describe STIF::NetexFile::Frame do
+
+ context "line object id extraction" do
+ it "gets the line object id if frame describes a line" do
+ expect( described_class.get_short_id('offre_C00109_10.xml') ).to eq('C00109')
+ end
+
+ it "gets nil if the frame does not describe a line" do
+ expect( described_class.get_short_id('commun.xml') ).to be_nil
+ end
+ end
+end
diff --git a/spec/lib/stif/netex_file_spec.rb b/spec/lib/stif/netex_file_spec.rb
index ef69b994c..850d0d3de 100644
--- a/spec/lib/stif/netex_file_spec.rb
+++ b/spec/lib/stif/netex_file_spec.rb
@@ -1,8 +1,9 @@
+require 'stif/netex_file'
RSpec.describe STIF::NetexFile do
let( :zip_file ){ fixtures_path 'OFFRE_TRANSDEV_2017030112251.zip' }
- let(:frames) { STIF::NetexFile.new(zip_file).frames }
+ let(:frames) { described_class.new(zip_file).frames }
it "should return a frame for each sub directory" do
expect(frames.size).to eq(2)
@@ -22,4 +23,5 @@ RSpec.describe STIF::NetexFile do
end
end
+
end
diff --git a/spec/lib/stif/permission_translator_spec.rb b/spec/lib/stif/permission_translator_spec.rb
index ae1a2d1d5..9771af187 100644
--- a/spec/lib/stif/permission_translator_spec.rb
+++ b/spec/lib/stif/permission_translator_spec.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
RSpec.describe Stif::PermissionTranslator do
context "No SSO Permissions" do
@@ -42,4 +43,19 @@ RSpec.describe Stif::PermissionTranslator do
).to match_array(Support::Permissions.all_permissions)
end
end
+
+ context "For the STIF organisation" do
+ let(:organisation){ build_stubbed :organisation, name: "STIF" }
+ let(:permissions){ %w{calendars.share stop_area_referentials.synchronize line_referentials.synchronize}.sort }
+ it "adds the STIF permission" do
+ expect(described_class.translate([], organisation).sort).to eq permissions
+ end
+
+ context "with the case changed" do
+ let(:organisation){ build_stubbed :organisation, name: "StiF" }
+ it "adds the STIF permission" do
+ expect(described_class.translate([], organisation).sort).to eq permissions
+ end
+ end
+ end
end
diff --git a/spec/mailers/calendar_mailer_spec.rb b/spec/mailers/calendar_mailer_spec.rb
index 9a2076f64..00d73a58b 100644
--- a/spec/mailers/calendar_mailer_spec.rb
+++ b/spec/mailers/calendar_mailer_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe CalendarMailer, type: :mailer do
end
it 'should have correct body' do
- key = I18n.t("mailers.calendar_mailer.#{type}.body", cal_name: calendar.name, cal_index_url: calendars_url)
+ key = I18n.t("mailers.calendar_mailer.#{type}.body", cal_name: calendar.name, cal_index_url: workgroup_calendars_url(calendar.workgroup))
expect(email).to have_body_text /#{key}/
end
end
diff --git a/spec/models/calendar_spec.rb b/spec/models/calendar_spec.rb
index e71c2b081..a5c0a7471 100644
--- a/spec/models/calendar_spec.rb
+++ b/spec/models/calendar_spec.rb
@@ -9,20 +9,34 @@ RSpec.describe Calendar, :type => :model do
it { is_expected.to be_versioned }
describe '#to_time_table' do
- let(:calendar) { create(:calendar, date_ranges: [Date.today...(Date.today + 1.month)]) }
+ let(:calendar) { create(:calendar, int_day_types: Calendar::MONDAY | Calendar::SUNDAY, date_ranges: [Date.today...(Date.today + 1.month)]) }
it 'should convert calendar to an instance of Chouette::TimeTable' do
time_table = calendar.convert_to_time_table
expect(time_table).to be_an_instance_of(Chouette::TimeTable)
+ expect(time_table.int_day_types).to eq calendar.int_day_types
expect(time_table.periods[0].period_start).to eq(calendar.periods[0].begin)
expect(time_table.periods[0].period_end).to eq(calendar.periods[0].end)
expect(time_table.dates.map(&:date)).to match_array(calendar.dates)
end
end
+ describe 'application days' do
+ let(:calendar) { create(:calendar) }
+ it "should default to all days" do
+ %w(monday tuesday wednesday thursday friday saturday sunday).each do |day|
+ expect(calendar.send(day)).to be_truthy
+ end
+ end
+ end
+
describe 'validations' do
it 'validates that dates and date_ranges do not overlap' do
- expect(build(:calendar, dates: [Date.today], date_ranges: [Date.today..Date.tomorrow])).to_not be_valid
+ expect(build(:calendar, dates: [Date.today.beginning_of_week], date_ranges: [Date.today.beginning_of_week..Date.today])).to_not be_valid
+ end
+
+ it 'validates that dates and date_ranges do not overlap but allow for days not in the list' do
+ expect(build(:calendar, dates: [Date.today.beginning_of_week - 1.week], date_ranges: [(Date.today.beginning_of_week - 1.week)..Date.today], int_day_types: Calendar::THURSDAY)).to be_valid
end
it 'validates that there are no duplicates in dates' do
@@ -42,4 +56,108 @@ RSpec.describe Calendar, :type => :model do
end
end
+ describe "Update state" do
+ def calendar_to_state calendar
+ calendar.slice('id').tap do |item|
+ item['comment'] = calendar.name
+ item['day_types'] = "Di,Lu,Ma,Me,Je,Ve,Sa"
+ item['current_month'] = calendar.month_inspect(Date.today.beginning_of_month)
+ item['current_periode_range'] = Date.today.beginning_of_month.to_s
+ item['time_table_periods'] = calendar.periods.map{|p| {'id': p.id, 'period_start': p.period_start.to_s, 'period_end': p.period_end.to_s}}
+ end
+ end
+
+ subject(:calendar){ create :calendar }
+ let(:state) { calendar_to_state subject }
+
+ it 'should update time table periods association' do
+ period = state['time_table_periods'].first
+ period['period_start'] = (Date.today - 1.month).to_s
+ period['period_end'] = (Date.today + 1.month).to_s
+
+ subject.state_update_periods state['time_table_periods']
+ ['period_end', 'period_start'].each do |prop|
+ expect(subject.reload.periods.first.send(prop).to_s).to eq(period[prop])
+ end
+ end
+
+ it 'should create time table periods association' do
+ state['time_table_periods'] << {
+ 'id' => false,
+ 'period_start' => (Date.today + 1.year).to_s,
+ 'period_end' => (Date.today + 2.year).to_s
+ }
+
+ expect {
+ subject.state_update_periods state['time_table_periods']
+ }.to change {subject.periods.count}.by(1)
+ expect(state['time_table_periods'].last['id']).to eq subject.reload.periods.last.id
+ end
+
+ it 'should delete time table periods association' do
+ state['time_table_periods'].first['deleted'] = true
+ expect {
+ subject.state_update_periods state['time_table_periods']
+ }.to change {subject.periods.count}.by(-1)
+ end
+
+ it 'should update name' do
+ state['comment'] = "Edited timetable name"
+ subject.state_update state
+ expect(subject.reload.name).to eq state['comment']
+ end
+
+ it 'should update day_types' do
+ state['day_types'] = "Di,Lu,Je,Ma"
+ subject.state_update state
+ expect(subject.reload.valid_days).to include(7, 1, 4, 2)
+ expect(subject.reload.valid_days).not_to include(3, 5, 6)
+ end
+
+ it 'should delete date if date is set to neither include or excluded date' do
+ updated = state['current_month'].map do |day|
+ day['include_date'] = false if day['include_date']
+ end
+
+ expect {
+ subject.state_update state
+ }.to change {subject.dates.count}.by(-updated.compact.count)
+ end
+
+ it 'should update date if date is set to excluded date' do
+ updated = state['current_month'].map do |day|
+ next unless day['include_date']
+ day['include_date'] = false
+ day['excluded_date'] = true
+ end
+
+ subject.state_update state
+ expect(subject.reload.excluded_days.count).to eq (updated.compact.count)
+ end
+
+ it 'should create new include date' do
+ 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)
+
+ expect {
+ subject.state_update state
+ }.to change {subject.dates.count}.by(1)
+ expect(subject.reload.included_days).to include(date)
+ end
+
+ it 'should create new exclude date' do
+ 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)
+
+ expect {
+ subject.state_update state
+ }.to change {subject.all_dates.count}.by(1)
+ expect(subject.reload.excluded_days).to include(date)
+ end
+ end
+
end
diff --git a/spec/models/chouette/access_point_spec.rb b/spec/models/chouette/access_point_spec.rb
index c734ecedf..2184c6ec2 100644
--- a/spec/models/chouette/access_point_spec.rb
+++ b/spec/models/chouette/access_point_spec.rb
@@ -136,7 +136,7 @@ describe Chouette::AccessPoint, :type => :model do
describe "#generic_access_link_matrix" do
it "should have 2 generic_access_links in matrix" do
- stop_place = create :stop_area, :area_type => "zdlp"
+ stop_place = create :stop_area, :area_type => "gdl"
commercial_stop_point = create :stop_area, :area_type => "lda" ,:parent => stop_place
subject = create :access_point, :stop_area => stop_place
expect(subject.generic_access_link_matrix.size).to eq(2)
diff --git a/spec/models/chouette/area_type_spec.rb b/spec/models/chouette/area_type_spec.rb
new file mode 100644
index 000000000..28325dd0a
--- /dev/null
+++ b/spec/models/chouette/area_type_spec.rb
@@ -0,0 +1,43 @@
+require "rails_helper"
+
+RSpec.describe Chouette::AreaType do
+
+ describe "::ALL" do
+ it "includes all supported types" do
+ expect(Chouette::AreaType::ALL).to match_array( %i(zdep zder zdlp zdlr lda gdl deposit border service_area relief other) )
+ expect(Chouette::AreaType::COMMERCIAL).to match_array( %i(zdep zder zdlp zdlr lda gdl) )
+ expect(Chouette::AreaType::NON_COMMERCIAL).to match_array( %i( deposit border service_area relief other) )
+ end
+ end
+
+ describe ".find" do
+ it "returns nil if the given code is nil" do
+ expect(Chouette::AreaType.find(nil)).to be_nil
+ end
+
+ it "returns nil if the given code is unknown" do
+ expect(Chouette::AreaType.find('dummy')).to be_nil
+ end
+
+ it "returns an AreaType associated to the code" do
+ expect(Chouette::AreaType.find('zdep').code).to eq :zdep
+ end
+ end
+
+ describe ".options" do
+ before do
+ Chouette::AreaType.reset_caches!
+ end
+
+ it "returns an array with label and code for each type" do
+ allow(Chouette::AreaType).to receive(:all).and_return(%i{zdep lda})
+
+ expected_options = [
+ [Chouette::AreaType.find('zdep').label, :zdep],
+ [Chouette::AreaType.find('lda').label, :lda]
+ ]
+ expect(Chouette::AreaType.options).to eq(expected_options)
+ end
+ end
+
+end
diff --git a/spec/models/chouette/footnote_spec.rb b/spec/models/chouette/footnote_spec.rb
index fc5e5f306..05f55c2f0 100644
--- a/spec/models/chouette/footnote_spec.rb
+++ b/spec/models/chouette/footnote_spec.rb
@@ -1,12 +1,12 @@
require 'spec_helper'
describe Chouette::Footnote, type: :model do
- let(:footnote) { create(:footnote) }
+ subject { create(:footnote) }
it { should validate_presence_of :line }
describe 'data_source_ref' do
it 'should set default if omitted' do
- expect(footnote.data_source_ref).to eq "DATASOURCEREF_EDITION_BOIV"
+ expect(subject.data_source_ref).to eq "DATASOURCEREF_EDITION_BOIV"
end
it 'should not set default if not omitted' do
@@ -18,16 +18,16 @@ describe Chouette::Footnote, type: :model do
end
describe 'checksum' do
- it_behaves_like 'checksum support', :footnote
+ it_behaves_like 'checksum support'
context '#checksum_attributes' do
it 'should return code and label' do
- expected = [footnote.code, footnote.label]
- expect(footnote.checksum_attributes).to include(*expected)
+ expected = [subject.code, subject.label]
+ expect(subject.checksum_attributes).to include(*expected)
end
it 'should not return other atrributes' do
- expect(footnote.checksum_attributes).to_not include(footnote.updated_at)
+ expect(subject.checksum_attributes).to_not include(subject.updated_at)
end
end
end
diff --git a/spec/models/chouette/journey_pattern_spec.rb b/spec/models/chouette/journey_pattern_spec.rb
index ea7c2a2e9..19a74a0e7 100644
--- a/spec/models/chouette/journey_pattern_spec.rb
+++ b/spec/models/chouette/journey_pattern_spec.rb
@@ -2,9 +2,10 @@ require 'spec_helper'
describe Chouette::JourneyPattern, :type => :model do
it { is_expected.to be_versioned }
+ subject { create(:journey_pattern) }
describe 'checksum' do
- it_behaves_like 'checksum support', :journey_pattern
+ it_behaves_like 'checksum support'
end
# context 'validate minimum stop_points size' do
@@ -32,6 +33,44 @@ describe Chouette::JourneyPattern, :type => :model do
# end
# end
+ describe "full_schedule?" do
+ let(:journey_pattern) { create :journey_pattern }
+ subject{ journey_pattern.full_schedule? }
+ context "when no time is set" do
+ it { should be_falsy }
+ end
+
+ context "when the costs are incomplete" do
+ context "with a missing distance" do
+ before(:each){
+ journey_pattern.costs = generate_journey_pattern_costs(->(i){i == 1 ? nil : 10}, 10)
+ }
+ it { should be_falsy }
+ end
+
+ context "with a missing time" do
+ before(:each){
+ journey_pattern.costs = generate_journey_pattern_costs(10, ->(i){i == 1 ? nil : 10})
+ }
+ it { should be_falsy }
+ end
+ end
+
+ context "with a zeroed cost" do
+ before(:each){
+ journey_pattern.costs = generate_journey_pattern_costs(->(i){i == 1 ? 0 : 10}, 10)
+ }
+ it { should be_falsy }
+ end
+
+ context "when all the times are set" do
+ before(:each){
+ journey_pattern.costs = generate_journey_pattern_costs(10, 10)
+ }
+ it { should be_truthy }
+ end
+ end
+
describe "state_update" do
def journey_pattern_to_state jp
jp.attributes.slice('name', 'published_name', 'registration_number').tap do |item|
@@ -39,6 +78,7 @@ describe Chouette::JourneyPattern, :type => :model do
item['stop_points'] = jp.stop_points.map do |sp|
{ 'id' => sp.stop_area_id }
end
+ item['costs'] = jp.costs
end
end
@@ -72,6 +112,14 @@ describe Chouette::JourneyPattern, :type => :model do
expect(new_state['new_record']).to be_truthy
end
+ it 'should create journey_pattern with state_update' do
+ new_state = journey_pattern_to_state(build(:journey_pattern, objectid: nil, route: route))
+ collection = [new_state]
+ expect {
+ Chouette::JourneyPattern.state_update route, collection
+ }.to change{Chouette::JourneyPattern.count}.by(1)
+ end
+
it 'should delete journey_pattern' do
state['deletable'] = true
collection = [state]
diff --git a/spec/models/chouette/purchase_window_spec.rb b/spec/models/chouette/purchase_window_spec.rb
new file mode 100644
index 000000000..702a44eeb
--- /dev/null
+++ b/spec/models/chouette/purchase_window_spec.rb
@@ -0,0 +1,27 @@
+RSpec.describe Chouette::PurchaseWindow, :type => :model do
+ let(:referential) {create(:referential)}
+ subject { create(:purchase_window, referential: referential) }
+
+ it { should belong_to(:referential) }
+ it { is_expected.to validate_presence_of(:name) }
+
+ describe 'validations' do
+ it 'validates and date_ranges do not overlap' do
+ expect(build(:purchase_window, referential: referential,date_ranges: [Date.today..Date.today + 10.day, Date.yesterday..Date.tomorrow])).to_not be_valid
+ # expect(build(periods: [Date.today..Date.today + 10.day, Date.yesterday..Date.tomorrow ])).to_not be_valid
+ end
+ end
+
+ describe 'before_validation' do
+ let(:purchase_window) { build(:purchase_window, referential: referential, date_ranges: []) }
+
+ it 'shoud fill date_ranges with date ranges' do
+ expected_range = Date.today..Date.tomorrow
+ purchase_window.date_ranges << expected_range
+ purchase_window.valid?
+
+ expect(purchase_window.date_ranges.map { |period| period.begin..period.end }).to eq([expected_range])
+ end
+ end
+
+end
diff --git a/spec/models/chouette/route/route_base_spec.rb b/spec/models/chouette/route/route_base_spec.rb
index 26f57eae5..98cb3e358 100644
--- a/spec/models/chouette/route/route_base_spec.rb
+++ b/spec/models/chouette/route/route_base_spec.rb
@@ -1,8 +1,8 @@
RSpec.describe Chouette::Route, :type => :model do
-
subject { create(:route) }
+
describe 'checksum' do
- it_behaves_like 'checksum support', :route
+ it_behaves_like 'checksum support'
end
it { is_expected.to enumerize(:direction).in(:straight_forward, :backward, :clockwise, :counter_clockwise, :north, :north_west, :west, :south_west, :south, :south_east, :east, :north_east) }
diff --git a/spec/models/chouette/route/route_duplication_spec.rb b/spec/models/chouette/route/route_duplication_spec.rb
index ee45b5005..8b3a948a2 100644
--- a/spec/models/chouette/route/route_duplication_spec.rb
+++ b/spec/models/chouette/route/route_duplication_spec.rb
@@ -2,7 +2,7 @@ RSpec.describe Chouette::Route do
let!( :route ){ create :route }
- context '#duplicate' do
+ context '#duplicate' do
describe 'properties' do
it 'same attribute values' do
route.duplicate
@@ -23,7 +23,12 @@ RSpec.describe Chouette::Route do
it 'duplicates its stop points' do
expect{ route.duplicate }.to change{Chouette::StopPoint.count}.by(route.stop_points.count)
end
- it 'does bot duplicate the stop areas' do
+
+ it 'duplicates its stop points in the same order' do
+ expect(route.duplicate.stop_points.order(:position).map(&:stop_area_id)).to eq route.stop_points.order(:position).map(&:stop_area_id)
+ end
+
+ it 'does not duplicate the stop areas' do
expect{ route.duplicate }.not_to change{Chouette::StopArea.count}
end
end
@@ -34,7 +39,7 @@ RSpec.describe Chouette::Route do
it 'the required attributes' do
expect( values_for_create(first_duplicate, except: %w{objectid name checksum checksum_source}) ).to eq( values_for_create( second_duplicate, except: %w{objectid name checksum checksum_source} ) )
- end
+ end
it 'the stop areas' do
expect( first_duplicate.stop_areas.pluck(:id) ).to eq( route.stop_areas.pluck(:id) )
diff --git a/spec/models/chouette/routing_constraint_zone_spec.rb b/spec/models/chouette/routing_constraint_zone_spec.rb
index 8ebd8695c..bda6bb04a 100644
--- a/spec/models/chouette/routing_constraint_zone_spec.rb
+++ b/spec/models/chouette/routing_constraint_zone_spec.rb
@@ -5,21 +5,16 @@ describe Chouette::RoutingConstraintZone, type: :model do
subject { create(:routing_constraint_zone) }
it { is_expected.to validate_presence_of :name }
+ it { is_expected.to validate_presence_of :route_id }
# shoulda matcher to validate length of array ?
xit { is_expected.to validate_length_of(:stop_point_ids).is_at_least(2) }
it { is_expected.to be_versioned }
describe 'checksum' do
- it_behaves_like 'checksum support', :routing_constraint_zone
+ it_behaves_like 'checksum support'
end
describe 'validations' do
- it 'validates the presence of route_id' do
- expect {
- subject.update!(route_id: nil)
- }.to raise_error(NoMethodError)
- end
-
it 'validates the presence of stop_point_ids' do
expect {
subject.update!(stop_point_ids: [])
diff --git a/spec/models/chouette/stop_area_spec.rb b/spec/models/chouette/stop_area_spec.rb
index c6aeafaf8..32ee5a3a6 100644
--- a/spec/models/chouette/stop_area_spec.rb
+++ b/spec/models/chouette/stop_area_spec.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
require 'spec_helper'
describe Chouette::StopArea, :type => :model do
@@ -9,10 +10,20 @@ describe Chouette::StopArea, :type => :model do
it { should belong_to(:stop_area_referential) }
it { should validate_presence_of :name }
+ it { should validate_presence_of :kind }
it { should validate_numericality_of :latitude }
it { should validate_numericality_of :longitude }
it { is_expected.to be_versioned }
+ describe "#area_type" do
+ it "should validate the value is correct regarding to the kind" do
+ expect(build(:stop_area, kind: :commercial, area_type: :gdl)).to be_valid
+ expect(build(:stop_area, kind: :non_commercial, area_type: :relief)).to be_valid
+ expect(build(:stop_area, kind: :commercial, area_type: :relief)).to_not be_valid
+ expect(build(:stop_area, kind: :non_commercial, area_type: :gdl)).to_not be_valid
+ end
+ end
+
# describe ".latitude" do
# it "should accept -90 value" do
# subject = create :stop_area, :area_type => "BoardingPosition"
@@ -426,5 +437,74 @@ describe Chouette::StopArea, :type => :model do
# end
# end
+ describe "#parent" do
+
+ let(:stop_area) { FactoryGirl.build :stop_area, parent: FactoryGirl.build(:stop_area) }
+
+ it "is valid when parent has an 'higher' type" do
+ stop_area.area_type = 'zdep'
+ stop_area.parent.area_type = 'zdlp'
+
+ stop_area.valid?
+ expect(stop_area.errors).to_not have_key(:parent_id)
+ end
+
+ it "is valid when parent is undefined" do
+ stop_area.parent = nil
+
+ stop_area.valid?
+ expect(stop_area.errors).to_not have_key(:parent_id)
+ end
+
+ it "isn't valid when parent has the same type" do
+ stop_area.parent.area_type = stop_area.area_type = 'zdep'
+
+ stop_area.valid?
+ expect(stop_area.errors).to have_key(:parent_id)
+ end
+
+ it "isn't valid when parent has a lower type" do
+ stop_area.area_type = 'lda'
+ stop_area.parent.area_type = 'zdep'
+
+ stop_area.valid?
+ expect(stop_area.errors).to have_key(:parent_id)
+ end
+
+ it "use parent area type label in validation error message" do
+ stop_area.area_type = 'zdep'
+ stop_area.parent.area_type = 'zdep'
+
+ stop_area.valid?
+ expect(stop_area.errors[:parent_id].first).to include(Chouette::AreaType.find(stop_area.parent.area_type).label)
+ end
+
+ end
+
+ describe '#waiting_time' do
+
+ let(:stop_area) { FactoryGirl.build :stop_area }
+
+ it 'can be nil' do
+ stop_area.waiting_time = nil
+ expect(stop_area).to be_valid
+ end
+
+ it 'can be zero' do
+ stop_area.waiting_time = 0
+ expect(stop_area).to be_valid
+ end
+
+ it 'can be positive' do
+ stop_area.waiting_time = 120
+ expect(stop_area).to be_valid
+ end
+
+ it "can't be negative" do
+ stop_area.waiting_time = -1
+ expect(stop_area).to_not be_valid
+ end
+
+ end
end
diff --git a/spec/models/chouette/time_table_period_spec.rb b/spec/models/chouette/time_table_period_spec.rb
index cc1a3ae09..e14d38ade 100644
--- a/spec/models/chouette/time_table_period_spec.rb
+++ b/spec/models/chouette/time_table_period_spec.rb
@@ -10,7 +10,7 @@ describe Chouette::TimeTablePeriod, :type => :model do
it { is_expected.to validate_presence_of :period_end }
describe 'checksum' do
- it_behaves_like 'checksum support', :time_table_period
+ it_behaves_like 'checksum support'
end
describe "#overlap" do
diff --git a/spec/models/chouette/time_table_spec.rb b/spec/models/chouette/time_table_spec.rb
index 677308fc8..bb88877b9 100644
--- a/spec/models/chouette/time_table_spec.rb
+++ b/spec/models/chouette/time_table_spec.rb
@@ -926,6 +926,7 @@ end
end
end
end
+
describe "#validity_out_between?" do
let(:empty_tm) {build(:time_table)}
it "should be false if empty calendar" do
@@ -1048,7 +1049,39 @@ end
# it { is_expected.to validate_uniqueness_of :objectid }
describe 'checksum' do
- it_behaves_like 'checksum support', :time_table
+ it_behaves_like 'checksum support'
+
+ it "handles newly built dates and periods" do
+ time_table = build(:time_table)
+ time_table.periods.build period_start: Time.now, period_end: 1.month.from_now
+ time_table.dates.build date: Time.now
+ time_table.save!
+ expect{time_table.update_checksum!}.to_not change{time_table.checksum}
+ expect(time_table.dates.count).to eq 1
+ expect(time_table.periods.count).to eq 1
+ end
+
+ it "changes when a date is updated" do
+ time_table = create(:time_table)
+ expect{time_table.dates.last.update_attribute(:date, Time.now)}.to change{time_table.reload.checksum}
+ end
+
+ it "changes when a date is added" do
+ time_table = create(:time_table)
+ expect(time_table).to receive(:update_checksum_without_callbacks!).at_least(:once).and_call_original
+ expect{create(:time_table_date, time_table: time_table, date: 1.year.ago)}.to change{time_table.checksum}
+ end
+
+ it "changes when a period is updated" do
+ time_table = create(:time_table)
+ expect{time_table.periods.last.update_attribute(:period_start, Time.now)}.to change{time_table.reload.checksum}
+ end
+
+ it "changes when a period is added" do
+ time_table = create(:time_table)
+ expect(time_table).to receive(:update_checksum_without_callbacks!).at_least(:once).and_call_original
+ expect{create(:time_table_period, time_table: time_table)}.to change{time_table.checksum}
+ end
end
describe "#excluded_days" do
@@ -1068,8 +1101,6 @@ end
end
end
-
-
describe "#effective_days" do
before do
subject.periods.clear
@@ -1094,8 +1125,6 @@ end
end
end
-
-
describe "#optimize_overlapping_periods" do
before do
subject.periods.clear
@@ -1187,4 +1216,99 @@ end
expect(subject.tag_list.size).to eq(2)
end
end
+
+ describe "#intersect_periods!" do
+ let(:time_table) { Chouette::TimeTable.new }
+ let(:periods) do
+ [
+ Date.new(2018, 1, 1)..Date.new(2018, 2, 1),
+ ]
+ end
+
+ it "remove a date not included in given periods" do
+ time_table.dates.build date: Date.new(2017,12,31)
+ time_table.intersect_periods! periods
+ expect(time_table.dates).to be_empty
+ end
+
+ it "keep a date included in given periods" do
+ time_table.dates.build date: Date.new(2018,1,15)
+ expect{time_table.intersect_periods! periods}.to_not change(time_table, :dates)
+ end
+
+ it "remove a period not included in given periods" do
+ time_table.periods.build period_start: Date.new(2017,12,1), period_end: Date.new(2017,12,31)
+ time_table.intersect_periods! periods
+ expect(time_table.periods).to be_empty
+ end
+
+ it "modify a start period if not included in given periods" do
+ period = time_table.periods.build period_start: Date.new(2017,12,1), period_end: Date.new(2018,1,15)
+ time_table.intersect_periods! periods
+ expect(period.period_start).to eq(Date.new(2018, 1, 1))
+ end
+
+ it "modify a end period if not included in given periods" do
+ period = time_table.periods.build period_start: Date.new(2018,1,15), period_end: Date.new(2018,3,1)
+ time_table.intersect_periods! periods
+ expect(period.period_end).to eq(Date.new(2018, 2, 1))
+ end
+
+ it "keep a period included in given periods" do
+ time_table.periods.build period_start: Date.new(2018,1,10), period_end: Date.new(2018,1,20)
+ expect{time_table.intersect_periods! periods}.to_not change(time_table, :periods)
+ end
+
+ end
+
+ describe "#remove_periods!" do
+ let(:time_table) { Chouette::TimeTable.new }
+ let(:periods) do
+ [
+ Date.new(2018, 1, 1)..Date.new(2018, 2, 1),
+ ]
+ end
+
+ it "remove a date included in given periods" do
+ time_table.dates.build date: Date.new(2018,1,15)
+ time_table.remove_periods! periods
+ expect(time_table.dates).to be_empty
+ end
+
+ it "keep a date not included in given periods" do
+ time_table.dates.build date: Date.new(2017,12,31)
+ expect{time_table.remove_periods! periods}.to_not change(time_table, :dates)
+ end
+
+ it "modify a end period if included in given periods" do
+ period = time_table.periods.build period_start: Date.new(2017,12,1), period_end: Date.new(2018,1,15)
+ time_table.remove_periods! periods
+ expect(period.period_end).to eq(Date.new(2017, 12, 31))
+ end
+
+ it "modify a start period if included in given periods" do
+ period = time_table.periods.build period_start: Date.new(2018,1,15), period_end: Date.new(2018,3,1)
+ time_table.remove_periods! periods
+ expect(period.period_start).to eq(Date.new(2018, 2, 2))
+ end
+
+ it "remove a period included in given periods" do
+ time_table.periods.build period_start: Date.new(2018,1,10), period_end: Date.new(2018,1,20)
+ time_table.remove_periods! periods
+ expect(time_table.periods).to be_empty
+ end
+
+ it "split a period including a given period" do
+ time_table.periods.build period_start: Date.new(2017,12,1), period_end: Date.new(2018,3,1)
+ time_table.remove_periods! periods
+
+ expected_ranges = [
+ Date.new(2017,12,1)..Date.new(2017,12,31),
+ Date.new(2018,2,2)..Date.new(2018,3,1)
+ ]
+ expect(time_table.periods.map(&:range)).to eq(expected_ranges)
+ 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 df8a630fe..a97559a0c 100644
--- a/spec/models/chouette/vehicle_journey_at_stop_spec.rb
+++ b/spec/models/chouette/vehicle_journey_at_stop_spec.rb
@@ -1,10 +1,12 @@
require 'spec_helper'
RSpec.describe Chouette::VehicleJourneyAtStop, type: :model do
+ subject { create(:vehicle_journey_at_stop) }
+
describe 'checksum' do
let(:at_stop) { build_stubbed(:vehicle_journey_at_stop) }
- it_behaves_like 'checksum support', :vehicle_journey_at_stop
+ it_behaves_like 'checksum support'
context '#checksum_attributes' do
it 'should return attributes' do
@@ -40,6 +42,41 @@ RSpec.describe Chouette::VehicleJourneyAtStop, type: :model do
end
end
+ context "the different times" do
+ let (:at_stop) { build_stubbed(:vehicle_journey_at_stop) }
+
+ describe "without a TimeZone" do
+ it "should not offset times" do
+ expect(at_stop.departure).to eq at_stop.departure_local
+ expect(at_stop.arrival).to eq at_stop.arrival_local
+ end
+ end
+
+
+ describe "with a TimeZone" do
+ before(:each) do
+ stop = at_stop.stop_point.stop_area
+ stop.time_zone = "Mexico City"
+ end
+
+ it "should offset times" do
+ expect(at_stop.departure_local).to eq at_stop.send(:format_time, at_stop.departure_time - 6.hours)
+ expect(at_stop.arrival_local).to eq at_stop.send(:format_time, at_stop.arrival_time - 6.hours)
+ end
+
+ context "with a wrong Timezone" do
+ before do
+ at_stop.stop_point.stop_area.time_zone = "Gotham City"
+ end
+
+ it "should not offset times" do
+ expect(at_stop.departure_local).to eq at_stop.send(:format_time, at_stop.departure_time)
+ expect(at_stop.arrival_local).to eq at_stop.send(:format_time, at_stop.arrival_time)
+ end
+ end
+ end
+ end
+
describe "#validate" do
it "displays the proper error message when day offset exceeds the max" do
bad_offset = Chouette::VehicleJourneyAtStop::DAY_OFFSET_MAX + 1
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index ac9b21ceb..76e73d9cf 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -1,7 +1,10 @@
require 'spec_helper'
describe Chouette::VehicleJourney, :type => :model do
+ subject { create(:vehicle_journey) }
+
it { is_expected.to be_versioned }
+ it { should have_and_belong_to_many(:purchase_windows) }
it "must be valid with an at-stop day offset of 1" do
vehicle_journey = create(
@@ -20,7 +23,183 @@ describe Chouette::VehicleJourney, :type => :model do
end
describe 'checksum' do
- it_behaves_like 'checksum support', :vehicle_journey
+ it_behaves_like 'checksum support'
+ it "changes when a vjas is updated" do
+ vehicle_journey = create(:vehicle_journey)
+ expect{vehicle_journey.vehicle_journey_at_stops.last.update_attribute(:departure_time, Time.now)}.to change{vehicle_journey.reload.checksum}
+ end
+
+ it "changes when a vjas is added" do
+ vehicle_journey = create(:vehicle_journey)
+ expect(vehicle_journey).to receive(:update_checksum_without_callbacks!).at_least(:once).and_call_original
+ expect{create(:vehicle_journey_at_stop, vehicle_journey: vehicle_journey)}.to change{vehicle_journey.checksum}
+ end
+ end
+
+ describe "#with_stop_area_ids" do
+ subject(:result){Chouette::VehicleJourney.with_stop_area_ids(ids)}
+ let(:ids){[]}
+ let(:common_stop_area){ create :stop_area}
+ let!(:journey_1){ create :vehicle_journey }
+ let!(:journey_2){ create :vehicle_journey }
+
+ before(:each) do
+ journey_1.journey_pattern.stop_points.last.update_attribute :stop_area_id, common_stop_area.id
+ journey_2.journey_pattern.stop_points.last.update_attribute :stop_area_id, common_stop_area.id
+ expect(journey_1.stop_areas).to include(common_stop_area)
+ expect(journey_2.stop_areas).to include(common_stop_area)
+ end
+ context "with no value" do
+ it "should return all journeys" do
+ expect(result).to eq Chouette::VehicleJourney.all
+ end
+ end
+
+ context "with a single value" do
+ let(:ids){[journey_1.stop_areas.first.id]}
+ it "should return all journeys" do
+ expect(result).to eq [journey_1]
+ end
+
+ context "with a common area" do
+ let(:ids){[common_stop_area.id]}
+ it "should return all journeys" do
+ expect(result.to_a.sort).to eq [journey_1, journey_2].sort
+ end
+ end
+ end
+
+ context "with a couple of values" do
+ let(:ids){[journey_1.stop_areas.first.id, common_stop_area.id]}
+ it "should return only the matching journeys" do
+ expect(result).to eq [journey_1]
+ end
+ end
+
+ end
+
+ describe '#in_purchase_window' do
+ let(:start_date){2.month.ago.to_date}
+ let(:end_date){1.month.ago.to_date}
+
+ subject{Chouette::VehicleJourney.in_purchase_window start_date..end_date}
+
+ let!(:without_purchase_window){ create :vehicle_journey }
+ let!(:without_matching_purchase_window){
+ pw = create :purchase_window, referential: Referential.first, date_ranges: [(end_date+1.day..end_date+2.days)]
+ pw2 = create :purchase_window, referential: Referential.first, date_ranges: [(end_date+10.day..end_date+20.days)]
+ create :vehicle_journey, purchase_windows: [pw, pw2]
+ }
+ let!(:included_purchase_window){
+ pw = create :purchase_window, referential: Referential.first, date_ranges: [(start_date..end_date)]
+ pw2 = create :purchase_window, referential: Referential.first
+ create :vehicle_journey, purchase_windows: [pw, pw2]
+ }
+ let!(:overlapping_purchase_window){
+ pw = create :purchase_window, referential: Referential.first, date_ranges: [(end_date..end_date+1.day)]
+ pw2 = create :purchase_window, referential: Referential.first
+ create :vehicle_journey, purchase_windows: [pw, pw2]
+ }
+
+
+ it "should not include VJ with no purchase window" do
+ expect(subject).to_not include without_purchase_window
+ end
+
+ it "should not include VJ with no matching purchase window" do
+ expect(subject).to_not include without_matching_purchase_window
+ end
+
+ it "should include VJ with included purchase window" do
+ expect(subject).to include included_purchase_window
+ end
+
+ it "should include VJ with overlapping purchase_window purchase window" do
+ expect(subject).to include overlapping_purchase_window
+ end
+ end
+
+ describe '#in_time_table' do
+ let(:start_date){2.month.ago.to_date}
+ let(:end_date){1.month.ago.to_date}
+
+ subject{Chouette::VehicleJourney.with_matching_timetable start_date..end_date}
+
+ context "without time table" do
+ let!(:vehicle_journey){ create :vehicle_journey }
+ it "should not include VJ " do
+ expect(subject).to_not include vehicle_journey
+ end
+ end
+
+ context "without a time table matching on a regular day" do
+ let(:timetable){
+ period = create :time_table_period, period_start: start_date-2.day, period_end: start_date
+ create :time_table, periods: [period], dates_count: 0
+ }
+ let!(:vehicle_journey){ create :vehicle_journey, time_tables: [timetable] }
+ it "should include VJ " do
+ expect(subject).to include vehicle_journey
+ end
+ end
+
+ context "without a time table matching on a regular day" do
+ let(:timetable){
+ period = create :time_table_period, period_start: end_date, period_end: end_date+1.day
+ create :time_table, periods: [period], dates_count: 0
+ }
+ let!(:vehicle_journey){ create :vehicle_journey, time_tables: [timetable] }
+ it "should include VJ " do
+ expect(subject).to include vehicle_journey
+ end
+ end
+
+ context "with a time table with a matching period but not the right day" do
+ let(:start_date){end_date - 1.day}
+ let(:end_date){Time.now.end_of_week.to_date}
+
+ let(:timetable){
+ period = create :time_table_period, period_start: start_date-1.month, period_end: end_date+1.month
+ create :time_table, periods: [period], int_day_types: 4 + 8, dates_count: 0
+ }
+ let!(:vehicle_journey){ create :vehicle_journey, time_tables: [timetable] }
+ it "should not include VJ " do
+ expect(subject).to_not include vehicle_journey
+ end
+ end
+
+ context "with a time table with a matching period but day opted-out" do
+ let(:start_date){end_date - 1.day}
+ let(:end_date){Time.now.end_of_week.to_date}
+
+ let(:timetable){
+ tt = create :time_table, dates_count: 0, periods_count: 0
+ create :time_table_period, period_start: start_date-1.month, period_end: start_date-1.day, time_table: tt
+ create(:time_table_date, :date => start_date, in_out: false, time_table: tt)
+ tt
+ }
+ let!(:vehicle_journey){ create :vehicle_journey, time_tables: [timetable] }
+ it "should not include VJ " do
+ expect(subject).to_not include vehicle_journey
+ end
+ end
+
+ context "with a time table with no matching period but not the right extra day" do
+ let(:start_date){end_date - 1.day}
+ let(:end_date){Time.now.end_of_week.to_date}
+
+ let(:timetable){
+ tt = create :time_table, dates_count: 0, periods_count: 0
+ create :time_table_period, period_start: start_date-1.month, period_end: start_date-1.day, time_table: tt
+ create(:time_table_date, :date => start_date, in_out: true, time_table: tt)
+ tt
+ }
+ let!(:vehicle_journey){ create :vehicle_journey, time_tables: [timetable] }
+ it "should include VJ " do
+ expect(subject).to include vehicle_journey
+ end
+ end
+
end
describe "vjas_departure_time_must_be_before_next_stop_arrival_time",
@@ -63,10 +242,12 @@ describe Chouette::VehicleJourney, :type => :model do
at_stop[att.to_s] = vjas.send(att) unless vjas.send(att).nil?
end
- [:arrival_time, :departure_time].map do |att|
- at_stop[att.to_s] = {
- 'hour' => vjas.send(att).strftime('%H'),
- 'minute' => vjas.send(att).strftime('%M'),
+ at_stop["stop_point_objectid"] = vjas&.stop_point&.objectid
+
+ [:arrival, :departure].map do |att|
+ at_stop["#{att}_time"] = {
+ 'hour' => vjas.send("#{att}_local_time").strftime('%H'),
+ 'minute' => vjas.send("#{att}_local_time").strftime('%M'),
}
end
at_stop
@@ -76,7 +257,10 @@ describe Chouette::VehicleJourney, :type => :model do
vj.slice('objectid', 'published_journey_name', 'journey_pattern_id', 'company_id').tap do |item|
item['vehicle_journey_at_stops'] = []
item['time_tables'] = []
+ item['purchase_windows'] = []
item['footnotes'] = []
+ item['purchase_windows'] = []
+ item['custom_fields'] = vj.custom_fields
vj.vehicle_journey_at_stops.each do |vjas|
item['vehicle_journey_at_stops'] << vehicle_journey_at_stop_to_state(vjas)
@@ -91,18 +275,44 @@ describe Chouette::VehicleJourney, :type => :model do
let(:collection) { [state] }
it 'should create new vj from state' do
- new_vj = build(:vehicle_journey, objectid: nil, published_journey_name: 'dummy', route: route, journey_pattern: journey_pattern)
+ create(:custom_field, code: :energy)
+ new_vj = build(:vehicle_journey, objectid: nil, published_journey_name: 'dummy', route: route, journey_pattern: journey_pattern, custom_field_values: {energy: 99})
collection << vehicle_journey_to_state(new_vj)
expect {
Chouette::VehicleJourney.state_update(route, collection)
}.to change {Chouette::VehicleJourney.count}.by(1)
- expect(collection.last['objectid']).not_to be_nil
obj = Chouette::VehicleJourney.last
+ expect(obj).to receive(:after_commit_objectid).and_call_original
+
+ # For some reason we have to force it
+ obj.after_commit_objectid
obj.run_callbacks(:commit)
+ expect(collection.last['objectid']).to eq obj.objectid
expect(obj.published_journey_name).to eq 'dummy'
+ expect(obj.custom_fields["energy"]["value"]).to eq 99
+ end
+
+ it 'should expect local times' do
+ new_vj = build(:vehicle_journey, objectid: nil, published_journey_name: 'dummy', route: route, journey_pattern: journey_pattern)
+ stop_area = create(:stop_area, time_zone: "Mexico City")
+ stop_point = create(:stop_point, stop_area: stop_area)
+ new_vj.vehicle_journey_at_stops << build(:vehicle_journey_at_stop, vehicle_journey: vehicle_journey, stop_point: stop_point)
+ data = vehicle_journey_to_state(new_vj)
+ data['vehicle_journey_at_stops'][0]["departure_time"]["hour"] = "15"
+ data['vehicle_journey_at_stops'][0]["arrival_time"]["hour"] = "12"
+ collection << data
+ expect {
+ Chouette::VehicleJourney.state_update(route, collection)
+ }.to change {Chouette::VehicleJourney.count}.by(1)
+ created = Chouette::VehicleJourney.last.vehicle_journey_at_stops.last
+ expect(created.stop_point).to eq stop_point
+ expect(created.departure_local_time.hour).to_not eq created.departure_time.hour
+ expect(created.arrival_local_time.hour).to_not eq created.arrival_time.hour
+ expect(created.departure_local_time.hour).to eq 15
+ expect(created.arrival_local_time.hour).to eq 12
end
it 'should save vehicle_journey_at_stops of newly created vj' do
@@ -159,6 +369,23 @@ describe Chouette::VehicleJourney, :type => :model do
expect(vehicle_journey.reload.time_tables).to be_empty
end
+ it 'should update vj purchase_windows association from state' do
+ 2.times{state['purchase_windows'] << create(:purchase_window, referential: referential).slice('id', 'name', 'objectid', 'color')}
+ vehicle_journey.update_has_and_belongs_to_many_from_state(state)
+
+ expected = state['purchase_windows'].map{|tt| tt['id']}
+ actual = vehicle_journey.reload.purchase_windows.map(&:id)
+ expect(actual).to match_array(expected)
+ end
+
+ it 'should clear vj purchase_windows association when remove from state' do
+ vehicle_journey.purchase_windows << create(:purchase_window, referential: referential)
+ state['purchase_windows'] = []
+ vehicle_journey.update_has_and_belongs_to_many_from_state(state)
+
+ expect(vehicle_journey.reload.purchase_windows).to be_empty
+ end
+
it 'should update vj footnote association from state' do
2.times{state['footnotes'] << create(:footnote, line: route.line).slice('id', 'code', 'label', 'line_id')}
vehicle_journey.update_has_and_belongs_to_many_from_state(state)
@@ -182,14 +409,24 @@ describe Chouette::VehicleJourney, :type => :model do
expect(vehicle_journey.reload.company_id).to eq state['company']['id']
end
+ it "handles vehicle journey company deletion" do
+ vehicle_journey.update(company: create(:company))
+ state.delete('company')
+ Chouette::VehicleJourney.state_update(route, collection)
+
+ expect(vehicle_journey.reload.company_id).to be_nil
+ end
+
it 'should update vj attributes from state' do
state['published_journey_name'] = 'edited_name'
state['published_journey_identifier'] = 'edited_identifier'
+ state['custom_fields'] = {energy: {value: 99}}
Chouette::VehicleJourney.state_update(route, collection)
expect(state['errors']).to be_nil
expect(vehicle_journey.reload.published_journey_name).to eq state['published_journey_name']
expect(vehicle_journey.reload.published_journey_identifier).to eq state['published_journey_identifier']
+ expect(vehicle_journey.reload.custom_field_value("energy")).to eq 99
end
it 'should return errors when validation failed' do
@@ -379,8 +616,7 @@ describe Chouette::VehicleJourney, :type => :model do
end
describe ".where_departure_time_between" do
- it "selects vehicle journeys whose departure times are between the
- specified range" do
+ it "selects vehicle journeys whose departure times are between the specified range" do
journey_early = create(
:vehicle_journey,
stop_departure_time: '02:00:00'
@@ -395,7 +631,7 @@ describe Chouette::VehicleJourney, :type => :model do
journey_pattern: journey_pattern,
stop_departure_time: '03:00:00'
)
- journey_late = create(
+ create(
:vehicle_journey,
route: route,
journey_pattern: journey_pattern,
diff --git a/spec/models/compliance_check_spec.rb b/spec/models/compliance_check_spec.rb
index f83d78c29..ffa59245c 100644
--- a/spec/models/compliance_check_spec.rb
+++ b/spec/models/compliance_check_spec.rb
@@ -15,4 +15,36 @@ RSpec.describe ComplianceCheck, type: :model do
it { should validate_presence_of :name }
it { should validate_presence_of :code }
it { should validate_presence_of :origin_code }
+
+ describe ".abort_old" do
+ it "changes check sets older than 4 hours to aborted" do
+ Timecop.freeze(Time.now) do
+ old_check_set = create(
+ :compliance_check_set,
+ status: 'pending',
+ created_at: 4.hours.ago - 1.minute
+ )
+ current_check_set = create(:compliance_check_set, status: 'pending')
+
+ ComplianceCheckSet.abort_old
+
+ expect(current_check_set.reload.status).to eq('pending')
+ expect(old_check_set.reload.status).to eq('aborted')
+ end
+ end
+
+ it "doesn't work on check sets with a `finished_status`" do
+ Timecop.freeze(Time.now) do
+ check_set = create(
+ :compliance_check_set,
+ status: 'successful',
+ created_at: 4.hours.ago - 1.minute
+ )
+
+ ComplianceCheckSet.abort_old
+
+ expect(check_set.reload.status).to eq('successful')
+ end
+ end
+ end
end
diff --git a/spec/models/compliance_control_class_level_defaults/generic_attribute_control/pattern_cccld_spec.rb b/spec/models/compliance_control_class_level_defaults/generic_attribute_control/pattern_cccld_spec.rb
index 9610cc796..90bb660ee 100644
--- a/spec/models/compliance_control_class_level_defaults/generic_attribute_control/pattern_cccld_spec.rb
+++ b/spec/models/compliance_control_class_level_defaults/generic_attribute_control/pattern_cccld_spec.rb
@@ -4,4 +4,7 @@ RSpec.describe GenericAttributeControl::Pattern, type: :model do
let( :factory ){ :generic_attribute_control_pattern }
it_behaves_like 'ComplianceControl Class Level Defaults'
+ it_behaves_like 'has target attribute'
+
+ it { should validate_presence_of(:pattern) }
end
diff --git a/spec/models/compliance_control_class_level_defaults/generic_attribute_control/uniqueness_cccld_spec.rb b/spec/models/compliance_control_class_level_defaults/generic_attribute_control/uniqueness_cccld_spec.rb
index e4ab8d2cd..c4874b5a2 100644
--- a/spec/models/compliance_control_class_level_defaults/generic_attribute_control/uniqueness_cccld_spec.rb
+++ b/spec/models/compliance_control_class_level_defaults/generic_attribute_control/uniqueness_cccld_spec.rb
@@ -4,4 +4,5 @@ RSpec.describe GenericAttributeControl::Uniqueness, type: :model do
let( :factory ){ :generic_attribute_control_uniqueness }
it_behaves_like 'ComplianceControl Class Level Defaults'
+ it_behaves_like 'has target attribute'
end
diff --git a/spec/models/compliance_control_spec.rb b/spec/models/compliance_control_spec.rb
index 4267459ea..5cffba58d 100644
--- a/spec/models/compliance_control_spec.rb
+++ b/spec/models/compliance_control_spec.rb
@@ -1,5 +1,15 @@
RSpec.describe ComplianceControl, type: :model do
+ context 'dynamic attributes' do
+ let(:compliance_control1) { build_stubbed :compliance_control }
+ let(:compliance_control2) { build_stubbed :compliance_control, type: 'VehicleJouneyControl::TimeTable' }
+
+ it 'should always return a array' do
+ expect(compliance_control1.class.dynamic_attributes).to be_kind_of Array
+ expect(compliance_control2.class.dynamic_attributes).to be_kind_of Array
+ end
+ end
+
context 'standard validation' do
let(:compliance_control) { build_stubbed :compliance_control }
diff --git a/spec/models/compliance_control_validations/genric_attribute_validation/min_max_validation_spec.rb b/spec/models/compliance_control_validations/genric_attribute_validation/min_max_validation_spec.rb
index 4d30d61e3..138f7aae1 100644
--- a/spec/models/compliance_control_validations/genric_attribute_validation/min_max_validation_spec.rb
+++ b/spec/models/compliance_control_validations/genric_attribute_validation/min_max_validation_spec.rb
@@ -4,5 +4,6 @@ RSpec.describe GenericAttributeControl::MinMax do
subject{ build factory }
it_behaves_like 'has min_max_values'
+ it_behaves_like 'has target attribute'
end
diff --git a/spec/models/custom_field_spec.rb b/spec/models/custom_field_spec.rb
new file mode 100644
index 000000000..51128b0a2
--- /dev/null
+++ b/spec/models/custom_field_spec.rb
@@ -0,0 +1,35 @@
+require 'rails_helper'
+
+RSpec.describe CustomField, type: :model do
+ let( :vj ){ create :vehicle_journey, custom_field_values: {energy: 99} }
+
+ context "validates" do
+ it { should validate_uniqueness_of(:name).scoped_to(:resource_type, :workgroup_id) }
+ it { should validate_uniqueness_of(:code).scoped_to(:resource_type, :workgroup_id).case_insensitive }
+ end
+
+ context "field access" do
+ let( :custom_field ){ build_stubbed :custom_field }
+
+ it "option's values can be accessed by a key" do
+ expect( custom_field.options['capacity'] ).to eq("0")
+ end
+ end
+
+
+ context "custom fields for a resource" do
+ let!( :fields ){ [create(:custom_field), create(:custom_field, code: :energy)] }
+ let!( :instance_fields ){
+ {
+ fields[0].code => fields[0].slice(:code, :name, :field_type, :options).update(value: nil),
+ "energy" => fields[1].slice(:code, :name, :field_type, :options).update(value: 99)
+ }
+ }
+ it { expect(Chouette::VehicleJourney.custom_fields).to eq(fields) }
+ it { expect(vj.custom_fields).to eq(instance_fields) }
+ end
+
+ context "custom field_values for a resource" do
+ it { expect(vj.custom_field_value("energy")).to eq(99) }
+ end
+end
diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb
index 3e4128865..8b85f151b 100644
--- a/spec/models/import_spec.rb
+++ b/spec/models/import_spec.rb
@@ -10,8 +10,9 @@ RSpec.describe Import, type: :model do
it { should validate_presence_of(:workbench) }
it { should validate_presence_of(:creator) }
- it { should allow_value('file.zip').for(:file).with_message(I18n.t('activerecord.errors.models.import.attributes.file.wrong_file_extension')) }
- it { should_not allow_values('file.json', 'file.png', 'file.pdf').for(:file) }
+ include ActionDispatch::TestProcess
+ it { should allow_value(fixture_file_upload('OFFRE_TRANSDEV_2017030112251.zip')).for(:file) }
+ it { should_not allow_value(fixture_file_upload('users.json')).for(:file).with_message(I18n.t('errors.messages.extension_whitelist_error', extension: '"json"', allowed_types: "zip")) }
let(:workbench_import) {netex_import.parent}
let(:workbench_import_with_completed_steps) do
@@ -28,6 +29,58 @@ RSpec.describe Import, type: :model do
)
end
+ describe ".abort_old" do
+ it "changes imports older than 4 hours to aborted" do
+ Timecop.freeze(Time.now) do
+ old_import = create(
+ :workbench_import,
+ status: 'pending',
+ created_at: 4.hours.ago - 1.minute
+ )
+ current_import = create(:workbench_import, status: 'pending')
+
+ Import.abort_old
+
+ expect(current_import.reload.status).to eq('pending')
+ expect(old_import.reload.status).to eq('aborted')
+ end
+ end
+
+ it "doesn't work on imports with a `finished_status`" do
+ Timecop.freeze(Time.now) do
+ import = create(
+ :workbench_import,
+ status: 'successful',
+ created_at: 4.hours.ago - 1.minute
+ )
+
+ Import.abort_old
+
+ expect(import.reload.status).to eq('successful')
+ end
+ end
+
+ it "only works on the caller type" do
+ Timecop.freeze(Time.now) do
+ workbench_import = create(
+ :workbench_import,
+ status: 'pending',
+ created_at: 4.hours.ago - 1.minute
+ )
+ netex_import = create(
+ :netex_import,
+ status: 'pending',
+ created_at: 4.hours.ago - 1.minute
+ )
+
+ NetexImport.abort_old
+
+ expect(workbench_import.reload.status).to eq('pending')
+ expect(netex_import.reload.status).to eq('aborted')
+ end
+ end
+ end
+
describe "#destroy" do
it "must destroy all child imports" do
netex_import = create(:netex_import)
diff --git a/spec/models/merge_spec.rb b/spec/models/merge_spec.rb
new file mode 100644
index 000000000..92f8f74b1
--- /dev/null
+++ b/spec/models/merge_spec.rb
@@ -0,0 +1,58 @@
+require "rails_helper"
+
+RSpec.describe Merge do
+
+ it "should work" do
+ stop_area_referential = FactoryGirl.create :stop_area_referential
+ 10.times { FactoryGirl.create :stop_area, stop_area_referential: stop_area_referential }
+
+ line_referential = FactoryGirl.create :line_referential
+ company = FactoryGirl.create :company, line_referential: line_referential
+ 10.times { FactoryGirl.create :line, line_referential: line_referential, company: company, network: nil }
+
+ workbench = FactoryGirl.create :workbench, line_referential: line_referential, stop_area_referential: stop_area_referential
+
+ referential_metadata = FactoryGirl.create(:referential_metadata, lines: line_referential.lines.limit(3))
+
+ referential = FactoryGirl.create :referential,
+ workbench: workbench,
+ organisation: workbench.organisation,
+ metadatas: [referential_metadata]
+
+ factor = 1
+
+ referential.switch do
+ line_referential.lines.each do |line|
+ factor.times do
+ stop_areas = stop_area_referential.stop_areas.order("random()").limit(5)
+ FactoryGirl.create :route, line: line, stop_areas: stop_areas, stop_points_count: 0
+ end
+ end
+
+ referential.routes.each do |route|
+ factor.times do
+ FactoryGirl.create :journey_pattern, route: route, stop_points: route.stop_points.sample(3)
+ end
+ end
+
+ referential.journey_patterns.each do |journey_pattern|
+ factor.times do
+ FactoryGirl.create :vehicle_journey, journey_pattern: journey_pattern, company: company
+ end
+ end
+
+ shared_time_table = FactoryGirl.create :time_table
+
+ referential.vehicle_journeys.each do |vehicle_journey|
+ vehicle_journey.time_tables << shared_time_table
+
+ specific_time_table = FactoryGirl.create :time_table
+ vehicle_journey.time_tables << specific_time_table
+ end
+ end
+
+ merge = Merge.create!(workbench: referential.workbench, referentials: [referential, referential])
+ merge.merge!
+ end
+
+end
diff --git a/spec/models/organisation_spec.rb b/spec/models/organisation_spec.rb
index 1217666f7..595b08058 100644
--- a/spec/models/organisation_spec.rb
+++ b/spec/models/organisation_spec.rb
@@ -2,8 +2,19 @@ describe Organisation, :type => :model do
it { should validate_presence_of(:name) }
it { should validate_uniqueness_of(:code) }
- it 'should have a valid factory' do
- expect(FactoryGirl.build(:organisation)).to be_valid
+ subject { build_stubbed :organisation }
+
+ it 'has a valid factory' do
+ expect_it.to be_valid
+ end
+
+ context 'lines_set' do
+ it 'has no lines' do
+ expect( subject.lines_set ).to eq(Set.new())
+ end
+ it 'has two lines' do
+ expect( build_stubbed(:org_with_lines).lines_set ).to eq(Set.new(%w{C00109 C00108}))
+ end
end
# it "create a rule_parameter_set" do
@@ -51,4 +62,26 @@ describe Organisation, :type => :model do
expect{Organisation.portail_sync}.to change{ Organisation.count }.by(4)
end
end
+
+ describe "#has_feature?" do
+
+ let(:organisation) { Organisation.new }
+
+ it 'return false if Organisation features is nil' do
+ organisation.features = nil
+ expect(organisation.has_feature?(:dummy)).to be_falsy
+ end
+
+ it 'return true if Organisation features contains given feature' do
+ organisation.features = %w{present}
+ expect(organisation.has_feature?(:present)).to be_truthy
+ end
+
+ it "return false if Organisation features doesn't contains given feature" do
+ organisation.features = %w{other}
+ expect(organisation.has_feature?(:absent)).to be_falsy
+ end
+
+ end
+
end
diff --git a/spec/models/referential/referential_lock_during_creation_spec.rb b/spec/models/referential/referential_lock_during_creation_spec.rb
new file mode 100644
index 000000000..717a96136
--- /dev/null
+++ b/spec/models/referential/referential_lock_during_creation_spec.rb
@@ -0,0 +1,198 @@
+RSpec.describe Referential, type: :model do
+ let (:workbench) { create(:workbench) }
+
+ def with_a_mutual_lock timeout: false
+ @with_a_mutual_lock = true
+ yield
+ thread_1 = Thread.new do
+ ActiveRecord::Base.transaction do
+ # seize LOCK
+ @locking_thread_content.try :call
+ sleep 10
+ # release LOCK
+ end
+ end
+
+ thread_2 = Thread.new do
+ sleep 5
+ ActiveRecord::Base.transaction do
+ if timeout
+ ActiveRecord::Base.connection.execute "SET lock_timeout = '1s'"
+ end
+ # waits for LOCK, (because of sleep 5)
+ @waiting_thread_content.try :call
+ # when lock was eventually obtained validation failed
+ end
+ end
+
+ thread_1.join
+ if timeout
+ expect do
+ thread_2.join
+ end.to raise_error(TableLockTimeoutError)
+ else
+ thread_2.join
+ end
+ @locking_thread_content = nil
+ @waiting_thread_content = nil
+ @with_a_mutual_lock = false
+ end
+
+ def locking_thread
+ raise "this method is intended to be called inside a `with_a_mutual_lock`" unless @with_a_mutual_lock
+ @locking_thread_content = yield
+ end
+
+ def waiting_thread
+ @waiting_thread_content = yield
+ end
+
+ context "when two identical Referentials are created, only one is saved" do
+ it "works synchronously" do
+ referential_1 = build(
+ :referential,
+ workbench: workbench,
+ organisation: workbench.organisation
+ )
+ referential_2 = referential_1.dup
+ referential_2.slug = "#{referential_1.slug}_different"
+
+ metadata_1 = build(:referential_metadata, referential: nil)
+ metadata_2 = metadata_1.dup
+
+ referential_1.metadatas << metadata_1
+ referential_2.metadatas << metadata_2
+
+ referential_1.save
+ referential_2.save
+
+ expect(referential_1).to be_persisted
+ expect(referential_2).not_to be_persisted
+ end
+
+ context truncation: true do
+ it "works asynchronously" do
+ skip('The truncation strategy breaks all subsequent tests (See #5295)')
+
+ begin
+ referential_1 = build(
+ :referential,
+ workbench: workbench,
+ organisation: workbench.organisation
+ )
+ referential_2 = referential_1.dup
+ referential_2.slug = "#{referential_1.slug}_different"
+ referential_3 = nil
+
+ metadata_1 = build(:referential_metadata, referential: nil)
+ metadata_2 = metadata_1.dup
+
+ referential_1.metadatas << metadata_1
+ referential_2.metadatas << metadata_2
+
+ with_a_mutual_lock do
+ locking_thread do
+ referential_1.save
+ end
+ waiting_thread do
+ referential_2.save
+ referential_3 = create(:referential)
+ end
+ end
+
+ expect(referential_1).to be_persisted
+ expect(referential_2).not_to be_persisted
+ expect(referential_3).to be_persisted
+ ensure
+ Apartment::Tenant.drop(referential_1.slug) if referential_1.persisted?
+ Apartment::Tenant.drop(referential_2.slug) if referential_2.persisted?
+
+ if referential_3.try(:persisted?)
+ Apartment::Tenant.drop(referential_3.slug)
+ end
+ end
+ end
+
+ it "works asynchronously when one is updated" do
+ skip('The truncation strategy breaks all subsequent tests (See #5295)')
+
+ begin
+ referential_1 = nil
+ referential_2 = nil
+
+ ActiveRecord::Base.transaction do
+ referential_1 = create(
+ :referential,
+ workbench: workbench,
+ organisation: workbench.organisation
+ )
+ referential_2 = referential_1.dup
+ referential_2.name = 'Another'
+ referential_2.slug = "#{referential_1.slug}_different"
+ referential_2.save!
+ end
+
+ metadata_2 = build(:referential_metadata, referential: nil)
+ metadata_1 = metadata_2.dup
+ with_a_mutual_lock do
+ locking_thread do
+ referential_1.metadatas_attributes = [metadata_1.attributes]
+ referential_1.save
+ end
+ waiting_thread do
+ referential_2.metadatas_attributes = [metadata_2.attributes]
+ referential_2.save
+ end
+ end
+
+ expect(referential_1).to be_valid
+ expect(referential_2).not_to be_valid
+ ensure
+ Apartment::Tenant.drop(referential_1.slug) if referential_1.persisted?
+ Apartment::Tenant.drop(referential_2.slug) if referential_2.persisted?
+ end
+ end
+ end
+ end
+
+ context "when two Referentials are created at the same time", truncation: true do
+ it "raises an error when the DB lock timeout is reached" do
+ skip('The truncation strategy breaks all subsequent tests (See #5295)')
+
+ begin
+ referential_1 = build(
+ :referential,
+ workbench: workbench,
+ organisation: workbench.organisation
+ )
+ referential_2 = referential_1.dup
+ referential_2.slug = "#{referential_1.slug}_different"
+ referential_3 = nil
+
+ metadata_1 = build(:referential_metadata, referential: nil)
+ metadata_2 = metadata_1.dup
+
+ referential_1.metadatas << metadata_1
+ referential_2.metadatas << metadata_2
+ with_a_mutual_lock timeout: true do
+ locking_thread do
+ referential_1.save
+ end
+ waiting_thread do
+ referential_2.save
+ referential_3 = create(:referential)
+ end
+ end
+
+ expect(referential_1).to be_persisted
+ ensure
+ Apartment::Tenant.drop(referential_1.slug) if referential_1.persisted?
+ Apartment::Tenant.drop(referential_2.slug) if referential_2.persisted?
+
+ if referential_3.try(:persisted?)
+ Apartment::Tenant.drop(referential_3.slug)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/referential_cloning_spec.rb b/spec/models/referential_cloning_spec.rb
index 5acd433ec..815e05a67 100644
--- a/spec/models/referential_cloning_spec.rb
+++ b/spec/models/referential_cloning_spec.rb
@@ -1,6 +1,7 @@
require 'spec_helper'
RSpec.describe ReferentialCloning, :type => :model do
+
it 'should have a valid factory' do
expect(FactoryGirl.build(:referential_cloning)).to be_valid
end
@@ -8,11 +9,79 @@ RSpec.describe ReferentialCloning, :type => :model do
it { should belong_to :source_referential }
it { should belong_to :target_referential }
- describe "ReferentialCloningWorker" do
+ describe 'after commit' do
+ let(:referential_cloning) { FactoryGirl.create(:referential_cloning) }
+
+ it 'invoke clone method' do
+ expect(referential_cloning).to receive(:clone)
+ referential_cloning.run_callbacks(:commit)
+ end
+ end
+
+ describe '#clone' 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)
+ expect{referential_cloning.clone}.to change {ReferentialCloningWorker.jobs.count}.by(1)
end
end
+
+ describe '#clone!' do
+ let(:source_referential) { Referential.new slug: "source"}
+ let(:target_referential) { Referential.new slug: "target"}
+ let(:referential_cloning) do
+ ReferentialCloning.new source_referential: source_referential,
+ target_referential: target_referential
+ end
+
+ let(:cloner) { double }
+
+ it 'creates a schema cloner with source and target schemas and clone schema' do
+ expect(AF83::SchemaCloner).to receive(:new).with(source_referential.slug, target_referential.slug).and_return(cloner)
+ expect(cloner).to receive(:clone_schema)
+
+ referential_cloning.clone!
+ end
+ end
+
+ describe '#clone_with_status!' do
+ let(:referential_cloning) do
+ ReferentialCloning.new(target_referential: Referential.new(slug: "target"))
+ end
+
+ before do
+ allow(referential_cloning).to receive(:clone!)
+ end
+
+ it 'invokes clone! method' do
+ expect(referential_cloning).to receive(:clone!)
+ referential_cloning.clone_with_status!
+ end
+
+ context 'when clone_schema is performed without error' do
+ it "should have successful status" do
+ referential_cloning.clone_with_status!
+ expect(referential_cloning.status).to eq("successful")
+ end
+ end
+
+ context 'when clone_schema raises an error' do
+ it "should have failed status" do
+ expect(referential_cloning).to receive(:clone!).and_raise("#fail")
+ referential_cloning.clone_with_status!
+ expect(referential_cloning.status).to eq("failed")
+ end
+ end
+
+ it "defines started_at" do
+ referential_cloning.clone_with_status!
+ expect(referential_cloning.started_at).not_to be_nil
+ end
+
+ it "defines ended_at" do
+ referential_cloning.clone_with_status!
+ expect(referential_cloning.ended_at).not_to be_nil
+ end
+
+ end
end
diff --git a/spec/models/referential_spec.rb b/spec/models/referential_spec.rb
index d0b1d6447..6d699f759 100644
--- a/spec/models/referential_spec.rb
+++ b/spec/models/referential_spec.rb
@@ -1,13 +1,6 @@
-require 'spec_helper'
-
describe Referential, :type => :model do
let(:ref) { create :workbench_referential, metadatas: [create(:referential_metadata)] }
- # it "create a rule_parameter_set" do
- # referential = create(:referential)
- # expect(referential.rule_parameter_sets.size).to eq(1)
- # end
-
it { should have_many(:metadatas) }
it { should belong_to(:workbench) }
it { should belong_to(:referential_suite) }
@@ -131,4 +124,40 @@ describe Referential, :type => :model do
end
end
end
+
+ context "to be referential_read_only or not to be referential_read_only" do
+ let( :referential ){ build_stubbed( :referential ) }
+
+ context "in the beginning" do
+ it{ expect( referential ).not_to be_referential_read_only }
+ end
+
+ context "after archivation" do
+ before{ referential.archived_at = 1.day.ago }
+ it{ expect( referential ).to be_referential_read_only }
+ end
+
+ context "used in a ReferentialSuite" do
+ before { referential.referential_suite_id = 42 }
+
+ it{ expect( referential ).to be_referential_read_only }
+
+ it "return true to in_referential_suite?" do
+ expect(referential).to be_in_referential_suite
+ end
+
+ it "don't use detect_overlapped_referentials in validation" do
+ expect(referential).to_not receive(:detect_overlapped_referentials)
+ expect(referential).to be_valid
+ end
+ end
+
+ context "archived and finalised" do
+ before do
+ referential.archived_at = 1.month.ago
+ referential.referential_suite_id = 53
+ end
+ it{ expect( referential ).to be_referential_read_only }
+ end
+ end
end
diff --git a/spec/models/workbench_spec.rb b/spec/models/workbench_spec.rb
index 3b9ed6b07..2f1fe39da 100644
--- a/spec/models/workbench_spec.rb
+++ b/spec/models/workbench_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe Workbench, :type => :model do
it { should belong_to(:organisation) }
it { should belong_to(:line_referential) }
it { should belong_to(:stop_area_referential) }
+ it { should belong_to(:workgroup) }
it { should belong_to(:output).class_name('ReferentialSuite') }
it { should have_many(:lines).through(:line_referential) }
@@ -36,7 +37,7 @@ RSpec.describe Workbench, :type => :model do
let(:workbench) { create :workbench, organisation: organisation }
it 'should filter lines based on my organisation functional_scope' do
- ids.insert('STIF:CODIFLIGNE:Line:0000').each do |id|
+ (ids + ['STIF:CODIFLIGNE:Line:0000']).each do |id|
create :line, objectid: id, line_referential: workbench.line_referential
end
lines = workbench.lines
diff --git a/spec/models/workgroup_spec.rb b/spec/models/workgroup_spec.rb
new file mode 100644
index 000000000..ac8d3fc98
--- /dev/null
+++ b/spec/models/workgroup_spec.rb
@@ -0,0 +1,30 @@
+require 'rails_helper'
+
+RSpec.describe Workgroup, type: :model do
+ context "associations" do
+ let( :workgroup ){ build_stubbed :workgroup, line_referential_id: 53, stop_area_referential_id: 42 }
+
+ it{ should have_many(:workbenches) }
+ it{ should validate_uniqueness_of(:name) }
+
+ it 'is not valid without a stop_area_referential' do
+ workgroup.stop_area_referential_id = nil
+ expect( workgroup ).not_to be_valid
+ end
+ it 'is not valid without a line_referential' do
+ workgroup.line_referential_id = nil
+ expect( workgroup ).not_to be_valid
+ end
+ it 'is valid with both assoications' do
+ expect( workgroup ).to be_valid
+ end
+ end
+
+ context "find organisations" do
+ let( :workgroup ){ create :workgroup }
+ let!( :workbench1 ){ create :workbench, workgroup: workgroup }
+ let!( :workbench2 ){ create :workbench, workgroup: workgroup }
+
+ it{ expect( Set.new(workgroup.organisations) ).to eq(Set.new([ workbench1.organisation, workbench2.organisation ])) }
+ end
+end
diff --git a/spec/policies/access_link_policy_spec.rb b/spec/policies/access_link_policy_spec.rb
index 6194ae55c..9ba3ffa45 100644
--- a/spec/policies/access_link_policy_spec.rb
+++ b/spec/policies/access_link_policy_spec.rb
@@ -3,18 +3,18 @@ RSpec.describe AccessLinkPolicy, type: :policy do
let( :record ){ build_stubbed :access_link }
permissions :create? do
- it_behaves_like 'permitted policy and same organisation', "access_links.create", archived: true
+ it_behaves_like 'permitted policy and same organisation', "access_links.create", archived_and_finalised: true
end
permissions :destroy? do
- it_behaves_like 'permitted policy and same organisation', "access_links.destroy", archived: true
+ it_behaves_like 'permitted policy and same organisation', "access_links.destroy", archived_and_finalised: true
end
permissions :edit? do
- it_behaves_like 'permitted policy and same organisation', "access_links.update", archived: true
+ it_behaves_like 'permitted policy and same organisation', "access_links.update", archived_and_finalised: true
end
permissions :new? do
- it_behaves_like 'permitted policy and same organisation', "access_links.create", archived: true
+ it_behaves_like 'permitted policy and same organisation', "access_links.create", archived_and_finalised: true
end
permissions :update? do
- it_behaves_like 'permitted policy and same organisation', "access_links.update", archived: true
+ it_behaves_like 'permitted policy and same organisation', "access_links.update", archived_and_finalised: true
end
end
diff --git a/spec/policies/access_point_policy_spec.rb b/spec/policies/access_point_policy_spec.rb
index b6bc46eb4..ec7bf1486 100644
--- a/spec/policies/access_point_policy_spec.rb
+++ b/spec/policies/access_point_policy_spec.rb
@@ -3,18 +3,18 @@ RSpec.describe AccessPointPolicy, type: :policy do
let( :record ){ build_stubbed :access_point }
permissions :create? do
- it_behaves_like 'permitted policy and same organisation', "access_points.create", archived: true
+ it_behaves_like 'permitted policy and same organisation', "access_points.create", archived_and_finalised: true
end
permissions :destroy? do
- it_behaves_like 'permitted policy and same organisation', "access_points.destroy", archived: true
+ it_behaves_like 'permitted policy and same organisation', "access_points.destroy", archived_and_finalised: true
end
permissions :edit? do
- it_behaves_like 'permitted policy and same organisation', "access_points.update", archived: true
+ it_behaves_like 'permitted policy and same organisation', "access_points.update", archived_and_finalised: true
end
permissions :new? do
- it_behaves_like 'permitted policy and same organisation', "access_points.create", archived: true
+ it_behaves_like 'permitted policy and same organisation', "access_points.create", archived_and_finalised: true
end
permissions :update? do
- it_behaves_like 'permitted policy and same organisation', "access_points.update", archived: true
+ it_behaves_like 'permitted policy and same organisation', "access_points.update", archived_and_finalised: true
end
end
diff --git a/spec/policies/calendar_policy_spec.rb b/spec/policies/calendar_policy_spec.rb
index 294be8198..144a1c6bb 100644
--- a/spec/policies/calendar_policy_spec.rb
+++ b/spec/policies/calendar_policy_spec.rb
@@ -5,18 +5,24 @@ RSpec.describe CalendarPolicy, type: :policy do
permissions :create? do
- it_behaves_like 'permitted policy', 'calendars.create', archived: true
+ it_behaves_like 'permitted policy', 'calendars.create'
+ end
+ permissions :share? do
+ it_behaves_like 'permitted policy and same organisation', 'calendars.share'
+ end
+ permissions :share? do
+ it_behaves_like 'permitted policy and same organisation', 'calendars.share'
end
permissions :destroy? do
- it_behaves_like 'permitted policy and same organisation', 'calendars.destroy', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'calendars.destroy'
end
permissions :edit? do
- it_behaves_like 'permitted policy and same organisation', 'calendars.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'calendars.update'
end
permissions :new? do
- it_behaves_like 'permitted policy', 'calendars.create', archived: true
+ it_behaves_like 'permitted policy', 'calendars.create'
end
permissions :update? do
- it_behaves_like 'permitted policy and same organisation', 'calendars.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'calendars.update'
end
end
diff --git a/spec/policies/company_policy_spec.rb b/spec/policies/company_policy_spec.rb
index e018902ca..16225c441 100644
--- a/spec/policies/company_policy_spec.rb
+++ b/spec/policies/company_policy_spec.rb
@@ -1,4 +1,3 @@
-# coding: utf-8
RSpec.describe CompanyPolicy, type: :policy do
let( :record ){ build_stubbed :company }
@@ -11,10 +10,10 @@ RSpec.describe CompanyPolicy, type: :policy do
context 'Non Destructive actions →' do
permissions :index? do
- it_behaves_like 'always allowed', 'anything', archived: true
+ it_behaves_like 'always allowed', 'anything', archived_and_finalised: true
end
permissions :show? do
- it_behaves_like 'always allowed', 'anything', archived: true
+ it_behaves_like 'always allowed', 'anything', archived_and_finalised: true
end
end
diff --git a/spec/policies/connection_link_policy_spec.rb b/spec/policies/connection_link_policy_spec.rb
index 23e40abe3..6fc9f95df 100644
--- a/spec/policies/connection_link_policy_spec.rb
+++ b/spec/policies/connection_link_policy_spec.rb
@@ -3,18 +3,18 @@ RSpec.describe ConnectionLinkPolicy, type: :policy do
let( :record ){ build_stubbed :connection_link }
permissions :create? do
- it_behaves_like 'permitted policy and same organisation', "connection_links.create", archived: true
+ it_behaves_like 'permitted policy and same organisation', "connection_links.create", archived_and_finalised: true
end
permissions :destroy? do
- it_behaves_like 'permitted policy and same organisation', "connection_links.destroy", archived: true
+ it_behaves_like 'permitted policy and same organisation', "connection_links.destroy", archived_and_finalised: true
end
permissions :edit? do
- it_behaves_like 'permitted policy and same organisation', "connection_links.update", archived: true
+ it_behaves_like 'permitted policy and same organisation', "connection_links.update", archived_and_finalised: true
end
permissions :new? do
- it_behaves_like 'permitted policy and same organisation', "connection_links.create", archived: true
+ it_behaves_like 'permitted policy and same organisation', "connection_links.create", archived_and_finalised: true
end
permissions :update? do
- it_behaves_like 'permitted policy and same organisation', "connection_links.update", archived: true
+ it_behaves_like 'permitted policy and same organisation', "connection_links.update", archived_and_finalised: true
end
end
diff --git a/spec/policies/group_of_line_policy_spec.rb b/spec/policies/group_of_line_policy_spec.rb
index 29fbb1bfb..0aeab97bd 100644
--- a/spec/policies/group_of_line_policy_spec.rb
+++ b/spec/policies/group_of_line_policy_spec.rb
@@ -10,10 +10,10 @@ RSpec.describe GroupOfLinePolicy, type: :policy do
context 'Non Destructive actions →' do
permissions :index? do
- it_behaves_like 'always allowed', 'anything', archived: true
+ it_behaves_like 'always allowed', 'anything', archived_and_finalised: true
end
permissions :show? do
- it_behaves_like 'always allowed', 'anything', archived: true
+ it_behaves_like 'always allowed', 'anything', archived_and_finalised: true
end
end
@@ -24,19 +24,19 @@ RSpec.describe GroupOfLinePolicy, type: :policy do
context 'Destructive actions →' do
permissions :create? do
- it_behaves_like 'always forbidden', 'group_of_lines.create', archived: true
+ it_behaves_like 'always forbidden', 'group_of_lines.create', archived_and_finalised: true
end
permissions :destroy? do
- it_behaves_like 'always forbidden', 'group_of_lines.destroy', archived: true
+ it_behaves_like 'always forbidden', 'group_of_lines.destroy', archived_and_finalised: true
end
permissions :edit? do
- it_behaves_like 'always forbidden', 'group_of_lines.update', archived: true
+ it_behaves_like 'always forbidden', 'group_of_lines.update', archived_and_finalised: true
end
permissions :new? do
- it_behaves_like 'always forbidden', 'group_of_lines.create', archived: true
+ it_behaves_like 'always forbidden', 'group_of_lines.create', archived_and_finalised: true
end
permissions :update? do
- it_behaves_like 'always forbidden', 'group_of_lines.update', archived: true
+ it_behaves_like 'always forbidden', 'group_of_lines.update', archived_and_finalised: true
end
end
end
diff --git a/spec/policies/journey_pattern_policy_spec.rb b/spec/policies/journey_pattern_policy_spec.rb
index 39f849277..b5e72d813 100644
--- a/spec/policies/journey_pattern_policy_spec.rb
+++ b/spec/policies/journey_pattern_policy_spec.rb
@@ -3,18 +3,18 @@ RSpec.describe JourneyPatternPolicy, type: :policy do
let( :record ){ build_stubbed :journey_pattern }
permissions :create? do
- it_behaves_like 'permitted policy and same organisation', "journey_patterns.create", archived: true
+ it_behaves_like 'permitted policy and same organisation', "journey_patterns.create", archived_and_finalised: true
end
permissions :destroy? do
- it_behaves_like 'permitted policy and same organisation', "journey_patterns.destroy", archived: true
+ it_behaves_like 'permitted policy and same organisation', "journey_patterns.destroy", archived_and_finalised: true
end
permissions :edit? do
- it_behaves_like 'permitted policy and same organisation', "journey_patterns.update", archived: true
+ it_behaves_like 'permitted policy and same organisation', "journey_patterns.update", archived_and_finalised: true
end
permissions :new? do
- it_behaves_like 'permitted policy and same organisation', "journey_patterns.create", archived: true
+ it_behaves_like 'permitted policy and same organisation', "journey_patterns.create", archived_and_finalised: true
end
permissions :update? do
- it_behaves_like 'permitted policy and same organisation', "journey_patterns.update", archived: true
+ it_behaves_like 'permitted policy and same organisation', "journey_patterns.update", archived_and_finalised: true
end
end
diff --git a/spec/policies/line_policy_spec.rb b/spec/policies/line_policy_spec.rb
index 452606bcf..555008abf 100644
--- a/spec/policies/line_policy_spec.rb
+++ b/spec/policies/line_policy_spec.rb
@@ -1,4 +1,3 @@
-# coding: utf-8
RSpec.describe LinePolicy, type: :policy do
let( :record ){ build_stubbed :line }
@@ -11,10 +10,10 @@ RSpec.describe LinePolicy, type: :policy do
context 'Non Destructive actions →' do
permissions :index? do
- it_behaves_like 'always allowed', 'anything', archived: true
+ it_behaves_like 'always allowed', 'anything', archived_and_finalised: true
end
permissions :show? do
- it_behaves_like 'always allowed', 'anything', archived: true
+ it_behaves_like 'always allowed', 'anything', archived_and_finalised: true
end
end
@@ -47,14 +46,14 @@ RSpec.describe LinePolicy, type: :policy do
# ---------------------------
permissions :create_footnote? do
- it_behaves_like 'permitted policy and same organisation', 'footnotes.create', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'footnotes.create', archived_and_finalised: true
end
permissions :destroy_footnote? do
- it_behaves_like 'permitted policy and same organisation', 'footnotes.destroy', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'footnotes.destroy', archived_and_finalised: true
end
permissions :update_footnote? do
- it_behaves_like 'permitted policy and same organisation', 'footnotes.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'footnotes.update', archived_and_finalised: true
end
end
diff --git a/spec/policies/line_referential_policy_spec.rb b/spec/policies/line_referential_policy_spec.rb
new file mode 100644
index 000000000..7e0a9da8e
--- /dev/null
+++ b/spec/policies/line_referential_policy_spec.rb
@@ -0,0 +1,9 @@
+RSpec.describe LineReferentialPolicy, type: :policy do
+
+ let( :record ){ build_stubbed :line_referential }
+ before { stub_policy_scope(record) }
+
+ permissions :synchronize? do
+ it_behaves_like 'permitted policy', 'line_referentials.synchronize'
+ end
+end
diff --git a/spec/policies/network_policy_spec.rb b/spec/policies/network_policy_spec.rb
index c09546c22..2b7bbcdca 100644
--- a/spec/policies/network_policy_spec.rb
+++ b/spec/policies/network_policy_spec.rb
@@ -10,10 +10,10 @@ RSpec.describe Chouette::NetworkPolicy, type: :policy do
context 'Non Destructive actions →' do
permissions :index? do
- it_behaves_like 'always allowed', 'anything', archived: true
+ it_behaves_like 'always allowed', 'anything', archived_and_finalised: true
end
permissions :show? do
- it_behaves_like 'always allowed', 'anything', archived: true
+ it_behaves_like 'always allowed', 'anything', archived_and_finalised: true
end
end
@@ -24,19 +24,19 @@ RSpec.describe Chouette::NetworkPolicy, type: :policy do
context 'Destructive actions →' do
permissions :create? do
- it_behaves_like 'always forbidden', 'networks.create', archived: true
+ it_behaves_like 'permitted policy', 'networks.create'
end
permissions :destroy? do
- it_behaves_like 'always forbidden', 'networks.destroy', archived: true
+ it_behaves_like 'permitted policy', 'networks.destroy'
end
permissions :edit? do
- it_behaves_like 'always forbidden', 'networks.update', archived: true
+ it_behaves_like 'permitted policy', 'networks.update'
end
permissions :new? do
- it_behaves_like 'always forbidden', 'networks.create', archived: true
+ it_behaves_like 'permitted policy', 'networks.create'
end
permissions :update? do
- it_behaves_like 'always forbidden', 'networks.update', archived: true
+ it_behaves_like 'permitted policy', 'networks.update'
end
end
end
diff --git a/spec/policies/purchase_window_policy_spec.rb b/spec/policies/purchase_window_policy_spec.rb
new file mode 100644
index 000000000..184152cec
--- /dev/null
+++ b/spec/policies/purchase_window_policy_spec.rb
@@ -0,0 +1,15 @@
+RSpec.describe PurchaseWindowPolicy, type: :policy do
+
+ let( :record ){ build_stubbed :purchase_window }
+ before { stub_policy_scope(record) }
+
+ permissions :create? do
+ it_behaves_like 'permitted policy and same organisation', "purchase_windows.create", archived_and_finalised: true
+ end
+ permissions :destroy? do
+ it_behaves_like 'permitted policy and same organisation', "purchase_windows.destroy", archived_and_finalised: true
+ end
+ permissions :update? do
+ it_behaves_like 'permitted policy and same organisation', "purchase_windows.update", archived_and_finalised: true
+ end
+end
diff --git a/spec/policies/referential_policy_spec.rb b/spec/policies/referential_policy_spec.rb
index d00415fc6..778e14901 100644
--- a/spec/policies/referential_policy_spec.rb
+++ b/spec/policies/referential_policy_spec.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
RSpec.describe ReferentialPolicy, type: :policy do
let( :record ){ build_stubbed :referential }
@@ -32,22 +33,22 @@ RSpec.describe ReferentialPolicy, type: :policy do
# ---------------------------------------
permissions :destroy? do
- it_behaves_like 'permitted policy and same organisation', 'referentials.destroy', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'referentials.destroy', archived_and_finalised: true
end
permissions :edit? do
- it_behaves_like 'permitted policy and same organisation', 'referentials.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'referentials.update', archived_and_finalised: true
end
permissions :update? do
- it_behaves_like 'permitted policy and same organisation', 'referentials.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'referentials.update', archived_and_finalised: true
end
#
# Custom Permissions
# ------------------
- permissions :clone? do
- it_behaves_like 'permitted policy', 'referentials.create', archived: true
- end
+ # permissions :clone? do
+ # it_behaves_like 'permitted policy', 'referentials.create', archived_and_finalised: true
+ # end
permissions :archive? do
diff --git a/spec/policies/route_policy_spec.rb b/spec/policies/route_policy_spec.rb
index df2e41a89..5dc8be76f 100644
--- a/spec/policies/route_policy_spec.rb
+++ b/spec/policies/route_policy_spec.rb
@@ -3,26 +3,26 @@ RSpec.describe Chouette::RoutePolicy, type: :policy do
let( :record ){ build_stubbed :route }
permissions :create? do
- it_behaves_like 'permitted policy and same organisation', 'routes.create', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'routes.create', archived_and_finalised: true
end
permissions :duplicate? do
- it_behaves_like 'permitted policy and same organisation', 'routes.create', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'routes.create', archived_and_finalised: true
end
permissions :destroy? do
- it_behaves_like 'permitted policy and same organisation', 'routes.destroy', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'routes.destroy', archived_and_finalised: true
end
permissions :edit? do
- it_behaves_like 'permitted policy and same organisation', 'routes.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'routes.update', archived_and_finalised: true
end
permissions :new? do
- it_behaves_like 'permitted policy and same organisation', 'routes.create', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'routes.create', archived_and_finalised: true
end
permissions :update? do
- it_behaves_like 'permitted policy and same organisation', 'routes.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'routes.update', archived_and_finalised: true
end
end
diff --git a/spec/policies/routing_constraint_zone_policy_spec.rb b/spec/policies/routing_constraint_zone_policy_spec.rb
index 2ef15fa95..d619649d3 100644
--- a/spec/policies/routing_constraint_zone_policy_spec.rb
+++ b/spec/policies/routing_constraint_zone_policy_spec.rb
@@ -4,22 +4,22 @@ RSpec.describe RoutingConstraintZonePolicy, type: :policy do
permissions :create? do
- it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.create', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.create', archived_and_finalised: true
end
permissions :destroy? do
- it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.destroy', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.destroy', archived_and_finalised: true
end
permissions :edit? do
- it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.update', archived_and_finalised: true
end
permissions :new? do
- it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.create', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.create', archived_and_finalised: true
end
permissions :update? do
- it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.update', archived_and_finalised: true
end
end
diff --git a/spec/policies/sto_area_referential_policy_spec.rb b/spec/policies/sto_area_referential_policy_spec.rb
new file mode 100644
index 000000000..5bd6da427
--- /dev/null
+++ b/spec/policies/sto_area_referential_policy_spec.rb
@@ -0,0 +1,9 @@
+RSpec.describe StopAreaReferentialPolicy, type: :policy do
+
+ let( :record ){ build_stubbed :stop_area_referential }
+ before { stub_policy_scope(record) }
+
+ permissions :synchronize? do
+ it_behaves_like 'permitted policy', 'stop_area_referentials.synchronize'
+ end
+end
diff --git a/spec/policies/stop_area_policy_spec.rb b/spec/policies/stop_area_policy_spec.rb
index 90835d1d8..8144c16e2 100644
--- a/spec/policies/stop_area_policy_spec.rb
+++ b/spec/policies/stop_area_policy_spec.rb
@@ -11,10 +11,10 @@ RSpec.describe StopAreaPolicy, type: :policy do
context 'Non Destructive actions →' do
permissions :index? do
- it_behaves_like 'always allowed', 'anything', archived: true
+ it_behaves_like 'always allowed', 'anything', archived_and_finalised: true
end
permissions :show? do
- it_behaves_like 'always allowed', 'anything', archived: true
+ it_behaves_like 'always allowed', 'anything', archived_and_finalised: true
end
end
diff --git a/spec/policies/time_table_policy_spec.rb b/spec/policies/time_table_policy_spec.rb
index dad3c13bc..5a2abc61d 100644
--- a/spec/policies/time_table_policy_spec.rb
+++ b/spec/policies/time_table_policy_spec.rb
@@ -3,22 +3,22 @@ RSpec.describe TimeTablePolicy, type: :policy do
let( :record ){ build_stubbed :time_table }
permissions :create? do
- it_behaves_like 'permitted policy and same organisation', 'time_tables.create', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'time_tables.create', archived_and_finalised: true
end
permissions :destroy? do
- it_behaves_like 'permitted policy and same organisation', 'time_tables.destroy', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'time_tables.destroy', archived_and_finalised: true
end
permissions :edit? do
- it_behaves_like 'permitted policy and same organisation', 'time_tables.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'time_tables.update', archived_and_finalised: true
end
permissions :new? do
- it_behaves_like 'permitted policy and same organisation', 'time_tables.create', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'time_tables.create', archived_and_finalised: true
end
permissions :update? do
- it_behaves_like 'permitted policy and same organisation', 'time_tables.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'time_tables.update', archived_and_finalised: true
end
end
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index 47578405e..9eb628d95 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -32,11 +32,6 @@ RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
- # If you're not using ActiveRecord, or you'd prefer not to run each of your
- # examples within a transaction, remove the following line or assign false
- # instead of true.
- config.use_transactional_fixtures = true
-
# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
diff --git a/spec/requests/api/v1/netex_import_spec.rb b/spec/requests/api/v1/netex_import_spec.rb
index a90e51e5b..8597c1d32 100644
--- a/spec/requests/api/v1/netex_import_spec.rb
+++ b/spec/requests/api/v1/netex_import_spec.rb
@@ -32,18 +32,18 @@ RSpec.describe "NetexImport", type: :request do
let( :authorization ){ authorization_token_header( get_api_key.token ) }
#TODO Check why referential_id is nil
it 'succeeds' do
- skip "Problem with referential_id" do
- create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00108', line_referential: workbench.line_referential)
- create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00109', line_referential: workbench.line_referential)
-
- post_request.(netex_import: legal_attributes)
- expect( response ).to be_success
- expect( json_response_body ).to eq(
- 'id' => NetexImport.last.id,
- 'referential_id' => Referential.last.id,
- 'workbench_id' => workbench.id
- )
- end
+ # skip "Problem with referential_id" do
+ create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00108', line_referential: workbench.line_referential)
+ create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00109', line_referential: workbench.line_referential)
+
+ post_request.(netex_import: legal_attributes)
+ expect( response ).to be_success
+ expect( json_response_body ).to eq(
+ 'id' => NetexImport.last.id,
+ 'referential_id' => Referential.last.id,
+ 'workbench_id' => workbench.id
+ )
+ # end
end
@@ -54,24 +54,21 @@ RSpec.describe "NetexImport", type: :request do
expect{ post_request.(netex_import: legal_attributes) }.to change{NetexImport.count}.by(1)
end
- #TODO Check why Referential count does not change
- it 'creates a correct Referential' do
- skip "Referential count does not change" do
- create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00108', line_referential: workbench.line_referential)
- create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00109', line_referential: workbench.line_referential)
-
- legal_attributes # force object creation for correct to change behavior
- expect{post_request.(netex_import: legal_attributes)}.to change{Referential.count}.by(1)
- Referential.last.tap do | ref |
- expect( ref.workbench_id ).to eq(workbench.id)
- expect( ref.organisation_id ).to eq(workbench.organisation_id)
- end
+ it 'creates a correct Referential', pending: 'see #5073' do
+ create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00108', line_referential: workbench.line_referential)
+ create(:line, objectid: 'STIF:CODIFLIGNE:Line:C00109', line_referential: workbench.line_referential)
+
+ legal_attributes # force object creation for correct to change behavior
+ expect{post_request.(netex_import: legal_attributes)}.to change{Referential.count}.by(1)
+ Referential.last.tap do | ref |
+ expect( ref.workbench_id ).to eq(workbench.id)
+ expect( ref.organisation_id ).to eq(workbench.organisation_id)
end
end
end
- context 'with incorrect credentials and correct request', pending: "see #4311" do
+ context 'with incorrect credentials and correct request', pending: "see #4311 & #5072" do
let( :authorization ){ authorization_token_header( "#{referential.id}-incorrect_token") }
it 'does not create any DB object and does not succeed' do
diff --git a/spec/services/meta_zip_data_spec.rb b/spec/services/meta_zip_data_spec.rb
new file mode 100644
index 000000000..1cbfee008
--- /dev/null
+++ b/spec/services/meta_zip_data_spec.rb
@@ -0,0 +1,55 @@
+# Convenience meta spec to debug potential bugs in zip support helpers
+# uncomment run and check files in `zip_fixtures_path`
+#
+# It also describes what the two helpers do and therefore facilitates the usage of
+#
+# * `make_zip` and
+# * `make_zip_from_tree
+#
+RSpec.describe 'ZipData', type: [:zip, :meta] do
+
+ # let( :zip_file ){ zip_fixtures_path('xxx.zip') }
+ # let( :tmp_output ){ zip_fixtures_path('tmp') }
+
+ # before do
+ # clear_all_zip_fixtures!
+ # Dir.mkdir(tmp_output)
+ # end
+
+ # context 'a simple archive' do
+ # let( :zip_data ){ make_zip "xxx.zip", archive_content }
+ # let( :archive_content ){ {
+ # 'hello.txt' => 'hello',
+ # 'subdir/too.txt' => 'in a subdir'
+ # } }
+
+ # it 'handmade: plausibility and manual check' do
+ # zip_data.write_to(zip_file)
+ # %x{unzip -oqq #{zip_file} -d #{tmp_output}}
+ # archive_content.each do | rel_path, content |
+ # expect(File.read(File.join(tmp_output, rel_path))).to eq(content)
+ # end
+ # end
+ # end
+
+ # context 'archive from dir tree' do
+ # let( :dir ){ fixtures_path 'meta_zip' }
+ # let( :zip_data ){ make_zip_from_tree dir }
+
+ # let( :archive_content ){ {
+ # 'one/alpha' => "alpha\n",
+ # 'two/beta' => "beta\n",
+ # 'two/subdir/gamma' => "gamma\n"
+ # } }
+
+ # it 'directory: plausibility and manual check' do
+ # zip_data.write_to(zip_file)
+ # %x{unzip -oqq #{zip_file} -d #{tmp_output}}
+ # archive_content.each do | rel_path, content |
+ # expect(File.read(File.join(tmp_output, rel_path))).to eq(content)
+ # end
+ # end
+
+ # end
+
+end
diff --git a/spec/services/parent_import_notifier_spec.rb b/spec/services/parent_notifier_spec.rb
index 3ab505f88..ecf508fcd 100644
--- a/spec/services/parent_import_notifier_spec.rb
+++ b/spec/services/parent_notifier_spec.rb
@@ -1,4 +1,4 @@
-RSpec.describe ParentImportNotifier do
+RSpec.describe ParentNotifier do
let(:workbench_import) { create(:workbench_import) }
describe ".notify_when_finished" do
@@ -20,7 +20,7 @@ RSpec.describe ParentImportNotifier do
expect(netex_import).to receive(:notify_parent)
end
- ParentImportNotifier.notify_when_finished(netex_imports)
+ ParentNotifier.new(Import).notify_when_finished(netex_imports)
end
it "doesn't call #notify_parent if its `notified_parent_at` is set" do
@@ -33,11 +33,11 @@ RSpec.describe ParentImportNotifier do
expect(netex_import).not_to receive(:notify_parent)
- ParentImportNotifier.notify_when_finished
+ ParentNotifier.new(Import).notify_when_finished
end
end
- describe ".imports_pending_notification" do
+ describe ".objects_pending_notification" do
it "includes imports with a parent and `notified_parent_at` unset" do
netex_import = create(
:netex_import,
@@ -47,7 +47,7 @@ RSpec.describe ParentImportNotifier do
)
expect(
- ParentImportNotifier.imports_pending_notification
+ ParentNotifier.new(Import).objects_pending_notification
).to eq([netex_import])
end
@@ -55,7 +55,7 @@ RSpec.describe ParentImportNotifier do
create(:import, parent: nil)
expect(
- ParentImportNotifier.imports_pending_notification
+ ParentNotifier.new(Import).objects_pending_notification
).to be_empty
end
@@ -70,7 +70,7 @@ RSpec.describe ParentImportNotifier do
end
expect(
- ParentImportNotifier.imports_pending_notification
+ ParentNotifier.new(Import).objects_pending_notification
).to be_empty
end
@@ -83,7 +83,7 @@ RSpec.describe ParentImportNotifier do
)
expect(
- ParentImportNotifier.imports_pending_notification
+ ParentNotifier.new(Import).objects_pending_notification
).to be_empty
end
end
diff --git a/spec/services/referential_overview_spec.rb b/spec/services/referential_overview_spec.rb
new file mode 100644
index 000000000..0ce29643c
--- /dev/null
+++ b/spec/services/referential_overview_spec.rb
@@ -0,0 +1,154 @@
+RSpec.describe ReferentialOverview do
+
+ subject{ described_class }
+
+end
+
+RSpec.describe ReferentialOverview::Week do
+
+ describe "#initialize" do
+ it "should respect the boundary" do
+ week = ReferentialOverview::Week.new(Time.now.beginning_of_week, 1.week.from_now, {})
+ expect(week.start_date).to eq Time.now.beginning_of_week.to_date
+ expect(week.end_date).to eq Time.now.end_of_week.to_date
+
+ week = ReferentialOverview::Week.new(Time.now.beginning_of_week, Time.now, {})
+ expect(week.start_date).to eq Time.now.beginning_of_week.to_date
+ expect(week.end_date).to eq Time.now.to_date
+ end
+ end
+end
+
+RSpec.describe ReferentialOverview::Line do
+
+ let(:ref_line){create(:line)}
+ let(:referential){create(:referential)}
+ let(:start){2.days.ago}
+ let(:period_1){(10.days.ago..8.days.ago)}
+ let(:period_2){(5.days.ago..1.days.ago)}
+
+ subject(:line){ReferentialOverview::Line.new ref_line, referential, start, {}}
+
+ before(:each) do
+ create(:referential_metadata, referential: referential, line_ids: [ref_line.id], periodes: [period_1, period_2].compact)
+ end
+
+ describe "#width" do
+ it "should have the right value" do
+ expect(line.width).to eq ReferentialOverview::Day::WIDTH * referential.metadatas_period.count
+ end
+ end
+
+ describe "#periods" do
+ context "when the periodes are split into several metadatas" do
+ let(:period_2){nil}
+ before do
+ create(:referential_metadata, referential: referential, line_ids: [ref_line.id], periodes: [(17.days.ago..11.days.ago)])
+ end
+ it "should find them all" do
+ expect(line.periods.count).to eq 2
+ expect(line.periods[0].empty?).to be_falsy
+ expect(line.periods[1].empty?).to be_falsy
+ end
+
+ context "when the periodes overlap" do
+ let(:period_2){nil}
+ before do
+ create(:referential_metadata, referential: referential, line_ids: [ref_line.id], periodes: [(17.days.ago..9.days.ago)])
+ end
+ it "should merge them" do
+ expect(line.periods.count).to eq 1
+ expect(line.periods[0].empty?).to be_falsy
+ expect(line.periods[0].start).to eq 17.days.ago.to_date
+ expect(line.periods[0].end).to eq 8.days.ago.to_date
+ end
+ end
+ end
+ end
+
+ describe "#fill_periods" do
+ it "should fill the voids" do
+ expect(line.periods.count).to eq 3
+ expect(line.periods[0].empty?).to be_falsy
+ expect(line.periods[1].empty?).to be_truthy
+ expect(line.periods[1].accepted?).to be_truthy
+ expect(line.periods[2].empty?).to be_falsy
+ end
+
+ context "with no void" do
+ let(:period_1){(10.days.ago..8.days.ago)}
+ let(:period_2){(7.days.ago..1.days.ago)}
+
+ it "should find no void" do
+ expect(line.periods.count).to eq 2
+ expect(line.periods[0].empty?).to be_falsy
+ expect(line.periods[1].empty?).to be_falsy
+ end
+ end
+
+ context "with a large void" do
+ let(:period_1){(20.days.ago..19.days.ago)}
+ let(:period_2){(2.days.ago..1.days.ago)}
+
+ it "should fill the void" do
+ expect(line.periods.count).to eq 3
+ expect(line.periods[0].empty?).to be_falsy
+ expect(line.periods[1].empty?).to be_truthy
+ expect(line.periods[1].accepted?).to be_falsy
+ expect(line.periods[2].empty?).to be_falsy
+ end
+ end
+
+ context "with a void at the end" do
+ before do
+ create(:referential_metadata, referential: referential, periodes: [(2.days.ago..1.days.ago)])
+ end
+ let(:period_1){(20.days.ago..19.days.ago)}
+ let(:period_2){nil}
+
+ it "should fill the void" do
+ expect(line.periods.count).to eq 2
+ expect(line.periods[0].empty?).to be_falsy
+ expect(line.periods[1].empty?).to be_truthy
+ expect(line.periods[1].accepted?).to be_falsy
+ expect(line.periods[1].end).to eq 1.days.ago.to_date
+ end
+ end
+
+ context "with a void at the beginning" do
+ before do
+ create(:referential_metadata, referential: referential, periodes: [(200.days.ago..199.days.ago)])
+ end
+ let(:period_1){(20.days.ago..19.days.ago)}
+ let(:period_2){nil}
+
+ it "should fill the void" do
+ expect(line.periods.count).to eq 2
+ expect(line.periods[0].start).to eq 200.days.ago.to_date
+ expect(line.periods[0].empty?).to be_truthy
+ expect(line.periods[0].accepted?).to be_falsy
+ expect(line.periods[1].empty?).to be_falsy
+ end
+ end
+ end
+end
+
+RSpec.describe ReferentialOverview::Line::Period do
+
+ let(:period){(1.day.ago.to_date..Time.now.to_date)}
+ let(:start){2.days.ago.to_date}
+
+ subject(:line_period){ReferentialOverview::Line::Period.new period, start, nil}
+
+ describe "#width" do
+ it "should have the right value" do
+ expect(line_period.width).to eq ReferentialOverview::Day::WIDTH * 2
+ end
+ end
+
+ describe "#left" do
+ it "should have the right value" do
+ expect(line_period.left).to eq ReferentialOverview::Day::WIDTH * 1
+ end
+ end
+end
diff --git a/spec/services/zip_service_spec.rb b/spec/services/zip_service_spec.rb
index 98cb9026d..1eadaa3bf 100644
--- a/spec/services/zip_service_spec.rb
+++ b/spec/services/zip_service_spec.rb
@@ -1,68 +1,167 @@
-RSpec.describe ZipService do
+RSpec.describe ZipService, type: :zip do
- let( :zip_service ){ described_class }
- let( :unzipper ){ zip_service.new(zip_data) }
- let( :zip_data ){ File.read zip_file }
+ let( :unzipper ){ described_class.new( zip_data, allowed_lines ) }
+ subject { unzipper.subdirs }
+ let( :allowed_lines ){ Set.new(%w{C00108 C00109}) }
+ let( :zip_data ){ zip_archive.data }
+ let( :zip_archive ){ make_zip zip_name, zip_content }
- context 'correct test data' do
- before do
- subdir_names.each do | subdir_name |
- File.unlink( subdir_file subdir_name, suffix: '.zip' ) rescue nil
- Dir.unlink( subdir_file subdir_name ) rescue nil
+ context 'one, legal, referential' do
+ let( :zip_name ){ 'one_referential_ok.zip' }
+ let( :zip_content ){ first_referential_ok_data }
+
+ it 'yields correct output' do
+ subject.each do | subdir |
+ expect_correct_subdir subdir, make_zip('expected.zip', first_referential_ok_data)
end
end
- let( :subdir_names ){ %w<OFFRE_TRANSDEV_20170301122517 OFFRE_TRANSDEV_20170301122519> }
- let( :expected_chksums ){
- checksum_trees( subdir_names.map{ |sn| subdir_file(sn, prefix: 'source_') } )
- }
+ end
- let( :zip_file ){ fixtures_path 'OFFRE_TRANSDEV_2017030112251.zip' }
- #
- # Remove potential test artefacts
+ context 'two, legal, referentials' do
+ let( :zip_name ){ 'two_referential_ok.zip' }
+ let( :zip_content ){ first_referential_ok_data.merge( second_referential_ok_data ) }
+ let( :expected_zips ){ [
+ make_zip('expected.zip', first_referential_ok_data),
+ make_zip('expected.zip', second_referential_ok_data)
+ ] }
- it 'yields the correct content' do
- # Write ZipService Streams to files and inflate them to file system
- unzipper.subdirs.each do | subdir |
- expect( subdir.spurious ).to be_empty
- File.open(subdir_file( subdir.name, suffix: '.zip' ), 'wb'){ |f| f.write subdir.stream.string }
- unzip_subdir subdir
+ it 'yields correct output' do
+ subject.zip(expected_zips).each do | subdir, expected_zip |
+ expect_correct_subdir subdir, expected_zip
end
- # Represent the inflated file_system as a checksum tree
- actual_checksums =
- checksum_trees( subdir_names.map{ |sn| subdir_file(sn, prefix: 'target/') } )
- expect( actual_checksums ).to eq( expected_chksums )
end
+ end
+
+ context 'one referential with a spurious directory' do
+ let( :zip_name ){ 'one_referential_spurious.zip' }
+ let( :zip_content ){ first_referential_spurious_data }
+ it 'returns a not ok object' do
+ expect_incorrect_subdir subject.first, expected_spurious: %w{SPURIOUS}
+ end
end
- context 'test data with spurious directories' do
- let( :zip_file ){ fixtures_path 'OFFRE_WITH_EXTRA.zip' }
+ context 'one referential with a foreign line' do
+ let( :zip_name ){ 'one_referential_foreign.zip' }
+ let( :zip_content ){ first_referential_foreign_data }
- it 'returns the extra dir in the spurious field of the entry' do
- expect( unzipper.subdirs.first.spurious ).to eq(%w{EXTRA})
+ it 'returns a not ok object' do
+ expect_incorrect_subdir subject.first, expected_foreign_lines: %w{C00110}
end
end
+ context '1st ref ok, 2nd foreign line, 3rd spurious' do
+ let( :zip_name ){ '3-mixture.zip' }
+ let( :zip_content ){ first_referential_ok_data
+ .merge(first_referential_foreign_data)
+ .merge(first_referential_spurious_data) }
+
+ it 'returns 3 objects accordingly' do
+ subdirs = subject.to_a
- def checksum_trees *dirs
- dirs.flatten.inject({},&method(:checksum_tree))
+ expect_correct_subdir subdirs.first, make_zip('expected.zip', first_referential_ok_data)
+
+ expect_incorrect_subdir subdirs.second, expected_foreign_lines: %w{C00110}
+ expect_incorrect_subdir subdirs.third, expected_spurious: %W{SPURIOUS}
+ end
end
- def checksum_tree repr, dir
- Dir.glob("#{dir}/**/*").each do |file|
- if !File.directory?(file)
- repr.merge!( File.basename(file) => %x{cksum #{file}}.split.first ){ |_, ov, nv| Array(ov) << nv }
- end
+
+ context 'one messed up' do
+ let( :zip_name ){ 'one_messed_up.zip' }
+ let( :zip_content ){ messed_up_referential_data }
+
+ it 'returns a not ok object (all error information provided)' do
+ expect_incorrect_subdir subject.first,
+ expected_foreign_lines: %w{C00110 C00111},
+ expected_spurious: %w{SPURIOUS1 SPURIOUS2}
+ end
+
+ end
+
+ # Regression treated in #5281
+ context 'one_first_level_dir' do
+ let( :zip_data ){ File.read fixtures_path('regression-5281.zip') }
+ let( :zip_name ){ 'regression_5281' }
+
+ let( :allowed_lines ){
+ Set.new([*164..168, 171].map{|line| "C00#{line}"})
+ }
+
+ let( :subdirs ){ subject.to_a }
+
+ it 'returns one not ok object' do
+ expect( subdirs.size ).to eq(1)
+ expect( subdirs.first ).not_to be_ok
+ expect( subdirs.first.spurious ).to eq(%w{OFFRE_SNTYO_1_20170820120001 OFFRE_SNTYO_2_20170820120001})
end
- repr
end
- def subdir_file( subdir, prefix: 'target_', suffix: '' )
- fixtures_path("#{prefix}#{subdir}#{suffix}")
+ # Behaviour
+ # ---------
+ def expect_correct_subdir subdir, expected_zip
+ expect( subdir ).to be_ok
+ expect( subdir.foreign_lines ).to be_empty
+ expect( subdir.spurious ).to be_empty
+ subdir.stream.tap do | stream |
+ stream.rewind
+ expect( stream.read ).to eq(expected_zip.data)
+ end
end
- def unzip_subdir subdir
- %x{unzip -oqq #{subdir_file subdir.name, suffix: '.zip'} -d #{fixture_path}/target}
+ def expect_incorrect_subdir subdir, expected_spurious: [], expected_foreign_lines: []
+ expect( subdir ).not_to be_ok
+ expect( subdir.foreign_lines ).to eq(expected_foreign_lines)
+ expect( subdir.spurious ).to eq(expected_spurious)
end
-end
+ # Data
+ # ----
+ let :first_referential_ok_data do
+ {
+ 'Referential1/calendriers.xml' => 'calendriers',
+ 'Referential1/commun.xml' => 'common',
+ 'Referential1/offre_C00108_9.xml' => 'line 108 ref 1',
+ 'Referential1/offre_C00109_10.xml' => 'line 109 ref 1'
+ }
+ end
+ let :first_referential_foreign_data do
+ {
+ 'Referential2/calendriers.xml' => 'calendriers',
+ 'Referential2/commun.xml' => 'common',
+ 'Referential2/offre_C00110_11.xml' => 'foreign line ref 1',
+ 'Referential2/offre_C00108_9.xml' => 'line 108 ref 1',
+ 'Referential2/offre_C00109_10.xml' => 'line 109 ref 1'
+ }
+ end
+ let :first_referential_spurious_data do
+ {
+ 'Referential3/calendriers.xml' => 'calendriers',
+ 'Referential3/commun.xml' => 'common',
+ 'Referential3/SPURIOUS/commun.xml' => 'common',
+ 'Referential3/offre_C00108_9.xml' => 'line 108 ref 1',
+ 'Referential3/offre_C00109_10.xml' => 'line 109 ref 1'
+ }
+ end
+ let :second_referential_ok_data do
+ {
+ 'Referential4/calendriers.xml' => 'calendriers',
+ 'Referential4/commun.xml' => 'common',
+ 'Referential4/offre_C00108_9.xml' => 'line 108 ref 2',
+ 'Referential4/offre_C00109_10.xml' => 'line 109 ref 2'
+ }
+ end
+ let :messed_up_referential_data do
+ {
+ 'Referential5/calendriers.xml' => 'calendriers',
+ 'Referential5/commun.xml' => 'common',
+ 'Referential5/SPURIOUS1/commun.xml' => 'common',
+ 'Referential5/SPURIOUS2/commun.xml' => 'common',
+ 'Referential5/offre_C00110_11.xml' => 'foreign line ref 1',
+ 'Referential5/offre_C00111_11.xml' => 'foreign line ref 1',
+ 'Referential5/offre_C00108_9.xml' => 'line 108 ref 1',
+ 'Referential5/offre_C00109_10.xml' => 'line 109 ref 1'
+ }
+ end
+
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 9679952df..cde252236 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -64,11 +64,11 @@ RSpec.configure do |config|
Capybara.javascript_driver = :poltergeist
# :meta tests can be run seperately in case of doubt about the tests themselves
# they serve mainly as an explanataion of complicated tests (as e.g. PG information_schema introspection)
- config.filter_run_excluding :meta => true
- config.filter_run_excluding :js => true
- config.filter_run :wip => true
+ config.filter_run_excluding meta: true
+ config.filter_run_excluding truncation: true
+ config.filter_run_excluding wip: true
config.run_all_when_everything_filtered = true
- config.include TokenInputHelper, :type => :feature
+ config.include TokenInputHelper, type: :feature
# ## Mock Framework
#
@@ -93,14 +93,13 @@ RSpec.configure do |config|
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
- # RSpec.describe UsersController, :type => :controller do
+ # RSpec.describe UsersController, type: :controller do
# # ...
# end
#
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
config.infer_spec_type_from_file_location!
-
end
Shoulda::Matchers.configure do |config|
diff --git a/spec/support/checksum_support.rb b/spec/support/checksum_support.rb
index 14ea3c55e..f8dffb1b7 100644
--- a/spec/support/checksum_support.rb
+++ b/spec/support/checksum_support.rb
@@ -1,25 +1,23 @@
-shared_examples 'checksum support' do |factory_name|
- let(:instance) { create(factory_name) }
-
+shared_examples 'checksum support' do
describe '#current_checksum_source' do
let(:attributes) { ['code_value', 'label_value'] }
- let(:seperator) { ChecksumSupport::SEPARATOR }
+ let(:separator) { 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)
+ allow_any_instance_of(subject.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")
+ it 'should separate attribute by separator' do
+ expect(subject.current_checksum_source).to eq("code_value#{separator}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)
+ source = "code_value#{separator}#{nil_value}"
+ expect(subject.current_checksum_source).to eq(source)
end
end
@@ -27,27 +25,62 @@ shared_examples 'checksum support' do |factory_name|
let(:attributes) { ['code_value', []] }
it 'should convert to nil' do
- source = "code_value#{seperator}#{nil_value}"
- expect(instance.current_checksum_source).to eq(source)
+ source = "code_value#{separator}#{nil_value}"
+ expect(subject.current_checksum_source).to eq(source)
+ end
+ end
+
+ context 'array value' do
+ let(:attributes) { [['v1', 'v2', 'v3'], 'code_value'] }
+
+ it 'should convert to list' do
+ source = "v1,v2,v3#{separator}code_value"
+ expect(subject.current_checksum_source).to eq(source)
+ end
+ end
+
+ context 'array of array value' do
+ let(:attributes) { [[['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']], 'code_value'] }
+
+ it 'should convert to list' do
+ source = "(a1,a2,a3),(b1,b2,b3)#{separator}code_value"
+ expect(subject.current_checksum_source).to eq(source)
+ end
+ end
+
+ context 'array of array value, with empty array' do
+ let(:attributes) { [[['a1', 'a2', 'a3'], []], 'code_value'] }
+
+ it 'should convert to list' do
+ source = "(a1,a2,a3),-#{separator}code_value"
+ expect(subject.current_checksum_source).to eq(source)
end
end
end
it 'should save checksum on create' do
- expect(instance.checksum).to_not be_nil
+ expect(subject.checksum).to_not be_nil
end
it 'should save checksum_source' do
- expect(instance.checksum_source).to_not be_nil
+ expect(subject.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
+ expect(subject).to receive(:set_current_checksum_source).at_least(:once)
+ subject.save
end
it 'should trigger update_checksum on save' do
- expect(instance).to receive(:update_checksum)
- instance.save
+ expect(subject).to receive(:update_checksum).at_least(:once)
+ subject.save
+ end
+
+ it "doesn't change the checksum on save if the source hasn't been changed" do
+ checksum = subject.checksum
+
+ subject.save
+
+ expect(subject.checksum).to eq(checksum)
end
end
diff --git a/spec/support/controller_spec_helper.rb b/spec/support/controller_spec_helper.rb
new file mode 100644
index 000000000..dbc7d582b
--- /dev/null
+++ b/spec/support/controller_spec_helper.rb
@@ -0,0 +1,33 @@
+module ControllerSpecHelper
+ def with_permission permission, &block
+ context "with permission #{permission}" do
+ login_user
+ before(:each) do
+ @user.permissions << permission
+ @user.save!
+ sign_in @user
+ end
+ context('', &block) if block_given?
+ end
+ end
+
+ def with_feature feature, &block
+ context "with feature #{feature}" do
+ login_user
+ before(:each) do
+ organisation = @user.organisation
+ unless organisation.has_feature?(feature)
+ organisation.features << feature
+ organisation.save!
+ end
+ sign_in @user
+ end
+ context('', &block) if block_given?
+ end
+ end
+
+end
+
+RSpec.configure do |config|
+ config.extend ControllerSpecHelper, type: :controller
+end
diff --git a/spec/support/decorator_helpers.rb b/spec/support/decorator_helpers.rb
index ffedd479b..b2c41e842 100644
--- a/spec/support/decorator_helpers.rb
+++ b/spec/support/decorator_helpers.rb
@@ -1,27 +1,35 @@
module Support
-
module DecoratorHelpers
def self.included(into)
into.instance_eval do
subject{ object.decorate }
let( :policy ){ ::Pundit.policy(user_context, object) }
let( :user_context ){ UserContext.new(user, referential: referential) }
-
+ let( :features ){ [] }
+ let( :filtered_action_links){}
before do
allow_any_instance_of(Draper::HelperProxy).to receive(:policy).and_return policy
+ allow_any_instance_of(AF83::Decorator::Link).to receive(:check_feature){|f|
+ features.include?(f)
+ }
end
end
end
- def expect_action_link_hrefs
- expect( subject.action_links.select(&Link.method(:===)).map(&:href) )
+ def expect_action_link_hrefs(action=:index)
+ if subject.action_links.is_a? AF83::Decorator::ActionLinks
+ expect( subject.action_links(action).map(&:href) )
+ else
+ expect( subject.action_links.select(&Link.method(:===)).map(&:href) )
+ end
end
- def expect_action_link_elements
- expect( subject.action_links.select(&HTMLElement.method(:===)).map(&:content) )
+
+ def expect_action_link_elements(action=:index)
+ if subject.action_links.is_a? AF83::Decorator::ActionLinks
+ expect( subject.action_links(action).map(&:content) )
+ else
+ expect( subject.action_links.select(&HTMLElement.method(:===)).map(&:content) )
+ end
end
end
end
-
-RSpec.configure do | c |
- c.include Support::DecoratorHelpers, type: :decorator
-end
diff --git a/spec/support/helpers/tree_walker.rb b/spec/support/helpers/tree_walker.rb
new file mode 100644
index 000000000..b86c3a8e1
--- /dev/null
+++ b/spec/support/helpers/tree_walker.rb
@@ -0,0 +1,15 @@
+module TreeWalker extend self
+ MAX_LEVEL = 5
+ def walk_tree path, max_level: MAX_LEVEL, level: 0, yield_dirs: :no, &blk
+ raise RuntimeError, "too many levels in tree walk, > #{max_level}" if level > max_level
+ Dir.glob(File.join(path, '*')) do | file |
+ if File.directory?( file )
+ blk.(:dir, file) if yield_dirs == :before
+ walk_tree(file, max_level: max_level, level: level.succ, yield_dirs: yield_dirs, &blk)
+ blk.(:dir, file) if yield_dirs == :after
+ else
+ blk.(:file, file)
+ end
+ end
+ end
+end
diff --git a/spec/support/integration_spec_helper.rb b/spec/support/integration_spec_helper.rb
new file mode 100644
index 000000000..7ba7e9f92
--- /dev/null
+++ b/spec/support/integration_spec_helper.rb
@@ -0,0 +1,78 @@
+module IntegrationSpecHelper
+
+ def paginate_collection klass, decorator, page=1, context={}
+ collection = klass.page(page)
+ if decorator
+ if decorator < AF83::Decorator
+ collection = decorator.decorate(collection, context: context)
+ else
+ collection = ModelDecorator.decorate(collection, with: decorator, context: context)
+ end
+ end
+ collection
+ end
+
+ def build_paginated_collection factory, decorator, opts={}
+ context = opts.delete(:context) || {}
+ count = opts.delete(:count) || 2
+ page = opts.delete(:page) || 1
+ klass = nil
+ count.times { klass = create(factory, opts).class }
+ paginate_collection klass, decorator, page, context
+ end
+
+ module Methods
+ def with_permission permission, &block
+ context "with permission #{permission}" do
+ let(:permissions){ [permission] }
+ context('', &block) if block_given?
+ end
+ end
+
+ def with_feature feature, &block
+ context "with feature #{feature}" do
+ let(:features){ [feature] }
+ context('', &block) if block_given?
+ end
+ end
+ end
+
+ def self.included into
+ into.extend Methods
+ end
+end
+
+RSpec.configure do |config|
+ config.include IntegrationSpecHelper, type: :view
+end
+
+RSpec::Matchers.define :have_link_for_each_item do |collection, name, opts|
+ opts = {href: opts} unless opts.is_a? Hash
+ href = opts[:href]
+ method = opts[:method]
+ method_selector = method.present? ? "[data-method='#{method.downcase}']": ""
+ match do |actual|
+ collection.each do |item|
+ @selector = "tr.#{TableBuilderHelper.item_row_class_name(collection)}-#{item.id} .actions a[href='#{href.call(item)}']#{method_selector}"
+ expect(rendered).to have_selector(@selector, count: 1)
+ end
+ end
+ description { "have #{name} link for each item" }
+ failure_message do
+ "expected view to have one #{name} link for each item, failed with selector: \"#{@selector}\""
+ end
+end
+
+RSpec::Matchers.define :have_the_right_number_of_links do |collection, count|
+ match do
+ collection.each do |item|
+ @selector = "tr.#{TableBuilderHelper.item_row_class_name(collection)}-#{item.id} .actions a"
+ expect(rendered).to have_selector(@selector, count: count)
+ end
+ end
+ description { "have #{count} links for each item" }
+ failure_message do
+ actual = Capybara::Node::Simple.new(rendered).all(@selector).count
+ "expected #{count} links for each item, got #{actual} for \"#{@selector}\""
+ end
+end
diff --git a/spec/support/journey_pattern_helper.rb b/spec/support/journey_pattern_helper.rb
new file mode 100644
index 000000000..3ba1c501b
--- /dev/null
+++ b/spec/support/journey_pattern_helper.rb
@@ -0,0 +1,19 @@
+module Support
+ module JourneyPatternHelper
+ def generate_journey_pattern_costs distance, time
+ costs = {}
+ (journey_pattern.stop_points.size - 1).times do |i|
+ start, finish = journey_pattern.stop_points[i..i+1]
+ costs["#{start.stop_area_id}-#{finish.stop_area_id}"] = {
+ distance: (distance.respond_to?(:call) ? distance.call(i) : distance),
+ time: (time.respond_to?(:call) ? time.call(i) : time)
+ }
+ end
+ costs
+ end
+ end
+end
+
+RSpec.configure do | config |
+ config.include Support::JourneyPatternHelper, type: :model
+end
diff --git a/spec/support/permissions.rb b/spec/support/permissions.rb
index dde530871..95afd6c1c 100644
--- a/spec/support/permissions.rb
+++ b/spec/support/permissions.rb
@@ -18,6 +18,7 @@ module Support
calendars
footnotes
imports
+ merges
journey_patterns
referentials
routes
diff --git a/spec/support/pundit/policies.rb b/spec/support/pundit/policies.rb
index a3489d9db..d8d12d735 100644
--- a/spec/support/pundit/policies.rb
+++ b/spec/support/pundit/policies.rb
@@ -12,11 +12,14 @@ module Support
UserContext.new(user, referential: referential)
end
+ def finalise_referential
+ referential.referential_suite_id = random_int
+ end
+
def remove_permissions(*permissions, from_user:, save: false)
from_user.permissions -= permissions.flatten
from_user.save! if save
end
-
end
module PoliciesMacros
diff --git a/spec/support/pundit/pundit_view_policy.rb b/spec/support/pundit/pundit_view_policy.rb
index b8434cac0..63970de02 100644
--- a/spec/support/pundit/pundit_view_policy.rb
+++ b/spec/support/pundit/pundit_view_policy.rb
@@ -1,16 +1,21 @@
module Pundit
module PunditViewPolicy
- extend ActiveSupport::Concern
-
- included do
- before do
- controller.singleton_class.class_eval do
- def policy(instance)
- Class.new do
- def method_missing(*args, &block); true; end
- end.new
- end
- helper_method :policy
+ def self.included into
+ into.let(:permissions){ nil }
+ into.let(:current_referential){ referential || build_stubbed(:referential, organisation: organisation) }
+ into.let(:current_user){ create :user, permissions: permissions, organisation: organisation }
+ into.let(:pundit_user){ UserContext.new(current_user, referential: current_referential) }
+ into.let(:current_offer_workbench) { create :workbench, organisation: organisation}
+ into.before do
+ allow(view).to receive(:pundit_user) { pundit_user }
+ allow(view).to receive(:current_user) { current_user }
+ allow(view).to receive(:current_organisation).and_return(organisation)
+ allow(view).to receive(:current_offer_workbench).and_return(current_offer_workbench)
+ allow(view).to receive(:current_workgroup).and_return(current_offer_workbench.workgroup)
+ allow(view).to receive(:has_feature?){ |f| features.include?(f)}
+ allow(view).to receive(:user_signed_in?).and_return true
+ allow(view).to receive(:policy) do |instance|
+ ::Pundit.policy pundit_user, instance
end
end
end
diff --git a/spec/support/pundit/shared_examples.rb b/spec/support/pundit/shared_examples.rb
index 49f915626..13f537c6d 100644
--- a/spec/support/pundit/shared_examples.rb
+++ b/spec/support/pundit/shared_examples.rb
@@ -1,6 +1,6 @@
RSpec.shared_examples 'always allowed' do
- | permission, archived: false|
+ | permission, archived_and_finalised: false |
context 'same organisation →' do
before do
user.organisation_id = referential.organisation_id
@@ -8,11 +8,16 @@ RSpec.shared_examples 'always allowed' do
it "allows a user with the same organisation" do
expect_it.to permit(user_context, record)
end
- if archived
+ if archived_and_finalised
it 'does not remove permission for archived referentials' do
referential.archived_at = 42.seconds.ago
expect_it.to permit(user_context, record)
end
+
+ it 'does not remove permission for finalised referentials' do
+ finalise_referential
+ expect_it.to permit(user_context, record)
+ end
end
end
@@ -23,27 +28,33 @@ RSpec.shared_examples 'always allowed' do
it "allows a user with a different organisation" do
expect_it.to permit(user_context, record)
end
- if archived
+ if archived_and_finalised
it 'does not remove permission for archived referentials' do
referential.archived_at = 42.seconds.ago
expect_it.to permit(user_context, record)
end
+ it 'does not remove permission for finalised referentials' do
+ finalise_referential
+ expect_it.to permit(user_context, record)
+ end
end
end
end
RSpec.shared_examples 'always forbidden' do
- | permission, archived: false|
+ | permission, archived_and_finalised: false|
context 'same organisation →' do
before do
user.organisation_id = referential.organisation_id
end
+
it "allows a user with the same organisation" do
expect_it.not_to permit(user_context, record)
end
- if archived
+
+ if archived_and_finalised
it 'still no permission for archived referentials' do
- referential.archived_at = 42.seconds.ago
+ finalise_referential
expect_it.not_to permit(user_context, record)
end
end
@@ -56,17 +67,22 @@ RSpec.shared_examples 'always forbidden' do
it "denies a user with a different organisation" do
expect_it.not_to permit(user_context, record)
end
- if archived
+ if archived_and_finalised
it 'still no permission for archived referentials' do
referential.archived_at = 42.seconds.ago
expect_it.not_to permit(user_context, record)
end
+
+ it 'still no permission for finalised referentials' do
+ finalise_referential
+ expect_it.not_to permit(user_context, record)
+ end
end
end
end
RSpec.shared_examples 'permitted policy and same organisation' do
- | permission, archived: false|
+ | permission, archived_and_finalised: false |
context 'permission absent → ' do
it "denies a user with a different organisation" do
@@ -92,18 +108,24 @@ RSpec.shared_examples 'permitted policy and same organisation' do
expect_it.to permit(user_context, record)
end
- if archived
+ if archived_and_finalised
it 'removes the permission for archived referentials' do
user.organisation_id = referential.organisation_id
referential.archived_at = 42.seconds.ago
expect_it.not_to permit(user_context, record)
end
+
+ it 'removes the permission for finalised referentials' do
+ user.organisation_id = referential.organisation_id
+ finalise_referential
+ expect_it.not_to permit(user_context, record)
+ end
end
end
end
RSpec.shared_examples 'permitted policy' do
- | permission, archived: false|
+ | permission, archived_and_finalised: false|
context 'permission absent → ' do
it "denies user" do
@@ -120,12 +142,17 @@ RSpec.shared_examples 'permitted policy' do
expect_it.to permit(user_context, record)
end
- if archived
+ if archived_and_finalised
it 'removes the permission for archived referentials' do
user.organisation_id = referential.organisation_id
referential.archived_at = 42.seconds.ago
expect_it.not_to permit(user_context, record)
end
+ it 'removes the permission for finalised referentials' do
+ user.organisation_id = referential.organisation_id
+ finalise_referential
+ expect_it.not_to permit(user_context, record)
+ end
end
end
end
@@ -148,4 +175,4 @@ RSpec.shared_examples 'permitted policy outside referential' do
expect_it.to permit(user_context, record)
end
end
-end \ No newline at end of file
+end
diff --git a/spec/support/referential.rb b/spec/support/referential.rb
index b615491da..9acdce73a 100644
--- a/spec/support/referential.rb
+++ b/spec/support/referential.rb
@@ -11,8 +11,8 @@ module ReferentialHelper
def self.included(base)
base.class_eval do
extend ClassMethods
- alias_method :referential, :first_referential
- alias_method :organisation, :first_organisation
+ base.let(:referential){ first_referential }
+ base.let(:organisation){ first_organisation }
end
end
@@ -29,7 +29,6 @@ module ReferentialHelper
end
end
-
end
end
@@ -78,7 +77,7 @@ RSpec.configure do |config|
first_referential.switch
end
- config.before(:each, :js => true) do
+ config.before(:each, truncation: true) do
DatabaseCleaner.strategy = :truncation, { except: %w[spatial_ref_sys] }
end
diff --git a/spec/support/shared_examples/compliance_control_validation.rb b/spec/support/shared_examples/compliance_control_validation.rb
index d4ab9f41d..b23c2984f 100644
--- a/spec/support/shared_examples/compliance_control_validation.rb
+++ b/spec/support/shared_examples/compliance_control_validation.rb
@@ -1,43 +1,54 @@
RSpec.shared_examples_for 'has min_max_values' do
context "is valid" do
- it 'if no value is provided' do
+ it { should validate_numericality_of(:minimum) }
+ it { should validate_numericality_of(:maximum) }
+
+ it 'if maximum is greater than minimum' do
+ min = random_int
+ max = min + 100
+ subject.assign_attributes maximum: max, minimum: min
expect_it.to be_valid
end
+ end
+
+ context "is invalid" do
+ it 'if no value is provided' do
+ subject.minimum = nil
+ subject.maximum = nil
+ expect_it.not_to be_valid
+ end
+
it 'if minimum is provided alone' do
subject.minimum = 42
- expect_it.to be_valid
+ subject.maximum = nil
+ expect_it.not_to be_valid
end
+
it 'if maximum is provided alone' do
+ subject.minimum = nil
subject.maximum = 42
- expect_it.to be_valid
- end
-
- it 'if maximum is not smaller than minimum' do
- 100.times do
- min = random_int
- max = min + random_int(20)
- subject.assign_attributes maximum: max, minimum: min
- subject.assign_attributes maximum: min, minimum: min
- expect_it.to be_valid
- end
+ expect_it.not_to be_valid
end
- end
- context "is invalid" do
it 'if maximum is smaller than minimum' do
- 100.times do
- min = random_int
- max = min - random_int(20) - 1
- subject.assign_attributes maximum: max, minimum: min
- expect_it.not_to be_valid
- end
+ min = random_int
+ max = min - 1
+ subject.assign_attributes maximum: max, minimum: min
+ expect_it.not_to be_valid
end
it 'and has a correct error message' do
subject.assign_attributes maximum: 1, minimum: 2
expect_it.not_to be_valid
- expect( subject.errors.messages[:min_max_values].first ).to match("la valeur de minimum (2) ne doit pas être superieur à la valuer du maximum (1)")
+ expect( subject.errors.messages[:minimum].first ).to match(I18n.t("compliance_controls.min_max_values", min: 2, max: 1))
end
end
end
+
+
+RSpec.shared_examples_for "has target attribute" do
+ context "is valid" do
+ it { should validate_presence_of(:target) }
+ end
+end
diff --git a/spec/support/snapshot_support.rb b/spec/support/snapshot_support.rb
new file mode 100644
index 000000000..b1ade5288
--- /dev/null
+++ b/spec/support/snapshot_support.rb
@@ -0,0 +1,60 @@
+module SnaphostSpecHelper
+
+ module Methods
+ def set_invariant expr, val=nil
+ val ||= expr
+ chain = expr.split(".")
+ method = chain.pop
+
+ before(:each) do
+ allow(eval(chain.join('.'))).to receive(method){ val }
+ end
+ end
+ end
+
+ def self.included into
+ into.extend Methods
+ end
+end
+
+RSpec.configure do |config|
+ config.include SnaphostSpecHelper, type: :view
+end
+
+
+RSpec::Matchers.define :match_actions_links_snapshot do |name|
+ match do |actual|
+ @content = Capybara::Node::Simple.new(rendered).find('.page_header').native.inner_html
+ expect(@content).to match_snapshot(name)
+ end
+
+ failure_message do |actual|
+ out = ["Snapshots did not match."]
+ snap_path = File.dirname(method_missing(:class).metadata[:file_path]) + "/__snapshots__/#{name}.snap"
+ temp_path = Pathname.new "#{Rails.root}/tmp/__snapshots__/#{name}.failed.snap"
+ FileUtils.mkdir_p temp_path.dirname
+ tmp = File.new temp_path, "w"
+ tmp.write @content
+ tmp.close()
+ expected = File.read snap_path
+ out << "Expected: #{expected}"
+ out << "Actual: #{@content}"
+ out << "\n\n --- DIFF ---"
+ out << differ.diff_as_string(@content, expected)
+ out << "\n\n --- Previews : ---"
+ out << "Expected: \n" + snapshot_url(snap: snap_path, layout: :actions_links)
+ out << " \nActual: \n" + snapshot_url(snap: tmp.path, layout: :actions_links)
+ out.join("\n")
+ end
+
+ def snapshot_url snap:, layout:
+ "http://localhost:3000/snap/?snap=#{URI.encode(snap.to_s)}&layout=#{URI.encode(layout.to_s)}"
+ end
+
+ def differ
+ RSpec::Support::Differ.new(
+ :object_preparer => lambda { |object| RSpec::Matchers::Composable.surface_descriptions_in(object) },
+ :color => RSpec::Matchers.configuration.color?
+ )
+ end
+end
diff --git a/spec/support/zip_support.rb b/spec/support/zip_support.rb
new file mode 100644
index 000000000..3d9b2f97c
--- /dev/null
+++ b/spec/support/zip_support.rb
@@ -0,0 +1,25 @@
+require_relative 'helpers/tree_walker'
+module ZipSupport
+
+ module Helper extend self
+ def remove
+ -> filetype, path do
+ filetype == :file ? File.unlink(path) : Dir.unlink(path)
+ end
+ end
+ end
+
+ def zip_fixtures_path(file_name)
+ fixtures_path(File.join('zip', file_name))
+ end
+
+ def clear_all_zip_fixtures! relpath = ''
+ raise ArgumentError, 'up dir not allowed (..)' if %r{\.\.} === relpath
+ TreeWalker.walk_tree zip_fixtures_path(relpath), yield_dirs: :after, &Helper.remove
+ end
+end
+
+RSpec.configure do |conf|
+ conf.include ZipSupport, type: :zip
+end
+
diff --git a/spec/support/zip_support/create_zip_data.rb b/spec/support/zip_support/create_zip_data.rb
new file mode 100644
index 000000000..250d67f74
--- /dev/null
+++ b/spec/support/zip_support/create_zip_data.rb
@@ -0,0 +1,70 @@
+require_relative '../helpers/tree_walker'
+module ZipSupport
+ module CreateZipData
+
+ class ZipData < Struct.new(:name, :data)
+
+ def write_to file
+ File.write(file, data)
+ end
+
+ end
+
+ class Implementation
+
+ attr_reader :name, :prefix, :zip
+
+ def initialize name
+ @name = name
+ @prefix = "#{name}/"
+ @zip = ZipData.new(name, '')
+ end
+
+ def make_from names_to_content_map
+ os = Zip::OutputStream.write_buffer do | zio |
+ names_to_content_map.each(&add_entries(zio))
+ end
+ zip.data = os.string
+ zip
+ end
+
+ def make_from_tree
+ os = Zip::OutputStream.write_buffer do | zio |
+ TreeWalker.walk_tree(name, &add_entry(zio))
+ end
+ zip.data = os.string
+ zip
+ end
+
+ private
+
+ def add_entry zio
+ -> _, path do
+ rel_path = path.sub(prefix, '')
+ zio.put_next_entry(rel_path)
+ zio.write(File.read(path))
+ end
+ end
+
+ def add_entries zio
+ -> name, content do
+ zio.put_next_entry(name)
+ zio.write(content)
+ end
+ end
+ end
+
+
+ def make_zip(name, names_to_content_map = {})
+ Implementation.new(name).make_from(names_to_content_map)
+ end
+
+ def make_zip_from_tree(dir)
+ Implementation.new(dir).make_from_tree
+ end
+ end
+end
+
+RSpec.configure do |conf|
+ conf.include ZipSupport::CreateZipData, type: :zip
+end
diff --git a/spec/views/companies/__snapshots__/companies/index.snap b/spec/views/companies/__snapshots__/companies/index.snap
new file mode 100644
index 000000000..2c5c23400
--- /dev/null
+++ b/spec/views/companies/__snapshots__/companies/index.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/companies/__snapshots__/companies/index_create.snap b/spec/views/companies/__snapshots__/companies/index_create.snap
new file mode 100644
index 000000000..df36d5f49
--- /dev/null
+++ b/spec/views/companies/__snapshots__/companies/index_create.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><a class="btn btn-default" href="/line_referentials/99/companies/new">Ajouter un transporteur</a></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/companies/__snapshots__/companies/index_destroy.snap b/spec/views/companies/__snapshots__/companies/index_destroy.snap
new file mode 100644
index 000000000..2c5c23400
--- /dev/null
+++ b/spec/views/companies/__snapshots__/companies/index_destroy.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/companies/__snapshots__/companies/index_update.snap b/spec/views/companies/__snapshots__/companies/index_update.snap
new file mode 100644
index 000000000..2c5c23400
--- /dev/null
+++ b/spec/views/companies/__snapshots__/companies/index_update.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/companies/__snapshots__/companies/show.snap b/spec/views/companies/__snapshots__/companies/show.snap
new file mode 100644
index 000000000..8fe847427
--- /dev/null
+++ b/spec/views/companies/__snapshots__/companies/show.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Transporteur Company Name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/companies/__snapshots__/companies/show_create.snap b/spec/views/companies/__snapshots__/companies/show_create.snap
new file mode 100644
index 000000000..8fe847427
--- /dev/null
+++ b/spec/views/companies/__snapshots__/companies/show_create.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Transporteur Company Name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/companies/__snapshots__/companies/show_destroy.snap b/spec/views/companies/__snapshots__/companies/show_destroy.snap
new file mode 100644
index 000000000..5d574e460
--- /dev/null
+++ b/spec/views/companies/__snapshots__/companies/show_destroy.snap
@@ -0,0 +1,7 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Transporteur Company Name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right"><a data-confirm="Etes vous sûr de supprimer ce transporteur ?" class="btn btn-primary" rel="nofollow" data-method="delete" href="/line_referentials/99/companies/909"><span class="fa fa-trash mr-xs"></span>Supprimer ce transporteur</a></div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/companies/__snapshots__/companies/show_update.snap b/spec/views/companies/__snapshots__/companies/show_update.snap
new file mode 100644
index 000000000..c2fbd3297
--- /dev/null
+++ b/spec/views/companies/__snapshots__/companies/show_update.snap
@@ -0,0 +1,7 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Transporteur Company Name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action">
+<div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div>
+<a class="btn btn-default" href="/line_referentials/99/companies/909/edit">Editer ce transporteur</a>
+</div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/companies/index.html.erb_spec.rb b/spec/views/companies/index.html.erb_spec.rb
index 9db689ba6..8ed5f2c21 100644
--- a/spec/views/companies/index.html.erb_spec.rb
+++ b/spec/views/companies/index.html.erb_spec.rb
@@ -3,7 +3,10 @@ require 'spec_helper'
RSpec.describe "/companies/index", :type => :view do
let!(:line_referential) { assign :line_referential, create(:line_referential) }
- let!(:companies) { assign :companies, CompanyDecorator.decorate_collection(Array.new(2) { create(:company, line_referential: line_referential) }.paginate) }
+ let(:context){{referential: line_referential}}
+ let!(:companies) do
+ assign :companies, build_paginated_collection(:company, CompanyDecorator, line_referential: line_referential, context: context)
+ end
let!(:search) { assign :q, Ransack::Search.new(Chouette::Company) }
# Fixme #1795
@@ -22,4 +25,28 @@ RSpec.describe "/companies/index", :type => :view do
# expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_line_referential_company_path(line_referential)}']")
# end
+ before(:each) do
+ allow(view).to receive(:collection).and_return(companies)
+ allow(view).to receive(:decorated_collection).and_return(companies)
+ allow(view).to receive(:current_referential).and_return(line_referential)
+ controller.request.path_parameters[:line_referential_id] = line_referential.id
+ allow(view).to receive(:params).and_return({action: :index})
+ end
+
+ describe "action links" do
+ set_invariant "line_referential.id", "99"
+
+ before(:each){
+ render template: "companies/index", layout: "layouts/application"
+ }
+
+ it { should match_actions_links_snapshot "companies/index" }
+
+ %w(create update destroy).each do |p|
+ with_permission "companies.#{p}" do
+ it { should match_actions_links_snapshot "companies/index_#{p}" }
+ end
+ end
+ end
+
end
diff --git a/spec/views/companies/show.html.erb_spec.rb b/spec/views/companies/show.html.erb_spec.rb
index aeb93aebb..b127bdf44 100644
--- a/spec/views/companies/show.html.erb_spec.rb
+++ b/spec/views/companies/show.html.erb_spec.rb
@@ -2,11 +2,38 @@ require 'spec_helper'
describe "/companies/show", :type => :view do
- let!(:company) { assign(:company, create(:company)) }
+ let!(:company) { c = create(:company); assign(:company, c.decorate(context: {referential: c.line_referential})) }
let!(:line_referential) { assign :line_referential, company.line_referential }
# it "should display a map with class 'company'" do
# render
# expect(rendered).to have_selector("#map", :class => 'company')
# end
+
+ before(:each) do
+ allow(view).to receive(:current_referential).and_return(line_referential)
+ allow(view).to receive(:resource).and_return(company)
+ controller.request.path_parameters[:line_referential_id] = line_referential.id
+ controller.request.path_parameters[:id] = company.id
+ allow(view).to receive(:params).and_return({action: :show})
+ end
+
+ describe "action links" do
+ set_invariant "line_referential.id", "99"
+ set_invariant "company.object.id", "909"
+ set_invariant "company.object.name", "Company Name"
+ set_invariant "company.object.updated_at", "2018/01/23".to_time
+
+ before(:each){
+ render template: "companies/show", layout: "layouts/application"
+ }
+
+ it { should match_actions_links_snapshot "companies/show" }
+
+ %w(create update destroy).each do |p|
+ with_permission "companies.#{p}" do
+ it { should match_actions_links_snapshot "companies/show_#{p}" }
+ end
+ end
+ end
end
diff --git a/spec/views/connection_links/index.html.erb_spec.rb b/spec/views/connection_links/index.html.erb_spec.rb
index a01380094..1f133e31e 100644
--- a/spec/views/connection_links/index.html.erb_spec.rb
+++ b/spec/views/connection_links/index.html.erb_spec.rb
@@ -17,9 +17,11 @@ describe "/connection_links/index", :type => :view do
end
end
- it "should render a link to create a new group" do
- render
- expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_referential_connection_link_path(referential)}']")
+ with_permission "connection_links.create" do
+ it "should render a link to create a new group" do
+ render
+ expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_referential_connection_link_path(referential)}']")
+ end
end
end
diff --git a/spec/views/connection_links/show.html.erb_spec.rb b/spec/views/connection_links/show.html.erb_spec.rb
deleted file mode 100644
index c04a4f3f1..000000000
--- a/spec/views/connection_links/show.html.erb_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-require 'spec_helper'
-
-describe "/connection_links/show", :type => :view do
-
- assign_referential
- let!(:connection_link) { assign(:connection_link, create(:connection_link)) }
- let!(:map) { assign(:map, double(:to_html => '<div id="map"/>'.html_safe)) }
-
- before do
- allow(view).to receive_messages(current_organisation: referential.organisation)
- end
-
- it "should render h2 with the connection_link name" do
- render
- expect(rendered).to have_selector("h2", :text => Regexp.new(connection_link.name))
- end
-
-# it "should display a map with class 'connection_link'" do
-# pending ": map not yet implemented"
-# render
-# expect(rendered).to have_selector("#map", :class => 'connection_link')
-# end
-
- it "should render a link to edit the connection_link" do
- render
- expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.edit_referential_connection_link_path(referential, connection_link)}']")
- end
-
- it "should render a link to remove the connection_link" do
- render
- expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.referential_connection_link_path(referential, connection_link)}'][class='remove']")
- end
-
-end
-
diff --git a/spec/views/connection_links/show.html.slim_spec.rb b/spec/views/connection_links/show.html.slim_spec.rb
new file mode 100644
index 000000000..afe94fc6c
--- /dev/null
+++ b/spec/views/connection_links/show.html.slim_spec.rb
@@ -0,0 +1,32 @@
+require 'spec_helper'
+
+describe "/connection_links/show", :type => :view do
+
+ assign_referential
+ let!(:connection_link) { assign(:connection_link, create(:connection_link)) }
+ let!(:map) { assign(:map, double(:to_html => '<div id="map"/>'.html_safe)) }
+
+ before do
+ allow(view).to receive_messages(current_organisation: referential.organisation)
+ end
+
+ it "should render h2 with the connection_link name" do
+ render
+ expect(rendered).to have_selector("h2", :text => Regexp.new(connection_link.name))
+ end
+
+ with_permission "connection_links.update" do
+ it "should render a link to edit the connection_link" do
+ render
+ expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.edit_referential_connection_link_path(referential, connection_link)}']")
+ end
+ end
+
+ with_permission "connection_links.destroy" do
+ it "should render a link to remove the connection_link" do
+ render
+ expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.referential_connection_link_path(referential, connection_link)}'][class='remove']")
+ end
+ end
+
+end
diff --git a/spec/views/imports/show.html.slim_spec.rb b/spec/views/imports/show.html.slim_spec.rb
new file mode 100644
index 000000000..faf473758
--- /dev/null
+++ b/spec/views/imports/show.html.slim_spec.rb
@@ -0,0 +1,35 @@
+RSpec.describe '/imports/show', type: :view do
+ let(:workbench){ create :workbench }
+ let(:workbench_import){ create :workbench_import, workbench: workbench }
+ let!( :messages ) {[
+ create(:corrupt_zip_file, import: workbench_import),
+ create(:inconsistent_zip_file, import: workbench_import),
+ ]}
+
+
+ before do
+ assign :import, workbench_import.decorate( context: {workbench: workbench} )
+ render
+ end
+
+ it 'shows the correct record...' do
+ # ... zip file name
+ expect(rendered).to have_selector('.dl-def') do
+ with_text workbench_import.file
+ end
+
+ # ... messages
+ messages.each do | message |
+ # require 'htmlbeautifier'
+ # b = HtmlBeautifier.beautify(rendered, indent: ' ')
+ expect(rendered).to have_selector('.import_message-list li') do
+ with_text rendered_message( message )
+ end
+ end
+ end
+
+ def rendered_message message
+ return I18n.t message.message_key, message.message_attributes.symbolize_keys
+ end
+
+end
diff --git a/spec/views/line_referentials/show.html.slim_spec.rb b/spec/views/line_referentials/show.html.slim_spec.rb
new file mode 100644
index 000000000..0516677cb
--- /dev/null
+++ b/spec/views/line_referentials/show.html.slim_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe "/line_referentials/show", :type => :view do
+
+ let!(:line_referential) { assign :line_referential, create(:line_referential) }
+
+ before :each do
+ render
+ end
+
+ it "should not present syncing infos and button" do
+ expect(view.content_for(:page_header_actions)).to_not have_selector("a[href=\"#{view.sync_line_referential_path(line_referential)}\"]")
+ expect(view.content_for(:page_header_meta)).to_not have_selector(".last-update")
+ end
+
+ with_permission "line_referentials.synchronize" do
+ it "should present syncing infos and button" do
+ expect(view.content_for(:page_header_actions)).to have_selector("a[href=\"#{view.sync_line_referential_path(line_referential)}\"]", count: 1)
+ expect(view.content_for(:page_header_meta)).to have_selector(".last-update", count: 1)
+ end
+ end
+end
diff --git a/spec/views/line_referentials/stop_area_referentials/show.html.slim_spec.rb b/spec/views/line_referentials/stop_area_referentials/show.html.slim_spec.rb
new file mode 100644
index 000000000..71a8d16f5
--- /dev/null
+++ b/spec/views/line_referentials/stop_area_referentials/show.html.slim_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe "/stop_area_referentials/show", :type => :view do
+
+ let!(:stop_area_referential) { assign :stop_area_referential, create(:stop_area_referential) }
+
+ before :each do
+ render
+ end
+
+ it "should not present syncing infos and button" do
+ expect(view.content_for(:page_header_actions)).to_not have_selector("a[href=\"#{view.sync_stop_area_referential_path(stop_area_referential)}\"]")
+ expect(view.content_for(:page_header_meta)).to_not have_selector(".last-update")
+ end
+
+ with_permission "stop_area_referentials.synchronize" do
+ it "should present syncing infos and button" do
+ expect(view.content_for(:page_header_actions)).to have_selector("a[href=\"#{view.sync_stop_area_referential_path(stop_area_referential)}\"]", count: 1)
+ expect(view.content_for(:page_header_meta)).to have_selector(".last-update", count: 1)
+ end
+ end
+end
diff --git a/spec/views/lines/__snapshots__/lines/index.snap b/spec/views/lines/__snapshots__/lines/index.snap
new file mode 100644
index 000000000..2c5c23400
--- /dev/null
+++ b/spec/views/lines/__snapshots__/lines/index.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/lines/__snapshots__/lines/index_create.snap b/spec/views/lines/__snapshots__/lines/index_create.snap
new file mode 100644
index 000000000..4e4f54e7f
--- /dev/null
+++ b/spec/views/lines/__snapshots__/lines/index_create.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><a class="btn btn-default" href="/line_referentials/99/lines/new">Ajouter une ligne</a></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/lines/__snapshots__/lines/index_destroy.snap b/spec/views/lines/__snapshots__/lines/index_destroy.snap
new file mode 100644
index 000000000..2c5c23400
--- /dev/null
+++ b/spec/views/lines/__snapshots__/lines/index_destroy.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/lines/__snapshots__/lines/index_update.snap b/spec/views/lines/__snapshots__/lines/index_update.snap
new file mode 100644
index 000000000..2c5c23400
--- /dev/null
+++ b/spec/views/lines/__snapshots__/lines/index_update.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/lines/__snapshots__/lines/show.snap b/spec/views/lines/__snapshots__/lines/show.snap
new file mode 100644
index 000000000..30eb6786e
--- /dev/null
+++ b/spec/views/lines/__snapshots__/lines/show.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Ligne Name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/line_referentials/99/networks/99">Voir le réseau</a><a class="btn btn-primary" href="/line_referentials/99/companies/99">Voir le transporteur principal</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/lines/__snapshots__/lines/show_create.snap b/spec/views/lines/__snapshots__/lines/show_create.snap
new file mode 100644
index 000000000..30eb6786e
--- /dev/null
+++ b/spec/views/lines/__snapshots__/lines/show_create.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Ligne Name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/line_referentials/99/networks/99">Voir le réseau</a><a class="btn btn-primary" href="/line_referentials/99/companies/99">Voir le transporteur principal</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/lines/__snapshots__/lines/show_destroy.snap b/spec/views/lines/__snapshots__/lines/show_destroy.snap
new file mode 100644
index 000000000..8ed08a90d
--- /dev/null
+++ b/spec/views/lines/__snapshots__/lines/show_destroy.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Ligne Name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/line_referentials/99/networks/99">Voir le réseau</a><a class="btn btn-primary" href="/line_referentials/99/companies/99">Voir le transporteur principal</a><a data-confirm="Etes vous sûr de supprimer cette ligne ?" class="btn btn-primary" rel="nofollow" data-method="delete" href="/line_referentials/99/lines/99"><span class="fa fa-trash mr-xs"></span>Supprimer cette ligne</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/lines/__snapshots__/lines/show_update.snap b/spec/views/lines/__snapshots__/lines/show_update.snap
new file mode 100644
index 000000000..30eb6786e
--- /dev/null
+++ b/spec/views/lines/__snapshots__/lines/show_update.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Ligne Name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/line_referentials/99/networks/99">Voir le réseau</a><a class="btn btn-primary" href="/line_referentials/99/companies/99">Voir le transporteur principal</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/lines/index.html.erb_spec.rb b/spec/views/lines/index.html.erb_spec.rb
deleted file mode 100644
index dbc3cbdb7..000000000
--- a/spec/views/lines/index.html.erb_spec.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-require 'spec_helper'
-
-describe "/lines/index", :type => :view do
-
- let!(:line_referential) { assign :line_referential, create(:line_referential) }
- let!(:network) { create :network }
- let!(:company) { create :company }
- let!(:lines) { assign :lines, Array.new(2) { create(:line, line_referential: line_referential, network: network, company: company) }.paginate }
- let!(:q) { assign :q, Ransack::Search.new(Chouette::Line) }
-
- before :each do
- allow(view).to receive(:link_with_search).and_return("#")
- end
-
- # it "should render a show link for each group" do
- # render
- # lines.each do |line|
- # expect(rendered).to have_selector(".line a[href='#{view.line_referential_line_path(line_referential, line)}']", :text => line.name)
- # end
- # end
- #
- # it "should render a link to create a new group" do
- # render
- # expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_line_referential_line_path(line_referential)}']")
- # end
-
-end
diff --git a/spec/views/lines/index.html.slim_spec.rb b/spec/views/lines/index.html.slim_spec.rb
new file mode 100644
index 000000000..20e1783e3
--- /dev/null
+++ b/spec/views/lines/index.html.slim_spec.rb
@@ -0,0 +1,93 @@
+require 'spec_helper'
+
+describe "/lines/index", :type => :view do
+ let(:deactivated_line){ nil }
+ let(:line_referential) { assign :line_referential, create(:line_referential) }
+ let(:current_organisation) { current_user.organisation }
+ let(:context) {
+ {
+ current_organisation: current_organisation,
+ line_referential: line_referential
+ }
+ }
+ let(:lines) do
+ assign :lines, build_paginated_collection(:line, LineDecorator, line_referential: line_referential, context: context)
+ end
+ let!(:q) { assign :q, Ransack::Search.new(Chouette::Line) }
+
+ before :each do
+ deactivated_line
+ allow(view).to receive(:collection).and_return(lines)
+ allow(view).to receive(:decorated_collection).and_return(lines)
+ allow(view).to receive(:current_referential).and_return(line_referential)
+ allow(view).to receive(:params).and_return({action: :index})
+ controller.request.path_parameters[:line_referential_id] = line_referential.id
+ controller.request.path_parameters[:action] = "index"
+ render
+ end
+
+ describe "action links" do
+ set_invariant "line_referential.id", "99"
+ set_invariant "line_referential.name", "Name"
+
+ before(:each){
+ render template: "lines/index", layout: "layouts/application"
+ }
+
+ it { should match_actions_links_snapshot "lines/index" }
+
+ %w(create update destroy).each do |p|
+ with_permission "lines.#{p}" do
+ it { should match_actions_links_snapshot "lines/index_#{p}" }
+ end
+ end
+ end
+
+ context "links" do
+ common_items = ->{
+ it { should have_link_for_each_item(lines, "show", -> (line){ view.line_referential_line_path(line_referential, line) }) }
+ it { should have_link_for_each_item(lines, "network", -> (line){ view.line_referential_network_path(line_referential, line.network) }) }
+ it { should have_link_for_each_item(lines, "company", -> (line){ view.line_referential_company_path(line_referential, line.company) }) }
+ }
+
+ common_items.call()
+ it { should have_the_right_number_of_links(lines, 3) }
+
+ with_permission "lines.change_status" do
+ common_items.call()
+ it { should have_link_for_each_item(lines, "deactivate", -> (line){ view.deactivate_line_referential_line_path(line_referential, line) }) }
+ it { should have_the_right_number_of_links(lines, 4) }
+ end
+
+ with_permission "lines.destroy" do
+ common_items.call()
+ it {
+ should have_link_for_each_item(lines, "destroy", {
+ href: ->(line){ view.line_referential_line_path(line_referential, line)},
+ method: :delete
+ })
+ }
+ it { should have_the_right_number_of_links(lines, 4) }
+ end
+
+ context "with a deactivated item" do
+ with_permission "lines.change_status" do
+ let(:deactivated_line){ create :line, deactivated: true }
+
+ common_items.call()
+ it "should display an activate link for the deactivated one" do
+ lines.each do |line|
+ if line == deactivated_line
+ href = view.activate_line_referential_line_path(line_referential, line)
+ else
+ href = view.deactivate_line_referential_line_path(line_referential, line)
+ end
+ selector = "tr.#{TableBuilderHelper.item_row_class_name(lines)}-#{line.id} .actions a[href='#{href}']"
+ expect(rendered).to have_selector(selector, count: 1)
+ end
+ end
+ it { should have_the_right_number_of_links(lines, 4) }
+ end
+ end
+ end
+end
diff --git a/spec/views/lines/show.html.erb_spec.rb b/spec/views/lines/show.html.erb_spec.rb
index 9649d9c8e..effdcd014 100644
--- a/spec/views/lines/show.html.erb_spec.rb
+++ b/spec/views/lines/show.html.erb_spec.rb
@@ -15,6 +15,30 @@ describe "/lines/show", :type => :view do
let!(:map) { assign(:map, double(:to_html => '<div id="map"/>'.html_safe)) }
before do
- allow(view).to receive_messages(current_organisation: referential.organisation)
+ allow(view).to receive_messages(current_organisation: referential.organisation, resource: line)
+ controller.request.path_parameters[:line_referential_id] = line_referential.id
+ controller.request.path_parameters[:id] = line.id
+ allow(view).to receive(:params).and_return({action: :show})
+ end
+
+ describe "action links" do
+ set_invariant "line_referential.id", "99"
+ set_invariant "line.object.id", "99"
+ set_invariant "line.object.name", "Name"
+ set_invariant "line.company.id", "99"
+ set_invariant "line.network.id", "99"
+ set_invariant "line.updated_at", "2018/01/23".to_time
+
+ before(:each){
+ render template: "lines/show", layout: "layouts/application"
+ }
+
+ it { should match_actions_links_snapshot "lines/show" }
+
+ %w(create update destroy).each do |p|
+ with_permission "lines.#{p}" do
+ it { should match_actions_links_snapshot "lines/show_#{p}" }
+ end
+ end
end
end
diff --git a/spec/views/networks/__snapshots__/networks/index.snap b/spec/views/networks/__snapshots__/networks/index.snap
new file mode 100644
index 000000000..2c5c23400
--- /dev/null
+++ b/spec/views/networks/__snapshots__/networks/index.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/networks/__snapshots__/networks/index_create.snap b/spec/views/networks/__snapshots__/networks/index_create.snap
new file mode 100644
index 000000000..afd4aa41b
--- /dev/null
+++ b/spec/views/networks/__snapshots__/networks/index_create.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><a class="btn btn-default" href="/line_referentials/99/networks/new">Ajouter un réseau</a></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/networks/__snapshots__/networks/index_destroy.snap b/spec/views/networks/__snapshots__/networks/index_destroy.snap
new file mode 100644
index 000000000..2c5c23400
--- /dev/null
+++ b/spec/views/networks/__snapshots__/networks/index_destroy.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/networks/__snapshots__/networks/index_update.snap b/spec/views/networks/__snapshots__/networks/index_update.snap
new file mode 100644
index 000000000..2c5c23400
--- /dev/null
+++ b/spec/views/networks/__snapshots__/networks/index_update.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/networks/__snapshots__/networks/show.snap b/spec/views/networks/__snapshots__/networks/show.snap
new file mode 100644
index 000000000..8f2992065
--- /dev/null
+++ b/spec/views/networks/__snapshots__/networks/show.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Réseau Name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/networks/__snapshots__/networks/show_create.snap b/spec/views/networks/__snapshots__/networks/show_create.snap
new file mode 100644
index 000000000..8f2992065
--- /dev/null
+++ b/spec/views/networks/__snapshots__/networks/show_create.snap
@@ -0,0 +1,4 @@
+<div class="container-fluid"><div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Réseau Name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div>
+</div></div> \ No newline at end of file
diff --git a/spec/views/networks/__snapshots__/networks/show_destroy.snap b/spec/views/networks/__snapshots__/networks/show_destroy.snap
new file mode 100644
index 000000000..c525c05b7
--- /dev/null
+++ b/spec/views/networks/__snapshots__/networks/show_destroy.snap
@@ -0,0 +1,7 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Réseau Name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right"><a data-confirm="Etes vous sûr de supprimer ce réseau ?" class="btn btn-primary" rel="nofollow" data-method="delete" href="/line_referentials/99/networks/909"><span class="fa fa-trash mr-xs"></span>Supprimer ce réseau</a></div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/networks/__snapshots__/networks/show_update.snap b/spec/views/networks/__snapshots__/networks/show_update.snap
new file mode 100644
index 000000000..35f8ee9ac
--- /dev/null
+++ b/spec/views/networks/__snapshots__/networks/show_update.snap
@@ -0,0 +1,7 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Réseau Name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right"><a class="btn btn-primary" href="/line_referentials/99/networks/909/edit">Editer ce réseau</a></div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/networks/index.html.erb_spec.rb b/spec/views/networks/index.html.erb_spec.rb
index d2dde7f87..80e755163 100644
--- a/spec/views/networks/index.html.erb_spec.rb
+++ b/spec/views/networks/index.html.erb_spec.rb
@@ -3,7 +3,11 @@ require 'spec_helper'
describe "/networks/index", :type => :view do
let!(:line_referential) { assign :line_referential, create(:line_referential) }
- let!(:networks) { assign :networks, Array.new(2){ create(:network, line_referential: line_referential) }.paginate }
+ let(:context){{line_referential: line_referential}}
+ let!(:networks) do
+ assign :networks, build_paginated_collection(:network, NetworkDecorator, line_referential: line_referential, context: context)
+ end
+
let!(:search) { assign :q, Ransack::Search.new(Chouette::Network) }
# it "should render a show link for each group" do
@@ -18,5 +22,27 @@ describe "/networks/index", :type => :view do
# render
# expect(view.content_for(:sidebar)).to have_selector("a[href='#{new_line_referential_network_path(line_referential)}']")
# end
+ before(:each) do
+ allow(view).to receive(:collection).and_return(networks)
+ allow(view).to receive(:decorated_collection).and_return(networks)
+ allow(view).to receive(:current_referential).and_return(line_referential)
+ controller.request.path_parameters[:line_referential_id] = line_referential.id
+ allow(view).to receive(:params).and_return({action: :index})
+ end
+
+ describe "action links" do
+ set_invariant "line_referential.id", "99"
+
+ before(:each){
+ render template: "networks/index", layout: "layouts/application"
+ }
+
+ it { should match_actions_links_snapshot "networks/index" }
+ %w(create update destroy).each do |p|
+ with_permission "networks.#{p}" do
+ it { should match_actions_links_snapshot "networks/index_#{p}" }
+ end
+ end
+ end
end
diff --git a/spec/views/networks/show.html.erb_spec.rb b/spec/views/networks/show.html.erb_spec.rb
index 3926ead14..998e8ac44 100644
--- a/spec/views/networks/show.html.erb_spec.rb
+++ b/spec/views/networks/show.html.erb_spec.rb
@@ -11,8 +11,30 @@ describe "/networks/show", :type => :view do
let!(:map) { assign(:map, double(:to_html => '<div id="map"/>'.html_safe)) }
let!(:line_referential) { assign :line_referential, network.line_referential }
- # it "should display a map with class 'network'" do
- # render
- # expect(rendered).to have_selector("#map")
- # end
+ before(:each) do
+ allow(view).to receive(:current_referential).and_return(line_referential)
+ allow(view).to receive(:resource).and_return(network)
+ controller.request.path_parameters[:line_referential_id] = line_referential.id
+ controller.request.path_parameters[:id] = network.id
+ allow(view).to receive(:params).and_return({action: :show})
+ end
+
+ describe "action links" do
+ set_invariant "line_referential.id", "99"
+ set_invariant "network.object.id", "909"
+ set_invariant "network.object.updated_at", "2018/01/23".to_time
+ set_invariant "network.object.name", "Name"
+
+ before(:each){
+ render template: "networks/show", layout: "layouts/application"
+ }
+
+ it { should match_actions_links_snapshot "networks/show" }
+
+ %w(create update destroy).each do |p|
+ with_permission "networks.#{p}" do
+ it { should match_actions_links_snapshot "networks/show_#{p}" }
+ end
+ end
+ end
end
diff --git a/spec/views/offer_workbenches/show.html.erb_spec.rb b/spec/views/offer_workbenches/show.html.erb_spec.rb
index 40b09268a..2a2642911 100644
--- a/spec/views/offer_workbenches/show.html.erb_spec.rb
+++ b/spec/views/offer_workbenches/show.html.erb_spec.rb
@@ -1,5 +1,62 @@
-require 'rails_helper'
+require 'spec_helper'
-RSpec.describe "workbenches/show.html.erb", :type => :view do
+RSpec::Matchers.define :have_box_for_item do |item, disabled|
+ match do |actual|
+ klass = "#{TableBuilderHelper.item_row_class_name([item])}-#{item.id}"
+ if disabled
+ selector = "tr.#{klass} [type=checkbox][disabled][value='#{item.id}']"
+ else
+ selector = "tr.#{klass} [type=checkbox][value='#{item.id}']:not([disabled])"
+ end
+ expect(actual).to have_selector(selector, count: 1)
+ end
+ description { "have a #{disabled ? "disabled ": ""}box for the item ##{item.id}" }
+end
+
+describe "workbenches/show", :type => :view do
+ let!(:ids) { ['STIF:CODIFLIGNE:Line:C00840', 'STIF:CODIFLIGNE:Line:C00086'] }
+ let!(:lines) {
+ ids.map do |id|
+ create :line, objectid: id, line_referential: workbench.line_referential
+ end
+ }
+ let!(:workbench){ assign :workbench, create(:workbench) }
+ let!(:same_organisation_referential){ create :workbench_referential, workbench: workbench, metadatas: [create(:referential_metadata, lines: lines)] }
+ let!(:different_organisation_referential) do
+ create(
+ :workbench_referential,
+ workbench: create(:workbench, workgroup: workbench.workgroup),
+ metadatas: [create(:referential_metadata, lines: lines)]
+ )
+ end
+ let!(:referentials){
+ same_organisation_referential && different_organisation_referential
+ assign :wbench_refs, paginate_collection(Referential, ReferentialDecorator)
+ }
+ let!(:q) { assign :q_for_form, Ransack::Search.new(Referential) }
+ before :each do
+ lines
+ controller.request.path_parameters[:id] = workbench.id
+ expect(workbench.referentials).to include same_organisation_referential
+ expect(workbench.referentials).to_not include different_organisation_referential
+ expect(workbench.all_referentials).to include same_organisation_referential
+ expect(workbench.all_referentials).to include different_organisation_referential
+ render
+ end
+
+ it { should have_link_for_each_item(referentials, "show", -> (referential){ view.referential_path(referential) }) }
+
+ context "without permission" do
+ it "should disable all the checkboxes" do
+ expect(rendered).to have_box_for_item same_organisation_referential, false
+ expect(rendered).to have_box_for_item different_organisation_referential, true
+ end
+ end
+ with_permission "referentials.destroy" do
+ it "should enable the checkbox for the referential which belongs to the same organisation and disable the other one" do
+ expect(rendered).to have_box_for_item same_organisation_referential, false
+ expect(rendered).to have_box_for_item different_organisation_referential, true
+ end
+ end
end
diff --git a/spec/views/referentials/__snapshots__/referentials/show.snap b/spec/views/referentials/__snapshots__/referentials/show.snap
new file mode 100644
index 000000000..83531ac0e
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_create.snap b/spec/views/referentials/__snapshots__/referentials/show_create.snap
new file mode 100644
index 000000000..e5d309b96
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_create.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" href="/referentials/new?from=99">Dupliquer</a><a class="btn btn-primary" href="/referentials/99/select_compliance_control_set">Valider</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_destroy.snap b/spec/views/referentials/__snapshots__/referentials/show_destroy.snap
new file mode 100644
index 000000000..d90198391
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_destroy.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a data-confirm="Etes vous sûr de vouloir supprimer ce jeu de données ?" class="btn btn-primary" rel="nofollow" data-method="delete" href="/referentials/99"><span class="fa fa-trash mr-xs"></span>Supprimer</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_purchase_windows.snap b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows.snap
new file mode 100644
index 000000000..83531ac0e
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_create.snap b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_create.snap
new file mode 100644
index 000000000..e5d309b96
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_create.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" href="/referentials/new?from=99">Dupliquer</a><a class="btn btn-primary" href="/referentials/99/select_compliance_control_set">Valider</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_destroy.snap b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_destroy.snap
new file mode 100644
index 000000000..d90198391
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_destroy.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a data-confirm="Etes vous sûr de vouloir supprimer ce jeu de données ?" class="btn btn-primary" rel="nofollow" data-method="delete" href="/referentials/99"><span class="fa fa-trash mr-xs"></span>Supprimer</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_update.snap b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_update.snap
new file mode 100644
index 000000000..32d46beda
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_update.snap
@@ -0,0 +1,12 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action">
+<div class="small last-update">Dernière mise à jour le 01/01/2000</div>
+<a class="btn btn-default" href="/referentials/99/edit">Editer</a>
+</div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" rel="nofollow" data-method="put" href="/referentials/99/archive">Conserver</a><button type="button" data-toggle="modal" data-target="#purgeModal" class="btn btn-primary">Purger</button>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_readonly.snap b/spec/views/referentials/__snapshots__/referentials/show_readonly.snap
new file mode 100644
index 000000000..83531ac0e
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_readonly.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_readonly_create.snap b/spec/views/referentials/__snapshots__/referentials/show_readonly_create.snap
new file mode 100644
index 000000000..82a77521a
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_readonly_create.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" href="/referentials/new?from=99">Dupliquer</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_readonly_destroy.snap b/spec/views/referentials/__snapshots__/referentials/show_readonly_destroy.snap
new file mode 100644
index 000000000..83531ac0e
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_readonly_destroy.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_readonly_update.snap b/spec/views/referentials/__snapshots__/referentials/show_readonly_update.snap
new file mode 100644
index 000000000..83531ac0e
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_readonly_update.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys.snap b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys.snap
new file mode 100644
index 000000000..83531ac0e
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_create.snap b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_create.snap
new file mode 100644
index 000000000..e5d309b96
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_create.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" href="/referentials/new?from=99">Dupliquer</a><a class="btn btn-primary" href="/referentials/99/select_compliance_control_set">Valider</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_destroy.snap b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_destroy.snap
new file mode 100644
index 000000000..d90198391
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_destroy.snap
@@ -0,0 +1,9 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a data-confirm="Etes vous sûr de vouloir supprimer ce jeu de données ?" class="btn btn-primary" rel="nofollow" data-method="delete" href="/referentials/99"><span class="fa fa-trash mr-xs"></span>Supprimer</a>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_update.snap b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_update.snap
new file mode 100644
index 000000000..32d46beda
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_update.snap
@@ -0,0 +1,12 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action">
+<div class="small last-update">Dernière mise à jour le 01/01/2000</div>
+<a class="btn btn-default" href="/referentials/99/edit">Editer</a>
+</div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" rel="nofollow" data-method="put" href="/referentials/99/archive">Conserver</a><button type="button" data-toggle="modal" data-target="#purgeModal" class="btn btn-primary">Purger</button>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/__snapshots__/referentials/show_update.snap b/spec/views/referentials/__snapshots__/referentials/show_update.snap
new file mode 100644
index 000000000..32d46beda
--- /dev/null
+++ b/spec/views/referentials/__snapshots__/referentials/show_update.snap
@@ -0,0 +1,12 @@
+<div class="container-fluid">
+<div class="row">
+<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div>
+<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action">
+<div class="small last-update">Dernière mise à jour le 01/01/2000</div>
+<a class="btn btn-default" href="/referentials/99/edit">Editer</a>
+</div></div>
+</div>
+<div class="row mb-sm"><div class="col-lg-12 text-right">
+<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" rel="nofollow" data-method="put" href="/referentials/99/archive">Conserver</a><button type="button" data-toggle="modal" data-target="#purgeModal" class="btn btn-primary">Purger</button>
+</div></div>
+</div> \ No newline at end of file
diff --git a/spec/views/referentials/show.html.erb_spec.rb b/spec/views/referentials/show.html.erb_spec.rb
index f1fa7188a..ea3bc1fe1 100644
--- a/spec/views/referentials/show.html.erb_spec.rb
+++ b/spec/views/referentials/show.html.erb_spec.rb
@@ -1,4 +1,73 @@
require 'spec_helper'
describe "referentials/show", type: :view do
+ let!(:referential) do
+ referential = create(:referential, organisation: organisation)
+ assign :referential, referential.decorate(context: {
+ current_organisation: referential.organisation
+ })
+ end
+ let(:permissions){ [] }
+ let(:current_organisation) { organisation }
+ let(:current_offer_workbench) { create :workbench, organisation: organisation}
+ let(:current_workgroup) { current_offer_workbench.workgroup }
+ let(:readonly){ false }
+
+ before :each do
+ assign :reflines, []
+ allow(view).to receive(:current_offer_workbench).and_return(current_offer_workbench)
+ allow(view).to receive(:current_organisation).and_return(current_organisation)
+ allow(view).to receive(:current_workgroup).and_return(current_workgroup)
+ allow(view).to receive(:current_user).and_return(current_user)
+
+ allow(view).to receive(:resource).and_return(referential)
+ allow(view).to receive(:has_feature?).and_return(true)
+ allow(view).to receive(:user_signed_in?).and_return true
+ controller.request.path_parameters[:id] = referential.id
+ allow(view).to receive(:params).and_return({action: :show})
+
+ allow(referential).to receive(:referential_read_only?){ readonly }
+ end
+
+ describe "action links" do
+ set_invariant "referential.object.full_name", "referential_full_name"
+ set_invariant "referential.object.updated_at", "01/01/2000 00:00".to_time
+ set_invariant "referential.object.id", "99"
+
+ before(:each){
+ render template: "referentials/show", layout: "layouts/application"
+ }
+ context "with a readonly referential" do
+ let(:readonly){ true }
+ it { should match_actions_links_snapshot "referentials/show_readonly" }
+
+ %w(create destroy update).each do |p|
+ with_permission "referentials.#{p}" do
+ it { should match_actions_links_snapshot "referentials/show_readonly_#{p}" }
+ end
+ end
+ end
+
+ context "with a non-readonly referential" do
+ it { should match_actions_links_snapshot "referentials/show" }
+
+ %w(create destroy update).each do |p|
+ with_permission "referentials.#{p}" do
+ it { should match_actions_links_snapshot "referentials/show_#{p}" }
+ end
+ end
+ end
+
+ %w(purchase_windows referential_vehicle_journeys).each do |f|
+ with_feature f do
+ it { should match_actions_links_snapshot "referentials/show_#{f}" }
+
+ %w(create update destroy).each do |p|
+ with_permission "referentials.#{p}" do
+ it { should match_actions_links_snapshot "referentials/show_#{f}_#{p}" }
+ end
+ end
+ end
+ end
+ end
end
diff --git a/spec/views/stop_areas/edit.html.erb_spec.rb b/spec/views/stop_areas/edit.html.erb_spec.rb
index 5105bff4b..bfbb0bb55 100644
--- a/spec/views/stop_areas/edit.html.erb_spec.rb
+++ b/spec/views/stop_areas/edit.html.erb_spec.rb
@@ -6,6 +6,10 @@ describe "/stop_areas/edit", :type => :view do
let!(:stop_area) { assign(:stop_area, create(:stop_area)) }
let!(:map) { assign(:map, double(:to_html => '<div id="map"/>'.html_safe)) }
+ before do
+ allow(view).to receive(:has_feature?)
+ end
+
describe "form" do
it "should render input for name" do
render
@@ -13,6 +17,5 @@ describe "/stop_areas/edit", :type => :view do
with_tag "input[type=text][name='stop_area[name]'][value=?]", stop_area.name
end
end
-
end
end
diff --git a/spec/views/stop_areas/index.html.erb_spec.rb b/spec/views/stop_areas/index.html.erb_spec.rb
deleted file mode 100644
index 2dfae1bfd..000000000
--- a/spec/views/stop_areas/index.html.erb_spec.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-require 'spec_helper'
-
-describe "/stop_areas/index", :type => :view do
-
- let!(:stop_area_referential) { assign :stop_area_referential, create(:stop_area_referential) }
- let!(:stop_areas) { assign :stop_areas, Array.new(2) { create(:stop_area, stop_area_referential: stop_area_referential) }.paginate }
- let!(:q) { assign :q, Ransack::Search.new(Chouette::StopArea) }
-
- before :each do
- allow(view).to receive(:link_with_search).and_return("#")
- end
-
- # it "should render a show link for each group" do
- # render
- # stop_areas.each do |stop_area|
- # expect(rendered).to have_selector(".stop_area a[href='#{view.stop_area_referential_stop_area_path(stop_area_referential, stop_area)}']", :text => stop_area.name)
- # end
- # end
- #
- # it "should render a link to create a new group" do
- # render
- # expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_stop_area_referential_stop_area_path(stop_area_referential)}']")
- # end
-
-end
diff --git a/spec/views/stop_areas/index.html.slim_spec.rb b/spec/views/stop_areas/index.html.slim_spec.rb
new file mode 100644
index 000000000..6e66c5ab9
--- /dev/null
+++ b/spec/views/stop_areas/index.html.slim_spec.rb
@@ -0,0 +1,77 @@
+require 'spec_helper'
+
+describe "/stop_areas/index", :type => :view do
+ let(:deactivated_stop_area){ nil }
+ let(:stop_area_referential) { assign :stop_area_referential, create(:stop_area_referential) }
+ let(:stop_areas) do
+ assign :stop_areas, build_paginated_collection(:stop_area, StopAreaDecorator, stop_area_referential: stop_area_referential)
+ end
+ let!(:q) { assign :q, Ransack::Search.new(Chouette::StopArea) }
+
+ before :each do
+ deactivated_stop_area
+ allow(view).to receive(:link_with_search).and_return("#")
+ allow(view).to receive(:collection).and_return(stop_areas)
+ allow(view).to receive(:current_referential).and_return(stop_area_referential)
+ allow(view).to receive(:params).and_return({action: :index})
+ controller.request.path_parameters[:stop_area_referential_id] = stop_area_referential.id
+ render
+ end
+
+ common_items = ->{
+ it { should have_link_for_each_item(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) }
+ }
+
+ common_items.call()
+ it { should have_the_right_number_of_links(stop_areas, 1) }
+
+ with_permission "stop_areas.create" do
+ common_items.call()
+ it { should_not have_link_for_each_item(stop_areas, "create", -> (stop_area){ view.new_stop_area_referential_stop_area_path(stop_area_referential) }) }
+ it { should have_the_right_number_of_links(stop_areas, 1) }
+ end
+
+ with_permission "stop_areas.update" do
+ common_items.call()
+ it { should have_link_for_each_item(stop_areas, "edit", -> (stop_area){ view.edit_stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) }
+ it { should have_the_right_number_of_links(stop_areas, 2) }
+ end
+
+ with_permission "stop_areas.change_status" do
+ common_items.call()
+ it { should have_link_for_each_item(stop_areas, "deactivate", -> (stop_area){ view.deactivate_stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) }
+ it { should have_the_right_number_of_links(stop_areas, 2) }
+ end
+
+ with_permission "stop_areas.destroy" do
+ common_items.call()
+ it {
+ should have_link_for_each_item(stop_areas, "destroy", {
+ href: ->(stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area)},
+ method: :delete
+ })
+ }
+ it { should have_the_right_number_of_links(stop_areas, 2) }
+ end
+
+ context "with a deactivated item" do
+ with_permission "stop_areas.change_status" do
+ let(:deactivated_stop_area){ create :stop_area, :deactivated, stop_area_referential: stop_area_referential }
+
+ common_items.call()
+ it "should display an activate link for the deactivated one" do
+ stop_areas.each do |stop_area|
+ if stop_area == deactivated_stop_area
+ href = view.activate_stop_area_referential_stop_area_path(stop_area_referential, stop_area)
+ else
+ href = view.deactivate_stop_area_referential_stop_area_path(stop_area_referential, stop_area)
+ end
+ selector = "tr.#{TableBuilderHelper.item_row_class_name(stop_areas)}-#{stop_area.id} .actions a[href='#{href}']"
+ expect(rendered).to have_selector(selector, count: 1)
+ end
+ end
+ it { should have_the_right_number_of_links(stop_areas, 2) }
+ end
+ end
+
+end
diff --git a/spec/views/stop_areas/new.html.erb_spec.rb b/spec/views/stop_areas/new.html.erb_spec.rb
index 749782349..23f7387fa 100644
--- a/spec/views/stop_areas/new.html.erb_spec.rb
+++ b/spec/views/stop_areas/new.html.erb_spec.rb
@@ -5,6 +5,10 @@ describe "/stop_areas/new", :type => :view do
let!(:stop_area_referential) { assign :stop_area_referential, stop_area.stop_area_referential }
let!(:stop_area) { assign(:stop_area, build(:stop_area)) }
+ before do
+ allow(view).to receive(:has_feature?)
+ end
+
describe "form" do
it "should render input for name" do
diff --git a/spec/views/vehicle_journeys/index.html.slim_spec.rb b/spec/views/vehicle_journeys/index.html.slim_spec.rb
new file mode 100644
index 000000000..920067fa9
--- /dev/null
+++ b/spec/views/vehicle_journeys/index.html.slim_spec.rb
@@ -0,0 +1,31 @@
+require 'spec_helper'
+
+describe "/vehicle_journeys/index", :type => :view do
+
+ let!(:referential) { assign :referential, create(:referential) }
+ let!(:line) { assign :line, create(:line) }
+ let!(:route) { assign :route, create(:route, line: line) }
+ let!(:vehicle_journeys) do
+ assign :vehicle_journeys, build_paginated_collection(:vehicle_journey, nil, route: route)
+ end
+
+ before :each do
+ allow(view).to receive(:link_with_search).and_return("#")
+ allow(view).to receive(:collection).and_return(vehicle_journeys)
+ allow(view).to receive(:current_referential).and_return(referential)
+ allow(view).to receive(:has_feature?).and_return(true)
+ controller.request.path_parameters[:referential_id] = referential.id
+ render
+ end
+
+ context "with an opposite_route" do
+ let!(:route) { assign :route, create(:route, :with_opposite, line: line) }
+
+ it "should have an 'oppposite route timetable' button" do
+ href = view.referential_line_route_vehicle_journeys_path(referential, line, route.opposite_route)
+ oppposite_button_selector = "a[href=\"#{href}\"]"
+
+ expect(view.content_for(:page_header_content)).to have_selector oppposite_button_selector
+ end
+ end
+end
diff --git a/spec/views/vehicle_journeys/new.html.erb_spec.rb b/spec/views/vehicle_journeys/new.html.erb_spec.rb
index 546e89ac8..3408a8a26 100644
--- a/spec/views/vehicle_journeys/new.html.erb_spec.rb
+++ b/spec/views/vehicle_journeys/new.html.erb_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe "/vehicle_journeys/new", :type => :view do
-
+
assign_referential
let!(:line) { assign :line, create(:line) }
let!(:route) { assign :route, create(:route, :line => line) }
@@ -13,4 +13,3 @@ describe "/vehicle_journeys/new", :type => :view do
end
end
-
diff --git a/spec/workers/referential_cloning_worker_spec.rb b/spec/workers/referential_cloning_worker_spec.rb
index 7e4a2357a..74e83c3b2 100644
--- a/spec/workers/referential_cloning_worker_spec.rb
+++ b/spec/workers/referential_cloning_worker_spec.rb
@@ -2,52 +2,35 @@ require 'spec_helper'
require 'ostruct'
RSpec.describe ReferentialCloningWorker do
+ alias_method :worker, :subject
context "given a referential cloning" do
+ let(:id) { double }
+ let(:referential_cloning) { double }
- let( :id ){ double }
+ it "invokes the clone! method of the associated ReferentialCloning" do
+ expect(ReferentialCloning).to receive(:find).with(id).and_return(referential_cloning)
+ expect(referential_cloning).to receive(:clone_with_status!)
- 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 ){ "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( 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( referential_cloning ).to receive(:successful!)
worker.perform(id)
end
end
- it "should clone an existing Referential" do
- source_referential = create :referential
-
- source_referential.switch
- source_time_table = create :time_table
+ context 'with existing Referential' do
+ it "preserve existing data" do
+ source_referential = create :referential
- target_referential = create :referential, created_from: source_referential
+ source_referential.switch
+ source_time_table = create :time_table
- cloning = ReferentialCloning.create source_referential: source_referential, target_referential: target_referential
- ReferentialCloningWorker.new.perform(cloning)
+ target_referential = create :referential, created_from: source_referential
- target_referential.switch
- expect(Chouette::TimeTable.where(objectid: source_time_table.objectid).exists?)
- end
+ cloning = ReferentialCloning.create source_referential: source_referential, target_referential: target_referential
+ worker.perform(cloning.id)
+ target_referential.switch
+ expect(Chouette::TimeTable.where(objectid: source_time_table.objectid).exists?)
+ end
+ end
end
diff --git a/spec/workers/workbench_import/workbench_import_with_corrupt_zip_spec.rb b/spec/workers/workbench_import/workbench_import_with_corrupt_zip_spec.rb
deleted file mode 100644
index 47626f5a1..000000000
--- a/spec/workers/workbench_import/workbench_import_with_corrupt_zip_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-RSpec.describe WorkbenchImportWorker do
-
- shared_examples_for 'corrupt zipfile data' do
- subject { described_class.new }
- let( :workbench_import ){ create :workbench_import, status: :pending }
-
- before do
- # Let us make sure that the name Enterprise will never be forgotten by history,
- # ahem, I meant, that nothing is uploaded, by forbidding any message to be sent
- # to HTTPService
- expect_it.to receive(:download).and_return(downloaded)
- end
-
- it 'does not upload' do
- stub_const 'HTTPService', double('HTTPService')
- subject.perform(workbench_import.id)
- end
-
- it 'does create a message' do
- expect{ subject.perform(workbench_import.id) }.to change{ workbench_import.messages.count }.by(1)
-
- message = workbench_import.messages.last
- expect( message.criticity ).to eq('error')
- expect( message.message_key ).to eq('corrupt_zip_file')
- expect( message.message_attributes ).to eq( 'source_filename' => workbench_import.file.file.file )
- end
-
- it 'does not change current step' do
- expect{ subject.perform(workbench_import.id) }.not_to change{ workbench_import.current_step }
- end
-
- it "sets the workbench_import.status to failed" do
- subject.perform(workbench_import.id)
- expect( workbench_import.reload.status ).to eq('failed')
- end
- end
-
- context 'empty zip file' do
- let( :downloaded ){ '' }
- it_should_behave_like 'corrupt zipfile data'
- end
-
- context 'corrupt data' do
- let( :downloaded ){ very_random }
- it_should_behave_like 'corrupt zipfile data'
- end
-end
diff --git a/spec/workers/workbench_import/workbench_import_worker_spec.rb b/spec/workers/workbench_import/workbench_import_worker_spec.rb
deleted file mode 100644
index 47ca2b4ff..000000000
--- a/spec/workers/workbench_import/workbench_import_worker_spec.rb
+++ /dev/null
@@ -1,169 +0,0 @@
-RSpec.describe WorkbenchImportWorker, type: [:worker, :request] do
-
- let( :worker ) { described_class.new }
- let( :import ){ build_stubbed :import, token_download: download_token, file: zip_file }
-
- let( :workbench ){ import.workbench }
- let( :referential ){ import.referential }
- let( :api_key ){ build_stubbed :api_key, referential: referential, token: "#{referential.id}-#{random_hex}" }
-
- # http://www.example.com/workbenches/:workbench_id/imports/:id/download
- let( :host ){ Rails.configuration.rails_host }
- let( :path ){ download_workbench_import_path(workbench, import) }
-
- let( :downloaded_zip ){ double("downloaded zip") }
- let( :download_zip_response ){ OpenStruct.new( body: downloaded_zip ) }
- let( :download_token ){ random_string }
-
- let( :upload_path ) { api_v1_netex_imports_path(format: :json) }
-
- let( :spurious ){ [[], [], []] }
- let( :subdirs ) do
- entry_count.times.map do |i|
- ZipService::Subdir.new(
- "subdir #{i}",
- double("subdir #{i}", rewind: 0, read: ''),
- spurious[i]
- )
- end
- end
-
- let( :zip_service ){ double("zip service") }
- let( :zip_file ){ open_fixture('multiple_references_import.zip') }
-
- let( :post_response_ok ){ double(status: 201, body: "{}") }
-
- before do
- Timecop.freeze(Time.now)
-
- # Silence Logger
- allow_any_instance_of(Logger).to receive(:info)
- allow_any_instance_of(Logger).to receive(:warn)
-
- # That should be `build_stubbed's` job, no?
- allow(Import).to receive(:find).with(import.id).and_return(import)
-
- allow(Api::V1::ApiKey).to receive(:from).and_return(api_key)
- allow(ZipService).to receive(:new).with(downloaded_zip).and_return zip_service
- expect(zip_service).to receive(:subdirs).and_return(subdirs)
- expect( import ).to receive(:update).with(
- status: 'running',
- started_at: Time.now
- )
- end
-
- after do
- Timecop.return
- end
-
-
- context 'multireferential zipfile, no errors' do
- let( :entry_count ){ 2 }
-
- it 'downloads a zip file, cuts it, and uploads all pieces' do
-
- expect(HTTPService).to receive(:get_resource)
- .with(host: host, path: path, params: {token: download_token})
- .and_return( download_zip_response )
-
- subdirs.each do |subdir|
- mock_post subdir, post_response_ok
- end
-
- expect( import ).to receive(:update).with(total_steps: 2)
- expect( import ).to receive(:update).with(current_step: 1)
- expect( import ).to receive(:update).with(current_step: 2)
- expect( import ).to receive(:update).with(ended_at: Time.now)
-
- worker.perform import.id
-
- end
- end
-
- context 'multireferential zipfile with error' do
- let( :entry_count ){ 3 }
- let( :post_response_failure ){ double(status: 406, body: {error: 'What was you thinking'}) }
-
- it 'downloads a zip file, cuts it, and uploads some pieces' do
- expect(HTTPService).to receive(:get_resource)
- .with(host: host, path: path, params: {token: download_token})
- .and_return( download_zip_response )
-
- # First subdir succeeds
- subdirs[0..0].each do |subdir|
- mock_post subdir, post_response_ok
- end
-
- # Second subdir fails (M I S E R A B L Y)
- subdirs[1..1].each do |subdir|
- mock_post subdir, post_response_failure
- end
-
- expect( import ).to receive(:update).with(total_steps: 3)
- expect( import ).to receive(:update).with(current_step: 1)
- expect( import ).to receive(:update).with(current_step: 2)
- expect( import ).to receive(:update).with(current_step: 3, status: 'failed')
-
- expect { worker.perform import.id }.to raise_error(StopIteration)
- end
- end
-
- context 'multireferential zipfile with spurious directories' do
- let( :entry_count ){ 2 }
- let( :spurious1 ){ [random_string] }
- let( :spurious2 ){ [random_string, random_string] }
- let( :spurious ){ [spurious1, spurious2] }
- let( :messages ){ double('messages') }
- let( :message_attributes ){{criticity: :warning, message_key: 'inconsistent_zip_file'}}
- let( :message1_attributes ){ message_attributes.merge(message_attributes: {'source_filename' => import.file.file.file, 'spurious_dirs' => spurious1.join(', ')}) }
- let( :message2_attributes ){ message_attributes.merge(message_attributes: {'source_filename' => import.file.file.file, 'spurious_dirs' => spurious2.join(', ')}) }
-
- before do
- allow(import).to receive(:messages).and_return(messages)
- end
-
- it 'downloads a zip file, cuts it, and uploads all pieces and adds messages' do
-
- expect(HTTPService).to receive(:get_resource)
- .with(host: host, path: path, params: {token: download_token})
- .and_return( download_zip_response )
-
- subdirs.each do |subdir|
- mock_post subdir, post_response_ok
- end
-
- expect( import ).to receive(:update).with(total_steps: 2)
- expect( import ).to receive(:update).with(current_step: 1)
- expect( messages ).to receive(:create).with(message1_attributes)
- expect( import ).to receive(:update).with(current_step: 2)
- expect( messages ).to receive(:create).with(message2_attributes)
- expect( import ).to receive(:update).with(ended_at: Time.now)
-
- worker.perform import.id
-
- end
-
- end
-
- def mock_post subdir, response
- allow(HTTPService).to receive(:upload)
- expect( HTTPService ).to receive(:post_resource)
- .with(
- host: host,
- path: upload_path,
- params: {
- netex_import: {
- parent_id: import.id,
- parent_type: import.class.name,
- workbench_id: workbench.id,
- name: subdir.name,
- file: HTTPService.upload(
- subdir.stream,
- 'application/zip',
- "#{subdir.name}.zip"
- )
- }
- }
- ).and_return(response)
- end
-end
diff --git a/spec/workers/workbench_import_worker_spec.rb b/spec/workers/workbench_import_worker_spec.rb
new file mode 100644
index 000000000..310693e1e
--- /dev/null
+++ b/spec/workers/workbench_import_worker_spec.rb
@@ -0,0 +1,102 @@
+RSpec.describe WorkbenchImportWorker, type: [:worker, :request, :zip] do
+
+ def self.expect_upload_with *entry_names, &blk
+ let(:expected_upload_names){ Set.new(entry_names.flatten) }
+
+ it "uploads the following entries: #{entry_names.flatten.inspect}" do
+ allow( HTTPService ).to receive(:post_resource)
+ .with(host: host, path: upload_path, params: anything) { |params|
+ name = params[:params][:netex_import][:name]
+ raise RuntimeError, "unexpected upload of entry #{name}" unless expected_upload_names.delete?(name)
+ OpenStruct.new(status: 201)
+ }
+ instance_eval(&blk)
+ expect( expected_upload_names ).to be_empty, "the following expected uploads were not executed: #{expected_upload_names.to_a.inspect}"
+ end
+ end
+
+ let( :lines ){ %w{*:C00109 *:C00108}.to_json }
+ let!( :organisation ){ workbench.organisation.update sso_attributes: {'functional_scope' => lines}}
+
+ let( :worker ) { described_class.new }
+ let( :workbench_import ){ create :workbench_import, token_download: download_token }
+
+ let( :workbench ){ workbench_import.workbench }
+
+ # http://www.example.com/workbenches/:workbench_id/imports/:id/download
+ let( :host ){ Rails.configuration.rails_host }
+ let( :path ){ download_workbench_import_path(workbench, workbench_import) }
+ let( :upload_path ){ api_v1_netex_imports_path(format: :json) }
+
+ let( :downloaded_zip_archive ){ make_zip_from_tree zip_data_dir }
+ let( :downloaded_zip_data ){ downloaded_zip_archive.data }
+ let( :download_token ){ random_string }
+
+ before do
+ stub_request(:get, "#{ host }#{ path }?token=#{ workbench_import.token_download }").
+ to_return(body: downloaded_zip_data, status: :success)
+ end
+
+ context 'correct workbench_import' do
+ let( :zip_data_dir ){ fixtures_path 'two_referentials_ok' }
+
+ expect_upload_with %w{ OFFRE_TRANSDEV_20170301122517 OFFRE_TRANSDEV_20170301122519 } do
+ expect{ worker.perform( workbench_import.id ) }.not_to change{ workbench_import.messages.count }
+ expect( workbench_import.reload.attributes.values_at(*%w{current_step total_steps}) )
+ .to eq([2, 2])
+ expect( workbench_import.reload.status ).to eq('running')
+ end
+
+ end
+
+ context 'correct but spurious directories' do
+ let( :zip_data_dir ){ fixtures_path 'extra_file_nok' }
+
+ expect_upload_with [] do
+ expect{ worker.perform( workbench_import.id ) }.to change{ workbench_import.messages.count }.by(1)
+ expect( workbench_import.reload.attributes.values_at(*%w{current_step total_steps}) )
+ .to eq([0, 0])
+ expect( workbench_import.messages.last.message_key ).to eq('inconsistent_zip_file')
+ expect( workbench_import.reload.status ).to eq('running')
+ end
+ end
+
+ context 'foreign lines' do
+ let( :zip_data_dir ){ fixtures_path 'some_foreign_mixed' }
+
+ expect_upload_with %w{ OFFRE_TRANSDEV_20170301122517 OFFRE_TRANSDEV_20170301122519 } do
+ expect{ worker.perform( workbench_import.id ) }.to change{ workbench_import.messages.count }.by(1)
+ expect( workbench_import.reload.attributes.values_at(*%w{current_step total_steps}) )
+ .to eq([2, 2])
+ expect( workbench_import.messages.last.message_key ).to eq('foreign_lines_in_referential')
+ expect( workbench_import.reload.status ).to eq('running')
+ end
+
+ end
+
+ context 'foreign and spurious' do
+ let( :zip_data_dir ){ fixtures_path 'foreign_and_spurious' }
+
+ expect_upload_with %w{ OFFRE_TRANSDEV_20170301122517 OFFRE_TRANSDEV_20170301122519 } do
+ expect{ worker.perform( workbench_import.id ) }.to change{ workbench_import.messages.count }.by(2)
+ expect( workbench_import.reload.attributes.values_at(*%w{current_step total_steps}) )
+ .to eq([2, 2])
+ expect( workbench_import.messages.last(2).map(&:message_key).sort )
+ .to eq(%w{foreign_lines_in_referential inconsistent_zip_file})
+ expect( workbench_import.reload.status ).to eq('running')
+ end
+ end
+
+ context 'corrupt zip file' do
+ let( :downloaded_zip_archive ){ OpenStruct.new(data: '') }
+
+ it 'will not upload anything' do
+ expect(HTTPService).not_to receive(:post_resource)
+ expect{ worker.perform( workbench_import.id ) }.to change{ workbench_import.messages.count }.by(1)
+ expect( workbench_import.messages.last.message_key ).to eq('corrupt_zip_file')
+ expect( workbench_import.reload.status ).to eq('failed')
+ end
+
+ end
+
+end