Skip to content

Instantly share code, notes, and snippets.

@macedo
Last active August 29, 2015 14:21
Show Gist options
  • Save macedo/bc249557c57d72718b42 to your computer and use it in GitHub Desktop.
Save macedo/bc249557c57d72718b42 to your computer and use it in GitHub Desktop.
ean rails validator
class EANValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless ean_valid?(value)
record.errors[attribute] << (options[:message] || :bad_ean)
end
end
def valid?(ean)
return false unless ean.length == 13
return false if ean.match(/[^\d]/)
ean_array = ean.chars.map(&:to_i)
verifier_digit = ean_array.pop
result = ean_array.each_with_index.reduce(0) do |sum, (value, index)|
sum += index.odd? ? (value * 3) : value
end
calculated_verifier_digit = result - (result % 10)
verifier_digit == calculated_verifier_digit
end
end
require 'rails_helper'
describe EANValidator do
subject(:validator) { EANValidator.new({attributes: { foo: :bar}}) }
describe '#validate_each' do
let!(:product) { double 'product' }
before do
allow(product).to receive(:errors).and_return([])
allow(product.errors).to receive('[]').and_return([])
end
context 'valid ean' do
it do
expect(product).to_not receive(:errors)
validator.validate_each(product, 'ean', '7891627314051')
end
end
context 'invalid ean' do
it do
expect(product).to receive(:errors)
validator.validate_each(product, 'ean', '1234567890987')
end
end
end
describe '.valid?' do
subject(:validator) { EANValidator }
context 'valid ean' do
['7891627314051', '9311960043718'].each do |ean|
it { expect(validator.valid?(ean)).to be_truthy }
end
end
context 'invalid ean' do
it { expect(validator.valid?('7898490000482')).to be_falsey }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment