fetch_remote_account_service_spec.rb 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe ActivityPub::FetchRemoteAccountService, type: :service do
  4. subject { described_class.new }
  5. let!(:actor) do
  6. {
  7. '@context': 'https://www.w3.org/ns/activitystreams',
  8. id: 'https://example.com/alice',
  9. type: 'Person',
  10. preferredUsername: 'alice',
  11. name: 'Alice',
  12. summary: 'Foo bar',
  13. inbox: 'http://example.com/alice/inbox',
  14. }
  15. end
  16. describe '#call' do
  17. let(:account) { subject.call('https://example.com/alice') }
  18. shared_examples 'sets profile data' do
  19. it 'returns an account with expected details' do
  20. expect(account)
  21. .to be_an(Account)
  22. .and have_attributes(
  23. display_name: eq('Alice'),
  24. note: eq('Foo bar'),
  25. url: eq('https://example.com/alice')
  26. )
  27. end
  28. end
  29. context 'when the account does not have a inbox' do
  30. let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
  31. before do
  32. actor[:inbox] = nil
  33. stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
  34. stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com').to_return(body: Oj.dump(webfinger), headers: { 'Content-Type': 'application/jrd+json' })
  35. end
  36. it 'fetches resource and looks up webfinger and returns nil' do
  37. expect(account).to be_nil
  38. expect(a_request(:get, 'https://example.com/alice')).to have_been_made.once
  39. expect(a_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com')).to have_been_made.once
  40. end
  41. end
  42. context 'when URI and WebFinger share the same host' do
  43. let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
  44. before do
  45. stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
  46. stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com').to_return(body: Oj.dump(webfinger), headers: { 'Content-Type': 'application/jrd+json' })
  47. end
  48. it 'fetches resource and looks up webfinger and sets attributes' do
  49. account
  50. expect(a_request(:get, 'https://example.com/alice')).to have_been_made.once
  51. expect(a_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com')).to have_been_made.once
  52. expect(account.username).to eq 'alice'
  53. expect(account.domain).to eq 'example.com'
  54. end
  55. include_examples 'sets profile data'
  56. end
  57. context 'when WebFinger presents different domain than URI' do
  58. let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
  59. before do
  60. stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
  61. stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com').to_return(body: Oj.dump(webfinger), headers: { 'Content-Type': 'application/jrd+json' })
  62. stub_request(:get, 'https://iscool.af/.well-known/webfinger?resource=acct:alice@iscool.af').to_return(body: Oj.dump(webfinger), headers: { 'Content-Type': 'application/jrd+json' })
  63. end
  64. it 'fetches resource and looks up webfinger and follows redirection and sets attributes' do
  65. account
  66. expect(a_request(:get, 'https://example.com/alice')).to have_been_made.once
  67. expect(a_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com')).to have_been_made.once
  68. expect(a_request(:get, 'https://iscool.af/.well-known/webfinger?resource=acct:alice@iscool.af')).to have_been_made.once
  69. expect(account.username).to eq 'alice'
  70. expect(account.domain).to eq 'iscool.af'
  71. end
  72. include_examples 'sets profile data'
  73. end
  74. context 'when WebFinger returns a different URI' do
  75. let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/bob' }] } }
  76. before do
  77. stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
  78. stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com').to_return(body: Oj.dump(webfinger), headers: { 'Content-Type': 'application/jrd+json' })
  79. end
  80. it 'fetches resource and looks up webfinger and does not create account' do
  81. expect(account).to be_nil
  82. expect(a_request(:get, 'https://example.com/alice')).to have_been_made.once
  83. expect(a_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com')).to have_been_made.once
  84. end
  85. end
  86. context 'when WebFinger returns a different URI after a redirection' do
  87. let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/bob' }] } }
  88. before do
  89. stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
  90. stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com').to_return(body: Oj.dump(webfinger), headers: { 'Content-Type': 'application/jrd+json' })
  91. stub_request(:get, 'https://iscool.af/.well-known/webfinger?resource=acct:alice@iscool.af').to_return(body: Oj.dump(webfinger), headers: { 'Content-Type': 'application/jrd+json' })
  92. end
  93. it 'fetches resource and looks up webfinger and follows redirect and does not create account' do
  94. expect(account).to be_nil
  95. expect(a_request(:get, 'https://example.com/alice')).to have_been_made.once
  96. expect(a_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com')).to have_been_made.once
  97. expect(a_request(:get, 'https://iscool.af/.well-known/webfinger?resource=acct:alice@iscool.af')).to have_been_made.once
  98. end
  99. end
  100. context 'with wrong id' do
  101. it 'does not create account' do
  102. expect(subject.call('https://fake.address/@foo', prefetched_body: Oj.dump(actor))).to be_nil
  103. end
  104. end
  105. end
  106. end