Merge branch 'dev'

This commit is contained in:
gregoirenovel 2018-10-10 15:29:23 +02:00
commit 90ab10d1d8
35 changed files with 154 additions and 147 deletions

View file

@ -65,7 +65,6 @@
} }
.confidentiel-explanation { .confidentiel-explanation {
display: none;
font-size: 14px; font-size: 14px;
color: $grey; color: $grey;
margin-top: -$default-padding; margin-top: -$default-padding;

View file

@ -2,7 +2,6 @@
@import "constants"; @import "constants";
.motivation { .motivation {
display: none;
padding: $default-padding; padding: $default-padding;
color: $black; color: $black;
width: 450px; width: 450px;

View file

@ -5,7 +5,7 @@ class InvitesController < ApplicationController
email = params[:invite_email].downcase email = params[:invite_email].downcase
dossier = current_user.dossiers.find(params[:dossier_id]) dossier = current_user.dossiers.find(params[:dossier_id])
invite = InviteUser.create( invite = Invite.create(
dossier: dossier, dossier: dossier,
user: User.find_by(email: email), user: User.find_by(email: email),
email: email, email: email,

View file

@ -1,5 +1,5 @@
import $ from 'jquery'; import { toggle } from '@utils';
export function toggleCondidentielExplanation() { export function toggleCondidentielExplanation() {
$('.confidentiel-explanation').toggle(); toggle(document.querySelector('.confidentiel-explanation'));
} }

View file

@ -1,5 +1,5 @@
import $ from 'jquery';
import L from 'leaflet'; import L from 'leaflet';
import { getJSON } from '@utils';
import { getData } from '../shared/data'; import { getData } from '../shared/data';
import { DEFAULT_POSITION } from '../shared/carto'; import { DEFAULT_POSITION } from '../shared/carto';
@ -11,8 +11,8 @@ import {
} from './carto/draw'; } from './carto/draw';
function initialize() { function initialize() {
if ($('#map').length > 0) { if (document.getElementById('map')) {
$.getJSON(getData('carto').getPositionUrl).then( getJSON(getData('carto').getPositionUrl).then(
position => initializeWithPosition(position), position => initializeWithPosition(position),
() => initializeWithPosition(DEFAULT_POSITION) () => initializeWithPosition(DEFAULT_POSITION)
); );

View file

@ -1,8 +1,6 @@
import Rails from 'rails-ujs'; import { delegate } from '@utils';
const { delegate } = Rails; delegate('click', 'body', event => {
delegate(document, 'body', 'click', event => {
if (!event.target.closest('.dropdown')) { if (!event.target.closest('.dropdown')) {
[...document.querySelectorAll('.dropdown')].forEach(element => [...document.querySelectorAll('.dropdown')].forEach(element =>
element.classList.remove('open', 'fade-in-down') element.classList.remove('open', 'fade-in-down')
@ -10,7 +8,7 @@ delegate(document, 'body', 'click', event => {
} }
}); });
delegate(document, '.dropdown-button', 'click', event => { delegate('click', '.dropdown-button', event => {
event.stopPropagation(); event.stopPropagation();
const parent = event.target.closest('.dropdown-button').parentElement; const parent = event.target.closest('.dropdown-button').parentElement;
if (parent.classList.contains('dropdown')) { if (parent.classList.contains('dropdown')) {

View file

@ -1,10 +1,19 @@
import $ from 'jquery'; import { delegate } from '@utils';
$(document).on('blur keydown', 'input, textarea', () => { delegate('blur keydown', 'input, textarea', ({ target }) => {
$(this).addClass('touched'); touch(target);
}); });
$(document).on('click', 'input[type="submit"]:not([formnovalidate])', () => { delegate(
const $form = $(this).closest('form'); 'click',
$('input, textarea', $form).addClass('touched'); 'input[type="submit"]:not([formnovalidate])',
}); ({ target }) => {
let form = target.closest('form');
let inputs = form ? form.querySelectorAll('input, textarea') : [];
[...inputs].forEach(touch);
}
);
function touch({ classList }) {
classList.add('touched');
}

View file

@ -1,27 +1,17 @@
import $ from 'jquery'; import { scrollTo, scrollToBottom } from '@utils';
export function scrollMessagerie() { export function scrollMessagerie() {
const $ul = $('.messagerie ul').first(); const ul = document.querySelector('.messagerie ul');
if ($ul.length) { if (ul) {
const $elementToScroll = $('.date.highlighted').first(); const elementToScroll = document.querySelector('.date.highlighted');
if ($elementToScroll.length != 0) { if (elementToScroll) {
scrollTo($ul, $elementToScroll); scrollTo(ul, elementToScroll);
} else { } else {
scrollToBottom($ul); scrollToBottom(ul);
} }
} }
} }
function scrollTo($container, $scrollTo) {
$container.scrollTop(
$scrollTo.offset().top - $container.offset().top + $container.scrollTop()
);
}
function scrollToBottom($container) {
$container.scrollTop($container.prop('scrollHeight'));
}
addEventListener('turbolinks:load', scrollMessagerie); addEventListener('turbolinks:load', scrollMessagerie);

View file

@ -1,7 +1,4 @@
import Rails from 'rails-ujs'; import { show, hide, delegate } from '@utils';
import { show, hide } from '../shared/utils';
const { delegate } = Rails;
function showSpinner() { function showSpinner() {
[...document.querySelectorAll('.spinner')].forEach(show); [...document.querySelectorAll('.spinner')].forEach(show);
@ -11,6 +8,6 @@ function hideSpinner() {
[...document.querySelectorAll('.spinner')].forEach(hide); [...document.querySelectorAll('.spinner')].forEach(hide);
} }
delegate(document, '[data-spinner]', 'ajax:complete', hideSpinner); delegate('ajax:complete', '[data-spinner]', hideSpinner);
delegate(document, '[data-spinner]', 'ajax:stopped', hideSpinner); delegate('ajax:stopped', '[data-spinner]', hideSpinner);
delegate(document, '[data-spinner]', 'ajax:send', showSpinner); delegate('ajax:send', '[data-spinner]', showSpinner);

View file

@ -1,12 +1,12 @@
import $ from 'jquery'; import { show, hide } from '@utils';
export function showMotivation(event, state) { export function showMotivation(event, state) {
event.preventDefault(); event.preventDefault();
$(`.motivation.${state}`).show(); show(document.querySelector(`.motivation.${state}`));
$('.dropdown-items').hide(); hide(document.querySelector('.dropdown-items'));
} }
export function motivationCancel() { export function motivationCancel() {
$('.motivation').hide(); document.querySelectorAll('.motivation').forEach(hide);
$('.dropdown-items').show(); show(document.querySelector('.dropdown-items'));
} }

View file

@ -1,28 +1,24 @@
import $ from 'jquery';
import Chartkick from 'chartkick'; import Chartkick from 'chartkick';
import { toggle } from '@utils';
export function toggleChart(event, chartClass) { export function toggleChart(event, chartClass) {
const nextSelectorItem = $(event.target), const nextSelectorItem = event.target,
nextChart = $(chartClass), nextChart = document.querySelector(chartClass),
nextChartId = nextChart nextChartId = nextChart.children[0].id,
.children() currentSelectorItem = nextSelectorItem.parentElement.querySelector(
.first() '.segmented-control-item-active'
.attr('id'), ),
currentSelectorItem = nextSelectorItem currentChart = nextSelectorItem.parentElement.parentElement.querySelector(
.parent() '.chart:not(.hidden)'
.find('.segmented-control-item-active'), );
currentChart = nextSelectorItem
.parent()
.parent()
.find('.chart:not(.hidden)');
// Change the current selector and the next selector states // Change the current selector and the next selector states
currentSelectorItem.toggleClass('segmented-control-item-active'); currentSelectorItem.classList.toggle('segmented-control-item-active');
nextSelectorItem.toggleClass('segmented-control-item-active'); nextSelectorItem.classList.toggle('segmented-control-item-active');
// Hide the currently shown chart and show the new one // Hide the currently shown chart and show the new one
currentChart.toggleClass('hidden'); toggle(currentChart);
nextChart.toggleClass('hidden'); toggle(nextChart);
// Reflow needed, see https://github.com/highcharts/highcharts/issues/1979 // Reflow needed, see https://github.com/highcharts/highcharts/issues/1979
Chartkick.charts[nextChartId].getChartObject().reflow(); Chartkick.charts[nextChartId].getChartObject().reflow();

View file

@ -4,7 +4,6 @@ import Rails from 'rails-ujs';
import ActiveStorage from '../shared/activestorage/ujs'; import ActiveStorage from '../shared/activestorage/ujs';
import Chartkick from 'chartkick'; import Chartkick from 'chartkick';
import Highcharts from 'highcharts'; import Highcharts from 'highcharts';
import jQuery from 'jquery';
import '../shared/sentry'; import '../shared/sentry';
import '../shared/rails-ujs-fix'; import '../shared/rails-ujs-fix';
@ -41,11 +40,6 @@ Rails.start();
Turbolinks.start(); Turbolinks.start();
ActiveStorage.start(); ActiveStorage.start();
// Disable jQuery-driven animations during tests
if (process.env['RAILS_ENV'] === 'test') {
jQuery.fx.off = true;
}
// Expose globals // Expose globals
window.DS = window.DS || DS; window.DS = window.DS || DS;
window.Chartkick = Chartkick; window.Chartkick = Chartkick;

View file

@ -1,5 +1,5 @@
import $ from 'jquery';
import autocomplete from 'autocomplete.js'; import autocomplete from 'autocomplete.js';
import { getJSON, fire } from '@utils';
const sources = [ const sources = [
{ {
@ -24,7 +24,7 @@ function selector(type) {
function source(url) { function source(url) {
return { return {
source(query, callback) { source(query, callback) {
$.getJSON(url, { request: query }).then(callback); getJSON(url, { request: query }).then(callback);
}, },
templates: { templates: {
suggestion({ label, mine }) { suggestion({ label, mine }) {
@ -41,7 +41,7 @@ addEventListener('turbolinks:load', function() {
for (let target of document.querySelectorAll(selector(type))) { for (let target of document.querySelectorAll(selector(type))) {
let select = autocomplete(target, options, [source(url)]); let select = autocomplete(target, options, [source(url)]);
select.on('autocomplete:selected', ({ target }, suggestion) => { select.on('autocomplete:selected', ({ target }, suggestion) => {
$(target).trigger('autocomplete:select', suggestion); fire(target, 'autocomplete:select', suggestion);
select.autocomplete.setVal(suggestion.label); select.autocomplete.setVal(suggestion.label);
}); });
} }

View file

@ -1,12 +1,13 @@
import Rails from 'rails-ujs'; import Rails from 'rails-ujs';
import jQuery from 'jquery'; import jQuery from 'jquery';
import { delegate } from '@utils';
// We use `jQuery.active` in our capybara suit to wait for ajax requests. // We use `jQuery.active` in our capybara suit to wait for ajax requests.
// Newer jQuery-less version of rails-ujs is breaking it. // Newer jQuery-less version of rails-ujs is breaking it.
// We have to set `ajax:complete` listener on the same element as the one // We have to set `ajax:complete` listener on the same element as the one
// we catch ajax:send on as by the end of the request // we catch ajax:send on as by the end of the request
// the old element may be removed from DOM. // the old element may be removed from DOM.
Rails.delegate(document, '[data-remote]', 'ajax:send', ({ target }) => { delegate('ajax:send', '[data-remote]', ({ target }) => {
let callback = () => { let callback = () => {
jQuery.active--; jQuery.active--;
target.removeEventListener('ajax:complete', callback); target.removeEventListener('ajax:complete', callback);

View file

@ -1,7 +1,4 @@
import Rails from 'rails-ujs'; import { delegate, fire, debounce } from '@utils';
import debounce from 'debounce';
const { delegate, fire } = Rails;
const remote = 'data-remote'; const remote = 'data-remote';
const inputChangeSelector = `input[${remote}], textarea[${remote}]`; const inputChangeSelector = `input[${remote}], textarea[${remote}]`;
@ -21,4 +18,4 @@ function isRemote(element) {
return value && value !== 'false'; return value && value !== 'false';
} }
delegate(document, inputChangeSelector, 'input', debounce(handleRemote, 200)); delegate('input', inputChangeSelector, debounce(handleRemote, 200));

View file

@ -1,3 +1,10 @@
import Rails from 'rails-ujs';
import $ from 'jquery';
import debounce from 'debounce';
export { debounce };
export const { fire } = Rails;
export function show({ classList }) { export function show({ classList }) {
classList.remove('hidden'); classList.remove('hidden');
} }
@ -9,3 +16,45 @@ export function hide({ classList }) {
export function toggle({ classList }) { export function toggle({ classList }) {
classList.toggle('hidden'); classList.toggle('hidden');
} }
export function delegate(eventNames, selector, callback) {
eventNames
.split(' ')
.forEach(eventName =>
Rails.delegate(document, selector, eventName, callback)
);
}
export function getJSON(url, data, method = 'get') {
data = method !== 'get' ? JSON.stringify(data) : data;
return $.ajax({
method,
url,
data,
contentType: 'application/json',
dataType: 'json'
});
}
export function scrollTo(container, scrollTo) {
container.scrollTop =
offset(scrollTo).top - offset(container).top + container.scrollTop;
}
export function scrollToBottom(container) {
container.scrollTop = container.scrollHeight;
}
export function on(selector, eventName, fn) {
[...document.querySelectorAll(selector)].forEach(element =>
element.addEventListener(eventName, event => fn(event, event.detail))
);
}
function offset(element) {
const rect = element.getBoundingClientRect();
return {
top: rect.top + document.body.scrollTop,
left: rect.left + document.body.scrollLeft
};
}

View file

@ -35,7 +35,7 @@ class Commentaire < ApplicationRecord
def notify def notify
dossier_user_email = dossier.user.email dossier_user_email = dossier.user.email
invited_users_emails = dossier.invites_user.pluck(:email).to_a invited_users_emails = dossier.invites.pluck(:email).to_a
# - If the email is the contact email, the commentaire is a copy # - If the email is the contact email, the commentaire is a copy
# of an automated notification email we sent to a user, so do nothing. # of an automated notification email we sent to a user, so do nothing.

View file

@ -24,8 +24,6 @@ class Dossier < ApplicationRecord
has_many :cadastres, dependent: :destroy has_many :cadastres, dependent: :destroy
has_many :commentaires, dependent: :destroy has_many :commentaires, dependent: :destroy
has_many :invites, dependent: :destroy has_many :invites, dependent: :destroy
has_many :invites_user, class_name: 'InviteUser', dependent: :destroy
has_many :invites_gestionnaires, class_name: 'InviteGestionnaire', dependent: :destroy
has_many :follows has_many :follows
has_many :followers_gestionnaires, through: :follows, source: :gestionnaire has_many :followers_gestionnaires, through: :follows, source: :gestionnaire
has_many :avis, dependent: :destroy has_many :avis, dependent: :destroy
@ -160,7 +158,7 @@ class Dossier < ApplicationRecord
end end
def invite_for_user(user) def invite_for_user(user)
invites_user.find_by(user_id: user.id) invites.find_by(user_id: user.id)
end end
def can_be_en_construction? def can_be_en_construction?

View file

@ -1,2 +0,0 @@
class InviteGestionnaire < Invite
end

View file

@ -1,2 +0,0 @@
class InviteUser < Invite
end

View file

@ -10,8 +10,7 @@ class DossierSerializer < ActiveModel::Serializer
:received_at, :received_at,
:processed_at, :processed_at,
:motivation, :motivation,
:instructeurs, :instructeurs
:invites
has_one :individual has_one :individual
has_one :entreprise has_one :entreprise
@ -62,10 +61,6 @@ class DossierSerializer < ActiveModel::Serializer
object.followers_gestionnaires.pluck(:email) object.followers_gestionnaires.pluck(:email)
end end
def invites
object.invites_gestionnaires.pluck(:email)
end
private private
def user_geometry(dossier) def user_geometry(dossier)

View file

@ -1,4 +1,4 @@
.motivation{ class: popup_class } .motivation.hidden{ class: popup_class }
%h3 %h3
%span.icon{ class: popup_class } %span.icon{ class: popup_class }
#{popup_title} #{popup_title}

View file

@ -17,7 +17,7 @@
.confidentiel-wrapper .confidentiel-wrapper
= f.label :confidentiel, 'Cet avis est' = f.label :confidentiel, 'Cet avis est'
= f.select :confidentiel, [['partagé avec les autres experts', false], ['confidentiel', true]], {}, onchange: "javascript:DS.toggleCondidentielExplanation(event);" = f.select :confidentiel, [['partagé avec les autres experts', false], ['confidentiel', true]], {}, onchange: "javascript:DS.toggleCondidentielExplanation(event);"
.confidentiel-explanation .confidentiel-explanation.hidden
Il ne sera pas affiché aux autres experts consultés mais sera visible par les instructeurs Il ne sera pas affiché aux autres experts consultés mais sera visible par les instructeurs
.send-wrapper .send-wrapper
= f.submit 'Demander un avis', class: 'button send' = f.submit 'Demander un avis', class: 'button send'

View file

@ -1,3 +1,4 @@
const path = require('path');
const { environment } = require('@rails/webpacker'); const { environment } = require('@rails/webpacker');
// By default don't transpile JS files in ./node_modules except for some specific modules. // By default don't transpile JS files in ./node_modules except for some specific modules.
@ -14,4 +15,12 @@ babelLoader.exclude = function(modulePath) {
); );
}; };
const resolve = {
alias: {
'@utils': path.resolve(__dirname, '..', '..', 'app/javascript/shared/utils')
}
};
environment.config.merge({ resolve });
module.exports = environment; module.exports = environment;

View file

@ -0,0 +1,5 @@
class RemoveTypeFromInvites < ActiveRecord::Migration[5.2]
def change
remove_column :invites, :type
end
end

View file

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2018_10_02_164310) do ActiveRecord::Schema.define(version: 2018_10_10_070424) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -384,7 +384,6 @@ ActiveRecord::Schema.define(version: 2018_10_02_164310) do
t.string "email_sender" t.string "email_sender"
t.integer "dossier_id" t.integer "dossier_id"
t.integer "user_id" t.integer "user_id"
t.string "type", default: "InviteGestionnaire"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end

View file

@ -139,7 +139,7 @@ describe API::V1::DossiersController do
let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure, motivation: "Motivation") } } let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure, motivation: "Motivation") } }
let(:dossier_id) { dossier.id } let(:dossier_id) { dossier.id }
let(:body) { JSON.parse(retour.body, symbolize_names: true) } let(:body) { JSON.parse(retour.body, symbolize_names: true) }
let(:field_list) { [:id, :created_at, :updated_at, :archived, :individual, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state, :simplified_state, :initiated_at, :processed_at, :received_at, :motivation, :email, :instructeurs, :invites] } let(:field_list) { [:id, :created_at, :updated_at, :archived, :individual, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state, :simplified_state, :initiated_at, :processed_at, :received_at, :motivation, :email, :instructeurs] }
subject { body[:dossier] } subject { body[:dossier] }
it 'return REST code 200', :show_in_doc do it 'return REST code 200', :show_in_doc do

View file

@ -44,7 +44,7 @@ describe InvitesController, type: :controller do
sign_in(user) sign_in(user)
end end
it { expect { subject }.to change(InviteUser, :count).by(1) } it { expect { subject }.to change(Invite, :count).by(1) }
end end
end end
end end
@ -54,7 +54,7 @@ describe InvitesController, type: :controller do
shared_examples_for "he can not create a invite" do shared_examples_for "he can not create a invite" do
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) } it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
it { expect { subject rescue nil }.to change(InviteUser, :count).by(0) } it { expect { subject rescue nil }.to change(Invite, :count).by(0) }
end end
context 'when user has no access to dossier' do context 'when user has no access to dossier' do
@ -73,7 +73,7 @@ describe InvitesController, type: :controller do
dossier.update(user: signed_in_profile) dossier.update(user: signed_in_profile)
end end
it { expect { subject }.to change(InviteUser, :count).by(1) } it { expect { subject }.to change(Invite, :count).by(1) }
it "redirects to the previous URL" do it "redirects to the previous URL" do
expect(subject).to redirect_to("/dossiers/#{dossier.id}/brouillon") expect(subject).to redirect_to("/dossiers/#{dossier.id}/brouillon")

View file

@ -50,13 +50,13 @@ describe NewUser::DossiersController, type: :controller do
end end
context 'when an invite asks for a dossier where they were invited' do context 'when an invite asks for a dossier where they were invited' do
before { create(:invite, dossier: asked_dossier, user: user, type: 'InviteUser') } before { create(:invite, dossier: asked_dossier, user: user) }
it_behaves_like 'redirects and flashes' it_behaves_like 'redirects and flashes'
end end
context 'when an invite asks for another dossier' do context 'when an invite asks for another dossier' do
before { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') } before { create(:invite, dossier: create(:dossier), user: user) }
it_behaves_like 'redirects and flashes' it_behaves_like 'redirects and flashes'
end end
@ -84,13 +84,13 @@ describe NewUser::DossiersController, type: :controller do
end end
context 'when an invite asks for a dossier where they were invited' do context 'when an invite asks for a dossier where they were invited' do
before { create(:invite, dossier: asked_dossier, user: user, type: 'InviteUser') } before { create(:invite, dossier: asked_dossier, user: user) }
it_behaves_like 'does not redirect nor flash' it_behaves_like 'does not redirect nor flash'
end end
context 'when an invite asks for another dossier' do context 'when an invite asks for another dossier' do
before { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') } before { create(:invite, dossier: create(:dossier), user: user) }
it_behaves_like 'redirects and flashes' it_behaves_like 'redirects and flashes'
end end
@ -123,14 +123,14 @@ describe NewUser::DossiersController, type: :controller do
end end
context 'when an invite save the draft for a dossier where they where invited' do context 'when an invite save the draft for a dossier where they where invited' do
before { create(:invite, dossier: asked_dossier, user: user, type: 'InviteUser') } before { create(:invite, dossier: asked_dossier, user: user) }
let(:draft) { true } let(:draft) { true }
it_behaves_like 'does not redirect nor flash' it_behaves_like 'does not redirect nor flash'
end end
context 'when an invite submit a dossier where they where invited' do context 'when an invite submit a dossier where they where invited' do
before { create(:invite, dossier: asked_dossier, user: user, type: 'InviteUser') } before { create(:invite, dossier: asked_dossier, user: user) }
let(:draft) { false } let(:draft) { false }
it_behaves_like 'redirects and flashes' it_behaves_like 'redirects and flashes'
@ -370,7 +370,7 @@ describe NewUser::DossiersController, type: :controller do
context 'when the user has an invitation but is not the owner' do context 'when the user has an invitation but is not the owner' do
let(:dossier) { create(:dossier) } let(:dossier) { create(:dossier) }
let!(:invite) { create(:invite, dossier: dossier, user: user, type: 'InviteUser') } let!(:invite) { create(:invite, dossier: dossier, user: user) }
context 'and the invite saves a draft' do context 'and the invite saves a draft' do
let(:payload) { submit_payload.merge(save_draft: true) } let(:payload) { submit_payload.merge(save_draft: true) }
@ -493,7 +493,7 @@ describe NewUser::DossiersController, type: :controller do
context 'when the user has an invitation but is not the owner' do context 'when the user has an invitation but is not the owner' do
let(:dossier) { create(:dossier) } let(:dossier) { create(:dossier) }
let!(:invite) { create(:invite, dossier: dossier, user: user, type: 'InviteUser') } let!(:invite) { create(:invite, dossier: dossier, user: user) }
before do before do
dossier.en_construction! dossier.en_construction!
@ -525,7 +525,7 @@ describe NewUser::DossiersController, type: :controller do
end end
context 'when the user only have some dossiers invites' do context 'when the user only have some dossiers invites' do
let!(:invite) { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') } let!(:invite) { create(:invite, dossier: create(:dossier), user: user) }
before { get(:index) } before { get(:index) }
@ -535,7 +535,7 @@ describe NewUser::DossiersController, type: :controller do
context 'when the user has both' do context 'when the user has both' do
let!(:own_dossier) { create(:dossier, user: user) } let!(:own_dossier) { create(:dossier, user: user) }
let!(:invite) { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') } let!(:invite) { create(:invite, dossier: create(:dossier), user: user) }
context 'and there is no current_tab param' do context 'and there is no current_tab param' do
before { get(:index) } before { get(:index) }
@ -560,8 +560,8 @@ describe NewUser::DossiersController, type: :controller do
before do before do
Timecop.freeze(4.days.ago) { create(:dossier, user: user) } Timecop.freeze(4.days.ago) { create(:dossier, user: user) }
Timecop.freeze(2.days.ago) { create(:dossier, user: user) } Timecop.freeze(2.days.ago) { create(:dossier, user: user) }
Timecop.freeze(4.days.ago) { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') } Timecop.freeze(4.days.ago) { create(:invite, dossier: create(:dossier), user: user) }
Timecop.freeze(2.days.ago) { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') } Timecop.freeze(2.days.ago) { create(:invite, dossier: create(:dossier), user: user) }
get(:index) get(:index)
end end

View file

@ -17,7 +17,7 @@ RSpec.describe Users::CarteController, type: :controller do
let(:adresse) { etablissement.geo_adresse } let(:adresse) { etablissement.geo_adresse }
before do before do
create :invite, dossier: dossier, user: invite_by_user, email: invite_by_user.email, type: 'InviteUser' create :invite, dossier: dossier, user: invite_by_user, email: invite_by_user.email
sign_in user sign_in user
end end

View file

@ -20,7 +20,7 @@ describe UsersController, type: :controller do
context 'when user is invite by the owner' do context 'when user is invite by the owner' do
before do before do
create :invite, email: invite_user.email, dossier: dossier, user: invite_user, type: 'InviteUser' create :invite, email: invite_user.email, dossier: dossier, user: invite_user
sign_in invite_user sign_in invite_user
end end

View file

@ -1,24 +0,0 @@
FactoryBot.define do
factory :invite_user do
email { 'plop@octo.com' }
after(:build) do |invite, _evaluator|
if invite.dossier.nil?
invite.dossier = create(:dossier)
end
if invite.user.present?
invite.email = invite.user.email
end
end
trait :with_user do
after(:build) do |invite, _evaluator|
if invite.user.nil?
invite.user = create(:user)
invite.email = invite.user.email
end
end
end
end
end

View file

@ -5,7 +5,7 @@ feature 'Invitations' do
let(:owner) { create(:user) } let(:owner) { create(:user) }
let(:invited_user) { create(:user, email: 'user_invite@exemple.fr') } let(:invited_user) { create(:user, email: 'user_invite@exemple.fr') }
let(:procedure) { create(:simple_procedure) } let(:procedure) { create(:simple_procedure) }
let(:invite) { create(:invite_user, user: invited_user, dossier: dossier) } let(:invite) { create(:invite, user: invited_user, dossier: dossier) }
context 'when the dossier is a brouillon' do context 'when the dossier is a brouillon' do
let!(:dossier) { create(:dossier, :for_individual, state: Dossier.states.fetch(:brouillon), user: owner, procedure: procedure) } let!(:dossier) { create(:dossier, :for_individual, state: Dossier.states.fetch(:brouillon), user: owner, procedure: procedure) }
@ -26,7 +26,7 @@ feature 'Invitations' do
end end
context 'when inviting someone without an existing account' do context 'when inviting someone without an existing account' do
let(:invite) { create(:invite_user, dossier: dossier, user: nil) } let(:invite) { create(:invite, dossier: dossier, user: nil) }
let(:user_password) { 'l33tus3r' } let(:user_password) { 'l33tus3r' }
scenario 'an invited user can register using the registration link sent in the invitation email' do scenario 'an invited user can register using the registration link sent in the invitation email' do

View file

@ -33,7 +33,7 @@ RSpec.describe CommentaireHelper, type: :helper do
describe '.commentaire_is_from_guest' do describe '.commentaire_is_from_guest' do
let(:dossier) { create(:dossier) } let(:dossier) { create(:dossier) }
let!(:guest) { create(:invite_user, dossier: dossier) } let!(:guest) { create(:invite, dossier: dossier) }
subject { commentaire_is_from_guest(commentaire) } subject { commentaire_is_from_guest(commentaire) }

View file

@ -66,7 +66,7 @@ describe User, type: :model do
context 'when user was invited by user' do context 'when user was invited by user' do
before do before do
create(:invite, dossier: dossier, user: invite_user, type: 'InviteUser') create(:invite, dossier: dossier, user: invite_user)
end end
let(:user) { invite_user } let(:user) { invite_user }
@ -116,7 +116,7 @@ describe User, type: :model do
context 'when user was invited by user' do context 'when user was invited by user' do
before do before do
create(:invite, dossier: dossier, user: invite_user, type: 'InviteUser') create(:invite, dossier: dossier, user: invite_user)
end end
let(:user) { invite_user } let(:user) { invite_user }