From ec9bcacd46b22456837203c9971ba18adcc68643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Fri, 14 Jul 2023 15:31:20 +0200 Subject: [PATCH] Add specs for RemoteStorageAuthorization model --- .../remote_storage_authorization_spec.rb | 212 ++++++++++++++++++ spec/rails_helper.rb | 1 + spec/support/helpers/redis_helper.rb | 8 + 3 files changed, 221 insertions(+) create mode 100644 spec/models/remote_storage_authorization_spec.rb create mode 100644 spec/support/helpers/redis_helper.rb diff --git a/spec/models/remote_storage_authorization_spec.rb b/spec/models/remote_storage_authorization_spec.rb new file mode 100644 index 0000000..3d046cf --- /dev/null +++ b/spec/models/remote_storage_authorization_spec.rb @@ -0,0 +1,212 @@ +require 'rails_helper' + +RSpec.describe RemoteStorageAuthorization, type: :model do + include ActiveJob::TestHelper + + let(:user) { create :user } + + describe "#create" do + after(:each) { clear_enqueued_jobs } + after(:all) { redis_rs_delete_keys("rs:authorizations:*") } + + let(:auth) do + user.remote_storage_authorizations.create!( + permissions: %w(documents photos contacts:rw videos:r tasks/work:r), + client_id: "example.com", + redirect_uri: "https://example.com" + ) + end + + it "generates a token" do + expect(auth.token).to match(/[a-zA-Z0-9]+/) + end + + it "stores a token in redis" do + user_auth_keys = redis_rs.keys("rs:authorizations:#{user.address}:*") + expect(user_auth_keys.length).to eq(1) + + authorizations = redis_rs.smembers(user_auth_keys.first) + expect(authorizations.sort).to eq(%w(documents photos contacts:rw videos:r tasks/work:r).sort) + end + + context "with expiry set" do + it "enqueues an expiration job" do + auth_with_expiry = user.remote_storage_authorizations.create!( + permissions: %w(documents:rw), client_id: "example.com", + redirect_uri: "https://example.com", + expire_at: 1.month.from_now + ) + job = enqueued_jobs.select{|j| j['job_class'] == "RemoteStorageExpireAuthorizationJob"}.first + expect(job['arguments'][0]).to eq(auth_with_expiry.id) + end + end + end + + describe "#destroy" do + after(:each) { clear_enqueued_jobs } + after(:all) { redis_rs_delete_keys("rs:authorizations:*") } + + it "removes the token from redis" do + auth = user.remote_storage_authorizations.create!( + permissions: %w(shares:rw documents pictures:r), + client_id: "sharesome.5apps.com", + redirect_uri: "https://sharesome.5apps.com" + ) + auth.destroy! + + expect(redis_rs.keys("rs:authorizations:#{user.address}:*")).to be_empty + end + + context "with expiry set" do + it "removes the expiration job" do + auth_with_expiry = user.remote_storage_authorizations.create!( + permissions: %w(documents:rw), client_id: "example.com", + redirect_uri: "https://example.com", + expire_at: 1.month.from_now + ) + # Cannot test for removal from the actual Sidekiq::Queue, because it is + # not used in specs, but the method directly removes jobs from there + expect(auth_with_expiry).to receive(:remove_token_expiry_job) + auth_with_expiry.destroy! + end + end + end + + # describe "#find_or_create_web_app" do + # context "with origin that looks hosted" do + # before do + # auth = user.remote_storage_authorizations.create!( + # permissions: %w(documents photos contacts:rw videos:r tasks/work:r), + # client_id: "example.com", + # redirect_uri: "https://example.com", + # expire_at: 1.month.from_now + # ) + # end + # + # it "generates a web_app" do + # expect(auth.web_app).to be_a(AppCatalog::WebApp) + # end + # + # it "uses the Web App's name as app name" do + # expect(auth.app_name).to eq("Example Domain") + # end + # end + # + # context "when creating two authorizations for the same app" do + # before do + # user_2 = create :user + # ResqueSpec.reset! + # auth_1 = user.remote_storage_authorizations.create!( + # permissions: %w(documents photos contacts:rw videos:r tasks/work:r), + # client_id: "example.com", + # redirect_uri: "https://example.com", + # expire_at: 1.month.from_now + # ) + # auth_2 = user_2.remote_storage_authorizations.create!( + # permissions: %w(documents photos contacts:rw videos:r tasks/work:r), + # client_id: "example.com", + # redirect_uri: "https://example.com", + # expire_at: 1.month.from_now + # ) + # end + # + # after do + # auth_1.destroy + # auth_2.destroy + # user_2.destroy + # end + # + # it "uses the same web app instance for both authorizations" do + # expect(auth_1.web_app).to be_a(AppCatalog::WebApp) + # expect(auth_1.web_app).to eq(auth_2.web_app) + # end + # end + # + # describe "non-production app origins" do + # context "when host is not an FQDN" do + # before do + # auth = user.remote_storage_authorizations.create!( + # permissions: %w(recipes), + # client_id: "localhost:4200", + # redirect_uri: "http://localhost:4200" + # ) + # end + # + # it "does not create a web app" do + # expect(auth.web_app).to be_nil + # expect(auth.app_name).to eq("localhost:4200") + # end + # end + # + # context "when host is an IP address" do + # before do + # auth = user.remote_storage_authorizations.create!( + # permissions: %w(recipes), + # client_id: "192.168.0.23:3000", + # redirect_uri: "http://192.168.0.23:3000" + # ) + # end + # + # it "does not create a web app" do + # expect(auth.web_app).to be_nil + # expect(auth.app_name).to eq("192.168.0.23:3000") + # end + # end + # + # context "when host is an extension URL" do # before do + # auth = user.remote_storage_authorizations.create!( + # permissions: %w(bookmarks), + # client_id: "123.addons.allizom.org", + # redirect_uri: "123.addons.allizom.org/foo" + # ) + # end + # + # it "does not create a web app" do + # expect(auth.web_app).to be_nil + # expect(auth.app_name).to eq("123.addons.allizom.org") + # end + # end + # end + # end + + # describe "auth notifications" do + # context "with auth notifications enabled" do + # before do + # ResqueSpec.reset! + # user.push(mailing_lists: "rs-auth-notifications-#{Rails.env}") + # auth = user.remote_storage_authorizations.create!( + # :permissions => %w(documents photos contacts:rw videos:r tasks/work:r), + # :client_id => "example.com", + # :redirect_uri => "https://example.com" + # ) + # end + # + # it "notifies the user via email" do + # expect(enqueued_jobs.size).to eq(1) + # job = enqueued_jobs.first + # expect(job).to eq( + # job: ActionMailer::DeliveryJob, + # args: ['StorageAuthorizationMailer', 'authorized_rs_app', 'deliver_now', + # auth.id.to_s], + # queue: 'mailers' + # ) + # end + # end + # + # context "with auth notifications disabled" do + # before do + # ResqueSpec.reset! + # user.pull(mailing_lists: "rs-auth-notifications-#{Rails.env}") + # auth = user.remote_storage_authorizations.create!( + # :permissions => %w(documents photos contacts:rw videos:r tasks/work:r), + # :client_id => "example.com", + # :redirect_uri => "https://example.com" + # ) + # end + # + # it "does not notify the user via email about new RS app" do + # expect(enqueued_jobs.size).to eq(0) + # end + # end + # end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index eab4dee..ae6309d 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -10,6 +10,7 @@ require 'capybara' require 'devise' require 'support/controller_macros' require 'support/database_cleaner' +require 'support/helpers/redis_helper' require "view_component/test_helpers" require "capybara/rspec" diff --git a/spec/support/helpers/redis_helper.rb b/spec/support/helpers/redis_helper.rb new file mode 100644 index 0000000..2571fce --- /dev/null +++ b/spec/support/helpers/redis_helper.rb @@ -0,0 +1,8 @@ +def redis_rs + @redis_rs ||= Redis.new(url: Setting.rs_redis_url) +end + +def redis_rs_delete_keys(pattern) + keys = redis_rs.keys(pattern) + redis_rs.del(*keys) +end