validate email format

pull/381/head
Alex Turchyn 1 year ago committed by Pete Matsyburka
parent 178ee47093
commit ab810be250

@ -2,6 +2,8 @@
module Params
class BaseValidator
EMAIL_REGEXP = /\A[a-z0-9][\.']?(?:(?:[a-z0-9_-]+[\.\+'])*[a-z0-9_-]+)*@(?:[a-z0-9]+[\.-])*[a-z0-9]+\.[a-z]{2,}\z/i
InvalidParameterError = Class.new(StandardError)
def self.call(...)
@ -65,6 +67,14 @@ module Params
raise_error(message || "#{key} must follow the #{regexp.source} format")
end
def email_format(params, key, message: nil)
return if params.blank?
return if params[key].blank?
return if params[key].to_s.strip.split(/\s*[;,]\s*/).all? { |email| email.match?(EMAIL_REGEXP) }
raise_error(message || "#{key} must follow the email format")
end
def unique_value(params, key, message: nil)
return unless params.is_a?(Array)
return if params.none?

@ -22,6 +22,7 @@ module Params
required(params, %i[emails email])
type(params, :emails, String)
email_format(params, :emails, message: 'emails are invalid')
boolean(params, :send_email)
type(params, :message, Hash)
@ -43,8 +44,8 @@ module Params
type(params, :completed_redirect_url, String)
type(params, :bcc_completed, String)
type(params, :reply_to, String)
format(params, :bcc_completed, /@/, message: 'bcc_completed email is invalid')
format(params, :reply_to, /@/, message: 'reply_to email is invalid')
email_format(params, :bcc_completed, message: 'bcc_completed email is invalid')
email_format(params, :reply_to, message: 'reply_to email is invalid')
type(params, :message, Hash)
type(params, :submitters, Array)
@ -75,8 +76,8 @@ module Params
type(submitter_params, :name, String)
type(submitter_params, :reply_to, String)
type(submitter_params, :email, String)
format(submitter_params, :email, /@/, message: 'email is invalid')
format(submitter_params, :reply_to, /@/, message: 'reply_to email is invalid')
email_format(submitter_params, :email, message: 'email is invalid')
email_format(submitter_params, :reply_to, message: 'reply_to email is invalid')
type(submitter_params, :phone, String)
format(submitter_params, :phone, /\A\+\d+\z/,
message: 'phone should start with +<country code> and contain only digits')
@ -106,7 +107,7 @@ module Params
type(params, :order, String)
type(params, :completed_redirect_url, String)
type(params, :bcc_completed, String)
format(params, :bcc_completed, /@/, message: 'bcc_completed email is invalid')
email_format(params, :bcc_completed, message: 'bcc_completed email is invalid')
type(params, :message, Hash)
in_path(params, :message) do |message_params|

@ -0,0 +1,139 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Params::BaseValidator do
let(:validator) { described_class.new({}) }
describe '#email_format' do
it 'when email is valid' do
emails = [
' john.doe@example.com ',
'john.doe@example.com',
'jane+newsletter@domain.org',
'mike_smith@company.net',
'lisa-wong@sub.example.co.uk',
'peter@webmail.com',
'anna.jones123@my-domain.com',
'contact@company.email',
'info@my-company123.org',
'hello.world@business.info',
'feedback@new-domain.com',
'alerts+user@localdomain.net',
'webmaster@industry.biz',
'services@agency.example',
'george123@consultant.pro',
'sales-team@company.io'
]
emails.each do |email|
expect { validator.email_format({ email: }, :email) }.not_to raise_error
end
end
it 'when signle email is invalid' do
emails = [
'jone.doe@',
'mike.smith@',
'jane.doe@@example.com',
'@example.com',
'lisa.wong@example',
'peter.parker..@example.com',
'anna.jones@.com',
'jack.brown@com',
'john doe@example.com',
'laura.martin@ example.com',
'dave.clark@example .com',
'susan.green@example,com',
'chris.lee@example;com',
'jenny.king@.example.com',
'.henry.ford@example.com',
'amy.baker@sub_domain.com',
'george.morris@-example.com',
'nancy.davis@example..com',
'kevin.white@.',
'diana.robinson@.example..com',
'oliver.scott@example.c',
'email1@g.comemail@g.com',
'user.name@subdomain.example@example.com',
'double@at@sign.com',
'user@@example.com',
'email@123.123.123.123',
'this...is@strange.but.valid.com',
'mix-and.match@strangely-formed-email_address.com',
'email@domain..com',
'user@-weird-domain-.com',
'user.name@[IPv6:2001:db8::1]',
'tricky.email@sub.example-.com',
'user@domain.c0m'
]
emails.each do |email|
expect do
validator.email_format({ email: }, :email)
end.to raise_error(described_class::InvalidParameterError, 'email must follow the email format')
end
end
it 'when multiple emails are valid' do
emails = [
'john.doe@example.com, jane.doe+newsletter@domain.org',
'joshua@automobile.car ; chloe+fashion@food.delivery',
'mike-smith@company.net;lisa.wong-sales@sub.example.co.uk',
'peter.parker+info@webmail.com,laura.martin-office@company.co',
'anna.jones123@my-domain.com, jack.brown+work@college.edu',
'susan.green@business-info.org; dave.clark+personal@nonprofit.org',
'chris.lee+team@new-domain.com;jenny.king.marketing@localdomain.net',
'george.morris@consultant.pro; nancy.davis-office@company.io',
'joshua-jones@automobile.car; chloe.taylor+fashion@food.delivery',
'ryan.moore+alerts@music-band.com,isabella.walker.design@fashion.design',
'support-team@company.com, contact.us@domain.org',
'admin.office@industry.biz, hr.department@service.pro',
'feedback@agency-example.org; hello.world@creative-studio.net',
'sales-team@e-commerce.shop, support.department@technology.co',
'media.contact@financial.servicesl; events-coordinator@food.delivery',
'order@music-band.com; info.support@creative.example',
'design.team@webmail.com , admin-office@company.co',
'contact.sales@sub-example.co.uk, support+info@legal.gov',
'support@media.group;subscribe-updates@concert.events'
]
emails.each do |email|
expect { validator.email_format({ email: }, :email) }.not_to raise_error
end
end
it 'when multiple emails are invalid' do
emails = [
'jone@gmail.com, ,mike@gmail.com',
'john.doe@example.com dave@nonprofit.org',
'; oliver.scott@example.com',
'amy.baker@ example.com, george.morris@ example.com',
'jenny.king@example.com . diana.robinson@example.com',
'nancy.davis@.com, henry.ford@.com',
'jack.brown@example.com, laura.martin@example .com',
'anna.jones@example,com lisa.wong@example.com',
'dave.clark@example.com kevin.white@example;com',
'susan.green@ example.com; john.doe@example.com',
'amy.baker@sub_domain.com george.morris@-example.com',
'nancy.davis@example..com john.doe@example.c',
'peter.parker@example.com, .henry.ford@example.com',
'diana.robinson@.example..com, mike.smith@.',
'oliver.scott@example.com; laura.martin@ example.com, jane.doe@@example.com'
]
emails.each do |email|
expect do
validator.email_format({ email: }, :email)
end.to raise_error(described_class::InvalidParameterError, 'email must follow the email format')
end
end
it 'when email is invalid with custom message' do
expect do
validator.email_format({ email: 'jone.doe@' }, :email, message: 'email is invalid')
end.to raise_error(described_class::InvalidParameterError, 'email is invalid')
end
end
end

@ -83,6 +83,20 @@ describe 'Submission API', type: :request do
expect(response.parsed_body[2]['email']).to eq('mike.doe@example.com')
end
it 'returns an error if the submitter email is invalid' do
post '/api/submissions', headers: { 'x-auth-token': author.access_token.token }, params: {
template_id: templates[0].id,
send_email: true,
submitters: [
{ role: 'First Role', email: 'john@example' }
]
}.to_json
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body).to eq({ 'error' => 'email is invalid in `submitters[0]`.' })
end
it 'returns an error if the template fields are missing' do
templates[0].update(fields: [])
@ -113,16 +127,28 @@ describe 'Submission API', type: :request do
describe 'POST /api/submissions/emails' do
it 'creates a submission using email' do
post '/api/submissions', headers: { 'x-auth-token': author.access_token.token }, params: {
post '/api/submissions/emails', headers: { 'x-auth-token': author.access_token.token }, params: {
template_id: templates[0].id,
emails: 'john.doe@example.com'
emails: 'john.doe@example.com,jane.doe@example.com'
}.to_json
expect(response).to have_http_status(:ok)
submission = Submission.last
submissions = Submission.last(2)
submissions_body = submissions.reduce([]) { |acc, submission| acc + create_submission_body(submission) }
expect(response.parsed_body).to eq(JSON.parse(create_submission_body(submission).to_json))
expect(response.parsed_body).to eq(JSON.parse(submissions_body.to_json))
end
it 'returns an error if emails are invalid' do
post '/api/submissions/emails', headers: { 'x-auth-token': author.access_token.token }, params: {
template_id: templates[0].id,
emails: 'amy.baker@example.com, george.morris@example.com@gmail.com'
}.to_json
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body).to eq({ 'error' => 'emails are invalid' })
end
end

Loading…
Cancel
Save