diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index e43875544a..5ed8499aad 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1,54 +1,4 @@
module ApplicationHelper
- def unique_tag(date, id, type)
- "tag:#{Rails.configuration.x.local_domain},#{date.strftime('%Y-%m-%d')}:objectId=#{id}:objectType=#{type}"
- end
-
- def unique_tag_to_local_id(tag, expected_type)
- matches = Regexp.new("objectId=([\\d]+):objectType=#{expected_type}").match(tag)
- return matches[1] unless matches.nil?
- end
-
- def local_id?(id)
- id.start_with?("tag:#{Rails.configuration.x.local_domain}")
- end
-
- def content_for_status(actual_status)
- if actual_status.local?
- linkify(actual_status)
- else
- sanitize(actual_status.content, tags: %w(a br p), attributes: %w(href rel))
- end
- end
-
- def account_from_mentions(search_string, mentions)
- mentions.each { |x| return x.account if x.account.acct.eql?(search_string) }
- nil
-
- # If that was unsuccessful, try fetching user from db separately
- # But this shouldn't ever happen if the mentions were created correctly!
- # username, domain = search_string.split('@')
-
- # if domain == Rails.configuration.x.local_domain
- # account = Account.find_local(username)
- # else
- # account = Account.find_remote(username, domain)
- # end
-
- # account
- end
-
- def linkify(status)
- auto_link(HTMLEntities.new.encode(status.text), link: :urls, html: { rel: 'nofollow noopener' }).gsub(Account::MENTION_RE) do |m|
- account = account_from_mentions(Account::MENTION_RE.match(m)[1], status.mentions)
-
- unless account.nil?
- "#{m.split('@').first}@#{account.acct}"
- else
- m
- end
- end.html_safe
- end
-
def active_nav_class(path)
current_page?(path) ? 'active' : ''
end
diff --git a/app/helpers/atom_builder_helper.rb b/app/helpers/atom_builder_helper.rb
index c8046182fa..39ea20e312 100644
--- a/app/helpers/atom_builder_helper.rb
+++ b/app/helpers/atom_builder_helper.rb
@@ -16,7 +16,7 @@ module AtomBuilderHelper
end
def unique_id(xml, date, id, type)
- xml.id_ unique_tag(date, id, type)
+ xml.id_ TagManager.instance.unique_tag(date, id, type)
end
def simple_id(xml, id)
@@ -97,32 +97,8 @@ module AtomBuilderHelper
xml['thr'].send('in-reply-to', { ref: uri, href: url, type: 'text/html' })
end
- def uri_for_target(target)
- if target.local?
- if target.object_type == :person
- account_url(target)
- else
- unique_tag(target.stream_entry.created_at, target.stream_entry.activity_id, target.stream_entry.activity_type)
- end
- else
- target.uri
- end
- end
-
- def url_for_target(target)
- if target.local?
- if target.object_type == :person
- account_url(target)
- else
- account_stream_entry_url(target.account, target.stream_entry)
- end
- else
- target.url
- end
- end
-
def link_mention(xml, account)
- xml.link(rel: 'mentioned', href: uri_for_target(account))
+ xml.link(rel: 'mentioned', href: TagManager.instance.uri_for(account))
end
def link_enclosure(xml, media)
@@ -145,7 +121,7 @@ module AtomBuilderHelper
def conditionally_formatted(activity)
if activity.is_a?(Status)
- content_for_status(activity.reblog? ? activity.reblog : activity)
+ Formatter.instance.format(activity.reblog? ? activity.reblog : activity)
elsif activity.nil?
nil
else
@@ -155,11 +131,11 @@ module AtomBuilderHelper
def include_author(xml, account)
object_type xml, :person
- uri xml, uri_for_target(account)
+ uri xml, TagManager.instance.uri_for(account)
name xml, account.username
email xml, account.local? ? "#{account.acct}@#{Rails.configuration.x.local_domain}" : account.acct
summary xml, account.note
- link_alternate xml, url_for_target(account)
+ link_alternate xml, TagManager.instance.url_for(account)
link_avatar xml, account
portable_contact xml, account
end
@@ -176,7 +152,7 @@ module AtomBuilderHelper
# Comments need thread element
if stream_entry.threaded?
- in_reply_to xml, uri_for_target(stream_entry.thread), url_for_target(stream_entry.thread)
+ in_reply_to xml, TagManager.instance.uri_for(stream_entry.thread), TagManager.instance.url_for(stream_entry.thread)
end
if stream_entry.targeted?
@@ -185,9 +161,9 @@ module AtomBuilderHelper
include_author xml, stream_entry.target
else
object_type xml, stream_entry.target.object_type
- simple_id xml, uri_for_target(stream_entry.target)
+ simple_id xml, TagManager.instance.uri_for(stream_entry.target)
title xml, stream_entry.target.title
- link_alternate xml, url_for_target(stream_entry.target)
+ link_alternate xml, TagManager.instance.url_for(stream_entry.target)
end
# Statuses have content and author
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index a19d06a85a..a0c480b94b 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -1,11 +1,15 @@
+require 'singleton'
+
class FeedManager
+ include Singleton
+
MAX_ITEMS = 800
- def self.key(type, id)
+ def key(type, id)
"feed:#{type}:#{id}"
end
- def self.filter_status?(status, follower)
+ def filter_status?(status, follower)
replied_to_user = status.reply? ? status.thread.account : nil
(status.reply? && !(follower.id = replied_to_user.id || follower.following?(replied_to_user)))
end
diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb
new file mode 100644
index 0000000000..52e2295208
--- /dev/null
+++ b/app/lib/formatter.rb
@@ -0,0 +1,47 @@
+require 'singleton'
+
+class Formatter
+ include Singleton
+
+ include ActionView::Helpers::TextHelper
+ include ActionView::Helpers::SanitizeHelper
+
+ def format(status)
+ return reformat(status) unless status.local?
+
+ html = status.text
+ html = encode(html)
+ html = link_urls(html)
+ html = link_mentions(html, status.mentions)
+
+ html.html_safe
+ end
+
+ def reformat(status)
+ sanitize(status.content, tags: %w(a br p), attributes: %w(href rel))
+ end
+
+ private
+
+ def encode(html)
+ HTMLEntities.new.encode(html)
+ end
+
+ def link_urls(html)
+ auto_link(html, link: :urls, html: { rel: 'nofollow noopener' })
+ end
+
+ def link_mentions(html, mentions)
+ html.gsub(Account::MENTION_RE) do |match|
+ acct = Account::MENTION_RE.match(match)[1]
+ mention = mentions.find { |mention| mention.account.acct.eql?(acct) }
+
+ return match if mention.nil?
+ mention_html(match, mention.account)
+ end
+ end
+
+ def mention_html(match, account)
+ "#{match.split('@').first}@#{account.acct}"
+ end
+end
diff --git a/app/lib/tag_manager.rb b/app/lib/tag_manager.rb
new file mode 100644
index 0000000000..4d29ca1f8b
--- /dev/null
+++ b/app/lib/tag_manager.rb
@@ -0,0 +1,41 @@
+require 'singleton'
+
+class TagManager
+ include Singleton
+ include RoutingHelper
+
+ def unique_tag(date, id, type)
+ "tag:#{Rails.configuration.x.local_domain},#{date.strftime('%Y-%m-%d')}:objectId=#{id}:objectType=#{type}"
+ end
+
+ def unique_tag_to_local_id(tag, expected_type)
+ matches = Regexp.new("objectId=([\\d]+):objectType=#{expected_type}").match(tag)
+ return matches[1] unless matches.nil?
+ end
+
+ def local_id?(id)
+ id.start_with?("tag:#{Rails.configuration.x.local_domain}")
+ end
+
+ def uri_for(target)
+ return target.uri if target.respond_to?(:local?) && !target.local?
+
+ case target.object_type
+ when :person
+ account_url(target)
+ else
+ unique_tag(target.stream_entry.created_at, target.stream_entry.activity_id, target.stream_entry.activity_type)
+ end
+ end
+
+ def url_for(target)
+ return target.url if target.respond_to?(:local?) && !target.local?
+
+ case target.object_type
+ when :person
+ account_url(target)
+ else
+ account_stream_entry_url(target.account, target.stream_entry)
+ end
+ end
+end
diff --git a/app/models/feed.rb b/app/models/feed.rb
index e7574956e5..bc3e960d46 100644
--- a/app/models/feed.rb
+++ b/app/models/feed.rb
@@ -21,7 +21,7 @@ class Feed
private
def key
- FeedManager.key(@type, @account.id)
+ FeedManager.instance.key(@type, @account.id)
end
def redis
diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb
index d51681e538..973451e339 100644
--- a/app/services/fan_out_on_write_service.rb
+++ b/app/services/fan_out_on_write_service.rb
@@ -15,7 +15,7 @@ class FanOutOnWriteService < BaseService
def deliver_to_followers(status)
status.account.followers.each do |follower|
- next if !follower.local? || FeedManager.filter_status?(status, follower)
+ next if !follower.local? || FeedManager.instance.filter_status?(status, follower)
push(:home, follower, status)
end
end
@@ -29,16 +29,16 @@ class FanOutOnWriteService < BaseService
end
def push(type, receiver, status)
- redis.zadd(FeedManager.key(type, receiver.id), status.id, status.id)
+ redis.zadd(FeedManager.instance.key(type, receiver.id), status.id, status.id)
trim(type, receiver)
ActionCable.server.broadcast("timeline:#{receiver.id}", type: 'update', timeline: type, message: inline_render(receiver, status))
end
def trim(type, receiver)
- return unless redis.zcard(FeedManager.key(type, receiver.id)) > FeedManager::MAX_ITEMS
+ return unless redis.zcard(FeedManager.instance.key(type, receiver.id)) > FeedManager::MAX_ITEMS
- last = redis.zrevrange(FeedManager.key(type, receiver.id), FeedManager::MAX_ITEMS - 1, FeedManager::MAX_ITEMS - 1)
- redis.zremrangebyscore(FeedManager.key(type, receiver.id), '-inf', "(#{last.last}")
+ last = redis.zrevrange(FeedManager.instance.key(type, receiver.id), FeedManager::MAX_ITEMS - 1, FeedManager::MAX_ITEMS - 1)
+ redis.zremrangebyscore(FeedManager.instance.key(type, receiver.id), '-inf', "(#{last.last}")
end
def redis
diff --git a/app/services/precompute_feed_service.rb b/app/services/precompute_feed_service.rb
index c8050bbd0d..df2330d092 100644
--- a/app/services/precompute_feed_service.rb
+++ b/app/services/precompute_feed_service.rb
@@ -7,8 +7,8 @@ class PrecomputeFeedService < BaseService
instant_return = []
Status.send("as_#{type}_timeline", account).order('created_at desc').limit(FeedManager::MAX_ITEMS).each do |status|
- next if type == :home && FeedManager.filter_status?(status, account)
- redis.zadd(FeedManager.key(type, account.id), status.id, status.id)
+ next if type == :home && FeedManager.instance.filter_status?(status, account)
+ redis.zadd(FeedManager.instance.key(type, account.id), status.id, status.id)
instant_return << status unless instant_return.size > limit
end
diff --git a/app/services/process_feed_service.rb b/app/services/process_feed_service.rb
index 97033a0047..ba7558e1f2 100644
--- a/app/services/process_feed_service.rb
+++ b/app/services/process_feed_service.rb
@@ -39,10 +39,10 @@ class ProcessFeedService < BaseService
# Also record all media attachments for the status and for the reblogged status if present
unless status.new_record?
record_remote_mentions(status, entry.xpath('./xmlns:link[@rel="mentioned"]'))
-
+
process_attachments(entry, status)
process_attachments(entry.xpath('./activity:object'), status.reblog) if status.reblog?
-
+
DistributionWorker.perform_async(status.id)
end
end
@@ -112,8 +112,8 @@ class ProcessFeedService < BaseService
def find_original_status(_xml, id)
return nil if id.nil?
- if local_id?(id)
- Status.find(unique_tag_to_local_id(id, 'Status'))
+ if TagManager.instance.local_id?(id)
+ Status.find(TagManager.instance.unique_tag_to_local_id(id, 'Status'))
else
Status.find_by(uri: id)
end
diff --git a/app/services/process_interaction_service.rb b/app/services/process_interaction_service.rb
index 536911e2f5..d9fcf9032d 100644
--- a/app/services/process_interaction_service.rb
+++ b/app/services/process_interaction_service.rb
@@ -45,7 +45,7 @@ class ProcessInteractionService < BaseService
end
def mentions_account?(xml, account)
- xml.xpath('/xmlns:entry/xmlns:link[@rel="mentioned"]').each { |mention_link| return true if mention_link.attribute('href').value == url_for_target(account) }
+ xml.xpath('/xmlns:entry/xmlns:link[@rel="mentioned"]').each { |mention_link| return true if mention_link.attribute('href').value == TagManager.instance.url_for(account) }
false
end
@@ -85,7 +85,7 @@ class ProcessInteractionService < BaseService
end
def status(xml)
- Status.find(unique_tag_to_local_id(activity_id(xml), 'Status'))
+ Status.find(TagManager.instance.unique_tag_to_local_id(activity_id(xml), 'Status'))
end
def activity_id(xml)
diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb
index db043df08b..e48a43be07 100644
--- a/app/services/remove_status_service.rb
+++ b/app/services/remove_status_service.rb
@@ -44,7 +44,7 @@ class RemoveStatusService < BaseService
end
def unpush(type, receiver, status)
- redis.zremrangebyscore(FeedManager.key(type, receiver.id), status.id, status.id)
+ redis.zremrangebyscore(FeedManager.instance.key(type, receiver.id), status.id, status.id)
ActionCable.server.broadcast("timeline:#{receiver.id}", type: 'delete', id: status.id)
end
diff --git a/app/views/accounts/_grid_card.html.haml b/app/views/accounts/_grid_card.html.haml
index d107f5274e..f65b78470c 100644
--- a/app/views/accounts/_grid_card.html.haml
+++ b/app/views/accounts/_grid_card.html.haml
@@ -2,7 +2,7 @@
.account-grid-card__header
.avatar= image_tag account.avatar.url(:medium)
.name
- = link_to url_for_target(account) do
+ = link_to TagManager.instance.url_for(account) do
%span.display_name= display_name(account)
%span.username= "@#{account.acct}"
%p.note= truncate(strip_tags(account.note), length: 150)
diff --git a/app/views/accounts/show.atom.ruby b/app/views/accounts/show.atom.ruby
index 8a7bc1b929..d7b2201d40 100644
--- a/app/views/accounts/show.atom.ruby
+++ b/app/views/accounts/show.atom.ruby
@@ -10,7 +10,7 @@ Nokogiri::XML::Builder.new do |xml|
include_author xml, @account
end
- link_alternate xml, url_for_target(@account)
+ link_alternate xml, TagManager.instance.url_for(@account)
link_self xml, account_url(@account, format: 'atom')
link_hub xml, Rails.configuration.x.hub_url
link_salmon xml, api_salmon_url(@account.id)
diff --git a/app/views/api/accounts/show.rabl b/app/views/api/accounts/show.rabl
index 4f7cee680e..d779393d13 100644
--- a/app/views/api/accounts/show.rabl
+++ b/app/views/api/accounts/show.rabl
@@ -2,7 +2,7 @@ object @account
attributes :id, :username, :acct, :display_name, :note
-node(:url) { |account| url_for_target(account) }
+node(:url) { |account| TagManager.instance.url_for(account) }
node(:avatar) { |account| full_asset_url(account.avatar.url(:large, false)) }
node(:followers_count) { |account| account.followers.count }
node(:following_count) { |account| account.following.count }
diff --git a/app/views/api/statuses/show.rabl b/app/views/api/statuses/show.rabl
index c7d028e141..047436b611 100644
--- a/app/views/api/statuses/show.rabl
+++ b/app/views/api/statuses/show.rabl
@@ -1,9 +1,9 @@
object @status
attributes :id, :created_at, :in_reply_to_id
-node(:uri) { |status| uri_for_target(status) }
-node(:content) { |status| content_for_status(status) }
-node(:url) { |status| url_for_target(status) }
+node(:uri) { |status| TagManager.instance.uri_for(status) }
+node(:content) { |status| Formatter.instance.format(status) }
+node(:url) { |status| TagManager.instance.url_for(status) }
node(:reblogs_count) { |status| status.reblogs_count }
node(:favourites_count) { |status| status.favourites_count }
node(:favourited) { |status| current_account.favourited?(status) }
diff --git a/app/views/notification_mailer/follow.text.erb b/app/views/notification_mailer/follow.text.erb
index 6f70c0d901..a13b6d7a99 100644
--- a/app/views/notification_mailer/follow.text.erb
+++ b/app/views/notification_mailer/follow.text.erb
@@ -2,4 +2,4 @@
<%= @account.acct %> is now following you!
-<%= url_for_target(@account) %>
+<%= TagManager.instance.url_for(@account) %>
diff --git a/app/views/notification_mailer/mention.text.erb b/app/views/notification_mailer/mention.text.erb
index b093f4ec02..f3582749d4 100644
--- a/app/views/notification_mailer/mention.text.erb
+++ b/app/views/notification_mailer/mention.text.erb
@@ -4,4 +4,4 @@ You were mentioned by <%= @status.account.acct %> in:
<%= strip_tags(@status.content) %>
-<%= url_for_target(@status) %>
+<%= TagManager.instance.url_for(@status) %>
diff --git a/app/views/stream_entries/_follow.html.haml b/app/views/stream_entries/_follow.html.haml
index f19e8783d9..f6ec8c4f5b 100644
--- a/app/views/stream_entries/_follow.html.haml
+++ b/app/views/stream_entries/_follow.html.haml
@@ -2,4 +2,4 @@
.content
%strong= link_to follow.account.acct, account_path(follow.account)
is now following
- %strong= link_to follow.target_account.acct, url_for_target(follow.target_account)
+ %strong= link_to follow.target_account.acct, TagManager.instance.url_for(follow.target_account)
diff --git a/app/views/stream_entries/_status.html.haml b/app/views/stream_entries/_status.html.haml
index ece31d0e2b..a0afccd396 100644
--- a/app/views/stream_entries/_status.html.haml
+++ b/app/views/stream_entries/_status.html.haml
@@ -12,7 +12,7 @@
.pre-header
%i.fa.fa-retweet
Shared by
- = link_to display_name(status.account), url_for_target(status.account), class: 'name'
+ = link_to display_name(status.account), TagManager.instance.url_for(status.account), class: 'name'
.entry__container
.avatar
@@ -21,10 +21,10 @@
.entry__container__container
.header
.header__left
- = link_to url_for_target(proper_status(status).account), class: 'name' do
+ = link_to TagManager.instance.url_for(proper_status(status).account), class: 'name' do
%strong= display_name(proper_status(status).account)
= "@#{proper_status(status).account.acct}"
- = link_to url_for_target(proper_status(status)), class: 'time' do
+ = link_to TagManager.instance.url_for(proper_status(status)), class: 'time' do
%span{ title: proper_status(status).created_at }
= relative_time(proper_status(status).created_at)
@@ -36,7 +36,7 @@
%i.fa.fa-star
%span.counter-number= proper_status(status).favourites_count
- .content= content_for_status(proper_status(status))
+ .content= Formatter.instance.format(proper_status(status))
%ul.media-attachments
- status.media_attachments.each do |media|
diff --git a/app/views/xrd/webfinger.xml.ruby b/app/views/xrd/webfinger.xml.ruby
index 7c920b678d..d633e3477f 100644
--- a/app/views/xrd/webfinger.xml.ruby
+++ b/app/views/xrd/webfinger.xml.ruby
@@ -1,8 +1,8 @@
Nokogiri::XML::Builder.new do |xml|
xml.XRD(xmlns: 'http://docs.oasis-open.org/ns/xri/xrd-1.0') do
xml.Subject @canonical_account_uri
- xml.Alias url_for_target(@account)
- xml.Link(rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: url_for_target(@account))
+ xml.Alias TagManager.instance.url_for(@account)
+ xml.Link(rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: TagManager.instance.url_for(@account))
xml.Link(rel: 'http://schemas.google.com/g/2010#updates-from', type: 'application/atom+xml', href: account_url(@account, format: 'atom'))
xml.Link(rel: 'salmon', href: api_salmon_url(@account.id))
xml.Link(rel: 'magic-public-key', href: @magic_key)
diff --git a/spec/controllers/oauth/applications_controller_spec.rb b/spec/controllers/oauth/applications_controller_spec.rb
index 350d5d521d..ecd8b16c65 100644
--- a/spec/controllers/oauth/applications_controller_spec.rb
+++ b/spec/controllers/oauth/applications_controller_spec.rb
@@ -1,8 +1,15 @@
require 'rails_helper'
RSpec.describe Oauth::ApplicationsController, type: :controller do
+ before do
+ sign_in Fabricate(:user), scope: :user
+ end
+
describe 'GET #index' do
- it 'returns http success'
+ it 'returns http success' do
+ get :index
+ expect(response).to have_http_status(:success)
+ end
end
describe 'POST #create' do
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 9f68a504ae..c2063c9958 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -1,59 +1,5 @@
require 'rails_helper'
RSpec.describe ApplicationHelper, type: :helper do
- let(:local_domain) { Rails.configuration.x.local_domain }
- describe '#unique_tag' do
- it 'returns a string' do
- expect(helper.unique_tag(Time.now, 12, 'Status')).to be_a String
- end
- end
-
- describe '#unique_tag_to_local_id' do
- it 'returns the ID part' do
- expect(helper.unique_tag_to_local_id("tag:#{local_domain};objectId=12:objectType=Status", 'Status')).to eql '12'
- end
- end
-
- describe '#local_id?' do
- it 'returns true for a local ID' do
- expect(helper.local_id?("tag:#{local_domain};objectId=12:objectType=Status")).to be true
- end
-
- it 'returns false for a foreign ID' do
- expect(helper.local_id?('tag:foreign.tld;objectId=12:objectType=Status')).to be false
- end
- end
-
- describe '#linkify' do
- let(:alice) { Fabricate(:account, username: 'alice') }
- let(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com', url: 'http://example.com/bob') }
-
- it 'turns mention of remote user into link' do
- status = Fabricate(:status, text: 'Hello @bob@example.com', account: bob)
- status.mentions.create(account: bob)
- expect(helper.linkify(status)).to match('@bob@example.com')
- end
-
- it 'turns mention of local user into link' do
- status = Fabricate(:status, text: 'Hello @alice', account: bob)
- status.mentions.create(account: alice)
- expect(helper.linkify(status)).to match('@alice')
- end
-
- it 'leaves mention of unresolvable user alone' do
- status = Fabricate(:status, text: 'Hello @foo', account: bob)
- expect(helper.linkify(status)).to match('Hello @foo')
- end
- end
-
- describe '#account_from_mentions' do
- let(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com') }
- let(:status) { Fabricate(:status, text: 'Hello @bob@example.com', account: bob) }
- let(:mentions) { [Mention.create(status: status, account: bob)] }
-
- it 'returns account' do
- expect(helper.account_from_mentions('bob@example.com', mentions)).to eq bob
- end
- end
end
diff --git a/spec/helpers/atom_builder_helper_spec.rb b/spec/helpers/atom_builder_helper_spec.rb
index 7366b5b791..7e11a8a772 100644
--- a/spec/helpers/atom_builder_helper_spec.rb
+++ b/spec/helpers/atom_builder_helper_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe AtomBuilderHelper, type: :helper do
describe '#unique_id' do
it 'creates an id' do
time = Time.now
- expect(used_in_builder { |xml| helper.unique_id(xml, time, 1, 'Status') }).to match "#{helper.unique_tag(time, 1, 'Status')}"
+ expect(used_in_builder { |xml| helper.unique_id(xml, time, 1, 'Status') }).to match "#{TagManager.instance.unique_tag(time, 1, 'Status')}"
end
end
@@ -146,18 +146,10 @@ RSpec.describe AtomBuilderHelper, type: :helper do
let(:account) { Fabricate(:account, username: 'alice') }
it 'creates a link' do
- expect(used_in_builder { |xml| helper.link_mention(xml, account) }).to match ''
+ expect(used_in_builder { |xml| helper.link_mention(xml, account) }).to match ''
end
end
- describe '#disambiguate_uri' do
- pending
- end
-
- describe '#disambiguate_url' do
- pending
- end
-
describe '#include_author' do
pending
end
diff --git a/spec/lib/feed_manager_spec.rb b/spec/lib/feed_manager_spec.rb
new file mode 100644
index 0000000000..4501e27b75
--- /dev/null
+++ b/spec/lib/feed_manager_spec.rb
@@ -0,0 +1,23 @@
+require 'rails_helper'
+
+RSpec.describe FeedManager do
+ describe '#key' do
+ subject { FeedManager.instance.key(:home, 1) }
+
+ it 'returns a string' do
+ expect(subject).to be_a String
+ end
+ end
+
+ describe '#filter_status?' do
+ let(:followee) { Fabricate(:account, username: 'alice') }
+ let(:status) { Fabricate(:status, text: 'Hello world', account: followee) }
+ let(:follower) { Fabricate(:account, username: 'bob') }
+
+ subject { FeedManager.instance.filter_status?(status, follower) }
+
+ it 'returns a boolean value' do
+ expect(subject).to be false
+ end
+ end
+end
diff --git a/spec/lib/formatter_spec.rb b/spec/lib/formatter_spec.rb
new file mode 100644
index 0000000000..36c4af7481
--- /dev/null
+++ b/spec/lib/formatter_spec.rb
@@ -0,0 +1,39 @@
+require 'rails_helper'
+
+RSpec.describe Formatter do
+ let(:account) { Fabricate(:account, username: 'alice') }
+ let(:local_status) { Fabricate(:status, text: 'Hello world http://google.com', account: account) }
+ let(:remote_status) { Fabricate(:status, text: ' Beep boop', uri: 'beepboop', account: account) }
+
+ describe '#format' do
+ subject { Formatter.instance.format(local_status) }
+
+ it 'returns a string' do
+ expect(subject).to be_a String
+ end
+
+ it 'contains plain text' do
+ expect(subject).to match('Hello world')
+ end
+
+ it 'contains a link' do
+ expect(subject).to match('http://google.com')
+ end
+ end
+
+ describe '#reformat' do
+ subject { Formatter.instance.format(remote_status) }
+
+ it 'returns a string' do
+ expect(subject).to be_a String
+ end
+
+ it 'contains plain text' do
+ expect(subject).to match('Beep boop')
+ end
+
+ it 'does not contain scripts' do
+ expect(subject).to_not match('')
+ end
+ end
+end
diff --git a/spec/lib/tag_manager_spec.rb b/spec/lib/tag_manager_spec.rb
new file mode 100644
index 0000000000..b605842538
--- /dev/null
+++ b/spec/lib/tag_manager_spec.rb
@@ -0,0 +1,107 @@
+require 'rails_helper'
+
+RSpec.describe TagManager do
+ let(:local_domain) { Rails.configuration.x.local_domain }
+
+ describe '#unique_tag' do
+ it 'returns a string' do
+ expect(TagManager.instance.unique_tag(Time.now, 12, 'Status')).to be_a String
+ end
+ end
+
+ describe '#unique_tag_to_local_id' do
+ it 'returns the ID part' do
+ expect(TagManager.instance.unique_tag_to_local_id("tag:#{local_domain};objectId=12:objectType=Status", 'Status')).to eql '12'
+ end
+ end
+
+ describe '#local_id?' do
+ it 'returns true for a local ID' do
+ expect(TagManager.instance.local_id?("tag:#{local_domain};objectId=12:objectType=Status")).to be true
+ end
+
+ it 'returns false for a foreign ID' do
+ expect(TagManager.instance.local_id?('tag:foreign.tld;objectId=12:objectType=Status')).to be false
+ end
+ end
+
+ describe '#uri_for' do
+ let(:alice) { Fabricate(:account, username: 'alice') }
+ let(:bob) { Fabricate(:account, username: 'bob') }
+ let(:status) { Fabricate(:status, text: 'Hello world', account: alice) }
+
+ subject { TagManager.instance.uri_for(target) }
+
+ context 'Account' do
+ let(:target) { alice }
+
+ it 'returns a string' do
+ expect(subject).to be_a String
+ end
+ end
+
+ context 'Status' do
+ let(:target) { status }
+
+ it 'returns a string' do
+ expect(subject).to be_a String
+ end
+ end
+
+ context 'Follow' do
+ let(:target) { Fabricate(:follow, account: alice, target_account: bob) }
+
+ it 'returns a string' do
+ expect(subject).to be_a String
+ end
+ end
+
+ context 'Favourite' do
+ let(:target) { Fabricate(:favourite, account: bob, status: status) }
+
+ it 'returns a string' do
+ expect(subject).to be_a String
+ end
+ end
+ end
+
+ describe '#url_for' do
+ let(:alice) { Fabricate(:account, username: 'alice') }
+ let(:bob) { Fabricate(:account, username: 'bob') }
+ let(:status) { Fabricate(:status, text: 'Hello world', account: alice) }
+
+ subject { TagManager.instance.url_for(target) }
+
+ context 'Account' do
+ let(:target) { alice }
+
+ it 'returns a URL' do
+ expect(subject).to be_a String
+ end
+ end
+
+ context 'Status' do
+ let(:target) { status }
+
+ it 'returns a URL' do
+ expect(subject).to be_a String
+ end
+ end
+
+ context 'Follow' do
+ let(:target) { Fabricate(:follow, account: alice, target_account: bob) }
+
+ it 'returns a URL' do
+ expect(subject).to be_a String
+ end
+ end
+
+ context 'Favourite' do
+ let(:target) { Fabricate(:favourite, account: bob, status: status) }
+
+ it 'returns a URL' do
+ expect(subject).to be_a String
+ end
+ end
+ end
+end
diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb
index 9d19fd3b48..93731d1e4c 100644
--- a/spec/models/account_spec.rb
+++ b/spec/models/account_spec.rb
@@ -112,6 +112,10 @@ RSpec.describe Account, type: :model do
pending
end
+ describe '.find_remote' do
+ pending
+ end
+
describe 'MENTION_RE' do
subject { Account::MENTION_RE }
diff --git a/spec/models/media_attachment_spec.rb b/spec/models/media_attachment_spec.rb
index 0a16276845..5995aa4f4e 100644
--- a/spec/models/media_attachment_spec.rb
+++ b/spec/models/media_attachment_spec.rb
@@ -1,5 +1,5 @@
require 'rails_helper'
RSpec.describe MediaAttachment, type: :model do
- pending "add some examples to (or delete) #{__FILE__}"
+
end