about summary refs log tree commit diff
path: root/app/validators
diff options
context:
space:
mode:
authorThibaut Girka <thib@sitedethib.com>2019-03-05 19:23:16 +0100
committerThibaut Girka <thib@sitedethib.com>2019-03-05 19:23:16 +0100
commitf513317ba262d9f5d7aa7dd66f8b61690297e107 (patch)
tree6732fcf1178fc3e27404c6830bc2bc1c832659ae /app/validators
parent2a4ce7458a16c64029842fde210089453be2ede1 (diff)
parent7d5e2dda78414316f9cf09fcf6096d6a158da312 (diff)
Merge branch 'master' into glitch-soc/merge-upstream
Conflicts:
- app/models/status.rb
- db/schema.rb

Both conflicts are caused by us having extra database columns.
Diffstat (limited to 'app/validators')
-rw-r--r--app/validators/poll_validator.rb19
-rw-r--r--app/validators/vote_validator.rb13
2 files changed, 32 insertions, 0 deletions
diff --git a/app/validators/poll_validator.rb b/app/validators/poll_validator.rb
new file mode 100644
index 000000000..d4ae4c16a
--- /dev/null
+++ b/app/validators/poll_validator.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class PollValidator < ActiveModel::Validator
+  MAX_OPTIONS      = 4
+  MAX_OPTION_CHARS = 25
+  MAX_EXPIRATION   = 1.month.freeze
+  MIN_EXPIRATION   = 5.minutes.freeze
+
+  def validate(poll)
+    current_time = Time.now.utc
+
+    poll.errors.add(:options, I18n.t('polls.errors.too_few_options')) unless poll.options.size > 1
+    poll.errors.add(:options, I18n.t('polls.errors.too_many_options', max: MAX_OPTIONS)) if poll.options.size > MAX_OPTIONS
+    poll.errors.add(:options, I18n.t('polls.errors.over_character_limit', max: MAX_OPTION_CHARS)) if poll.options.any? { |option| option.mb_chars.grapheme_length > MAX_OPTION_CHARS }
+    poll.errors.add(:options, I18n.t('polls.errors.duplicate_options')) unless poll.options.uniq.size == poll.options.size
+    poll.errors.add(:expires_at, I18n.t('polls.errors.duration_too_long')) if poll.expires_at.nil? || poll.expires_at - current_time >= MAX_EXPIRATION
+    poll.errors.add(:expires_at, I18n.t('polls.errors.duration_too_short')) if poll.expires_at.present? && poll.expires_at - current_time <= MIN_EXPIRATION
+  end
+end
diff --git a/app/validators/vote_validator.rb b/app/validators/vote_validator.rb
new file mode 100644
index 000000000..2e1818bdb
--- /dev/null
+++ b/app/validators/vote_validator.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class VoteValidator < ActiveModel::Validator
+  def validate(vote)
+    vote.errors.add(:base, I18n.t('polls.errors.expired')) if vote.poll.expired?
+
+    if vote.poll.multiple? && vote.poll.votes.where(account: vote.account, choice: vote.choice).exists?
+      vote.errors.add(:base, I18n.t('polls.errors.already_voted'))
+    elsif !vote.poll.multiple? && vote.poll.votes.where(account: vote.account).exists?
+      vote.errors.add(:base, I18n.t('polls.errors.already_voted'))
+    end
+  end
+end