186 lines
4.8 KiB
Ruby
186 lines
4.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
RSpec.describe TokenAuthenticatable, feature_category: :shared do
|
|
let(:field) { 'token' }
|
|
let(:digest_field) { "#{field}_digest" }
|
|
let(:encrypted_field) { "#{field}_encrypted" }
|
|
let(:base_class) do
|
|
Struct.new(:name, :token_prefix, field) do
|
|
include TokenAuthenticatable
|
|
|
|
alias_method :read_attribute, :[]
|
|
|
|
def has_attribute?(_)
|
|
true
|
|
end
|
|
end
|
|
end
|
|
|
|
let(:options) { {} }
|
|
|
|
let(:test_class) do
|
|
Class.new(base_class).tap do |klass|
|
|
klass.send(:add_authentication_token_field, field, options)
|
|
end
|
|
end
|
|
|
|
subject(:instance) { test_class.new }
|
|
|
|
describe 'setting same token field multiple times' do
|
|
let(:test_class) do
|
|
Class.new(base_class).tap do |klass|
|
|
klass.send(:add_authentication_token_field, field, options)
|
|
klass.send(:add_authentication_token_field, field, options)
|
|
end
|
|
end
|
|
|
|
it 'raises error' do
|
|
expect { test_class.new }.to raise_error(ArgumentError)
|
|
end
|
|
end
|
|
|
|
describe '.encrypted_token_authenticatable_fields' do
|
|
subject(:token_authenticatable_fields) { test_class.encrypted_token_authenticatable_fields }
|
|
|
|
it { is_expected.to be_empty }
|
|
|
|
context 'with encrypted: true' do
|
|
let(:options) { { encrypted: true } }
|
|
|
|
it { is_expected.to contain_exactly(field) }
|
|
end
|
|
|
|
context 'with digest: true' do
|
|
let(:options) { { digest: true } }
|
|
|
|
it { is_expected.to be_empty }
|
|
end
|
|
end
|
|
|
|
describe '.token_authenticatable_fields' do
|
|
subject(:token_authenticatable_fields) { test_class.token_authenticatable_fields }
|
|
|
|
it { is_expected.to contain_exactly(field) }
|
|
|
|
context 'with encrypted: true' do
|
|
let(:options) { { encrypted: true } }
|
|
|
|
it { is_expected.to contain_exactly(field) }
|
|
end
|
|
|
|
context 'with digest: true' do
|
|
let(:options) { { digest: true } }
|
|
|
|
it { is_expected.to contain_exactly(field) }
|
|
end
|
|
end
|
|
|
|
describe '.token_authenticatable_sensitive_fields' do
|
|
subject(:token_authenticatable_fields) { test_class.token_authenticatable_sensitive_fields }
|
|
|
|
it { is_expected.to contain_exactly(field.to_sym, digest_field.to_sym) }
|
|
|
|
context 'with encrypted: true' do
|
|
let(:options) { { encrypted: true } }
|
|
|
|
it { is_expected.to contain_exactly(field.to_sym, encrypted_field.to_sym) }
|
|
end
|
|
|
|
context 'with digest: true' do
|
|
let(:options) { { digest: true } }
|
|
|
|
it { is_expected.to contain_exactly(field.to_sym, digest_field.to_sym) }
|
|
end
|
|
|
|
context 'with expires_at option' do
|
|
let(:options) { { expires_at: -> { Time.current } } }
|
|
|
|
it { is_expected.to contain_exactly(field.to_sym, digest_field.to_sym) }
|
|
end
|
|
end
|
|
|
|
describe 'dynamic methods' do
|
|
let(:strategy) { instance_double(Authn::TokenField::Base, sensitive_fields: []) }
|
|
|
|
before do
|
|
allow(Authn::TokenField::Base)
|
|
.to receive(:fabricate).with(anything, field, options)
|
|
.and_return(strategy)
|
|
end
|
|
|
|
describe '#<field>' do
|
|
it 'delegates to strategy' do
|
|
expect(strategy).to receive(:get_token).with(instance)
|
|
|
|
instance.public_send(field)
|
|
end
|
|
end
|
|
|
|
describe '#set_<field>' do
|
|
it 'delegates to strategy' do
|
|
expect(strategy).to receive(:set_token).with(instance, 'foo')
|
|
|
|
instance.public_send(:"set_#{field}", 'foo')
|
|
end
|
|
end
|
|
|
|
describe '#ensure_<field>' do
|
|
it 'delegates to strategy' do
|
|
expect(strategy).to receive(:ensure_token).with(instance)
|
|
|
|
instance.public_send(:"ensure_#{field}")
|
|
end
|
|
end
|
|
|
|
describe '#ensure_<field>!' do
|
|
it 'delegates to strategy' do
|
|
expect(strategy).to receive(:ensure_token!).with(instance)
|
|
|
|
instance.public_send(:"ensure_#{field}!")
|
|
end
|
|
end
|
|
|
|
describe '#reset_<field>!' do
|
|
it 'delegates to strategy' do
|
|
expect(strategy).to receive(:reset_token!).with(instance)
|
|
|
|
instance.public_send(:"reset_#{field}!")
|
|
end
|
|
end
|
|
|
|
describe '#<field>_matches?' do
|
|
it 'delegates to strategy' do
|
|
instance.public_send(:"#{field}=", 'foo')
|
|
|
|
expect(instance.public_send(:"#{field}_matches?", 'bar')).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe '#<field>_expires_at' do
|
|
it 'delegates to strategy' do
|
|
expect(strategy).to receive(:expires_at).with(instance)
|
|
|
|
instance.public_send(:"#{field}_expires_at")
|
|
end
|
|
end
|
|
|
|
describe '#<field>_expired?' do
|
|
it 'delegates to strategy' do
|
|
expect(strategy).to receive(:expired?).with(instance)
|
|
|
|
instance.public_send(:"#{field}_expired?")
|
|
end
|
|
end
|
|
|
|
describe '#<field>_with_expiration' do
|
|
it 'delegates to strategy' do
|
|
expect(strategy).to receive(:token_with_expiration).with(instance)
|
|
|
|
instance.public_send(:"#{field}_with_expiration")
|
|
end
|
|
end
|
|
end
|
|
end
|