Merge branch 'recurrent'
This commit is contained in:
commit
dfc18d452d
2
Gemfile
2
Gemfile
@ -2,6 +2,8 @@ source 'https://rubygems.org'
|
||||
|
||||
# The central piece of this application: the month calendar view
|
||||
gem 'simple_calendar'
|
||||
# The recurrence management library
|
||||
gem 'ice_cube'
|
||||
|
||||
gem 'rails'
|
||||
gem 'has_scope'
|
||||
|
@ -210,6 +210,7 @@ GEM
|
||||
http_accept_language (2.0.5)
|
||||
http_parser.rb (0.6.0)
|
||||
i18n (0.7.0)
|
||||
ice_cube (0.14.0)
|
||||
inherited_resources (1.6.0)
|
||||
actionpack (>= 3.2, < 5)
|
||||
has_scope (~> 0.6.0.rc)
|
||||
@ -445,6 +446,7 @@ DEPENDENCIES
|
||||
has_scope
|
||||
http_accept_language
|
||||
i18n-active_record!
|
||||
ice_cube
|
||||
jbuilder
|
||||
jquery-rails (< 4.1)
|
||||
jquery-sparkline-rails!
|
||||
|
@ -1,4 +1,14 @@
|
||||
$(document).on 'turbolinks:load', ->
|
||||
# Quick mechanism so that the ice cube rule only appears when useful
|
||||
if $('#event_repeat').val() == '0'
|
||||
$('.field.rule').hide()
|
||||
|
||||
$('#event_repeat').change ->
|
||||
if $(this).val() > 0
|
||||
$('.field.rule').show()
|
||||
else
|
||||
$('.field.rule').hide()
|
||||
|
||||
# Manage event tags edition
|
||||
$('#event_tags').each ->
|
||||
elt = $(this)
|
||||
|
@ -52,6 +52,10 @@
|
||||
content: $fa-var-toggle-on
|
||||
.field.end_time label:before
|
||||
content: $fa-var-toggle-off
|
||||
.field.repeat label:before
|
||||
content: $fa-var-repeat
|
||||
.field.rule > label:before
|
||||
content: $fa-var-calculator
|
||||
.field.description label:before
|
||||
content: $fa-var-pencil-square-o
|
||||
.field.place_name label:before
|
||||
|
@ -102,9 +102,9 @@ class EventsController < ApplicationController
|
||||
# through
|
||||
def event_params
|
||||
params.require(:event)
|
||||
.permit :lock_version, :title, :start_time, :end_time, :description,
|
||||
:place_name, :address, :city, :region_id, :locality, :url,
|
||||
:contact, :submitter, :tags
|
||||
.permit :lock_version, :title, :start_time, :end_time, :repeat, :rule,
|
||||
:description, :place_name, :address, :city, :region_id,
|
||||
:locality, :url, :contact, :submitter, :tags
|
||||
end
|
||||
|
||||
def locked
|
||||
|
@ -65,9 +65,9 @@ class ModerationsController < ApplicationController
|
||||
# through.
|
||||
def moderation_params
|
||||
params.require(:event)
|
||||
.permit :lock_version, :title, :start_time, :end_time, :description,
|
||||
:place_name, :address, :city, :region_id, :locality, :url,
|
||||
:contact, :submitter, :tags
|
||||
.permit :lock_version, :title, :start_time, :end_time, :repeat, :rule,
|
||||
:description, :place_name, :address, :city, :region_id,
|
||||
:locality, :url, :contact, :submitter, :tags
|
||||
end
|
||||
|
||||
# Useful to manage absolute url in mails
|
||||
|
@ -2,14 +2,20 @@
|
||||
class Event < ActiveRecord::Base
|
||||
extend SimpleCalendar
|
||||
strip_attributes
|
||||
has_paper_trail ignore: [:last_updated, :secret, :submitter, :decision_time,
|
||||
:lock_version, :latitude, :longitude]
|
||||
has_paper_trail ignore: [:last_updated, :lock_version, :secret,
|
||||
:submitter, :decision_time,
|
||||
:latitude, :longitude]
|
||||
|
||||
belongs_to :region
|
||||
# This is the scheduled first event
|
||||
belongs_to :event
|
||||
has_many :notes, dependent: :destroy
|
||||
has_many :events, dependent: :destroy
|
||||
|
||||
validates :title, presence: true
|
||||
validate :end_after_start
|
||||
RULES = %w(daily weekly monthly).freeze
|
||||
validates :rule, inclusion: RULES
|
||||
validates :description, presence: true
|
||||
validates :city, presence: true
|
||||
validates :region, presence: true
|
||||
@ -25,8 +31,14 @@ class Event < ActiveRecord::Base
|
||||
# Mechanism to store some reason which can be used when sending notifications
|
||||
attr_accessor :reason
|
||||
|
||||
before_validation EventCallbacks
|
||||
|
||||
before_create EventCallbacks
|
||||
after_create EventCallbacks
|
||||
|
||||
before_update EventCallbacks
|
||||
after_update EventCallbacks
|
||||
|
||||
after_destroy EventCallbacks
|
||||
|
||||
scope :moderated, ->(*) { where moderated: true }
|
||||
@ -55,11 +67,6 @@ class Event < ActiveRecord::Base
|
||||
scope :tag, ->(tag) { where 'tags like ?', "%#{tag}%" }
|
||||
scope :geo, -> { where 'latitude is not null and longitude is not null' }
|
||||
|
||||
before_validation do
|
||||
# Tags are always downcased
|
||||
self.tags = tags.mb_chars.downcase if tags
|
||||
end
|
||||
|
||||
before_validation on: :create do
|
||||
self.submission_time = Time.zone.now
|
||||
self.decision_time = Time.zone.now
|
||||
@ -73,22 +80,11 @@ class Event < ActiveRecord::Base
|
||||
self.longitude = nil if address_changed?
|
||||
end
|
||||
|
||||
before_create do
|
||||
self.secret = SecureRandom.urlsafe_base64(32)[0...32]
|
||||
self.moderator_mail_id = SecureRandom.urlsafe_base64(32)[0...32]
|
||||
self.submitter_mail_id = SecureRandom.urlsafe_base64(32)[0...32]
|
||||
end
|
||||
|
||||
before_update do
|
||||
self.decision_time = Time.zone.now if moderated? && moderated_changed?
|
||||
end
|
||||
|
||||
def as_json(_options = {})
|
||||
{ type: 'Feature', properties: {
|
||||
id: id, name: title, start_time: start_time, end_time: end_time,
|
||||
place_name: place_name, address: address, city: city, locality: locality,
|
||||
tags: tags,
|
||||
popupContent: "<a href=\"/events/#{id}\">#{self}</a>"
|
||||
tags: tags, popupContent: "<a href=\"/events/#{id}\">#{self}</a>"
|
||||
}, geometry: { type: 'Point', coordinates: [longitude, latitude] } }
|
||||
end
|
||||
|
||||
@ -98,6 +94,12 @@ class Event < ActiveRecord::Base
|
||||
[address, city].compact.join ', '
|
||||
end
|
||||
|
||||
def schedule
|
||||
IceCube::Schedule.new(start_time, end_time: end_time) do |s|
|
||||
s.add_recurrence_rule IceCube::Rule.send(rule).count(repeat + 1)
|
||||
end
|
||||
end
|
||||
|
||||
def hashtags
|
||||
tags.split.map { |tag| "##{tag.tr('-', '_').camelize :lower}" }
|
||||
end
|
||||
|
@ -1,29 +1,67 @@
|
||||
# All the mail and tweet related callbacks to event's lifecycle
|
||||
# also the scheduled events
|
||||
class EventCallbacks
|
||||
def self.before_validation(event)
|
||||
# Tags are always downcased
|
||||
event.tags = event.tags.mb_chars.downcase if event.tags
|
||||
end
|
||||
|
||||
def self.before_create(event)
|
||||
event.secret = SecureRandom.urlsafe_base64(32)[0...32]
|
||||
event.moderator_mail_id = SecureRandom.urlsafe_base64(32)[0...32]
|
||||
event.submitter_mail_id = SecureRandom.urlsafe_base64(32)[0...32]
|
||||
end
|
||||
|
||||
def self.after_create(event)
|
||||
EventMailer.create(event).deliver_now!
|
||||
ModerationMailer.create(event).deliver_now!
|
||||
end
|
||||
|
||||
def self.before_update(event)
|
||||
if event.moderated_changed? && event.moderated?
|
||||
event.decision_time = Time.zone.now
|
||||
create_repeats event if event.repeat > 0
|
||||
end
|
||||
end
|
||||
|
||||
def self.after_update(event)
|
||||
if event.moderated_changed?
|
||||
tweet(event)
|
||||
tweet event
|
||||
|
||||
if ActionMailer::Base.default_url_options[:host]
|
||||
# Send an acceptation mail to its author
|
||||
EventMailer.accept(event).deliver_now
|
||||
|
||||
# Send an acceptation mail to moderators
|
||||
ModerationMailer.accept(event).deliver_now
|
||||
else
|
||||
end
|
||||
|
||||
elsif ActionMailer::Base.default_url_options[:host]
|
||||
# Send an update mail to moderators
|
||||
ModerationMailer.update(event).deliver_now
|
||||
end
|
||||
end
|
||||
|
||||
def self.after_destroy(event)
|
||||
if ActionMailer::Base.default_url_options[:host]
|
||||
EventMailer.destroy(event).deliver_now
|
||||
ModerationMailer.destroy(event).deliver_now
|
||||
end
|
||||
end
|
||||
|
||||
# Create multiple events corresponding to a repetition
|
||||
def self.create_repeats(event)
|
||||
event.schedule.last(event.repeat).each do |schedule|
|
||||
event.events.build create_sub_event(event, schedule)
|
||||
end
|
||||
end
|
||||
|
||||
def self.create_sub_event(event, schedule)
|
||||
att = event.attributes.reject { |a| a == 'id' || a == 'lock_version' }
|
||||
att[:start_time] = schedule.start_time
|
||||
att[:end_time] = schedule.end_time
|
||||
att
|
||||
end
|
||||
|
||||
# Tweet this event, if configured using apache/system variables!
|
||||
def self.tweet(event)
|
||||
|
@ -7,6 +7,13 @@
|
||||
= t '.delete_link'
|
||||
= cancel_event_url @event, secret: @event.secret
|
||||
\
|
||||
- if @event.repeat > 0 && !@event.event_id
|
||||
= t '.repeat_helper', count: @event.repeat
|
||||
- @event.events.each do |e|
|
||||
= e
|
||||
= edit_event_url e, secret: e.secret
|
||||
= cancel_event_url e, secret: e.secret
|
||||
\
|
||||
= render file: '/events/show'
|
||||
\
|
||||
= t '.signature'
|
||||
|
@ -6,3 +6,5 @@
|
||||
= link_to event do
|
||||
%strong.city{ title: event.address }= event.city
|
||||
= event.title
|
||||
- if event.repeat > 0
|
||||
%em.fa.fa-repeat(title="#{event.repeat} - #{t event.rule, scope: 'activerecord.attributes.event.rule_values'}")
|
||||
|
@ -12,13 +12,30 @@
|
||||
|
||||
.field.title
|
||||
= f.label :title
|
||||
= f.text_field :title, required: true, placeholder: "#{t '.title_helper'}"
|
||||
= f.text_field :title, required: true, placeholder: t('.title_helper')
|
||||
.field.start_time
|
||||
= f.label :start_time
|
||||
= f.datetime_local_field :start_time, required: true
|
||||
.field.end_time
|
||||
= f.label :end_time
|
||||
= f.datetime_local_field :end_time, required: true
|
||||
|
||||
- unless @event.moderated?
|
||||
.field.repeat
|
||||
= f.label :repeat
|
||||
= f.number_field :repeat, in: 0..40, maxlength: 2, size: 2
|
||||
|
||||
.field.rule
|
||||
.helper
|
||||
:markdown
|
||||
#{t '.rule_helper'}
|
||||
= f.label :rule
|
||||
%span.radios
|
||||
- Event::RULES.each do |rule|
|
||||
= f.radio_button :rule, rule
|
||||
= f.label "rule_#{rule}",
|
||||
t(rule, scope: 'activerecord.attributes.event.rule_values')
|
||||
|
||||
.field.description
|
||||
.helper
|
||||
:markdown
|
||||
@ -46,7 +63,8 @@
|
||||
%option= city
|
||||
.field.region
|
||||
= f.label :region
|
||||
= f.collection_select :region_id, Region.all, :id, :name, { include_blank: true }
|
||||
= f.collection_select :region_id, Region.all, :id, :name,
|
||||
include_blank: true
|
||||
.field.locality
|
||||
= f.label :locality
|
||||
%span.radios
|
||||
|
@ -77,8 +77,8 @@
|
||||
"http://fr.wikipedia.org/wiki/#{url_encode @event.region.try :name}"
|
||||
|
||||
- if @event.latitude && @event.longitude
|
||||
.event#map{ data: { url: "#{maps_path format: :json}",
|
||||
latitude: "#{@event.latitude}", longitude: "#{@event.longitude}" } }
|
||||
.event#map{ data: { url: maps_path(format: :json),
|
||||
latitude: @event.latitude, longitude: @event.longitude } }
|
||||
|
||||
- elsif controller.action_name != 'show'
|
||||
%em.fa.fa-compress
|
||||
@ -114,3 +114,13 @@
|
||||
%span.label= Event.human_attribute_name :tags
|
||||
- @event.tags.split.each do |tag|
|
||||
= link_to tag, tag_path(tag), rel: :tag
|
||||
|
||||
- if @event.repeat > 0
|
||||
%h3
|
||||
%em.fa.fa-repeat
|
||||
= t @event.rule, scope: 'activerecord.attributes.event.rule_values'
|
||||
|
||||
%ul
|
||||
%li= link_to_unless_current @event.event || @event, @event.event || @event
|
||||
- (@event.event || @event).events.each do |e|
|
||||
%li= link_to_unless_current e, e
|
||||
|
@ -2,6 +2,9 @@
|
||||
#{Event.human_attribute_name(:title).concat(':').ljust 12 } #{@event.title}
|
||||
#{Event.human_attribute_name(:start_time).concat(':').ljust 12 } #{l @event.start_time, format: :at}
|
||||
#{Event.human_attribute_name(:end_time).concat(':').ljust 12 } #{l @event.end_time, format: :at}
|
||||
-if @event.repeat > 0
|
||||
#{Event.human_attribute_name(:repeat).concat(':').ljust 12 } #{@event.repeat}
|
||||
#{Event.human_attribute_name(:rule).concat(':').ljust 12 } #{t @event.rule, scope: 'activerecord.attributes.event.rule_values'}
|
||||
#{Event.human_attribute_name(:place_name).concat(':').ljust 12 } #{@event.place_name}
|
||||
#{Event.human_attribute_name(:address).concat(':').ljust 12 } #{@event.address}
|
||||
#{Event.human_attribute_name(:city).concat(':').ljust 12 } #{@event.city}
|
||||
|
@ -24,6 +24,18 @@
|
||||
|
||||
= @event.to_tweet
|
||||
|
||||
- if @event.repeat > 0
|
||||
%fieldset
|
||||
%legend
|
||||
%em.fa.fa-repeat
|
||||
= Event.human_attribute_name :repeat
|
||||
|
||||
%h3= t '.repeat_helper', count: @event.repeat
|
||||
|
||||
%p.rule
|
||||
= Event.human_attribute_name :rule
|
||||
= t @event.rule, scope: 'activerecord.attributes.event.rule_values'
|
||||
|
||||
%fieldset
|
||||
%legend
|
||||
%em.fa.fa-calendar
|
||||
|
173
config/locales/ice_cube.fr.yml
Normal file
173
config/locales/ice_cube.fr.yml
Normal file
@ -0,0 +1,173 @@
|
||||
fr:
|
||||
ice_cube:
|
||||
pieces_connector: ' / '
|
||||
not: 'pas %{target}'
|
||||
not_on: 'pas durant %{target}'
|
||||
date:
|
||||
formats:
|
||||
default: '%d %B %Y'
|
||||
month_names:
|
||||
-
|
||||
- janvier
|
||||
- février
|
||||
- mars
|
||||
- avril
|
||||
- mai
|
||||
- juin
|
||||
- juillet
|
||||
- août
|
||||
- septembre
|
||||
- octobre
|
||||
- novembre
|
||||
- décembre
|
||||
day_names:
|
||||
- dimanche
|
||||
- lundi
|
||||
- mardi
|
||||
- mercredi
|
||||
- jeudi
|
||||
- vendredi
|
||||
- samedi
|
||||
times:
|
||||
other: '%{count} fois'
|
||||
one: '%{count} fois'
|
||||
until: "jusqu'au %{date}"
|
||||
days_of_week: '%{segments} %{day}'
|
||||
days_of_month:
|
||||
other: '%{segments} jours du mois'
|
||||
one: '%{segments} jours du mois'
|
||||
days_of_year:
|
||||
other: "%{segments} jours de l'année"
|
||||
one: "%{segments} jours de l'année"
|
||||
at_hours_of_the_day:
|
||||
other: aux %{segments} heures de la journée
|
||||
one: à %{segments}h
|
||||
on_minutes_of_hour:
|
||||
other: aux %{segments} minutes de l'heure
|
||||
one: à la %{segments} minute de l'heure
|
||||
at_seconds_of_minute:
|
||||
other: aux %{segments} secondes
|
||||
one: à la %{segments} seconde
|
||||
on_seconds_of_minute:
|
||||
other: aux %{segments} secondes de la minute
|
||||
one: à la %{segments} seconde de la minute
|
||||
each_second:
|
||||
one: Toutes les secondes
|
||||
other: Toutes les %{count} secondes
|
||||
each_minute:
|
||||
one: Toutes les minutes
|
||||
other: Toutes les %{count} minutes
|
||||
each_hour:
|
||||
one: Toutes les heures
|
||||
other: Toutes les %{count} heures
|
||||
each_day:
|
||||
one: Quotidien
|
||||
other: Tous les %{count} jours
|
||||
each_week:
|
||||
one: Hebdomadaire
|
||||
other: Toutes les %{count} semaines
|
||||
each_month:
|
||||
one: Mensuel
|
||||
other: Tous les %{count} mois
|
||||
each_year:
|
||||
one: Annuel
|
||||
other: Tous les %{count} ans
|
||||
'on': les %{sentence}
|
||||
in: 'en %{target}'
|
||||
integer:
|
||||
negative: '%{ordinal} depuis la fin'
|
||||
literal_ordinals:
|
||||
-1: derniers
|
||||
-2: avant-derniers
|
||||
ordinal: '%{number}%{ordinal}'
|
||||
ordinals:
|
||||
default: '°'
|
||||
1: °
|
||||
on_weekends: pendant les weekends
|
||||
on_weekdays: pendant les jours ouvrés
|
||||
days_on:
|
||||
- dimanches
|
||||
- lundis
|
||||
- mardis
|
||||
- mercredis
|
||||
- jeudis
|
||||
- vendredis
|
||||
- samedis
|
||||
on_days: les %{days}
|
||||
array:
|
||||
last_word_connector: ', et '
|
||||
two_words_connector: ' et '
|
||||
words_connector: ', '
|
||||
string:
|
||||
format:
|
||||
day: '%{rest} %{current}'
|
||||
day_of_week: '%{rest} %{current}'
|
||||
day_of_month: '%{rest} %{current}'
|
||||
day_of_year: '%{rest} %{current}'
|
||||
hour_of_day: '%{rest} %{current}'
|
||||
minute_of_hour: '%{rest} %{current}'
|
||||
until: '%{rest} %{current}'
|
||||
count: '%{rest} %{current}'
|
||||
default: '%{rest} %{current}'
|
||||
|
||||
date:
|
||||
abbr_day_names:
|
||||
- Dim
|
||||
- Lun
|
||||
- Mar
|
||||
- Mer
|
||||
- Jeu
|
||||
- Ven
|
||||
- Sam
|
||||
abbr_month_names:
|
||||
-
|
||||
- Jan
|
||||
- Fév
|
||||
- Mar
|
||||
- Avr
|
||||
- Mai
|
||||
- Jun
|
||||
- Jul
|
||||
- Aou
|
||||
- Sep
|
||||
- Oct
|
||||
- Nov
|
||||
- Déc
|
||||
day_names:
|
||||
- dimanche
|
||||
- lundi
|
||||
- mardi
|
||||
- mecredi
|
||||
- jeudi
|
||||
- vendredi
|
||||
- samedi
|
||||
formats:
|
||||
default: "%d-%m-%Y"
|
||||
long: "%d %B %Y"
|
||||
short: "%d %b"
|
||||
month_names:
|
||||
-
|
||||
- janvier
|
||||
- février
|
||||
- mars
|
||||
- avril
|
||||
- mai
|
||||
- juin
|
||||
- juillet
|
||||
- août
|
||||
- septembre
|
||||
- octobre
|
||||
- novembre
|
||||
- décembre
|
||||
order:
|
||||
- :year
|
||||
- :month
|
||||
- :day
|
||||
|
||||
time:
|
||||
am: am
|
||||
formats:
|
||||
default: "%a, %d %b %Y %H:%M:%S %z"
|
||||
long: "%d %B %Y %H:%M"
|
||||
short: "%d %b %H:%M"
|
||||
pm: pm
|
@ -63,6 +63,13 @@ en:
|
||||
title: Title
|
||||
start_time: Start
|
||||
end_time: End
|
||||
repeat: Repeat
|
||||
rule: Règle
|
||||
rule_values:
|
||||
daily: Daily
|
||||
weekly: Weekly
|
||||
monthly: Monthly
|
||||
yearly: Yearly
|
||||
description: Description
|
||||
place_name: Place name
|
||||
address: Address
|
||||
|
@ -63,6 +63,13 @@ fr:
|
||||
title: Titre
|
||||
start_time: Début
|
||||
end_time: Fin
|
||||
repeat: Répéter
|
||||
rule: Règle
|
||||
rule_values:
|
||||
daily: Journalière
|
||||
weekly: Hebdomadaire
|
||||
monthly: Mensuelle
|
||||
yearly: Annuelle
|
||||
description: Description
|
||||
place_name: Nom du lieu
|
||||
address: Adresse
|
||||
|
@ -89,6 +89,8 @@ it more readable or agreable.
|
||||
ok: Your event was updated
|
||||
form:
|
||||
title_helper: Less than 5 words, without address or date
|
||||
rule_helper: Repeated events will be generated during validation. You
|
||||
will receive by mail edition and cancellation links
|
||||
description_helper: Describe with as much precision as possible your event
|
||||
address_helper: Associated to the city and region, it will generate an
|
||||
[OpenStreetMap](http://www.openstreetmap.org) map, displayed alongside
|
||||
@ -179,6 +181,10 @@ it more readable or agreable.
|
||||
ok: Yes
|
||||
ko: Moderation
|
||||
tweet_helper: A tweet will be published, here is its content
|
||||
repeat_helper:
|
||||
zero:
|
||||
one: One other event will be generated
|
||||
other: "%{count} events will be generated"
|
||||
accept:
|
||||
ok: Event accepted
|
||||
refuse:
|
||||
@ -318,6 +324,10 @@ description."
|
||||
edit_link: "You can modify this event later to add details at the
|
||||
address:"
|
||||
delete_link: "You can can also cancel it at the address:"
|
||||
repeat_helper:
|
||||
zero:
|
||||
one: Another event was genereated, here are the edition and cancellation links
|
||||
other: "%{count} other events were generated, here are the edition and cancellation links"
|
||||
signature: Thank you for your contribution and see you soon!
|
||||
destroy:
|
||||
subject: "Event '%{subject}' refused"
|
||||
|
@ -80,6 +80,8 @@ fr:
|
||||
ok: Votre événement a été mis à jour
|
||||
form:
|
||||
title_helper: Moins de 5 mots, sans lieu ou date
|
||||
rule_helper: Les événements répétés seront générés lors de la
|
||||
validation. Vous recevrez par mail les liens d'édition et d'annulation
|
||||
description_helper: Décrivez de la manière la plus complète possible
|
||||
votre événement
|
||||
address_helper: "*Associée à la ville et la région, elle générera une
|
||||
@ -176,6 +178,10 @@ fr:
|
||||
ok: Oui
|
||||
ko: Modération
|
||||
tweet_helper: Un tweet sera publié, dont voici le contenu
|
||||
repeat_helper:
|
||||
zero:
|
||||
one: Un autre événement sera généré
|
||||
other: "%{count} autres événements seront générés"
|
||||
accept:
|
||||
ok: Événement accepté
|
||||
refuse:
|
||||
@ -324,6 +330,10 @@ est maintenant visible à l'adresse:"
|
||||
ajouter des précisions en vous rendant à l'adresse:"
|
||||
delete_link: "Vous pouvez également l'annuler en vous rendant à
|
||||
l'adresse:"
|
||||
repeat_helper:
|
||||
zero:
|
||||
one: Un autre événement a été généré, voici les liens d'édition et annulation
|
||||
other: "%{count} autres événements ont été générés, voici les liens d'édition et annulation"
|
||||
signature: Merci de votre contribution et à bientôt!
|
||||
destroy:
|
||||
subject: "Événement '%{subject}' refusé"
|
||||
|
9
db/migrate/20160616190823_create_schedules.rb
Normal file
9
db/migrate/20160616190823_create_schedules.rb
Normal file
@ -0,0 +1,9 @@
|
||||
# Manage a schedule for events, that will let adl create recurring events
|
||||
class CreateSchedules < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :events, :repeat, :integer, default: 0
|
||||
add_column :events, :rule, :text, default: 'daily'
|
||||
# This column is there to manage scheduled events
|
||||
add_reference :events, :event, index: true
|
||||
end
|
||||
end
|
@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20160409131029) do
|
||||
ActiveRecord::Schema.define(version: 20160616190823) do
|
||||
|
||||
create_table "active_admin_comments", force: :cascade do |t|
|
||||
t.string "namespace", limit: 255
|
||||
@ -81,8 +81,13 @@ ActiveRecord::Schema.define(version: 20160409131029) do
|
||||
t.float "longitude", limit: 24
|
||||
t.integer "lock_version", limit: 4, default: 0, null: false
|
||||
t.string "place_name", limit: 255
|
||||
t.integer "count", default: 1
|
||||
t.integer "repeat", default: 0
|
||||
t.text "rule", default: "daily"
|
||||
t.integer "event_id"
|
||||
end
|
||||
|
||||
add_index "events", ["event_id"], name: "index_events_on_event_id"
|
||||
add_index "events", ["start_time", "end_time"], name: "events_date"
|
||||
|
||||
create_table "kinds", force: :cascade do |t|
|
||||
|
47
test/models/event_callbacks_test.rb
Normal file
47
test/models/event_callbacks_test.rb
Normal file
@ -0,0 +1,47 @@
|
||||
require 'test_helper'
|
||||
|
||||
# Test event callbacks
|
||||
class EventCallbacksTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
ActionMailer::Base.default_url_options[:host] = 'localhost:3000'
|
||||
|
||||
@event = events :one
|
||||
end
|
||||
|
||||
test 'schedule' do
|
||||
@event = Event.new(
|
||||
title: 'hello world',
|
||||
start_time: Time.zone.now, end_time: Time.zone.now + 1.hour,
|
||||
description: 'et hop!',
|
||||
city: City.first, region: Region.first,
|
||||
url: 'http://example.com',
|
||||
contact: 'contact@example.com',
|
||||
tags: 'hello world'
|
||||
)
|
||||
assert_difference 'Event.count' do
|
||||
assert @event.save, @event.errors.messages
|
||||
end
|
||||
end
|
||||
|
||||
test 'moderation' do
|
||||
@event = Event.new(
|
||||
title: 'hello world',
|
||||
start_time: Time.zone.now + 1.hour, end_time: Time.zone.now + 2.hours,
|
||||
repeat: 1, rule: 'monthly',
|
||||
description: 'et hop!',
|
||||
city: City.first, region: Region.first,
|
||||
url: 'http://example.com',
|
||||
contact: 'contact@example.com',
|
||||
tags: 'hello world'
|
||||
)
|
||||
|
||||
assert @event.save, @event.errors.messages
|
||||
assert !@event.moderated?
|
||||
|
||||
assert_difference 'Event.count' do
|
||||
@event.update moderated: 1
|
||||
end
|
||||
|
||||
assert @event.moderated?, @event.errors.messages
|
||||
end
|
||||
end
|
@ -21,7 +21,9 @@ class EventTest < ActiveSupport::TestCase
|
||||
submitter: 'submitter@example.com',
|
||||
tags: 'hello world'
|
||||
)
|
||||
assert_difference 'Event.count' do
|
||||
assert @event.save, @event.errors.messages
|
||||
end
|
||||
|
||||
assert_equal 32, @event.secret.size
|
||||
assert_equal 32, @event.moderator_mail_id.size
|
||||
|
Loading…
Reference in New Issue
Block a user