From feb9c32537489a6a16209566e6bd9b85405edb81 Mon Sep 17 00:00:00 2001 From: clemkeirua Date: Tue, 3 Sep 2019 15:17:19 +0200 Subject: [PATCH 1/2] search attachments inside bloc repetables --- app/services/pieces_justificatives_service.rb | 18 +++++++++++++++--- spec/factories/champ.rb | 14 ++++++++++++++ .../active_storage/downloadable_file_spec.rb | 9 +++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/app/services/pieces_justificatives_service.rb b/app/services/pieces_justificatives_service.rb index bd2dd2af3..ea7475d17 100644 --- a/app/services/pieces_justificatives_service.rb +++ b/app/services/pieces_justificatives_service.rb @@ -1,8 +1,12 @@ class PiecesJustificativesService def self.liste_pieces_justificatives(dossier) - dossier.champs - .select { |c| c.type_champ == TypeDeChamp.type_champs.fetch(:piece_justificative) } - .filter { |pj| pj.piece_justificative_file.attached? } + champs_blocs_repetables = dossier.champs + .select { |c| c.type_champ == TypeDeChamp.type_champs.fetch(:repetition) } + .flat_map(&:champs) + + champs_pieces_justificatives_with_attachments( + champs_blocs_repetables + dossier.champs + ) end def self.pieces_justificatives_total_size(dossier) @@ -37,4 +41,12 @@ class PiecesJustificativesService } end end + + private + + def self.champs_pieces_justificatives_with_attachments(champs) + champs + .select { |c| c.type_champ == TypeDeChamp.type_champs.fetch(:piece_justificative) } + .filter { |pj| pj.piece_justificative_file.attached? } + end end diff --git a/spec/factories/champ.rb b/spec/factories/champ.rb index 114b25bdd..b9913a536 100644 --- a/spec/factories/champ.rb +++ b/spec/factories/champ.rb @@ -175,4 +175,18 @@ FactoryBot.define do create(:champ_number, row: 1, type_de_champ: type_de_champ_number, parent: champ_repetition) end end + + factory :champ_repetition_with_piece_jointe, class: 'Champs::RepetitionChamp' do + type_de_champ { create(:type_de_champ_repetition) } + + after(:build) do |champ_repetition, _evaluator| + type_de_champ_pj0 = create(:type_de_champ_piece_justificative, order_place: 0, parent: champ_repetition.type_de_champ, libelle: 'Justificatif de domicile') + type_de_champ_pj1 = create(:type_de_champ_piece_justificative, order_place: 1, parent: champ_repetition.type_de_champ, libelle: 'Carte d\'identité') + + create(:champ_piece_justificative, row: 0, type_de_champ: type_de_champ_pj0, parent: champ_repetition) + create(:champ_piece_justificative, row: 0, type_de_champ: type_de_champ_pj1, parent: champ_repetition) + create(:champ_piece_justificative, row: 1, type_de_champ: type_de_champ_pj0, parent: champ_repetition) + create(:champ_piece_justificative, row: 1, type_de_champ: type_de_champ_pj1, parent: champ_repetition) + end + end end diff --git a/spec/lib/active_storage/downloadable_file_spec.rb b/spec/lib/active_storage/downloadable_file_spec.rb index dc40ec1d8..271915378 100644 --- a/spec/lib/active_storage/downloadable_file_spec.rb +++ b/spec/lib/active_storage/downloadable_file_spec.rb @@ -15,5 +15,14 @@ describe ActiveStorage::DownloadableFile do it { expect(list.length).to be 1 } end + + context 'when there is a repetition bloc' do + let(:champ) { build(:champ_repetition_with_piece_jointe) } + let(:dossier) { create(:dossier, :en_construction, champs: [champ]) } + + it 'should have 4 piece_justificatives' do + expect(list.size).to eq(4) + end + end end end From 65e227c44b36412bee20c8473ba547fbbd872ba4 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 4 Jul 2019 12:36:17 +0200 Subject: [PATCH 2/2] Migrate to flipper --- Gemfile | 3 ++ Gemfile.lock | 12 +++++ app/controllers/application_controller.rb | 10 ++-- .../instructeurs/dossiers_controller.rb | 2 +- .../manager/administrateurs_controller.rb | 14 ------ .../manager/instructeurs_controller.rb | 14 ------ app/controllers/manager/users_controller.rb | 14 ++++++ app/helpers/flipper_helper.rb | 5 ++ app/helpers/procedure_helper.rb | 4 +- app/lib/api_entreprise/api.rb | 2 +- .../strategies/user_preference_strategy.rb | 32 ------------- app/models/administrateur.rb | 17 ------- app/models/dossier_operation_log.rb | 2 +- app/models/instructeur.rb | 17 ------- app/models/user.rb | 4 ++ .../admin/procedures/_informations.html.haml | 2 +- .../fields/features_field/_show.html.haml | 15 +++--- .../dossiers/_header_actions.html.haml | 2 +- app/views/layouts/_pre_maintenance.html.haml | 2 +- app/views/layouts/application.html.haml | 4 +- .../manager/application/_navigation.html.erb | 2 +- config/application.rb | 1 + config/features.rb | 42 ----------------- config/initializers/flipper.rb | 46 +++++++++++++++++++ config/routes.rb | 5 +- .../20190704094454_create_flipper_tables.rb | 22 +++++++++ db/schema.rb | 18 +++++++- ...829065022_migrate_flipflop_to_flipper.rake | 33 +++++++++++++ .../application_controller_spec.rb | 2 +- .../instructeurs/dossiers_controller_spec.rb | 4 -- spec/models/administrateur_spec.rb | 11 ----- spec/spec_helper.rb | 2 +- spec/support/feature_helpers.rb | 2 +- 33 files changed, 186 insertions(+), 181 deletions(-) create mode 100644 app/helpers/flipper_helper.rb delete mode 100644 app/lib/flipflop/strategies/user_preference_strategy.rb delete mode 100644 config/features.rb create mode 100644 config/initializers/flipper.rb create mode 100644 db/migrate/20190704094454_create_flipper_tables.rb create mode 100644 lib/tasks/deployment/20190829065022_migrate_flipflop_to_flipper.rake diff --git a/Gemfile b/Gemfile index 17d37eee9..8849da0e9 100644 --- a/Gemfile +++ b/Gemfile @@ -27,6 +27,9 @@ gem 'devise' # Gestion des comptes utilisateurs gem 'devise-async' gem 'dotenv-rails', require: 'dotenv/rails-now' # dotenv should always be loaded before rails gem 'flipflop' +gem 'flipper' +gem 'flipper-active_record' +gem 'flipper-ui' gem 'fog-openstack' gem 'font-awesome-rails' gem 'gon' diff --git a/Gemfile.lock b/Gemfile.lock index 7c9448de9..9bf075646 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -222,6 +222,15 @@ GEM ffi (1.9.25) flipflop (2.4.0) activesupport (>= 4.0) + flipper (0.16.2) + flipper-active_record (0.16.2) + activerecord (>= 3.2, < 6) + flipper (~> 0.16.2) + flipper-ui (0.16.2) + erubis (~> 2.7.0) + flipper (~> 0.16.2) + rack (>= 1.4, < 3) + rack-protection (>= 1.5.3, < 2.1.0) fog-core (2.1.2) builder excon (~> 0.58) @@ -725,6 +734,9 @@ DEPENDENCIES dotenv-rails factory_bot flipflop + flipper + flipper-active_record + flipper-ui fog-openstack font-awesome-rails gon diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 8648c7b08..e70dadfda 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -12,7 +12,7 @@ class ApplicationController < ActionController::Base before_action :set_raven_context before_action :redirect_if_untrusted before_action :authorize_request_for_profiler - before_action :reject, if: -> { Flipflop.maintenance_mode? } + before_action :reject, if: -> { feature_enabled?(:maintenance_mode) } before_action :staging_authenticate before_action :set_active_storage_host @@ -28,7 +28,7 @@ class ApplicationController < ActionController::Base end def authorize_request_for_profiler - if Flipflop.mini_profiler_enabled? + if feature_enabled?(:mini_profiler) Rack::MiniProfiler.authorize_request end end @@ -77,6 +77,10 @@ class ApplicationController < ActionController::Base protected + def feature_enabled?(feature_name) + Flipper.enabled?(feature_name, current_user) + end + def authenticate_logged_user! if instructeur_signed_in? authenticate_instructeur! @@ -190,7 +194,7 @@ class ApplicationController < ActionController::Base def redirect_if_untrusted if instructeur_signed_in? && sensitive_path && - !Flipflop.bypass_email_login_token? && + !feature_enabled?(:instructeur_bypass_email_login_token) && !IPService.ip_trusted?(request.headers['X-Forwarded-For']) && !trusted_device? diff --git a/app/controllers/instructeurs/dossiers_controller.rb b/app/controllers/instructeurs/dossiers_controller.rb index dca392aa1..c213a0255 100644 --- a/app/controllers/instructeurs/dossiers_controller.rb +++ b/app/controllers/instructeurs/dossiers_controller.rb @@ -191,7 +191,7 @@ module Instructeurs end def telecharger_pjs - return head(:forbidden) if !Flipflop.download_as_zip_enabled? || !dossier.attachments_downloadable? + return head(:forbidden) if !feature_enabled?(:instructeur_download_as_zip) || !dossier.attachments_downloadable? files = ActiveStorage::DownloadableFile.create_list_from_dossier(dossier) diff --git a/app/controllers/manager/administrateurs_controller.rb b/app/controllers/manager/administrateurs_controller.rb index 74bd191ea..18e30f9a1 100644 --- a/app/controllers/manager/administrateurs_controller.rb +++ b/app/controllers/manager/administrateurs_controller.rb @@ -19,20 +19,6 @@ module Manager redirect_to manager_administrateur_path(params[:id]) end - def enable_feature - administrateur = Administrateur.find(params[:id]) - - params[:features].each do |key, enable| - if enable - administrateur.enable_feature(key.to_sym) - else - administrateur.disable_feature(key.to_sym) - end - end - - head :ok - end - def delete administrateur = Administrateur.find(params[:id]) diff --git a/app/controllers/manager/instructeurs_controller.rb b/app/controllers/manager/instructeurs_controller.rb index 89ed9bdc3..82b1e11eb 100644 --- a/app/controllers/manager/instructeurs_controller.rb +++ b/app/controllers/manager/instructeurs_controller.rb @@ -6,19 +6,5 @@ module Manager flash[:notice] = "Instructeur réinvité." redirect_to manager_instructeur_path(instructeur) end - - def enable_feature - instructeur = Instructeur.find(params[:id]) - - params[:features].each do |key, enable| - if enable - instructeur.enable_feature(key.to_sym) - else - instructeur.disable_feature(key.to_sym) - end - end - - head :ok - end end end diff --git a/app/controllers/manager/users_controller.rb b/app/controllers/manager/users_controller.rb index d655c552b..e80d22404 100644 --- a/app/controllers/manager/users_controller.rb +++ b/app/controllers/manager/users_controller.rb @@ -6,5 +6,19 @@ module Manager flash[:notice] = "L'email d'activation de votre compte a été renvoyé." redirect_to manager_user_path(user) end + + def enable_feature + user = User.find(params[:id]) + + params[:features].each do |key, enable| + if enable + Flipper.enable_actor(key.to_sym, user) + else + Flipper.disable_actor(key.to_sym, user) + end + end + + head :ok + end end end diff --git a/app/helpers/flipper_helper.rb b/app/helpers/flipper_helper.rb new file mode 100644 index 000000000..aa81299c5 --- /dev/null +++ b/app/helpers/flipper_helper.rb @@ -0,0 +1,5 @@ +module FlipperHelper + def feature_enabled?(feature_name) + Flipper.enabled?(feature_name, current_user) + end +end diff --git a/app/helpers/procedure_helper.rb b/app/helpers/procedure_helper.rb index 76ddd6760..52a834f16 100644 --- a/app/helpers/procedure_helper.rb +++ b/app/helpers/procedure_helper.rb @@ -50,7 +50,7 @@ module ProcedureHelper private TOGGLES = { - TypeDeChamp.type_champs.fetch(:integer_number) => :champ_integer_number? + TypeDeChamp.type_champs.fetch(:integer_number) => :administrateur_champ_integer_number } def types_de_champ_types @@ -58,7 +58,7 @@ module ProcedureHelper types_de_champ_types.select! do |tdc| toggle = TOGGLES[tdc.last] - toggle.blank? || Flipflop.send(toggle) + toggle.blank? || feature_enabled?(toggle) end types_de_champ_types diff --git a/app/lib/api_entreprise/api.rb b/app/lib/api_entreprise/api.rb index f90abd6e9..818d1e833 100644 --- a/app/lib/api_entreprise/api.rb +++ b/app/lib/api_entreprise/api.rb @@ -44,7 +44,7 @@ class ApiEntreprise::API def self.url(resource_name, siret_or_siren) base_url = [API_ENTREPRISE_URL, resource_name, siret_or_siren].join("/") - if Flipflop.insee_api_v3? + if Flipper.enabled?(:insee_api_v3) base_url += "?with_insee_v3=true" end diff --git a/app/lib/flipflop/strategies/user_preference_strategy.rb b/app/lib/flipflop/strategies/user_preference_strategy.rb deleted file mode 100644 index 1aa2c1165..000000000 --- a/app/lib/flipflop/strategies/user_preference_strategy.rb +++ /dev/null @@ -1,32 +0,0 @@ -module Flipflop::Strategies - class UserPreferenceStrategy < AbstractStrategy - def self.default_description - "Allows configuration of features per user." - end - - def switchable? - false - end - - def enabled?(feature) - find_current_administrateur&.feature_enabled?(feature) || - find_current_instructeur&.feature_enabled?(feature) - end - - private - - def find_current_administrateur - administrateur_id = Current.administrateur&.id - if administrateur_id - Administrateur.find_by(id: administrateur_id) - end - end - - def find_current_instructeur - instructeur_id = Current.instructeur&.id - if instructeur_id - Instructeur.find_by(id: instructeur_id) - end - end - end -end diff --git a/app/models/administrateur.rb b/app/models/administrateur.rb index 89fbbecc0..738281e29 100644 --- a/app/models/administrateur.rb +++ b/app/models/administrateur.rb @@ -72,23 +72,6 @@ class Administrateur < ApplicationRecord administrateur end - def feature_enabled?(feature) - Flipflop.feature_set.feature(feature) - features[feature.to_s] - end - - def disable_feature(feature) - Flipflop.feature_set.feature(feature) - features.delete(feature.to_s) - save - end - - def enable_feature(feature) - Flipflop.feature_set.feature(feature) - features[feature.to_s] = true - save - end - def owns?(procedure) procedure.administrateurs.include?(self) end diff --git a/app/models/dossier_operation_log.rb b/app/models/dossier_operation_log.rb index a54f0718e..fbb3df559 100644 --- a/app/models/dossier_operation_log.rb +++ b/app/models/dossier_operation_log.rb @@ -66,7 +66,7 @@ class DossierOperationLog < ApplicationRecord def self.serialize_subject(subject) if subject.nil? nil - elsif !Flipflop.operation_log_serialize_subject? + elsif !Flipper.enabled?(:operation_log_serialize_subject) { id: subject.id } else case subject diff --git a/app/models/instructeur.rb b/app/models/instructeur.rb index bf849e4ba..08087b61e 100644 --- a/app/models/instructeur.rb +++ b/app/models/instructeur.rb @@ -180,23 +180,6 @@ class Instructeur < ApplicationRecord Follow.where(instructeur: self, dossier: dossier).update_all(attributes) end - def feature_enabled?(feature) - Flipflop.feature_set.feature(feature) - features[feature.to_s] - end - - def disable_feature(feature) - Flipflop.feature_set.feature(feature) - features.delete(feature.to_s) - save - end - - def enable_feature(feature) - Flipflop.feature_set.feature(feature) - features[feature.to_s] = true - save - end - def young_login_token? trusted_device_token = trusted_device_tokens.order(created_at: :desc).first trusted_device_token&.token_young? diff --git a/app/models/user.rb b/app/models/user.rb index 8a6fdd86e..1f5217767 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -87,6 +87,10 @@ class User < ApplicationRecord user end + def flipper_id + "User:#{id}" + end + private def link_invites! diff --git a/app/views/admin/procedures/_informations.html.haml b/app/views/admin/procedures/_informations.html.haml index 6d783feae..bcd59d4a8 100644 --- a/app/views/admin/procedures/_informations.html.haml +++ b/app/views/admin/procedures/_informations.html.haml @@ -125,7 +125,7 @@ .col-md-6 %h4 Options avancées - - if Flipflop.web_hook? + - if feature_enabled?(:administrateur_web_hook) %label{ for: :web_hook_url } Lien de rappel HTTP (webhook) = f.text_field :web_hook_url, class: 'form-control', placeholder: 'https://callback.exemple.fr/' %p.help-block diff --git a/app/views/fields/features_field/_show.html.haml b/app/views/fields/features_field/_show.html.haml index 6db607e55..221825c3e 100644 --- a/app/views/fields/features_field/_show.html.haml +++ b/app/views/fields/features_field/_show.html.haml @@ -1,14 +1,11 @@ :ruby - url = if field.resource.class.name == 'Instructeur' - enable_feature_manager_instructeur_path(field.resource.id) - else - enable_feature_manager_administrateur_path(field.resource.id) - end + group = field.resource.class.name.downcase + user = field.resource.user + url = enable_feature_manager_user_path(user) %table#features - - admin_features = Flipflop.feature_set.features.reject{ |f| f.group.try(:key) == :production } - - admin_features.each do |feature| + - Flipper.features.select { |feature| feature.key.start_with?("#{group}_") }.each do |feature| %tr - %td= feature.title + %td= feature %td - = check_box_tag "enable-feature", "enable", field.data[feature.name], data: { url: url, key: feature.key } + = check_box_tag "enable-feature", "enable", feature.enabled?(user), data: { url: url, key: feature.key } diff --git a/app/views/instructeurs/dossiers/_header_actions.html.haml b/app/views/instructeurs/dossiers/_header_actions.html.haml index 3cbaa91f4..27c428f59 100644 --- a/app/views/instructeurs/dossiers/_header_actions.html.haml +++ b/app/views/instructeurs/dossiers/_header_actions.html.haml @@ -7,7 +7,7 @@ %li = link_to "Uniquement cet onglet", "#", onclick: "window.print()", class: "menu-item menu-link" -- if Flipflop.download_as_zip_enabled? && !PiecesJustificativesService.liste_pieces_justificatives(dossier).empty? +- if feature_enabled?(:instructeur_download_as_zip) && !PiecesJustificativesService.liste_pieces_justificatives(dossier).empty? %span.dropdown.print-menu-opener %button.button.dropdown-button.icon-only %span.icon.attachment diff --git a/app/views/layouts/_pre_maintenance.html.haml b/app/views/layouts/_pre_maintenance.html.haml index 636556d16..c14ca1e61 100644 --- a/app/views/layouts/_pre_maintenance.html.haml +++ b/app/views/layouts/_pre_maintenance.html.haml @@ -1,4 +1,4 @@ -- if Flipflop.pre_maintenance_mode? +- if feature_enabled?(:pre_maintenance_mode) .maintenance %span Une opération de maintenance est prévue sur demarches-simplifiees.fr à 23 h 00. La plateforme sera inaccessible pendant une vingtaine de minutes. diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 456ebfb5c..7178d975f 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -21,7 +21,7 @@ = Gon::Base.render_data(camel_case: true, init: true, nonce: request.content_security_policy_nonce) - - if Flipflop.xray_enabled? + - if feature_enabled?(:xray) = stylesheet_link_tag :xray %body{ id: content_for(:page_id), class: browser.platform.ios? ? 'ios' : nil } @@ -39,7 +39,7 @@ - if content_for?(:footer) = content_for(:footer) - - if Flipflop.xray_enabled? + - if feature_enabled?(:xray) = javascript_include_tag :xray = yield :charts_js diff --git a/app/views/manager/application/_navigation.html.erb b/app/views/manager/application/_navigation.html.erb index 216e3fe4c..891658871 100644 --- a/app/views/manager/application/_navigation.html.erb +++ b/app/views/manager/application/_navigation.html.erb @@ -24,5 +24,5 @@ as defined by the routes in the `admin/` namespace
<%= link_to "Delayed Jobs", manager_delayed_job_path, class: "navigation__link" %> - <%= link_to "Features", manager_flipflop_path, class: "navigation__link" %> + <%= link_to "Features", manager_flipper_path, class: "navigation__link" %> diff --git a/config/application.rb b/config/application.rb index 5f6cbc055..b42657278 100644 --- a/config/application.rb +++ b/config/application.rb @@ -42,5 +42,6 @@ module TPS config.ds_weekly_overview = ENV['APP_NAME'] == 'tps' config.middleware.use Rack::Attack + config.middleware.use Flipper::Middleware::Memoizer, preload_all: true end end diff --git a/config/features.rb b/config/features.rb deleted file mode 100644 index 6e3dbf490..000000000 --- a/config/features.rb +++ /dev/null @@ -1,42 +0,0 @@ -Flipflop.configure do - strategy :cookie, - secure: Rails.env.production?, - httponly: true - strategy :active_record - strategy :user_preference - strategy :default - - group :champs do - feature :champ_integer_number, - title: "Champ nombre entier" - end - - feature :web_hook - - feature :operation_log_serialize_subject - feature :download_as_zip_enabled - feature :bypass_email_login_token, - default: Rails.env.test? - - group :development do - feature :mini_profiler_enabled, - default: Rails.env.development? - feature :xray_enabled, - default: Rails.env.development? - end - - group :production do - feature :insee_api_v3, - default: true - feature :pre_maintenance_mode - feature :maintenance_mode - end - - if Rails.env.test? - # It would be nicer to configure this in administrateur_spec.rb in #feature_enabled?, - # but that results in a FrozenError: can't modify frozen Hash - - feature :test_a - feature :test_b - end -end diff --git a/config/initializers/flipper.rb b/config/initializers/flipper.rb new file mode 100644 index 000000000..f50fb3a8f --- /dev/null +++ b/config/initializers/flipper.rb @@ -0,0 +1,46 @@ +Flipper.configure do |config| + config.default do + Flipper.new(Flipper::Adapters::ActiveRecord.new) + end +end + +Flipper.register('Administrateurs') do |user| + user.administrateur_id.present? +end +Flipper.register('Instructeurs') do |user| + user.instructeur_id.present? +end + +# This setup is primarily for first deployment, because consequently +# we can add new features from the Web UI. However when the new DB is created +# this will immediately migrate the default features to be controlled. +def setup_features(features) + features.each do |feature| + if Flipper.exist?(feature) + return + end + + # Disable feature by default + Flipper.disable(feature) + end +end + +# A list of features to be deployed on first push +features = [ + :administrateur_champ_integer_number, + :administrateur_web_hook, + :insee_api_v3, + :instructeur_bypass_email_login_token, + :instructeur_download_as_zip, + :maintenance_mode, + :mini_profiler, + :operation_log_serialize_subject, + :pre_maintenance_mode, + :xray +] + +ActiveSupport.on_load(:active_record) do + if ActiveRecord::Base.connection.data_source_exists? 'flipper_features' + setup_features(features) + end +end diff --git a/config/routes.rb b/config/routes.rb index 01301c3fb..0bb11a794 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -21,17 +21,16 @@ Rails.application.routes.draw do resources :administrateurs, only: [:index, :show, :new, :create] do post 'reinvite', on: :member - put 'enable_feature', on: :member delete 'delete', on: :member end resources :users, only: [:index, :show] do post 'resend_confirmation_instructions', on: :member + put 'enable_feature', on: :member end resources :instructeurs, only: [:index, :show] do post 'reinvite', on: :member - put 'enable_feature', on: :member end resources :dossiers, only: [:show] @@ -46,7 +45,7 @@ Rails.application.routes.draw do post 'demandes/refuse_administrateur' authenticate :administration do - mount Flipflop::Engine => "/features" + mount Flipper::UI.app(-> { Flipper.instance }) => "/features", as: :flipper match "/delayed_job" => DelayedJobWeb, :anchor => false, :via => [:get, :post] end diff --git a/db/migrate/20190704094454_create_flipper_tables.rb b/db/migrate/20190704094454_create_flipper_tables.rb new file mode 100644 index 000000000..ca4390c5c --- /dev/null +++ b/db/migrate/20190704094454_create_flipper_tables.rb @@ -0,0 +1,22 @@ +class CreateFlipperTables < ActiveRecord::Migration[5.2] + def self.up + create_table :flipper_features do |t| + t.string :key, null: false + t.timestamps null: false + end + add_index :flipper_features, :key, unique: true + + create_table :flipper_gates do |t| + t.string :feature_key, null: false + t.string :key, null: false + t.string :value + t.timestamps null: false + end + add_index :flipper_gates, [:feature_key, :key, :value], unique: true + end + + def self.down + drop_table :flipper_gates + drop_table :flipper_features + end +end diff --git a/db/schema.rb b/db/schema.rb index 39061aa04..c064f5dba 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2019_08_22_143413) do +ActiveRecord::Schema.define(version: 2019_08_28_073736) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -355,6 +355,22 @@ ActiveRecord::Schema.define(version: 2019_08_22_143413) do t.datetime "updated_at", null: false end + create_table "flipper_features", force: :cascade do |t| + t.string "key", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["key"], name: "index_flipper_features_on_key", unique: true + end + + create_table "flipper_gates", force: :cascade do |t| + t.string "feature_key", null: false + t.string "key", null: false + t.string "value" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["feature_key", "key", "value"], name: "index_flipper_gates_on_feature_key_and_key_and_value", unique: true + end + create_table "follows", id: :serial, force: :cascade do |t| t.integer "instructeur_id", null: false t.integer "dossier_id", null: false diff --git a/lib/tasks/deployment/20190829065022_migrate_flipflop_to_flipper.rake b/lib/tasks/deployment/20190829065022_migrate_flipflop_to_flipper.rake new file mode 100644 index 000000000..6d1a3c9a8 --- /dev/null +++ b/lib/tasks/deployment/20190829065022_migrate_flipflop_to_flipper.rake @@ -0,0 +1,33 @@ +namespace :after_party do + desc 'Deployment task: migrate_flipflop_to_flipper' + task migrate_flipflop_to_flipper: :environment do + puts "Running deploy task 'migrate_flipflop_to_flipper'" + + Instructeur.includes(:user).find_each do |instructeur| + if instructeur.features['download_as_zip_enabled'] + pp "enable :instructeur_download_as_zip for #{instructeur.user.email}" + Flipper.enable_actor(:instructeur_download_as_zip, instructeur.user) + end + if instructeur.features['bypass_email_login_token'] + pp "enable :instructeur_bypass_email_login_token for #{instructeur.user.email}" + Flipper.enable_actor(:instructeur_bypass_email_login_token, instructeur.user) + end + end + + Administrateur.includes(:user).find_each do |administrateur| + if administrateur.features['web_hook'] + pp "enable :administrateur_web_hook for #{administrateur.user.email}" + Flipper.enable_actor(:administrateur_web_hook, administrateur.user) + end + + if administrateur.features['champ_integer_number'] + pp "enable :administrateur_champ_integer_number for #{administrateur.user.email}" + Flipper.enable_actor(:administrateur_champ_integer_number, administrateur.user) + end + end + + # Update task as completed. If you remove the line below, the task will + # run with every deploy (or every time you call after_party:run). + AfterParty::TaskRecord.create version: '20190829065022' + end +end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 24929f43e..4eac9c120 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -167,7 +167,7 @@ describe ApplicationController, type: :controller do let(:sensitive_path) { true } before do - Flipflop::FeatureSet.current.test!.switch!(:bypass_email_login_token, false) + Flipper.disable(:instructeur_bypass_email_login_token) end context 'when the instructeur is signed_in' do diff --git a/spec/controllers/instructeurs/dossiers_controller_spec.rb b/spec/controllers/instructeurs/dossiers_controller_spec.rb index 89afec1ae..01033f0b1 100644 --- a/spec/controllers/instructeurs/dossiers_controller_spec.rb +++ b/spec/controllers/instructeurs/dossiers_controller_spec.rb @@ -544,10 +544,6 @@ describe Instructeurs::DossiersController, type: :controller do end context 'when zip download is disabled through flipflop' do - before do - Flipflop::FeatureSet.current.test!.switch!(:download_as_zip_enabled, false) - end - it 'is forbidden' do subject expect(response).to have_http_status(:forbidden) diff --git a/spec/models/administrateur_spec.rb b/spec/models/administrateur_spec.rb index a4e679441..4b9fef1f0 100644 --- a/spec/models/administrateur_spec.rb +++ b/spec/models/administrateur_spec.rb @@ -21,17 +21,6 @@ describe Administrateur, type: :model do end end - describe '#feature_enabled?' do - let(:administrateur) { create(:administrateur) } - - before do - administrateur.enable_feature(:test_a) - end - - it { expect(administrateur.feature_enabled?(:test_b)).to be_falsey } - it { expect(administrateur.feature_enabled?(:test_a)).to be_truthy } - end - # describe '#password_complexity' do # let(:email) { 'mail@beta.gouv.fr' } # let(:passwords) { ['pass', '12pass23', 'démarches ', 'démarches-simple', 'démarches-simplifiées-pwd'] } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ca4b4feed..dd0af845a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -139,7 +139,7 @@ RSpec.configure do |config| config.include FactoryBot::Syntax::Methods config.before(:each) do - Flipflop::FeatureSet.current.test!.reset! + Flipper.enable(:instructeur_bypass_email_login_token) end config.before(:all) { diff --git a/spec/support/feature_helpers.rb b/spec/support/feature_helpers.rb index 545406561..6e11bea16 100644 --- a/spec/support/feature_helpers.rb +++ b/spec/support/feature_helpers.rb @@ -22,7 +22,7 @@ module FeatureHelpers fill_in :user_password, with: password if sign_in_by_link - Flipflop::FeatureSet.current.test!.switch!(:bypass_email_login_token, false) + Flipper.disable(:instructeur_bypass_email_login_token) end perform_enqueued_jobs do