commit: 71fe24096c612996cb2a827c919a4c88ae1e3495
parent: 42eeecba3f334227c10533a065e238f51f6dee4c
Author: Eugen Rochko <eugen@zeonfederated.com>
Date: Thu, 25 Feb 2016 00:17:01 +0100
Adding a Mention model, test stubs
Diffstat:
38 files changed, 355 insertions(+), 47 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -15,3 +15,4 @@
/log/*
!/log/.keep
/tmp
+coverage
diff --git a/.rspec b/.rspec
@@ -0,0 +1,3 @@
+--color
+--require spec_helper
+--format Fuubar
diff --git a/Gemfile b/Gemfile
@@ -28,11 +28,15 @@ gem 'ostatus2'
gem 'goldfinger'
group :development, :test do
- gem 'byebug'
gem 'rspec-rails'
gem 'quiet_assets'
- gem 'nyan-cat-formatter'
gem 'pry-rails'
+ gem 'nyan-cat-formatter'
+ gem 'fuubar'
+end
+
+group :test do
+ gem 'simplecov', require: false
end
group :development do
diff --git a/Gemfile.lock b/Gemfile.lock
@@ -50,7 +50,6 @@ GEM
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
builder (3.2.2)
- byebug (8.2.2)
coderay (1.1.1)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
@@ -66,6 +65,7 @@ GEM
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.2.5)
+ docile (1.1.5)
domain_name (0.5.20160128)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.1.0)
@@ -75,6 +75,9 @@ GEM
equalizer (0.0.11)
erubis (2.7.0)
execjs (2.6.0)
+ fuubar (2.0.0)
+ rspec (~> 3.0)
+ ruby-progressbar (~> 1.4)
globalid (0.3.6)
activesupport (>= 4.1.0)
goldfinger (1.0.1)
@@ -249,6 +252,11 @@ GEM
json (~> 1.7, >= 1.7.7)
rdoc (~> 4.0)
sexp_processor (4.7.0)
+ simplecov (0.11.2)
+ docile (~> 1.1.0)
+ json (~> 1.8)
+ simplecov-html (~> 0.10.0)
+ simplecov-html (0.10.0)
slop (3.6.0)
spring (1.6.3)
sprockets (3.5.2)
@@ -292,9 +300,9 @@ DEPENDENCIES
addressable
better_errors
binding_of_caller
- byebug
coffee-rails (~> 4.1.0)
dotenv-rails
+ fuubar
goldfinger
grape
grape-entity
@@ -318,6 +326,7 @@ DEPENDENCIES
rubocop
sass-rails (~> 5.0)
sdoc (~> 0.4.0)
+ simplecov
spring
sqlite3
therubyracer
diff --git a/app/models/mention.rb b/app/models/mention.rb
@@ -0,0 +1,7 @@
+class Mention < ActiveRecord::Base
+ belongs_to :account, inverse_of: :mentions
+ belongs_to :status, inverse_of: :mentions
+
+ validates :account, :status, presence: true
+ validates :account, uniqueness: { scope: :status }
+end
diff --git a/app/models/status.rb b/app/models/status.rb
@@ -9,6 +9,7 @@ class Status < ActiveRecord::Base
has_many :favourites, inverse_of: :status, dependent: :destroy
has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status'
has_many :replies, foreign_key: 'in_reply_to_id', class_name: 'Status'
+ has_many :mentioned_accounts, class_name: 'Mention', dependent: :destroy
validates :account, presence: true
validates :uri, uniqueness: true, unless: 'local?'
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
@@ -6,30 +6,13 @@ class PostStatusService < BaseService
# @return [Status]
def call(account, text, in_reply_to = nil)
status = account.statuses.create!(text: text, thread: in_reply_to)
-
- status.text.scan(Account::MENTION_RE).each do |match|
- next if match.first.split('@').size == 1
- username, domain = match.first.split('@')
- local_account = Account.find_by(username: username, domain: domain)
- next unless local_account.nil?
- follow_remote_account_service.("acct:#{match.first}")
- end
-
- status.mentions.each do |mentioned_account|
- next if mentioned_account.local?
- send_interaction_service.(status.stream_entry, mentioned_account)
- end
-
+ process_mentions_service.(status)
status
end
private
- def follow_remote_account_service
- @follow_remote_account_service ||= FollowRemoteAccountService.new
- end
-
- def send_interaction_service
- @send_interaction_service ||= SendInteractionService.new
+ def process_mentions_service
+ @process_mentions_service ||= ProcessMentionsService.new
end
end
diff --git a/app/services/process_feed_service.rb b/app/services/process_feed_service.rb
@@ -21,6 +21,8 @@ class ProcessFeedService < BaseService
else
add_post!(entry, status)
end
+
+ process_mentions_service.(status) unless status.new_record?
end
end
@@ -120,4 +122,8 @@ class ProcessFeedService < BaseService
def follow_remote_account_service
@follow_remote_account_service ||= FollowRemoteAccountService.new
end
+
+ def process_mentions_service
+ @process_mentions_service ||= ProcessMentionsService.new
+ end
end
diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb
@@ -0,0 +1,33 @@
+class ProcessMentionsService < BaseService
+ # Scan status for mentions and fetch remote mentioned users, create
+ # local mention pointers, send Salmon notifications to mentioned
+ # remote users
+ # @param [Status] status
+ def call(status)
+ status.text.scan(Account::MENTION_RE).each do |match|
+ username, domain = match.first.split('@')
+ local_account = Account.find_by(username: username, domain: domain)
+
+ if local_account.nil?
+ local_account = follow_remote_account_service.("acct:#{match.first}")
+ end
+
+ local_account.mentions.first_or_create(status: status)
+ end
+
+ status.mentions.each do |mentioned_account|
+ next if mentioned_account.local?
+ send_interaction_service.(status.stream_entry, mentioned_account)
+ end
+ end
+
+ private
+
+ def follow_remote_account_service
+ @follow_remote_account_service ||= FollowRemoteAccountService.new
+ end
+
+ def send_interaction_service
+ @send_interaction_service ||= SendInteractionService.new
+ end
+end
diff --git a/db/migrate/20160224223247_create_mentions.rb b/db/migrate/20160224223247_create_mentions.rb
@@ -0,0 +1,12 @@
+class CreateMentions < ActiveRecord::Migration
+ def change
+ create_table :mentions do |t|
+ t.integer :account_id
+ t.integer :status_id
+
+ t.timestamps null: false
+ end
+
+ add_index :mentions, [:account_id, :status_id], unique: true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20160223171800) do
+ActiveRecord::Schema.define(version: 20160224223247) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -54,6 +54,15 @@ ActiveRecord::Schema.define(version: 20160223171800) do
add_index "follows", ["account_id", "target_account_id"], name: "index_follows_on_account_id_and_target_account_id", unique: true, using: :btree
+ create_table "mentions", force: :cascade do |t|
+ t.integer "account_id"
+ t.integer "status_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
+ add_index "mentions", ["account_id", "status_id"], name: "index_mentions_on_account_id_and_status_id", unique: true, using: :btree
+
create_table "statuses", force: :cascade do |t|
t.string "uri"
t.integer "account_id", null: false
diff --git a/spec/controllers/atom_controller_spec.rb b/spec/controllers/atom_controller_spec.rb
@@ -1,5 +1,11 @@
require 'rails_helper'
RSpec.describe AtomController, type: :controller do
+ describe 'GET #user_stream' do
+ pending
+ end
+ describe 'GET #entry' do
+ pending
+ end
end
diff --git a/spec/controllers/home_controller_spec.rb b/spec/controllers/home_controller_spec.rb
@@ -1,5 +1,7 @@
require 'rails_helper'
RSpec.describe HomeController, type: :controller do
-
+ describe 'GET #index' do
+ pending
+ end
end
diff --git a/spec/controllers/profile_controller_spec.rb b/spec/controllers/profile_controller_spec.rb
@@ -1,12 +1,11 @@
require 'rails_helper'
RSpec.describe ProfileController, type: :controller do
-
- describe "GET #show" do
- it "returns http success" do
- get :show
- expect(response).to have_http_status(:success)
- end
+ describe 'GET #show' do
+ pending
end
+ describe 'GET #entry' do
+ pending
+ end
end
diff --git a/spec/controllers/xrd_controller_spec.rb b/spec/controllers/xrd_controller_spec.rb
@@ -1,5 +1,11 @@
require 'rails_helper'
RSpec.describe XrdController, type: :controller do
+ describe 'GET #host_meta' do
+ pending
+ end
+ describe 'GET #webfinger' do
+ pending
+ end
end
diff --git a/spec/helpers/routing_helper.rb b/spec/helpers/routing_helper.rb
@@ -0,0 +1,15 @@
+require 'rails_helper'
+
+# Specs in this file have access to a helper object that includes
+# the RoutingHelper. For example:
+#
+# describe RoutingHelper do
+# describe "string concat" do
+# it "concats two strings with spaces" do
+# expect(helper.concat_strings("this","that")).to eq("this that")
+# end
+# end
+# end
+RSpec.describe RoutingHelper, type: :helper do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb
@@ -1,5 +1,47 @@
require 'rails_helper'
RSpec.describe Account, type: :model do
- pending "add some examples to (or delete) #{__FILE__}"
+ describe '#follow!' do
+ pending
+ end
+
+ describe '#unfollow!' do
+ pending
+ end
+
+ describe '#following?' do
+ pending
+ end
+
+ describe '#local?' do
+ pending
+ end
+
+ describe '#acct' do
+ pending
+ end
+
+ describe '#subscribed?' do
+ pending
+ end
+
+ describe '#keypair' do
+ pending
+ end
+
+ describe '#subscription' do
+ pending
+ end
+
+ describe '#object_type' do
+ pending
+ end
+
+ describe '#title' do
+ pending
+ end
+
+ describe '#content' do
+ pending
+ end
end
diff --git a/spec/models/favourite_spec.rb b/spec/models/favourite_spec.rb
@@ -1,5 +1,31 @@
require 'rails_helper'
RSpec.describe Favourite, type: :model do
- pending "add some examples to (or delete) #{__FILE__}"
+ describe '#verb' do
+ pending
+ end
+
+ describe '#title' do
+ pending
+ end
+
+ describe '#content' do
+ pending
+ end
+
+ describe '#object_type' do
+ pending
+ end
+
+ describe '#target' do
+ pending
+ end
+
+ describe '#mentions' do
+ pending
+ end
+
+ describe '#thread' do
+ pending
+ end
end
diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb
@@ -1,5 +1,27 @@
require 'rails_helper'
RSpec.describe Follow, type: :model do
- pending "add some examples to (or delete) #{__FILE__}"
+ describe '#verb' do
+ pending
+ end
+
+ describe '#title' do
+ pending
+ end
+
+ describe '#content' do
+ pending
+ end
+
+ describe '#object_type' do
+ pending
+ end
+
+ describe '#target' do
+ pending
+ end
+
+ describe '#mentions' do
+ pending
+ end
end
diff --git a/spec/models/mention_spec.rb b/spec/models/mention_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe Mention, type: :model do
+
+end
diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb
@@ -1,5 +1,35 @@
require 'rails_helper'
RSpec.describe Status, type: :model do
- pending "add some examples to (or delete) #{__FILE__}"
+ describe '#local?' do
+ pending
+ end
+
+ describe '#reblog?' do
+ pending
+ end
+
+ describe '#reply?' do
+ pending
+ end
+
+ describe '#mentions' do
+ pending
+ end
+
+ describe '#verb' do
+ pending
+ end
+
+ describe '#object_type' do
+ pending
+ end
+
+ describe '#title' do
+ pending
+ end
+
+ describe '#target' do
+ pending
+ end
end
diff --git a/spec/models/stream_entry_spec.rb b/spec/models/stream_entry_spec.rb
@@ -0,0 +1,11 @@
+require 'rails_helper'
+
+RSpec.describe StreamEntry, type: :model do
+ describe '#targeted?' do
+ pending
+ end
+
+ describe '#threaded?' do
+ pending
+ end
+end
diff --git a/spec/models/stream_spec.rb b/spec/models/stream_spec.rb
@@ -1,5 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe Stream, type: :model do
- pending "add some examples to (or delete) #{__FILE__}"
-end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
@@ -1,5 +1,5 @@
require 'rails_helper'
RSpec.describe User, type: :model do
- pending "add some examples to (or delete) #{__FILE__}"
+
end
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
@@ -0,0 +1,16 @@
+ENV['RAILS_ENV'] ||= 'test'
+require File.expand_path('../../config/environment', __FILE__)
+
+abort("The Rails environment is running in production mode!") if Rails.env.production?
+
+require 'spec_helper'
+require 'rspec/rails'
+
+ActiveRecord::Migration.maintain_test_schema!
+
+RSpec.configure do |config|
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
+ config.use_transactional_fixtures = true
+ config.infer_spec_type_from_file_location!
+ config.filter_rails_from_backtrace!
+end
diff --git a/spec/services/fetch_feed_service_spec.rb b/spec/services/fetch_feed_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe FetchFeedService do
+ pending
+end
diff --git a/spec/services/follow_remote_account_service_spec.rb b/spec/services/follow_remote_account_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe FollowRemoteAccountService do
+ pending
+end
diff --git a/spec/services/follow_service_spec.rb b/spec/services/follow_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe FollowService do
+ pending
+end
diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe PostStatusService do
+ pending
+end
diff --git a/spec/services/process_feed_service_spec.rb b/spec/services/process_feed_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe ProcessFeedService do
+ pending
+end
diff --git a/spec/services/process_interaction_service_spec.rb b/spec/services/process_interaction_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe ProcessInteractionService do
+ pending
+end
diff --git a/spec/services/process_mentions_service_spec.rb b/spec/services/process_mentions_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe ProcessMentionsService do
+ pending
+end
diff --git a/spec/services/reblog_service_spec.rb b/spec/services/reblog_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe ReblogService do
+ pending
+end
diff --git a/spec/services/send_interaction_service_spec.rb b/spec/services/send_interaction_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe SendInteractionService do
+ pending
+end
diff --git a/spec/services/setup_local_account_service_spec.rb b/spec/services/setup_local_account_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe SetupLocalAccountService do
+ pending
+end
diff --git a/spec/services/unfollow_service_spec.rb b/spec/services/unfollow_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe UnfollowService do
+ pending
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
@@ -0,0 +1,15 @@
+require 'simplecov'
+
+SimpleCov.start 'rails' do
+ add_group "Services", "app/services"
+end
+
+RSpec.configure do |config|
+ config.expect_with :rspec do |expectations|
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
+ end
+
+ config.mock_with :rspec do |mocks|
+ mocks.verify_partial_doubles = true
+ end
+end
diff --git a/spec/views/profile/show.html.haml_spec.rb b/spec/views/profile/show.html.haml_spec.rb
@@ -1,5 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe "profile/show.html.haml", type: :view do
- pending "add some examples to (or delete) #{__FILE__}"
-end