about summary refs log tree commit diff
path: root/spec
diff options
context:
space:
mode:
authorStarfall <us@starfall.systems>2022-12-13 09:37:37 -0600
committerStarfall <us@starfall.systems>2022-12-13 09:37:37 -0600
commit9a99643ecd1e11c8763bbcb5c10bd3dfac3dd638 (patch)
treedb93273e38a54683bd41d19f166fe39787b58b67 /spec
parentdc9a63381b3498e915d8334728f0951b231527e6 (diff)
parentb0ef980aa17868f18089233060900aa5d5632863 (diff)
Merge remote-tracking branch 'glitch/main'
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/admin/accounts_controller_spec.rb81
-rw-r--r--spec/controllers/api/v1/admin/accounts_controller_spec.rb18
-rw-r--r--spec/controllers/api/v1/filters_controller_spec.rb26
-rw-r--r--spec/lib/advanced_text_formatter_spec.rb14
-rw-r--r--spec/models/account_migration_spec.rb43
-rw-r--r--spec/services/activitypub/process_account_service_spec.rb94
6 files changed, 268 insertions, 8 deletions
diff --git a/spec/controllers/admin/accounts_controller_spec.rb b/spec/controllers/admin/accounts_controller_spec.rb
index 1bd51a0c8..81d592ddd 100644
--- a/spec/controllers/admin/accounts_controller_spec.rb
+++ b/spec/controllers/admin/accounts_controller_spec.rb
@@ -147,6 +147,87 @@ RSpec.describe Admin::AccountsController, type: :controller do
     end
   end
 
+  describe 'POST #approve' do
+    subject { post :approve, params: { id: account.id } }
+
+    let(:current_user) { Fabricate(:user, role: role) }
+    let(:account) { user.account }
+    let(:user) { Fabricate(:user) }
+
+    before do
+      account.user.update(approved: false)
+    end
+
+    context 'when user is admin' do
+      let(:role) { UserRole.find_by(name: 'Admin') }
+
+      it 'succeeds in approving account' do
+        is_expected.to redirect_to admin_accounts_path(status: 'pending')
+        expect(user.reload).to be_approved
+      end
+
+      it 'logs action' do
+        is_expected.to have_http_status :found
+
+        log_item = Admin::ActionLog.last
+
+        expect(log_item).to_not be_nil
+        expect(log_item.action).to eq :approve
+        expect(log_item.account_id).to eq current_user.account_id
+        expect(log_item.target_id).to eq account.user.id
+      end
+    end
+
+    context 'when user is not admin' do
+      let(:role) { UserRole.everyone }
+
+      it 'fails to approve account' do
+        is_expected.to have_http_status :forbidden
+        expect(user.reload).not_to be_approved
+      end
+    end
+  end
+
+  describe 'POST #reject' do
+    subject { post :reject, params: { id: account.id } }
+
+    let(:current_user) { Fabricate(:user, role: role) }
+    let(:account) { user.account }
+    let(:user) { Fabricate(:user) }
+
+    before do
+      account.user.update(approved: false)
+    end
+
+    context 'when user is admin' do
+      let(:role) { UserRole.find_by(name: 'Admin') }
+
+      it 'succeeds in rejecting account' do
+        is_expected.to redirect_to admin_accounts_path(status: 'pending')
+      end
+
+      it 'logs action' do
+        is_expected.to have_http_status :found
+
+        log_item = Admin::ActionLog.last
+
+        expect(log_item).to_not be_nil
+        expect(log_item.action).to eq :reject
+        expect(log_item.account_id).to eq current_user.account_id
+        expect(log_item.target_id).to eq account.user.id
+      end
+    end
+
+    context 'when user is not admin' do
+      let(:role) { UserRole.everyone }
+
+      it 'fails to reject account' do
+        is_expected.to have_http_status :forbidden
+        expect(user.reload).not_to be_approved
+      end
+    end
+  end
+
   describe 'POST #redownload' do
     subject { post :redownload, params: { id: account.id } }
 
diff --git a/spec/controllers/api/v1/admin/accounts_controller_spec.rb b/spec/controllers/api/v1/admin/accounts_controller_spec.rb
index cd38030e0..8d35b86cb 100644
--- a/spec/controllers/api/v1/admin/accounts_controller_spec.rb
+++ b/spec/controllers/api/v1/admin/accounts_controller_spec.rb
@@ -100,6 +100,15 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do
     it 'approves user' do
       expect(account.reload.user_approved?).to be true
     end
+
+    it 'logs action' do
+      log_item = Admin::ActionLog.last
+
+      expect(log_item).to_not be_nil
+      expect(log_item.action).to eq :approve
+      expect(log_item.account_id).to eq user.account_id
+      expect(log_item.target_id).to eq account.user.id
+    end
   end
 
   describe 'POST #reject' do
@@ -118,6 +127,15 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do
     it 'removes user' do
       expect(User.where(id: account.user.id).count).to eq 0
     end
+
+    it 'logs action' do
+      log_item = Admin::ActionLog.last
+
+      expect(log_item).to_not be_nil
+      expect(log_item.action).to eq :reject
+      expect(log_item.account_id).to eq user.account_id
+      expect(log_item.target_id).to eq account.user.id
+    end
   end
 
   describe 'POST #enable' do
diff --git a/spec/controllers/api/v1/filters_controller_spec.rb b/spec/controllers/api/v1/filters_controller_spec.rb
index af1951f0b..8acb46a00 100644
--- a/spec/controllers/api/v1/filters_controller_spec.rb
+++ b/spec/controllers/api/v1/filters_controller_spec.rb
@@ -22,9 +22,11 @@ RSpec.describe Api::V1::FiltersController, type: :controller do
 
   describe 'POST #create' do
     let(:scopes) { 'write:filters' }
+    let(:irreversible) { true }
+    let(:whole_word)   { false }
 
     before do
-      post :create, params: { phrase: 'magic', context: %w(home), irreversible: true }
+      post :create, params: { phrase: 'magic', context: %w(home), irreversible: irreversible, whole_word: whole_word }
     end
 
     it 'returns http success' do
@@ -34,11 +36,29 @@ RSpec.describe Api::V1::FiltersController, type: :controller do
     it 'creates a filter' do
       filter = user.account.custom_filters.first
       expect(filter).to_not be_nil
-      expect(filter.keywords.pluck(:keyword)).to eq ['magic']
+      expect(filter.keywords.pluck(:keyword, :whole_word)).to eq [['magic', whole_word]]
       expect(filter.context).to eq %w(home)
-      expect(filter.irreversible?).to be true
+      expect(filter.irreversible?).to be irreversible
       expect(filter.expires_at).to be_nil
     end
+
+    context 'with different parameters' do
+      let(:irreversible) { false }
+      let(:whole_word)   { true }
+
+      it 'returns http success' do
+        expect(response).to have_http_status(200)
+      end
+
+      it 'creates a filter' do
+        filter = user.account.custom_filters.first
+        expect(filter).to_not be_nil
+        expect(filter.keywords.pluck(:keyword, :whole_word)).to eq [['magic', whole_word]]
+        expect(filter.context).to eq %w(home)
+        expect(filter.irreversible?).to be irreversible
+        expect(filter.expires_at).to be_nil
+      end
+    end
   end
 
   describe 'GET #show' do
diff --git a/spec/lib/advanced_text_formatter_spec.rb b/spec/lib/advanced_text_formatter_spec.rb
index 3255fc927..c1e469606 100644
--- a/spec/lib/advanced_text_formatter_spec.rb
+++ b/spec/lib/advanced_text_formatter_spec.rb
@@ -35,7 +35,7 @@ RSpec.describe AdvancedTextFormatter do
       end
 
       context 'given a block code' do
-        let(:text) { "test\n\n```\nint main(void) {\n  return 0;\n}\n```\n" }
+        let(:text) { "test\n\n```\nint main(void) {\n  return 0; // https://joinmastodon.org/foo\n}\n```\n" }
 
         it 'formats code using <pre> and <code>' do
           is_expected.to include '<pre><code>int main'
@@ -44,13 +44,17 @@ RSpec.describe AdvancedTextFormatter do
         it 'does not strip leading spaces' do
           is_expected.to include '>  return 0'
         end
+
+        it 'does not format links' do
+          is_expected.to include 'return 0; // https://joinmastodon.org/foo'
+        end
       end
 
-      context 'given some quote' do
-        let(:text) { "> foo\n\nbar" }
+      context 'given a link in inline code using backticks' do
+        let(:text) { 'test `https://foo.bar/bar` bar' }
 
-        it 'formats code using <code>' do
-          is_expected.to include '<blockquote><p>foo</p></blockquote>'
+        it 'does not rewrite the link' do
+          is_expected.to include 'test <code>https://foo.bar/bar</code> bar'
         end
       end
 
diff --git a/spec/models/account_migration_spec.rb b/spec/models/account_migration_spec.rb
index 8461b4b28..5f66fe8da 100644
--- a/spec/models/account_migration_spec.rb
+++ b/spec/models/account_migration_spec.rb
@@ -1,5 +1,48 @@
 require 'rails_helper'
 
 RSpec.describe AccountMigration, type: :model do
+  describe 'validations' do
+    let(:source_account) { Fabricate(:account) }
+    let(:target_acct)    { target_account.acct }
 
+    let(:subject) { AccountMigration.new(account: source_account, acct: target_acct) }
+
+    context 'with valid properties' do
+      let(:target_account) { Fabricate(:account, username: 'target', domain: 'remote.org') }
+
+      before do
+        target_account.aliases.create!(acct: source_account.acct)
+
+        service_double = double
+        allow(ResolveAccountService).to receive(:new).and_return(service_double)
+        allow(service_double).to receive(:call).with(target_acct, anything).and_return(target_account)
+      end
+
+      it 'passes validations' do
+        expect(subject).to be_valid
+      end
+    end
+
+    context 'with unresolveable account' do
+      let(:target_acct) { 'target@remote' }
+
+      before do
+        service_double = double
+        allow(ResolveAccountService).to receive(:new).and_return(service_double)
+        allow(service_double).to receive(:call).with(target_acct, anything).and_return(nil)
+      end
+
+      it 'has errors on acct field' do
+        expect(subject).to model_have_error_on_field(:acct)
+      end
+    end
+
+    context 'with a space in the domain part' do
+      let(:target_acct) { 'target@remote. org' }
+
+      it 'has errors on acct field' do
+        expect(subject).to model_have_error_on_field(:acct)
+      end
+    end
+  end
 end
diff --git a/spec/services/activitypub/process_account_service_spec.rb b/spec/services/activitypub/process_account_service_spec.rb
index 7728b9ba8..2b20d17b1 100644
--- a/spec/services/activitypub/process_account_service_spec.rb
+++ b/spec/services/activitypub/process_account_service_spec.rb
@@ -109,4 +109,98 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do
       end
     end
   end
+
+  context 'discovering many subdomains in a short timeframe' do
+    before do
+      stub_const 'ActivityPub::ProcessAccountService::SUBDOMAINS_RATELIMIT', 5
+    end
+
+    let(:subject) do
+      8.times do |i|
+        domain = "test#{i}.testdomain.com"
+        json = {
+          id: "https://#{domain}/users/1",
+          type: 'Actor',
+          inbox: "https://#{domain}/inbox",
+        }.with_indifferent_access
+        described_class.new.call('alice', domain, json)
+      end
+    end
+
+    it 'creates at least some accounts' do
+      expect { subject }.to change { Account.remote.count }.by_at_least(2)
+    end
+
+    it 'creates no more account than the limit allows' do
+      expect { subject }.to change { Account.remote.count }.by_at_most(5)
+    end
+  end
+
+  context 'accounts referencing other accounts' do
+    before do
+      stub_const 'ActivityPub::ProcessAccountService::DISCOVERIES_PER_REQUEST', 5
+    end
+
+    let(:payload) do
+      {
+        '@context': ['https://www.w3.org/ns/activitystreams'],
+        id: 'https://foo.test/users/1',
+        type: 'Person',
+        inbox: 'https://foo.test/inbox',
+        featured: 'https://foo.test/users/1/featured',
+        preferredUsername: 'user1',
+      }.with_indifferent_access
+    end
+
+    before do
+      8.times do |i|
+        actor_json = {
+          '@context': ['https://www.w3.org/ns/activitystreams'],
+          id: "https://foo.test/users/#{i}",
+          type: 'Person',
+          inbox: 'https://foo.test/inbox',
+          featured: "https://foo.test/users/#{i}/featured",
+          preferredUsername: "user#{i}",
+        }.with_indifferent_access
+        status_json = {
+          '@context': ['https://www.w3.org/ns/activitystreams'],
+          id: "https://foo.test/users/#{i}/status",
+          attributedTo: "https://foo.test/users/#{i}",
+          type: 'Note',
+          content: "@user#{i + 1} test",
+          tag: [
+            {
+              type: 'Mention',
+              href: "https://foo.test/users/#{i + 1}",
+              name: "@user#{i + 1 }",
+            }
+          ],
+          to: [ 'as:Public', "https://foo.test/users/#{i + 1}" ]
+        }.with_indifferent_access
+        featured_json = {
+          '@context': ['https://www.w3.org/ns/activitystreams'],
+          id: "https://foo.test/users/#{i}/featured",
+          type: 'OrderedCollection',
+          totelItems: 1,
+          orderedItems: [status_json],
+        }.with_indifferent_access
+        webfinger = {
+          subject: "acct:user#{i}@foo.test",
+          links: [{ rel: 'self', href: "https://foo.test/users/#{i}" }],
+        }.with_indifferent_access
+        stub_request(:get, "https://foo.test/users/#{i}").to_return(status: 200, body: actor_json.to_json, headers: { 'Content-Type': 'application/activity+json' })
+        stub_request(:get, "https://foo.test/users/#{i}/featured").to_return(status: 200, body: featured_json.to_json, headers: { 'Content-Type': 'application/activity+json' })
+        stub_request(:get, "https://foo.test/users/#{i}/status").to_return(status: 200, body: status_json.to_json, headers: { 'Content-Type': 'application/activity+json' })
+        stub_request(:get, "https://foo.test/.well-known/webfinger?resource=acct:user#{i}@foo.test").to_return(body: webfinger.to_json, headers: { 'Content-Type': 'application/jrd+json' })
+      end
+    end
+
+    it 'creates at least some accounts' do
+      expect { subject.call('user1', 'foo.test', payload) }.to change { Account.remote.count }.by_at_least(2)
+    end
+
+    it 'creates no more account than the limit allows' do
+      expect { subject.call('user1', 'foo.test', payload) }.to change { Account.remote.count }.by_at_most(5)
+    end
+  end
 end