Skip to content

Commit 71fe240

Browse files
committed
Adding a Mention model, test stubs
1 parent 42eeecb commit 71fe240

38 files changed

+355
-47
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@
1515
/log/*
1616
!/log/.keep
1717
/tmp
18+
coverage

.rspec

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
--color
2+
--require spec_helper
3+
--format Fuubar

Gemfile

+6-2
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,15 @@ gem 'ostatus2'
2828
gem 'goldfinger'
2929

3030
group :development, :test do
31-
gem 'byebug'
3231
gem 'rspec-rails'
3332
gem 'quiet_assets'
34-
gem 'nyan-cat-formatter'
3533
gem 'pry-rails'
34+
gem 'nyan-cat-formatter'
35+
gem 'fuubar'
36+
end
37+
38+
group :test do
39+
gem 'simplecov', require: false
3640
end
3741

3842
group :development do

Gemfile.lock

+11-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ GEM
5050
binding_of_caller (0.7.2)
5151
debug_inspector (>= 0.0.1)
5252
builder (3.2.2)
53-
byebug (8.2.2)
5453
coderay (1.1.1)
5554
coercible (1.0.0)
5655
descendants_tracker (~> 0.0.1)
@@ -66,6 +65,7 @@ GEM
6665
descendants_tracker (0.0.4)
6766
thread_safe (~> 0.3, >= 0.3.1)
6867
diff-lcs (1.2.5)
68+
docile (1.1.5)
6969
domain_name (0.5.20160128)
7070
unf (>= 0.0.5, < 1.0.0)
7171
dotenv (2.1.0)
@@ -75,6 +75,9 @@ GEM
7575
equalizer (0.0.11)
7676
erubis (2.7.0)
7777
execjs (2.6.0)
78+
fuubar (2.0.0)
79+
rspec (~> 3.0)
80+
ruby-progressbar (~> 1.4)
7881
globalid (0.3.6)
7982
activesupport (>= 4.1.0)
8083
goldfinger (1.0.1)
@@ -249,6 +252,11 @@ GEM
249252
json (~> 1.7, >= 1.7.7)
250253
rdoc (~> 4.0)
251254
sexp_processor (4.7.0)
255+
simplecov (0.11.2)
256+
docile (~> 1.1.0)
257+
json (~> 1.8)
258+
simplecov-html (~> 0.10.0)
259+
simplecov-html (0.10.0)
252260
slop (3.6.0)
253261
spring (1.6.3)
254262
sprockets (3.5.2)
@@ -292,9 +300,9 @@ DEPENDENCIES
292300
addressable
293301
better_errors
294302
binding_of_caller
295-
byebug
296303
coffee-rails (~> 4.1.0)
297304
dotenv-rails
305+
fuubar
298306
goldfinger
299307
grape
300308
grape-entity
@@ -318,6 +326,7 @@ DEPENDENCIES
318326
rubocop
319327
sass-rails (~> 5.0)
320328
sdoc (~> 0.4.0)
329+
simplecov
321330
spring
322331
sqlite3
323332
therubyracer

app/models/mention.rb

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Mention < ActiveRecord::Base
2+
belongs_to :account, inverse_of: :mentions
3+
belongs_to :status, inverse_of: :mentions
4+
5+
validates :account, :status, presence: true
6+
validates :account, uniqueness: { scope: :status }
7+
end

app/models/status.rb

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class Status < ActiveRecord::Base
99
has_many :favourites, inverse_of: :status, dependent: :destroy
1010
has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status'
1111
has_many :replies, foreign_key: 'in_reply_to_id', class_name: 'Status'
12+
has_many :mentioned_accounts, class_name: 'Mention', dependent: :destroy
1213

1314
validates :account, presence: true
1415
validates :uri, uniqueness: true, unless: 'local?'

app/services/post_status_service.rb

+3-20
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,13 @@ class PostStatusService < BaseService
66
# @return [Status]
77
def call(account, text, in_reply_to = nil)
88
status = account.statuses.create!(text: text, thread: in_reply_to)
9-
10-
status.text.scan(Account::MENTION_RE).each do |match|
11-
next if match.first.split('@').size == 1
12-
username, domain = match.first.split('@')
13-
local_account = Account.find_by(username: username, domain: domain)
14-
next unless local_account.nil?
15-
follow_remote_account_service.("acct:#{match.first}")
16-
end
17-
18-
status.mentions.each do |mentioned_account|
19-
next if mentioned_account.local?
20-
send_interaction_service.(status.stream_entry, mentioned_account)
21-
end
22-
9+
process_mentions_service.(status)
2310
status
2411
end
2512

2613
private
2714

28-
def follow_remote_account_service
29-
@follow_remote_account_service ||= FollowRemoteAccountService.new
30-
end
31-
32-
def send_interaction_service
33-
@send_interaction_service ||= SendInteractionService.new
15+
def process_mentions_service
16+
@process_mentions_service ||= ProcessMentionsService.new
3417
end
3518
end

app/services/process_feed_service.rb

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ def call(body, account)
2121
else
2222
add_post!(entry, status)
2323
end
24+
25+
process_mentions_service.(status) unless status.new_record?
2426
end
2527
end
2628

@@ -120,4 +122,8 @@ def verb(xml)
120122
def follow_remote_account_service
121123
@follow_remote_account_service ||= FollowRemoteAccountService.new
122124
end
125+
126+
def process_mentions_service
127+
@process_mentions_service ||= ProcessMentionsService.new
128+
end
123129
end
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class ProcessMentionsService < BaseService
2+
# Scan status for mentions and fetch remote mentioned users, create
3+
# local mention pointers, send Salmon notifications to mentioned
4+
# remote users
5+
# @param [Status] status
6+
def call(status)
7+
status.text.scan(Account::MENTION_RE).each do |match|
8+
username, domain = match.first.split('@')
9+
local_account = Account.find_by(username: username, domain: domain)
10+
11+
if local_account.nil?
12+
local_account = follow_remote_account_service.("acct:#{match.first}")
13+
end
14+
15+
local_account.mentions.first_or_create(status: status)
16+
end
17+
18+
status.mentions.each do |mentioned_account|
19+
next if mentioned_account.local?
20+
send_interaction_service.(status.stream_entry, mentioned_account)
21+
end
22+
end
23+
24+
private
25+
26+
def follow_remote_account_service
27+
@follow_remote_account_service ||= FollowRemoteAccountService.new
28+
end
29+
30+
def send_interaction_service
31+
@send_interaction_service ||= SendInteractionService.new
32+
end
33+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class CreateMentions < ActiveRecord::Migration
2+
def change
3+
create_table :mentions do |t|
4+
t.integer :account_id
5+
t.integer :status_id
6+
7+
t.timestamps null: false
8+
end
9+
10+
add_index :mentions, [:account_id, :status_id], unique: true
11+
end
12+
end

db/schema.rb

+10-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#
1212
# It's strongly recommended that you check this file into your version control system.
1313

14-
ActiveRecord::Schema.define(version: 20160223171800) do
14+
ActiveRecord::Schema.define(version: 20160224223247) do
1515

1616
# These are extensions that must be enabled in order to support this database
1717
enable_extension "plpgsql"
@@ -54,6 +54,15 @@
5454

5555
add_index "follows", ["account_id", "target_account_id"], name: "index_follows_on_account_id_and_target_account_id", unique: true, using: :btree
5656

57+
create_table "mentions", force: :cascade do |t|
58+
t.integer "account_id"
59+
t.integer "status_id"
60+
t.datetime "created_at", null: false
61+
t.datetime "updated_at", null: false
62+
end
63+
64+
add_index "mentions", ["account_id", "status_id"], name: "index_mentions_on_account_id_and_status_id", unique: true, using: :btree
65+
5766
create_table "statuses", force: :cascade do |t|
5867
t.string "uri"
5968
t.integer "account_id", null: false
+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
require 'rails_helper'
22

33
RSpec.describe AtomController, type: :controller do
4+
describe 'GET #user_stream' do
5+
pending
6+
end
47

8+
describe 'GET #entry' do
9+
pending
10+
end
511
end
+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
require 'rails_helper'
22

33
RSpec.describe HomeController, type: :controller do
4-
4+
describe 'GET #index' do
5+
pending
6+
end
57
end
+5-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
require 'rails_helper'
22

33
RSpec.describe ProfileController, type: :controller do
4-
5-
describe "GET #show" do
6-
it "returns http success" do
7-
get :show
8-
expect(response).to have_http_status(:success)
9-
end
4+
describe 'GET #show' do
5+
pending
106
end
117

8+
describe 'GET #entry' do
9+
pending
10+
end
1211
end
+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
require 'rails_helper'
22

33
RSpec.describe XrdController, type: :controller do
4+
describe 'GET #host_meta' do
5+
pending
6+
end
47

8+
describe 'GET #webfinger' do
9+
pending
10+
end
511
end

spec/helpers/routing_helper.rb

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
require 'rails_helper'
2+
3+
# Specs in this file have access to a helper object that includes
4+
# the RoutingHelper. For example:
5+
#
6+
# describe RoutingHelper do
7+
# describe "string concat" do
8+
# it "concats two strings with spaces" do
9+
# expect(helper.concat_strings("this","that")).to eq("this that")
10+
# end
11+
# end
12+
# end
13+
RSpec.describe RoutingHelper, type: :helper do
14+
pending "add some examples to (or delete) #{__FILE__}"
15+
end

spec/models/account_spec.rb

+43-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,47 @@
11
require 'rails_helper'
22

33
RSpec.describe Account, type: :model do
4-
pending "add some examples to (or delete) #{__FILE__}"
4+
describe '#follow!' do
5+
pending
6+
end
7+
8+
describe '#unfollow!' do
9+
pending
10+
end
11+
12+
describe '#following?' do
13+
pending
14+
end
15+
16+
describe '#local?' do
17+
pending
18+
end
19+
20+
describe '#acct' do
21+
pending
22+
end
23+
24+
describe '#subscribed?' do
25+
pending
26+
end
27+
28+
describe '#keypair' do
29+
pending
30+
end
31+
32+
describe '#subscription' do
33+
pending
34+
end
35+
36+
describe '#object_type' do
37+
pending
38+
end
39+
40+
describe '#title' do
41+
pending
42+
end
43+
44+
describe '#content' do
45+
pending
46+
end
547
end

spec/models/favourite_spec.rb

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
11
require 'rails_helper'
22

33
RSpec.describe Favourite, type: :model do
4-
pending "add some examples to (or delete) #{__FILE__}"
4+
describe '#verb' do
5+
pending
6+
end
7+
8+
describe '#title' do
9+
pending
10+
end
11+
12+
describe '#content' do
13+
pending
14+
end
15+
16+
describe '#object_type' do
17+
pending
18+
end
19+
20+
describe '#target' do
21+
pending
22+
end
23+
24+
describe '#mentions' do
25+
pending
26+
end
27+
28+
describe '#thread' do
29+
pending
30+
end
531
end

0 commit comments

Comments
 (0)