diff --git a/spec/models/doorkeeper/access_grant_spec.rb b/spec/models/doorkeeper/access_grant_spec.rb new file mode 100644 index 000000000..9a6b87a49 --- /dev/null +++ b/spec/models/doorkeeper/access_grant_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Doorkeeper::AccessGrant do + describe 'Validations' do + subject { Fabricate :access_grant } + + it { is_expected.to validate_presence_of(:application_id) } + it { is_expected.to validate_presence_of(:expires_in) } + it { is_expected.to validate_presence_of(:redirect_uri) } + it { is_expected.to validate_presence_of(:token) } + end + + describe 'Scopes' do + describe '.expired' do + let!(:unexpired) { Fabricate :access_grant, expires_in: 10.hours } + let!(:expired) do + travel_to 10.minutes.ago do + Fabricate :access_grant, expires_in: 5.minutes + end + end + + it 'returns records past their expired time' do + expect(described_class.expired) + .to include(expired) + .and not_include(unexpired) + end + end + + describe '.revoked' do + let!(:revoked) { Fabricate :access_grant, revoked_at: 10.minutes.ago } + let!(:unrevoked) { Fabricate :access_grant, revoked_at: 10.minutes.from_now } + + it 'returns records past their expired time' do + expect(described_class.revoked) + .to include(revoked) + .and not_include(unrevoked) + end + end + end +end diff --git a/spec/models/doorkeeper/access_token_spec.rb b/spec/models/doorkeeper/access_token_spec.rb new file mode 100644 index 000000000..77071b88b --- /dev/null +++ b/spec/models/doorkeeper/access_token_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Doorkeeper::AccessToken do + describe 'Associations' do + it { is_expected.to have_many(:web_push_subscriptions).class_name('Web::PushSubscription').inverse_of(:access_token) } + end + + describe 'Validations' do + subject { Fabricate :access_token } + + it { is_expected.to validate_presence_of(:token) } + end + + describe 'Scopes' do + describe '.expired' do + let!(:unexpired) { Fabricate :access_token, expires_in: 10.hours } + let!(:expired) do + travel_to 10.minutes.ago do + Fabricate :access_token, expires_in: 5.minutes + end + end + + it 'returns records past their expired time' do + expect(described_class.expired) + .to include(expired) + .and not_include(unexpired) + end + end + + describe '.revoked' do + let!(:revoked) { Fabricate :access_token, revoked_at: 10.minutes.ago } + let!(:unrevoked) { Fabricate :access_token, revoked_at: 10.minutes.from_now } + + it 'returns records past their expired time' do + expect(described_class.revoked) + .to include(revoked) + .and not_include(unrevoked) + end + end + end + + describe '#revoke' do + let(:record) { Fabricate :access_token, revoked_at: 10.days.from_now } + + it 'marks the record as revoked' do + expect { record.revoke } + .to change(record, :revoked_at).to(be_within(1).of(Time.now.utc)) + end + end + + describe '#update_last_used' do + let(:record) { Fabricate :access_token, last_used_at: nil, last_used_ip: nil } + let(:request) { instance_double(ActionDispatch::Request, remote_ip: '1.1.1.1') } + + it 'marks the record as revoked' do + expect { record.update_last_used(request) } + .to change(record, :last_used_at).to(be_within(1).of(Time.now.utc)) + .and change(record, :last_used_ip).to(IPAddr.new('1.1.1.1')) + end + end +end diff --git a/spec/models/doorkeeper/application_spec.rb b/spec/models/doorkeeper/application_spec.rb index e026d90ca..a9bbba3a7 100644 --- a/spec/models/doorkeeper/application_spec.rb +++ b/spec/models/doorkeeper/application_spec.rb @@ -8,8 +8,45 @@ RSpec.describe Doorkeeper::Application do end describe 'Validations' do + subject { Fabricate :application } + + it { is_expected.to validate_presence_of(:name) } + it { is_expected.to validate_presence_of(:uid) } + it { is_expected.to validate_length_of(:name).is_at_most(described_class::APP_NAME_LIMIT) } it { is_expected.to validate_length_of(:redirect_uri).is_at_most(described_class::APP_REDIRECT_URI_LIMIT) } it { is_expected.to validate_length_of(:website).is_at_most(described_class::APP_WEBSITE_LIMIT) } end + + describe '#redirect_uris' do + subject { Fabricate.build(:application, redirect_uri:).redirect_uris } + + context 'with single value' do + let(:redirect_uri) { 'https://test.example/one' } + + it { is_expected.to be_an(Array).and(eq(['https://test.example/one'])) } + end + + context 'with multiple values' do + let(:redirect_uri) { "https://test.example/one\nhttps://test.example/two" } + + it { is_expected.to be_an(Array).and(eq(['https://test.example/one', 'https://test.example/two'])) } + end + end + + describe '#confirmation_redirect_uri' do + subject { Fabricate.build(:application, redirect_uri:).confirmation_redirect_uri } + + context 'with single value' do + let(:redirect_uri) { 'https://test.example/one ' } + + it { is_expected.to eq('https://test.example/one') } + end + + context 'with multiple values' do + let(:redirect_uri) { "https://test.example/one \nhttps://test.example/two " } + + it { is_expected.to eq('https://test.example/one') } + end + end end