aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuc Donnet2014-06-27 17:43:16 +0200
committerLuc Donnet2014-06-27 17:43:16 +0200
commit486d7f1eca4c35bfcc065feb16cec4429a66cfa3 (patch)
treef266ee84674a4775f20bc20dda85fb84e4bd9933
parent24d901950acc7eb623a1b18d0de798f41743f422 (diff)
downloadchouette-core-486d7f1eca4c35bfcc065feb16cec4429a66cfa3.tar.bz2
Initialize stop area import model Refs #0026832
-rw-r--r--app/models/stop_area_import.rb66
-rw-r--r--config/locales/stop_area_import.yml18
-rw-r--r--spec/fixtures/stop_area_import_invalid.csv7
-rw-r--r--spec/fixtures/stop_area_import_valid.csv7
-rw-r--r--spec/models/stop_area_import_spec.rb50
5 files changed, 148 insertions, 0 deletions
diff --git a/app/models/stop_area_import.rb b/app/models/stop_area_import.rb
new file mode 100644
index 000000000..09fd92ddb
--- /dev/null
+++ b/app/models/stop_area_import.rb
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+
+class StopAreaImport
+ include ActiveModel::Validations
+ include ActiveModel::Conversion
+ extend ActiveModel::Naming
+
+ attr_accessor :file
+
+ validates_presence_of :file
+
+ def initialize(attributes = {})
+ attributes.each { |name, value| send("#{name}=", value) }
+ end
+
+ def persisted?
+ false
+ end
+
+ def save
+ begin
+ Chouette::StopArea.transaction do
+ if imported_stop_areas.map(&:valid?).all?
+ imported_stop_areas.each(&:save!)
+ true
+ else
+ imported_stop_areas.each_with_index do |imported_stop_area, index|
+ imported_stop_area.errors.full_messages.each do |message|
+ errors.add :base, I18n.t("stop_area_import.errors.invalid_stop_area", :column => index+2, :message => message)
+ end
+ end
+ false
+ end
+ end
+ rescue Exception => exception
+ errors.add :base, I18n.t("stop_area_import.errors.exception", :message => exception.message)
+ false
+ end
+ end
+
+ def imported_stop_areas
+ @imported_stop_areas ||= load_imported_stop_areas
+ end
+
+ def load_imported_stop_areas
+ spreadsheet = open_spreadsheet(file)
+ header = spreadsheet.row(1)
+ (2..spreadsheet.last_row).map do |i|
+ row = Hash[[header, spreadsheet.row(i)].transpose]
+ stop_area = Chouette::StopArea.find_by_id(row["id"]) || Chouette::StopArea.new
+ stop_area.attributes = row.to_hash.slice(*Chouette::StopArea.accessible_attributes)
+ stop_area
+ end
+ end
+
+ def open_spreadsheet(file)
+ case File.extname(file.original_filename)
+ when '.csv' then Roo::CSV.new(file.path)
+ when '.xls' then Roo::Excel.new(file.path)
+ when '.xlsx' then Roo::Excelx.new(file.path)
+ else
+ raise "Unknown file type: #{file.original_filename}"
+ end
+ end
+
+end
diff --git a/config/locales/stop_area_import.yml b/config/locales/stop_area_import.yml
new file mode 100644
index 000000000..cb557b540
--- /dev/null
+++ b/config/locales/stop_area_import.yml
@@ -0,0 +1,18 @@
+en:
+ stop_area_import:
+ new:
+ title: "Import stop areas"
+ form:
+ file: "File"
+ errors:
+ invalid_stop_area: "Error column %{column}, stop_area is invalid : %{message}"
+ exception: "An exception occured : %{message}"
+fr:
+ stop_area_import:
+ new:
+ title: "Import des arrĂȘts"
+ form:
+ file: "Fichier"
+ errors:
+ invalid_stop_area: "Erreur colonne %{column}, l'arrĂȘt est invalide : %{message}"
+ exception: "Une exception est survenu : %{message}" \ No newline at end of file
diff --git a/spec/fixtures/stop_area_import_invalid.csv b/spec/fixtures/stop_area_import_invalid.csv
new file mode 100644
index 000000000..522bf029c
--- /dev/null
+++ b/spec/fixtures/stop_area_import_invalid.csv
@@ -0,0 +1,7 @@
+"id","name","registration_number","longitude","latitude","area_type","comment","country_code","street_name","mobility_restricted_suitability","stairs_availability","lift_availability","int_user_needs"
+,"StopArea1",,"0.1","0.1",,"Comment",,,,,,
+,"StopArea2",,"0.2","0.2",,"Comment",,,,,,
+,"StopArea3",,"0.3","0.3",,"Comment",,,,,,
+,"StopArea4",,"0.4","0.4",,"Comment",,,,,,
+,"StopArea5",,"0.5","0.5",,"Comment",,,,,,
+,"StopArea6",,"0.6","0.6",,"Comment",,,,,,
diff --git a/spec/fixtures/stop_area_import_valid.csv b/spec/fixtures/stop_area_import_valid.csv
new file mode 100644
index 000000000..0dc54f215
--- /dev/null
+++ b/spec/fixtures/stop_area_import_valid.csv
@@ -0,0 +1,7 @@
+"id","name","registration_number","longitude","latitude","area_type","comment","country_code","street_name","mobility_restricted_suitability","stairs_availability","lift_availability","int_user_needs"
+,"StopArea1","1","0.1","0.1","Quay","Comment",,,,,,
+,"StopArea2","2","0.2","0.2","Quay","Comment",,,,,,
+,"StopArea3","3","0.3","0.3","Quay","Comment",,,,,,
+,"StopArea4","4","0.4","0.4","Quay","Comment",,,,,,
+,"StopArea5","5","0.5","0.5","Quay","Comment",,,,,,
+,"StopArea6","6","0.6","0.6","Quay","Comment",,,,,,
diff --git a/spec/models/stop_area_import_spec.rb b/spec/models/stop_area_import_spec.rb
new file mode 100644
index 000000000..1792ba8a3
--- /dev/null
+++ b/spec/models/stop_area_import_spec.rb
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+require 'spec_helper'
+
+describe VehicleJourneyImport do
+
+ let(:valid_file) {
+ csv_file = File.open(Rails.root.join("spec", "fixtures", "stop_area_import_valid.csv").to_s, "r")
+ mock("CSV", :tempfile => csv_file, :original_filename => File.basename(csv_file), :path => File.path(csv_file) )
+ }
+
+ let(:invalid_file) {
+ csv_file = File.open(Rails.root.join("spec", "fixtures", "stop_area_import_invalid.csv").to_s, "r")
+ mock("CSV", :tempfile => csv_file, :original_filename => File.basename(csv_file), :path => File.path(csv_file) )
+ }
+
+ subject { StopAreaImport.new(:file => valid_file) }
+
+ describe ".save" do
+
+ it "should validate presence of file" do
+ expect(StopAreaImport.new.save).to be_false
+ end
+
+ it "should import stop areas and create the right number of objects" do
+ expect(StopAreaImport.new(:file => valid_file).save).to be_true
+ expect(Chouette::StopArea.all.size).to eq(6)
+ end
+
+ it "should not import vehicle_journeys and not create objects when vehicle journey at stops are not in ascendant order" do
+ expect(StopAreaImport.new(:file => invalid_file).save).to be_false
+ expect(Chouette::StopArea.all.size).to eq(0)
+ end
+
+ end
+
+ describe ".load_imported_stop_areas" do
+
+ # it "should return errors when stop_areas in file are invalid" do
+ # stop_area_import = StopAreaImport.new(:referential => referential, :file => invalid_file)
+ # expect { stop_area_import.load_imported_stop_areas }.to raise_exception
+ # end
+
+ it "should load stop ateas" do
+ expect(subject.load_imported_stop_areas.size).to eq(6)
+ expect(subject.errors.messages).to eq({})
+ end
+
+ end
+
+end