aboutsummaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
authorEdouard Maffert2016-09-09 10:13:18 +0200
committerEdouard Maffert2016-09-09 10:13:18 +0200
commitfebca10492e68c10a18f48860577bf21748bc7cd (patch)
treee46ea4f92ae2d8b5408a4f6acbca8660dce29f5d /spec
parenta1f01c4eb5b3f8cc587775fedc825bbfb2f100d9 (diff)
parent4425686bdf93f9d90187244b2f336043934cc75e (diff)
downloadchouette-core-febca10492e68c10a18f48860577bf21748bc7cd.tar.bz2
Merge branch 'master' into staging
Diffstat (limited to 'spec')
-rw-r--r--spec/fabricators/user_fabricator.rb8
-rw-r--r--spec/factories/chouette_2_factories.rb1
-rw-r--r--spec/factories/chouette_companies.rb4
-rw-r--r--spec/factories/chouette_group_of_lines.rb2
-rw-r--r--spec/factories/chouette_lines.rb2
-rw-r--r--spec/factories/chouette_networks.rb2
-rw-r--r--spec/factories/line_referential_syncs.rb16
-rw-r--r--spec/factories/line_referentials.rb1
-rw-r--r--spec/factories/line_sync_operations.rb6
-rw-r--r--spec/features/companies_spec.rb2
-rw-r--r--spec/features/group_of_lines_spec.rb2
-rw-r--r--spec/features/lines_spec.rb2
-rw-r--r--spec/features/networks_spec.rb28
-rw-r--r--spec/features/users/user_edit_spec.rb2
-rw-r--r--spec/features/users/user_index_spec.rb1
-rw-r--r--spec/features/users/user_show_spec.rb3
-rw-r--r--spec/fixtures/organizations.json98
-rwxr-xr-xspec/fixtures/reflex.xml222
-rw-r--r--spec/fixtures/reflex.zipbin0 -> 2469 bytes
-rwxr-xr-xspec/fixtures/reflex_updated.xml207
-rw-r--r--spec/fixtures/reflex_updated.zipbin0 -> 2469 bytes
-rw-r--r--spec/fixtures/users.json144
-rw-r--r--spec/models/chouette/line_spec.rb2
-rw-r--r--spec/models/line_referential_spec.rb1
-rw-r--r--spec/models/line_referential_sync_spec.rb23
-rw-r--r--spec/models/line_sync_operation_spec.rb9
-rw-r--r--spec/models/organisation_spec.rb37
-rw-r--r--spec/models/user_spec.rb103
-rw-r--r--spec/spec_helper.rb13
-rw-r--r--spec/support/devise.rb2
-rw-r--r--spec/tasks/reflex_rake_spec.rb61
-rw-r--r--spec/views/referentials/edit.html.erb_spec.rb2
-rw-r--r--spec/views/referentials/new.html.erb_spec.rb2
-rw-r--r--spec/views/referentials/show.html.erb_spec.rb2
34 files changed, 971 insertions, 39 deletions
diff --git a/spec/fabricators/user_fabricator.rb b/spec/fabricators/user_fabricator.rb
new file mode 100644
index 000000000..04c1c6279
--- /dev/null
+++ b/spec/fabricators/user_fabricator.rb
@@ -0,0 +1,8 @@
+Fabricator :user do
+ email { sequence(:email) { |i| "user#{i}@example.com" } }
+ name { sequence(:name) { |i| "fname#{i}" } }
+
+ password { 'password' }
+
+ username { "#{FFaker::Name.first_name.parameterize}.#{FFaker::Name.last_name.parameterize}" }
+end \ No newline at end of file
diff --git a/spec/factories/chouette_2_factories.rb b/spec/factories/chouette_2_factories.rb
index 6234f6540..b88b0d773 100644
--- a/spec/factories/chouette_2_factories.rb
+++ b/spec/factories/chouette_2_factories.rb
@@ -2,6 +2,7 @@ FactoryGirl.define do
factory :organisation do
sequence(:name) { |n| "Organisation #{n}" }
+ sequence(:code) { |n| "000#{n}" }
end
factory :referential do
diff --git a/spec/factories/chouette_companies.rb b/spec/factories/chouette_companies.rb
index c0e46fe42..35ce34257 100644
--- a/spec/factories/chouette_companies.rb
+++ b/spec/factories/chouette_companies.rb
@@ -2,8 +2,10 @@ FactoryGirl.define do
factory :company, :class => Chouette::Company do
sequence(:name) { |n| "Company #{n}" }
- sequence(:objectid) { |n| "test:Company:#{n}" }
+ sequence(:objectid) { |n| "chouette:test:Company:#{n}" }
sequence(:registration_number) { |n| "test-#{n}" }
+
+ association :line_referential, :factory => :line_referential
end
end
diff --git a/spec/factories/chouette_group_of_lines.rb b/spec/factories/chouette_group_of_lines.rb
index 75fef2ce9..75739d6d3 100644
--- a/spec/factories/chouette_group_of_lines.rb
+++ b/spec/factories/chouette_group_of_lines.rb
@@ -2,7 +2,7 @@ FactoryGirl.define do
factory :group_of_line, :class => Chouette::GroupOfLine do
sequence(:name) { |n| "Group Of Line #{n}" }
- sequence(:objectid) { |n| "test:GroupOfLine:#{n}" }
+ sequence(:objectid) { |n| "chouette:test:GroupOfLine:#{n}" }
sequence(:registration_number) { |n| "#{n}" }
association :line_referential
diff --git a/spec/factories/chouette_lines.rb b/spec/factories/chouette_lines.rb
index 0a720da48..da79f8c98 100644
--- a/spec/factories/chouette_lines.rb
+++ b/spec/factories/chouette_lines.rb
@@ -2,7 +2,7 @@ FactoryGirl.define do
factory :line, :class => Chouette::Line do
sequence(:name) { |n| "Line #{n}" }
- sequence(:objectid) { |n| "test:Line:#{n}" }
+ sequence(:objectid) { |n| "chouette:test:Line:#{n}" }
sequence(:transport_mode_name) { |n| "Bus" }
association :network, :factory => :network
diff --git a/spec/factories/chouette_networks.rb b/spec/factories/chouette_networks.rb
index 8f9bfea51..f9cc4b5d6 100644
--- a/spec/factories/chouette_networks.rb
+++ b/spec/factories/chouette_networks.rb
@@ -2,7 +2,7 @@ FactoryGirl.define do
factory :network, :class => Chouette::Network do
sequence(:name) { |n| "Network #{n}" }
- sequence(:objectid) { |n| "test:GroupOfLine:#{n}" }
+ sequence(:objectid) { |n| "chouette:test:GroupOfLine:#{n}" }
sequence(:registration_number) { |n| "test-#{n}" }
end
diff --git a/spec/factories/line_referential_syncs.rb b/spec/factories/line_referential_syncs.rb
new file mode 100644
index 000000000..86b1a2182
--- /dev/null
+++ b/spec/factories/line_referential_syncs.rb
@@ -0,0 +1,16 @@
+FactoryGirl.define do
+ factory :line_referential_sync do
+ line_referential nil
+
+ factory :line_referential_sync_with_record do
+ transient do
+ line_sync_operations_count rand(1..30)
+ end
+
+ after(:create) do |line_referential_sync, evaluator|
+ create_list(:line_sync_operation, evaluator.line_sync_operations_count, line_referential_sync: line_referential_sync)
+ end
+
+ end
+ end
+end
diff --git a/spec/factories/line_referentials.rb b/spec/factories/line_referentials.rb
index cfce1399f..47d0727c5 100644
--- a/spec/factories/line_referentials.rb
+++ b/spec/factories/line_referentials.rb
@@ -1,5 +1,6 @@
FactoryGirl.define do
factory :line_referential do
sequence(:name) { |n| "Line Referential #{n}" }
+ association :line_referential_sync, :factory => :line_referential_sync
end
end
diff --git a/spec/factories/line_sync_operations.rb b/spec/factories/line_sync_operations.rb
new file mode 100644
index 000000000..3d353bb3b
--- /dev/null
+++ b/spec/factories/line_sync_operations.rb
@@ -0,0 +1,6 @@
+FactoryGirl.define do
+ factory :line_sync_operation do
+ status ["OK","KO"].sample
+ line_referential_sync nil
+ end
+end
diff --git a/spec/features/companies_spec.rb b/spec/features/companies_spec.rb
index 3628d04f0..c85f6f2cd 100644
--- a/spec/features/companies_spec.rb
+++ b/spec/features/companies_spec.rb
@@ -31,7 +31,7 @@ describe "Companies", :type => :feature do
click_link "Ajouter un transporteur"
fill_in "company_name", :with => "Company 1"
fill_in "Numéro d'enregistrement", :with => "test-1"
- fill_in "Identifiant Neptune", :with => "test:Company:1"
+ fill_in "Identifiant Neptune", :with => "chouette:test:Company:1"
click_button("Créer transporteur")
expect(page).to have_content("Company 1")
end
diff --git a/spec/features/group_of_lines_spec.rb b/spec/features/group_of_lines_spec.rb
index 202f9f1c4..f6de06c8b 100644
--- a/spec/features/group_of_lines_spec.rb
+++ b/spec/features/group_of_lines_spec.rb
@@ -44,7 +44,7 @@ describe "Group of lines", :type => :feature do
click_link I18n.t('group_of_lines.actions.new')
fill_in "group_of_line[name]", :with => "Group of lines 1"
fill_in "group_of_line[registration_number]", :with => "1"
- fill_in "group_of_line[objectid]", :with => "test:GroupOfLine:999"
+ fill_in "group_of_line[objectid]", :with => "chouette:test:GroupOfLine:999"
click_button(I18n.t('formtastic.create',model: I18n.t('activerecord.models.group_of_line.one')))
expect(page).to have_content("Group of lines 1")
end
diff --git a/spec/features/lines_spec.rb b/spec/features/lines_spec.rb
index 91185c22e..67303e05b 100644
--- a/spec/features/lines_spec.rb
+++ b/spec/features/lines_spec.rb
@@ -41,7 +41,7 @@ describe "Lines", :type => :feature do
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 => "test:Line:999"
+ fill_in "Identifiant Neptune", :with => "chouette:test:Line:999"
click_button("Créer ligne")
expect(page).to have_content("Line 1")
end
diff --git a/spec/features/networks_spec.rb b/spec/features/networks_spec.rb
index c2433f04e..b68dda558 100644
--- a/spec/features/networks_spec.rb
+++ b/spec/features/networks_spec.rb
@@ -16,39 +16,39 @@ describe "Networks", :type => :feature do
end
- describe "show" do
+ describe "show" do
it "display network" do
- allow(subject).to receive(:stop_areas).and_return(Array.new(2) { create(:stop_area) })
+ # allow(subject).to receive(:stop_areas).and_return(Array.new(2) { create(:stop_area) })
visit referential_networks_path(referential)
click_link "#{networks.first.name}"
expect(page).to have_content(networks.first.name)
end
- it "display map" do
- allow(subject).to receive(:stop_areas).and_return(Array.new(2) { create(:stop_area) })
- visit referential_networks_path(referential)
- click_link "#{networks.first.name}"
- expect(page).to have_selector("#map.network")
- end
+ # it "display map" do
+ # # allow(subject).to receive(:stop_areas).and_return(Array.new(2) { create(:stop_area) })
+ # visit referential_networks_path(referential)
+ # click_link "#{networks.first.name}"
+ # expect(page).to have_selector("#map.network")
+ # end
end
- describe "new" do
+ describe "new" do
it "creates network and return to show" do
- allow(subject).to receive(:stop_areas).and_return(Array.new(2) { create(:stop_area) })
+ # allow(subject).to receive(:stop_areas).and_return(Array.new(2) { create(:stop_area) })
visit referential_networks_path(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 => "test:GroupOfLine:1"
+ fill_in "Identifiant Neptune", :with => "chouette:test:GroupOfLine:1"
click_button("Créer réseau")
expect(page).to have_content("Network 1")
end
end
- describe "edit and return to show" do
+ describe "edit and return to show" do
it "edit network" do
- allow(subject).to receive(:stop_areas).and_return(Array.new(2) { create(:stop_area) })
+ # allow(subject).to receive(:stop_areas).and_return(Array.new(2) { create(:stop_area) })
visit referential_network_path(referential, subject)
click_link "Modifier ce réseau"
fill_in "network_name", :with => "Network Modified"
@@ -58,7 +58,7 @@ describe "Networks", :type => :feature do
end
end
- # describe "delete", :js => true do
+ # describe "delete", :js => true do
# it "delete network and return to the list" do
# subject.stub(:stop_areas).and_return(Array.new(2) { create(:stop_area) })
# visit referential_network_path(referential, subject)
diff --git a/spec/features/users/user_edit_spec.rb b/spec/features/users/user_edit_spec.rb
index c7c742416..23a58ecae 100644
--- a/spec/features/users/user_edit_spec.rb
+++ b/spec/features/users/user_edit_spec.rb
@@ -36,9 +36,7 @@ feature 'User edit', :devise do
# Then I see my own 'edit profile' page
scenario "user cannot cannot edit another user's profile", :me do
me = FactoryGirl.create(:user)
- me.confirm!
other = FactoryGirl.create(:user, email: 'other@example.com')
- other.confirm!
login_as(me, :scope => :user)
visit edit_user_registration_path(other)
expect(page).to have_content 'Votre Profil'
diff --git a/spec/features/users/user_index_spec.rb b/spec/features/users/user_index_spec.rb
index 2f6ec4426..2a9199da3 100644
--- a/spec/features/users/user_index_spec.rb
+++ b/spec/features/users/user_index_spec.rb
@@ -19,7 +19,6 @@ feature 'User index page', :devise do
# Then I see my own email address
scenario 'user sees own email address' do
user = create(:user)
- user.confirm!
login_as(user, scope: :user)
visit organisation_path
expect(page).to have_content user.name.truncate(15)
diff --git a/spec/features/users/user_show_spec.rb b/spec/features/users/user_show_spec.rb
index 4a56e3255..d840d752c 100644
--- a/spec/features/users/user_show_spec.rb
+++ b/spec/features/users/user_show_spec.rb
@@ -19,7 +19,6 @@ feature 'User profile page', :devise do
# Then I see my own email address
scenario 'user sees own profile' do
user = FactoryGirl.create(:user)
- user.confirm!
login_as(user, :scope => :user)
visit organisation_user_path(user)
# FIXME ref #819
@@ -33,9 +32,7 @@ feature 'User profile page', :devise do
# Then I see an 'access denied' message
scenario "user cannot see another user's profile" do
me = FactoryGirl.create(:user)
- me.confirm!
other = FactoryGirl.create(:user, email: 'other@example.com', :organisation => me.organisation)
- other.confirm!
login_as(me, :scope => :user)
Capybara.current_session.driver.header 'Referer', authenticated_root_path
visit organisation_user_path(other)
diff --git a/spec/fixtures/organizations.json b/spec/fixtures/organizations.json
new file mode 100644
index 000000000..b70f99520
--- /dev/null
+++ b/spec/fixtures/organizations.json
@@ -0,0 +1,98 @@
+[{
+ "id": 1,
+ "name": "STIF",
+ "code": "STIF",
+ "created_at": "2016-05-17T15:33:45.951Z",
+ "updated_at": "2016-05-17T15:33:45.951Z",
+ "organization_users": {
+ "users_count": 9
+ },
+ "suborganizations": {
+ "suborganizations_count": 4,
+ "suborganizations": [{
+ "id": 6,
+ "name": "ALBATRANS",
+ "code": "ALBATRANS"
+ }, {
+ "id": 5,
+ "name": "OPTILE",
+ "code": "OPTILE"
+ }, {
+ "id": 2,
+ "name": "RATP",
+ "code": "RATP"
+ }, {
+ "id": 3,
+ "name": "SNCF",
+ "code": "SNCF"
+ }]
+ }
+}, {
+ "id": 3,
+ "name": "SNCF",
+ "code": "SNCF",
+ "created_at": "2016-05-17T16:04:27.047Z",
+ "updated_at": "2016-05-17T16:04:27.047Z",
+ "organization_users": {
+ "users_count": 2
+ },
+ "suborganizations": {
+ "suborganizations_count": 0,
+ "suborganizations": []
+ },
+ "organization_parent": {
+ "parent_id": 1,
+ "parent_name": "STIF"
+ }
+}, {
+ "id": 5,
+ "name": "OPTILE",
+ "code": "OPTILE",
+ "created_at": "2016-05-17T16:04:27.655Z",
+ "updated_at": "2016-05-17T16:04:27.655Z",
+ "organization_users": {
+ "users_count": 0
+ },
+ "suborganizations": {
+ "suborganizations_count": 0,
+ "suborganizations": []
+ },
+ "organization_parent": {
+ "parent_id": 1,
+ "parent_name": "STIF"
+ }
+}, {
+ "id": 6,
+ "name": "ALBATRANS",
+ "code": "ALBATRANS",
+ "created_at": "2016-05-17T16:04:27.955Z",
+ "updated_at": "2016-05-17T16:04:27.955Z",
+ "organization_users": {
+ "users_count": 0
+ },
+ "suborganizations": {
+ "suborganizations_count": 0,
+ "suborganizations": []
+ },
+ "organization_parent": {
+ "parent_id": 1,
+ "parent_name": "STIF"
+ }
+}, {
+ "id": 2,
+ "name": "RATP",
+ "code": "RATP",
+ "created_at": "2016-05-17T16:04:26.646Z",
+ "updated_at": "2016-05-31T10:06:39.349Z",
+ "organization_users": {
+ "users_count": 8
+ },
+ "suborganizations": {
+ "suborganizations_count": 0,
+ "suborganizations": []
+ },
+ "organization_parent": {
+ "parent_id": 1,
+ "parent_name": "STIF"
+ }
+}]
diff --git a/spec/fixtures/reflex.xml b/spec/fixtures/reflex.xml
new file mode 100755
index 000000000..1a7f37728
--- /dev/null
+++ b/spec/fixtures/reflex.xml
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PublicationDelivery xsi:schemaLocation="http://www.netex.org.uk/netex localPathToXSDFileIfNecessary/NeTEx_publication.xsd" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:acsb="http://www.ifopt.org.uk/acsb" xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:netex="http://www.netex.org.uk/netex" xmlns:siri="http://www.siri.org.uk/siri" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <PublicationTimestamp>2016-08-11T06:00:46.0Z</PublicationTimestamp>
+ <ParticipantRef>SYS001</ParticipantRef>
+ <dataObjects>
+ <CompositeFrame version="1" created="2016-08-11T06:00:46.0Z" id="STIF-REFLEX:CompositeFrame:NETEX_STIF">
+ <frames>
+ <GeneralFrame version="001" id="STIF-REFLEX:TypeOfFrame:NETEX_COMMUN">
+ <Name>Frame NETEX_COMMUN</Name>
+ <Description>Frame NETEX_COMMUN</Description>
+ <members modificationSet="all">
+ <GeneralGroupOfEntities version="657750" created="2015-04-21T10:04:37.0Z" changed="2015-04-21T10:04:37.0Z" id="FR:91479:GDL:415731:STIF">
+ <Name>Aéroport d'Orly</Name>
+ <PurposeOfGroupingRef version="any" ref="NETEX_ARRET_STIF:PurposeOfGrouping:groupOfStopPlace"/>
+ <members>
+ <StopPlaceRef ref="FR:91479:LDA:63284:STIF">version=63284</StopPlaceRef>
+ <StopPlaceRef ref="FR:91479:LDA:63278:STIF">version=63278</StopPlaceRef>
+ </members>
+ </GeneralGroupOfEntities>
+ <GeneralGroupOfEntities version="657753" created="2015-04-21T10:04:57.0Z" changed="2015-04-21T10:04:57.0Z" id="FR:77282:GDL:415732:STIF">
+ <Name>Aéroport Roissy Charles de Gaulle</Name>
+ <PurposeOfGroupingRef version="any" ref="NETEX_ARRET_STIF:PurposeOfGrouping:groupOfStopPlace"/>
+ <members>
+ <StopPlaceRef ref="FR:77282:LDA:69212:STIF">version=69212</StopPlaceRef>
+ <StopPlaceRef ref="FR:93073:LDA:412554:STIF">version=480224</StopPlaceRef>
+ <StopPlaceRef ref="FR:93073:LDA:412553:STIF">version=480203</StopPlaceRef>
+ <StopPlaceRef ref="FR:77291:LDA:73699:STIF">version=654808</StopPlaceRef>
+ <StopPlaceRef ref="FR:null:LDA:412679:STIF">version=483360</StopPlaceRef>
+ <StopPlaceRef ref="FR:95527:LDA:74162:STIF">version=739348</StopPlaceRef>
+ <StopPlaceRef ref="FR:77291:LDA:411293:STIF">version=411628</StopPlaceRef>
+ <StopPlaceRef ref="FR:93073:LDA:73596:STIF">version=73596</StopPlaceRef>
+ <StopPlaceRef ref="FR:93073:LDA:73846:STIF">version=73846</StopPlaceRef>
+ <StopPlaceRef ref="FR:77291:LDA:73845:STIF">version=73845</StopPlaceRef>
+ <StopPlaceRef ref="FR:77291:LDA:73595:STIF">version=73595</StopPlaceRef>
+ </members>
+ </GeneralGroupOfEntities>
+ <GeneralGroupOfEntities version="657747" created="2015-04-21T10:04:27.0Z" changed="2015-04-21T10:04:27.0Z" id="FR:75115:GDL:415730:STIF">
+ <Name>Gare Montparnasse</Name>
+ <PurposeOfGroupingRef version="any" ref="NETEX_ARRET_STIF:PurposeOfGrouping:groupOfStopPlace"/>
+ <members>
+ <StopPlaceRef ref="FR:75115:LDA:71139:STIF">version=657746</StopPlaceRef>
+ </members>
+ </GeneralGroupOfEntities>
+ <ValueSet version="any" id="NETEX_ARRET_STIF:ValueSet:VS01">
+ <values>
+ <PurposeOfGrouping version="any" id="NETEX_ARRET_STIF:PurposeOfGrouping:groupOfStopPlace">
+ <Name>Group of Stop Place</Name>
+ <classes>
+ <ClassRef nameOfClass="StopPlace"/>
+ </classes>
+ </PurposeOfGrouping>
+ </values>
+ </ValueSet>
+ </members>
+ </GeneralFrame>
+ <GeneralFrame version="001" id="STIF-REFLEX:TypeOfFrame:NETEX_ARRET_STIF">
+ <Name>Frame NETEX_ARRET_STIF</Name>
+ <Description>Frame NETEX_ARRET_STIF</Description>
+ <members modificationSet="all">
+ <StopPlace version="777416" created="2014-12-29T03:12:51.0Z" changed="2016-07-26T12:07:19.0Z" id="FR:77153:LDA:69325:STIF">
+ <Name>First stopPlace</Name>
+ <placeTypes>
+ <TypeOfPlaceRef ref="LDA"/>
+ </placeTypes>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:69325">
+ <Town>Dammartin-en-Goële</Town>
+ <PostalRegion>77153</PostalRegion>
+ </PostalAddress>
+ <AccessibilityAssessment version="any" id="STIF-REFLEX:AccessibilityAssessment:69325">
+ <MobilityImpairedAccess>false</MobilityImpairedAccess>
+ </AccessibilityAssessment>
+ <StopPlaceType>onstreetBus</StopPlaceType>
+ </StopPlace>
+ <StopPlace version="42564" created="2014-12-29T03:12:51.0Z" changed="2014-12-29T03:12:51.0Z" id="FR:77153:ZDL:42564:STIF">
+ <keyList>
+ <KeyValue typeOfKey="OBJET_QUALIFIER">
+ <Key>OBJECT_STATUS</Key>
+ <Value>REFERENCE_OBJECT</Value>
+ </KeyValue>
+ </keyList>
+ <Name>First stopPlace children</Name>
+ <placeTypes>
+ <TypeOfPlaceRef ref="ZDL"/>
+ </placeTypes>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:42564">
+ <Town>Dammartin-en-Goële</Town>
+ <PostalRegion>77153</PostalRegion>
+ </PostalAddress>
+ <AccessibilityAssessment version="any" id="STIF-REFLEX:AccessibilityAssessment:42564">
+ <MobilityImpairedAccess>false</MobilityImpairedAccess>
+ </AccessibilityAssessment>
+ <ParentSiteRef ref="FR:77153:LDA:69325:STIF" version="777416"/>
+ <entrances>
+ <StopPlaceEntrance version="174" id="FR:91421:ADL:174:STIF">
+ <Name>Montgeron Crosne - Rue Du Moulin De Senlis</Name>
+ <Centroid>
+ <Location>
+ <gml:pos srsName="EPSG:2154">660491.94 6845481.0</gml:pos>
+ </Location>
+ </Centroid>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:174">
+ <Town>Montgeron</Town>
+ <PostalRegion>91421</PostalRegion>
+ </PostalAddress>
+ <IsEntry>true</IsEntry>
+ <IsExit>true</IsExit>
+ </StopPlaceEntrance>
+ <StopPlaceEntrance version="173" id="FR:91421:ADL:173:STIF">
+ <Name>Montgeron Crosne - Rue Du Moulin De Senlis</Name>
+ <Centroid>
+ <Location>
+ <gml:pos srsName="EPSG:2154">660324.94 6845590.5</gml:pos>
+ </Location>
+ </Centroid>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:173">
+ <Town>Montgeron</Town>
+ <PostalRegion>91421</PostalRegion>
+ </PostalAddress>
+ <IsEntry>true</IsEntry>
+ <IsExit>true</IsExit>
+ </StopPlaceEntrance>
+ </entrances>
+ <StopPlaceType>onstreetBus</StopPlaceType>
+ <quays>
+ <QuayRef ref="FR:77153:ZDE:38240:STIF" version="782150"/>
+ </quays>
+ </StopPlace>
+
+ <StopPlace version="779971" created="2014-12-29T12:12:00.0Z" changed="2016-07-28T03:07:39.0Z" id="FR:95277:LDA:65926:STIF">
+ <Name>Second StopPlace</Name>
+ <placeTypes>
+ <TypeOfPlaceRef ref="LDA"/>
+ </placeTypes>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:65926">
+ <Town>Gonesse</Town>
+ <PostalRegion>95277</PostalRegion>
+ </PostalAddress>
+ <AccessibilityAssessment version="any" id="STIF-REFLEX:AccessibilityAssessment:65926">
+ <MobilityImpairedAccess>false</MobilityImpairedAccess>
+ </AccessibilityAssessment>
+ <StopPlaceType>onstreetBus</StopPlaceType>
+ </StopPlace>
+ <StopPlace version="779966" created="2014-12-29T03:12:51.0Z" changed="2016-07-28T03:07:56.0Z" id="FR:95277:ZDL:46738:STIF">
+ <keyList>
+ <KeyValue typeOfKey="OBJET_QUALIFIER">
+ <Key>OBJECT_STATUS</Key>
+ <Value>REFERENCE_OBJECT</Value>
+ </KeyValue>
+ </keyList>
+ <Name>Second StopPlace children</Name>
+ <placeTypes>
+ <TypeOfPlaceRef ref="ZDL"/>
+ </placeTypes>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:46738">
+ <Town>Gonesse</Town>
+ <PostalRegion>95277</PostalRegion>
+ </PostalAddress>
+ <AccessibilityAssessment version="any" id="STIF-REFLEX:AccessibilityAssessment:46738">
+ <MobilityImpairedAccess>false</MobilityImpairedAccess>
+ </AccessibilityAssessment>
+ <ParentSiteRef ref="FR:95277:LDA:65926:STIF" version="779971"/>
+ <StopPlaceType>onstreetBus</StopPlaceType>
+ <quays>
+ <QuayRef ref="FR:95277:ZDE:38010:STIF" version="777963"/>
+ </quays>
+ </StopPlace>
+ <Quay version="783636" created="2014-12-29T03:12:51.0Z" changed="2016-08-05T10:08:59.0Z" id="FR:95277:ZDE:38010:STIF">
+ <keyList>
+ <KeyValue typeOfKey="OBJET_QUALIFIER">
+ <Key>OBJECT_STATUS</Key>
+ <Value>REFERENCE_OBJECT</Value>
+ </KeyValue>
+ <KeyValue typeOfKey="OBJET_QUALIFIER">
+ <Key>LINE_ID</Key>
+ <Value>002002003</Value>
+ </KeyValue>
+ </keyList>
+ <Name>Quay of Second StopPlace children</Name>
+ <Centroid>
+ <Location>
+ <gml:pos srsName="EPSG:2154">657252.0 6847664.0</gml:pos>
+ </Location>
+ </Centroid>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:21634">
+ <Town>Ablon-sur-Seine</Town>
+ <PostalRegion>94001</PostalRegion>
+ </PostalAddress>
+ <AccessibilityAssessment version="any" id="STIF-REFLEX:AccessibilityAssessment:21634">
+ <MobilityImpairedAccess>false</MobilityImpairedAccess>
+ </AccessibilityAssessment>
+ </Quay>
+ <Quay version="783636" created="2014-12-29T03:12:51.0Z" changed="2016-08-05T10:08:59.0Z" id="FR:77153:ZDE:38240:STIF">
+ <keyList>
+ <KeyValue typeOfKey="OBJET_QUALIFIER">
+ <Key>OBJECT_STATUS</Key>
+ <Value>REFERENCE_OBJECT</Value>
+ </KeyValue>
+ <KeyValue typeOfKey="OBJET_QUALIFIER">
+ <Key>LINE_ID</Key>
+ <Value>002002003</Value>
+ </KeyValue>
+ </keyList>
+ <Name>Quay of First stopPlace children</Name>
+ <Centroid>
+ <Location>
+ <gml:pos srsName="EPSG:2154">657252.0 6847664.0</gml:pos>
+ </Location>
+ </Centroid>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:21634">
+ <Town>Ablon-sur-Seine</Town>
+ <PostalRegion>94001</PostalRegion>
+ </PostalAddress>
+ <AccessibilityAssessment version="any" id="STIF-REFLEX:AccessibilityAssessment:21634">
+ <MobilityImpairedAccess>false</MobilityImpairedAccess>
+ </AccessibilityAssessment>
+ </Quay>
+ </members>
+ </GeneralFrame>
+ </frames>
+ </CompositeFrame>
+ </dataObjects>
+</PublicationDelivery>
diff --git a/spec/fixtures/reflex.zip b/spec/fixtures/reflex.zip
new file mode 100644
index 000000000..7c8858a8f
--- /dev/null
+++ b/spec/fixtures/reflex.zip
Binary files differ
diff --git a/spec/fixtures/reflex_updated.xml b/spec/fixtures/reflex_updated.xml
new file mode 100755
index 000000000..e49b84759
--- /dev/null
+++ b/spec/fixtures/reflex_updated.xml
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PublicationDelivery xsi:schemaLocation="http://www.netex.org.uk/netex localPathToXSDFileIfNecessary/NeTEx_publication.xsd" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:acsb="http://www.ifopt.org.uk/acsb" xmlns:ifopt="http://www.ifopt.org.uk/ifopt" xmlns:netex="http://www.netex.org.uk/netex" xmlns:siri="http://www.siri.org.uk/siri" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <PublicationTimestamp>2016-08-11T06:00:46.0Z</PublicationTimestamp>
+ <ParticipantRef>SYS001</ParticipantRef>
+ <dataObjects>
+ <CompositeFrame version="1" created="2016-08-11T06:00:46.0Z" id="STIF-REFLEX:CompositeFrame:NETEX_STIF">
+ <frames>
+ <GeneralFrame version="001" id="STIF-REFLEX:TypeOfFrame:NETEX_COMMUN">
+ <Name>Frame NETEX_COMMUN</Name>
+ <Description>Frame NETEX_COMMUN</Description>
+ <members modificationSet="all">
+ <GeneralGroupOfEntities version="657750" created="2015-04-21T10:04:37.0Z" changed="2015-04-21T10:04:37.0Z" id="FR:91479:GDL:415731:STIF">
+ <Name>Aéroport d'Orly</Name>
+ <PurposeOfGroupingRef version="any" ref="NETEX_ARRET_STIF:PurposeOfGrouping:groupOfStopPlace"/>
+ <members>
+ <StopPlaceRef ref="FR:91479:LDA:63284:STIF">version=63284</StopPlaceRef>
+ <StopPlaceRef ref="FR:91479:LDA:63278:STIF">version=63278</StopPlaceRef>
+ </members>
+ </GeneralGroupOfEntities>
+ <GeneralGroupOfEntities version="657753" created="2015-04-21T10:04:57.0Z" changed="2015-04-21T10:04:57.0Z" id="FR:77282:GDL:415732:STIF">
+ <Name>Aéroport Roissy Charles de Gaulle</Name>
+ <PurposeOfGroupingRef version="any" ref="NETEX_ARRET_STIF:PurposeOfGrouping:groupOfStopPlace"/>
+ <members>
+ <StopPlaceRef ref="FR:77282:LDA:69212:STIF">version=69212</StopPlaceRef>
+ <StopPlaceRef ref="FR:93073:LDA:412554:STIF">version=480224</StopPlaceRef>
+ <StopPlaceRef ref="FR:93073:LDA:412553:STIF">version=480203</StopPlaceRef>
+ <StopPlaceRef ref="FR:77291:LDA:73699:STIF">version=654808</StopPlaceRef>
+ <StopPlaceRef ref="FR:null:LDA:412679:STIF">version=483360</StopPlaceRef>
+ <StopPlaceRef ref="FR:95527:LDA:74162:STIF">version=739348</StopPlaceRef>
+ <StopPlaceRef ref="FR:77291:LDA:411293:STIF">version=411628</StopPlaceRef>
+ <StopPlaceRef ref="FR:93073:LDA:73596:STIF">version=73596</StopPlaceRef>
+ <StopPlaceRef ref="FR:93073:LDA:73846:STIF">version=73846</StopPlaceRef>
+ <StopPlaceRef ref="FR:77291:LDA:73845:STIF">version=73845</StopPlaceRef>
+ <StopPlaceRef ref="FR:77291:LDA:73595:STIF">version=73595</StopPlaceRef>
+ </members>
+ </GeneralGroupOfEntities>
+ <GeneralGroupOfEntities version="657747" created="2015-04-21T10:04:27.0Z" changed="2015-04-21T10:04:27.0Z" id="FR:75115:GDL:415730:STIF">
+ <Name>Gare Montparnasse</Name>
+ <PurposeOfGroupingRef version="any" ref="NETEX_ARRET_STIF:PurposeOfGrouping:groupOfStopPlace"/>
+ <members>
+ <StopPlaceRef ref="FR:75115:LDA:71139:STIF">version=657746</StopPlaceRef>
+ </members>
+ </GeneralGroupOfEntities>
+ <ValueSet version="any" id="NETEX_ARRET_STIF:ValueSet:VS01">
+ <values>
+ <PurposeOfGrouping version="any" id="NETEX_ARRET_STIF:PurposeOfGrouping:groupOfStopPlace">
+ <Name>Group of Stop Place</Name>
+ <classes>
+ <ClassRef nameOfClass="StopPlace"/>
+ </classes>
+ </PurposeOfGrouping>
+ </values>
+ </ValueSet>
+ </members>
+ </GeneralFrame>
+ <GeneralFrame version="001" id="STIF-REFLEX:TypeOfFrame:NETEX_ARRET_STIF">
+ <Name>Frame NETEX_ARRET_STIF</Name>
+ <Description>Frame NETEX_ARRET_STIF</Description>
+ <members modificationSet="all">
+ <StopPlace version="777416" created="2014-12-29T03:12:51.0Z" changed="2016-07-26T12:07:19.0Z" id="FR:77153:LDA:69325:STIF">
+ <Name>First stopPlace edited</Name>
+ <placeTypes>
+ <TypeOfPlaceRef ref="LDA"/>
+ </placeTypes>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:69325">
+ <Town>Dammartin-en-Goële</Town>
+ <PostalRegion>77153</PostalRegion>
+ </PostalAddress>
+ <AccessibilityAssessment version="any" id="STIF-REFLEX:AccessibilityAssessment:69325">
+ <MobilityImpairedAccess>false</MobilityImpairedAccess>
+ </AccessibilityAssessment>
+ <StopPlaceType>onstreetBus</StopPlaceType>
+ </StopPlace>
+ <StopPlace version="42564" created="2014-12-29T03:12:51.0Z" changed="2014-12-29T03:12:51.0Z" id="FR:77153:ZDL:42564:STIF">
+ <keyList>
+ <KeyValue typeOfKey="OBJET_QUALIFIER">
+ <Key>OBJECT_STATUS</Key>
+ <Value>REFERENCE_OBJECT</Value>
+ </KeyValue>
+ </keyList>
+ <Name>First stopPlace children edited</Name>
+ <placeTypes>
+ <TypeOfPlaceRef ref="ZDL"/>
+ </placeTypes>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:42564">
+ <Town>Dammartin-en-Goële</Town>
+ <PostalRegion>77153</PostalRegion>
+ </PostalAddress>
+ <AccessibilityAssessment version="any" id="STIF-REFLEX:AccessibilityAssessment:42564">
+ <MobilityImpairedAccess>false</MobilityImpairedAccess>
+ </AccessibilityAssessment>
+ <ParentSiteRef ref="FR:77153:LDA:69325:STIF" version="777416"/>
+ <entrances>
+ <StopPlaceEntrance version="174" id="FR:91421:ADL:174:STIF">
+ <Name>Montgeron Crosne - Rue Du Moulin De Senlis</Name>
+ <Centroid>
+ <Location>
+ <gml:pos srsName="EPSG:2154">660491.94 6845481.0</gml:pos>
+ </Location>
+ </Centroid>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:174">
+ <Town>Montgeron</Town>
+ <PostalRegion>91421</PostalRegion>
+ </PostalAddress>
+ <IsEntry>true</IsEntry>
+ <IsExit>true</IsExit>
+ </StopPlaceEntrance>
+ <StopPlaceEntrance version="173" id="FR:91421:ADL:173:STIF">
+ <Name>Montgeron Crosne - Rue Du Moulin De Senlis</Name>
+ <Centroid>
+ <Location>
+ <gml:pos srsName="EPSG:2154">660324.94 6845590.5</gml:pos>
+ </Location>
+ </Centroid>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:173">
+ <Town>Montgeron</Town>
+ <PostalRegion>91421</PostalRegion>
+ </PostalAddress>
+ <IsEntry>true</IsEntry>
+ <IsExit>true</IsExit>
+ </StopPlaceEntrance>
+ </entrances>
+ <StopPlaceType>onstreetBus</StopPlaceType>
+ <quays>
+ <QuayRef ref="FR:77153:ZDE:38240:STIF" version="782150"/>
+ </quays>
+ </StopPlace>
+ <StopPlace version="779966" created="2014-12-29T03:12:51.0Z" changed="2016-07-28T03:07:56.0Z" id="FR:95277:ZDL:46738:STIF">
+ <keyList>
+ <KeyValue typeOfKey="OBJET_QUALIFIER">
+ <Key>OBJECT_STATUS</Key>
+ <Value>REFERENCE_OBJECT</Value>
+ </KeyValue>
+ </keyList>
+ <Name>Second StopPlace children</Name>
+ <placeTypes>
+ <TypeOfPlaceRef ref="ZDL"/>
+ </placeTypes>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:46738">
+ <Town>Gonesse</Town>
+ <PostalRegion>95277</PostalRegion>
+ </PostalAddress>
+ <AccessibilityAssessment version="any" id="STIF-REFLEX:AccessibilityAssessment:46738">
+ <MobilityImpairedAccess>false</MobilityImpairedAccess>
+ </AccessibilityAssessment>
+ <ParentSiteRef ref="FR:95277:LDA:65926:STIF" version="779971"/>
+ <StopPlaceType>onstreetBus</StopPlaceType>
+ <quays>
+ <QuayRef ref="FR:95277:ZDE:38010:STIF" version="777963"/>
+ </quays>
+ </StopPlace>
+ <Quay version="783636" created="2014-12-29T03:12:51.0Z" changed="2016-08-05T10:08:59.0Z" id="FR:95277:ZDE:38010:STIF">
+ <keyList>
+ <KeyValue typeOfKey="OBJET_QUALIFIER">
+ <Key>OBJECT_STATUS</Key>
+ <Value>REFERENCE_OBJECT</Value>
+ </KeyValue>
+ <KeyValue typeOfKey="OBJET_QUALIFIER">
+ <Key>LINE_ID</Key>
+ <Value>002002003</Value>
+ </KeyValue>
+ </keyList>
+ <Name>Quay of Second StopPlace children</Name>
+ <Centroid>
+ <Location>
+ <gml:pos srsName="EPSG:2154">657252.0 6847664.0</gml:pos>
+ </Location>
+ </Centroid>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:21634">
+ <Town>Ablon-sur-Seine</Town>
+ <PostalRegion>94001</PostalRegion>
+ </PostalAddress>
+ <AccessibilityAssessment version="any" id="STIF-REFLEX:AccessibilityAssessment:21634">
+ <MobilityImpairedAccess>false</MobilityImpairedAccess>
+ </AccessibilityAssessment>
+ </Quay>
+ <Quay version="783636" created="2014-12-29T03:12:51.0Z" changed="2016-08-05T10:08:59.0Z" id="FR:77153:ZDE:38240:STIF">
+ <keyList>
+ <KeyValue typeOfKey="OBJET_QUALIFIER">
+ <Key>OBJECT_STATUS</Key>
+ <Value>REFERENCE_OBJECT</Value>
+ </KeyValue>
+ <KeyValue typeOfKey="OBJET_QUALIFIER">
+ <Key>LINE_ID</Key>
+ <Value>002002003</Value>
+ </KeyValue>
+ </keyList>
+ <Name>Quay of First stopPlace children</Name>
+ <Centroid>
+ <Location>
+ <gml:pos srsName="EPSG:2154">657252.0 6847664.0</gml:pos>
+ </Location>
+ </Centroid>
+ <PostalAddress version="any" id="STIF-REFLEX:PostalAddress:21634">
+ <Town>Ablon-sur-Seine</Town>
+ <PostalRegion>94001</PostalRegion>
+ </PostalAddress>
+ <AccessibilityAssessment version="any" id="STIF-REFLEX:AccessibilityAssessment:21634">
+ <MobilityImpairedAccess>false</MobilityImpairedAccess>
+ </AccessibilityAssessment>
+ </Quay>
+ </members>
+ </GeneralFrame>
+ </frames>
+ </CompositeFrame>
+ </dataObjects>
+</PublicationDelivery>
diff --git a/spec/fixtures/reflex_updated.zip b/spec/fixtures/reflex_updated.zip
new file mode 100644
index 000000000..772327c4d
--- /dev/null
+++ b/spec/fixtures/reflex_updated.zip
Binary files differ
diff --git a/spec/fixtures/users.json b/spec/fixtures/users.json
new file mode 100644
index 000000000..d5affc81b
--- /dev/null
+++ b/spec/fixtures/users.json
@@ -0,0 +1,144 @@
+[{
+ "id": 1,
+ "username": "admin",
+ "email": "stif-portail@af83.com",
+ "firstname": "admin",
+ "lastname": "stif",
+ "phone_number": null,
+ "created_at": "2016-08-05T12:33:45.152Z",
+ "updated_at": "2016-08-05T12:33:45.152Z",
+ "locked_at": null,
+ "profile": "Administrateur",
+ "organization_name": "STIF",
+ "organization_code": "STIF"
+}, {
+ "id": 2,
+ "username": "luc.donnet",
+ "email": "luc.donnet@af83.com",
+ "firstname": "Luc",
+ "lastname": "Donnet",
+ "phone_number": "+336 69 25 15 71",
+ "created_at": "2016-08-05T12:34:03.049Z",
+ "updated_at": "2016-08-05T12:34:03.049Z",
+ "locked_at": null,
+ "profile": "Administrateur",
+ "organization_name": "STIF",
+ "organization_code": "STIF"
+}, {
+ "id": 3,
+ "username": "alban.peignier",
+ "email": "alban.peignier@af83.com",
+ "firstname": "Alban",
+ "lastname": "Peignier",
+ "phone_number": "0697099622",
+ "created_at": "2016-08-05T12:34:03.161Z",
+ "updated_at": "2016-08-05T12:34:03.161Z",
+ "locked_at": null,
+ "profile": "Administrateur",
+ "organization_name": "STIF",
+ "organization_code": "STIF"
+}, {
+ "id": 4,
+ "username": "pierre.vabre",
+ "email": "pierre.vabre@af83.com",
+ "firstname": "Pierre",
+ "lastname": "Vabre",
+ "phone_number": "0033778300069",
+ "created_at": "2016-08-05T12:34:03.256Z",
+ "updated_at": "2016-08-05T12:34:03.256Z",
+ "locked_at": null,
+ "profile": "Administrateur",
+ "organization_name": "STIF",
+ "organization_code": "STIF"
+}, {
+ "id": 5,
+ "username": "laure.dubuc",
+ "email": "laure.dubuc@af83.com",
+ "firstname": "Laure",
+ "lastname": "Dubuc",
+ "phone_number": "0302098171",
+ "created_at": "2016-08-05T12:34:03.360Z",
+ "updated_at": "2016-08-05T12:34:03.360Z",
+ "locked_at": null,
+ "profile": "Administrateur",
+ "organization_name": "STIF",
+ "organization_code": "STIF"
+}, {
+ "id": 6,
+ "username": "thomas.haddad",
+ "email": "thomas.haddad@af83.com",
+ "firstname": "Thomas",
+ "lastname": "Haddad",
+ "phone_number": "0033763987210",
+ "created_at": "2016-08-05T12:34:03.457Z",
+ "updated_at": "2016-08-05T12:34:03.457Z",
+ "locked_at": null,
+ "profile": "Administrateur",
+ "organization_name": "STIF",
+ "organization_code": "STIF"
+}, {
+ "id": 7,
+ "username": "jean-paul.lescouzeres",
+ "email": "jean-paul.lescouzeres@af83.com",
+ "firstname": "Jean-Paul",
+ "lastname": "Lescouzères",
+ "phone_number": "0033790632621",
+ "created_at": "2016-08-05T12:34:03.553Z",
+ "updated_at": "2016-08-05T12:34:03.553Z",
+ "locked_at": null,
+ "profile": "Administrateur",
+ "organization_name": "STIF",
+ "organization_code": "STIF"
+}, {
+ "id": 8,
+ "username": "xinhui.xu",
+ "email": "xinhui.xu@af83.com",
+ "firstname": "Xinhui",
+ "lastname": "Xu",
+ "phone_number": "+33799062141",
+ "created_at": "2016-08-05T12:34:03.649Z",
+ "updated_at": "2016-08-05T12:34:03.649Z",
+ "locked_at": null,
+ "profile": "Administrateur",
+ "organization_name": "STIF",
+ "organization_code": "STIF"
+}, {
+ "id": 9,
+ "username": "edouard.maffert",
+ "email": "edouard.maffert@af83.com",
+ "firstname": "Edouard",
+ "lastname": "Maffert",
+ "phone_number": "+33614563995",
+ "created_at": "2016-08-05T12:34:03.756Z",
+ "updated_at": "2016-08-05T12:34:03.756Z",
+ "locked_at": null,
+ "profile": "Administrateur",
+ "organization_name": "STIF",
+ "organization_code": "STIF"
+}, {
+ "id": 10,
+ "username": "john.doe",
+ "email": "john.doe@af83.com",
+ "firstname": "John",
+ "lastname": "Doe",
+ "phone_number": "00337 67 87 93 02",
+ "created_at": "2016-08-05T12:34:03.894Z",
+ "updated_at": "2016-08-05T12:34:03.894Z",
+ "locked_at": null,
+ "profile": "Référent IV Transporteur",
+ "organization_name": "RATP",
+ "organization_code": "RATP"
+}, {
+ "id": 11,
+ "username": "jane.doe",
+ "email": "jane.doe@af83.com",
+ "firstname": "Jane",
+ "lastname": "Doe",
+ "phone_number": "+337 07 54 55 73",
+ "created_at": "2016-08-05T12:34:03.995Z",
+ "updated_at": "2016-08-05T12:34:03.995Z",
+ "locked_at": "2016-08-05T12:34:03.995Z",
+ "profile": "Référent IV Transporteur",
+ "organization_name": "RATP",
+ "organization_code": "RATP"
+}]
diff --git a/spec/models/chouette/line_spec.rb b/spec/models/chouette/line_spec.rb
index 2394db85a..4b22a911d 100644
--- a/spec/models/chouette/line_spec.rb
+++ b/spec/models/chouette/line_spec.rb
@@ -15,7 +15,7 @@ describe Chouette::Line, :type => :model do
describe '#objectid' do
subject { super().objectid }
- it { is_expected.to be_kind_of(Chouette::ObjectId) }
+ it { is_expected.to be_kind_of(Chouette::NetexObjectId) }
end
# it { should validate_numericality_of :objectversion }
diff --git a/spec/models/line_referential_spec.rb b/spec/models/line_referential_spec.rb
index 70c005017..677d61f77 100644
--- a/spec/models/line_referential_spec.rb
+++ b/spec/models/line_referential_spec.rb
@@ -6,4 +6,5 @@ RSpec.describe LineReferential, :type => :model do
end
it { should validate_presence_of(:name) }
+ it { should validate_presence_of(:sync_interval) }
end
diff --git a/spec/models/line_referential_sync_spec.rb b/spec/models/line_referential_sync_spec.rb
new file mode 100644
index 000000000..a237f4d24
--- /dev/null
+++ b/spec/models/line_referential_sync_spec.rb
@@ -0,0 +1,23 @@
+require 'rails_helper'
+
+RSpec.describe LineReferentialSync, :type => :model do
+ it 'should have a valid factory' do
+ expect(FactoryGirl.build(:line_referential_sync)).to be_valid
+ end
+
+ it { is_expected.to belong_to(:line_referential) }
+
+ describe '.record_status'
+ let!(:line_ref_sync) { create(:line_referential_sync) }
+ let!(:line_ref_sync_with_records) { create(:line_referential_sync_with_record, line_sync_operations_count: 30) }
+
+ it 'should add a new record' do
+ line_ref_sync.record_status :ok, "message"
+ expect(line_ref_sync.line_sync_operations.count).to eq(1)
+ end
+
+ it 'should not have more than 30 records' do
+ line_ref_sync_with_records.record_status :ok, "message"
+ expect(line_ref_sync_with_records.line_sync_operations.count).to eq(30)
+ end
+end
diff --git a/spec/models/line_sync_operation_spec.rb b/spec/models/line_sync_operation_spec.rb
new file mode 100644
index 000000000..dab7f1056
--- /dev/null
+++ b/spec/models/line_sync_operation_spec.rb
@@ -0,0 +1,9 @@
+require 'rails_helper'
+
+RSpec.describe LineSyncOperation, :type => :model do
+ it 'should have a valid factory' do
+ expect(FactoryGirl.build(:line_sync_operation)).to be_valid
+ end
+
+ it { is_expected.to belong_to(:line_referential_sync) }
+end
diff --git a/spec/models/organisation_spec.rb b/spec/models/organisation_spec.rb
index fb9d3629b..9d9749b18 100644
--- a/spec/models/organisation_spec.rb
+++ b/spec/models/organisation_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Organisation do
+describe Organisation, :type => :model do
it { should validate_presence_of(:name) }
it { should validate_uniqueness_of(:name) }
@@ -13,4 +13,39 @@ describe Organisation do
organisation = create(:organisation)
organisation.rule_parameter_sets.size.should == 1
end
+
+ describe "Portail sync" do
+ let(:conf) { Rails.application.config.stif_portail_api }
+ before :each do
+ stub_request(:get, "#{conf[:url]}/api/v1/organizations").
+ with(headers: { 'Authorization' => "Token token=\"#{conf[:key]}\"" }).
+ to_return(body: File.open(File.join(Rails.root, 'spec', 'fixtures', 'organizations.json')), status: 200)
+ end
+
+ it 'should retrieve data from portail api' do
+ expect(Organisation.portail_api_request).to be_truthy
+ expect(WebMock).to have_requested(:get, "#{conf[:url]}/api/v1/organizations").
+ with(headers: { 'Authorization' => "Token token=\"#{conf[:key]}\"" })
+ end
+
+ it 'should create new organisations' do
+ expect{Organisation.portail_sync}.to change{ Organisation.count }.by(5)
+ expect(Organisation.all.map(&:name)).to include 'ALBATRANS', 'OPTILE', 'SNCF', 'STIF'
+ end
+
+ it 'should update existing organisations' do
+ create :organisation, name: 'dummy_name', code:'RATP', updated_at: 10.days.ago
+ Organisation.portail_sync
+ Organisation.find_by(code: 'RATP').tap do |org|
+ expect(org.name).to eq('RATP')
+ expect(org.updated_at.utc).to be_within(1.second).of Time.now
+ expect(org.synced_at.utc).to be_within(1.second).of Time.now
+ end
+ end
+
+ it 'should not create organisation if code is already present' do
+ create :organisation, code:'RATP'
+ expect{Organisation.portail_sync}.to change{ Organisation.count }.by(4)
+ end
+ end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index e22e53797..16fbed27a 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1,14 +1,113 @@
require 'spec_helper'
describe User, :type => :model do
- #it { should validate_uniqueness_of :email }
- #it { should validate_presence_of :name }
+ # it { should validate_uniqueness_of :email }
+ # it { should validate_presence_of :name }
+
+ describe "SSO" do
+ let(:ticket) do
+ CASClient::ServiceTicket.new("ST-test", nil).tap do |ticket|
+ ticket.extra_attributes = {
+ :full_name => 'john doe',
+ :username => 'john.doe',
+ :email => 'john.doe@af83.com',
+ :organisation_code => '0083',
+ :organisation_name => 'af83'
+ }
+ ticket.user = "john.doe"
+ ticket.success = true
+ end
+ end
+
+ context 'First time sign on' do
+ it 'should create a new user if user is not registered' do
+ expect{User.authenticate_with_cas_ticket(ticket)}.to change{ User.count }
+ user = User.find_by(username: 'john.doe')
+ expect(user.email).to eq(ticket.extra_attributes[:email])
+ expect(user.name).to eq(ticket.extra_attributes[:full_name])
+ end
+
+ it 'should create a new organisation if organisation is not present' do
+ expect{User.authenticate_with_cas_ticket(ticket)}.to change{ Organisation.count }
+ expect(Organisation.find_by(code: ticket.extra_attributes[:organisation_code])).to be_truthy
+ end
+
+ it 'should not create a new organisation if organisation is already present' do
+ ticket.extra_attributes[:organisation_code] = create(:organisation).code
+ expect{User.authenticate_with_cas_ticket(ticket)}.not_to change{ Organisation.count }
+ end
+ end
+
+ context 'Update attributes on sign on' do
+ let!(:organisation) { create(:organisation) }
+ let!(:user) { create(:user, username: 'john.doe', name:'fake name' , email: 'test@example.com', :organisation => organisation) }
+
+ it 'should update user attributes on sign on' do
+ User.authenticate_with_cas_ticket(ticket)
+ expect(user.reload.email).to eq(ticket.extra_attributes[:email])
+ expect(user.reload.name).to eq(ticket.extra_attributes[:full_name])
+ end
+ end
+ end
+
+ describe "Portail sync" do
+ let(:conf) { Rails.application.config.stif_portail_api }
+ before :each do
+ stub_request(:get, "#{conf[:url]}/api/v1/users").
+ with(headers: { 'Authorization' => "Token token=\"#{conf[:key]}\"" }).
+ to_return(body: File.open(File.join(Rails.root, 'spec', 'fixtures', 'users.json')), status: 200)
+ end
+
+ it 'should retrieve data from portail api' do
+ expect(User.portail_api_request).to be_truthy
+ expect(WebMock).to have_requested(:get, "#{conf[:url]}/api/v1/users").
+ with(headers: { 'Authorization' => "Token token=\"#{conf[:key]}\"" })
+ end
+
+ it 'should create new users' do
+ User.portail_sync
+ expect(User.count).to eq(11)
+ expect(Organisation.count).to eq(3)
+ end
+
+ it 'should update existing users' do
+ create :user, username: 'alban.peignier', email:'dummy@example.com', updated_at: 10.days.ago
+ User.portail_sync
+ user = User.find_by(username: 'alban.peignier')
+
+ expect(user.name).to eq('Alban Peignier')
+ expect(user.email).to eq('alban.peignier@af83.com')
+ expect(user.updated_at.utc).to be_within(1.second).of Time.now
+ expect(user.synced_at.utc).to be_within(1.second).of Time.now
+ end
+
+ it 'should update organisation assignement' do
+ create :user, username: 'alban.peignier', organisation: create(:organisation)
+ User.portail_sync
+ expect(User.find_by(username: 'alban.peignier').organisation.name).to eq("STIF")
+ end
+
+ it 'should update locked_at attribute' do
+ create :user, username: 'alban.peignier', locked_at: Time.now
+ User.portail_sync
+ expect(User.find_by(username: 'alban.peignier').locked_at).to be_nil
+ expect(User.find_by(username: 'jane.doe').locked_at).to eq("2016-08-05T12:34:03.995Z")
+ end
+
+ it 'should not create new user if username is already present' do
+ create :user, username: 'alban.peignier'
+ User.portail_sync
+ expect(User.count).to eq(11)
+ end
+ end
describe "#destroy" do
let!(:organisation){create(:organisation)}
let!(:user){create(:user, :organisation => organisation)}
+
context "user's organisation contains many user" do
let!(:other_user){create(:user, :organisation => organisation)}
+
it "should destoy also user's organisation" do
user.destroy
expect(Organisation.where(:name => organisation.name).exists?).to be_truthy
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 92afd410b..93b148496 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -11,10 +11,17 @@ require 'capybara/poltergeist'
require 'georuby-ext'
require 'will_paginate/array'
require 'fakeweb'
+require 'webmock/rspec'
require 'simplecov'
-SimpleCov.start 'rails' do
- add_filter "/.bundle"
+
+if ENV['JOB_NAME']
+ require 'simplecov-rcov'
+ SimpleCov.formatters = [
+ SimpleCov::Formatter::HTMLFormatter,
+ SimpleCov::Formatter::RcovFormatter
+ ]
end
+SimpleCov.start 'rails'
# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
@@ -42,7 +49,7 @@ RSpec.configure do |config|
config.filter_run_excluding :js => true
config.run_all_when_everything_filtered = true
config.include TokenInputHelper, :type => :feature
-
+
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
diff --git a/spec/support/devise.rb b/spec/support/devise.rb
index cd5782f36..d33812e6f 100644
--- a/spec/support/devise.rb
+++ b/spec/support/devise.rb
@@ -4,7 +4,6 @@ module DeviseRequestHelper
def login_user
organisation = Organisation.where(:name => "first").first_or_create(attributes_for(:organisation))
@user ||= create(:user, :organisation => organisation)
- @user.confirm!
login_as @user, :scope => :user
# post_via_redirect user_session_path, 'user[email]' => @user.email, 'user[password]' => @user.password
end
@@ -36,7 +35,6 @@ module DeviseControllerHelper
@request.env["devise.mapping"] = Devise.mappings[:user]
organisation = Organisation.where(:name => "first").first_or_create(attributes_for(:organisation))
user = create(:user, :organisation => organisation)
- user.confirm!
sign_in user
end
end
diff --git a/spec/tasks/reflex_rake_spec.rb b/spec/tasks/reflex_rake_spec.rb
new file mode 100644
index 000000000..bf1a81a82
--- /dev/null
+++ b/spec/tasks/reflex_rake_spec.rb
@@ -0,0 +1,61 @@
+require 'spec_helper'
+
+describe 'reflex:sync' do
+ context 'On first sync' do
+ before(:each) do
+ ['getOP', 'getOR'].each do |method|
+ stub_request(:get, "https://reflex.stif.info/ws/reflex/V1/service=getData/?format=xml&idRefa=0&method=#{method}").
+ to_return(body: File.open("#{fixture_path}/reflex.zip"), status: 200)
+ end
+ create(:stop_area_referential, name: 'Reflex')
+ Stif::ReflexSynchronization.synchronize
+ end
+
+ it 'should create stopArea on successfull request' do
+ expect(Chouette::StopArea.count).to eq 6
+ expect(Chouette::AccessPoint.count).to eq 2
+ end
+
+ it 'should convert StopPlaceEntrance to AccessPoint' do
+ access = Chouette::AccessPoint.find_by(name: 'Montgeron Crosne - Rue Du Moulin De Senlis')
+ expect(access.stop_area.name).to eq 'First stopPlace children'
+ end
+
+ it 'should save hierarchy' do
+ stop_area = Chouette::StopArea.find_by(name: 'First stopPlace children')
+ expect(stop_area.parent.name).to eq 'First stopPlace'
+ end
+
+ it 'should map xml data to StopArea attribute' do
+ stop_area = Chouette::StopArea.find_by(name: 'First stopPlace')
+ expect(stop_area.city_name).to eq 'Dammartin-en-Goële'
+ expect(stop_area.zip_code).to eq '77153'
+ expect(stop_area.area_type).to eq 'StopPlace'
+ end
+
+ context 'On next sync' do
+ before(:each) do
+ ['getOP', 'getOR'].each do |method|
+ stub_request(:get, "https://reflex.stif.info/ws/reflex/V1/service=getData/?format=xml&idRefa=0&method=#{method}").
+ to_return(body: File.open("#{fixture_path}/reflex_updated.zip"), status: 200)
+ end
+ Stif::ReflexSynchronization.synchronize
+ end
+
+ it 'should not create duplicate stop_area' do
+ expect(Chouette::StopArea.count).to eq 6
+ expect(Chouette::AccessPoint.count).to eq 2
+ end
+
+ it 'should flag deleted_at for missing element from last sync' do
+ stop_area = Chouette::StopArea.find_by(name: 'Second StopPlace')
+ expect(stop_area.deleted_at).to be_within(1.minute).of(Time.now)
+ end
+
+ it 'should update existing stop_area' do
+ expect(Chouette::StopArea.where(name: 'First stopPlace edited')).to exist
+ expect(Chouette::StopArea.where(name: 'First stopPlace children edited')).to exist
+ end
+ end
+ end
+end
diff --git a/spec/views/referentials/edit.html.erb_spec.rb b/spec/views/referentials/edit.html.erb_spec.rb
index a3978210b..a73fb2ef5 100644
--- a/spec/views/referentials/edit.html.erb_spec.rb
+++ b/spec/views/referentials/edit.html.erb_spec.rb
@@ -1,5 +1,5 @@
require 'spec_helper'
-describe "referentials/edit.html.erb", :type => :view do
+describe "referentials/edit", :type => :view do
pending "add some examples to (or delete) #{__FILE__}"
end
diff --git a/spec/views/referentials/new.html.erb_spec.rb b/spec/views/referentials/new.html.erb_spec.rb
index 82c8161ca..0673b4578 100644
--- a/spec/views/referentials/new.html.erb_spec.rb
+++ b/spec/views/referentials/new.html.erb_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe "referentials/new.html.erb", :type => :view do
+describe "referentials/new", :type => :view do
before(:each) do
assign(:referential, Referential.new)
diff --git a/spec/views/referentials/show.html.erb_spec.rb b/spec/views/referentials/show.html.erb_spec.rb
index 1ea888c31..8b7a4e4b5 100644
--- a/spec/views/referentials/show.html.erb_spec.rb
+++ b/spec/views/referentials/show.html.erb_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe "referentials/show.html.erb", :type => :view do
+describe "referentials/show", :type => :view do
assign_referential
it "should have a title with name" do