diff options
90 files changed, 845 insertions, 123 deletions
| diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js b/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js index 34689070d..825e7bb7d 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js @@ -90,7 +90,7 @@ const actions = {    resetValidation: (target) => {      $(target).parent().removeClass('has-error').children('.help-block').remove()    }, -  humanOID : (oid) => oid.split(':')[2], +  humanOID : (oid) => oid.split(':')[2].split("-").pop(),    validateFields : (fields) => {      const test = [] diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js index de87c14af..2e2e06514 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js @@ -269,7 +269,7 @@ const actions = {      type: 'RECEIVE_TOTAL_COUNT',      total    }), -  humanOID: (oid) => oid.split(':')[2], +  humanOID: (oid) => oid.split(':')[2].split("-").pop(),    fetchVehicleJourneys : (dispatch, currentPage, nextPage, queryString) => {      if(currentPage == undefined){        currentPage = 1 diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/MissionSelect2.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/MissionSelect2.js index 922a1e5ee..2f49e9980 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/MissionSelect2.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/MissionSelect2.js @@ -2,6 +2,7 @@ var _ = require('lodash')  var React = require('react')  var PropTypes = require('react').PropTypes  var Select2 = require('react-select2') +var humanOID = require('../../../actions').humanOID  // get JSON full path  var origin = window.location.origin @@ -34,7 +35,7 @@ class BSelect4 extends React.Component{              delay: '500',              data: function(params) {                return { -                q: {published_name_cont_or_short_id_or_registration_number_cont: params.term}, +                q: {published_name_or_objectid_or_registration_number_cont: params.term},                };              },              processResults: function(data, params) { @@ -43,7 +44,7 @@ class BSelect4 extends React.Component{                    item => _.assign(                      {},                      item, -                    { text: "<strong>" + item.published_name + " - " + item.short_id + "</strong><br/><small>" + item.registration_number + "</small>" } +                    { text: "<strong>" + item.published_name + " - " + humanOID(item.object_id) + "</strong><br/><small>" + item.registration_number + "</small>" }                    )                  )                }; diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/TimetableSelect2.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/TimetableSelect2.js index 5157300ba..2248175ab 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/TimetableSelect2.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/TimetableSelect2.js @@ -2,7 +2,7 @@ var _ = require('lodash')  var React = require('react')  var PropTypes = require('react').PropTypes  var Select2 = require('react-select2') -var actions = require('../../../actions') +var humanOID = require('../../../actions').humanOID  // get JSON full path  var origin = window.location.origin @@ -48,7 +48,7 @@ class BSelect4 extends React.Component{                    item => _.assign(                      {},                      item, -                    {text: '<strong>' + "<span class='fa fa-circle' style='color:" + (item.color ? item.color : '#4B4B4B') + "'></span> " + item.comment + ' - ' + item.short_id + '</strong><br/><small>' + (item.day_types ? item.day_types.match(/[A-Z]?[a-z]+/g).join(', ') : "") + '</small>'} +                    {text: '<strong>' + "<span class='fa fa-circle' style='color:" + (item.color ? item.color : '#4B4B4B') + "'></span> " + item.comment + ' - ' + humanOID(item.objectid) + '</strong><br/><small>' + (item.day_types ? item.day_types.match(/[A-Z]?[a-z]+/g).join(', ') : "") + '</small>'}                    )                  )                }; diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/VJSelect2.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/VJSelect2.js index cc2ee4b9e..b9678ea9a 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/VJSelect2.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/VJSelect2.js @@ -2,6 +2,7 @@ var _ = require('lodash')  var React = require('react')  var PropTypes = require('react').PropTypes  var Select2 = require('react-select2') +var humanOID = require('../../../actions').humanOID  // get JSON full path  var origin = window.location.origin @@ -12,10 +13,6 @@ class BSelect4b extends React.Component{    constructor(props) {      super(props)    } -  humanOID(oid) { -    var a = oid.split(':') -    return a[a.length - 1] -  }    render() {      return ( @@ -46,7 +43,7 @@ class BSelect4b extends React.Component{                    item => _.assign(                      {},                      item, -                    { id: item.objectid, text: _.last(_.split(item.objectid, ':')) } +                    { id: item.objectid, text: humanOID(item.objectid) }                    )                  )                }; diff --git a/app/assets/javascripts/filters/import.js b/app/assets/javascripts/filters/import.js index d0b96da10..bb665d5ad 100644 --- a/app/assets/javascripts/filters/import.js +++ b/app/assets/javascripts/filters/import.js @@ -1,6 +1,6 @@  const DateFilter = require('../helpers/date_filters')  $(document).ready(function(){ -  const importDF = new DateFilter("#import_filter_btn", "Tous les champs du filtre de date doivent être remplis", "#q_started_on_date_NUMi") +  const importDF = new DateFilter("#import_filter_btn", "Tous les champs du filtre de date doivent être remplis", "#q_started_at_begin_NUMi", "#q_started_at_end_NUMi")    importDF()  }) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 8cb5726c4..853c2f715 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -34,7 +34,7 @@ class ApplicationController < ActionController::Base    helper_method :current_organisation    def current_offer_workbench -    current_organisation.workbenches.where(name: "Gestion de l'offre") +    current_organisation.workbenches.find_by_name("Gestion de l'offre")    end    helper_method :current_offer_workbench diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb index 97a8f91aa..fa8919f20 100644 --- a/app/controllers/imports_controller.rb +++ b/app/controllers/imports_controller.rb @@ -1,7 +1,8 @@  class ImportsController < BreadcrumbController    skip_before_action :authenticate_user!, only: [:download]    defaults resource_class: Import, collection_name: 'imports', instance_name: 'import' -  before_action :ransack_started_on_date, only: [:index] +  before_action :ransack_started_at_params, only: [:index] +  before_action :ransack_status_params, only: [:index]    respond_to :html    belongs_to :workbench @@ -45,7 +46,10 @@ class ImportsController < BreadcrumbController    protected    def collection -    @q = parent.imports.where(type: "WorkbenchImport").search(params[:q]) +    scope = parent.imports.where(type: "WorkbenchImport") +    scope = ransack_period scope + +    @q = scope.search(params[:q])      if sort_column && sort_direction        @imports ||= @q.result(distinct: true).order(sort_column + ' ' + sort_direction).paginate(page: params[:page], per_page: 10) @@ -56,14 +60,39 @@ class ImportsController < BreadcrumbController    private -  def ransack_started_on_date -    date =[] -    if params[:q] && !params[:q]['started_on_date(1i)'].empty? -      ['started_on_date(1i)', 'started_on_date(2i)', 'started_on_date(3i)'].each do |key| -        date << params[:q][key].to_i -        params[:q].delete(key) +  def ransack_started_at_params +    start_date = [] +    end_date = [] + +    if params[:q] && params[:q][:started_at] && !params[:q][:started_at].has_value?(nil) && !params[:q][:started_at].has_value?("") +      [1, 2, 3].each do |key| +        start_date <<  params[:q][:started_at]["begin(#{key}i)"].to_i +        end_date <<  params[:q][:started_at]["end(#{key}i)"].to_i        end -      params[:q]['started_on_date'] = DateTime.new(*date) rescue nil +      params[:q].delete([:started_at]) +      @begin_range = DateTime.new(*start_date,0,0,0) rescue nil +      @end_range = DateTime.new(*end_date,23,59,59) rescue nil +    end +  end + +  # Fake ransack filter +  def ransack_period scope +    return scope unless !!@begin_range && !!@end_range + +    if @begin_range > @end_range +      flash.now[:error] = t('imports.filters.error_period_filter') +    else +      scope = scope.where_started_at_between(@begin_range, @end_range) +    end +    scope +  end + +  def ransack_status_params +    if params[:q] +      binding.pry +      return params[:q].delete(:status_eq_any) if params[:q][:status_eq_any].empty? || ( (Import.status.values & params[:q][:status_eq_any]).length >= 4 ) +      params[:q][:status_eq_any].push("new", "running") if params[:q][:status_eq_any].include?("pending") +      params[:q][:status_eq_any].push("aborted", "canceled") if params[:q][:status_eq_any].include?("failed")      end    end diff --git a/app/controllers/referential_lines_controller.rb b/app/controllers/referential_lines_controller.rb index 1da64991d..ec0bbbb18 100644 --- a/app/controllers/referential_lines_controller.rb +++ b/app/controllers/referential_lines_controller.rb @@ -11,7 +11,7 @@ class ReferentialLinesController < ChouetteController    belongs_to :referential    def show -    @routes = resource.routes +    @routes = resource.routes.order(:objectid)      case sort_route_column      when "stop_points", "journey_patterns" diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb index bd0544a74..c8984076a 100644 --- a/app/controllers/referentials_controller.rb +++ b/app/controllers/referentials_controller.rb @@ -7,17 +7,19 @@ class ReferentialsController < BreadcrumbController    respond_to :js, :only => :show    def new -    if params[:from] -      source_referential = Referential.find(params[:from]) -      @referential = Referential.new_from(source_referential, current_functional_scope) +    new! do +      build_referenial      end +  end -    new! do -      @referential.data_format = current_organisation.data_format -      @referential.workbench_id ||= params[:workbench_id] +  def create +    create! do |format| +      build_referenial -      if @referential.in_workbench? -        @referential.init_metadatas default_date_range: Range.new(Date.today, Date.today.advance(months: 1)) +      if !!@referential.created_from_id +        format.html { redirect_to workbench_path(@referential.workbench) } +      else +        build_breadcrumb :new        end      end    end @@ -25,7 +27,7 @@ class ReferentialsController < BreadcrumbController    def show      resource.switch      show! do |format| -      @referential = @referential.decorate(context: { workbench_id: params[:workbench_id] } ) +      @referential = @referential.decorate(context: { current_workbench_id: params[:current_workbench_id] } )        @reflines = lines_collection.paginate(page: params[:page], per_page: 10)        @reflines = ModelDecorator.decorate(          @reflines, @@ -123,6 +125,21 @@ class ReferentialsController < BreadcrumbController      super    end +  def build_referenial +    if params[:from] +      source_referential = Referential.find(params[:from]) +      @referential = Referential.new_from(source_referential, current_functional_scope) +      @referential.workbench_id = params[:current_workbench_id] +    end + +    @referential.data_format = current_organisation.data_format +    @referential.workbench_id ||= params[:workbench_id] + +    if @referential.in_workbench? +      @referential.init_metadatas default_date_range: Range.new(Date.today, Date.today.advance(months: 1)) +    end +  end +    private    def sort_column      sortable_columns = Chouette::Line.column_names + ['networks.name', 'companies.name'] diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 7ba2c1a58..04f63c112 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -69,11 +69,11 @@ class RoutesController < ChouetteController      end    end - # def update -   # update! do |success, failure| -   #   success.html { redirect_to referential_line_path(@referential,@line) } -   # end - # end +  def duplicate +    route = Chouette::Route.find(params[:id]).duplicate +    redirect_to edit_referential_line_route_path(@referential, route.line, route) +  end +    protected    alias_method :route, :resource diff --git a/app/controllers/workbenches_controller.rb b/app/controllers/workbenches_controller.rb index bae3fcff2..54ddb8be1 100644 --- a/app/controllers/workbenches_controller.rb +++ b/app/controllers/workbenches_controller.rb @@ -24,7 +24,7 @@ class WorkbenchesController < BreadcrumbController        @wbench_refs,        with: ReferentialDecorator,        context: { -        workbench_id: params[:id] +        current_workbench_id: params[:id]        }      )      show! do diff --git a/app/decorators/referential_decorator.rb b/app/decorators/referential_decorator.rb index 4e9c242fd..dccf0052c 100644 --- a/app/decorators/referential_decorator.rb +++ b/app/decorators/referential_decorator.rb @@ -13,7 +13,7 @@ class ReferentialDecorator < Draper::Decorator      if policy.clone?        links << Link.new(          content: h.t('actions.clone'), -        href: h.new_referential_path(from: object.id, workbench_id: context[:workbench_id]) +        href: h.new_referential_path(from: object.id, current_workbench_id: context[:current_workbench_id])        )      end      if policy.archive? diff --git a/app/decorators/route_decorator.rb b/app/decorators/route_decorator.rb index 484c3db04..510c941a3 100644 --- a/app/decorators/route_decorator.rb +++ b/app/decorators/route_decorator.rb @@ -45,6 +45,18 @@ class RouteDecorator < Draper::Decorator        )      ) +    if h.policy(object).duplicate? +      links << Link.new( +        content: h.t('routes.duplicate.title'), +        href: h.duplicate_referential_line_route_path( +          context[:referential], +          context[:line], +          object +        ), +        method: :post +      ) +    end +      if h.policy(object).destroy?        links << Link.new(          content: h.destroy_link_content, diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb index 2b62d5c7f..fa2a9c8bb 100644 --- a/app/models/chouette/journey_pattern.rb +++ b/app/models/chouette/journey_pattern.rb @@ -23,7 +23,7 @@ class Chouette::JourneyPattern < Chouette::TridentActiveRecord    def local_id -    "IBOO-#{self.try(:route).try(:line).try(:objectid).try(:local_id)}-#{self.referential.id}-#{self.id}" +    "IBOO-#{self.referential.id}-#{self.try(:route).try(:line).try(:objectid).try(:local_id)}-#{self.id}"    end    def checksum_attributes diff --git a/app/models/chouette/netex_object_id.rb b/app/models/chouette/netex_object_id.rb index 07d862992..441004c1e 100644 --- a/app/models/chouette/netex_object_id.rb +++ b/app/models/chouette/netex_object_id.rb @@ -5,7 +5,7 @@ class Chouette::NetexObjectId < String    end    alias_method :objectid?, :valid? -  @@format = /^([A-Za-z_]+):([0-9A-Za-z_]+):([A-Za-z]+):([0-9A-Za-z_-]+)$/  +  @@format = /^([A-Za-z_]+):([0-9A-Za-z_]+):([A-Za-z]+):([0-9A-Za-z_-]+)$/    cattr_reader :format    def parts @@ -27,7 +27,7 @@ class Chouette::NetexObjectId < String    def local_id      parts.try(:fourth)    end -   +    def self.create(provider_id, system_id, object_type, local_id)      new [provider_id, system_id, object_type, local_id].join(":")    end diff --git a/app/models/chouette/object_id.rb b/app/models/chouette/object_id.rb index 4f58048e1..0b122c91b 100644 --- a/app/models/chouette/object_id.rb +++ b/app/models/chouette/object_id.rb @@ -5,7 +5,7 @@ class Chouette::ObjectId < String    end    alias_method :objectid?, :valid? -  @@format = /^([0-9A-Za-z_]+):([A-Za-z]+):([0-9A-Za-z_-]+)$/  +  @@format = /^([0-9A-Za-z_]+):([A-Za-z]+):([0-9A-Za-z_-]+)$/    cattr_reader :format    def parts @@ -23,7 +23,7 @@ class Chouette::ObjectId < String    def local_id      parts.try(:third)    end -   +    def self.create(system_id, object_type, local_id)      new [system_id, object_type, local_id].join(":")    end diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 5b89fbbe8..49493d5b5 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -16,6 +16,7 @@ class Chouette::Route < Chouette::TridentActiveRecord    end    belongs_to :line +  belongs_to :opposite_route, :class_name => 'Chouette::Route', :foreign_key => :opposite_route_id    has_many :routing_constraint_zones    has_many :journey_patterns, :dependent => :destroy @@ -30,7 +31,6 @@ class Chouette::Route < Chouette::TridentActiveRecord        Chouette::Route.vehicle_journeys_timeless(proxy_association.owner.journey_patterns.pluck( :departure_stop_point_id))      end    end -  belongs_to :opposite_route, :class_name => 'Chouette::Route', :foreign_key => :opposite_route_id    has_many :stop_points, -> { order("position") }, :dependent => :destroy do      def find_by_stop_area(stop_area)        stop_area_ids = Integer === stop_area ? [stop_area] : (stop_area.children_in_depth + [stop_area]).map(&:id) @@ -56,12 +56,13 @@ class Chouette::Route < Chouette::TridentActiveRecord    end    has_many :stop_areas, -> { order('stop_points.position ASC') }, :through => :stop_points do      def between(departure, arrival) -      departure, arrival = [departure, arrival].collect do |endpoint| +      departure, arrival = [departure, arrival].map do |endpoint|          String === endpoint ? Chouette::StopArea.find_by_objectid(endpoint) : endpoint        end        proxy_owner.stop_points.between(departure, arrival).includes(:stop_area).collect(&:stop_area)      end    end +    accepts_nested_attributes_for :stop_points, :allow_destroy => :true    validates_presence_of :name @@ -75,8 +76,30 @@ class Chouette::Route < Chouette::TridentActiveRecord    after_commit :journey_patterns_control_route_sections +  def duplicate +    overrides = { +      'opposite_route_id' => nil +    } +    keys_for_create = attributes.keys - %w{id objectid created_at updated_at} +    atts_for_create = attributes +      .slice(*keys_for_create) +      .merge(overrides) +    new_route = self.class.create!(atts_for_create) +    duplicate_stop_points(for_route: new_route) +    new_route +  end + +  def duplicate_stop_points(for_route:) +    stop_points.each(&duplicate_stop_point(for_route: for_route)) +  end +  def duplicate_stop_point(for_route:) +    -> stop_point do +      stop_point.duplicate(for_route: for_route) +    end +  end +    def local_id -    "IBOO-#{self.line.objectid.local_id}-#{self.referential.id}-#{self.id}" +    "IBOO-#{self.referential.id}-#{self.line.objectid.local_id}-#{self.id}"    end    def geometry_presenter diff --git a/app/models/chouette/routing_constraint_zone.rb b/app/models/chouette/routing_constraint_zone.rb index 21efa2539..efe1b7237 100644 --- a/app/models/chouette/routing_constraint_zone.rb +++ b/app/models/chouette/routing_constraint_zone.rb @@ -9,7 +9,7 @@ class Chouette::RoutingConstraintZone < Chouette::TridentActiveRecord    validate :stop_points_belong_to_route, :not_all_stop_points_selected    def local_id -    "IBOO-#{self.route.line.objectid.local_id}-#{self.route.objectid.local_id}-#{self.referential.id}-#{self.id}" +    "IBOO-#{self.referential.id}-#{self.route.line.objectid.local_id}-#{self.route.objectid.local_id}-#{self.id}"    end    scope :order_by_stop_points_count, ->(direction) do diff --git a/app/models/chouette/stif_netex_objectid.rb b/app/models/chouette/stif_netex_objectid.rb index 3b11691d9..a0a91668a 100644 --- a/app/models/chouette/stif_netex_objectid.rb +++ b/app/models/chouette/stif_netex_objectid.rb @@ -26,6 +26,10 @@ class Chouette::StifNetexObjectid < String      parts.try(:fourth)    end +  def short_id +    local_id.try(:split, "-").try(:[], -1) +  end +    def self.create(provider_id, object_type, local_id, boiv_id)      new [provider_id, object_type, local_id, boiv_id].join(":")    end diff --git a/app/models/chouette/stop_point.rb b/app/models/chouette/stop_point.rb index 8fe79dc0c..89c492b91 100644 --- a/app/models/chouette/stop_point.rb +++ b/app/models/chouette/stop_point.rb @@ -20,6 +20,11 @@ module Chouette      validates_presence_of :stop_area      validate :stop_area_id_validation +    def stop_area_id_validation +      if stop_area_id.nil? +        errors.add(:stop_area_id, I18n.t("stop_areas.errors.empty")) +      end +    end      scope :default_order, -> { order("position") } @@ -34,10 +39,12 @@ module Chouette        end      end -    def stop_area_id_validation -      if stop_area_id.nil? -        errors.add(:stop_area_id, I18n.t("stop_areas.errors.empty")) -      end +    def duplicate(for_route:) +      keys_for_create = attributes.keys - %w{id objectid created_at updated_at} +      atts_for_create = attributes +        .slice(*keys_for_create) +        .merge('route_id' => for_route.id) +      self.class.create!(atts_for_create)      end      def self.area_candidates diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb index e60afef6e..f574afc93 100644 --- a/app/models/chouette/vehicle_journey.rb +++ b/app/models/chouette/vehicle_journey.rb @@ -57,7 +57,7 @@ module Chouette      end      def local_id -      "IBOO-#{self.route.line.objectid.local_id}-#{self.referential.id}-#{self.id}" +      "IBOO-#{self.referential.id}-#{self.route.line.objectid.local_id}-#{self.id}"      end      def checksum_attributes diff --git a/app/models/compliance_check.rb b/app/models/compliance_check.rb index a9dbc4211..85cf5e37e 100644 --- a/app/models/compliance_check.rb +++ b/app/models/compliance_check.rb @@ -1,3 +1,9 @@ -class ComplianceCheck +class ComplianceCheck < ActiveRecord::Base +  belongs_to :compliance_check_set +  belongs_to :compliance_check_block +  enum criticity: [:info, :warning, :error] +  validates :criticity, presence: true +  validates :name, presence: true +  validates :code, presence: true  end diff --git a/app/models/compliance_check_block.rb b/app/models/compliance_check_block.rb new file mode 100644 index 000000000..035c03ed9 --- /dev/null +++ b/app/models/compliance_check_block.rb @@ -0,0 +1,3 @@ +class ComplianceCheckBlock < ActiveRecord::Base +  belongs_to :compliance_check_set +end diff --git a/app/models/compliance_check_resource.rb b/app/models/compliance_check_resource.rb new file mode 100644 index 000000000..7826f00c3 --- /dev/null +++ b/app/models/compliance_check_resource.rb @@ -0,0 +1,5 @@ +class ComplianceCheckResource < ActiveRecord::Base +  extend Enumerize + +  enumerize :status, in: %w[new successful warning failed] +end diff --git a/app/models/compliance_check_result.rb b/app/models/compliance_check_result.rb index 06f8649f5..161e45189 100644 --- a/app/models/compliance_check_result.rb +++ b/app/models/compliance_check_result.rb @@ -1,3 +1,4 @@ -class ComplianceCheckResult - +class ComplianceCheckResult < ActiveRecord::Base +  belongs_to :compliance_check +  belongs_to :compliance_check_resource  end diff --git a/app/models/compliance_check_set.rb b/app/models/compliance_check_set.rb new file mode 100644 index 000000000..7b6400a21 --- /dev/null +++ b/app/models/compliance_check_set.rb @@ -0,0 +1,10 @@ +class ComplianceCheckSet < ActiveRecord::Base +  extend Enumerize + +  belongs_to :referential +  belongs_to :compliance_control_set +  belongs_to :workbench +  belongs_to :parent, polymorphic: true + +  enumerize :status, in: %w[new pending successful warning failed running aborted canceled] +end diff --git a/app/models/compliance_control.rb b/app/models/compliance_control.rb new file mode 100644 index 000000000..64556b524 --- /dev/null +++ b/app/models/compliance_control.rb @@ -0,0 +1,9 @@ +class ComplianceControl < ActiveRecord::Base +  belongs_to :compliance_control_set +  belongs_to :compliance_control_block + +  enum criticity: [:info, :warning, :error] +  validates :criticity, presence: true +  validates :name, presence: true +  validates :code, presence: true +end diff --git a/app/models/compliance_control_block.rb b/app/models/compliance_control_block.rb new file mode 100644 index 000000000..cf5a9d72b --- /dev/null +++ b/app/models/compliance_control_block.rb @@ -0,0 +1,3 @@ +class ComplianceControlBlock < ActiveRecord::Base +  belongs_to :compliance_control_set +end diff --git a/app/models/compliance_control_set.rb b/app/models/compliance_control_set.rb new file mode 100644 index 000000000..7801eb612 --- /dev/null +++ b/app/models/compliance_control_set.rb @@ -0,0 +1,3 @@ +class ComplianceControlSet < ActiveRecord::Base +  belongs_to :organisation +end diff --git a/app/models/import.rb b/app/models/import.rb index 55d74c13c..74f7ef10c 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -9,7 +9,9 @@ class Import < ActiveRecord::Base    has_many :resources, class_name: "ImportResource", dependent: :destroy    has_many :children, foreign_key: :parent_id, class_name: "Import", dependent: :destroy -  scope :started_on_date, ->(date) { where('started_at BETWEEN ? AND ?', date.beginning_of_day, date.end_of_day) } +  scope :where_started_at_between, ->(start_date, end_date) do +     where('started_at BETWEEN ? AND ?', start_date, end_date) +   end    extend Enumerize    enumerize :status, in: %i(new pending successful warning failed running aborted canceled), scope: true, default: :new @@ -19,10 +21,6 @@ class Import < ActiveRecord::Base    before_create :initialize_fields -  def self.ransackable_scopes(auth_object = nil) -    [:started_on_date] -  end -    def self.model_name      ActiveModel::Name.new Import, Import, "Import"    end diff --git a/app/models/import_message.rb b/app/models/import_message.rb index 913f6fd41..5d0f5c862 100644 --- a/app/models/import_message.rb +++ b/app/models/import_message.rb @@ -1,6 +1,6 @@  class ImportMessage < ActiveRecord::Base    belongs_to :import -  belongs_to :resource, class_name: ImportResource, dependent: :destroy +  belongs_to :resource, class_name: ImportResource    enum criticity: [:info, :warning, :error]    validates :criticity, presence: true diff --git a/app/models/referential.rb b/app/models/referential.rb index b508e2f33..af08aa868 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -11,6 +11,9 @@ class Referential < ActiveRecord::Base    # validates_presence_of :lower_corner    validates_uniqueness_of :slug + +  validates_presence_of :line_referential +  validates_presence_of :stop_area_referential    validates_format_of :slug, :with => %r{\A[a-z][0-9a-z_]+\Z}    validates_format_of :prefix, :with => %r{\A[0-9a-zA-Z_]+\Z}    validates_format_of :upper_corner, :with => %r{\A-?[0-9]+\.?[0-9]*\,-?[0-9]+\.?[0-9]*\Z} @@ -180,8 +183,7 @@ class Referential < ActiveRecord::Base      projection_type || ""    end -  before_validation :assign_line_and_stop_area_referential, :on => :create, if: :workbench, unless: :created_from -  before_validation :clone_associations, :on => :create, if: :created_from +  before_validation :assign_line_and_stop_area_referential, :on => :create, if: :workbench    before_validation :assign_slug, :on => :create    before_validation :assign_prefix, :on => :create    before_create :create_schema @@ -202,18 +204,6 @@ class Referential < ActiveRecord::Base      end    end -  def clone_associations -    self.line_referential      = created_from.line_referential -    self.stop_area_referential = created_from.stop_area_referential -    self.workbench             = created_from.workbench -  end - -  def clone_metadatas -    created_from.metadatas.each do |meta| -      self.metadatas << ReferentialMetadata.new_from(meta) -    end -  end -    def metadatas_period      query = "select min(lower), max(upper) from (select lower(unnest(periodes)) as lower, upper(unnest(periodes)) as upper from public.referential_metadata where public.referential_metadata.referential_id = #{id}) bounds;" diff --git a/app/models/referential_metadata.rb b/app/models/referential_metadata.rb index 839a937f4..393dc70d3 100644 --- a/app/models/referential_metadata.rb +++ b/app/models/referential_metadata.rb @@ -157,6 +157,7 @@ class ReferentialMetadata < ActiveRecord::Base    def self.new_from(from, functional_scope)      from.dup.tap do |metadata| +      metadata.referential_source_id = from.referential_id        metadata.line_ids = from.referential.lines.where(id: metadata.line_ids, objectid: functional_scope).collect(&:id)        metadata.referential_id = nil      end diff --git a/app/models/stop_area_copy.rb b/app/models/stop_area_copy.rb index 0fa56ff68..d3eb78557 100644 --- a/app/models/stop_area_copy.rb +++ b/app/models/stop_area_copy.rb @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -  class StopAreaCopy    include ActiveModel::Validations    include ActiveModel::Conversion diff --git a/app/policies/route_policy.rb b/app/policies/route_policy.rb index 786b0acf4..7e9fe251a 100644 --- a/app/policies/route_policy.rb +++ b/app/policies/route_policy.rb @@ -16,4 +16,8 @@ class RoutePolicy < ApplicationPolicy    def update?      !archived? && organisation_match? && user.has_permission?('routes.update')    end + +  def duplicate? +    create? +  end  end diff --git a/app/views/imports/_filters.html.slim b/app/views/imports/_filters.html.slim index a216019b6..85099b99a 100644 --- a/app/views/imports/_filters.html.slim +++ b/app/views/imports/_filters.html.slim @@ -9,12 +9,14 @@    .ffg-row      .form-group.togglable        = f.label Import.human_attribute_name(:status), required: false, class: 'control-label' -      = f.input :status_eq_any, collection: @imports.map(&:status).uniq.compact, as: :check_boxes, label: false, label_method: lambda{|l| ("<span>" + import_status(l) + "</span>").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}, input_html: { checked: true} +      = f.input :status_eq_any, collection: %w(pending successful warning failed), as: :check_boxes, label: false, label_method: lambda{|l| ("<span>" + import_status(l) + "</span>").html_safe}, required: false, wrapper_html: { class: "checkbox_list"}      .form-group.togglable        = f.label Import.human_attribute_name(:started_at), required: false, class: 'control-label'        .filter_menu -        = f.input :started_on_date, as: :date, label: false, wrapper_html: { class: 'date smart_date filter_menu-item' }, include_blank: true +        = f.simple_fields_for :started_at do |p| +          = p.input :begin, as: :date, label: false, wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @begin_range, include_blank: @begin_range ? false : true +          = p.input :end, as: :date, label: false, wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @end_range, include_blank: @end_range ? false : true    .actions      = link_to t('actions.erase'), workbench_imports_path(@workbench), class: 'btn btn-link' diff --git a/app/views/referential_lines/show.html.slim b/app/views/referential_lines/show.html.slim index cbce7a7d5..6e59d83b3 100644 --- a/app/views/referential_lines/show.html.slim +++ b/app/views/referential_lines/show.html.slim @@ -46,7 +46,7 @@                  [ \                    TableBuilderHelper::Column.new( \                      name: 'ID', \ -                    attribute: Proc.new { |n| n.objectid.local_id }, \ +                    attribute: Proc.new { |n| n.objectid.short_id }, \                      sortable: false \                    ), \                    TableBuilderHelper::Column.new( \ diff --git a/app/views/routes/show.html.slim b/app/views/routes/show.html.slim index a21b5ec8a..e2681d215 100644 --- a/app/views/routes/show.html.slim +++ b/app/views/routes/show.html.slim @@ -21,7 +21,7 @@      .row        .col-lg-6.col-md-6.col-sm-12.col-xs-12          = definition_list t('metadatas'), -          { t('id_codif') => @route.try(:objectid).try(:local_id), +          { t('objectid') => @route.objectid.short_id,              t('activerecord.attributes.route.published_name') => (@route.published_name ? @route.published_name : '-'),              @route.human_attribute_name(:wayback) => (@route.wayback ? @route.wayback_text : '-' ),              @route.human_attribute_name(:opposite_route) => (@route.opposite_route ? @route.opposite_route.name : '-') } @@ -29,7 +29,7 @@        - if @route_sp.any?          .col-lg-6.col-md-6.col-sm-12.col-xs-12            #route_map.map.mb-lg -       +      .row        .col-lg-12          - if @route_sp.any? diff --git a/app/views/time_tables/index.html.slim b/app/views/time_tables/index.html.slim index a1b9c4e09..b984f95c8 100644 --- a/app/views/time_tables/index.html.slim +++ b/app/views/time_tables/index.html.slim @@ -18,7 +18,7 @@              [ \                TableBuilderHelper::Column.new( \                  name: 'ID', \ -                attribute: Proc.new { |n| n.objectid.local_id }, \ +                attribute: Proc.new { |n| n.objectid.short_id}, \                  sortable: false \                ), \                TableBuilderHelper::Column.new( \ @@ -69,4 +69,4 @@  = javascript_tag do    | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe}; -= javascript_include_tag 'filters/timetable.js' += javascript_include_tag 'filters/time_table.js' diff --git a/app/views/workbenches/index.html.slim b/app/views/workbenches/index.html.slim index 2ea1f0fe4..d35ed8121 100644 --- a/app/views/workbenches/index.html.slim +++ b/app/views/workbenches/index.html.slim @@ -61,7 +61,7 @@            - if @referentials.any?              .list-group                - @referentials.each_with_index do |referential, i| -                = link_to referential.name, referential_path(referential, workbench_id: referential.workbench_id), class: 'list-group-item' if i < 6 +                = link_to referential.name, referential_path(referential, workbench_id: referential.workbench_id, current_workbench_id: @workbench.id), class: 'list-group-item' if i < 6            - else              .panel-body diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim index 50c719d12..fd72979ea 100644 --- a/app/views/workbenches/show.html.slim +++ b/app/views/workbenches/show.html.slim @@ -29,7 +29,7 @@                    key: :name, \                    attribute: 'name', \                    link_to: lambda do |referential| \ -                    referential_path(referential, workbench_id: referential.workbench_id) \ +                    referential_path(referential, current_workbench_id: params[:id]) \                    end \                  ), \                  TableBuilderHelper::Column.new( \ diff --git a/config/initializers/apartment.rb b/config/initializers/apartment.rb index e1e86449c..0d65c3505 100644 --- a/config/initializers/apartment.rb +++ b/config/initializers/apartment.rb @@ -46,7 +46,14 @@ Apartment.configure do |config|      'NetexImport',      'WorkbenchImport',      'ImportMessage', -    'ImportResource' +    'ImportResource', +    'ComplianceControl', +    'ComplianceControlSet', +    'ComplianceControlBlock', +    'ComplianceCheck', +    'ComplianceCheckSet', +    'ComplianceCheckBlock', +    'ComplianceCheckResource',    ]    # use postgres schemas? diff --git a/config/locales/imports.en.yml b/config/locales/imports.en.yml index b92b8843f..9bf877c86 100644 --- a/config/locales/imports.en.yml +++ b/config/locales/imports.en.yml @@ -4,6 +4,7 @@ en:      filters:        referential: "Select data space..."        name_or_creator_cont: "Select an import or creator name..." +      error_period_filter: "End date must be greater or equal than begin date"      actions:        new: "New import"        show: "Import report" diff --git a/config/locales/imports.fr.yml b/config/locales/imports.fr.yml index f7bf8c178..6998c89d2 100644 --- a/config/locales/imports.fr.yml +++ b/config/locales/imports.fr.yml @@ -4,6 +4,7 @@ fr:      filters:        referential: "Sélectionnez un jeu de données..."        name_or_creator_cont: "Indiquez un nom d'import ou d'opérateur..." +      error_period_filter: "La date de fin doit être supérieure ou égale à la date de début"      actions:        new: "Nouvel import"        show: "Rapport d'import" diff --git a/config/locales/routes.en.yml b/config/locales/routes.en.yml index 3099d4ab1..e94adf490 100644 --- a/config/locales/routes.en.yml +++ b/config/locales/routes.en.yml @@ -32,6 +32,8 @@ en:        stop_area_name: "Stop area name"        for_boarding: "Boarding"        for_alighting: "Alighting" +    duplicate: +      title: "Duplicate route"      route:        no_journey_pattern: "No Journey pattern"        wayback: diff --git a/config/locales/routes.fr.yml b/config/locales/routes.fr.yml index 0af2832a2..a494e60ec 100644 --- a/config/locales/routes.fr.yml +++ b/config/locales/routes.fr.yml @@ -32,6 +32,8 @@ fr:        stop_area_name: "Nom de l'arrêt"        for_boarding: "Montée"        for_alighting: "Descente" +    duplicate: +      title: "Dupliquer l'itinéraire"      route:        no_journey_pattern: "Pas de mission"        wayback: diff --git a/config/routes.rb b/config/routes.rb index 4fcd649a7..0f1b22e44 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -118,6 +118,7 @@ ChouetteIhm::Application.routes.draw do          member do            get 'edit_boarding_alighting'            put 'save_boarding_alighting' +          post 'duplicate', to: 'routes#duplicate'          end          resource :journey_patterns_collection, :only => [:show, :update]          resources :journey_patterns do diff --git a/db/migrate/20170905101656_create_compliance_control_sets.rb b/db/migrate/20170905101656_create_compliance_control_sets.rb new file mode 100644 index 000000000..d074267cd --- /dev/null +++ b/db/migrate/20170905101656_create_compliance_control_sets.rb @@ -0,0 +1,10 @@ +class CreateComplianceControlSets < ActiveRecord::Migration +  def change +    create_table :compliance_control_sets do |t| +      t.string :name +      t.references :organisation, index: true, foreign_key: true + +      t.timestamps null: false +    end +  end +end diff --git a/db/migrate/20170905122539_create_compliance_control_blocks.rb b/db/migrate/20170905122539_create_compliance_control_blocks.rb new file mode 100644 index 000000000..54ed027ff --- /dev/null +++ b/db/migrate/20170905122539_create_compliance_control_blocks.rb @@ -0,0 +1,11 @@ +class CreateComplianceControlBlocks < ActiveRecord::Migration +  def change +    create_table :compliance_control_blocks do |t| +      t.string :name +      t.hstore :condition_attributes +      t.references :compliance_control_set, index: true, foreign_key: true + +      t.timestamps null: false +    end +  end +end diff --git a/db/migrate/20170905123421_create_compliance_controls.rb b/db/migrate/20170905123421_create_compliance_controls.rb new file mode 100644 index 000000000..6b507bb8d --- /dev/null +++ b/db/migrate/20170905123421_create_compliance_controls.rb @@ -0,0 +1,16 @@ +class CreateComplianceControls < ActiveRecord::Migration +  def change +    create_table :compliance_controls do |t| +      t.references :compliance_control_set, index: true, foreign_key: true +      t.references :compliance_control_block, index: true, foreign_key: true +      t.string :type +      t.json :control_attributes +      t.string :name +      t.string :code +      t.integer :criticity +      t.text :comment + +      t.timestamps null: false +    end +  end +end diff --git a/db/migrate/20170905130413_create_compliance_check_sets.rb b/db/migrate/20170905130413_create_compliance_check_sets.rb new file mode 100644 index 000000000..21055a3f2 --- /dev/null +++ b/db/migrate/20170905130413_create_compliance_check_sets.rb @@ -0,0 +1,14 @@ +class CreateComplianceCheckSets < ActiveRecord::Migration +  def change +    create_table :compliance_check_sets do |t| +      t.references :referential, index: true, foreign_key: true +      t.references :compliance_control_set, index: true, foreign_key: true +      t.references :workbench, index: true, foreign_key: true +      t.string :creator +      t.string :status +      t.references :parent, polymorphic: true, index: true + +      t.timestamps null: false +    end +  end +end diff --git a/db/migrate/20170905135646_create_compliance_check_blocks.rb b/db/migrate/20170905135646_create_compliance_check_blocks.rb new file mode 100644 index 000000000..c461e656b --- /dev/null +++ b/db/migrate/20170905135646_create_compliance_check_blocks.rb @@ -0,0 +1,11 @@ +class CreateComplianceCheckBlocks < ActiveRecord::Migration +  def change +    create_table :compliance_check_blocks do |t| +      t.string :name +      t.hstore :condition_attributes +      t.references :compliance_check_set, index: true, foreign_key: true + +      t.timestamps null: false +    end +  end +end diff --git a/db/migrate/20170906084628_create_compliance_checks.rb b/db/migrate/20170906084628_create_compliance_checks.rb new file mode 100644 index 000000000..1d6bdaaf2 --- /dev/null +++ b/db/migrate/20170906084628_create_compliance_checks.rb @@ -0,0 +1,16 @@ +class CreateComplianceChecks < ActiveRecord::Migration +  def change +    create_table :compliance_checks do |t| +      t.references :compliance_check_set, index: true, foreign_key: true +      t.references :compliance_check_block, index: true, foreign_key: true +      t.string :type +      t.json :control_attributes +      t.string :name +      t.string :code +      t.integer :criticity +      t.text :comment + +      t.timestamps null: false +    end +  end +end diff --git a/db/migrate/20170906091136_create_compliance_check_resources.rb b/db/migrate/20170906091136_create_compliance_check_resources.rb new file mode 100644 index 000000000..45713fed5 --- /dev/null +++ b/db/migrate/20170906091136_create_compliance_check_resources.rb @@ -0,0 +1,13 @@ +class CreateComplianceCheckResources < ActiveRecord::Migration +  def change +    create_table :compliance_check_resources do |t| +      t.string :status +      t.string :name +      t.string :type +      t.string :reference +      t.hstore :metrics + +      t.timestamps null: false +    end +  end +end diff --git a/db/migrate/20170906092619_create_new_compliance_check_results.rb b/db/migrate/20170906092619_create_new_compliance_check_results.rb new file mode 100644 index 000000000..a22800a8f --- /dev/null +++ b/db/migrate/20170906092619_create_new_compliance_check_results.rb @@ -0,0 +1,14 @@ +class CreateNewComplianceCheckResults < ActiveRecord::Migration +  def change +    drop_table :compliance_check_results if table_exists? :compliance_check_results +    create_table :compliance_check_results do |t| +      t.references :compliance_check, index: true, foreign_key: true +      t.references :compliance_check_resource, index: true, foreign_key: true +      t.string :message_key +      t.hstore :message_attributes +      t.hstore :resource_attributes + +      t.timestamps null: false +    end +  end +end diff --git a/db/schema.rb b/db/schema.rb index 98e60c909..9207590b5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -145,6 +145,107 @@ ActiveRecord::Schema.define(version: 20170907082913) do    add_index "companies", ["objectid"], name: "companies_objectid_key", unique: true, using: :btree    add_index "companies", ["registration_number"], name: "companies_registration_number_key", using: :btree +  create_table "compliance_check_blocks", id: :bigserial, force: :cascade do |t| +    t.string   "name" +    t.hstore   "condition_attributes" +    t.integer  "compliance_check_set_id" +    t.datetime "created_at",              null: false +    t.datetime "updated_at",              null: false +  end + +  add_index "compliance_check_blocks", ["compliance_check_set_id"], name: "index_compliance_check_blocks_on_compliance_check_set_id", using: :btree + +  create_table "compliance_check_resources", id: :bigserial, force: :cascade do |t| +    t.string   "status" +    t.string   "name" +    t.string   "type" +    t.string   "reference" +    t.hstore   "metrics" +    t.datetime "created_at", null: false +    t.datetime "updated_at", null: false +  end + +  create_table "compliance_check_results", id: :bigserial, force: :cascade do |t| +    t.integer  "compliance_check_id" +    t.integer  "compliance_check_resource_id" +    t.string   "message_key" +    t.hstore   "message_attributes" +    t.hstore   "resource_attributes" +    t.datetime "created_at",                   null: false +    t.datetime "updated_at",                   null: false +  end + +  add_index "compliance_check_results", ["compliance_check_id"], name: "index_compliance_check_results_on_compliance_check_id", using: :btree +  add_index "compliance_check_results", ["compliance_check_resource_id"], name: "index_compliance_check_results_on_compliance_check_resource_id", using: :btree + +  create_table "compliance_check_sets", id: :bigserial, force: :cascade do |t| +    t.integer  "referential_id" +    t.integer  "compliance_control_set_id" +    t.integer  "workbench_id" +    t.string   "creator" +    t.string   "status" +    t.integer  "parent_id" +    t.string   "parent_type" +    t.datetime "created_at",                null: false +    t.datetime "updated_at",                null: false +  end + +  add_index "compliance_check_sets", ["compliance_control_set_id"], name: "index_compliance_check_sets_on_compliance_control_set_id", using: :btree +  add_index "compliance_check_sets", ["parent_type", "parent_id"], name: "index_compliance_check_sets_on_parent_type_and_parent_id", using: :btree +  add_index "compliance_check_sets", ["referential_id"], name: "index_compliance_check_sets_on_referential_id", using: :btree +  add_index "compliance_check_sets", ["workbench_id"], name: "index_compliance_check_sets_on_workbench_id", using: :btree + +  create_table "compliance_checks", id: :bigserial, force: :cascade do |t| +    t.integer  "compliance_check_set_id" +    t.integer  "compliance_check_block_id" +    t.string   "type" +    t.json     "control_attributes" +    t.string   "name" +    t.string   "code" +    t.integer  "criticity" +    t.text     "comment" +    t.datetime "created_at",                null: false +    t.datetime "updated_at",                null: false +  end + +  add_index "compliance_checks", ["compliance_check_block_id"], name: "index_compliance_checks_on_compliance_check_block_id", using: :btree +  add_index "compliance_checks", ["compliance_check_set_id"], name: "index_compliance_checks_on_compliance_check_set_id", using: :btree + +  create_table "compliance_control_blocks", id: :bigserial, force: :cascade do |t| +    t.string   "name" +    t.hstore   "condition_attributes" +    t.integer  "compliance_control_set_id" +    t.datetime "created_at",                null: false +    t.datetime "updated_at",                null: false +  end + +  add_index "compliance_control_blocks", ["compliance_control_set_id"], name: "index_compliance_control_blocks_on_compliance_control_set_id", using: :btree + +  create_table "compliance_control_sets", id: :bigserial, force: :cascade do |t| +    t.string   "name" +    t.integer  "organisation_id" +    t.datetime "created_at",      null: false +    t.datetime "updated_at",      null: false +  end + +  add_index "compliance_control_sets", ["organisation_id"], name: "index_compliance_control_sets_on_organisation_id", using: :btree + +  create_table "compliance_controls", id: :bigserial, force: :cascade do |t| +    t.integer  "compliance_control_set_id" +    t.integer  "compliance_control_block_id" +    t.string   "type" +    t.json     "control_attributes" +    t.string   "name" +    t.string   "code" +    t.integer  "criticity" +    t.text     "comment" +    t.datetime "created_at",                  null: false +    t.datetime "updated_at",                  null: false +  end + +  add_index "compliance_controls", ["compliance_control_block_id"], name: "index_compliance_controls_on_compliance_control_block_id", using: :btree +  add_index "compliance_controls", ["compliance_control_set_id"], name: "index_compliance_controls_on_compliance_control_set_id", using: :btree +    create_table "connection_links", id: :bigserial, force: :cascade do |t|      t.integer  "departure_id",                           limit: 8      t.integer  "arrival_id",                             limit: 8 @@ -864,6 +965,18 @@ ActiveRecord::Schema.define(version: 20170907082913) do    add_foreign_key "access_links", "access_points", name: "aclk_acpt_fkey"    add_foreign_key "api_keys", "organisations" +  add_foreign_key "compliance_check_blocks", "compliance_check_sets" +  add_foreign_key "compliance_check_results", "compliance_check_resources" +  add_foreign_key "compliance_check_results", "compliance_checks" +  add_foreign_key "compliance_check_sets", "compliance_control_sets" +  add_foreign_key "compliance_check_sets", "referentials" +  add_foreign_key "compliance_check_sets", "workbenches" +  add_foreign_key "compliance_checks", "compliance_check_blocks" +  add_foreign_key "compliance_checks", "compliance_check_sets" +  add_foreign_key "compliance_control_blocks", "compliance_control_sets" +  add_foreign_key "compliance_control_sets", "organisations" +  add_foreign_key "compliance_controls", "compliance_control_blocks" +  add_foreign_key "compliance_controls", "compliance_control_sets"    add_foreign_key "group_of_lines_lines", "group_of_lines", name: "groupofline_group_fkey", on_delete: :cascade    add_foreign_key "journey_frequencies", "timebands", on_delete: :nullify    add_foreign_key "journey_frequencies", "vehicle_journeys", on_delete: :nullify diff --git a/lib/stif/reflex_synchronization.rb b/lib/stif/reflex_synchronization.rb index b3f474221..a3bf3957e 100644 --- a/lib/stif/reflex_synchronization.rb +++ b/lib/stif/reflex_synchronization.rb @@ -38,7 +38,7 @@ module Stif          if object.valid?            object.save          else -          Rails.logger.error "Reflex:sync - #{object.class.model_name} with objectid #{object.objectid} and name #{object.name} can't be saved" +          Rails.logger.error "Reflex:sync - #{object.class.model_name} with objectid #{object.objectid} can't be saved - errors : #{object.errors.messages}"          end        end diff --git a/lib/tasks/ci.rake b/lib/tasks/ci.rake index 90e47560e..7fe289ed6 100644 --- a/lib/tasks/ci.rake +++ b/lib/tasks/ci.rake @@ -2,7 +2,7 @@ namespace :ci do    desc "Prepare CI build"    task :setup do      cp "config/database/jenkins.yml", "config/database.yml" -    sh "RAILS_ENV=test rake db:migrate" +    sh "RAILS_ENV=test rake db:drop db:create db:migrate"      sh "npm --production --no-progress install"    end @@ -19,7 +19,11 @@ namespace :ci do    end    def deploy_env -    git_branch.in?(deploy_envs) ? git_branch : "dev" +    if git_branch == "master" +      "dev" +    elsif git_branch.in?(deploy_envs) +      git_branch +    end    end    desc "Check security aspects" @@ -37,7 +41,11 @@ namespace :ci do    desc "Deploy after CI"    task :deploy do -    sh "cap #{deploy_env} deploy:migrations" +    if deploy_env +      sh "cap #{deploy_env} deploy:migrations" +    else +      puts "No deploy for branch #{git_branch}" +    end    end    desc "Clean test files" diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 000b799db..336f20945 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -1,7 +1,9 @@ -RSpec.describe RoutesController, :type => :controller do +Route = Chouette::Route + +RSpec.describe RoutesController, type: :controller do    login_user -  let!(:route) { create(:route) } +  let(:route) { create(:route) }    it { is_expected.to be_kind_of(ChouetteController) } @@ -10,6 +12,7 @@ RSpec.describe RoutesController, :type => :controller do        # expect(response).to redirect_to( referential_line_path(referential,route.line) )      end    end +    shared_examples_for "line and referential linked" do      it "assigns route.line as @line" do        expect(assigns[:line]).to eq(route.line) @@ -19,6 +22,7 @@ RSpec.describe RoutesController, :type => :controller do        expect(assigns[:referential]).to eq(referential)      end    end +    shared_examples_for "route, line and referential linked" do      it "assigns route as @route" do        expect(assigns[:route]).to eq(route) @@ -28,8 +32,8 @@ RSpec.describe RoutesController, :type => :controller do    describe "GET /index" do      before(:each) do -      get :index, :line_id => route.line_id, -          :referential_id => referential.id +      get :index, line_id: route.line_id, +          referential_id: referential.id      end      it_behaves_like "line and referential linked" @@ -38,9 +42,9 @@ RSpec.describe RoutesController, :type => :controller do    describe "POST /create" do      before(:each) do -      post :create, :line_id => route.line_id, -          :referential_id => referential.id, -          :route => { :name => "changed"} +      post :create, line_id: route.line_id, +          referential_id: referential.id, +          route: { name: "changed"}      end      it_behaves_like "line and referential linked" @@ -49,9 +53,9 @@ RSpec.describe RoutesController, :type => :controller do    describe "PUT /update" do      before(:each) do -      put :update, :id => route.id, :line_id => route.line_id, -          :referential_id => referential.id, -          :route => route.attributes +      put :update, id: route.id, line_id: route.line_id, +          referential_id: referential.id, +          route: route.attributes      end      it_behaves_like "route, line and referential linked" @@ -60,9 +64,9 @@ RSpec.describe RoutesController, :type => :controller do    describe "GET /show" do      before(:each) do -      get :show, :id => route.id, -          :line_id => route.line_id, -          :referential_id => referential.id +      get :show, id: route.id, +          line_id: route.line_id, +          referential_id: referential.id      end      it_behaves_like "route, line and referential linked" @@ -71,11 +75,22 @@ RSpec.describe RoutesController, :type => :controller do        expect(assigns[:map]).to be_an_instance_of(RouteMap)        expect(assigns[:map].route).to eq(route)      end - -    #it "assigns route.stop_points.paginate(:page => nil) as @stop_points" do -    #  expect(assigns[:stop_points]).to eq(route.stop_points.paginate(:page => nil)) -    #end    end -end +  describe "POST /duplicate" do +    let!( :route_prime ){ route } + +    it "creates a new route" do +      expect do +        post :duplicate, +          referential_id: route.line.line_referential_id, +          line_id: route.line_id, +          id: route.id +      end.to change { Route.count }.by(1) + +      expect(Route.last.name).to eq(route.name) +      expect(Route.last.published_name).to eq(route.published_name) +    end +  end +end diff --git a/spec/factories/compliance_check_blocks.rb b/spec/factories/compliance_check_blocks.rb new file mode 100644 index 000000000..0bd23c0d6 --- /dev/null +++ b/spec/factories/compliance_check_blocks.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do +  factory :compliance_check_block do +    sequence(:name) { |n| "Compliance check block #{n}" } +    association :compliance_check_set +  end +end diff --git a/spec/factories/compliance_check_resources.rb b/spec/factories/compliance_check_resources.rb new file mode 100644 index 000000000..813153be2 --- /dev/null +++ b/spec/factories/compliance_check_resources.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do +  factory :compliance_check_resource do +    status :new +    sequence(:name) { |n| "Compliance check resource #{n}" } +  end +end diff --git a/spec/factories/compliance_check_results.rb b/spec/factories/compliance_check_results.rb new file mode 100644 index 000000000..a56d77ce4 --- /dev/null +++ b/spec/factories/compliance_check_results.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do +  factory :compliance_check_result do +    association :compliance_check +    association :compliance_check_resource +    message_key "message_key" +  end +end diff --git a/spec/factories/compliance_check_sets.rb b/spec/factories/compliance_check_sets.rb new file mode 100644 index 000000000..9fd6ef4e0 --- /dev/null +++ b/spec/factories/compliance_check_sets.rb @@ -0,0 +1,8 @@ +FactoryGirl.define do +  factory :compliance_check_set do +    status :new +    association :referential +    association :compliance_control_set +    association :workbench +  end +end diff --git a/spec/factories/compliance_checks.rb b/spec/factories/compliance_checks.rb new file mode 100644 index 000000000..4009653da --- /dev/null +++ b/spec/factories/compliance_checks.rb @@ -0,0 +1,11 @@ +FactoryGirl.define do +  factory :compliance_check do +    sequence(:name) { |n| "Compliance check #{n}" } +    type "Type" +    criticity :info +    code "code" +    comment "Text" +    association :compliance_check_set +    association :compliance_check_block +  end +end diff --git a/spec/factories/compliance_control_blocks.rb b/spec/factories/compliance_control_blocks.rb new file mode 100644 index 000000000..5bc45cc75 --- /dev/null +++ b/spec/factories/compliance_control_blocks.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do +  factory :compliance_control_block do +    sequence(:name) { |n| "Compliance control block #{n}" } +    association :compliance_control_set +  end +end diff --git a/spec/factories/compliance_control_sets.rb b/spec/factories/compliance_control_sets.rb new file mode 100644 index 000000000..5e4acf3c4 --- /dev/null +++ b/spec/factories/compliance_control_sets.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do +  factory :compliance_control_set do +    sequence(:name) { |n| "Compliance control set #{n}" } +    association :organisation +  end +end diff --git a/spec/factories/compliance_controls.rb b/spec/factories/compliance_controls.rb new file mode 100644 index 000000000..28b760383 --- /dev/null +++ b/spec/factories/compliance_controls.rb @@ -0,0 +1,11 @@ +FactoryGirl.define do +  factory :compliance_control do +    sequence(:name) { |n| "Compliance control #{n}" } +    type "Type" +    criticity :info +    code "code" +    comment "Text" +    association :compliance_control_set +    association :compliance_control_block +  end +end diff --git a/spec/factories/import_messages.rb b/spec/factories/import_messages.rb new file mode 100644 index 000000000..75f80566c --- /dev/null +++ b/spec/factories/import_messages.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do +  factory :import_message do +    association :import +    association :resource, factory: :import_resource +    criticity :info +  end +end diff --git a/spec/factories/workbenches.rb b/spec/factories/workbenches.rb index f51e7d94c..d55141513 100644 --- a/spec/factories/workbenches.rb +++ b/spec/factories/workbenches.rb @@ -1,8 +1,8 @@  FactoryGirl.define do    factory :workbench do -    sequence(:name) { |n| "Workbench #{n}" } +    name "Gestion de l'offre" -    association :organisation, :factory => :organisation +    association :organisation      association :line_referential      association :stop_area_referential    end diff --git a/spec/features/referentials_spec.rb b/spec/features/referentials_spec.rb index 337271fea..a38577aba 100644 --- a/spec/features/referentials_spec.rb +++ b/spec/features/referentials_spec.rb @@ -120,6 +120,73 @@ describe "Referentials", :type => :feature do    end +  describe "new_from" do +    # let(:cloning) +    let(:worker) { ReferentialCloningWorker.new } + +    let(:line) { create(:line_with_stop_areas) } +    let(:jp) { create(:journey_pattern, route: line.routes.first) } +    let(:tt) { create(:time_table) } +    let(:vj) { create(:vehicle_journey, journey_pattern: jp, time_table: tt) } +    let(:ref_metadata) { create(:referential_metadata, lines: [line], referential: referential) } + +    context "when user is from the same organisation" do + +      xit "should" do +        visit new_referential_path(from: referential.id, current_workbench_id: @user.organisation.workbenches.first.id) + +        select "2018", :from => "referential_metadatas_attributes_0_periods_attributes_0_begin_1i" + +        select "2018", :from => "referential_metadatas_attributes_0_periods_attributes_0_end_1i" + +        click_button "Valider" + +        clone = Referential.where(name: "Copie de first") + +        expect(clone.lines).to include(line) +        expect(clone.lines.first.routes).to match_array(referential.lines.first.routes) + +        clone_jp = clone.lines.first.routes.first.journey_patterns +        expect(clone_jp).to include(jp) + +        clone_vj = clone.lines.first.routes.first.journey_patterns.first.vehicle_journeys +        expect(clone_vj).to include(vj) + +        clone_tt = clone.lines.first.routes.first.journey_patterns.first.vehicle_journeys.first.time_tables +        expect(clone_tt).to include(tt) +      end + +      # it "should have the lines from source" do +      #   expect(clone.lines).to include(line) +      # end +      # +      # it "should have the routes from source" do +      #   expect(clone.lines.first.routes).to match_array(referential.lines.first.routes) +      # end +      # +      # it "should have the journey patterns from source" do +      #   clone_jp = clone.lines.first.routes.first.journey_patterns +      #   expect(clone_jp).to include(jp) +      # end +      # +      # it "should have the vehicle journeys from source" do +      #   clone_vj = clone.lines.first.routes.first.journey_patterns.first.vehicle_journeys +      #   expect(clone_vj).to include(vj) +      # end +      # +      # it "should have the timetables from source" do +      #   clone_tt = clone.lines.first.routes.first.journey_patterns.first.vehicle_journeys.first.time_tables +      #   expect(clone_tt).to include(tt) +      # end +    end + +    # context "when user is from another organisation" do +    #   before :each do +    # +    #   end +    # end +  end +    describe "destroy" do      let(:referential) {  create(:referential, :organisation => @user.organisation) } diff --git a/spec/features/users/user_edit_spec.rb b/spec/features/users/user_edit_spec.rb index 4b083a226..14995d8e5 100644 --- a/spec/features/users/user_edit_spec.rb +++ b/spec/features/users/user_edit_spec.rb @@ -36,6 +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.organisation.workbenches << create(:workbench)      other = FactoryGirl.create(:user, email: 'other@example.com')      login_as(me, :scope => :user)      visit edit_user_registration_path(other) diff --git a/spec/features/users/user_index_spec.rb b/spec/features/users/user_index_spec.rb index 2a9199da3..b2dbdbb51 100644 --- a/spec/features/users/user_index_spec.rb +++ b/spec/features/users/user_index_spec.rb @@ -19,6 +19,7 @@ feature 'User index page', :devise do    #   Then I see my own email address    scenario 'user sees own email address' do      user = create(:user) +    user.organisation.workbenches << create(:workbench)      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 d840d752c..ae3c25933 100644 --- a/spec/features/users/user_show_spec.rb +++ b/spec/features/users/user_show_spec.rb @@ -19,6 +19,7 @@ feature 'User profile page', :devise do    #   Then I see my own email address    scenario 'user sees own profile' do      user = FactoryGirl.create(:user) +    user.organisation.workbenches << create(:workbench)      login_as(user, :scope => :user)      visit organisation_user_path(user)      # FIXME ref #819 @@ -32,6 +33,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.organisation.workbenches << create(:workbench)      other = FactoryGirl.create(:user, email: 'other@example.com', :organisation => me.organisation)      login_as(me, :scope => :user)      Capybara.current_session.driver.header 'Referer', authenticated_root_path diff --git a/spec/models/chouette/route/route_duplication_spec.rb b/spec/models/chouette/route/route_duplication_spec.rb new file mode 100644 index 000000000..6645b909f --- /dev/null +++ b/spec/models/chouette/route/route_duplication_spec.rb @@ -0,0 +1,52 @@ +# From Chouette import what we need ™ +Route     = Chouette::Route +StopArea  = Chouette::StopArea +StopPoint = Chouette::StopPoint + +RSpec.describe Route do + +  let!( :route ){ create :route } + +  context '#duplicate' do  +    describe 'properties' do +      it 'same attribute values' do +        route.duplicate +        expect( values_for_create(Route.last, except: %w{objectid}) ).to eq( values_for_create( route, except: %w{objectid} ) ) +      end +      it 'and others cannot' do +        expect{ route.duplicate name: 'YAN', line_id: 42  }.to raise_error(ArgumentError) +      end +      it 'same associated stop_areeas' do +        expect( route.duplicate.stop_areas.pluck(:id) ).to eq(route.stop_areas.pluck(:id)) +      end +    end + +    describe 'side_effects' do +      it { +        expect{ route.duplicate }.to change{Route.count}.by(1) +      } +      it 'duplicates its stop points' do +        expect{ route.duplicate }.to change{StopPoint.count}.by(route.stop_points.count) +      end +      it 'does bot duplicate the stop areas' do +        expect{ route.duplicate }.not_to change{StopArea.count} +      end +    end + +    describe 'is idempotent, concerning' do +      let( :first_duplicate ){ route.duplicate  } +      let( :second_duplicate ){ first_duplicate.reload.duplicate } + +      it 'the required attributes' do +        expect( values_for_create(first_duplicate, except: %w{objectid}) ).to eq( values_for_create( second_duplicate, except: %w{objectid} ) ) +      end  + +      it 'the stop areas' do +        expect( first_duplicate.stop_areas.pluck(:id) ).to eq( route.stop_areas.pluck(:id) ) +        expect( second_duplicate.stop_areas.pluck(:id) ).to eq( first_duplicate.stop_areas.pluck(:id) ) +      end + +    end +  end + +end diff --git a/spec/models/chouette/stop_point_spec.rb b/spec/models/chouette/stop_point_spec.rb index 5eae8caf0..329e76a75 100644 --- a/spec/models/chouette/stop_point_spec.rb +++ b/spec/models/chouette/stop_point_spec.rb @@ -1,6 +1,7 @@ -require 'spec_helper' +# From Chouette import what we need ™ +StopPoint = Chouette::StopPoint -describe Chouette::StopPoint, :type => :model do +describe StopPoint, :type => :model do    let!(:vehicle_journey) { create(:vehicle_journey)}    subject { Chouette::Route.find( vehicle_journey.route_id).stop_points.first } @@ -38,4 +39,18 @@ describe Chouette::StopPoint, :type => :model do        expect(jpsp_stop_point_ids(@vehicle.journey_pattern_id)).not_to include(@stop_point.id)      end    end + +  describe '#duplicate' do +    let!( :new_route ){ create :route } + +    it 'creates a new instance' do +      expect{ subject.duplicate(for_route: new_route) }.to change{ StopPoint.count }.by(1) +    end +    it 'new instance has a new route' do +      expect(subject.duplicate(for_route: new_route).route).to eq(new_route) +    end +    it 'and old stop_area' do +      expect(subject.duplicate(for_route: new_route).stop_area).to eq(subject.stop_area) +    end +  end  end diff --git a/spec/models/compliance_check_block_spec.rb b/spec/models/compliance_check_block_spec.rb new file mode 100644 index 000000000..f581d5085 --- /dev/null +++ b/spec/models/compliance_check_block_spec.rb @@ -0,0 +1,9 @@ +require 'rails_helper' + +RSpec.describe ComplianceCheckBlock, type: :model do +  it 'should have a valid factory' do +    expect(FactoryGirl.build(:compliance_check_block)).to be_valid +  end + +  it { should belong_to :compliance_check_set } +end diff --git a/spec/models/compliance_check_resource_spec.rb b/spec/models/compliance_check_resource_spec.rb new file mode 100644 index 000000000..a9366bea2 --- /dev/null +++ b/spec/models/compliance_check_resource_spec.rb @@ -0,0 +1,7 @@ +require 'rails_helper' + +RSpec.describe ComplianceCheckResource, type: :model do +  it 'should have a valid factory' do +    expect(FactoryGirl.build(:compliance_check_resource)).to be_valid +  end +end diff --git a/spec/models/compliance_check_result_spec.rb b/spec/models/compliance_check_result_spec.rb new file mode 100644 index 000000000..95586862f --- /dev/null +++ b/spec/models/compliance_check_result_spec.rb @@ -0,0 +1,10 @@ +require 'rails_helper' + +RSpec.describe ComplianceCheckResult, type: :model do +  it 'should have a valid factory' do +    expect(FactoryGirl.build(:compliance_check_result)).to be_valid +  end + +  it { should belong_to :compliance_check } +  it { should belong_to :compliance_check_resource } +end diff --git a/spec/models/compliance_check_set_spec.rb b/spec/models/compliance_check_set_spec.rb new file mode 100644 index 000000000..6e53c9def --- /dev/null +++ b/spec/models/compliance_check_set_spec.rb @@ -0,0 +1,12 @@ +require 'rails_helper' + +RSpec.describe ComplianceCheckSet, type: :model do +  it 'should have a valid factory' do +    expect(FactoryGirl.build(:compliance_check_set)).to be_valid +  end + +  it { should belong_to :referential } +  it { should belong_to :workbench } +  it { should belong_to :compliance_control_set } +  it { should belong_to :parent } +end diff --git a/spec/models/compliance_check_spec.rb b/spec/models/compliance_check_spec.rb new file mode 100644 index 000000000..4fbc23d42 --- /dev/null +++ b/spec/models/compliance_check_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +RSpec.describe ComplianceCheck, type: :model do +  it 'should have a valid factory' do +    expect(FactoryGirl.build(:compliance_check)).to be_valid +  end + +  it { should belong_to :compliance_check_set } +  it { should belong_to :compliance_check_block } + +  it { should validate_presence_of :criticity } +  it { should validate_presence_of :name } +  it { should validate_presence_of :code } +end diff --git a/spec/models/compliance_control_block_spec.rb b/spec/models/compliance_control_block_spec.rb new file mode 100644 index 000000000..248049b0c --- /dev/null +++ b/spec/models/compliance_control_block_spec.rb @@ -0,0 +1,9 @@ +require 'rails_helper' + +RSpec.describe ComplianceControlBlock, type: :model do +  it 'should have a valid factory' do +    expect(FactoryGirl.build(:compliance_control_block)).to be_valid +  end + +  it { should belong_to :compliance_control_set } +end diff --git a/spec/models/compliance_control_set_spec.rb b/spec/models/compliance_control_set_spec.rb new file mode 100644 index 000000000..fb46bc65a --- /dev/null +++ b/spec/models/compliance_control_set_spec.rb @@ -0,0 +1,9 @@ +require 'rails_helper' + +RSpec.describe ComplianceControlSet, type: :model do +  it 'should have a valid factory' do +    expect(FactoryGirl.build(:compliance_control_set)).to be_valid +  end + +  it { should belong_to :organisation } +end diff --git a/spec/models/compliance_control_spec.rb b/spec/models/compliance_control_spec.rb new file mode 100644 index 000000000..b00ff4c5a --- /dev/null +++ b/spec/models/compliance_control_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +RSpec.describe ComplianceControl, type: :model do +  it 'should have a valid factory' do +    expect(FactoryGirl.build(:compliance_control)).to be_valid +  end + +  it { should belong_to :compliance_control_set } +  it { should belong_to :compliance_control_block } + +  it { should validate_presence_of :criticity } +  it { should validate_presence_of :name } +  it { should validate_presence_of :code } +end diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb index 477d269e0..cd5a30982 100644 --- a/spec/models/import_spec.rb +++ b/spec/models/import_spec.rb @@ -26,12 +26,35 @@ RSpec.describe Import, type: :model do      )    end -  # describe "#destroy" do -  #   it "must call #destroy on imports children and then import_messages, import_resources linked" do -  #     TODO -  # -  #   end -  # end +  describe "#destroy" do +    it "must destroy all child imports" do +      workbench_import = create(:workbench_import) +      create(:netex_import, parent: workbench_import) + +      workbench_import.destroy + +      expect(workbench_import).to be_destroyed +      expect(NetexImport.count).to eq(0) +    end + +    it "must destroy all associated ImportMessages" do +      import = create(:import) +      create(:import_resource, import: import) + +      import.destroy + +      expect(ImportResource.count).to eq(0) +    end + +    it "must destroy all associated ImportResources" do +      import = create(:import) +      create(:import_message, import: import) + +      import.destroy + +      expect(ImportMessage.count).to eq(0) +    end +  end    describe "#notify_parent" do      it "must call #child_change on its parent" do diff --git a/spec/models/referential_metadata_spec.rb b/spec/models/referential_metadata_spec.rb index 775e6f228..291ed974a 100644 --- a/spec/models/referential_metadata_spec.rb +++ b/spec/models/referential_metadata_spec.rb @@ -30,8 +30,8 @@ RSpec.describe ReferentialMetadata, :type => :model do        expect(new_referential_metadata.referential).to be(nil)      end -    it "should have the same referential_source" do -      expect(new_referential_metadata.referential_source).to eq(referential_metadata.referential_source) +    it "should have the right referential_source" do +      expect(new_referential_metadata.referential_source).to eq(referential_metadata.referential)      end    end diff --git a/spec/policies/route_policy_spec.rb b/spec/policies/route_policy_spec.rb index 243d85acb..d7edceaef 100644 --- a/spec/policies/route_policy_spec.rb +++ b/spec/policies/route_policy_spec.rb @@ -6,6 +6,10 @@ RSpec.describe RoutePolicy, type: :policy do      it_behaves_like 'permitted policy and same organisation', 'routes.create', archived: true    end +  permissions :duplicate? do +    it_behaves_like 'permitted policy and same organisation', 'routes.create', archived: true +  end +    permissions :destroy? do      it_behaves_like 'permitted policy and same organisation', 'routes.destroy', archived: true    end diff --git a/spec/routing/routes_routing_spec.rb b/spec/routing/routes_routing_spec.rb new file mode 100644 index 000000000..311de9f39 --- /dev/null +++ b/spec/routing/routes_routing_spec.rb @@ -0,0 +1,12 @@ +RSpec.describe "routes for Routes", type: :routing do +  context "routes /referentials/:id/lines/:id/routes/:id/duplicate" do + +    let( :controller ){ {controller: 'routes', referential_id: ':referential_id', line_id: ':line_id', id: ':id'}  } + +    it 'with method post to #post_duplicate' do +      expect( +        post: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' +      ).to route_to controller.merge(action: 'duplicate') +    end +  end +end diff --git a/spec/support/helpers/model_compare_helpers.rb b/spec/support/helpers/model_compare_helpers.rb new file mode 100644 index 000000000..a10892af0 --- /dev/null +++ b/spec/support/helpers/model_compare_helpers.rb @@ -0,0 +1,15 @@ +module Support::ModelCompareHelpers +   +  def values_for_create obj, **overrides +    except = overrides.delete(:except) || [] +    keys = obj.attributes.keys - except - %w{id created_at updated_at} +    overrides.inject(obj.attributes.slice(*keys)){ |atts, (k,v)| +      atts.merge k.to_s => v +    } +  end + +end + +RSpec.configure do | rspec | +  rspec.include Support::ModelCompareHelpers, type: :model +end diff --git a/spec/support/referential.rb b/spec/support/referential.rb index c431856b8..3b74cb639 100644 --- a/spec/support/referential.rb +++ b/spec/support/referential.rb @@ -52,7 +52,7 @@ RSpec.configure do |config|        referential.add_member organisation, owner: true      end -    workbench = Workbench.create!(:name => "first", organisation: organisation, line_referential: line_referential, stop_area_referential: stop_area_referential) +    workbench = Workbench.create!(:name => "Gestion de l'offre", organisation: organisation, line_referential: line_referential, stop_area_referential: stop_area_referential)      referential = Referential.create! prefix: "first", name: "first", slug: "first", organisation: organisation, workbench: workbench    end | 
