Merge branch 'demarches-simplifiees:main' into poc-self_hosted_runners

This commit is contained in:
kleph 2023-08-31 18:55:57 +02:00 committed by GitHub
commit dd4d60fdfe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
83 changed files with 331 additions and 382 deletions

View file

@ -41,11 +41,11 @@ demarches-simplifiees.fr est **compliqué à héberger**. Parmi les problématiq
- **Utilisation de services externes** : demarches-simplifiees.fr sinterconnecte à de nombreux services externes : des APIs (API Entreprise, API Carto, la Base Adresse Nationale, etc.) mais aussi des services pour le stockage externe des pièces-jointes, lanalyse anti-virus ou lenvoi des emails. Le fonctionnement de demarches-simplifiees.fr dépend de la disponibilité de ces services externes. - **Utilisation de services externes** : demarches-simplifiees.fr sinterconnecte à de nombreux services externes : des APIs (API Entreprise, API Carto, la Base Adresse Nationale, etc.) mais aussi des services pour le stockage externe des pièces-jointes, lanalyse anti-virus ou lenvoi des emails. Le fonctionnement de demarches-simplifiees.fr dépend de la disponibilité de ces services externes.
- **Mises à jour** : le schéma de la base de données change régulièrement. Nous codons également des scripts pour harmoniser les anciennes données. Parfois des modifications ponctuelles sont effectuées sur des démarches anciennes, pour les mettre en conformité avec de nouvelles règles métiers. Nous maintenons également les dépendances logicielles utilisées notamment en réagissant rapidement lorsquune faille de sécurité est signalée. Ces mises à jour fréquentes en production sont indispensables au bon fonctionnement de loutil. - **Mises à jour** : le schéma de la base de données change régulièrement. Nous codons également des scripts pour harmoniser les anciennes données. Parfois des modifications ponctuelles sont effectuées sur des démarches anciennes, pour les mettre en conformité avec de nouvelles règles métiers. Nous maintenons également les dépendances logicielles utilisées notamment en réagissant rapidement lorsquune faille de sécurité est signalée. Ces mises à jour fréquentes en production sont indispensables au bon fonctionnement de loutil.
Si vous souhaitez adapter demarches-simplifiees.fr à votre besoin, nous vous recommandons de **proposer vos modifications à la base de code principale** (par exemple en créant une issue) **plutôt que dhéberger une autre instance vous-même**. Si vous souhaitez adapter demarches-simplifiees.fr à vos besoins, nous vous recommandons de **proposer vos modifications à la base de code principale** (par exemple en créant une issue) **plutôt que dhéberger une autre instance vous-même**.
Dans le cas où vous envisagez dhéberger une instance de demarches-simplifiees.fr vous-même, nous n'avons malheureusement pas les moyens de vous accompagner, ni dassurer de support technique concernant votre installation. Dans le cas où vous envisagez dhéberger une instance de demarches-simplifiees.fr vous-même, nous ne disposons malheureusement pas des moyens pour vous accompagner, ni dassurer de support technique concernant votre installation.
Toutefois, certains acteurs (le ministère des armées, ladministration autonome en Polynésie française) ont déployé des instances séparées. Nous proposons aux personnes intéressées de les mettre en relation avec ces acteurs existants, afin de disposer dun retour dexpérience, et de bénéficier de leur retour. Toutefois, certains acteurs (le ministère des armées, ladministration autonome en Polynésie française, l'association Adullact) ont déployé des instances séparées. Nous proposons aux personnes intéressées de les mettre en relation avec ces acteurs existants, pour obtenir un retour dexpérience et bénéficier de leur retour.
## Bonnes pratiques de code ## Bonnes pratiques de code

View file

@ -28,7 +28,7 @@ Vous souhaitez y apporter des changements ou des améliorations ? Lisez notre [
- Chrome - Chrome
- chromedriver : - chromedriver :
* Mac : `brew install chromedriver` * Mac : `brew install chromedriver`
* Linux : voir https://sites.google.com/a/chromium.org/chromedriver/downloads * Linux : voir https://developer.chrome.com/blog/chrome-for-testing
Si l'emplacement d'installation de Chrome n'est pas standard, ou que vous utilisez Brave ou Chromium à la place, Si l'emplacement d'installation de Chrome n'est pas standard, ou que vous utilisez Brave ou Chromium à la place,
il peut être nécessaire d'overrider pour votre machine le path vers le binaire Chrome, par exemple : il peut être nécessaire d'overrider pour votre machine le path vers le binaire Chrome, par exemple :
@ -42,8 +42,7 @@ Selenium::WebDriver::Chrome.path = "/Applications/Brave Browser.app/Contents/Mac
Webdrivers::Chromedriver.required_version = "103.0.5060.53" Webdrivers::Chromedriver.required_version = "103.0.5060.53"
``` ```
Il peut être également pertinent de désactiver la mise à jour automatique du webdriver Il est également possible de faire une installation et mise à jour automatique lors de l'exécution de `bin/update` en définissant la variable d'environnement `UPDATE_WEBDRIVER`. Les binaires seront installés dans le repertoire `~/.local/bin/` qui doit être rajouté manuellement dans le path.
en définissant une variable d'environnement `SKIP_UPDATE_WEBDRIVER` lors de l'exécution de `bin/update`.
### Création des rôles de la base de données ### Création des rôles de la base de données

View file

@ -49,7 +49,7 @@
} }
} }
:not(.fr-downloads-group) > ul { :not(.fr-downloads-group):not(.fr-pagination) > ul {
list-style-type: disc; list-style-type: disc;
list-style-position: inside; list-style-position: inside;
padding-left: $default-padding; padding-left: $default-padding;

View file

@ -18,6 +18,8 @@
= render partial: "shared/champs/carte/show", locals: { champ: champ } = render partial: "shared/champs/carte/show", locals: { champ: champ }
- when TypeDeChamp.type_champs.fetch(:dossier_link) - when TypeDeChamp.type_champs.fetch(:dossier_link)
= render partial: "shared/champs/dossier_link/show", locals: { champ: champ } = render partial: "shared/champs/dossier_link/show", locals: { champ: champ }
- when TypeDeChamp.type_champs.fetch(:drop_down_list)
= render partial: "shared/champs/drop_down_list/show", locals: { champ: champ }
- when TypeDeChamp.type_champs.fetch(:multiple_drop_down_list) - when TypeDeChamp.type_champs.fetch(:multiple_drop_down_list)
= render partial: "shared/champs/multiple_drop_down_list/show", locals: { champ: champ } = render partial: "shared/champs/multiple_drop_down_list/show", locals: { champ: champ }
- when TypeDeChamp.type_champs.fetch(:piece_justificative), TypeDeChamp.type_champs.fetch(:titre_identite) - when TypeDeChamp.type_champs.fetch(:piece_justificative), TypeDeChamp.type_champs.fetch(:titre_identite)

View file

@ -7,6 +7,7 @@ class Dsfr::InputComponent < ApplicationComponent
# use it to indicate detailed about the inputs, ex: https://www.systeme-de-design.gouv.fr/elements-d-interface/modeles-et-blocs-fonctionnels/demande-de-mot-de-passe # use it to indicate detailed about the inputs, ex: https://www.systeme-de-design.gouv.fr/elements-d-interface/modeles-et-blocs-fonctionnels/demande-de-mot-de-passe
# it uses aria-describedby on input and link it to yielded content # it uses aria-describedby on input and link it to yielded content
renders_one :describedby renders_one :describedby
renders_one :label
def initialize(form:, attribute:, input_type: :text_field, opts: {}, required: true) def initialize(form:, attribute:, input_type: :text_field, opts: {}, required: true)
@form = form @form = form
@ -46,7 +47,7 @@ class Dsfr::InputComponent < ApplicationComponent
# i18n lookups # i18n lookups
def label def label
object.class.human_attribute_name(@attribute) get_slot(:label).presence || default_label
end end
# kind of input helpers # kind of input helpers
@ -63,4 +64,8 @@ class Dsfr::InputComponent < ApplicationComponent
end end
private private
def default_label
object.class.human_attribute_name(@attribute)
end
end end

View file

@ -159,20 +159,13 @@ module Administrateurs
def update_state def update_state
@groupe_instructeur = procedure.groupe_instructeurs.find(params[:groupe_instructeur_id]) @groupe_instructeur = procedure.groupe_instructeurs.find(params[:groupe_instructeur_id])
if closed_params? && @groupe_instructeur.id == procedure.defaut_groupe_instructeur.id if @groupe_instructeur.update(closed: params[:closed])
redirect_to admin_procedure_groupe_instructeur_path(procedure, @groupe_instructeur),
alert: "Il est impossible de désactiver le groupe dinstructeurs par défaut."
elsif @groupe_instructeur.update(closed: params[:closed])
state_for_notice = @groupe_instructeur.closed ? 'désactivé' : 'activé' state_for_notice = @groupe_instructeur.closed ? 'désactivé' : 'activé'
redirect_to admin_procedure_groupe_instructeur_path(procedure, @groupe_instructeur), redirect_to admin_procedure_groupe_instructeur_path(procedure, @groupe_instructeur),
notice: "Le groupe #{@groupe_instructeur.label} est #{state_for_notice}." notice: "Le groupe #{@groupe_instructeur.label} est #{state_for_notice}."
else else
@procedure = procedure redirect_to admin_procedure_groupe_instructeur_path(procedure, @groupe_instructeur),
@instructeurs = paginated_instructeurs alert: @groupe_instructeur.errors.messages_for(:closed).to_sentence
@available_instructeur_emails = available_instructeur_emails
flash.now[:alert] = @groupe_instructeur.errors.full_messages
render :show
end end
end end

View file

@ -5,8 +5,9 @@ class Champs::OptionsController < ApplicationController
def remove def remove
champ = policy_scope(Champ).includes(:champs).find(params[:champ_id]) champ = policy_scope(Champ).includes(:champs).find(params[:champ_id])
champ.remove_option([params[:option]].compact) champ.remove_option([params[:option]].compact, true)
champs = champ.private? ? champ.dossier.champs_private_all : champ.dossier.champs_public_all champs = champ.private? ? champ.dossier.champs_private_all : champ.dossier.champs_public_all
@dossier = champ.private? ? nil : champ.dossier
@to_show, @to_hide, @to_update = champs_to_turbo_update({ params[:champ_id] => true }, champs) @to_show, @to_hide, @to_update = champs_to_turbo_update({ params[:champ_id] => true }, champs)
end end
end end

View file

@ -35,7 +35,7 @@ class RechercheController < ApplicationController
# to make it simpler we only do it if the @search_terms is an id # to make it simpler we only do it if the @search_terms is an id
return if !DossierSearchService.id_compatible?(@search_terms) return if !DossierSearchService.id_compatible?(@search_terms)
dossier_instructeur_searched_for = Dossier.find_by(id: @search_terms) dossier_instructeur_searched_for = Dossier.state_not_brouillon.find_by(id: @search_terms)
return if dossier_instructeur_searched_for.nil? return if dossier_instructeur_searched_for.nil?
return if current_instructeur&.groupe_instructeur_ids&.include?(dossier_instructeur_searched_for.groupe_instructeur_id) return if current_instructeur&.groupe_instructeur_ids&.include?(dossier_instructeur_searched_for.groupe_instructeur_id)

View file

@ -1348,6 +1348,11 @@ type Dossier {
""" """
datePassageEnInstruction: ISO8601DateTime datePassageEnInstruction: ISO8601DateTime
"""
Date prévisionnelle de décision automatique par le SVA/SVR.
"""
datePrevisionnelleDecisionSVASVR: ISO8601Date
""" """
Date de la suppression par ladministration. Date de la suppression par ladministration.
""" """
@ -1362,6 +1367,11 @@ type Dossier {
Date du dernier traitement. Date du dernier traitement.
""" """
dateTraitement: ISO8601DateTime dateTraitement: ISO8601DateTime
"""
Date du traitement automatique par le SVA/SVR.
"""
dateTraitementSVASVR: ISO8601DateTime
demandeur: Demandeur! demandeur: Demandeur!
demarche: DemarcheDescriptor! demarche: DemarcheDescriptor!

View file

@ -32,6 +32,9 @@ module Types
field :date_derniere_correction_en_attente, GraphQL::Types::ISO8601DateTime, "Date de la dernière demande de correction qui na pas encore été traitée par lusager.", null: true field :date_derniere_correction_en_attente, GraphQL::Types::ISO8601DateTime, "Date de la dernière demande de correction qui na pas encore été traitée par lusager.", null: true
field :date_previsionnelle_decision_sva_svr, GraphQL::Types::ISO8601Date, "Date prévisionnelle de décision automatique par le SVA/SVR.", null: true, method: :sva_svr_decision_on
field :date_traitement_sva_svr, GraphQL::Types::ISO8601DateTime, "Date du traitement automatique par le SVA/SVR.", null: true, method: :sva_svr_decision_triggered_at
field :archived, Boolean, null: false field :archived, Boolean, null: false
field :connection_usager, ConnectionUsager, null: false field :connection_usager, ConnectionUsager, null: false

View file

@ -84,7 +84,8 @@ export class AutoUpload {
return { return {
title: title:
'Le fichier na pas pu être envoyé. Vérifiez votre connexion à Internet, puis ré-essayez. Vérifiez aussi que le pare-feu de votre appareil ou votre réseau autorise lenvoi de fichier vers ' + 'Le fichier na pas pu être envoyé. Vérifiez votre connexion à Internet, puis ré-essayez. Vérifiez aussi que le pare-feu de votre appareil ou votre réseau autorise lenvoi de fichier vers ' +
window.location.host, window.location.host +
' et static.demarches-simplifiees.fr.',
retry: true retry: true
}; };
} else if (error.code == ERROR_CODE_READ) { } else if (error.code == ERROR_CODE_READ) {

View file

@ -62,6 +62,7 @@ class Champ < ApplicationRecord
delegate :to_typed_id, :to_typed_id_for_query, to: :type_de_champ, prefix: true delegate :to_typed_id, :to_typed_id_for_query, to: :type_de_champ, prefix: true
delegate :revision, to: :dossier, prefix: true delegate :revision, to: :dossier, prefix: true
delegate :used_by_routing_rules?, to: :type_de_champ
scope :updated_since?, -> (date) { where('champs.updated_at > ?', date) } scope :updated_since?, -> (date) { where('champs.updated_at > ?', date) }
scope :public_only, -> { where(private: false) } scope :public_only, -> { where(private: false) }

View file

@ -62,8 +62,12 @@ class Champs::DropDownListChamp < Champ
options.include?(value) options.include?(value)
end end
def remove_option(options) def remove_option(options, touch = false)
update_column(:value, nil) if touch
update(value: nil)
else
update_column(:value, nil)
end
end end
private private

View file

@ -70,8 +70,12 @@ class Champs::LinkedDropDownListChamp < Champ
options.include?(primary_value) || options.include?(secondary_value) options.include?(primary_value) || options.include?(secondary_value)
end end
def remove_option(options) def remove_option(options, touch = false)
update_column(:value, nil) if touch
update(value: nil)
else
update_column(:value, nil)
end
end end
private private

View file

@ -51,8 +51,13 @@ class Champs::MultipleDropDownListChamp < Champ
(selected_options - options).size != selected_options.size (selected_options - options).size != selected_options.size
end end
def remove_option(options) def remove_option(options, touch = false)
update_column(:value, (selected_options - options).to_json) value = (selected_options - options).to_json
if touch
update(value:)
else
update_columns(value:)
end
end end
def focusable_input_id def focusable_input_id

View file

@ -34,6 +34,7 @@ class Expert < ApplicationRecord
procedure_with_new, procedure_without_new = old_expert procedure_with_new, procedure_without_new = old_expert
.procedures .procedures
.with_discarded
.partition { |p| p.experts.exists?(id) } .partition { |p| p.experts.exists?(id) }
ExpertsProcedure ExpertsProcedure

View file

@ -16,13 +16,7 @@ class GroupeInstructeur < ApplicationRecord
validates :label, presence: true, allow_nil: false validates :label, presence: true, allow_nil: false
validates :label, uniqueness: { scope: :procedure } validates :label, uniqueness: { scope: :procedure }
validates :closed, acceptance: { accept: [false] }, if: -> do validates :closed, acceptance: { accept: [false] }, if: -> { (self == procedure.defaut_groupe_instructeur) }
if closed
(other_groupe_instructeurs.map(&:closed) + [closed]).all?
else
false
end
end
before_validation -> { label&.strip! } before_validation -> { label&.strip! }

View file

@ -7,7 +7,7 @@
= hidden_field_tag 'statuses[]', status, id: "status_#{status}" = hidden_field_tag 'statuses[]', status, id: "status_#{status}"
= hidden_field_tag 'from_publication_date', @filter.from_publication_date if @filter.from_publication_date.present? = hidden_field_tag 'from_publication_date', @filter.from_publication_date if @filter.from_publication_date.present?
= f.label 'email', 'Recercher des administrateurs par email', class: 'fr-label' = f.label 'email', 'Rechercher des administrateurs par email', class: 'fr-label'
= f.search_field 'email', size: 40, class: 'fr-input', data: { turbo_force: :server } = f.search_field 'email', size: 40, class: 'fr-input', data: { turbo_force: :server }
.actions= link_to 'Voir la liste des démarches', all_admin_procedures_path(@filter.params), class: 'fr-btn fr-btn--secondary' .actions= link_to 'Voir la liste des démarches', all_admin_procedures_path(@filter.params), class: 'fr-btn fr-btn--secondary'
.fr-table.fr-table--bordered .fr-table.fr-table--bordered

View file

@ -14,7 +14,7 @@
= link_to t('.citizen_page'), new_user_session_path, class: "fr-btn fr-btn--secondary" = link_to t('.citizen_page'), new_user_session_path, class: "fr-btn fr-btn--secondary"
.column .column
%h1.fr-my-2 %h1.fr-my-2w
= t('.connect') = t('.connect')
.fr-connect-group.fr-my-2w .fr-connect-group.fr-my-2w
@ -29,20 +29,30 @@
%p.fr-hr-or= t('views.shared.france_connect_login.separator') %p.fr-hr-or= t('views.shared.france_connect_login.separator')
#session-new.auth-form.sign-in-form #session-new.auth-form.sign-in-form
= form_for User.new, url: user_session_path, html: { class: "form" } do |f| = form_for User.new, url: user_session_path do |f|
= f.label :email, t('.pro_email')
= f.text_field :email, type: :email, autocomplete: 'username', autofocus: true
= f.label :password, t('views.users.sessions.new.password', min_length: PASSWORD_MIN_LENGTH) %fieldset.fr-mb-0.fr-fieldset{ aria: { labelledby: 'new-account-legend' } }
= f.password_field :password, autocomplete: 'current-password' %legend.fr-fieldset__legend#new-account-legend
%h2.fr-h6= I18n.t('views.users.sessions.new.subtitle')
.auth-options .fr-fieldset__element
.flex-no-shrink %p.fr-text--sm= t('utils.mandatory_champs')
= f.check_box :remember_me
= f.label :remember_me, t('views.users.sessions.new.remember_me'), class: 'remember-me' .fr-fieldset__element
= render Dsfr::InputComponent.new(form: f, attribute: :email, input_type: :email_field, opts: { autocomplete: 'email', autofocus: true }) do |c|
- c.with_label { t('.pro_email') }
.fr-fieldset__element
= render Dsfr::InputComponent.new(form: f, attribute: :password, input_type: :password_field, opts: { autocomplete: 'current-password' })
%p= link_to t('views.users.sessions.new.reset_password'), new_user_password_path, class: "link"
.fr-fieldset__element
.auth-options
.flex-no-shrink
= f.check_box :remember_me
= f.label :remember_me, t('views.users.sessions.new.remember_me'), class: 'remember-me'
.text-right
= link_to t('views.users.sessions.new.reset_password'), new_user_password_path, class: "link"
= f.submit t('views.users.sessions.new.connection'), class: "fr-btn fr-btn--lg" = f.submit t('views.users.sessions.new.connection'), class: "fr-btn fr-btn--lg"

View file

@ -1 +1 @@
= render partial: 'shared/dossiers/update_champs', locals: { to_show: @to_show, to_hide: @to_hide, to_update: @to_update } = render partial: 'shared/dossiers/update_champs', locals: { to_show: @to_show, to_hide: @to_hide, to_update: @to_update, dossier: @dossier }

View file

@ -3,17 +3,20 @@
- content_for :footer do - content_for :footer do
= render partial: 'root/footer' = render partial: 'root/footer'
.container.devise-container .fr-container.fr-my-5w
.one-column-centered .fr-grid-row.fr-grid-row--center
= devise_error_messages! .fr-col-lg-6
= devise_error_messages!
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { class: 'form' }) do |f| = form_for(resource, as: resource_name, url: password_path(resource_name)) do |f|
%fieldset.fr-mb-0.fr-fieldset{ aria: { labelledby: 'new-password-legend' } }
%legend.fr-fieldset__legend#new-password-legend
%h1.fr-h2= t('devise.passwords.new.forgot_your_password')
%h1= t('devise.passwords.new.forgot_your_password') .fr-fieldset__element
%p.fr-text--sm= t('devise.passwords.new.send_me_reset_password_instructions')
%p.notice= t('devise.passwords.new.send_me_reset_password_instructions') .fr-fieldset__element
= render Dsfr::InputComponent.new(form: f, attribute: :email, input_type: :email_field, opts: { autocomplete: 'email', autofocus: true })
= f.label :email, 'Email' = f.submit t('devise.passwords.new.request_new_password'), class: 'fr-btn fr-btn--lg fr-mt-4w'
= f.email_field :email, autofocus: true
= f.submit t('devise.passwords.new.request_new_password'), class: 'fr-btn fr-btn--lg'

View file

@ -1 +1 @@
= render partial: 'shared/dossiers/update_champs', locals: { to_show: @to_show, to_hide: @to_hide, to_update: @to_update } = render partial: 'shared/dossiers/update_champs', locals: { to_show: @to_show, to_hide: @to_hide, to_update: @to_update, dossier: nil }

View file

@ -0,0 +1,6 @@
- if champ.used_by_routing_rules? && champ.dossier.forced_groupe_instructeur
%p
%span= champ.value
%span.fr-badge.fr-badge--warning.fr-badge--sm dossier réaffecté au groupe « #{champ.dossier.groupe_instructeur.label} »
- else
%p= champ.value

View file

@ -13,3 +13,7 @@
= turbo_stream.remove_all(".editable-champ .spinner-removable") = turbo_stream.remove_all(".editable-champ .spinner-removable")
= turbo_stream.hide_all(".editable-champ .spinner") = turbo_stream.hide_all(".editable-champ .spinner")
- if dossier.present?
= turbo_stream.replace_all '.dossier-edit-sticky-footer' do
= render Dossiers::EditFooterComponent.new(dossier:, annotation: false)

View file

@ -1,20 +1,22 @@
.super-admin.flex.justify-center .fr-container.fr-my-5w
%div .fr-grid-row.fr-grid-row--center
%h2.huge-title Espace Manager .fr-col-lg-6
.auth-form.sign-in-form %h1.fr-h2 Espace Manager
= devise_error_messages!
= form_for SuperAdmin.new, url: super_admin_session_path, html: { class: "form" } do |f| = form_for SuperAdmin.new, url: super_admin_session_path do |f|
%h1.fr-h2 Connectez-vous %fieldset.fr-mb-0.fr-fieldset
.fr-fieldset__element
= render Dsfr::InputComponent.new(form: f, attribute: :email, input_type: :email_field, opts: { autocomplete: 'email', autofocus: true })
= f.label :email, "Email" .fr-fieldset__element
= f.text_field :email, type: :email, autocomplete: 'username', autofocus: true = render Dsfr::InputComponent.new(form: f, attribute: :password, input_type: :password_field, opts: { autocomplete: 'current-password' })
= f.label :password, "Mot de passe (#{PASSWORD_MIN_LENGTH} caractères minimum)" - if SUPER_ADMIN_OTP_ENABLED
= f.password_field :password, autocomplete: 'current-password' .fr-fieldset__element
= render Dsfr::InputComponent.new(form: f, attribute: :otp_attempt, input_type: :number_field, opts: { inputmode: :numeric }, required: false)
- if SUPER_ADMIN_OTP_ENABLED .fr-fieldset__element
= f.label :otp_attempt, 'Code OTP (uniquement si vous avez déjà activé 2FA)' %p= link_to "Mot de passe oublié ou réinitialisation 2FA ?", new_super_admin_password_path, class: "link"
= f.text_field :otp_attempt
%p= link_to "Mot de passe oublié ou réinitialisation 2FA ?", new_super_admin_password_path, class: "link" = f.submit t('views.users.sessions.new.connection'), class: "fr-btn fr-btn--lg"
= f.submit "Se connecter", class: "fr-btn fr-btn--lg"

View file

@ -1,4 +1 @@
= render partial: 'shared/dossiers/update_champs', locals: { to_show: @to_show, to_hide: @to_hide, to_update: @to_update, dossier: @dossier, annotation: false } = render partial: 'shared/dossiers/update_champs', locals: { to_show: @to_show, to_hide: @to_hide, to_update: @to_update, dossier: @dossier }
= turbo_stream.replace_all '.dossier-edit-sticky-footer' do
= render Dossiers::EditFooterComponent.new(dossier: @dossier, annotation: false)

View file

@ -19,11 +19,16 @@ FileUtils.chdir APP_ROOT do
system! 'bin/yarn install' system! 'bin/yarn install'
system! 'bin/yarn clean' system! 'bin/yarn clean'
if ENV["SKIP_UPDATE_WEBDRIVER"] if ENV["UPDATE_WEBDRIVER"]
puts "\n== Ignoring webdrivers update because of local configuration. You may need to update it manually.=="
else
puts "\n== Updating webdrivers ==" puts "\n== Updating webdrivers =="
system! 'RAILS_ENV=test bin/rails webdrivers:chromedriver:update' puts "\nyou must add ~/.local/bin to your path"
system! 'npx @puppeteer/browsers clear --path ~/.local/bin/headless_browsers'
system! 'npx @puppeteer/browsers install chromedriver --path ~/.local/bin/headless_browsers'
system! 'npx @puppeteer/browsers install chrome --path ~/.local/bin/headless_browsers'
system! 'rm -f ~/.local/bin/chromedriver && ln -s $(find ~/.local/bin/headless_browsers -type f -name chromedriver) ~/.local/bin/chromedriver'
system! 'rm -f ~/.local/bin/chrome && ln -s $(find ~/.local/bin/headless_browsers -type f -name chrome) ~/.local/bin/chrome'
end end
puts "\n== Updating database ==" puts "\n== Updating database =="

View file

@ -26,7 +26,7 @@ features = [
def database_exists? def database_exists?
ActiveRecord::Base.connection ActiveRecord::Base.connection
true true
rescue ActiveRecord::NoDatabaseError, PG::ConnectionBad rescue ActiveRecord::ConnectionNotEstablished, ActiveRecord::NoDatabaseError, PG::ConnectionBad
false false
end end

View file

@ -251,7 +251,7 @@ en:
pays_html: An <a href="https://en.wikipedia.org/wiki/ISO_3166-2" target="_blank" rel="noopener noreferrer">ISO 3166-2 country code</a> pays_html: An <a href="https://en.wikipedia.org/wiki/ISO_3166-2" target="_blank" rel="noopener noreferrer">ISO 3166-2 country code</a>
regions_html: An <a href="https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise" target="_blank" rel="noopener noreferrer">INSEE region code</a> regions_html: An <a href="https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise" target="_blank" rel="noopener noreferrer">INSEE region code</a>
departements_html: A <a href="https://fr.wikipedia.org/wiki/Num%C3%A9rotation_des_d%C3%A9partements_fran%C3%A7ais" target="_blank">department number</a> departements_html: A <a href="https://fr.wikipedia.org/wiki/Num%C3%A9rotation_des_d%C3%A9partements_fran%C3%A7ais" target="_blank">department number</a>
communes_html: An array of the department code and the <a href="https://geo.api.gouv.fr/communes" target="_blank" rel="noopener noreferrer">INSEE commune code</a> communes_html: An array of the postal code and the <a href="https://geo.api.gouv.fr/communes" target="_blank" rel="noopener noreferrer">INSEE commune code</a>
address_html: An address EXACTLY formated as the label returned by <a href="https://adresse.data.gouv.fr" target="_blank" rel="noopener noreferrer">the Base Adresse Nationale</a> address_html: An address EXACTLY formated as the label returned by <a href="https://adresse.data.gouv.fr" target="_blank" rel="noopener noreferrer">the Base Adresse Nationale</a>
drop_down_list_html: A choice among those selected when the procedure was created drop_down_list_html: A choice among those selected when the procedure was created
date_html: ISO8601 date date_html: ISO8601 date
@ -491,7 +491,6 @@ en:
sessions: sessions:
new: new:
sign_in: Sign in on %{application_name} sign_in: Sign in on %{application_name}
password: Password (minimum length %{min_length} characters)
remember_me: Remember me remember_me: Remember me
reset_password: Forgot password? reset_password: Forgot password?
connection: Sign in connection: Sign in
@ -548,6 +547,7 @@ en:
<< : *default_attributes << : *default_attributes
super_admin: super_admin:
<< : *default_attributes << : *default_attributes
otp_attempt: 'OTP code (only if you have already activated 2FA)'
procedure: procedure:
zone: This procedure is run by zone: This procedure is run by
champs: champs:

View file

@ -247,7 +247,7 @@ fr:
pays_html: Un <a href="https://en.wikipedia.org/wiki/ISO_3166-2" target="_blank" rel="noopener noreferrer">code pays ISO 3166-2</a> pays_html: Un <a href="https://en.wikipedia.org/wiki/ISO_3166-2" target="_blank" rel="noopener noreferrer">code pays ISO 3166-2</a>
regions_html: Un <a href="https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise" target="_blank" rel="noopener noreferrer">code INSEE de région</a> regions_html: Un <a href="https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise" target="_blank" rel="noopener noreferrer">code INSEE de région</a>
departements_html: Un <a href="https://fr.wikipedia.org/wiki/Num%C3%A9rotation_des_d%C3%A9partements_fran%C3%A7ais" target="_blank">numéro de département</a> departements_html: Un <a href="https://fr.wikipedia.org/wiki/Num%C3%A9rotation_des_d%C3%A9partements_fran%C3%A7ais" target="_blank">numéro de département</a>
communes_html: Un tableau contenant le code de département et <a href="https://geo.api.gouv.fr/communes" target="_blank" rel="noopener noreferrer">le code INSEE de la commune</a> communes_html: Un tableau contenant le code postal et <a href="https://geo.api.gouv.fr/communes" target="_blank" rel="noopener noreferrer">le code INSEE de la commune</a>
address_html: Une adresse EXACTEMENT formatée telle que le label retourné par <a href="https://adresse.data.gouv.fr" target="_blank" rel="noopener noreferrer">la Base Adresse Nationale</a> address_html: Une adresse EXACTEMENT formatée telle que le label retourné par <a href="https://adresse.data.gouv.fr" target="_blank" rel="noopener noreferrer">la Base Adresse Nationale</a>
drop_down_list_html: Un choix parmi ceux sélectionnés à la création de la procédure drop_down_list_html: Un choix parmi ceux sélectionnés à la création de la procédure
datetime_html: Datetime au format ISO8601 datetime_html: Datetime au format ISO8601
@ -494,7 +494,6 @@ fr:
sessions: sessions:
new: new:
sign_in: Connexion à %{application_name} sign_in: Connexion à %{application_name}
password: Mot de passe (%{min_length} caractères minimum)
remember_me: Se souvenir de moi remember_me: Se souvenir de moi
reset_password: Mot de passe oublié ? reset_password: Mot de passe oublié ?
connection: Se connecter connection: Se connecter
@ -552,6 +551,7 @@ fr:
<< : *default_attributes << : *default_attributes
super_admin: super_admin:
<< : *default_attributes << : *default_attributes
otp_attempt: 'Code OTP (uniquement si vous avez déjà activé 2FA)'
procedure: procedure:
zone: La démarche est mise en œuvre par zone: La démarche est mise en œuvre par
champs: champs:

View file

@ -15,4 +15,4 @@ fr:
format: "Le libellé %{message}" format: "Le libellé %{message}"
closed: closed:
format: "%{message}" format: "%{message}"
accepted: Il doit y avoir au moins un groupe dinstructeurs actif sur chaque démarche accepted: Il est impossible de désactiver le groupe dinstructeurs par défaut.

View file

@ -18,4 +18,4 @@ fr:
connect: Connectez-vous connect: Connectez-vous
signin_with: "Sidentifier avec" signin_with: "Sidentifier avec"
whats_agentconnect: 'Quʼest ce quʼAgentConnect ?' whats_agentconnect: 'Quʼest ce quʼAgentConnect ?'
pro_email: Email professionnel pro_email: Adresse électronique professionnelle

View file

@ -78,7 +78,7 @@
"postcss": "^8.4.23", "postcss": "^8.4.23",
"prettier": "^2.8.8", "prettier": "^2.8.8",
"typescript": "^5.0.4", "typescript": "^5.0.4",
"vite": "^4.3.0", "vite": "^4.3.9",
"vite-plugin-full-reload": "^1.0.5", "vite-plugin-full-reload": "^1.0.5",
"vite-plugin-ruby": "^3.2.2", "vite-plugin-ruby": "^3.2.2",
"vitest": "^0.31.0" "vitest": "^0.31.0"

View file

@ -639,9 +639,9 @@ describe API::V2::GraphqlController do
let(:variables) { { input: { groupeInstructeurId: dossier.groupe_instructeur.to_typed_id, closed: true } } } let(:variables) { { input: { groupeInstructeurId: dossier.groupe_instructeur.to_typed_id, closed: true } } }
context 'with multiple groupes' do context 'with multiple groupes' do
before do let!(:defaut_groupe_instructeur) { create(:groupe_instructeur, procedure: procedure) }
create(:groupe_instructeur, procedure: procedure)
end before { procedure.update(defaut_groupe_instructeur_id: defaut_groupe_instructeur.id) }
it { it {
expect(gql_errors).to be_nil expect(gql_errors).to be_nil
@ -656,10 +656,11 @@ describe API::V2::GraphqlController do
let(:types_de_champ_public) { [{ type: :drop_down_list }] } let(:types_de_champ_public) { [{ type: :drop_down_list }] }
let(:groupe_instructeur) { procedure.groupe_instructeurs.first } let(:groupe_instructeur) { procedure.groupe_instructeurs.first }
let(:routing_champ) { procedure.active_revision.types_de_champ.first } let(:routing_champ) { procedure.active_revision.types_de_champ.first }
let!(:defaut_groupe_instructeur) { create(:groupe_instructeur, procedure: procedure) }
before do before do
groupe_instructeur.update(routing_rule: ds_eq(champ_value(routing_champ.stable_id), constant(groupe_instructeur.label))) groupe_instructeur.update(routing_rule: ds_eq(champ_value(routing_champ.stable_id), constant(groupe_instructeur.label)))
create(:groupe_instructeur, procedure: procedure) procedure.update(defaut_groupe_instructeur_id: defaut_groupe_instructeur.id)
Flipper.enable(:groupe_instructeur_api_hack, procedure) Flipper.enable(:groupe_instructeur_api_hack, procedure)
end end
@ -675,7 +676,7 @@ describe API::V2::GraphqlController do
context 'validation error' do context 'validation error' do
it { it {
expect(gql_errors).to be_nil expect(gql_errors).to be_nil
expect(gql_data[:groupeInstructeurModifier][:errors].first[:message]).to eq('Il doit y avoir au moins un groupe dinstructeurs actif sur chaque démarche') expect(gql_data[:groupeInstructeurModifier][:errors].first[:message]).to eq('Il est impossible de désactiver le groupe dinstructeurs par défaut.')
} }
end end
end end

View file

@ -559,7 +559,7 @@ describe Experts::AvisController, type: :controller do
procedure_id:, procedure_id:,
email: avis.expert.email, email: avis.expert.email,
user: { user: {
password: 'my-s3cure-p4ssword' password: SECURE_PASSWORD
} }
} }
end end
@ -575,7 +575,7 @@ describe Experts::AvisController, type: :controller do
it 'saves the expert new password' do it 'saves the expert new password' do
subject subject
expect(expert.user.reload.valid_password?('my-s3cure-p4ssword')).to be true expect(expert.user.reload.valid_password?(SECURE_PASSWORD)).to be true
end end
it { is_expected.to redirect_to expert_all_avis_path } it { is_expected.to redirect_to expert_all_avis_path }
@ -586,7 +586,7 @@ describe Experts::AvisController, type: :controller do
it 'doesnt change the expert password' do it 'doesnt change the expert password' do
subject subject
expect(expert.user.reload.valid_password?('my-s3cure-p4ssword')).to be false expect(expert.user.reload.valid_password?(SECURE_PASSWORD)).to be false
end end
it { is_expected.to redirect_to new_user_session_url } it { is_expected.to redirect_to new_user_session_url }

View file

@ -197,7 +197,7 @@ describe FranceConnect::ParticulierController, type: :controller do
let(:fci) { FranceConnectInformation.create!(user_info) } let(:fci) { FranceConnectInformation.create!(user_info) }
let(:merge_token) { fci.create_merge_token! } let(:merge_token) { fci.create_merge_token! }
let(:email) { 'EXISTING_account@a.com ' } let(:email) { 'EXISTING_account@a.com ' }
let(:password) { 'my-s3cure-p4ssword' } let(:password) { SECURE_PASSWORD }
let(:format) { :turbo_stream } let(:format) { :turbo_stream }
subject { post :merge_with_existing_account, params: { merge_token: merge_token, email: email, password: password }, format: format } subject { post :merge_with_existing_account, params: { merge_token: merge_token, email: email, password: password }, format: format }

View file

@ -36,7 +36,7 @@ describe Manager::AdministrateursController, type: :controller do
describe 'POST #create' do describe 'POST #create' do
let(:email) { 'plop@plop.com' } let(:email) { 'plop@plop.com' }
let(:password) { 'my-s3cure-p4ssword' } let(:password) { SECURE_PASSWORD }
subject { post :create, params: { administrateur: { email: email } } } subject { post :create, params: { administrateur: { email: email } } }

View file

@ -78,6 +78,20 @@ describe RechercheController, type: :controller do
end end
end end
context 'when dossier is brouillon without groupe instructeur' do
let(:dossier2) { create(:dossier, :brouillon, procedure: procedure) }
let(:query) { dossier2.id }
before { dossier2.update(groupe_instructeur_id: nil) }
it { is_expected.to have_http_status(200) }
it 'does not return the dossier' do
subject
expect(assigns(:projected_dossiers).count).to eq(0)
expect(assigns(:dossier_not_in_instructor_group)).to eq(nil)
end
end
context 'when instructeur is attached to the procedure but is not in the instructor group of the dossier' do context 'when instructeur is attached to the procedure but is not in the instructor group of the dossier' do
let!(:gi_p1_1) { GroupeInstructeur.create(label: 'groupe 1', procedure: procedure) } let!(:gi_p1_1) { GroupeInstructeur.create(label: 'groupe 1', procedure: procedure) }
let!(:gi_p1_2) { GroupeInstructeur.create(label: 'groupe 2', procedure: procedure) } let!(:gi_p1_2) { GroupeInstructeur.create(label: 'groupe 2', procedure: procedure) }

View file

@ -1,6 +1,6 @@
describe Users::RegistrationsController, type: :controller do describe Users::RegistrationsController, type: :controller do
let(:email) { 'test@octo.com' } let(:email) { 'test@octo.com' }
let(:password) { 'my-s3cure-p4ssword' } let(:password) { SECURE_PASSWORD }
let(:user) { { email: email, password: password } } let(:user) { { email: email, password: password } }

View file

@ -1,6 +1,6 @@
describe Users::SessionsController, type: :controller do describe Users::SessionsController, type: :controller do
let(:email) { 'unique@plop.com' } let(:email) { 'unique@plop.com' }
let(:password) { 'my-s3cure-p4ssword' } let(:password) { SECURE_PASSWORD }
let(:loged_in_with_france_connect) { User.loged_in_with_france_connects.fetch(:particulier) } let(:loged_in_with_france_connect) { User.loged_in_with_france_connects.fetch(:particulier) }
let!(:user) { create(:user, email: email, password: password, loged_in_with_france_connect: loged_in_with_france_connect) } let!(:user) { create(:user, email: email, password: password, loged_in_with_france_connect: loged_in_with_france_connect) }

View file

@ -257,6 +257,28 @@ RSpec.describe Types::DossierType, type: :graphql do
} }
end end
describe 'dossier on sva procedure' do
let(:procedure) { create(:procedure, :sva) }
let(:query) { DOSSIER_WITH_SVA_QUERY }
let(:variables) { { number: dossier.id } }
context 'dossier en_instruction' do
let(:dossier) { create(:dossier, :en_instruction, procedure:, sva_svr_decision_on: 3.days.from_now.to_date) }
it {
expect(data[:dossier][:datePrevisionnelleDecisionSVASVR]).not_to be_nil
}
end
context 'dossier accepte' do
let(:dossier) { create(:dossier, :accepte, procedure:, sva_svr_decision_triggered_at: 24.hours.ago) }
it {
expect(data[:dossier][:dateTraitementSVASVR]).not_to be_nil
}
end
end
DOSSIER_QUERY = <<-GRAPHQL DOSSIER_QUERY = <<-GRAPHQL
query($number: Int!) { query($number: Int!) {
dossier(number: $number) { dossier(number: $number) {
@ -440,6 +462,15 @@ RSpec.describe Types::DossierType, type: :graphql do
} }
GRAPHQL GRAPHQL
DOSSIER_WITH_SVA_QUERY = <<-GRAPHQL
query($number: Int!) {
dossier(number: $number) {
datePrevisionnelleDecisionSVASVR
dateTraitementSVASVR
}
}
GRAPHQL
DOSSIER_WITH_SELECTED_CHAMP_QUERY = <<-GRAPHQL DOSSIER_WITH_SELECTED_CHAMP_QUERY = <<-GRAPHQL
query($number: Int!, $id: ID!) { query($number: Int!, $id: ID!) {
dossier(number: $number) { dossier(number: $number) {

View file

@ -38,6 +38,19 @@ RSpec.describe Expert, type: :model do
end end
end end
context 'when an old expert access a hidden procedure' do
let(:procedure) { create(:procedure, hidden_at: 1.month.ago) }
before do
procedure.experts << old_expert
subject
end
it 'transfers the access to the new expert' do
expect(procedure.reload.experts).to match_array(new_expert)
end
end
context 'when both expert access a procedure' do context 'when both expert access a procedure' do
let(:procedure) { create(:procedure) } let(:procedure) { create(:procedure) }

View file

@ -99,14 +99,15 @@ describe GroupeInstructeur, type: :model do
end end
describe "active group validations" do describe "active group validations" do
context "there is at least one active groupe instructeur" do let(:gi_active) { procedure.defaut_groupe_instructeur }
let(:gi_active) { procedure.defaut_groupe_instructeur } let(:gi_closed) { create(:groupe_instructeur, procedure:) }
let(:gi_closed) { create(:groupe_instructeur, procedure:) }
before do
gi_active
gi_closed.update(closed: true)
end
before do
gi_active
gi_closed.update(closed: true)
end
context "there is one active groupe instructeur" do
it "closed is valid when there is one other active groupe" do it "closed is valid when there is one other active groupe" do
expect(gi_active).to be_valid expect(gi_active).to be_valid
expect(gi_closed).to be_valid expect(gi_closed).to be_valid
@ -117,6 +118,15 @@ describe GroupeInstructeur, type: :model do
expect(gi_active).not_to be_valid expect(gi_active).not_to be_valid
end end
end end
context "there are many active groupes instructeurs" do
let!(:second_gi_active) { create(:groupe_instructeur, procedure:) }
it "closed is invalid for defaut groupe instructeur even if many active groupes" do
gi_active.update(closed: true)
expect(gi_active).not_to be_valid
end
end
end end
private private

View file

@ -6,7 +6,7 @@ describe User, type: :model do
let(:user) do let(:user) do
create(:user, create(:user,
email: email, email: email,
password: 'my-s3cure-p4ssword', password: SECURE_PASSWORD,
confirmation_token: '123', confirmation_token: '123',
confirmed_at: nil) confirmed_at: nil)
end end
@ -125,11 +125,11 @@ describe User, type: :model do
end end
context 'with an existing user' do context 'with an existing user' do
before { create(:user, email: email, password: 'my-s3cure-p4ssword') } before { create(:user, email: email, password: SECURE_PASSWORD) }
it 'keeps the previous password' do it 'keeps the previous password' do
user = subject user = subject
expect(user.valid_password?('my-s3cure-p4ssword')).to be true expect(user.valid_password?(SECURE_PASSWORD)).to be true
expect(user.instructeur).to be_present expect(user.instructeur).to be_present
end end
@ -189,11 +189,11 @@ describe User, type: :model do
end end
context 'with an existing user' do context 'with an existing user' do
before { create(:user, email: email, password: 'my-s3cure-p4ssword') } before { create(:user, email: email, password: SECURE_PASSWORD) }
it 'keeps the previous password' do it 'keeps the previous password' do
user = subject user = subject
expect(user.valid_password?('my-s3cure-p4ssword')).to be true expect(user.valid_password?(SECURE_PASSWORD)).to be true
expect(user.expert).to be_present expect(user.expert).to be_present
end end

View file

@ -18,6 +18,8 @@
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
require 'rspec/retry' require 'rspec/retry'
SECURE_PASSWORD = 'my-s3cure-p4ssword'
RSpec.configure do |config| RSpec.configure do |config|
config.filter_run_excluding disable: true config.filter_run_excluding disable: true
config.color = true config.color = true

View file

@ -34,7 +34,7 @@ module SystemHelpers
end end
end end
def sign_up_with(email, password = 'my-s3cure-p4ssword') def sign_up_with(email, password = SECURE_PASSWORD)
fill_in :user_email, with: email fill_in :user_email, with: email
fill_in :user_password, with: password fill_in :user_password, with: password

View file

@ -1,4 +1,4 @@
describe 'wcag rules for usager', js: true do describe 'wcag rules for usager', js: true, retry: 3 do
let(:procedure) { create(:procedure, :published, :with_all_champs, :with_service, :for_individual) } let(:procedure) { create(:procedure, :published, :with_all_champs, :with_service, :for_individual) }
let(:password) { 'a very complicated password' } let(:password) { 'a very complicated password' }
let(:litteraire_user) { create(:user, password: password) } let(:litteraire_user) { create(:user, password: password) }

View file

@ -1,4 +1,4 @@
describe 'As an administrateur', js: true do describe 'As an administrateur', js: true, retry: 3 do
let(:super_admin) { create(:super_admin) } let(:super_admin) { create(:super_admin) }
let(:admin_email) { 'new_admin@gouv.fr' } let(:admin_email) { 'new_admin@gouv.fr' }
let(:new_admin) { Administrateur.by_email(admin_email) } let(:new_admin) { Administrateur.by_email(admin_email) }
@ -15,7 +15,7 @@ describe 'As an administrateur', js: true do
end end
end end
scenario 'I can register', js: true do scenario 'I can register', js: true, retry: 3 do
expect(new_admin.reload.user.active?).to be(false) expect(new_admin.reload.user.active?).to be(false)
confirmation_email = open_email(admin_email) confirmation_email = open_email(admin_email)

View file

@ -1,4 +1,4 @@
describe 'As an administrateur I can edit annotation', js: true do describe 'As an administrateur I can edit annotation', js: true, retry: 3 do
let(:administrateur) { procedure.administrateurs.first } let(:administrateur) { procedure.administrateurs.first }
let(:procedure) { create(:procedure) } let(:procedure) { create(:procedure) }

View file

@ -1,4 +1,4 @@
describe 'As an administrateur I can edit types de champ condition', js: true do describe 'As an administrateur I can edit types de champ condition', js: true, retry: 3 do
include Logic include Logic
let(:administrateur) { procedure.administrateurs.first } let(:administrateur) { procedure.administrateurs.first }

View file

@ -1,6 +1,6 @@
require 'system/administrateurs/procedure_spec_helper' require 'system/administrateurs/procedure_spec_helper'
describe 'Administrateurs can manage administrateurs', js: true do describe 'Administrateurs can manage administrateurs', js: true, retry: 3 do
include ProcedureSpecHelper include ProcedureSpecHelper
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }

View file

@ -1,6 +1,6 @@
require 'system/administrateurs/procedure_spec_helper' require 'system/administrateurs/procedure_spec_helper'
describe 'Creating a new procedure', js: true do describe 'Creating a new procedure', js: true, retry: 3 do
include ProcedureSpecHelper include ProcedureSpecHelper
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }

View file

@ -1,6 +1,6 @@
require 'system/administrateurs/procedure_spec_helper' require 'system/administrateurs/procedure_spec_helper'
describe 'As an administrateur, I want to manage the procedures attestation', js: true do describe 'As an administrateur, I want to manage the procedures attestation', js: true, retry: 3 do
include ProcedureSpecHelper include ProcedureSpecHelper
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }

View file

@ -1,6 +1,6 @@
require 'system/administrateurs/procedure_spec_helper' require 'system/administrateurs/procedure_spec_helper'
describe 'As an administrateur I wanna clone a procedure', js: true do describe 'As an administrateur I wanna clone a procedure', js: true, retry: 3 do
include ProcedureSpecHelper include ProcedureSpecHelper
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }

View file

@ -1,6 +1,6 @@
require 'system/administrateurs/procedure_spec_helper' require 'system/administrateurs/procedure_spec_helper'
describe 'Creating a new procedure', js: true do describe 'Creating a new procedure', js: true, retry: 3 do
include ProcedureSpecHelper include ProcedureSpecHelper
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }

View file

@ -1,6 +1,6 @@
require 'system/administrateurs/procedure_spec_helper' require 'system/administrateurs/procedure_spec_helper'
describe 'Manage procedure instructeurs', js: true do describe 'Manage procedure instructeurs', js: true, retry: 3 do
include ProcedureSpecHelper include ProcedureSpecHelper
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }

View file

@ -1,6 +1,6 @@
require 'system/administrateurs/procedure_spec_helper' require 'system/administrateurs/procedure_spec_helper'
describe 'Publishing a procedure', js: true do describe 'Publishing a procedure', js: true, retry: 3 do
include ProcedureSpecHelper include ProcedureSpecHelper
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }

View file

@ -1,6 +1,6 @@
require 'system/administrateurs/procedure_spec_helper' require 'system/administrateurs/procedure_spec_helper'
describe 'Administrateurs can edit procedures', js: true do describe 'Administrateurs can edit procedures', js: true, retry: 3 do
include ProcedureSpecHelper include ProcedureSpecHelper
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }

View file

@ -1,4 +1,4 @@
describe 'As an administrateur I can edit types de champ', js: true do describe 'As an administrateur I can edit types de champ', js: true, retry: 3 do
include ActionView::RecordIdentifier include ActionView::RecordIdentifier
let(:administrateur) { procedure.administrateurs.first } let(:administrateur) { procedure.administrateurs.first }

View file

@ -1,4 +1,4 @@
describe 'fetch API Particulier Data', js: true do describe 'fetch API Particulier Data', js: true, retry: 3 do
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }
let(:expected_token) { 'd7e9c9f4c3ca00caadde31f50fd4521a' } let(:expected_token) { 'd7e9c9f4c3ca00caadde31f50fd4521a' }

View file

@ -130,7 +130,7 @@ describe 'Inviting an expert:' do
# scenario 'I can invite other experts' do # scenario 'I can invite other experts' do
# end # end
context 'with dossiers having attached files', js: true do context 'with dossiers having attached files', js: true, retry: 3 do
let(:path) { 'spec/fixtures/files/piece_justificative_0.pdf' } let(:path) { 'spec/fixtures/files/piece_justificative_0.pdf' }
let(:commentaire) { create(:commentaire, instructeur: instructeur, dossier: dossier) } let(:commentaire) { create(:commentaire, instructeur: instructeur, dossier: dossier) }

View file

@ -47,7 +47,7 @@ describe 'France Connect Particulier Connexion' do
end end
context 'and an user exists with the same email' do context 'and an user exists with the same email' do
let!(:user) { create(:user, email: email, password: 'my-s3cure-p4ssword') } let!(:user) { create(:user, email: email, password: SECURE_PASSWORD) }
before do before do
page.find('.fr-connect').click page.find('.fr-connect').click
@ -59,7 +59,7 @@ describe 'France Connect Particulier Connexion' do
scenario 'it merges its account' do scenario 'it merges its account' do
page.find('#it-is-mine').click page.find('#it-is-mine').click
fill_in 'password', with: 'my-s3cure-p4ssword' fill_in 'password', with: SECURE_PASSWORD
click_on 'Fusionner les comptes' click_on 'Fusionner les comptes'
expect(page).to have_content('Dossiers') expect(page).to have_content('Dossiers')
@ -73,8 +73,8 @@ describe 'France Connect Particulier Connexion' do
expect(page).to have_content('Dossiers') expect(page).to have_content('Dossiers')
end end
context 'and the user wants an email that belongs to another account', js: true do context 'and the user wants an email that belongs to another account', js: true, retry: 3 do
let!(:another_user) { create(:user, email: 'an_existing_email@a.com', password: 'my-s3cure-p4ssword') } let!(:another_user) { create(:user, email: 'an_existing_email@a.com', password: SECURE_PASSWORD) }
scenario 'it uses another email that belongs to another account' do scenario 'it uses another email that belongs to another account' do
page.find('#it-is-not-mine').click page.find('#it-is-not-mine').click
@ -84,7 +84,7 @@ describe 'France Connect Particulier Connexion' do
expect(page).to have_css('#password-for-another-account', visible: true) expect(page).to have_css('#password-for-another-account', visible: true)
within '#new-account-password-confirmation' do within '#new-account-password-confirmation' do
fill_in 'password', with: 'my-s3cure-p4ssword' fill_in 'password', with: SECURE_PASSWORD
click_on 'Fusionner les comptes' click_on 'Fusionner les comptes'
end end

View file

@ -1,4 +1,4 @@
describe 'BatchOperation a dossier:', js: true do describe 'BatchOperation a dossier:', js: true, retry: 3 do
include ActionView::RecordIdentifier include ActionView::RecordIdentifier
include ActiveJob::TestHelper include ActiveJob::TestHelper

View file

@ -1,8 +1,8 @@
describe 'Inviting an expert:', js: true do describe 'Inviting an expert:', js: true, retry: 3 do
include ActiveJob::TestHelper include ActiveJob::TestHelper
include ActionView::Helpers include ActionView::Helpers
let(:instructeur) { create(:instructeur, password: 'my-s3cure-p4ssword') } let(:instructeur) { create(:instructeur, password: SECURE_PASSWORD) }
let(:expert) { create(:expert, password: expert_password) } let(:expert) { create(:expert, password: expert_password) }
let(:expert2) { create(:expert, password: expert_password) } let(:expert2) { create(:expert, password: expert_password) }
let(:expert_password) { 'mot de passe dexpert' } let(:expert_password) { 'mot de passe dexpert' }

View file

@ -1,4 +1,4 @@
describe 'As an instructeur', js: true do describe 'As an instructeur', js: true, retry: 3 do
let(:administrateur) { create(:administrateur, :with_procedure) } let(:administrateur) { create(:administrateur, :with_procedure) }
let(:procedure) { administrateur.procedures.first } let(:procedure) { administrateur.procedures.first }
let(:instructeur_email) { 'new_instructeur@gouv.fr' } let(:instructeur_email) { 'new_instructeur@gouv.fr' }
@ -20,7 +20,7 @@ describe 'As an instructeur', js: true do
token_params = confirmation_email.body.match(/token=[^"]+/) token_params = confirmation_email.body.match(/token=[^"]+/)
visit "users/activate?#{token_params}" visit "users/activate?#{token_params}"
fill_in :user_password, with: 'my-s3cure-p4ssword' fill_in :user_password, with: SECURE_PASSWORD
click_button 'Définir le mot de passe' click_button 'Définir le mot de passe'

View file

@ -1,7 +1,7 @@
describe 'Instructing a dossier:', js: true do describe 'Instructing a dossier:', js: true, retry: 3 do
include ActiveJob::TestHelper include ActiveJob::TestHelper
let(:password) { 'my-s3cure-p4ssword' } let(:password) { SECURE_PASSWORD }
let!(:instructeur) { create(:instructeur, password: password) } let!(:instructeur) { create(:instructeur, password: password) }
let!(:procedure) { create(:procedure, :with_type_de_champ, :published, instructeurs: [instructeur]) } let!(:procedure) { create(:procedure, :with_type_de_champ, :published, instructeurs: [instructeur]) }
@ -157,7 +157,7 @@ describe 'Instructing a dossier:', js: true do
expect(page).to have_text(instructeur2.email) expect(page).to have_text(instructeur2.email)
end end
scenario 'A instructeur can send a dossier to several instructeurs', js: true do scenario 'A instructeur can send a dossier to several instructeurs', js: true, retry: 3 do
instructeur_2 = create(:instructeur) instructeur_2 = create(:instructeur)
instructeur_3 = create(:instructeur) instructeur_3 = create(:instructeur)
procedure.defaut_groupe_instructeur.instructeurs << [instructeur_2, instructeur_3] procedure.defaut_groupe_instructeur.instructeurs << [instructeur_2, instructeur_3]
@ -195,7 +195,7 @@ describe 'Instructing a dossier:', js: true do
expect(Archive.first.month).not_to be_nil expect(Archive.first.month).not_to be_nil
end end
end end
context 'with dossiers having attached files', js: true do context 'with dossiers having attached files', js: true, retry: 3 do
let(:procedure) { create(:procedure, :published, :with_piece_justificative, instructeurs: [instructeur]) } let(:procedure) { create(:procedure, :published, :with_piece_justificative, instructeurs: [instructeur]) }
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) } let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
let(:champ) { dossier.champs_public.first } let(:champ) { dossier.champs_public.first }

View file

@ -40,7 +40,7 @@ describe "procedure filters" do
end end
end end
scenario "should add be able to add created_at column", js: true do scenario "should add be able to add created_at column", js: true, retry: 3 do
add_column("Créé le") add_column("Créé le")
within ".dossiers-table" do within ".dossiers-table" do
expect(page).to have_link("Créé le") expect(page).to have_link("Créé le")
@ -48,7 +48,7 @@ describe "procedure filters" do
end end
end end
scenario "should add be able to add and remove custom type_de_champ column", js: true do scenario "should add be able to add and remove custom type_de_champ column", js: true, retry: 3 do
add_column(type_de_champ.libelle) add_column(type_de_champ.libelle)
within ".dossiers-table" do within ".dossiers-table" do
expect(page).to have_link(type_de_champ.libelle) expect(page).to have_link(type_de_champ.libelle)
@ -62,7 +62,7 @@ describe "procedure filters" do
end end
end end
scenario "should be able to add and remove filter", js: true do scenario "should be able to add and remove filter", js: true, retry: 3 do
add_filter(type_de_champ.libelle, champ.value) add_filter(type_de_champ.libelle, champ.value)
expect(page).to have_content("#{type_de_champ.libelle} : #{champ.value}") expect(page).to have_content("#{type_de_champ.libelle} : #{champ.value}")
@ -86,7 +86,7 @@ describe "procedure filters" do
end end
end end
scenario "should be able to user custom fiters", js: true do scenario "should be able to user custom fiters", js: true, retry: 3 do
# use date filter # use date filter
click_on 'Sélectionner un filtre' click_on 'Sélectionner un filtre'
select "En construction le", from: "Colonne" select "En construction le", from: "Colonne"
@ -104,7 +104,7 @@ describe "procedure filters" do
end end
describe 'with a vcr cached cassette' do describe 'with a vcr cached cassette' do
scenario "should be able to find by departements with custom enum lookup", js: true do scenario "should be able to find by departements with custom enum lookup", js: true, retry: 3 do
departement_champ = new_unfollow_dossier.champs.find(&:departement?) departement_champ = new_unfollow_dossier.champs.find(&:departement?)
departement_champ.update!(value: 'Oise', external_id: '60') departement_champ.update!(value: 'Oise', external_id: '60')
departement_champ.reload departement_champ.reload
@ -119,7 +119,7 @@ describe "procedure filters" do
expect(page).to have_link(new_unfollow_dossier.id.to_s) expect(page).to have_link(new_unfollow_dossier.id.to_s)
end end
scenario "should be able to find by region with custom enum lookup", js: true do scenario "should be able to find by region with custom enum lookup", js: true, retry: 3 do
region_champ = new_unfollow_dossier.champs.find(&:region?) region_champ = new_unfollow_dossier.champs.find(&:region?)
region_champ.update!(value: 'Bretagne', external_id: '53') region_champ.update!(value: 'Bretagne', external_id: '53')
region_champ.reload region_champ.reload
@ -134,7 +134,7 @@ describe "procedure filters" do
end end
end end
scenario "should be able to add and remove two filters for the same field", js: true do scenario "should be able to add and remove two filters for the same field", js: true, retry: 3 do
add_filter(type_de_champ.libelle, champ.value) add_filter(type_de_champ.libelle, champ.value)
add_filter(type_de_champ.libelle, champ_2.value) add_filter(type_de_champ.libelle, champ_2.value)
add_enum_filter('Groupe instructeur', procedure.groupe_instructeurs.first.label) add_enum_filter('Groupe instructeur', procedure.groupe_instructeurs.first.label)

View file

@ -1,4 +1,4 @@
describe "procedure sort", js: true do describe "procedure sort", js: true, retry: 3 do
let(:instructeur) { create(:instructeur) } let(:instructeur) { create(:instructeur) }
let(:procedure) { create(:procedure, :published, :with_type_de_champ, instructeurs: [instructeur]) } let(:procedure) { create(:procedure, :published, :with_type_de_champ, instructeurs: [instructeur]) }
let!(:new_unfollow_dossier) { create(:dossier, procedure: procedure, state: Dossier.states.fetch(:en_instruction)) } let!(:new_unfollow_dossier) { create(:dossier, procedure: procedure, state: Dossier.states.fetch(:en_instruction)) }

View file

@ -1,4 +1,4 @@
describe 'As an integrator:', js: true do describe 'As an integrator:', js: true, retry: 3 do
let(:procedure) { create(:procedure, :published, opendata: true) } let(:procedure) { create(:procedure, :published, opendata: true) }
let!(:type_de_champ) { create(:type_de_champ_text, procedure: procedure) } let!(:type_de_champ) { create(:type_de_champ_text, procedure: procedure) }

View file

@ -1,4 +1,4 @@
describe 'The routing with rules', js: true do describe 'The routing with rules', js: true, retry: 3 do
let(:password) { 'a very complicated password' } let(:password) { 'a very complicated password' }
let(:procedure) do let(:procedure) do

View file

@ -1,6 +1,6 @@
describe 'Signin in:' do describe 'Signin in:' do
let!(:user) { create(:user, password: password) } let!(:user) { create(:user, password: password) }
let(:password) { 'my-s3cure-p4ssword' } let(:password) { SECURE_PASSWORD }
scenario 'an existing user can sign-in' do scenario 'an existing user can sign-in' do
visit root_path visit root_path

View file

@ -1,5 +1,5 @@
describe 'The user' do describe 'The user' do
let(:password) { 'my-s3cure-p4ssword' } let(:password) { SECURE_PASSWORD }
let!(:user) { create(:user, password: password) } let!(:user) { create(:user, password: password) }
let!(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs_mandatory) } let!(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs_mandatory) }
@ -104,7 +104,7 @@ describe 'The user' do
expect(page).to have_text('Analyse antivirus en cours') expect(page).to have_text('Analyse antivirus en cours')
end end
scenario 'fill nothing and every error anchor links points to an existing element', js: true do scenario 'fill nothing and every error anchor links points to an existing element', js: true, retry: 3 do
log_in(user, procedure) log_in(user, procedure)
fill_individual fill_individual
click_on 'Déposer le dossier' click_on 'Déposer le dossier'
@ -120,7 +120,7 @@ describe 'The user' do
create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :repetition, mandatory: true, children: [{ libelle: 'sub type de champ' }] }]) create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :repetition, mandatory: true, children: [{ libelle: 'sub type de champ' }] }])
end end
scenario 'fill a dossier with repetition', js: true do scenario 'fill a dossier with repetition', js: true, retry: 3 do
log_in(user, procedure_with_repetition) log_in(user, procedure_with_repetition)
fill_individual fill_individual
@ -146,7 +146,7 @@ describe 'The user' do
let(:simple_procedure) { create(:procedure, :published, :for_individual, types_de_champ_public: [{ mandatory: true, libelle: 'texte obligatoire' }, { mandatory: false, libelle: 'texte optionnel' }]) } let(:simple_procedure) { create(:procedure, :published, :for_individual, types_de_champ_public: [{ mandatory: true, libelle: 'texte obligatoire' }, { mandatory: false, libelle: 'texte optionnel' }]) }
scenario 'save an incomplete dossier as draft but cannot not submit it', js: true do scenario 'save an incomplete dossier as draft but cannot not submit it', js: true, retry: 3 do
log_in(user, simple_procedure) log_in(user, simple_procedure)
fill_individual fill_individual
@ -163,7 +163,6 @@ describe 'The user' do
# Check a dossier can be submitted when all mandatory fields are filled # Check a dossier can be submitted when all mandatory fields are filled
fill_in('texte obligatoire', with: 'super texte') fill_in('texte obligatoire', with: 'super texte')
wait_for_autosave
click_on 'Déposer le dossier' click_on 'Déposer le dossier'
wait_until { user_dossier.reload.en_construction? } wait_until { user_dossier.reload.en_construction? }
@ -171,7 +170,7 @@ describe 'The user' do
expect(page).to have_current_path(merci_dossier_path(user_dossier)) expect(page).to have_current_path(merci_dossier_path(user_dossier))
end end
scenario 'extends dossier experation date more than one time, ', js: true do scenario 'extends dossier experation date more than one time, ', js: true, retry: 3 do
simple_procedure.update(procedure_expires_when_termine_enabled: true) simple_procedure.update(procedure_expires_when_termine_enabled: true)
user_old_dossier = create(:dossier, user_old_dossier = create(:dossier,
procedure: simple_procedure, procedure: simple_procedure,
@ -196,7 +195,7 @@ describe 'The user' do
let(:procedure_with_pjs) { create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :piece_justificative, mandatory: true, libelle: 'Pièce justificative 1' }, { type: :piece_justificative, mandatory: true, libelle: 'Pièce justificative 2' }]) } let(:procedure_with_pjs) { create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :piece_justificative, mandatory: true, libelle: 'Pièce justificative 1' }, { type: :piece_justificative, mandatory: true, libelle: 'Pièce justificative 2' }]) }
let(:old_procedure_with_disabled_pj_validation) { create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :piece_justificative, mandatory: true, libelle: 'Pièce justificative 1', skip_pj_validation: true }]) } let(:old_procedure_with_disabled_pj_validation) { create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :piece_justificative, mandatory: true, libelle: 'Pièce justificative 1', skip_pj_validation: true }]) }
scenario 'add an attachment', js: true do scenario 'add an attachment', js: true, retry: 3 do
log_in(user, procedure_with_pjs) log_in(user, procedure_with_pjs)
fill_individual fill_individual
@ -220,7 +219,7 @@ describe 'The user' do
expect(page).to have_text('RIB.pdf') expect(page).to have_text('RIB.pdf')
end end
scenario 'add an invalid attachment on an old procedure where pj validation is disabled', js: true do scenario 'add an invalid attachment on an old procedure where pj validation is disabled', js: true, retry: 3 do
log_in(user, old_procedure_with_disabled_pj_validation) log_in(user, old_procedure_with_disabled_pj_validation)
fill_individual fill_individual
@ -230,7 +229,7 @@ describe 'The user' do
expect(page).to have_text('Analyse antivirus en cours', count: 1, wait: 5) expect(page).to have_text('Analyse antivirus en cours', count: 1, wait: 5)
end end
scenario 'retry on transcient upload error', js: true do scenario 'retry on transcient upload error', js: true, retry: 3 do
log_in(user, procedure_with_pjs) log_in(user, procedure_with_pjs)
fill_individual fill_individual
@ -259,7 +258,7 @@ describe 'The user' do
expect(page).to have_text('file.pdf') expect(page).to have_text('file.pdf')
end end
scenario "upload multiple pieces justificatives on same champ", js: true do scenario "upload multiple pieces justificatives on same champ", js: true, retry: 3 do
log_in(user, procedure_with_pjs) log_in(user, procedure_with_pjs)
fill_individual fill_individual
@ -324,7 +323,7 @@ describe 'The user' do
]) ])
end end
scenario 'submit a dossier with an hidden mandatory champ within a repetition', js: true do scenario 'submit a dossier with an hidden mandatory champ within a repetition', js: true, retry: 3 do
log_in(user, procedure) log_in(user, procedure)
fill_individual fill_individual
@ -354,7 +353,7 @@ describe 'The user' do
]) ])
end end
scenario 'fill a dossier', js: true do scenario 'fill a dossier', js: true, retry: 3 do
log_in(user, procedure) log_in(user, procedure)
fill_individual fill_individual
@ -386,7 +385,7 @@ describe 'The user' do
]) ])
end end
scenario 'submit a dossier with an hidden mandatory champ ', js: true do scenario 'submit a dossier with an hidden mandatory champ ', js: true, retry: 3 do
log_in(user, procedure) log_in(user, procedure)
fill_individual fill_individual
@ -395,7 +394,7 @@ describe 'The user' do
expect(page).to have_current_path(merci_dossier_path(user_dossier)) expect(page).to have_current_path(merci_dossier_path(user_dossier))
end end
scenario 'cannot submit a reveal dossier with a revealed mandatory champ ', js: true do scenario 'cannot submit a reveal dossier with a revealed mandatory champ ', js: true, retry: 3 do
log_in(user, procedure) log_in(user, procedure)
fill_individual fill_individual
@ -427,7 +426,7 @@ describe 'The user' do
]) ])
end end
scenario 'fill a dossier', js: true do scenario 'fill a dossier', js: true, retry: 3 do
log_in(user, procedure) log_in(user, procedure)
fill_individual fill_individual
@ -476,7 +475,7 @@ describe 'The user' do
end end
context 'draft autosave' do context 'draft autosave' do
scenario 'autosave a draft', js: true do scenario 'autosave a draft', js: true, retry: 3 do
log_in(user, simple_procedure) log_in(user, simple_procedure)
fill_individual fill_individual
@ -491,7 +490,7 @@ describe 'The user' do
expect(page).to have_field('texte obligatoire', with: 'a valid user input') expect(page).to have_field('texte obligatoire', with: 'a valid user input')
end end
scenario 'retry on autosave error', :capybara_ignore_server_errors, js: true do scenario 'retry on autosave error', :capybara_ignore_server_errors, js: true, retry: 3 do
log_in(user, simple_procedure) log_in(user, simple_procedure)
fill_individual fill_individual
@ -511,7 +510,7 @@ describe 'The user' do
expect(page).to have_field('texte obligatoire', with: 'a valid user input') expect(page).to have_field('texte obligatoire', with: 'a valid user input')
end end
scenario 'autosave redirects to sign-in after being disconnected', js: true do scenario 'autosave redirects to sign-in after being disconnected', js: true, retry: 3 do
log_in(user, simple_procedure) log_in(user, simple_procedure)
fill_individual fill_individual

View file

@ -48,7 +48,7 @@ describe 'Dossier details:' do
expect(page).to have_current_path(dossier_path(dossier)) expect(page).to have_current_path(dossier_path(dossier))
end end
context 'with js', js: true do context 'with js', js: true, retry: 3 do
it_behaves_like 'the user can edit the submitted demande' it_behaves_like 'the user can edit the submitted demande'
it_behaves_like 'the user can send messages to the instructeur' it_behaves_like 'the user can send messages to the instructeur'
end end

View file

@ -1,5 +1,5 @@
describe 'Prefilling a dossier (with a GET request):', js: true do describe 'Prefilling a dossier (with a GET request):', js: true, retry: 3 do
let(:password) { 'my-s3cure-p4ssword' } let(:password) { SECURE_PASSWORD }
let(:procedure) { create(:procedure, :published, opendata: true) } let(:procedure) { create(:procedure, :published, opendata: true) }
let(:dossier) { procedure.dossiers.last } let(:dossier) { procedure.dossiers.last }

View file

@ -1,5 +1,5 @@
describe 'Prefilling a dossier (with a POST request):', js: true do describe 'Prefilling a dossier (with a POST request):', js: true, retry: 3 do
let(:password) { 'my-s3cure-p4ssword' } let(:password) { SECURE_PASSWORD }
let(:procedure) { create(:procedure, :published) } let(:procedure) { create(:procedure, :published) }
let(:dossier) { procedure.dossiers.last } let(:dossier) { procedure.dossiers.last }

View file

@ -1,5 +1,5 @@
describe 'dropdown list with other option activated', js: true do describe 'dropdown list with other option activated', js: true, retry: 3 do
let(:password) { 'my-s3cure-p4ssword' } let(:password) { SECURE_PASSWORD }
let!(:user) { create(:user, password: password) } let!(:user) { create(:user, password: password) }
let(:procedure) { create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :drop_down_list, libelle: 'simple dropdown other', options: options + [:other] }]) } let(:procedure) { create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :drop_down_list, libelle: 'simple dropdown other', options: options + [:other] }]) }
@ -20,14 +20,14 @@ describe 'dropdown list with other option activated', js: true do
] ]
end end
scenario 'Select other option and the other input hidden must appear', js: true do scenario 'Select other option and the other input hidden must appear', js: true, retry: 3 do
fill_individual fill_individual
find('.radios').find('label:last-child').find('input').select_option find('.radios').find('label:last-child').find('input').select_option
expect(page).to have_selector('.drop_down_other', visible: true) expect(page).to have_selector('.drop_down_other', visible: true)
end end
scenario "Getting back from other save the new option", js: true do scenario "Getting back from other save the new option", js: true, retry: 3 do
fill_individual fill_individual
choose "Autre" choose "Autre"

View file

@ -11,7 +11,7 @@ describe "Dossier en_construction" do
dossier.find_editing_fork(dossier.user).champs_public.find { _1.type_de_champ_id == tdc.id } dossier.find_editing_fork(dossier.user).champs_public.find { _1.type_de_champ_id == tdc.id }
} }
scenario 'delete a non mandatory piece justificative', js: true do scenario 'delete a non mandatory piece justificative', js: true, retry: 3 do
visit_dossier(dossier) visit_dossier(dossier)
expect(page).not_to have_button("Remplacer") expect(page).not_to have_button("Remplacer")
@ -26,7 +26,7 @@ describe "Dossier en_construction" do
tdc.update_attribute(:mandatory, true) tdc.update_attribute(:mandatory, true)
end end
scenario 'remplace a mandatory piece justificative', js: true do scenario 'remplace a mandatory piece justificative', js: true, retry: 3 do
visit_dossier(dossier) visit_dossier(dossier)
click_on "Supprimer le fichier toto.txt" click_on "Supprimer le fichier toto.txt"
@ -50,7 +50,7 @@ describe "Dossier en_construction" do
tdc.update_attribute(:mandatory, true) tdc.update_attribute(:mandatory, true)
end end
scenario 'remplace a mandatory titre identite', js: true do scenario 'remplace a mandatory titre identite', js: true, retry: 3 do
visit_dossier(dossier) visit_dossier(dossier)
click_on "Supprimer le fichier toto.png" click_on "Supprimer le fichier toto.png"

View file

@ -9,7 +9,7 @@ describe 'Invitations' do
context 'when the dossier is a brouillon' do context 'when the dossier is a brouillon' do
let!(:dossier) { create(:dossier, :with_individual, state: Dossier.states.fetch(:brouillon), user: owner, procedure: procedure) } let!(:dossier) { create(:dossier, :with_individual, state: Dossier.states.fetch(:brouillon), user: owner, procedure: procedure) }
scenario 'on the form, the owner of a dossier can invite another user to collaborate on the dossier', js: true do scenario 'on the form, the owner of a dossier can invite another user to collaborate on the dossier', js: true, retry: 3 do
log_in(owner) log_in(owner)
navigate_to_brouillon(dossier) navigate_to_brouillon(dossier)
fill_in 'Texte obligatoire', with: 'Some edited value' fill_in 'Texte obligatoire', with: 'Some edited value'
@ -94,7 +94,7 @@ describe 'Invitations' do
end end
end end
scenario 'an invited user can see and edit the draft', js: true do scenario 'an invited user can see and edit the draft', js: true, retry: 3 do
navigate_to_invited_dossier(invite) navigate_to_invited_dossier(invite)
expect(page).to have_current_path(brouillon_dossier_path(dossier)) expect(page).to have_current_path(brouillon_dossier_path(dossier))
@ -117,7 +117,7 @@ describe 'Invitations' do
context 'when the dossier is en_construction' do context 'when the dossier is en_construction' do
let!(:dossier) { create(:dossier, :with_individual, :en_construction, user: owner, procedure: procedure) } let!(:dossier) { create(:dossier, :with_individual, :en_construction, user: owner, procedure: procedure) }
scenario 'on dossier details, the owner of a dossier can invite another user to collaborate on the dossier', js: true do scenario 'on dossier details, the owner of a dossier can invite another user to collaborate on the dossier', js: true, retry: 3 do
log_in(owner) log_in(owner)
navigate_to_dossier(dossier) navigate_to_dossier(dossier)
@ -128,7 +128,7 @@ describe 'Invitations' do
expect(page).to have_text("user_invite@exemple.fr") expect(page).to have_text("user_invite@exemple.fr")
end end
context 'as an invited user', js: true do context 'as an invited user', js: true, retry: 3 do
before do before do
navigate_to_invited_dossier(invite) navigate_to_invited_dossier(invite)
expect(page).to have_current_path(dossier_path(invite.dossier)) expect(page).to have_current_path(dossier_path(invite.dossier))

View file

@ -1,5 +1,5 @@
describe 'linked dropdown lists' do describe 'linked dropdown lists' do
let(:password) { 'my-s3cure-p4ssword' } let(:password) { SECURE_PASSWORD }
let!(:user) { create(:user, password: password) } let!(:user) { create(:user, password: password) }
let(:options) do let(:options) do
@ -19,7 +19,7 @@ describe 'linked dropdown lists' do
let(:user_dossier) { user.dossiers.first } let(:user_dossier) { user.dossiers.first }
context 'not mandatory' do context 'not mandatory' do
let(:mandatory) { false } let(:mandatory) { false }
scenario 'change primary value, secondary options are updated', js: true do scenario 'change primary value, secondary options are updated', js: true, retry: 3 do
log_in(user.email, password, procedure) log_in(user.email, password, procedure)
fill_individual fill_individual
@ -42,7 +42,7 @@ describe 'linked dropdown lists' do
context 'mandatory' do context 'mandatory' do
let(:mandatory) { true } let(:mandatory) { true }
scenario 'change primary value, secondary options are updated', js: true do scenario 'change primary value, secondary options are updated', js: true, retry: 3 do
log_in(user.email, password, procedure) log_in(user.email, password, procedure)
fill_individual fill_individual

View file

@ -1,4 +1,4 @@
describe 'user access to the list of their dossiers', js: true do describe 'user access to the list of their dossiers', js: true, retry: 3 do
let(:user) { create(:user) } let(:user) { create(:user) }
let!(:dossier_brouillon) { create(:dossier, user: user) } let!(:dossier_brouillon) { create(:dossier, user: user) }
let!(:dossier_en_construction) { create(:dossier, :with_populated_champs, :en_construction, user: user) } let!(:dossier_en_construction) { create(:dossier, :with_populated_champs, :en_construction, user: user) }
@ -155,7 +155,7 @@ describe 'user access to the list of their dossiers', js: true do
expect(page).not_to have_link('Supprimer le dossier', href: dossier_path(dossier_en_instruction)) expect(page).not_to have_link('Supprimer le dossier', href: dossier_path(dossier_en_instruction))
end end
context 'when user clicks on delete button', js: true do context 'when user clicks on delete button', js: true, retry: 3 do
scenario 'the dossier is deleted' do scenario 'the dossier is deleted' do
expect(page).to have_content(dossier_en_construction.procedure.libelle) expect(page).to have_content(dossier_en_construction.procedure.libelle)
within(:css, ".card", match: :first) do within(:css, ".card", match: :first) do
@ -177,7 +177,7 @@ describe 'user access to the list of their dossiers', js: true do
expect(page).to have_link(nil, href: clone_dossier_path(dossier_en_instruction)) expect(page).to have_link(nil, href: clone_dossier_path(dossier_en_instruction))
end end
context 'when user clicks on clone button', js: true do context 'when user clicks on clone button', js: true, retry: 3 do
scenario 'the dossier is cloned' do scenario 'the dossier is cloned' do
within(:css, ".card", match: :first) do within(:css, ".card", match: :first) do
click_on 'Autres actions' click_on 'Autres actions'

View file

@ -1,4 +1,4 @@
describe 'Managing password:', js: true do describe 'Managing password:', js: true, retry: 3 do
context 'for simple users' do context 'for simple users' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:new_password) { 'a simple password' } let(:new_password) { 'a simple password' }
@ -11,7 +11,7 @@ describe 'Managing password:', js: true do
click_on 'Mot de passe oublié ?' click_on 'Mot de passe oublié ?'
expect(page).to have_current_path(new_user_password_path) expect(page).to have_current_path(new_user_password_path)
fill_in 'Email', with: user.email fill_in 'Adresse électronique', with: user.email
perform_enqueued_jobs do perform_enqueued_jobs do
click_on 'Demander un nouveau mot de passe' click_on 'Demander un nouveau mot de passe'
end end
@ -34,7 +34,7 @@ describe 'Managing password:', js: true do
let(:weak_password) { '12345678' } let(:weak_password) { '12345678' }
let(:strong_password) { 'a new, long, and complicated password!' } let(:strong_password) { 'a new, long, and complicated password!' }
scenario 'an admin can reset their password', js: true do scenario 'an admin can reset their password', js: true, retry: 3 do
visit root_path visit root_path
within('.fr-header .fr-container .fr-header__tools .fr-btns-group') do within('.fr-header .fr-container .fr-header__tools .fr-btns-group') do
click_on 'Se connecter' click_on 'Se connecter'
@ -42,7 +42,7 @@ describe 'Managing password:', js: true do
click_on 'Mot de passe oublié ?' click_on 'Mot de passe oublié ?'
expect(page).to have_current_path(new_user_password_path) expect(page).to have_current_path(new_user_password_path)
fill_in 'Email', with: user.email fill_in 'Adresse électronique', with: user.email
perform_enqueued_jobs do perform_enqueued_jobs do
click_on 'Demander un nouveau mot de passe' click_on 'Demander un nouveau mot de passe'
end end
@ -73,12 +73,12 @@ describe 'Managing password:', js: true do
let(:weak_password) { '12345678' } let(:weak_password) { '12345678' }
let(:strong_password) { 'a new, long, and complicated password!' } let(:strong_password) { 'a new, long, and complicated password!' }
scenario 'a super-admin can reset their password', js: true do scenario 'a super-admin can reset their password', js: true, retry: 3 do
visit manager_root_path visit manager_root_path
click_on 'Mot de passe oublié' click_on 'Mot de passe oublié'
expect(page).to have_current_path(new_super_admin_password_path) expect(page).to have_current_path(new_super_admin_password_path)
fill_in 'Email', with: super_admin.email fill_in 'Adresse électronique', with: super_admin.email
perform_enqueued_jobs do perform_enqueued_jobs do
click_on 'Demander un nouveau mot de passe' click_on 'Demander un nouveau mot de passe'
end end

View file

@ -1,6 +1,6 @@
describe 'Signing up:' do describe 'Signing up:' do
let(:user_email) { generate :user_email } let(:user_email) { generate :user_email }
let(:user_password) { 'my-s3cure-p4ssword' } let(:user_password) { SECURE_PASSWORD }
let(:procedure) { create :simple_procedure, :with_service } let(:procedure) { create :simple_procedure, :with_service }
scenario 'a new user can sign-up from scratch' do scenario 'a new user can sign-up from scratch' do
@ -25,21 +25,21 @@ describe 'Signing up:' do
fill_in 'Mot de passe', with: '12345' fill_in 'Mot de passe', with: '12345'
end end
scenario 'they can accept the suggestion', js: true do scenario 'they can accept the suggestion', js: true, retry: 3 do
expect(page).to have_selector('.suspect-email', visible: true) expect(page).to have_selector('.suspect-email', visible: true)
click_on 'Oui' click_on 'Oui'
expect(page).to have_field("Adresse électronique", :with => 'bidou@yahoo.fr') expect(page).to have_field("Adresse électronique", :with => 'bidou@yahoo.fr')
expect(page).to have_selector('.suspect-email', visible: false) expect(page).to have_selector('.suspect-email', visible: false)
end end
scenario 'they can discard the suggestion', js: true do scenario 'they can discard the suggestion', js: true, retry: 3 do
expect(page).to have_selector('.suspect-email', visible: true) expect(page).to have_selector('.suspect-email', visible: true)
click_on 'Non' click_on 'Non'
expect(page).to have_field("Adresse électronique", :with => 'bidou@yahoo.rf') expect(page).to have_field("Adresse électronique", :with => 'bidou@yahoo.rf')
expect(page).to have_selector('.suspect-email', visible: false) expect(page).to have_selector('.suspect-email', visible: false)
end end
scenario 'they can fix the typo themselves', js: true do scenario 'they can fix the typo themselves', js: true, retry: 3 do
expect(page).to have_selector('.suspect-email', visible: true) expect(page).to have_selector('.suspect-email', visible: true)
fill_in 'Adresse électronique', with: 'bidou@yahoo.fr' fill_in 'Adresse électronique', with: 'bidou@yahoo.fr'
blur blur

181
yarn.lock
View file

@ -1190,221 +1190,111 @@
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
"@esbuild/android-arm64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.14.tgz#f02c9f0d43086ddf6ed2795b881ddf7990f74456"
integrity sha512-hTqB6Iq13pW4xaydeqQrs8vPntUnMjbkq+PgGiBMi69eYk74naG2ftHWqKnxn874kNrt5Or3rQ0PJutx2doJuQ==
"@esbuild/android-arm64@0.17.14": "@esbuild/android-arm64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.14.tgz#4624cea3c8941c91f9e9c1228f550d23f1cef037" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.14.tgz#4624cea3c8941c91f9e9c1228f550d23f1cef037"
integrity sha512-eLOpPO1RvtsP71afiFTvS7tVFShJBCT0txiv/xjFBo5a7R7Gjw7X0IgIaFoLKhqXYAXhahoXm7qAmRXhY4guJg== integrity sha512-eLOpPO1RvtsP71afiFTvS7tVFShJBCT0txiv/xjFBo5a7R7Gjw7X0IgIaFoLKhqXYAXhahoXm7qAmRXhY4guJg==
"@esbuild/android-arm@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.16.14.tgz#24e4faf569d0d6bbf9ed46f6ed395d68eb7f04fc"
integrity sha512-u0rITLxFIeYAvtJXBQNhNuV4YZe+MD1YvIWT7Nicj8hZAtRVZk2PgNH6KclcKDVHz1ChLKXRfX7d7tkbQBUfrg==
"@esbuild/android-arm@0.17.14": "@esbuild/android-arm@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.14.tgz#74fae60fcab34c3f0e15cb56473a6091ba2b53a6" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.14.tgz#74fae60fcab34c3f0e15cb56473a6091ba2b53a6"
integrity sha512-0CnlwnjDU8cks0yJLXfkaU/uoLyRf9VZJs4p1PskBr2AlAHeEsFEwJEo0of/Z3g+ilw5mpyDwThlxzNEIxOE4g== integrity sha512-0CnlwnjDU8cks0yJLXfkaU/uoLyRf9VZJs4p1PskBr2AlAHeEsFEwJEo0of/Z3g+ilw5mpyDwThlxzNEIxOE4g==
"@esbuild/android-x64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.16.14.tgz#1173e706cf57c0d4dbf069d18e5d50ae6a5b0871"
integrity sha512-jir51K4J0K5Rt0KOcippjSNdOl7akKDVz5I6yrqdk4/m9y+rldGptQUF7qU4YpX8U61LtR+w2Tu2Ph+K/UaJOw==
"@esbuild/android-x64@0.17.14": "@esbuild/android-x64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.14.tgz#f002fbc08d5e939d8314bd23bcfb1e95d029491f" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.14.tgz#f002fbc08d5e939d8314bd23bcfb1e95d029491f"
integrity sha512-nrfQYWBfLGfSGLvRVlt6xi63B5IbfHm3tZCdu/82zuFPQ7zez4XjmRtF/wIRYbJQ/DsZrxJdEvYFE67avYXyng== integrity sha512-nrfQYWBfLGfSGLvRVlt6xi63B5IbfHm3tZCdu/82zuFPQ7zez4XjmRtF/wIRYbJQ/DsZrxJdEvYFE67avYXyng==
"@esbuild/darwin-arm64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.14.tgz#67f05693c5b097bcb4ff656ba5839459f30f79c2"
integrity sha512-vrlaP81IuwPaw1fyX8fHCmivP3Gr73ojVEZy+oWJLAiZVcG8o8Phwun/XDnYIFUHxIoUnMFEpg9o38MIvlw8zw==
"@esbuild/darwin-arm64@0.17.14": "@esbuild/darwin-arm64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.14.tgz#b8dcd79a1dd19564950b4ca51d62999011e2e168" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.14.tgz#b8dcd79a1dd19564950b4ca51d62999011e2e168"
integrity sha512-eoSjEuDsU1ROwgBH/c+fZzuSyJUVXQTOIN9xuLs9dE/9HbV/A5IqdXHU1p2OfIMwBwOYJ9SFVGGldxeRCUJFyw== integrity sha512-eoSjEuDsU1ROwgBH/c+fZzuSyJUVXQTOIN9xuLs9dE/9HbV/A5IqdXHU1p2OfIMwBwOYJ9SFVGGldxeRCUJFyw==
"@esbuild/darwin-x64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.16.14.tgz#519c9d127c5363d4a1e73b9d954460f798b41d2a"
integrity sha512-KV1E01eC2hGYA2qzFDRCK4wdZCRUvMwCNcobgpiiOzp5QXpJBqFPdxI69j8vvzuU7oxFXDgANwEkXvpeQqyOyg==
"@esbuild/darwin-x64@0.17.14": "@esbuild/darwin-x64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.14.tgz#4b49f195d9473625efc3c773fc757018f2c0d979" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.14.tgz#4b49f195d9473625efc3c773fc757018f2c0d979"
integrity sha512-zN0U8RWfrDttdFNkHqFYZtOH8hdi22z0pFm0aIJPsNC4QQZv7je8DWCX5iA4Zx6tRhS0CCc0XC2m7wKsbWEo5g== integrity sha512-zN0U8RWfrDttdFNkHqFYZtOH8hdi22z0pFm0aIJPsNC4QQZv7je8DWCX5iA4Zx6tRhS0CCc0XC2m7wKsbWEo5g==
"@esbuild/freebsd-arm64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.14.tgz#2e3f5de2951a8ec732a3e4ec4f5d47a7c9626001"
integrity sha512-xRM1RQsazSvL42BNa5XC7ytD4ZDp0ZyJcH7aB0SlYUcHexJUKiDNKR7dlRVlpt6W0DvoRPU2nWK/9/QWS4u2fw==
"@esbuild/freebsd-arm64@0.17.14": "@esbuild/freebsd-arm64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.14.tgz#480923fd38f644c6342c55e916cc7c231a85eeb7" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.14.tgz#480923fd38f644c6342c55e916cc7c231a85eeb7"
integrity sha512-z0VcD4ibeZWVQCW1O7szaLxGsx54gcCnajEJMdYoYjLiq4g1jrP2lMq6pk71dbS5+7op/L2Aod+erw+EUr28/A== integrity sha512-z0VcD4ibeZWVQCW1O7szaLxGsx54gcCnajEJMdYoYjLiq4g1jrP2lMq6pk71dbS5+7op/L2Aod+erw+EUr28/A==
"@esbuild/freebsd-x64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.14.tgz#d3cf84ff28357ac8d0123309bac37fcfcdd98f53"
integrity sha512-7ALTAn6YRRf1O6fw9jmn0rWmOx3XfwDo7njGtjy1LXhDGUjTY/vohEPM3ii5MQ411vJv1r498EEx2aBQTJcrEw==
"@esbuild/freebsd-x64@0.17.14": "@esbuild/freebsd-x64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.14.tgz#a6b6b01954ad8562461cb8a5e40e8a860af69cbe" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.14.tgz#a6b6b01954ad8562461cb8a5e40e8a860af69cbe"
integrity sha512-hd9mPcxfTgJlolrPlcXkQk9BMwNBvNBsVaUe5eNUqXut6weDQH8whcNaKNF2RO8NbpT6GY8rHOK2A9y++s+ehw== integrity sha512-hd9mPcxfTgJlolrPlcXkQk9BMwNBvNBsVaUe5eNUqXut6weDQH8whcNaKNF2RO8NbpT6GY8rHOK2A9y++s+ehw==
"@esbuild/linux-arm64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.16.14.tgz#f44b0e3d5d470cd763a9bc4855a12b8cb73d6c12"
integrity sha512-TLh2OcbBUQcMYRH4GbiDkDZfZ4t1A3GgmeXY27dHSI6xrU7IkO00MGBiJySmEV6sH3Wa6pAN6UtaVL0DwkGW4Q==
"@esbuild/linux-arm64@0.17.14": "@esbuild/linux-arm64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.14.tgz#1fe2f39f78183b59f75a4ad9c48d079916d92418" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.14.tgz#1fe2f39f78183b59f75a4ad9c48d079916d92418"
integrity sha512-FhAMNYOq3Iblcj9i+K0l1Fp/MHt+zBeRu/Qkf0LtrcFu3T45jcwB6A1iMsemQ42vR3GBhjNZJZTaCe3VFPbn9g== integrity sha512-FhAMNYOq3Iblcj9i+K0l1Fp/MHt+zBeRu/Qkf0LtrcFu3T45jcwB6A1iMsemQ42vR3GBhjNZJZTaCe3VFPbn9g==
"@esbuild/linux-arm@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.16.14.tgz#b239eb7e6cb7df9c34c6b08f4adf113da47e0e09"
integrity sha512-X6xULug66ulrr4IzrW7qq+eq9n4MtEyagdWvj4o4cmWr+JXOT47atjpDF9j5M2zHY0UQBmqnHhwl+tXpkpIb2w==
"@esbuild/linux-arm@0.17.14": "@esbuild/linux-arm@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.14.tgz#18d594a49b64e4a3a05022c005cb384a58056a2a" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.14.tgz#18d594a49b64e4a3a05022c005cb384a58056a2a"
integrity sha512-BNTl+wSJ1omsH8s3TkQmIIIQHwvwJrU9u1ggb9XU2KTVM4TmthRIVyxSp2qxROJHhZuW/r8fht46/QE8hU8Qvg== integrity sha512-BNTl+wSJ1omsH8s3TkQmIIIQHwvwJrU9u1ggb9XU2KTVM4TmthRIVyxSp2qxROJHhZuW/r8fht46/QE8hU8Qvg==
"@esbuild/linux-ia32@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.16.14.tgz#f5f7886027cd61bed59178e981a0ef47ca5b72ef"
integrity sha512-oBZkcZ56UZDFCAfE3Fd/Jgy10EoS7Td77NzNGenM+HSY8BkdQAcI9VF9qgwdOLZ+tuftWD7UqZ26SAhtvA3XhA==
"@esbuild/linux-ia32@0.17.14": "@esbuild/linux-ia32@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.14.tgz#f7f0182a9cfc0159e0922ed66c805c9c6ef1b654" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.14.tgz#f7f0182a9cfc0159e0922ed66c805c9c6ef1b654"
integrity sha512-91OK/lQ5y2v7AsmnFT+0EyxdPTNhov3y2CWMdizyMfxSxRqHazXdzgBKtlmkU2KYIc+9ZK3Vwp2KyXogEATYxQ== integrity sha512-91OK/lQ5y2v7AsmnFT+0EyxdPTNhov3y2CWMdizyMfxSxRqHazXdzgBKtlmkU2KYIc+9ZK3Vwp2KyXogEATYxQ==
"@esbuild/linux-loong64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.16.14.tgz#d2329371726f9778156c89ea0bed26fc1bc3cd7e"
integrity sha512-udz/aEHTcuHP+xdWOJmZ5C9RQXHfZd/EhCnTi1Hfay37zH3lBxn/fNs85LA9HlsniFw2zccgcbrrTMKk7Cn1Qg==
"@esbuild/linux-loong64@0.17.14": "@esbuild/linux-loong64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.14.tgz#5f5305fdffe2d71dd9a97aa77d0c99c99409066f" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.14.tgz#5f5305fdffe2d71dd9a97aa77d0c99c99409066f"
integrity sha512-vp15H+5NR6hubNgMluqqKza85HcGJgq7t6rMH7O3Y6ApiOWPkvW2AJfNojUQimfTp6OUrACUXfR4hmpcENXoMQ== integrity sha512-vp15H+5NR6hubNgMluqqKza85HcGJgq7t6rMH7O3Y6ApiOWPkvW2AJfNojUQimfTp6OUrACUXfR4hmpcENXoMQ==
"@esbuild/linux-mips64el@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.14.tgz#8af86bdc6ee937c8a2803b3c197b28824f48df8e"
integrity sha512-kJ2iEnikUOdC1SiTGbH0fJUgpZwa0ITDTvj9EHf9lm3I0hZ4Yugsb3M6XSl696jVxrEocLe519/8CbSpQWFSrg==
"@esbuild/linux-mips64el@0.17.14": "@esbuild/linux-mips64el@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.14.tgz#a602e85c51b2f71d2aedfe7f4143b2f92f97f3f5" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.14.tgz#a602e85c51b2f71d2aedfe7f4143b2f92f97f3f5"
integrity sha512-90TOdFV7N+fgi6c2+GO9ochEkmm9kBAKnuD5e08GQMgMINOdOFHuYLPQ91RYVrnWwQ5683sJKuLi9l4SsbJ7Hg== integrity sha512-90TOdFV7N+fgi6c2+GO9ochEkmm9kBAKnuD5e08GQMgMINOdOFHuYLPQ91RYVrnWwQ5683sJKuLi9l4SsbJ7Hg==
"@esbuild/linux-ppc64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.14.tgz#3fa3f8c6c9db3127f2ec5b2eba1cec67ff9a9b8e"
integrity sha512-kclKxvZvX5YhykwlJ/K9ljiY4THe5vXubXpWmr7q3Zu3WxKnUe1VOZmhkEZlqtnJx31GHPEV4SIG95IqTdfgfg==
"@esbuild/linux-ppc64@0.17.14": "@esbuild/linux-ppc64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.14.tgz#32d918d782105cbd9345dbfba14ee018b9c7afdf" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.14.tgz#32d918d782105cbd9345dbfba14ee018b9c7afdf"
integrity sha512-NnBGeoqKkTugpBOBZZoktQQ1Yqb7aHKmHxsw43NddPB2YWLAlpb7THZIzsRsTr0Xw3nqiPxbA1H31ZMOG+VVPQ== integrity sha512-NnBGeoqKkTugpBOBZZoktQQ1Yqb7aHKmHxsw43NddPB2YWLAlpb7THZIzsRsTr0Xw3nqiPxbA1H31ZMOG+VVPQ==
"@esbuild/linux-riscv64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.14.tgz#1bd1b631de2533106a08876295bad3a19b20f629"
integrity sha512-fdwP9Dc+Kx/cZwp9T9kNqjAE/PQjfrxbio4rZ3XnC3cVvZBjuxpkiyu/tuCwt6SbAK5th6AYNjFdEV9kGC020A==
"@esbuild/linux-riscv64@0.17.14": "@esbuild/linux-riscv64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.14.tgz#38612e7b6c037dff7022c33f49ca17f85c5dec58" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.14.tgz#38612e7b6c037dff7022c33f49ca17f85c5dec58"
integrity sha512-0qdlKScLXA8MGVy21JUKvMzCYWovctuP8KKqhtE5A6IVPq4onxXhSuhwDd2g5sRCzNDlDjitc5sX31BzDoL5Fw== integrity sha512-0qdlKScLXA8MGVy21JUKvMzCYWovctuP8KKqhtE5A6IVPq4onxXhSuhwDd2g5sRCzNDlDjitc5sX31BzDoL5Fw==
"@esbuild/linux-s390x@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.16.14.tgz#c87440b6522b9a36a9cafd05b0f1ca3c5bad4cca"
integrity sha512-++fw3P4fQk9nqvdzbANRqimKspL8pDCnSpXomyhV7V/ISha/BZIYvZwLBWVKp9CVWKwWPJ4ktsezuLIvlJRHqA==
"@esbuild/linux-s390x@0.17.14": "@esbuild/linux-s390x@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.14.tgz#4397dff354f899e72fd035d72af59a700c465ccb" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.14.tgz#4397dff354f899e72fd035d72af59a700c465ccb"
integrity sha512-Hdm2Jo1yaaOro4v3+6/zJk6ygCqIZuSDJHdHaf8nVH/tfOuoEX5Riv03Ka15LmQBYJObUTNS1UdyoMk0WUn9Ww== integrity sha512-Hdm2Jo1yaaOro4v3+6/zJk6ygCqIZuSDJHdHaf8nVH/tfOuoEX5Riv03Ka15LmQBYJObUTNS1UdyoMk0WUn9Ww==
"@esbuild/linux-x64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.16.14.tgz#49cd974dad6042ac0141ba332df6307c44e77fed"
integrity sha512-TomtswAuzBf2NnddlrS4W01Tv85RM9YtATB3OugY6On0PLM4Ksz5qvQKVAjtzPKoLgL1FiZtfc8mkZc4IgoMEA==
"@esbuild/linux-x64@0.17.14": "@esbuild/linux-x64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.14.tgz#6c5cb99891b6c3e0c08369da3ef465e8038ad9c2" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.14.tgz#6c5cb99891b6c3e0c08369da3ef465e8038ad9c2"
integrity sha512-8KHF17OstlK4DuzeF/KmSgzrTWQrkWj5boluiiq7kvJCiQVzUrmSkaBvcLB2UgHpKENO2i6BthPkmUhNDaJsVw== integrity sha512-8KHF17OstlK4DuzeF/KmSgzrTWQrkWj5boluiiq7kvJCiQVzUrmSkaBvcLB2UgHpKENO2i6BthPkmUhNDaJsVw==
"@esbuild/netbsd-x64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.14.tgz#53dcfb5131376feff0911adff7f01b4821706cf6"
integrity sha512-U06pfx8P5CqyoPNfqIJmnf+5/r4mJ1S62G4zE6eOjS59naQcxi6GnscUCPH3b+hRG0qdKoGX49RAyiqW+M9aSw==
"@esbuild/netbsd-x64@0.17.14": "@esbuild/netbsd-x64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.14.tgz#5fa5255a64e9bf3947c1b3bef5e458b50b211994" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.14.tgz#5fa5255a64e9bf3947c1b3bef5e458b50b211994"
integrity sha512-nVwpqvb3yyXztxIT2+VsxJhB5GCgzPdk1n0HHSnchRAcxqKO6ghXwHhJnr0j/B+5FSyEqSxF4q03rbA2fKXtUQ== integrity sha512-nVwpqvb3yyXztxIT2+VsxJhB5GCgzPdk1n0HHSnchRAcxqKO6ghXwHhJnr0j/B+5FSyEqSxF4q03rbA2fKXtUQ==
"@esbuild/openbsd-x64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.14.tgz#f36888f73087bcd12c5bf9a4b18e348da9c80ad0"
integrity sha512-/Jl8XVaWEZNu9rZw+n792GIBupQwHo6GDoapHSb/2xp/Ku28eK6QpR2O9cPBkzHH4OOoMH0LB6zg/qczJ5TTGg==
"@esbuild/openbsd-x64@0.17.14": "@esbuild/openbsd-x64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.14.tgz#74d14c79dcb6faf446878cc64284aa4e02f5ca6f" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.14.tgz#74d14c79dcb6faf446878cc64284aa4e02f5ca6f"
integrity sha512-1RZ7uQQ9zcy/GSAJL1xPdN7NDdOOtNEGiJalg/MOzeakZeTrgH/DoCkbq7TaPDiPhWqnDF+4bnydxRqQD7il6g== integrity sha512-1RZ7uQQ9zcy/GSAJL1xPdN7NDdOOtNEGiJalg/MOzeakZeTrgH/DoCkbq7TaPDiPhWqnDF+4bnydxRqQD7il6g==
"@esbuild/sunos-x64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.16.14.tgz#41e046bb0849ae59702a5cfa8be300431a61ee3a"
integrity sha512-2iI7D34uTbDn/TaSiUbEHz+fUa8KbN90vX5yYqo12QGpu6T8Jl+kxODsWuMCwoTVlqUpwfPV22nBbFPME9OPtw==
"@esbuild/sunos-x64@0.17.14": "@esbuild/sunos-x64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.14.tgz#5c7d1c7203781d86c2a9b2ff77bd2f8036d24cfa" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.14.tgz#5c7d1c7203781d86c2a9b2ff77bd2f8036d24cfa"
integrity sha512-nqMjDsFwv7vp7msrwWRysnM38Sd44PKmW8EzV01YzDBTcTWUpczQg6mGao9VLicXSgW/iookNK6AxeogNVNDZA== integrity sha512-nqMjDsFwv7vp7msrwWRysnM38Sd44PKmW8EzV01YzDBTcTWUpczQg6mGao9VLicXSgW/iookNK6AxeogNVNDZA==
"@esbuild/win32-arm64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.16.14.tgz#d6ed78742a6edd413e75796882ddaef8c1e23b93"
integrity sha512-SjlM7AHmQVTiGBJE/nqauY1aDh80UBsXZ94g4g60CDkrDMseatiqALVcIuElg4ZSYzJs8hsg5W6zS2zLpZTVgg==
"@esbuild/win32-arm64@0.17.14": "@esbuild/win32-arm64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.14.tgz#dc36ed84f1390e73b6019ccf0566c80045e5ca3d" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.14.tgz#dc36ed84f1390e73b6019ccf0566c80045e5ca3d"
integrity sha512-xrD0mccTKRBBIotrITV7WVQAwNJ5+1va6L0H9zN92v2yEdjfAN7864cUaZwJS7JPEs53bDTzKFbfqVlG2HhyKQ== integrity sha512-xrD0mccTKRBBIotrITV7WVQAwNJ5+1va6L0H9zN92v2yEdjfAN7864cUaZwJS7JPEs53bDTzKFbfqVlG2HhyKQ==
"@esbuild/win32-ia32@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.16.14.tgz#558bd53859a83fe887d7d2dcdc6cb3fc9aa9a9bc"
integrity sha512-z06t5zqk8ak0Xom5HG81z2iOQ1hNWYsFQp3sczVLVx+dctWdgl80tNRyTbwjaFfui2vFO12dfE3trCTvA+HO4g==
"@esbuild/win32-ia32@0.17.14": "@esbuild/win32-ia32@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.14.tgz#0802a107afa9193c13e35de15a94fe347c588767" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.14.tgz#0802a107afa9193c13e35de15a94fe347c588767"
integrity sha512-nXpkz9bbJrLLyUTYtRotSS3t5b+FOuljg8LgLdINWFs3FfqZMtbnBCZFUmBzQPyxqU87F8Av+3Nco/M3hEcu1w== integrity sha512-nXpkz9bbJrLLyUTYtRotSS3t5b+FOuljg8LgLdINWFs3FfqZMtbnBCZFUmBzQPyxqU87F8Av+3Nco/M3hEcu1w==
"@esbuild/win32-x64@0.16.14":
version "0.16.14"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.14.tgz#90558dcb279989d92a42e5be4dfb884b2399361f"
integrity sha512-ED1UpWcM6lAbalbbQ9TrGqJh4Y9TaASUvu8bI/0mgJcxhSByJ6rbpgqRhxYMaQ682WfA71nxUreaTO7L275zrw==
"@esbuild/win32-x64@0.17.14": "@esbuild/win32-x64@0.17.14":
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.14.tgz#e81fb49de05fed91bf74251c9ca0343f4fc77d31" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.14.tgz#e81fb49de05fed91bf74251c9ca0343f4fc77d31"
@ -3467,34 +3357,6 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1" is-date-object "^1.0.1"
is-symbol "^1.0.2" is-symbol "^1.0.2"
esbuild@^0.16.3:
version "0.16.14"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.14.tgz#366249a0a0fd431d3ab706195721ef1014198919"
integrity sha512-6xAn3O6ZZyoxZAEkwfI9hw4cEqSr/o1ViJtnkvImVkblmUN65Md04o0S/7H1WNu1XGf1Cjij/on7VO4psIYjkw==
optionalDependencies:
"@esbuild/android-arm" "0.16.14"
"@esbuild/android-arm64" "0.16.14"
"@esbuild/android-x64" "0.16.14"
"@esbuild/darwin-arm64" "0.16.14"
"@esbuild/darwin-x64" "0.16.14"
"@esbuild/freebsd-arm64" "0.16.14"
"@esbuild/freebsd-x64" "0.16.14"
"@esbuild/linux-arm" "0.16.14"
"@esbuild/linux-arm64" "0.16.14"
"@esbuild/linux-ia32" "0.16.14"
"@esbuild/linux-loong64" "0.16.14"
"@esbuild/linux-mips64el" "0.16.14"
"@esbuild/linux-ppc64" "0.16.14"
"@esbuild/linux-riscv64" "0.16.14"
"@esbuild/linux-s390x" "0.16.14"
"@esbuild/linux-x64" "0.16.14"
"@esbuild/netbsd-x64" "0.16.14"
"@esbuild/openbsd-x64" "0.16.14"
"@esbuild/sunos-x64" "0.16.14"
"@esbuild/win32-arm64" "0.16.14"
"@esbuild/win32-ia32" "0.16.14"
"@esbuild/win32-x64" "0.16.14"
esbuild@^0.17.5: esbuild@^0.17.5:
version "0.17.14" version "0.17.14"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.14.tgz#d61a22de751a3133f3c6c7f9c1c3e231e91a3245" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.14.tgz#d61a22de751a3133f3c6c7f9c1c3e231e91a3245"
@ -5004,11 +4866,6 @@ nano-time@1.0.0:
dependencies: dependencies:
big-integer "^1.6.16" big-integer "^1.6.16"
nanoid@^3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
nanoid@^3.3.6: nanoid@^3.3.6:
version "3.3.6" version "3.3.6"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
@ -5335,15 +5192,6 @@ postcss-value-parser@^4.2.0:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@^8.4.20:
version "8.4.20"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.20.tgz#64c52f509644cecad8567e949f4081d98349dc56"
integrity sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==
dependencies:
nanoid "^3.3.4"
picocolors "^1.0.0"
source-map-js "^1.0.2"
postcss@^8.4.23: postcss@^8.4.23:
version "8.4.23" version "8.4.23"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab"
@ -5673,7 +5521,7 @@ resolve-protobuf-schema@^2.1.0:
dependencies: dependencies:
protocol-buffers-schema "^3.3.1" protocol-buffers-schema "^3.3.1"
resolve@^1.14.2, resolve@^1.22.1: resolve@^1.14.2:
version "1.22.1" version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
@ -5717,13 +5565,6 @@ rollup@^3.21.0:
optionalDependencies: optionalDependencies:
fsevents "~2.3.2" fsevents "~2.3.2"
rollup@^3.7.0:
version "3.9.1"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.9.1.tgz#27501d3d026418765fe379d5620d25954ff2a011"
integrity sha512-GswCYHXftN8ZKGVgQhTFUJB/NBXxrRGgO2NCy6E8s1rwEJ4Q9/VttNqcYfEvx4dTo4j58YqdC3OVztPzlKSX8w==
optionalDependencies:
fsevents "~2.3.2"
rrweb-cssom@^0.6.0: rrweb-cssom@^0.6.0:
version "0.6.0" version "0.6.0"
resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz#ed298055b97cbddcdeb278f904857629dec5e0e1" resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz#ed298055b97cbddcdeb278f904857629dec5e0e1"
@ -6440,22 +6281,10 @@ vite-plugin-ruby@^3.2.2:
debug "^4.3.4" debug "^4.3.4"
fast-glob "^3.2.12" fast-glob "^3.2.12"
"vite@^3.0.0 || ^4.0.0": "vite@^3.0.0 || ^4.0.0", vite@^4.3.9:
version "4.0.4" version "4.3.9"
resolved "https://registry.yarnpkg.com/vite/-/vite-4.0.4.tgz#4612ce0b47bbb233a887a54a4ae0c6e240a0da31" resolved "https://registry.yarnpkg.com/vite/-/vite-4.3.9.tgz#db896200c0b1aa13b37cdc35c9e99ee2fdd5f96d"
integrity sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw== integrity sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==
dependencies:
esbuild "^0.16.3"
postcss "^8.4.20"
resolve "^1.22.1"
rollup "^3.7.0"
optionalDependencies:
fsevents "~2.3.2"
vite@^4.3.0:
version "4.3.4"
resolved "https://registry.yarnpkg.com/vite/-/vite-4.3.4.tgz#1c518d763d5a700d890c3a19ab59220f06e7a7d5"
integrity sha512-f90aqGBoxSFxWph2b39ae2uHAxm5jFBBdnfueNxZAT1FTpM13ccFQExCaKbR2xFW5atowjleRniQ7onjJ22QEg==
dependencies: dependencies:
esbuild "^0.17.5" esbuild "^0.17.5"
postcss "^8.4.23" postcss "^8.4.23"