Browse Source

Adding a Mention model, test stubs

Eugen Rochko 2 years ago
parent
commit
71fe24096c
38 changed files with 355 additions and 47 deletions
  1. 1
    0
      .gitignore
  2. 3
    0
      .rspec
  3. 6
    2
      Gemfile
  4. 11
    2
      Gemfile.lock
  5. 7
    0
      app/models/mention.rb
  6. 1
    0
      app/models/status.rb
  7. 3
    20
      app/services/post_status_service.rb
  8. 6
    0
      app/services/process_feed_service.rb
  9. 33
    0
      app/services/process_mentions_service.rb
  10. 12
    0
      db/migrate/20160224223247_create_mentions.rb
  11. 10
    1
      db/schema.rb
  12. 6
    0
      spec/controllers/atom_controller_spec.rb
  13. 3
    1
      spec/controllers/home_controller_spec.rb
  14. 5
    6
      spec/controllers/profile_controller_spec.rb
  15. 6
    0
      spec/controllers/xrd_controller_spec.rb
  16. 15
    0
      spec/helpers/routing_helper.rb
  17. 43
    1
      spec/models/account_spec.rb
  18. 27
    1
      spec/models/favourite_spec.rb
  19. 23
    1
      spec/models/follow_spec.rb
  20. 5
    0
      spec/models/mention_spec.rb
  21. 31
    1
      spec/models/status_spec.rb
  22. 11
    0
      spec/models/stream_entry_spec.rb
  23. 0
    5
      spec/models/stream_spec.rb
  24. 1
    1
      spec/models/user_spec.rb
  25. 16
    0
      spec/rails_helper.rb
  26. 5
    0
      spec/services/fetch_feed_service_spec.rb
  27. 5
    0
      spec/services/follow_remote_account_service_spec.rb
  28. 5
    0
      spec/services/follow_service_spec.rb
  29. 5
    0
      spec/services/post_status_service_spec.rb
  30. 5
    0
      spec/services/process_feed_service_spec.rb
  31. 5
    0
      spec/services/process_interaction_service_spec.rb
  32. 5
    0
      spec/services/process_mentions_service_spec.rb
  33. 5
    0
      spec/services/reblog_service_spec.rb
  34. 5
    0
      spec/services/send_interaction_service_spec.rb
  35. 5
    0
      spec/services/setup_local_account_service_spec.rb
  36. 5
    0
      spec/services/unfollow_service_spec.rb
  37. 15
    0
      spec/spec_helper.rb
  38. 0
    5
      spec/views/profile/show.html.haml_spec.rb

+ 1
- 0
.gitignore View File

@@ -15,3 +15,4 @@
15 15
 /log/*
16 16
 !/log/.keep
17 17
 /tmp
18
+coverage

+ 3
- 0
.rspec View File

@@ -0,0 +1,3 @@
1
+--color
2
+--require spec_helper
3
+--format Fuubar

+ 6
- 2
Gemfile View File

@@ -28,11 +28,15 @@ gem 'ostatus2'
28 28
 gem 'goldfinger'
29 29
 
30 30
 group :development, :test do
31
-  gem 'byebug'
32 31
   gem 'rspec-rails'
33 32
   gem 'quiet_assets'
34
-  gem 'nyan-cat-formatter'
35 33
   gem 'pry-rails'
34
+  gem 'nyan-cat-formatter'
35
+  gem 'fuubar'
36
+end
37
+
38
+group :test do
39
+  gem 'simplecov', require: false
36 40
 end
37 41
 
38 42
 group :development do

+ 11
- 2
Gemfile.lock View File

@@ -50,7 +50,6 @@ GEM
50 50
     binding_of_caller (0.7.2)
51 51
       debug_inspector (>= 0.0.1)
52 52
     builder (3.2.2)
53
-    byebug (8.2.2)
54 53
     coderay (1.1.1)
55 54
     coercible (1.0.0)
56 55
       descendants_tracker (~> 0.0.1)
@@ -66,6 +65,7 @@ GEM
66 65
     descendants_tracker (0.0.4)
67 66
       thread_safe (~> 0.3, >= 0.3.1)
68 67
     diff-lcs (1.2.5)
68
+    docile (1.1.5)
69 69
     domain_name (0.5.20160128)
70 70
       unf (>= 0.0.5, < 1.0.0)
71 71
     dotenv (2.1.0)
@@ -75,6 +75,9 @@ GEM
75 75
     equalizer (0.0.11)
76 76
     erubis (2.7.0)
77 77
     execjs (2.6.0)
78
+    fuubar (2.0.0)
79
+      rspec (~> 3.0)
80
+      ruby-progressbar (~> 1.4)
78 81
     globalid (0.3.6)
79 82
       activesupport (>= 4.1.0)
80 83
     goldfinger (1.0.1)
@@ -249,6 +252,11 @@ GEM
249 252
       json (~> 1.7, >= 1.7.7)
250 253
       rdoc (~> 4.0)
251 254
     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)
252 260
     slop (3.6.0)
253 261
     spring (1.6.3)
254 262
     sprockets (3.5.2)
@@ -292,9 +300,9 @@ DEPENDENCIES
292 300
   addressable
293 301
   better_errors
294 302
   binding_of_caller
295
-  byebug
296 303
   coffee-rails (~> 4.1.0)
297 304
   dotenv-rails
305
+  fuubar
298 306
   goldfinger
299 307
   grape
300 308
   grape-entity
@@ -318,6 +326,7 @@ DEPENDENCIES
318 326
   rubocop
319 327
   sass-rails (~> 5.0)
320 328
   sdoc (~> 0.4.0)
329
+  simplecov
321 330
   spring
322 331
   sqlite3
323 332
   therubyracer

+ 7
- 0
app/models/mention.rb View File

@@ -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

+ 1
- 0
app/models/status.rb View File

@@ -9,6 +9,7 @@ class Status < ActiveRecord::Base
9 9
   has_many :favourites, inverse_of: :status, dependent: :destroy
10 10
   has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status'
11 11
   has_many :replies, foreign_key: 'in_reply_to_id', class_name: 'Status'
12
+  has_many :mentioned_accounts, class_name: 'Mention', dependent: :destroy
12 13
 
13 14
   validates :account, presence: true
14 15
   validates :uri, uniqueness: true, unless: 'local?'

+ 3
- 20
app/services/post_status_service.rb View File

@@ -6,30 +6,13 @@ class PostStatusService < BaseService
6 6
   # @return [Status]
7 7
   def call(account, text, in_reply_to = nil)
8 8
     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)
23 10
     status
24 11
   end
25 12
 
26 13
   private
27 14
 
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
34 17
   end
35 18
 end

+ 6
- 0
app/services/process_feed_service.rb View File

@@ -21,6 +21,8 @@ class ProcessFeedService < BaseService
21 21
       else
22 22
         add_post!(entry, status)
23 23
       end
24
+
25
+      process_mentions_service.(status) unless status.new_record?
24 26
     end
25 27
   end
26 28
 
@@ -120,4 +122,8 @@ class ProcessFeedService < BaseService
120 122
   def follow_remote_account_service
121 123
     @follow_remote_account_service ||= FollowRemoteAccountService.new
122 124
   end
125
+
126
+  def process_mentions_service
127
+    @process_mentions_service ||= ProcessMentionsService.new
128
+  end
123 129
 end

+ 33
- 0
app/services/process_mentions_service.rb View File

@@ -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

+ 12
- 0
db/migrate/20160224223247_create_mentions.rb View File

@@ -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

+ 10
- 1
db/schema.rb View File

@@ -11,7 +11,7 @@
11 11
 #
12 12
 # It's strongly recommended that you check this file into your version control system.
13 13
 
14
-ActiveRecord::Schema.define(version: 20160223171800) do
14
+ActiveRecord::Schema.define(version: 20160224223247) do
15 15
 
16 16
   # These are extensions that must be enabled in order to support this database
17 17
   enable_extension "plpgsql"
@@ -54,6 +54,15 @@ ActiveRecord::Schema.define(version: 20160223171800) do
54 54
 
55 55
   add_index "follows", ["account_id", "target_account_id"], name: "index_follows_on_account_id_and_target_account_id", unique: true, using: :btree
56 56
 
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
+
57 66
   create_table "statuses", force: :cascade do |t|
58 67
     t.string   "uri"
59 68
     t.integer  "account_id",                  null: false

+ 6
- 0
spec/controllers/atom_controller_spec.rb View File

@@ -1,5 +1,11 @@
1 1
 require 'rails_helper'
2 2
 
3 3
 RSpec.describe AtomController, type: :controller do
4
+  describe 'GET #user_stream' do
5
+    pending
6
+  end
4 7
 
8
+  describe 'GET #entry' do
9
+    pending
10
+  end
5 11
 end

+ 3
- 1
spec/controllers/home_controller_spec.rb View File

@@ -1,5 +1,7 @@
1 1
 require 'rails_helper'
2 2
 
3 3
 RSpec.describe HomeController, type: :controller do
4
-
4
+  describe 'GET #index' do
5
+    pending
6
+  end
5 7
 end

+ 5
- 6
spec/controllers/profile_controller_spec.rb View File

@@ -1,12 +1,11 @@
1 1
 require 'rails_helper'
2 2
 
3 3
 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
10 6
   end
11 7
 
8
+  describe 'GET #entry' do
9
+    pending
10
+  end
12 11
 end

+ 6
- 0
spec/controllers/xrd_controller_spec.rb View File

@@ -1,5 +1,11 @@
1 1
 require 'rails_helper'
2 2
 
3 3
 RSpec.describe XrdController, type: :controller do
4
+  describe 'GET #host_meta' do
5
+    pending
6
+  end
4 7
 
8
+  describe 'GET #webfinger' do
9
+    pending
10
+  end
5 11
 end

+ 15
- 0
spec/helpers/routing_helper.rb View File

@@ -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

+ 43
- 1
spec/models/account_spec.rb View File

@@ -1,5 +1,47 @@
1 1
 require 'rails_helper'
2 2
 
3 3
 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
5 47
 end

+ 27
- 1
spec/models/favourite_spec.rb View File

@@ -1,5 +1,31 @@
1 1
 require 'rails_helper'
2 2
 
3 3
 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
5 31
 end

+ 23
- 1
spec/models/follow_spec.rb View File

@@ -1,5 +1,27 @@
1 1
 require 'rails_helper'
2 2
 
3 3
 RSpec.describe Follow, 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
5 27
 end

+ 5
- 0
spec/models/mention_spec.rb View File

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe Mention, type: :model do
4
+
5
+end

+ 31
- 1
spec/models/status_spec.rb View File

@@ -1,5 +1,35 @@
1 1
 require 'rails_helper'
2 2
 
3 3
 RSpec.describe Status, type: :model do
4
-  pending "add some examples to (or delete) #{__FILE__}"
4
+  describe '#local?' do
5
+    pending
6
+  end
7
+
8
+  describe '#reblog?' do
9
+    pending
10
+  end
11
+
12
+  describe '#reply?' do
13
+    pending
14
+  end
15
+
16
+  describe '#mentions' do
17
+    pending
18
+  end
19
+
20
+  describe '#verb' do
21
+    pending
22
+  end
23
+
24
+  describe '#object_type' do
25
+    pending
26
+  end
27
+
28
+  describe '#title' do
29
+    pending
30
+  end
31
+
32
+  describe '#target' do
33
+    pending
34
+  end
5 35
 end

+ 11
- 0
spec/models/stream_entry_spec.rb View File

@@ -0,0 +1,11 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe StreamEntry, type: :model do
4
+  describe '#targeted?' do
5
+    pending
6
+  end
7
+
8
+  describe '#threaded?' do
9
+    pending
10
+  end
11
+end

+ 0
- 5
spec/models/stream_spec.rb View File

@@ -1,5 +0,0 @@
1
-require 'rails_helper'
2
-
3
-RSpec.describe Stream, type: :model do
4
-  pending "add some examples to (or delete) #{__FILE__}"
5
-end

+ 1
- 1
spec/models/user_spec.rb View File

@@ -1,5 +1,5 @@
1 1
 require 'rails_helper'
2 2
 
3 3
 RSpec.describe User, type: :model do
4
-  pending "add some examples to (or delete) #{__FILE__}"
4
+
5 5
 end

+ 16
- 0
spec/rails_helper.rb View File

@@ -0,0 +1,16 @@
1
+ENV['RAILS_ENV'] ||= 'test'
2
+require File.expand_path('../../config/environment', __FILE__)
3
+
4
+abort("The Rails environment is running in production mode!") if Rails.env.production?
5
+
6
+require 'spec_helper'
7
+require 'rspec/rails'
8
+
9
+ActiveRecord::Migration.maintain_test_schema!
10
+
11
+RSpec.configure do |config|
12
+  config.fixture_path = "#{::Rails.root}/spec/fixtures"
13
+  config.use_transactional_fixtures = true
14
+  config.infer_spec_type_from_file_location!
15
+  config.filter_rails_from_backtrace!
16
+end

+ 5
- 0
spec/services/fetch_feed_service_spec.rb View File

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe FetchFeedService do
4
+  pending
5
+end

+ 5
- 0
spec/services/follow_remote_account_service_spec.rb View File

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe FollowRemoteAccountService do
4
+  pending
5
+end

+ 5
- 0
spec/services/follow_service_spec.rb View File

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe FollowService do
4
+  pending
5
+end

+ 5
- 0
spec/services/post_status_service_spec.rb View File

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe PostStatusService do
4
+  pending
5
+end

+ 5
- 0
spec/services/process_feed_service_spec.rb View File

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe ProcessFeedService do
4
+  pending
5
+end

+ 5
- 0
spec/services/process_interaction_service_spec.rb View File

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe ProcessInteractionService do
4
+  pending
5
+end

+ 5
- 0
spec/services/process_mentions_service_spec.rb View File

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe ProcessMentionsService do
4
+  pending
5
+end

+ 5
- 0
spec/services/reblog_service_spec.rb View File

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe ReblogService do
4
+  pending
5
+end

+ 5
- 0
spec/services/send_interaction_service_spec.rb View File

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe SendInteractionService do
4
+  pending
5
+end

+ 5
- 0
spec/services/setup_local_account_service_spec.rb View File

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe SetupLocalAccountService do
4
+  pending
5
+end

+ 5
- 0
spec/services/unfollow_service_spec.rb View File

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe UnfollowService do
4
+  pending
5
+end

+ 15
- 0
spec/spec_helper.rb View File

@@ -0,0 +1,15 @@
1
+require 'simplecov'
2
+
3
+SimpleCov.start 'rails' do
4
+  add_group "Services", "app/services"
5
+end
6
+
7
+RSpec.configure do |config|
8
+  config.expect_with :rspec do |expectations|
9
+    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
10
+  end
11
+
12
+  config.mock_with :rspec do |mocks|
13
+    mocks.verify_partial_doubles = true
14
+  end
15
+end

+ 0
- 5
spec/views/profile/show.html.haml_spec.rb View File

@@ -1,5 +0,0 @@
1
-require 'rails_helper'
2
-
3
-RSpec.describe "profile/show.html.haml", type: :view do
4
-  pending "add some examples to (or delete) #{__FILE__}"
5
-end