Merge commit '4aea3f88a6d30f102a79c2da7fcfac96465ba1a8' into merging-upstream

This commit is contained in:
Ondřej Hruška
2017-09-28 09:12:17 +02:00
282 changed files with 4626 additions and 1622 deletions

View File

@ -6,6 +6,7 @@ RSpec.describe HomeController, type: :controller do
describe 'GET #index' do
context 'when not signed in' do
it 'redirects to about page' do
@request.path = '/'
get :index
expect(response).to redirect_to(about_path)
end
@ -13,6 +14,7 @@ RSpec.describe HomeController, type: :controller do
context 'when signed in' do
let(:user) { Fabricate(:user) }
subject do
sign_in(user)
get :index

View File

@ -0,0 +1,5 @@
Fabricator(:custom_emoji) do
shortcode 'coolcat'
domain nil
image { File.open(Rails.root.join('spec', 'fixtures', 'files', 'emojo.png')) }
end

View File

@ -0,0 +1,3 @@
Fabricator(:site_upload) do
end

BIN
spec/fixtures/files/emojo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -0,0 +1,9 @@
HTTP/1.1 200 OK
Date: Sun, 17 Sep 2017 06:51:23 GMT
Content-Type: application/json; charset=utf-8
X-XSS-Protection: 1; mode=block
Link: <https://ap.example.com/.well-known/webfinger?resource=acct%3Afoo%40ap.example.com>; rel="lrdd"; type="application/xrd+xml", <https://ap.example.com/users/foo.atom>; rel="alternate"; type="application/atom+xml"
Vary: Accept-Encoding
Cache-Control: max-age=0, private, must-revalidate
{"@context":"https://www.w3.org/ns/activitystreams","id":"https://ap.example.com/users/foo","type":"Person","following":"https://ap.example.com/users/foo/following","followers":"https://ap.example.com/users/foo/followers","inbox":null,"outbox":"https://ap.example.com/users/foo/outbox","preferredUsername":"foo","name":"","summary":"\u003cp\u003etest\u003c/p\u003e","icon":"https://quitter.no/avatar/7477-300-20160211190340.png","image":"/headers/original/missing.png","publicKey":{"id":"https://ap.example.com/users/foo#main-key","owner":"https://ap.example.com/users/foo","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu3L4vnpNLzVH31MeWI39\n4F0wKeJFsLDAsNXGeOu0QF2x+h1zLWZw/agqD2R3JPU9/kaDJGPIV2Sn5zLyUA9S\n6swCCMOtn7BBR9g9sucgXJmUFB0tACH2QSgHywMAybGfmSb3LsEMNKsGJ9VsvYoh\n8lDET6X4Pyw+ZJU0/OLo/41q9w+OrGtlsTm/PuPIeXnxa6BLqnDaxC+4IcjG/FiP\nahNCTINl/1F/TgSSDZ4Taf4U9XFEIFw8wmgploELozzIzKq+t8nhQYkgAkt64euW\npva3qL5KD1mTIZQEP+LZvh3s2WHrLi3fhbdRuwQ2c0KkJA2oSTFPDpqqbPGZ3Qvu\nHQIDAQAB\n-----END PUBLIC KEY-----\n"}}

View File

@ -0,0 +1,9 @@
HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/activity+json; charset=utf-8
Link: <https://ap.example.com/.well-known/webfinger?resource=acct%3Afoo%40ap.example.com>; rel="lrdd"; type="application/xrd+xml", <https://ap.example.com/users/foo.atom>; rel="alternate"; type="application/atom+xml", <https://ap.example.com/users/foo>; rel="alternate"; type="application/activity+json"
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Xss-Protection: 1; mode=block
{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","sensitive":"as:sensitive","Hashtag":"as:Hashtag","ostatus":"http://ostatus.org#","atomUri":"ostatus:atomUri","inReplyToAtomUri":"ostatus:inReplyToAtomUri","conversation":"ostatus:conversation"}],"id":"https://ap.example.com/users/foo","type":"Person","following":"https://ap.example.com/users/foo/following","followers":"https://ap.example.com/users/foo/followers","inbox":"https://ap.example.com/users/foo/inbox","outbox":"https://ap.example.com/users/foo/outbox","preferredUsername":"foo","name":"","summary":"\u003cp\u003etest\u003c/p\u003e","url":"https://ap.example.com/@foo","manuallyApprovesFollowers":false,"publicKey":{"id":"https://ap.example.com/users/foo#main-key","owner":"https://ap.example.com/users/foo","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu3L4vnpNLzVH31MeWI39\n4F0wKeJFsLDAsNXGeOu0QF2x+h1zLWZw/agqD2R3JPU9/kaDJGPIV2Sn5zLyUA9S\n6swCCMOtn7BBR9g9sucgXJmUFB0tACH2QSgHywMAybGfmSb3LsEMNKsGJ9VsvYoh\n8lDET6X4Pyw+ZJU0/OLo/41q9w+OrGtlsTm/PuPIeXnxa6BLqnDaxC+4IcjG/FiP\nahNCTINl/1F/TgSSDZ4Taf4U9XFEIFw8wmgploELozzIzKq+t8nhQYkgAkt64euW\npva3qL5KD1mTIZQEP+LZvh3s2WHrLi3fhbdRuwQ2c0KkJA2oSTFPDpqqbPGZ3Qvu\nHQIDAQAB\n-----END PUBLIC KEY-----\n"},"endpoints":{"sharedInbox":"https://ap.example.com/inbox"},"icon":{"type":"Image","url":"https://quitter.no/avatar/7477-300-20160211190340.png"}}

View File

@ -0,0 +1,47 @@
HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/atom+xml; charset=utf-8
Link: <https://ap.example.com/.well-known/webfinger?resource=acct%3Afoo%40ap.example.com>; rel="lrdd"; type="application/xrd+xml", <https://ap.example.com/users/foo.atom>; rel="alternate"; type="application/atom+xml", <https://ap.example.com/users/foo>; rel="alternate"; type="application/activity+json"
Vary: Accept-Encoding
Date: Sun, 17 Sep 2017 06:33:53 GMT
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:poco="http://portablecontacts.net/spec/1.0" xmlns:media="http://purl.org/syndication/atommedia" xmlns:ostatus="http://ostatus.org/schema/1.0" xmlns:mastodon="http://mastodon.social/schema/1.0">
<id>https://ap.example.com/users/foo.atom</id>
<title>foo</title>
<subtitle>test</subtitle>
<updated>2017-09-16T18:50:09Z</updated>
<logo>https://ap.example.com/system/accounts/avatars/000/000/001/original/141ee5846d159cba.png?1505587809</logo>
<author>
<id>https://ap.example.com/users/foo</id>
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
<uri>https://ap.example.com/users/foo</uri>
<name>foo</name>
<email>foo@ap.example.com</email>
<summary type="html">&lt;p&gt;test&lt;/p&gt;</summary>
<link rel="alternate" type="text/html" href="https://ap.example.com/@foo"/>
<link rel="avatar" type="image/jpeg" media:width="120" media:height="120" href="https://quitter.no/avatar/7477-300-20160211190340.png"/>
<poco:preferredUsername>foo</poco:preferredUsername>
<poco:note>test</poco:note>
<mastodon:scope>public</mastodon:scope>
</author>
<link rel="alternate" type="text/html" href="https://ap.example.com/@foo"/>
<link rel="self" type="application/atom+xml" href="https://ap.example.com/users/foo.atom"/>
<link rel="hub" href="https://ap.example.com/api/push"/>
<link rel="salmon" href="https://ap.example.com/api/salmon/1"/>
<entry>
<id>https://ap.example.com/users/foo/statuses/11076</id>
<published>2017-09-13T01:23:19Z</published>
<updated>2017-09-13T01:23:19Z</updated>
<title>New status by foo</title>
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
<link rel="alternate" type="application/activity+json" href="https://ap.example.com/users/foo/statuses/11076"/>
<content type="html" xml:lang="ja">&lt;p&gt;test&lt;/p&gt;</content>
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
<mastodon:scope>public</mastodon:scope>
<link rel="alternate" type="text/html" href="https://ap.example.com/@foo/11076"/>
<link rel="self" type="application/atom+xml" href="https://ap.example.com/users/foo/updates/11015.atom"/>
<ostatus:conversation ref="tag:ap.example.com,2017-09-13:objectId=7412:objectType=Conversation"/>
</entry>
</feed>

View File

@ -0,0 +1,7 @@
HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/jrd+json; charset=utf-8
X-Content-Type-Options: nosniff
Date: Sun, 17 Sep 2017 06:22:50 GMT
{"subject":"acct:foo@ap.example.com","aliases":["https://ap.example.com/@foo","https://ap.example.com/users/foo"],"links":[{"rel":"http://webfinger.net/rel/profile-page","type":"text/html","href":"https://ap.example.com/@foo"},{"rel":"http://schemas.google.com/g/2010#updates-from","type":"application/atom+xml","href":"https://ap.example.com/users/foo.atom"},{"rel":"self","type":"application/activity+json","href":"https://ap.example.com/users/foo"},{"rel":"salmon","href":"https://ap.example.com/api/salmon/1"},{"rel":"magic-public-key","href":"data:application/magic-public-key,RSA.u3L4vnpNLzVH31MeWI394F0wKeJFsLDAsNXGeOu0QF2x-h1zLWZw_agqD2R3JPU9_kaDJGPIV2Sn5zLyUA9S6swCCMOtn7BBR9g9sucgXJmUFB0tACH2QSgHywMAybGfmSb3LsEMNKsGJ9VsvYoh8lDET6X4Pyw-ZJU0_OLo_41q9w-OrGtlsTm_PuPIeXnxa6BLqnDaxC-4IcjG_FiPahNCTINl_1F_TgSSDZ4Taf4U9XFEIFw8wmgploELozzIzKq-t8nhQYkgAkt64euWpva3qL5KD1mTIZQEP-LZvh3s2WHrLi3fhbdRuwQ2c0KkJA2oSTFPDpqqbPGZ3QvuHQ==.AQAB"},{"rel":"http://ostatus.org/schema/1.0/subscribe","template":"https://ap.example.com/authorize_follow?acct={uri}"}]}

View File

@ -17,6 +17,7 @@ RSpec.describe ActivityPub::Activity::Create do
before do
stub_request(:get, 'http://example.com/attachment.png').to_return(request_fixture('avatar.txt'))
stub_request(:get, 'http://example.com/emoji.png').to_return(body: attachment_fixture('emojo.png'))
end
describe '#perform' do
@ -217,5 +218,29 @@ RSpec.describe ActivityPub::Activity::Create do
expect(status.tags.map(&:name)).to include('test')
end
end
context 'with emojis' do
let(:object_json) do
{
id: 'bar',
type: 'Note',
content: 'Lorem ipsum :tinking:',
tag: [
{
type: 'Emoji',
href: 'http://example.com/emoji.png',
name: 'tinking',
},
],
}
end
it 'creates status' do
status = sender.statuses.first
expect(status).to_not be_nil
expect(status.emojis.map(&:shortcode)).to include('tinking')
end
end
end
end

View File

@ -89,6 +89,54 @@ RSpec.describe Formatter do
end
end
context 'matches a URL with Japanese path string' do
let(:text) { 'https://ja.wikipedia.org/wiki/日本' }
it 'has valid URL' do
is_expected.to include 'href="https://ja.wikipedia.org/wiki/%E6%97%A5%E6%9C%AC"'
end
end
context 'matches a URL with Korean path string' do
let(:text) { 'https://ko.wikipedia.org/wiki/대한민국' }
it 'has valid URL' do
is_expected.to include 'href="https://ko.wikipedia.org/wiki/%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD"'
end
end
context 'matches a URL with Simplified Chinese path string' do
let(:text) { 'https://baike.baidu.com/item/中华人民共和国' }
it 'has valid URL' do
is_expected.to include 'href="https://baike.baidu.com/item/%E4%B8%AD%E5%8D%8E%E4%BA%BA%E6%B0%91%E5%85%B1%E5%92%8C%E5%9B%BD"'
end
end
context 'matches a URL with Traditional Chinese path string' do
let(:text) { 'https://zh.wikipedia.org/wiki/臺灣' }
it 'has valid URL' do
is_expected.to include 'href="https://zh.wikipedia.org/wiki/%E8%87%BA%E7%81%A3"'
end
end
context 'contains unsafe URL (XSS attack, visible part)' do
let(:text) { %q{http://example.com/b<del>b</del>} }
it 'has escaped HTML' do
is_expected.to include '&lt;del&gt;b&lt;/del&gt;'
end
end
context 'contains unsafe URL (XSS attack, invisible part)' do
let(:text) { %q{http://example.com/blahblahblahblah/a<script>alert("Hello")</script>} }
it 'has escaped HTML' do
is_expected.to include '&lt;script&gt;alert(&quot;Hello&quot;)&lt;/script&gt;'
end
end
context 'contains HTML (script tag)' do
let(:text) { '<script>alert("Hello")</script>' }
@ -175,6 +223,45 @@ RSpec.describe Formatter do
include_examples 'encode and link URLs'
end
context 'with custom_emojify option' do
let!(:emoji) { Fabricate(:custom_emoji) }
let(:status) { Fabricate(:status, account: local_account, text: text) }
subject { Formatter.instance.format(status, custom_emojify: true) }
context 'with emoji at the start' do
let(:text) { ':coolcat: Beep boop' }
it 'converts shortcode to image tag' do
is_expected.to match(/<p><img draggable="false" class="emojione" alt=":coolcat:"/)
end
end
context 'with emoji in the middle' do
let(:text) { 'Beep :coolcat: boop' }
it 'converts shortcode to image tag' do
is_expected.to match(/Beep <img draggable="false" class="emojione" alt=":coolcat:"/)
end
end
context 'with concatenated emoji' do
let(:text) { ':coolcat::coolcat:' }
it 'does not touch the shortcodes' do
is_expected.to match(/:coolcat::coolcat:/)
end
end
context 'with emoji at the end' do
let(:text) { 'Beep boop :coolcat:' }
it 'converts shortcode to image tag' do
is_expected.to match(/boop <img draggable="false" class="emojione" alt=":coolcat:"/)
end
end
end
end
context 'with remote status' do
@ -183,6 +270,45 @@ RSpec.describe Formatter do
it 'reformats' do
is_expected.to eq 'Beep boop'
end
context 'with custom_emojify option' do
let!(:emoji) { Fabricate(:custom_emoji, domain: remote_account.domain) }
let(:status) { Fabricate(:status, account: remote_account, text: text) }
subject { Formatter.instance.format(status, custom_emojify: true) }
context 'with emoji at the start' do
let(:text) { '<p>:coolcat: Beep boop<br />' }
it 'converts shortcode to image tag' do
is_expected.to match(/<p><img draggable="false" class="emojione" alt=":coolcat:"/)
end
end
context 'with emoji in the middle' do
let(:text) { '<p>Beep :coolcat: boop</p>' }
it 'converts shortcode to image tag' do
is_expected.to match(/Beep <img draggable="false" class="emojione" alt=":coolcat:"/)
end
end
context 'with concatenated emoji' do
let(:text) { '<p>:coolcat::coolcat:</p>' }
it 'does not touch the shortcodes' do
is_expected.to match(/<p>:coolcat::coolcat:<\/p>/)
end
end
context 'with emoji at the end' do
let(:text) { '<p>Beep boop<br />:coolcat:</p>' }
it 'converts shortcode to image tag' do
is_expected.to match(/<br><img draggable="false" class="emojione" alt=":coolcat:"/)
end
end
end
end
end

View File

@ -3,10 +3,10 @@
require 'rails_helper'
describe LanguageDetector do
describe 'prepared_text' do
describe 'prepare_text' do
it 'returns unmodified string without special cases' do
string = 'just a regular string'
result = described_class.new(string).prepared_text
result = described_class.instance.send(:prepare_text, string)
expect(result).to eq string
end
@ -14,33 +14,35 @@ describe LanguageDetector do
it 'collapses spacing in strings' do
string = 'The formatting in this is very odd'
result = described_class.new(string).prepared_text
result = described_class.instance.send(:prepare_text, string)
expect(result).to eq 'The formatting in this is very odd'
end
it 'strips usernames from strings before detection' do
string = '@username Yeah, very surreal...! also @friend'
result = described_class.new(string).prepared_text
result = described_class.instance.send(:prepare_text, string)
expect(result).to eq 'Yeah, very surreal...! also'
end
it 'strips URLs from strings before detection' do
string = 'Our website is https://example.com and also http://localhost.dev'
result = described_class.new(string).prepared_text
result = described_class.instance.send(:prepare_text, string)
expect(result).to eq 'Our website is and also'
end
it 'strips #hashtags from strings before detection' do
string = 'Hey look at all the #animals and #fish'
result = described_class.new(string).prepared_text
result = described_class.instance.send(:prepare_text, string)
expect(result).to eq 'Hey look at all the and'
end
end
describe 'to_iso_s' do
describe 'detect' do
let(:account_without_user_locale) { Fabricate(:user, locale: nil).account }
it 'detects english language for basic strings' do
strings = [
"Hello and welcome to mastodon how are you today?",
@ -48,7 +50,7 @@ describe LanguageDetector do
"a lot of people just want to feel righteous all the time and that's all that matters",
]
strings.each do |string|
result = described_class.new(string).to_iso_s
result = described_class.instance.detect(string, account_without_user_locale)
expect(result).to eq(:en), string
end
@ -56,14 +58,14 @@ describe LanguageDetector do
it 'detects spanish language' do
string = 'Obtener un Hola y bienvenidos a Mastodon'
result = described_class.new(string).to_iso_s
result = described_class.instance.detect(string, account_without_user_locale)
expect(result).to eq :es
end
describe 'when language can\'t be detected' do
it 'uses nil when sent an empty document' do
result = described_class.new('').to_iso_s
result = described_class.instance.detect('', account_without_user_locale)
expect(result).to eq nil
end
@ -73,7 +75,7 @@ describe LanguageDetector do
cld_result = CLD3::NNetLanguageIdentifier.new(0, 2048).find_language(string)
expect(cld_result).not_to eq :en
result = described_class.new(string).to_iso_s
result = described_class.instance.detect(string, account_without_user_locale)
expect(result).to eq nil
end
@ -82,14 +84,13 @@ describe LanguageDetector do
describe 'with an account' do
it 'uses the account locale when present' do
account = double(user_locale: 'fr')
result = described_class.new('', account).to_iso_s
result = described_class.instance.detect('', account)
expect(result).to eq :fr
end
it 'uses nil when account is present but has no locale' do
account = double(user_locale: nil)
result = described_class.new('', account).to_iso_s
result = described_class.instance.detect('', account_without_user_locale)
expect(result).to eq nil
end
@ -97,8 +98,7 @@ describe LanguageDetector do
describe 'with an `en` default locale' do
it 'uses nil for undetectable string' do
string = ''
result = described_class.new(string).to_iso_s
result = described_class.instance.detect('', account_without_user_locale)
expect(result).to eq nil
end
@ -114,7 +114,7 @@ describe LanguageDetector do
it 'uses nil for undetectable string' do
string = ''
result = described_class.new(string).to_iso_s
result = described_class.instance.detect(string, account_without_user_locale)
expect(result).to eq nil
end

View File

@ -97,11 +97,23 @@ RSpec.describe OStatus::AtomSerializer do
mentioned = element.nodes.find do |node|
node.name == 'link' &&
node[:rel] == 'mentioned' &&
node['ostatus:object-type'] == TagManager::TYPES[:person]
node[:rel] == 'mentioned' &&
node['ostatus:object-type'] == TagManager::TYPES[:person]
end
expect(mentioned[:href]).to eq 'https://cb6e6126.ngrok.io/users/username'
end
it 'appends link elements for emojis' do
Fabricate(:custom_emoji)
status = Fabricate(:status, text: ':coolcat:')
element = serialize(status)
emoji = element.nodes.find { |node| node.name == 'link' && node[:rel] == 'emoji' }
expect(emoji[:name]).to eq 'coolcat'
expect(emoji[:href]).to_not be_blank
end
end
describe 'render' do

View File

@ -63,23 +63,23 @@ RSpec.describe TagManager do
describe '#local_url?' do
around do |example|
original_local_domain = Rails.configuration.x.local_domain
original_web_domain = Rails.configuration.x.web_domain
example.run
Rails.configuration.x.local_domain = original_local_domain
Rails.configuration.x.web_domain = original_web_domain
end
it 'returns true if the normalized string with port is local URL' do
Rails.configuration.x.local_domain = 'domain:42'
Rails.configuration.x.web_domain = 'domain:42'
expect(TagManager.instance.local_url?('https://DoMaIn:42/')).to eq true
end
it 'returns true if the normalized string without port is local URL' do
Rails.configuration.x.local_domain = 'domain'
Rails.configuration.x.web_domain = 'domain'
expect(TagManager.instance.local_url?('https://DoMaIn/')).to eq true
end
it 'returns false for string with irrelevant characters' do
Rails.configuration.x.local_domain = 'domain'
Rails.configuration.x.web_domain = 'domain'
expect(TagManager.instance.local_url?('https://domainn/')).to eq false
end
end

View File

@ -0,0 +1,25 @@
require 'rails_helper'
RSpec.describe CustomEmoji, type: :model do
describe '.from_text' do
let!(:emojo) { Fabricate(:custom_emoji) }
subject { described_class.from_text(text, nil) }
context 'with plain text' do
let(:text) { 'Hello :coolcat:' }
it 'returns records used via shortcodes in text' do
is_expected.to include(emojo)
end
end
context 'with html' do
let(:text) { '<p>Hello :coolcat:</p>' }
it 'returns records used via shortcodes in text' do
is_expected.to include(emojo)
end
end
end
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe SiteUpload, type: :model do
end

View File

@ -173,19 +173,6 @@ RSpec.describe Status, type: :model do
end
end
describe '.local_only' do
it 'returns only statuses from local accounts' do
local_account = Fabricate(:account, domain: nil)
remote_account = Fabricate(:account, domain: 'test.com')
local_status = Fabricate(:status, account: local_account)
remote_status = Fabricate(:status, account: remote_account)
results = described_class.local_only
expect(results).to include(local_status)
expect(results).not_to include(remote_status)
end
end
describe '.as_home_timeline' do
let(:account) { Fabricate(:account) }
let(:followed) { Fabricate(:account) }
@ -529,6 +516,14 @@ RSpec.describe Status, type: :model do
end
end
describe 'validation' do
it 'disallow empty uri for remote status' do
alice.update(domain: 'example.com')
status = Fabricate.build(:status, uri: '', account: alice)
expect(status).to model_have_error_on_field(:uri)
end
end
describe 'after_create' do
it 'saves ActivityPub uri as uri for local status' do
status = Status.create(account: alice, text: 'foo')

View File

@ -12,6 +12,8 @@ RSpec.describe FetchLinkCardService do
stub_request(:get, 'http://example.com/sjis_with_wrong_charset').to_return(request_fixture('sjis_with_wrong_charset.txt'))
stub_request(:head, 'http://example.com/koi8-r').to_return(status: 200, headers: { 'Content-Type' => 'text/html' })
stub_request(:get, 'http://example.com/koi8-r').to_return(request_fixture('koi8-r.txt'))
stub_request(:head, 'http://example.com/日本語').to_return(status: 200, headers: { 'Content-Type' => 'text/html' })
stub_request(:get, 'http://example.com/日本語').to_return(request_fixture('sjis.txt'))
stub_request(:head, 'https://github.com/qbi/WannaCry').to_return(status: 404)
subject.call(status)
@ -52,6 +54,15 @@ RSpec.describe FetchLinkCardService do
expect(status.preview_cards.first.title).to eq("Московя начинаетъ только въ XVI ст. привлекать внимане иностранцевъ.")
end
end
context do
let(:status) { Fabricate(:status, text: 'テストhttp://example.com/日本語') }
it 'works with Japanese path string' do
expect(a_request(:get, 'http://example.com/日本語')).to have_been_made.at_least_once
expect(status.preview_cards.first.title).to eq("SJISのページ")
end
end
end
context 'in a remote status' do

View File

@ -65,15 +65,12 @@ RSpec.describe PostStatusService do
end
it 'creates a status with a language set' do
detector = double(to_iso_s: :en)
allow(LanguageDetector).to receive(:new).and_return(detector)
account = Fabricate(:account)
text = 'test status text'
text = 'This is an English text.'
subject.call(account, text)
status = subject.call(account, text)
expect(LanguageDetector).to have_received(:new).with(text, account)
expect(status.language).to eq 'en'
end
it 'processes mentions' do

View File

@ -72,6 +72,39 @@ RSpec.describe ResolveRemoteAccountService do
end
context 'with an ActivityPub account' do
before do
stub_request(:get, "https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com").to_return(request_fixture('activitypub-webfinger.txt'))
stub_request(:get, "https://ap.example.com/users/foo").to_return(request_fixture('activitypub-actor.txt'))
stub_request(:get, "https://ap.example.com/users/foo.atom").to_return(request_fixture('activitypub-feed.txt'))
stub_request(:get, %r{https://ap.example.com/users/foo/\w+}).to_return(status: 404)
end
it 'fallback to OStatus if actor json could not be fetched' do
stub_request(:get, "https://ap.example.com/users/foo").to_return(status: 404)
account = subject.call('foo@ap.example.com')
expect(account.ostatus?).to eq true
expect(account.remote_url).to eq 'https://ap.example.com/users/foo.atom'
end
it 'fallback to OStatus if actor json did not have inbox_url' do
stub_request(:get, "https://ap.example.com/users/foo").to_return(request_fixture('activitypub-actor-noinbox.txt'))
account = subject.call('foo@ap.example.com')
expect(account.ostatus?).to eq true
expect(account.remote_url).to eq 'https://ap.example.com/users/foo.atom'
end
it 'returns new remote account' do
account = subject.call('foo@ap.example.com')
expect(account.activitypub?).to eq true
expect(account.domain).to eq 'ap.example.com'
expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox'
end
pending
end

View File

@ -17,6 +17,7 @@ describe 'about/show.html.haml', without_verify_partial_doubles: true do
version_number: '1.0',
source_url: 'https://github.com/tootsuite/mastodon',
open_registrations: false,
thumbnail: nil,
closed_registrations_message: 'yes',
commit_hash: commit_hash)

View File

@ -80,9 +80,9 @@ describe 'stream_entries/show.html.haml', without_verify_partial_doubles: true d
header_tags = view.content_for(:header_tags)
expect(header_tags).to match(%r{<meta content='.+' property='og:title'>})
expect(header_tags).to match(%r{<meta content='article' property='og:type'>})
expect(header_tags).to match(%r{<meta content='.+' property='og:image'>})
expect(header_tags).to match(%r{<meta content='http://.+' property='og:url'>})
expect(header_tags).to match(%r{<meta content=".+" property="og:title" />})
expect(header_tags).to match(%r{<meta content="article" property="og:type" />})
expect(header_tags).to match(%r{<meta content=".+" property="og:image" />})
expect(header_tags).to match(%r{<meta content="http://.+" property="og:url" />})
end
end