diff options
78 files changed, 651 insertions, 316 deletions
diff --git a/INSTALL.md b/INSTALL.md index e44b072f4..392ef5d9f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -8,6 +8,17 @@ Example with [rvm](https://rvm.io/) (other solutions : rbenv, packages..): rvm install 2.3.1 ``` +Nokogiri on macOS + +http://www.nokogiri.org/tutorials/installing_nokogiri.html tells us that `xz` can cause troubles, here is what to do + +``` +brew unlink xz +gem install nokogiri # or bundle install +brew link xz +``` + + ## Node and Yarn Yarn needs node. If you use Node Version Manager [NVM](https://github.com/creationix/nvm) you can rely on the content of `.nvmrc`. Otherwise please make sure to use a compatible version, still best to use the same as indicated by `.nvrmc`. @@ -15,7 +26,7 @@ Yarn needs node. If you use Node Version Manager [NVM](https://github.com/creati * Install node ```sh -nvm install 6.12.0 +nvm install 6.13.0 ``` * Install [yarn](https://yarnpkg.com/lang/en/docs/install/) @@ -36,41 +47,6 @@ sudo apt-get update && sudo apt-get install yarn yarn install ``` -### Installation Caveats - -#### Node Related Issue, libv8 - -`libv8` might cause you troubles, depending on your local configuration. If you have `libv8` installed (probably because of `node.js`) you might need to tell bundler/Rubygems to use the system version. - -```sh -bundle config build.libv8 --with-system-v8 -bundle -``` - -or - -```sh -gem install libv8 -v '<version>' -- --with-system-v8 -bundle -``` - -You will get the correct value of `<version>` from bundler's error message. - -#### Node Related Issue, therubyracer - -Even after `libv8` installation working, the gem `therubyracer` might not like the `libv8` version chosen. - -In that case however we can let the gem make its own choice: - -```sh -gem uninstall libv8 -gem install therubyracer -v '<version>' -``` - -The version to be installed is indicated in the error message bundler gave us in the first place. - -This will install an appropriate `libv8` version and we can continue with `bundle`. - ## Postgres ### Create user @@ -89,53 +65,12 @@ When promted for the password enter the highly secure string `chouette`. As documented [here](https://github.com/dryade/georuby-ext/issues/2) we need some more libs before we can start the `rake` setup tasks. - On mac/OS : ```sh brew install postgis ``` -<<<<<<< HEAD -### Authentication - -See `config.chouette_authentication_settings`. - -Use the database authentication or get an invitation to [STIF Portail](http://stif-portail-dev.af83.priv/). - -### Run seed - -Run : - - bundle exec rake db:seed - -Two users are created : stif-boiv@af83.com/secret and stif-boiv+transporteur@af83.com/secret - -If you have access to STIF CodifLigne and Reflex : - - bundle exec rake codifligne:sync - bundle exec rake reflex:sync - -To create Referential with some data (Route, JourneyPattern, VehicleJourney, etc) : - - bundle exec rake referential:create - -# Troubleshooting - -If PG complains about illegal type `hstore` in your tests that is probably because the shared extension is not installed, here is what to do: - -#### Check installation - -* Run tests - - bundle exec rake spec - bundle exec rake teaspoon - -* Start local server - - bundle exec rails server - -======= On debian/ubuntu system : ```sh @@ -156,50 +91,34 @@ Go into your local repository and install the gems bundle install ``` -#### Nokogiri on macOS - -http://www.nokogiri.org/tutorials/installing_nokogiri.html tells us that `xz` can cause troubles, here is what to do - -``` -brew unlink xz -gem install nokogiri # or bundle install -brew link xz -``` - ### Database #### Create database ```sh bundle exec rake db:create db:migrate -RAILS_ENV=test bundle exec rake db:create db:migrate ``` -#### Load seed datas ->>>>>>> master +#### Use seed + +Run : ```sh bundle exec rake db:seed:stif ``` -#### Synchronise datas with lines and stop areas referentials - -* Launch Sidekiq - -```sh -bundle exec sidekiq -``` +Two users are created : stif-boiv@af83.com/secret and stif-boiv+transporteur@af83.com/secret -* Execute the Synchronization Tasks +#### Synchronize with STIF CODIFLIGNE (Line) and REFLEX (StopArea) ```sh bundle exec rake codifligne:sync bundle exec rake reflex:sync ``` -**N.B.** These are asynchronious tasks, you can observe the launched jobs in your [Sidekiq Console](http://localhost:3000/sidekiq) +**N.B.** These are asynchronous tasks, you can observe the launched jobs in your [Sidekiq Console](http://localhost:3000/sidekiq) -#### Data in various Apartments (Referentials) +#### Create Referential To create `Referential` objects with some data (`Route`, `JourneyPattern`, `VehicleJourney`, etc), you need to wait codifligne and reflex jobs finished. And then you can launch : @@ -207,33 +126,32 @@ To create `Referential` objects with some data (`Route`, `JourneyPattern`, `Vehi bundle exec rake referential:create ``` -### Check installation +### Run tests -#### Run tests - -#### Rspec +* Rspec (Rails test) ```sh bundle exec rake spec -bundle exec rake teaspoon ``` -If Postgres complains about illegal type `hstore` or `unaccent` in your tests that is probably because the shared extension is not installed, here is what to do: - - bundle exec rake db:test:purge - -Thanks to `lib/tasks/extensions.rake`. +* Jest (JavaScript tests) -#### Jest (React integration specs) +```sh +grunt jest #to run the whole specs. +grunt #to watch for changes and automatically run corresponding tests. +``` -`grunt jest` to run the whole specs. +### Run -`grunt` to watch for changes and automatically run corresponding tests. +Launch Sidekiq -#### Start local server +```sh +bundle exec sidekiq +``` ```sh bin/webpack-dev-server // Launch webpack server to compile assets on the fly bundle exec rails server // Launch rails server ``` + You need to have an account on [STIF Portail](http://stif-portail-dev.af83.priv/) to connect to the Rails application. diff --git a/app/assets/javascripts/main_menu.coffee b/app/assets/javascripts/main_menu.coffee index e943f448a..22ecebd25 100644 --- a/app/assets/javascripts/main_menu.coffee +++ b/app/assets/javascripts/main_menu.coffee @@ -21,8 +21,9 @@ $ -> sticker = () -> limit = 51 + offset = 30 - if $(window).scrollTop() >= limit + if $(window).scrollTop() >= limit + offset if stickyActions.length == 0 if ($('.page-action .small').length > 0) stickyActions.push @@ -53,7 +54,7 @@ $ -> for child in item.content child.appendTo $('.sticky-paction') - else + else if $(window).scrollTop() <= limit - offset $('#main_nav').removeClass 'sticky' if $('#menu_top').find('.sticky-content').length > 0 diff --git a/app/assets/stylesheets/OpenLayers/custom.sass b/app/assets/stylesheets/OpenLayers/custom.sass index fa874d924..013c056d6 100644 --- a/app/assets/stylesheets/OpenLayers/custom.sass +++ b/app/assets/stylesheets/OpenLayers/custom.sass @@ -2,15 +2,20 @@ .list-group-item & margin-top: 15px - .routes-labels + .ol-routes-layers + position: absolute + right: 42px + top: .5em padding: 0 - display: flex - justify-content: space-between - flex-wrap: wrap margin: 5px -5px - li - list-style-type: none - flex: 1 0 25% + width: 30% + background-color: transparentize(white, 0.2) + border-radius: 3px + max-height: 90% + overflow-y: scroll + a + display: block + width: calc(100% - 10px) border: 1px solid $lightgrey padding: 5px margin: 5px @@ -18,11 +23,21 @@ cursor: pointer color: $blue white-space: nowrap - + text-overflow: ellipsis + overflow: hidden + font-size: 0.6em &:hover - background: $orange + text-decoration: none + + &.active + background: $blue color: white + .ol-routes-layers-button-wrapper + position: absolute + right: .5em + top: .5em + .ol-scale-line background-color: transparent bottom: 5px @@ -55,20 +70,20 @@ .ol-zoom background-color: transparent - .ol-zoom-in, .ol-zoom-out - background-color: $darkblue - color: #fff - border-radius: 3px - margin: 0 + .ol-zoom-in, .ol-zoom-out, .ol-routes-layers-button + background-color: $darkblue + color: #fff + border-radius: 3px + margin: 0 - .ol-zoom-in - border-bottom-left-radius: 0 - border-bottom-right-radius: 0 + .ol-zoom-in + border-bottom-left-radius: 0 + border-bottom-right-radius: 0 - .ol-zoom-out - margin-top: 1px - border-top-left-radius: 0 - border-top-right-radius: 0 + .ol-zoom-out + margin-top: 1px + border-top-left-radius: 0 + border-top-right-radius: 0 .ol-zoomslider margin: 2px diff --git a/app/assets/stylesheets/components/_modals.sass b/app/assets/stylesheets/components/_modals.sass index e52a2e125..14b783c51 100644 --- a/app/assets/stylesheets/components/_modals.sass +++ b/app/assets/stylesheets/components/_modals.sass @@ -50,3 +50,9 @@ $modalW: 600px .modal-footer border-color: rgba($blue, 0.25) padding: 15px 30px + + .has-error .form-group + margin-bottom: -10px + + .form-group + margin-bottom: 25px diff --git a/app/assets/stylesheets/components/_referential_overview.sass b/app/assets/stylesheets/components/_referential_overview.sass index fc48411a3..7a0cc98c5 100644 --- a/app/assets/stylesheets/components/_referential_overview.sass +++ b/app/assets/stylesheets/components/_referential_overview.sass @@ -117,6 +117,7 @@ padding: 7px 10px border-bottom: 1px solid $grey font-size: 0.8em + display: block &:last-child border-bottom: none .number @@ -135,10 +136,9 @@ overflow: hidden .name display: inline-block - width: $left-size - 50px() + width: $left-size - 10px white-space: nowrap line-height: 20px - margin-left: 5px text-overflow: ellipsis overflow: hidden vertical-align: bottom @@ -182,8 +182,8 @@ height: 100% transition: margin 0.5s background: white - &:last-child - box-shadow: 0 -10px 10px rgba(0,0,0,0.5) + // &:last-child + // box-shadow: 0 -10px 10px rgba(0,0,0,0.5) .week-span left: 15px top: 15px @@ -246,18 +246,17 @@ &.selected, &:hover color: $blue background-color: transparentize($blue, 0.7) + + &:hover + background-color: transparentize(white, 0.7) &:after content: "" left: -1px right: -1px top: 100% height: 10000px - background-color: transparentize($blue, 0.7) position: absolute z-index: 4 - &:hover - background-color: transparentize(white, 0.7) - &:after background-color: transparentize(white, 0.7) .line diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 45b7f55f6..c4961123d 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -28,7 +28,7 @@ class ApplicationController < ActionController::Base protected def user_not_authorized - redirect_to forbidden_path + render 'errors/forbidden', status: 403 end def current_organisation diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb index 75d4cbd09..cc7570d65 100644 --- a/app/controllers/calendars_controller.rb +++ b/app/controllers/calendars_controller.rb @@ -31,10 +31,11 @@ class CalendarsController < ChouetteController end def create - create! do - if @calendar.valid? && has_feature?('application_days_on_calendars') - redirect_to([:edit, @calendar]) - return + create! do |success, failure| + if has_feature?('application_days_on_calendars') + success.html do + redirect_to([:edit, @workgroup, @calendar]) + end end end end @@ -125,4 +126,4 @@ class CalendarsController < ChouetteController scope end -end
\ No newline at end of file +end diff --git a/app/controllers/compliance_check_sets_controller.rb b/app/controllers/compliance_check_sets_controller.rb index 271598428..62b0e6ba3 100644 --- a/app/controllers/compliance_check_sets_controller.rb +++ b/app/controllers/compliance_check_sets_controller.rb @@ -12,7 +12,7 @@ class ComplianceCheckSetsController < ChouetteController @q_for_form = scope.ransack(params[:q]) format.html { @compliance_check_sets = ComplianceCheckSetDecorator.decorate( - @q_for_form.result.order(created_at: :desc) + @q_for_form.result.order(created_at: :desc).paginate(page: params[:page], per_page: 30) ) } end diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb index 5267c15d8..6e3694547 100644 --- a/app/controllers/referentials_controller.rb +++ b/app/controllers/referentials_controller.rb @@ -7,6 +7,8 @@ class ReferentialsController < ChouetteController respond_to :json, :only => :show respond_to :js, :only => :show + before_action :check_cloning_source_is_accessible, only: %i(new create) + def new new! do build_referential @@ -175,6 +177,12 @@ class ReferentialsController < ChouetteController ) end + def check_cloning_source_is_accessible + return unless params[:from] + source = Referential.find params[:from] + return user_not_authorized unless current_user.organisation.workgroups.include?(source.workbench.workgroup) + end + def load_workbench @workbench ||= Workbench.find(params[:workbench_id]) if params[:workbench_id] @workbench ||= resource&.workbench if params[:id] diff --git a/app/controllers/workbenches_controller.rb b/app/controllers/workbenches_controller.rb index 2a71fe811..35438eaaf 100644 --- a/app/controllers/workbenches_controller.rb +++ b/app/controllers/workbenches_controller.rb @@ -3,7 +3,10 @@ class WorkbenchesController < ChouetteController include RansackDateFilter before_action only: [:show] { set_date_time_params("validity_period", Date) } defaults resource_class: Workbench - respond_to :html, only: [:show, :index] + + include PolicyChecker + + respond_to :html, except: :destroy def index redirect_to dashboard_path @@ -24,7 +27,6 @@ class WorkbenchesController < ChouetteController current_workbench_id: params[:id] } ) - show! end def delete_referentials @@ -38,6 +40,11 @@ class WorkbenchesController < ChouetteController end private + + def workbench_params + params.require(:workbench).permit(:import_compliance_control_set_id, :merge_compliance_control_set_id) + end + def resource @workbench = current_organisation.workbenches.find params[:id] end diff --git a/app/helpers/compliance_control_sets_helper.rb b/app/helpers/compliance_control_sets_helper.rb index 448d5c008..0c63cb139 100644 --- a/app/helpers/compliance_control_sets_helper.rb +++ b/app/helpers/compliance_control_sets_helper.rb @@ -1,7 +1,7 @@ module ComplianceControlSetsHelper def organisations_filters_values - [current_organisation, Organisation.find_by_name("STIF")].uniq + [current_organisation, *Organisation.find_by_name("STIF")].uniq end def floating_links ccs_id diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb index 2068dd23c..d16858678 100644 --- a/app/helpers/table_builder_helper.rb +++ b/app/helpers/table_builder_helper.rb @@ -224,7 +224,7 @@ module TableBuilderHelper if column.linkable? path = column.link_to(item) - link = link_to(value, path) + link = value.present? && path.present? ? link_to(value, path) : "" if overhead.empty? bcont << content_tag(:td, link, title: 'Voir') diff --git a/app/helpers/table_builder_helper/column.rb b/app/helpers/table_builder_helper/column.rb index 05aa9f563..ff6f2f36f 100644 --- a/app/helpers/table_builder_helper/column.rb +++ b/app/helpers/table_builder_helper/column.rb @@ -2,19 +2,21 @@ module TableBuilderHelper class Column attr_reader :key, :name, :attribute, :sortable - def initialize(key: nil, name: '', attribute:, sortable: true, link_to: nil) + def initialize(key: nil, name: '', attribute:, sortable: true, link_to: nil, **opts) if key.nil? && name.empty? raise ColumnMustHaveKeyOrNameError end - + opts ||= {} @key = key @name = name @attribute = attribute @sortable = sortable @link_to = link_to + @condition = opts[:if] end def value(obj) + return unless check_condition(obj) if @attribute.is_a?(Proc) @attribute.call(obj) else @@ -36,8 +38,18 @@ module TableBuilderHelper end def link_to(obj) + return unless check_condition(obj) @link_to.call(obj) end + + def check_condition(obj) + condition_val = true + if @condition.present? + condition_val = @condition + condition_val = condition_val.call(obj) if condition_val.is_a?(Proc) + end + !!condition_val + end end diff --git a/app/javascript/helpers/routes_map.coffee b/app/javascript/helpers/routes_map.coffee index 6834406fc..42377cd6e 100644 --- a/app/javascript/helpers/routes_map.coffee +++ b/app/javascript/helpers/routes_map.coffee @@ -1,3 +1,65 @@ +RoutesLayersButton = (options) -> + menu = options.menu + + toggleMenu = (e)=> + $(menu.element).toggleClass 'hidden' + button.innerHTML = if button.innerHTML == "+" then "-" else "+" + + button = document.createElement("button") + button.innerHTML = "+" + button.addEventListener('click', toggleMenu, false) + button.addEventListener('touchstart', toggleMenu, false) + button.className = "ol-routes-layers-button" + + element = document.createElement('div'); + element.className = 'ol-control ol-routes-layers-button-wrapper'; + + element.appendChild(button) + + ol.control.Control.call(this, { + element + target: options.target + }) + +ol.inherits RoutesLayersButton, ol.control.Control + +RoutesLayersControl = (routes, routes_map) -> + + element = document.createElement('div') + element.className = 'ol-unselectable ol-routes-layers hidden' + Object.keys(routes).forEach (id)=> + route = routes[id] + route.active = true + label = document.createElement('a') + label.title = route.name + label.className = 'active' + label.innerHTML = route.name + element.appendChild label + label.addEventListener "click", => + route.active = !route.active + $(label).toggleClass "active" + route.active + route.vectorPtsLayer.setStyle routes_map.defaultStyles(route.active) + route.vectorEdgesLayer.setStyle routes_map.edgeStyles(route.active) + route.vectorLnsLayer.setStyle routes_map.lineStyle(route.active) + routes_map.fitZoom() + label.addEventListener "mouseenter", => + route.vectorPtsLayer.setStyle routes_map.defaultStyles(true) + route.vectorEdgesLayer.setStyle routes_map.edgeStyles(true) + route.vectorLnsLayer.setStyle routes_map.lineStyle(true) + + label.addEventListener "mouseleave", => + route.vectorPtsLayer.setStyle routes_map.defaultStyles(route.active) + route.vectorEdgesLayer.setStyle routes_map.edgeStyles(route.active) + route.vectorLnsLayer.setStyle routes_map.lineStyle(route.active) + + + ol.control.Control.call(this, { + element + }) + +ol.inherits RoutesLayersControl, ol.control.Control + class RoutesMap constructor: (@target)-> @initMap() @@ -20,6 +82,7 @@ class RoutesMap addRoute: (route)-> geoColPts = [] geoColLns = [] + route.active = true @routes[route.id] = route if route.id stops = route.stops || route geoColEdges = [ @@ -77,68 +140,49 @@ class RoutesMap @map.addLayer vectorEdgesLayer @map.addLayer vectorLnsLayer - lineStyle: (highlighted=false)-> + lineStyle: (active=true)-> new ol.style.Style stroke: new ol.style.Stroke - color: if highlighted then "#ed7f00" else '#007fbb' - width: 3 + color: '#007fbb' + width: if active then 3 else 0 - edgeStyles: (highlighted=false)-> + edgeStyles: (active=true)-> new ol.style.Style image: new ol.style.Circle radius: 5 stroke: new ol.style.Stroke - color: if highlighted then "#ed7f00" else '#007fbb' - width: 2 + color: '#007fbb' + width: if active then 3 else 0 fill: new ol.style.Fill - color: if highlighted then "#ed7f00" else '#007fbb' - width: 2 + color: '#007fbb' + width: if active then 3 else 0 - defaultStyles: (highlighted=false)-> + defaultStyles: (active=true)-> new ol.style.Style image: new ol.style.Circle radius: 4 stroke: new ol.style.Stroke - color: if highlighted then "#ed7f00" else '#007fbb' - width: 2 + color: '#007fbb' + width: if active then 3 else 0 fill: new ol.style.Fill color: '#ffffff' - width: 2 + width: if active then 3 else 0 addRoutesLabels: -> - labelsContainer = $("<ul class='routes-labels'></ul>") - labelsContainer.appendTo $("##{@target}") - @vectorPtsLayer = null - @vectorEdgesLayer = null - @vectorLnsLayer = null + menu = new RoutesLayersControl(@routes, this) + @map.addControl menu + @map.addControl new RoutesLayersButton(menu: menu) + + fitZoom: ()-> + area = [] + found = false Object.keys(@routes).forEach (id)=> route = @routes[id] - label = $("<li>#{route.name}</ul>") - label.appendTo labelsContainer - label.mouseleave => - route.vectorPtsLayer.setStyle @defaultStyles(false) - route.vectorEdgesLayer.setStyle @edgeStyles(false) - route.vectorLnsLayer.setStyle @lineStyle(false) - route.vectorPtsLayer.setZIndex 2 - route.vectorEdgesLayer.setZIndex 3 - route.vectorLnsLayer.setZIndex 1 - @fitZoom() - label.mouseenter => - route.vectorPtsLayer.setStyle @defaultStyles(true) - route.vectorEdgesLayer.setStyle @edgeStyles(true) - route.vectorLnsLayer.setStyle @lineStyle(true) - route.vectorPtsLayer.setZIndex 11 - route.vectorEdgesLayer.setZIndex 12 - route.vectorLnsLayer.setZIndex 10 - @fitZoom(route) - - fitZoom: (route)-> - if route - area = [] - route.stops.forEach (stop, i) => - area.push [parseFloat(stop.longitude), parseFloat(stop.latitude)] - else - area = @area + if route.active + found = true + route.stops.forEach (stop, i) => + area.push [parseFloat(stop.longitude), parseFloat(stop.latitude)] + area = @area unless found boundaries = ol.extent.applyTransform( ol.extent.boundingExtent(area), ol.proj.getTransform('EPSG:4326', 'EPSG:3857') ) diff --git a/app/javascript/packs/referential_lines/show.js b/app/javascript/packs/referential_lines/show.js index 542188018..99c5072ef 100644 --- a/app/javascript/packs/referential_lines/show.js +++ b/app/javascript/packs/referential_lines/show.js @@ -6,5 +6,5 @@ routes = JSON.parse(decodeURIComponent(routes)) var map = new RoutesMap('routes_map') map.addRoutes(routes) -// map.addRoutesLabels() +map.addRoutesLabels() map.fitZoom() diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js index e67753e4b..5fb88f024 100644 --- a/app/javascript/vehicle_journeys/actions/index.js +++ b/app/javascript/vehicle_journeys/actions/index.js @@ -203,11 +203,10 @@ const actions = { let field = fields[key] if(field.validity && !field.validity.valid){ valid = false - $(field).parent().addClass('has-error').children('.help-block').remove() + $(field).parent().parent().addClass('has-error').children('.help-block').remove() $(field).parent().append("<span class='small help-block'>" + field.validationMessage + "</span>") } }) - return valid }, toggleArrivals : () => ({ diff --git a/app/javascript/vehicle_journeys/components/VehicleJourney.js b/app/javascript/vehicle_journeys/components/VehicleJourney.js index 7db0cee1c..d605614c7 100644 --- a/app/javascript/vehicle_journeys/components/VehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/VehicleJourney.js @@ -48,6 +48,14 @@ export default class VehicleJourney extends Component { } } + displayDelta(delta) { + if(delta > 99){ + return "+" + } + return delta + } + + hasTimeTable(time_tables, tt) { let found = false time_tables.map((t, index) => { @@ -150,7 +158,7 @@ export default class VehicleJourney extends Component { } <div className={(this.columnHasDelta() ? '' : 'hidden')}> {(vj.delta != 0) && - <span className='sb sb-chrono sb-lg text-warning' data-textinside={vj.delta}></span> + <span className='sb sb-chrono sb-lg text-warning' data-textinside={this.displayDelta(vj.delta)}></span> } </div> <div data-headline={I18n.t("vehicle_journeys.form.departure_at")}> diff --git a/app/javascript/vehicle_journeys/components/tools/CreateModal.js b/app/javascript/vehicle_journeys/components/tools/CreateModal.js index 24d9a23c2..a60429765 100644 --- a/app/javascript/vehicle_journeys/components/tools/CreateModal.js +++ b/app/javascript/vehicle_journeys/components/tools/CreateModal.js @@ -12,7 +12,13 @@ export default class CreateModal extends Component { } handleSubmit() { - if (actions.validateFields(...this.refs, $('.vjCreateSelectJP')[0]) && this.props.modal.modalProps.selectedJPModal) { + if(!this.props.modal.modalProps.selectedJPModal){ + let field = $('#NewVehicleJourneyModal').find(".vjCreateSelectJP") + field.parent().parent().addClass('has-error').children('.help-block').remove() + field.parent().append("<span class='small help-block'>" + I18n.t("simple_form.required.text") + "</span>") + return + } + if (actions.validateFields(...this.refs, $('.vjCreateSelectJP')[0])) { this.props.onAddVehicleJourney(_.assign({}, this.refs, {custom_fields: this.custom_fields}), this.props.modal.modalProps.selectedJPModal, this.props.stopPointsList, this.props.modal.modalProps.vehicleJourney && this.props.modal.modalProps.vehicleJourney.company) this.props.onModalClose() $('#NewVehicleJourneyModal').modal('hide') diff --git a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js index 8705b3cf2..e7f68761e 100644 --- a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js +++ b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js @@ -90,6 +90,11 @@ const vehicleJourney= (state = {}, action, keep) => { } }) + let lastStop = action.selectedJourneyPattern.stop_areas && action.selectedJourneyPattern.stop_areas[action.selectedJourneyPattern.stop_areas.length - 1] + if(lastStop && lastStop.stop_area_short_description.id == sp.id){ + newVjas.departure_time = newVjas.arrival_time + } + if(newVjas.dummy){ newVjas.departure_time = {hour: "00", minute: "00"} newVjas.arrival_time = {hour: "00", minute: "00"} diff --git a/app/models/chouette/access_link.rb b/app/models/chouette/access_link.rb index 4b99ab5ba..6b08443be 100644 --- a/app/models/chouette/access_link.rb +++ b/app/models/chouette/access_link.rb @@ -2,8 +2,6 @@ module Chouette class AccessLink < Chouette::TridentActiveRecord has_paper_trail include ObjectidSupport - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" attr_accessor :access_link_type, :link_orientation_type, :link_key diff --git a/app/models/chouette/access_point.rb b/app/models/chouette/access_point.rb index b6f78f239..ac6580015 100644 --- a/app/models/chouette/access_point.rb +++ b/app/models/chouette/access_point.rb @@ -5,8 +5,6 @@ require 'geo_ruby' module Chouette class AccessPoint < Chouette::ActiveRecord has_paper_trail - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" include Geokit::Mappable include ProjectionFields diff --git a/app/models/chouette/connection_link.rb b/app/models/chouette/connection_link.rb index d5ddc606a..c53d6f5f1 100644 --- a/app/models/chouette/connection_link.rb +++ b/app/models/chouette/connection_link.rb @@ -3,8 +3,6 @@ module Chouette has_paper_trail include ObjectidSupport include ConnectionLinkRestrictions - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" attr_accessor :connection_link_type diff --git a/app/models/chouette/group_of_line.rb b/app/models/chouette/group_of_line.rb index 75ee1ce73..3b6a7cea7 100644 --- a/app/models/chouette/group_of_line.rb +++ b/app/models/chouette/group_of_line.rb @@ -5,8 +5,6 @@ module Chouette include GroupOfLineRestrictions include LineReferentialSupport - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" has_and_belongs_to_many :lines, :class_name => 'Chouette::Line', :order => 'lines.name' diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb index 10c8b5439..ff85f376a 100644 --- a/app/models/chouette/journey_pattern.rb +++ b/app/models/chouette/journey_pattern.rb @@ -4,8 +4,6 @@ module Chouette include ChecksumSupport include JourneyPatternRestrictions include ObjectidSupport - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" belongs_to :route has_many :vehicle_journeys, :dependent => :destroy diff --git a/app/models/chouette/line.rb b/app/models/chouette/line.rb index d077d5c9d..b3c4f2463 100644 --- a/app/models/chouette/line.rb +++ b/app/models/chouette/line.rb @@ -8,8 +8,6 @@ module Chouette include StifTransportSubmodeEnumerations extend ActiveModel::Naming - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" belongs_to :company belongs_to :network diff --git a/app/models/chouette/network.rb b/app/models/chouette/network.rb index 6843c69ad..942fc5d67 100644 --- a/app/models/chouette/network.rb +++ b/app/models/chouette/network.rb @@ -5,8 +5,6 @@ module Chouette include LineReferentialSupport include ObjectidSupport extend Enumerize - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" has_many :lines attr_accessor :source_type_name diff --git a/app/models/chouette/pt_link.rb b/app/models/chouette/pt_link.rb index d14d5f29c..399539d44 100644 --- a/app/models/chouette/pt_link.rb +++ b/app/models/chouette/pt_link.rb @@ -3,8 +3,6 @@ require 'geokit' module Chouette class PtLink < Chouette::ActiveRecord has_paper_trail - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" include Geokit::Mappable def geometry diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 3729deb7d..26b80733d 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -12,8 +12,6 @@ module Chouette enumerize :direction, in: %i(straight_forward backward clockwise counter_clockwise north north_west west south_west south south_east east north_east) enumerize :wayback, in: %i(outbound inbound), default: :outbound - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" def self.nullable_attributes [:published_name, :comment, :number, :name, :direction, :wayback] diff --git a/app/models/chouette/stop_point.rb b/app/models/chouette/stop_point.rb index 3b9eaa2f6..6b363cd93 100644 --- a/app/models/chouette/stop_point.rb +++ b/app/models/chouette/stop_point.rb @@ -9,8 +9,6 @@ module Chouette include ForAlightingEnumerations include ObjectidSupport - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" belongs_to :stop_area belongs_to :route, inverse_of: :stop_points diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb index 20d6e69ac..506e498b8 100644 --- a/app/models/chouette/time_table.rb +++ b/app/models/chouette/time_table.rb @@ -7,8 +7,6 @@ module Chouette include ApplicationDaysSupport include TimetableSupport - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" acts_as_taggable attr_accessor :tag_search diff --git a/app/models/chouette/time_table_date.rb b/app/models/chouette/time_table_date.rb index 98d8fa765..6a68d7fe1 100644 --- a/app/models/chouette/time_table_date.rb +++ b/app/models/chouette/time_table_date.rb @@ -2,7 +2,6 @@ module Chouette class TimeTableDate < Chouette::ActiveRecord include ChecksumSupport - self.primary_key = "id" belongs_to :time_table, inverse_of: :dates acts_as_list :scope => 'time_table_id = #{time_table_id}',:top_of_list => 0 diff --git a/app/models/chouette/time_table_period.rb b/app/models/chouette/time_table_period.rb index d9b707675..6965d828a 100644 --- a/app/models/chouette/time_table_period.rb +++ b/app/models/chouette/time_table_period.rb @@ -2,7 +2,6 @@ module Chouette class TimeTablePeriod < Chouette::ActiveRecord include ChecksumSupport - self.primary_key = "id" belongs_to :time_table, inverse_of: :periods acts_as_list :scope => 'time_table_id = #{time_table_id}',:top_of_list => 0 diff --git a/app/models/chouette/timeband.rb b/app/models/chouette/timeband.rb index 6155ffc77..5a4e17b98 100644 --- a/app/models/chouette/timeband.rb +++ b/app/models/chouette/timeband.rb @@ -10,7 +10,6 @@ module Chouette class Timeband < Chouette::TridentActiveRecord include ObjectidSupport has_paper_trail - self.primary_key = "id" validates :start_time, :end_time, presence: true validates_with Chouette::TimebandValidator diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb index 194dc85ff..60279422c 100644 --- a/app/models/chouette/vehicle_journey.rb +++ b/app/models/chouette/vehicle_journey.rb @@ -3,11 +3,10 @@ module Chouette class VehicleJourney < Chouette::TridentActiveRecord has_paper_trail include ChecksumSupport + include CustomFieldsSupport include VehicleJourneyRestrictions include ObjectidSupport include StifTransportModeEnumerations - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" enum journey_category: { timed: 0, frequency: 1 } @@ -347,21 +346,6 @@ module Chouette end end - def self.custom_fields - CustomField.where(resource_type: self.name.split("::").last) - end - - - def custom_fields - Hash[*self.class.custom_fields.map do |v| - [v.code, v.slice(:code, :name, :field_type, :options).update(value: custom_field_value(v.code))] - end.flatten] - end - - def custom_field_value key - (custom_field_values || {})[key.to_s] - end - def self.matrix(vehicle_journeys) Hash[*VehicleJourneyAtStop.where(vehicle_journey_id: vehicle_journeys.pluck(:id)).map do |vjas| [ "#{vjas.vehicle_journey_id}-#{vjas.stop_point_id}", vjas] diff --git a/app/models/chouette/vehicle_journey_at_stop.rb b/app/models/chouette/vehicle_journey_at_stop.rb index 3b4f35f13..d875442ee 100644 --- a/app/models/chouette/vehicle_journey_at_stop.rb +++ b/app/models/chouette/vehicle_journey_at_stop.rb @@ -6,8 +6,6 @@ module Chouette DAY_OFFSET_MAX = 1 - # FIXME http://jira.codehaus.org/browse/JRUBY-6358 - self.primary_key = "id" belongs_to :stop_point belongs_to :vehicle_journey diff --git a/app/models/compliance_check_message_export.rb b/app/models/compliance_check_message_export.rb index 04e1a9caa..bbaaa8e3f 100644 --- a/app/models/compliance_check_message_export.rb +++ b/app/models/compliance_check_message_export.rb @@ -26,12 +26,14 @@ class ComplianceCheckMessageExport end def to_csv(options = {}) - CSV.generate(options.slice(:col_sep, :quote_char, :force_quotes)) do |csv| + csv_string = CSV.generate(options.slice(:col_sep, :quote_char, :force_quotes)) do |csv| csv << column_names compliance_check_messages.each do |compliance_check_message| csv << [compliance_check_message.compliance_check.criticity, *compliance_check_message.message_attributes.values_at('test_id', 'source_objectid'), options[:server_url] + compliance_check_message.message_attributes['source_object_path'], I18n.t("compliance_check_messages.#{compliance_check_message.message_key}", compliance_check_message.message_attributes.deep_symbolize_keys)] end end + # We add a BOM to indicate we use UTF-8 + "\uFEFF" + csv_string end def to_zip(temp_file,options = {}) diff --git a/app/models/concerns/custom_fields_support.rb b/app/models/concerns/custom_fields_support.rb new file mode 100644 index 000000000..6c76bd653 --- /dev/null +++ b/app/models/concerns/custom_fields_support.rb @@ -0,0 +1,24 @@ +module CustomFieldsSupport + extend ActiveSupport::Concern + + included do + validate :custom_fields_values_are_valid + + def self.custom_fields + CustomField.where(resource_type: self.name.split("::").last) + end + + def custom_fields + CustomField::Collection.new self + end + + def custom_field_value key + (custom_field_values || {})[key.to_s] + end + + private + def custom_fields_values_are_valid + custom_fields.values.all?{|cf| cf.valid?} + end + end +end diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb index 774c8b0f6..4a840744e 100644 --- a/app/models/custom_field.rb +++ b/app/models/custom_field.rb @@ -6,4 +6,80 @@ class CustomField < ActiveRecord::Base validates :name, uniqueness: {scope: [:resource_type, :workgroup_id]} validates :code, uniqueness: {scope: [:resource_type, :workgroup_id], case_sensitive: false} + + class Collection < HashWithIndifferentAccess + def initialize object + vals = object.class.custom_fields.map do |v| + [v.code, CustomField::Value.new(object, v, object.custom_field_value(v.code))] + end + super Hash[*vals.flatten] + end + + def to_hash + HashWithIndifferentAccess[*self.map{|k, v| [k, v.to_hash]}.flatten(1)] + end + end + + class Value + def self.new owner, custom_field, value + field_type = custom_field.options["field_type"] + klass_name = field_type && "CustomField::Value::#{field_type.classify}" + klass = klass_name && const_defined?(klass_name) ? klass_name.constantize : CustomField::Value::Base + klass.new owner, custom_field, value + end + + class Base + def initialize owner, custom_field, value + @custom_field = custom_field + @raw_value = value + @owner = owner + @errors = [] + @validated = false + @valid = false + end + + delegate :code, :name, :field_type, :options, to: :@custom_field + + def validate + @valid = true + end + + def valid? + validate unless @validated + @valid + end + + def value + @raw_value + end + + def errors_key + "custom_fields.#{code}" + end + + def to_hash + HashWithIndifferentAccess[*%w(code name field_type options value).map{|k| [k, send(k)]}.flatten(1)] + end + end + + class Integer < Base + def value + @raw_value.to_i + end + + def validate + @valid = true + unless @raw_value =~ /\A\d*\Z/ + @owner.errors.add errors_key, "'#{@raw_value}' is not a valid integer" + @valid = false + end + end + end + + class String < Base + def value + "#{@raw_value}" + end + end + end end diff --git a/app/models/dashboard.rb b/app/models/dashboard.rb index 46c621266..e0857dca3 100644 --- a/app/models/dashboard.rb +++ b/app/models/dashboard.rb @@ -27,4 +27,5 @@ class Dashboard def current_organisation context.send(:current_organisation) end + end diff --git a/app/models/import_message_export.rb b/app/models/import_message_export.rb index 05f8a2cc7..991eb0f61 100644 --- a/app/models/import_message_export.rb +++ b/app/models/import_message_export.rb @@ -26,12 +26,14 @@ class ImportMessageExport end def to_csv(options = {}) - CSV.generate(options) do |csv| + csv_string = CSV.generate(options) do |csv| csv << column_names import_messages.each do |import_message| csv << [import_message.criticity, import_message.message_key, I18n.t("import_messages.#{import_message.message_key}", import_message.message_attributes.deep_symbolize_keys), *import_message.resource_attributes.values_at("filename", "line_number", "column_number") ] end end + # We add a BOM to indicate we use UTF-8 + "\uFEFF" + csv_string end def to_zip(temp_file,options = {}) diff --git a/app/models/organisation.rb b/app/models/organisation.rb index e8fb4e060..745bc0d22 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -13,6 +13,8 @@ class Organisation < ActiveRecord::Base has_many :line_referentials, through: :line_referential_memberships has_many :workbenches + has_many :workgroups, through: :workbenches + has_many :calendars has_many :api_keys, class_name: 'Api::V1::ApiKey' diff --git a/app/models/workbench.rb b/app/models/workbench.rb index eb53af7aa..b6f90c7dc 100644 --- a/app/models/workbench.rb +++ b/app/models/workbench.rb @@ -42,6 +42,10 @@ class Workbench < ActiveRecord::Base end end + def calendars + workgroup.calendars.where('(organisation_id = ? OR shared = ?)', organisation.id, true) + end + def self.default self.last if self.count == 1 where(name: DEFAULT_WORKBENCH_NAME).last diff --git a/app/policies/workbench_policy.rb b/app/policies/workbench_policy.rb new file mode 100644 index 000000000..7b925e91a --- /dev/null +++ b/app/policies/workbench_policy.rb @@ -0,0 +1,11 @@ +class WorkbenchPolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope + end + end + + def update? + true + end +end diff --git a/app/services/referential_overview.rb b/app/services/referential_overview.rb index ccfe0617a..7ef2909ad 100644 --- a/app/services/referential_overview.rb +++ b/app/services/referential_overview.rb @@ -208,7 +208,11 @@ class ReferentialOverview end def span - h.l(@start_date, format: "#{@start_date.day}-#{@end_date.day} %b") + if @start_date.month == @end_date.month + h.l(@start_date, format: "#{@start_date.day}-#{@end_date.day} %b %Y") + else + "#{h.l(@start_date, format: "%d %b")} - #{h.l(@end_date, format: "%d %b %Y")}" + end end def number diff --git a/app/views/calendars/_form_advanced.html.slim b/app/views/calendars/_form_advanced.html.slim index e796e2e36..aa4fd4e40 100644 --- a/app/views/calendars/_form_advanced.html.slim +++ b/app/views/calendars/_form_advanced.html.slim @@ -3,6 +3,6 @@ = javascript_tag do | window.actionType = "#{raw params[:action]}"; // | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe}; - | window.timetablesUrl = "#{calendar_url(@calendar).html_safe}"; + | window.timetablesUrl = "#{workgroup_calendar_url(@workgroup, @calendar).html_safe}"; = javascript_pack_tag 'calendars/edit.js' diff --git a/app/views/compliance_check_sets/index.html.slim b/app/views/compliance_check_sets/index.html.slim index 31ad31e5b..9abd95dd1 100644 --- a/app/views/compliance_check_sets/index.html.slim +++ b/app/views/compliance_check_sets/index.html.slim @@ -23,9 +23,10 @@ ), \ TableBuilderHelper::Column.new( \ key: :associated_object, \ - attribute: Proc.new{|n| n.referential.present? ? n.referential.name : ''}, \ + if: ->(compliance_check_set){ compliance_check_set.referential.present? }, \ + attribute: Proc.new{|n| n.referential.name}, \ link_to: lambda do |compliance_check_set| \ - compliance_check_set.referential.present? ? referential_path(compliance_check_set.referential_id) : '#' \ + referential_path(compliance_check_set.referential_id) \ end \ ), \ TableBuilderHelper::Column.new( \ @@ -42,6 +43,8 @@ ], sortable: true, cls: 'table has-filter has-search' + + = new_pagination @compliance_check_sets, 'pull-right' - unless @compliance_check_sets.any? .row.mt-xs .col-lg-12 diff --git a/app/views/dashboards/_dashboard.html.slim b/app/views/dashboards/_dashboard.html.slim index 7f78934a6..f93b85cad 100644 --- a/app/views/dashboards/_dashboard.html.slim +++ b/app/views/dashboards/_dashboard.html.slim @@ -22,12 +22,12 @@ .panel.panel-default .panel-heading h3.panel-title.with_actions - = link_to I18n.t("activerecord.models.calendar", count: @dashboard.current_organisation.calendars.size), workgroup_calendars_path(workbench.workgroup) + = link_to I18n.t("activerecord.models.calendar", count: workbench.calendars.size), workgroup_calendars_path(workbench.workgroup) div = link_to '', workgroup_calendars_path(workbench.workgroup), class: ' fa fa-chevron-right pull-right' - - if @dashboard.current_organisation.calendars.present? + - if workbench.calendars.present? .list-group - - @dashboard.current_organisation.calendars.order("updated_at desc").limit(5).each do |calendar| + - workbench.calendars.order("updated_at desc").limit(5).each do |calendar| = link_to calendar.name, workgroup_calendars_path(workbench.workgroup, calendar), class: 'list-group-item' - else .panel-body diff --git a/app/views/lines/show.html.slim b/app/views/lines/show.html.slim index 34b907bdd..96bb5bb0d 100644 --- a/app/views/lines/show.html.slim +++ b/app/views/lines/show.html.slim @@ -6,13 +6,13 @@ .row .col-lg-6.col-md-6.col-sm-12.col-xs-12 = definition_list t('metadatas'), - { 'ID Codif' => @line.get_objectid.short_id, - 'Activé' => (@line.deactivated? ? t('false') : t('true')), + { t('id_codif') => @line.get_objectid.short_id, + @line.human_attribute_name(:deactivated) => (@line.deactivated? ? t('false') : t('true')), @line.human_attribute_name(:network_id) => (@line.network.nil? ? t('lines.index.unset') : @line.network.name), @line.human_attribute_name(:company_id) => (@line.company.nil? ? t('lines.index.unset') : @line.company.name), - 'Transporteur(s) secondaire(s)' => (@line.secondary_companies.nil? ? t('lines.index.unset') : array_to_html_list(@line.secondary_companies.collect(&:name))), - 'Nom court' => @line.number, - 'Code public' => (@line.registration_number ? @line.registration_number : '-'), + @line.human_attribute_name(:secondary_companies) => (@line.secondary_companies.nil? ? t('lines.index.unset') : array_to_html_list(@line.secondary_companies.collect(&:name))), + @line.human_attribute_name(:number) => @line.number, + @line.human_attribute_name(:registration_number) => (@line.registration_number ? @line.registration_number : '-'), @line.human_attribute_name(:transport_mode) => (@line.transport_mode.present? ? t("enumerize.transport_mode.#{@line.transport_mode}") : '-'), @line.human_attribute_name(:transport_submode) => (@line.transport_submode.present? ? t("enumerize.transport_submode.#{@line.transport_submode}") : '-'), @line.human_attribute_name(:url) => (@line.url ? @line.url : '-'), diff --git a/app/views/referential_lines/show.html.slim b/app/views/referential_lines/show.html.slim index 5ea0e31bb..ef32ef6b0 100644 --- a/app/views/referential_lines/show.html.slim +++ b/app/views/referential_lines/show.html.slim @@ -82,6 +82,6 @@ = replacement_msg t('routes.search_no_results') = javascript_tag do - | window.routes = "#{URI.escape(@routes.map{|r| {name: r.name, id: r.id, stops: route_json_for_edit(r, serialize: false)}}.to_json)}" + | window.routes = "#{URI.escape(@routes.select{|r| r.wayback == :outbound}.map{|r| {name: r.name, id: r.id, stops: route_json_for_edit(r, serialize: false)}}.to_json)}" = javascript_pack_tag 'referential_lines/show.js' diff --git a/app/views/referentials/_form.html.slim b/app/views/referentials/_form.html.slim index 1e59ab566..96d847ec1 100644 --- a/app/views/referentials/_form.html.slim +++ b/app/views/referentials/_form.html.slim @@ -47,8 +47,13 @@ = link_to_add_association t('simple_form.labels.referential.actions.add_period'), subform, :periods, class: 'btn btn-outline-primary' .separator + .row + .col-lg-11 + = subform.input :lines, as: :select, collection: Chouette::Line.includes(:company).order(:name).where(objectid: current_functional_scope), selected: subform.object.line_ids, label_method: :display_name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': t('simple_form.labels.referential.placeholders.select_lines'), 'multiple': 'multiple', style: 'width: 100%' } + .col-lg-1 + a.clear-lines.btn.btn-default href='#' + .fa.fa-trash - = subform.input :lines, as: :select, collection: Chouette::Line.includes(:company).order(:name).where(objectid: current_functional_scope), selected: subform.object.line_ids, label_method: :display_name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': t('simple_form.labels.referential.placeholders.select_lines'), 'multiple': 'multiple', style: 'width: 100%' } .hidden = form.input :workbench_id, as: :hidden @@ -58,3 +63,10 @@ class: 'btn btn-default formSubmitr', data: { disable_with: t('actions.processing') }, form: 'referential_form' + + - content_for :javascript do + coffee: + $(".clear-lines").click (e)-> + e.preventDefault() + $(e.currentTarget).parents('.row').first().find('[name*=line]').val('').trigger('change') + false diff --git a/app/views/referentials/_overview.html.slim b/app/views/referentials/_overview.html.slim index 870f642d4..6bed5f282 100644 --- a/app/views/referentials/_overview.html.slim +++ b/app/views/referentials/_overview.html.slim @@ -35,9 +35,12 @@ .lines= I18n.t("referentials.overview.head.lines") .lines - overview.lines.each do |line| - .line - a.number style="background-color: #{line.color.present? ? "##{line.color}" : 'whitesmoke'}" title=line.name - = line.number + a.line title=line.name + - if line.number.present? + .number style="background-color: #{line.color.present? ? "##{line.color}" : 'whitesmoke'}" + = line.number + - else + .name= line.name .company= line.company&.name .mode= line.transport_mode.present? ? t("enumerize.transport_mode.#{line.transport_mode}") : "" .right diff --git a/app/views/stif/dashboards/_dashboard.html.slim b/app/views/stif/dashboards/_dashboard.html.slim index 83a2106bb..e0f754fd4 100644 --- a/app/views/stif/dashboards/_dashboard.html.slim +++ b/app/views/stif/dashboards/_dashboard.html.slim @@ -57,7 +57,7 @@ .panel-heading h3.panel-title.with_actions = I18n.t("calendars.index.title") - span.badge.ml-xs = @dashboard.calendars.count if @dashboard.calendars.present? + span.badge.ml-xs = @dashboard.workbench.calendars.count if @dashboard.calendars.present? div = link_to '', workgroup_calendars_path(@dashboard.workbench.workgroup), class: ' fa fa-chevron-right pull-right', title: t('.see') diff --git a/app/views/stop_areas/show.html.slim b/app/views/stop_areas/show.html.slim index a4e14a272..34b872e91 100644 --- a/app/views/stop_areas/show.html.slim +++ b/app/views/stop_areas/show.html.slim @@ -20,7 +20,7 @@ @stop_area.human_attribute_name(:zip_code) => @stop_area.zip_code, @stop_area.human_attribute_name(:city_name) => @stop_area.city_name, @stop_area.human_attribute_name(:country_code) => @stop_area.country_code.presence || '-', - 'Etat' => (@stop_area.deleted_at ? 'Supprimé' : 'Actif'), + t('activerecord.attributes.stop_area.state') => (@stop_area.deleted_at ? t('stop_areas.show.state.deactivated') : t('stop_areas.show.state.active')), @stop_area.human_attribute_name(:comment) => @stop_area.try(:comment), }) = definition_list t('metadatas'), attributes diff --git a/app/views/workbenches/_form.html.slim b/app/views/workbenches/_form.html.slim new file mode 100644 index 000000000..534a5f378 --- /dev/null +++ b/app/views/workbenches/_form.html.slim @@ -0,0 +1,9 @@ += simple_form_for @workbench, html: { class: 'form-horizontal', id: 'workbench_form' }, wrapper: :horizontal_form do |f| + .row + .col-lg-12 + = f.input :import_compliance_control_set_id, as: :select, collection: current_organisation.compliance_control_sets, value_method: :id + = f.input :merge_compliance_control_set_id, as: :select, collection: current_organisation.compliance_control_sets, value_method: :id + + .separator + + = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'workbench_form' diff --git a/app/views/workbenches/edit.html.slim b/app/views/workbenches/edit.html.slim new file mode 100644 index 000000000..893024490 --- /dev/null +++ b/app/views/workbenches/edit.html.slim @@ -0,0 +1,8 @@ +- breadcrumb @workbench +- page_header_content_for @workbench + +.page_content + .container-fluid + .row + .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1 + == render 'form' diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim index 159aa8ea2..5c2468296 100644 --- a/app/views/workbenches/show.html.slim +++ b/app/views/workbenches/show.html.slim @@ -3,6 +3,8 @@ - content_for :page_header_content do .row.mb-sm .col-lg-12.text-right + - if policy(Workbench).update? + = link_to t('workbenches.actions.configure'), edit_workbench_path(@workbench), class: 'btn btn-primary' - if policy(Referential).create? = link_to t('actions.import'), workbench_imports_path(@workbench), class: 'btn btn-primary' = link_to t('actions.add'), new_workbench_referential_path(@workbench), class: 'btn btn-primary' diff --git a/config/locales/stop_areas.en.yml b/config/locales/stop_areas.en.yml index c1ced1094..ac3dce280 100644 --- a/config/locales/stop_areas.en.yml +++ b/config/locales/stop_areas.en.yml @@ -66,6 +66,9 @@ en: access_managment: "Access Points and Links managment" access_points: "Access Points" not_editable: "Le type d'arrêt est non modifiable" + state: + active: Active + deactivated: Deactivated genealogical: genealogical: "Links between stop area" genealogical_routing: "Routing constraint's links" @@ -139,6 +142,7 @@ en: created_at: Created at updated_at: Updated at waiting_time: Waiting time (minutes) + state: State formtastic: titles: stop_area: diff --git a/config/locales/stop_areas.fr.yml b/config/locales/stop_areas.fr.yml index ede1aada6..f75c4ebe7 100644 --- a/config/locales/stop_areas.fr.yml +++ b/config/locales/stop_areas.fr.yml @@ -67,6 +67,9 @@ fr: access_managment: "Gestion des accès et liens associés" access_points: "Points d'accès" not_editable: "Le type d'arrêt est non modifiable" + state: + active: Actif + deactivated: Désactivé genealogical: genealogical: "Lien entre arrêts" genealogical_routing: "Liens de l'ITL" @@ -141,6 +144,7 @@ fr: created_at: "Créé le" updated_at: "Edité le" waiting_time: Temps de desserte (minutes) + state: État formtastic: titles: stop_area: diff --git a/config/locales/workbenches.en.yml b/config/locales/workbenches.en.yml index 7f21f47a0..2d9b27045 100644 --- a/config/locales/workbenches.en.yml +++ b/config/locales/workbenches.en.yml @@ -2,6 +2,14 @@ en: workbenches: show: title: "%{name}" + edit: + title: "Configure the workbench" + update: + title: "Configure the workbench" + referential_count: + zero: "There are no referentials in your workbench" + one: "There is one referential in your workbench" + other: "There are #{count} referentials in your workbench" index: title: "%{organisation} dashboard" offers: @@ -12,10 +20,9 @@ en: calendars: "Calendars" see: "See the list" no_content: "No content yet." - referential_count: - zero: "There is no referential in your workbench" - one: "There is one referential in your workbench" - other: "There are #{count} referentials in your workbench" + actions: + show_output: "Merge offer" + affect_ccset: "Configure" activerecord: models: workbench: diff --git a/config/locales/workbenches.fr.yml b/config/locales/workbenches.fr.yml index e7a392e66..8eee1a516 100644 --- a/config/locales/workbenches.fr.yml +++ b/config/locales/workbenches.fr.yml @@ -2,12 +2,27 @@ fr: workbenches: show: title: "%{name}" + edit: + title: "Configurer l'espace de travail" + update: + title: "Configurer l'espace de travail" referential_count: zero: "Aucun jeu de données dans cet espace de travail" one: "1 jeu de données dans cet espace de travail" other: "#{count} jeux de données dans cet espace de travail" + index: + title: "%{organisation} dashboard" + offers: + title: "Offre de transport" + organisation: "Offres de mon Organisation" + idf: "Offres IDF" + referentials: "Jeux de données" + calendars: "Calendriers" + see: "Voir la liste" + no_content: "Aucun contenu" actions: show_output: "Finaliser l'Offre" + configure: "Configurer" activerecord: models: workbench: diff --git a/config/routes.rb b/config/routes.rb index 456cb66f5..a3a21511c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,7 +3,7 @@ require 'sidekiq/web' ChouetteIhm::Application.routes.draw do resource :dashboard - resources :workbenches, only: [:show, :index] do + resources :workbenches, except: [:destroy] do delete :referentials, on: :member, action: :delete_referentials resources :imports do get :download, on: :member @@ -174,7 +174,7 @@ ChouetteIhm::Application.routes.draw do namespace :api do namespace :v1 do - resources :workbenches, only: [:index, :show] do + resources :workbenches, except: [:destroy] do resources :imports, only: [:index, :show, :create] end resources :access_links, only: [:index, :show] diff --git a/db/migrate/20180208174834_add_attributes_to_workbench.rb b/db/migrate/20180208174834_add_attributes_to_workbench.rb new file mode 100644 index 000000000..02002a772 --- /dev/null +++ b/db/migrate/20180208174834_add_attributes_to_workbench.rb @@ -0,0 +1,9 @@ +class AddAttributesToWorkbench < ActiveRecord::Migration + def change + add_column :workbenches, :import_compliance_control_set_id, :integer, limit: 8 + add_column :workbenches, :merge_compliance_control_set_id, :integer, limit: 8 + + add_index :workbenches, :import_compliance_control_set_id + add_index :workbenches, :merge_compliance_control_set_id + end +end diff --git a/db/schema.rb b/db/schema.rb index d6f3cdbe0..27e38e1b7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -421,9 +421,9 @@ ActiveRecord::Schema.define(version: 20180301142531) do t.string "type" t.integer "parent_id", limit: 8 t.string "parent_type" - t.datetime "notified_parent_at" t.integer "current_step", default: 0 t.integer "total_steps", default: 0 + t.datetime "notified_parent_at" t.string "creator" end @@ -1008,17 +1008,21 @@ ActiveRecord::Schema.define(version: 20180301142531) do create_table "workbenches", id: :bigserial, force: :cascade do |t| t.string "name" - t.integer "organisation_id", limit: 8 + t.integer "organisation_id", limit: 8 t.datetime "created_at" t.datetime "updated_at" - t.integer "line_referential_id", limit: 8 - t.integer "stop_area_referential_id", limit: 8 - t.integer "output_id", limit: 8 + t.integer "line_referential_id", limit: 8 + t.integer "stop_area_referential_id", limit: 8 + t.integer "output_id", limit: 8 t.string "objectid_format" - t.integer "workgroup_id", limit: 8 + t.integer "workgroup_id", limit: 8 + t.integer "import_compliance_control_set_id", limit: 8 + t.integer "merge_compliance_control_set_id", limit: 8 end + add_index "workbenches", ["import_compliance_control_set_id"], name: "index_workbenches_on_import_compliance_control_set_id", using: :btree add_index "workbenches", ["line_referential_id"], name: "index_workbenches_on_line_referential_id", using: :btree + add_index "workbenches", ["merge_compliance_control_set_id"], name: "index_workbenches_on_merge_compliance_control_set_id", using: :btree add_index "workbenches", ["organisation_id"], name: "index_workbenches_on_organisation_id", using: :btree add_index "workbenches", ["stop_area_referential_id"], name: "index_workbenches_on_stop_area_referential_id", using: :btree add_index "workbenches", ["workgroup_id"], name: "index_workbenches_on_workgroup_id", using: :btree diff --git a/lib/stif/dashboard.rb b/lib/stif/dashboard.rb index 46c635091..f558b79fb 100644 --- a/lib/stif/dashboard.rb +++ b/lib/stif/dashboard.rb @@ -1,7 +1,7 @@ module Stif class Dashboard < ::Dashboard def workbench - @workbench ||= current_organisation.workbenches.find_by(name: "Gestion de l'offre") + @workbench ||= current_organisation.workbenches.default end def workgroup @@ -13,7 +13,7 @@ module Stif end def calendars - @calendars ||= Calendar.where('(organisation_id = ? OR shared = ?) AND workgroup_id = ?', current_organisation.id, true, workgroup.id) + workbench.calendars end end end diff --git a/spec/controllers/line_referentials_controller_spec.rb b/spec/controllers/line_referentials_controller_spec.rb index 17ffb670d..8e8d48fda 100644 --- a/spec/controllers/line_referentials_controller_spec.rb +++ b/spec/controllers/line_referentials_controller_spec.rb @@ -6,8 +6,8 @@ RSpec.describe LineReferentialsController, :type => :controller do describe 'PUT sync' do let(:request){ put :sync, id: line_referential.id } - it 'should redirect to 403' do - expect(request).to redirect_to "/403" + it 'should respond with 403' do + expect(request).to have_http_status 403 end with_permission "line_referentials.synchronize" do diff --git a/spec/controllers/lines_controller_spec.rb b/spec/controllers/lines_controller_spec.rb index 65fe88b96..96f49bb36 100644 --- a/spec/controllers/lines_controller_spec.rb +++ b/spec/controllers/lines_controller_spec.rb @@ -7,8 +7,8 @@ RSpec.describe LinesController, :type => :controller do describe 'PUT deactivate' do let(:request){ put :deactivate, id: line.id, line_referential_id: line_referential.id } - it 'should redirect to 403' do - expect(request).to redirect_to "/403" + it 'should respond with 403' do + expect(request).to have_http_status 403 end with_permission "lines.change_status" do @@ -24,8 +24,8 @@ RSpec.describe LinesController, :type => :controller do before(:each){ line.deactivate! } - it 'should redirect to 403' do - expect(request).to redirect_to "/403" + it 'should respond with 403' do + expect(request).to have_http_status 403 end with_permission "lines.change_status" do diff --git a/spec/controllers/referentials_controller_spec.rb b/spec/controllers/referentials_controller_spec.rb index 5e0b1e505..ff450c905 100644 --- a/spec/controllers/referentials_controller_spec.rb +++ b/spec/controllers/referentials_controller_spec.rb @@ -6,6 +6,42 @@ describe ReferentialsController, :type => :controller do let(:organisation) { create :organisation } let(:other_referential) { create :referential, organisation: organisation } + describe "GET new" do + let(:request){ get :new, workbench_id: referential.workbench_id } + before{ request } + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + context "when cloning another referential" do + let(:source){ referential } + let(:request){ get :new, workbench_id: referential.workbench_id, from: source.id } + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + context "when the referential is in another organisation but accessible by the user" do + let(:source){ create(:workbench_referential) } + before do + source.workbench.update_attribute :workgroup_id, referential.workbench.workgroup_id + end + + it 'returns http forbidden' do + expect(response).to have_http_status(403) + end + end + + context "when the referential is not accessible by the user" do + let(:source){ create(:workbench_referential) } + it 'returns http forbidden' do + expect(response).to have_http_status(403) + end + end + end + end + describe 'PUT archive' do context "user's organisation matches referential's organisation" do it 'returns http success' do diff --git a/spec/controllers/stop_area_referentials_controller_spec.rb b/spec/controllers/stop_area_referentials_controller_spec.rb index 384323334..737ef631f 100644 --- a/spec/controllers/stop_area_referentials_controller_spec.rb +++ b/spec/controllers/stop_area_referentials_controller_spec.rb @@ -6,7 +6,9 @@ RSpec.describe StopAreaReferentialsController, :type => :controller do describe 'PUT sync' do let(:request){ put :sync, id: stop_area_referential.id } - it { expect(request).to redirect_to "/403" } + it 'should respond with 403' do + expect(request).to have_http_status 403 + end with_permission "stop_area_referentials.synchronize" do it 'returns HTTP success' do diff --git a/spec/controllers/stop_areas_controller_spec.rb b/spec/controllers/stop_areas_controller_spec.rb index 23bca3c36..f39ac5776 100644 --- a/spec/controllers/stop_areas_controller_spec.rb +++ b/spec/controllers/stop_areas_controller_spec.rb @@ -7,8 +7,8 @@ RSpec.describe StopAreasController, :type => :controller do describe 'PUT deactivate' do let(:request){ put :deactivate, id: stop_area.id, stop_area_referential_id: stop_area_referential.id } - it 'should redirect to 403' do - expect(request).to redirect_to "/403" + it 'should respond with 403' do + expect(request).to have_http_status 403 end with_permission "stop_areas.change_status" do @@ -24,8 +24,8 @@ RSpec.describe StopAreasController, :type => :controller do before(:each){ stop_area.deactivate! } - it 'should redirect to 403' do - expect(request).to redirect_to "/403" + it 'should respond with 403' do + expect(request).to have_http_status 403 end with_permission "stop_areas.change_status" do diff --git a/spec/factories/custom_fields.rb b/spec/factories/custom_fields.rb index 2f5fae555..7c43a6147 100644 --- a/spec/factories/custom_fields.rb +++ b/spec/factories/custom_fields.rb @@ -4,6 +4,6 @@ FactoryGirl.define do resource_type "VehicleJourney" sequence(:name){|n| "custom field ##{n}"} field_type "list" - options( { "capacity" => "0" } ) + options( { capacity: "0" } ) end end diff --git a/spec/features/compliance_control_sets_spec.rb b/spec/features/compliance_control_sets_spec.rb index 36dc5c2a9..0f4597db3 100644 --- a/spec/features/compliance_control_sets_spec.rb +++ b/spec/features/compliance_control_sets_spec.rb @@ -8,6 +8,9 @@ RSpec.describe "ComplianceControlSets", type: :feature do let( :control_set ){ create :compliance_control_set, organisation: organisation } let( :controls ){ control_set.compliance_controls } + let(:other_orga) { create :organisation } + let(:other_control_cset) { create :compliance_control_set, organisation: other_orga } + let(:blox){ 2.times.map{ | _ | create :compliance_control_block, compliance_control_set: control_set } } @@ -95,6 +98,18 @@ RSpec.describe "ComplianceControlSets", type: :feature do end + describe 'index' do + + before do + visit compliance_control_sets_path + end + + it "only showw compliance control sets from user organisation" do + expect(page).not_to have_content (other_orga.name) + expect(page).to have_content (organisation.name) + end + end + def make_control ccblock=nil, times: 1, severity: :warning times.times do make_one_control ccblock, severity diff --git a/spec/helpers/table_builder_helper_spec.rb b/spec/helpers/table_builder_helper_spec.rb index 478875118..b0c17859f 100644 --- a/spec/helpers/table_builder_helper_spec.rb +++ b/spec/helpers/table_builder_helper_spec.rb @@ -441,6 +441,53 @@ describe TableBuilderHelper, type: :helper do allow(helper).to receive(:mutual_workbench).and_return(referential.workbench) } + context "with a condition" do + let(:columns){ + [ + TableBuilderHelper::Column.new( + key: :name, + attribute: 'name', + if: condition + ), + ] + } + + context "when the condition is true" do + let(:condition){ ->(obj){true} } + it "should show the value" do + items.each do |i| + tr = helper.send(:tr, i, columns, selectable, links, overhead, model_name, :index) + klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{i.id}" + expect(tr).to include(i.name) + end + end + end + + context "when the condition depends on the object" do + let(:condition){ ->(obj){ obj == referential } } + it "should show the value accordingly" do + tr = helper.send(:tr, item, columns, selectable, links, overhead, model_name, :index) + klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{referential.id}" + expect(tr).to include(referential.name) + tr = helper.send(:tr, other_item, columns, selectable, links, overhead, model_name, :index) + klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{other_referential.id}" + expect(tr).to_not include(other_referential.name) + end + end + + context "when the condition is false" do + let(:condition){ ->(obj){false} } + it "should not show the value" do + items.each do |i| + tr = helper.send(:tr, i, columns, selectable, links, overhead, model_name, :index) + klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{i.id}" + expect(tr).to_not include(i.name) + end + end + end + + end + context "with all rows non-selectable" do let(:selectable){ false } it "sets all rows as non selectable" do diff --git a/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js b/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js index 608115727..bfa0942c6 100644 --- a/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js +++ b/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js @@ -219,7 +219,7 @@ describe('vehicleJourneys reducer', () => { type: 'ADD_VEHICLEJOURNEY', data: fakeData, selectedJourneyPattern: fakeSelectedJourneyPattern, - stopPointsList: [{object_id: 'test-1', city_name: 'city', stop_area_id: 1, id: 1, time_zone_offset: 0, waiting_time: null}, {object_id: 'test-2', city_name: 'city', stop_area_id: 2, id: 2, time_zone_offset: -3600, waiting_time: 10}, {object_id: 'test-3', city_name: 'city', stop_area_id: 3, id: 3, time_zone_offset: 0, waiting_time: 20}, {object_id: 'test-4', city_name: 'city', stop_area_id: 4, id: 4, time_zone_offset: 0}], + stopPointsList: [{object_id: 'test-1', city_name: 'city', stop_area_id: 1, id: 1, time_zone_offset: 0, waiting_time: 10}, {object_id: 'test-2', city_name: 'city', stop_area_id: 2, id: 2, time_zone_offset: -3600, waiting_time: 10}, {object_id: 'test-3', city_name: 'city', stop_area_id: 3, id: 3, time_zone_offset: 0, waiting_time: 20}, {object_id: 'test-4', city_name: 'city', stop_area_id: 4, id: 4, time_zone_offset: 0, waiting_time: 100}], selectedCompany: fakeSelectedCompany }) ).toEqual([{ diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb index 76e73d9cf..c69655bd4 100644 --- a/spec/models/chouette/vehicle_journey_spec.rb +++ b/spec/models/chouette/vehicle_journey_spec.rb @@ -260,7 +260,7 @@ describe Chouette::VehicleJourney, :type => :model do item['purchase_windows'] = [] item['footnotes'] = [] item['purchase_windows'] = [] - item['custom_fields'] = vj.custom_fields + item['custom_fields'] = vj.custom_fields.to_hash vj.vehicle_journey_at_stops.each do |vjas| item['vehicle_journey_at_stops'] << vehicle_journey_at_stop_to_state(vjas) @@ -282,7 +282,6 @@ describe Chouette::VehicleJourney, :type => :model do Chouette::VehicleJourney.state_update(route, collection) }.to change {Chouette::VehicleJourney.count}.by(1) - obj = Chouette::VehicleJourney.last expect(obj).to receive(:after_commit_objectid).and_call_original @@ -292,7 +291,7 @@ describe Chouette::VehicleJourney, :type => :model do expect(collection.last['objectid']).to eq obj.objectid expect(obj.published_journey_name).to eq 'dummy' - expect(obj.custom_fields["energy"]["value"]).to eq 99 + expect(obj.custom_fields["energy"].value).to eq 99 end it 'should expect local times' do diff --git a/spec/models/custom_field_spec.rb b/spec/models/custom_field_spec.rb index 51128b0a2..b92bcfbdb 100644 --- a/spec/models/custom_field_spec.rb +++ b/spec/models/custom_field_spec.rb @@ -16,7 +16,6 @@ RSpec.describe CustomField, type: :model do end end - context "custom fields for a resource" do let!( :fields ){ [create(:custom_field), create(:custom_field, code: :energy)] } let!( :instance_fields ){ @@ -26,10 +25,49 @@ RSpec.describe CustomField, type: :model do } } it { expect(Chouette::VehicleJourney.custom_fields).to eq(fields) } - it { expect(vj.custom_fields).to eq(instance_fields) } + it { + instance_fields.each do |code, cf| + cf.each do |k, v| + expect(vj.custom_fields[code].send(k)).to eq(v) + end + end + } end context "custom field_values for a resource" do it { expect(vj.custom_field_value("energy")).to eq(99) } end + + context "with an 'integer' field_type" do + let!(:field){ [create(:custom_field, code: :energy, options: {field_type: 'integer'})] } + let!( :vj ){ create :vehicle_journey, custom_field_values: {energy: "99"} } + it "should cast the value" do + expect(vj.custom_fields[:energy].value).to eq 99 + end + + it "should validate the value" do + { + "99" => true, + "azerty" => false, + "91a" => false, + "a91" => false + }.each do |val, valid| + vj = build :vehicle_journey, custom_field_values: {energy: val} + if valid + expect(vj.validate).to be_truthy + else + expect(vj.validate).to be_falsy + expect(vj.errors.messages[:"custom_fields.energy"]).to be_present + end + end + end + end + + context "with a 'string' field_type" do + let!(:field){ [create(:custom_field, code: :energy, options: {field_type: 'string'})] } + let!( :vj ){ create :vehicle_journey, custom_field_values: {energy: 99} } + it "should cast the value" do + expect(vj.custom_fields[:energy].value).to eq '99' + end + end end diff --git a/spec/models/referential_spec.rb b/spec/models/referential_spec.rb index 025ad80f9..1d9b3d78a 100644 --- a/spec/models/referential_spec.rb +++ b/spec/models/referential_spec.rb @@ -58,16 +58,21 @@ describe Referential, :type => :model do Referential.new_from(ref, []) end - # let(:saved_clone) do - # clone.tap do |clone| - # clone.organisation = ref.organisation - # clone.metadatas.each do |metadata| - # metadata.line_ids = ref.lines.where(id: clone.line_ids, objectid: JSON.parse(ref.organisation.sso_attributes["functional_scope"]).collect(&:id) - # metadata.periodes = metadata.periodes.map { |period| Range.new(period.end+1, period.end+10) } - # end - # clone.save! - # end - # end + let!(:workbench){ create :workbench } + + let(:saved_clone) do + clone.tap do |clone| + clone.organisation = workbench.organisation + clone.workbench = workbench + clone.metadatas = [create(:referential_metadata, referential: clone)] + clone.save! + end + end + + it 'should create a Referential' do + ref + expect { saved_clone }.to change{Referential.count}.by(1) + end xit 'should create a ReferentialCloning' do expect { saved_clone }.to change{ReferentialCloning.count}.by(1) diff --git a/spec/support/pundit/pundit_view_policy.rb b/spec/support/pundit/pundit_view_policy.rb index 316ff6718..efe7f0f76 100644 --- a/spec/support/pundit/pundit_view_policy.rb +++ b/spec/support/pundit/pundit_view_policy.rb @@ -5,13 +5,13 @@ module Pundit into.let(:current_referential){ referential || build_stubbed(:referential, organisation: organisation) } into.let(:current_user){ create :user, permissions: permissions, organisation: organisation } into.let(:pundit_user){ UserContext.new(current_user, referential: current_referential) } - into.let(:current_offer_workbench) { create :workbench, organisation: organisation} + into.let(:current_workbench) { create :workbench, organisation: organisation} into.before do allow(view).to receive(:pundit_user) { pundit_user } allow(view).to receive(:current_user) { current_user } allow(view).to receive(:current_organisation).and_return(organisation) - allow(view).to receive(:current_offer_workbench).and_return(current_offer_workbench) - allow(view).to receive(:current_workgroup).and_return(current_offer_workbench.workgroup) + allow(view).to receive(:current_workbench).and_return(current_workbench) + allow(view).to receive(:current_workgroup).and_return(current_workbench.workgroup) allow(view).to receive(:has_feature?){ |f| respond_to?(:features) && features.include?(f)} allow(view).to receive(:user_signed_in?).and_return true allow(view).to receive(:policy) do |instance| diff --git a/spec/views/referentials/show.html.erb_spec.rb b/spec/views/referentials/show.html.erb_spec.rb index a7f37d180..82328cb8e 100644 --- a/spec/views/referentials/show.html.erb_spec.rb +++ b/spec/views/referentials/show.html.erb_spec.rb @@ -11,6 +11,7 @@ describe "referentials/show", type: :view do let(:organisation){ referential.try(:organisation) } let(:permissions){ [] } let(:current_organisation) { organisation } + let(:organisation) { referential.organisation } let(:readonly){ false } before :each do |
