socialization 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -0
  3. data/.travis.yml +2 -1
  4. data/Appraisals +13 -1
  5. data/CHANGELOG.md +12 -0
  6. data/Guardfile +12 -0
  7. data/LICENSE +2 -2
  8. data/README.md +46 -1
  9. data/Rakefile +8 -10
  10. data/lib/socialization/stores/active_record/follow.rb +4 -0
  11. data/lib/socialization/stores/active_record/like.rb +4 -0
  12. data/lib/socialization/stores/active_record/mention.rb +4 -0
  13. data/lib/socialization/stores/active_record/mixins/base.rb +4 -0
  14. data/lib/socialization/stores/mixins/follow.rb +1 -1
  15. data/lib/socialization/version.rb +1 -1
  16. data/socialization.gemspec +5 -3
  17. data/spec/actors/follower_spec.rb +113 -0
  18. data/spec/actors/liker_spec.rb +105 -0
  19. data/spec/actors/mentioner_spec.rb +105 -0
  20. data/spec/spec_helper.rb +21 -0
  21. data/{test/test_helper.rb → spec/spec_support/data_stores.rb} +76 -81
  22. data/spec/spec_support/matchers.rb +54 -0
  23. data/spec/stores/active_record/follow_store_spec.rb +147 -0
  24. data/spec/stores/active_record/like_store_spec.rb +146 -0
  25. data/spec/stores/active_record/mention_store_spec.rb +148 -0
  26. data/spec/stores/active_record/mixins/base_spec.rb +25 -0
  27. data/spec/stores/redis/base_spec.rb +195 -0
  28. data/spec/stores/redis/config_spec.rb +28 -0
  29. data/spec/stores/redis/follow_store_spec.rb +26 -0
  30. data/spec/stores/redis/like_store_spec.rb +23 -0
  31. data/spec/stores/redis/mention_store_spec.rb +23 -0
  32. data/spec/string_spec.rb +13 -0
  33. data/spec/victims/followable_spec.rb +59 -0
  34. data/spec/victims/likeable_spec.rb +58 -0
  35. data/spec/victims/mentionable_spec.rb +59 -0
  36. data/spec/world_spec.rb +107 -0
  37. metadata +79 -42
  38. data/test/actors/follower_test.rb +0 -114
  39. data/test/actors/liker_test.rb +0 -106
  40. data/test/actors/mentioner_test.rb +0 -106
  41. data/test/stores/active_record/follow_store_test.rb +0 -138
  42. data/test/stores/active_record/like_store_test.rb +0 -139
  43. data/test/stores/active_record/mention_store_test.rb +0 -138
  44. data/test/stores/redis/base_test.rb +0 -203
  45. data/test/stores/redis/config_test.rb +0 -30
  46. data/test/stores/redis/follow_store_test.rb +0 -27
  47. data/test/stores/redis/like_store_test.rb +0 -25
  48. data/test/stores/redis/mention_store_test.rb +0 -25
  49. data/test/string_test.rb +0 -13
  50. data/test/victims/followable_test.rb +0 -60
  51. data/test/victims/likeable_test.rb +0 -60
  52. data/test/victims/mentionable_test.rb +0 -60
  53. data/test/world_test.rb +0 -112
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe Socialization::Mentioner do
4
+ before(:all) do
5
+ use_ar_store
6
+ @mentioner = ImAMentioner.new
7
+ @mentionable = ImAMentionable.create
8
+ end
9
+
10
+ describe "#is_mentioner?" do
11
+ it "returns true" do
12
+ expect(@mentioner.is_mentioner?).to be true
13
+ end
14
+ end
15
+
16
+ describe "#mentioner?" do
17
+ it "returns true" do
18
+ expect(@mentioner.mentioner?).to be true
19
+ end
20
+ end
21
+
22
+ describe "#mention!" do
23
+ it "does not accept non-mentionables" do
24
+ expect { @mentioner.mention!(:foo) }.to raise_error(Socialization::ArgumentError)
25
+ end
26
+
27
+ it "calls $Mention.mention!" do
28
+ expect($Mention).to receive(:mention!).with(@mentioner, @mentionable).once
29
+ @mentioner.mention!(@mentionable)
30
+ end
31
+ end
32
+
33
+ describe "#unmention!" do
34
+ it "does not accept non-mentionables" do
35
+ expect { @mentioner.unmention!(:foo) }.to raise_error(Socialization::ArgumentError)
36
+ end
37
+
38
+ it "calls $Mention.mention!" do
39
+ expect($Mention).to receive(:unmention!).with(@mentioner, @mentionable).once
40
+ @mentioner.unmention!(@mentionable)
41
+ end
42
+ end
43
+
44
+ describe "#toggle_mention!" do
45
+ it "does not accept non-mentionables" do
46
+ expect { @mentioner.unmention!(:foo) }.to raise_error(Socialization::ArgumentError)
47
+ end
48
+
49
+ it "unmentions when mentioning" do
50
+ expect(@mentioner).to receive(:mentions?).with(@mentionable).once.and_return(true)
51
+ expect(@mentioner).to receive(:unmention!).with(@mentionable).once
52
+ @mentioner.toggle_mention!(@mentionable)
53
+ end
54
+
55
+ it "mentions when not mentioning" do
56
+ expect(@mentioner).to receive(:mentions?).with(@mentionable).once.and_return(false)
57
+ expect(@mentioner).to receive(:mention!).with(@mentionable).once
58
+ @mentioner.toggle_mention!(@mentionable)
59
+ end
60
+ end
61
+
62
+ describe "#mentions?" do
63
+ it "does not accept non-mentionables" do
64
+ expect { @mentioner.unmention!(:foo) }.to raise_error(Socialization::ArgumentError)
65
+ end
66
+
67
+ it "calls $Mention.mentions?" do
68
+ expect($Mention).to receive(:mentions?).with(@mentioner, @mentionable).once
69
+ @mentioner.mentions?(@mentionable)
70
+ end
71
+ end
72
+
73
+ describe "#mentionables" do
74
+ it "calls $Mention.mentionables" do
75
+ expect($Mention).to receive(:mentionables).with(@mentioner, @mentionable.class, { :foo => :bar })
76
+ @mentioner.mentionables(@mentionable.class, { :foo => :bar })
77
+ end
78
+ end
79
+
80
+ describe "#mentionees" do
81
+ it "calls $Mention.mentionables" do
82
+ expect($Mention).to receive(:mentionables).with(@mentioner, @mentionable.class, { :foo => :bar })
83
+ @mentioner.mentionees(@mentionable.class, { :foo => :bar })
84
+ end
85
+ end
86
+
87
+ describe "#mentionables_relation" do
88
+ it "calls $Mention.mentionables_relation" do
89
+ expect($Mention).to receive(:mentionables_relation).with(@mentioner, @mentionable.class, { :foo => :bar })
90
+ @mentioner.mentionables_relation(@mentionable.class, { :foo => :bar })
91
+ end
92
+ end
93
+
94
+ describe "#mentionees_relation" do
95
+ it "calls $Mention.mentionables_relation" do
96
+ expect($Mention).to receive(:mentionables_relation).with(@mentioner, @mentionable.class, { :foo => :bar })
97
+ @mentioner.mentionees_relation(@mentionable.class, { :foo => :bar })
98
+ end
99
+ end
100
+
101
+ it "removes mention relationships" do
102
+ expect(Socialization.mention_model).to receive(:remove_mentionables).with(@mentioner)
103
+ @mentioner.destroy
104
+ end
105
+ end
@@ -0,0 +1,21 @@
1
+ $MOCK_REDIS = true
2
+
3
+ require 'bundler/setup'
4
+ Bundler.setup
5
+
6
+ RSpec.configure do |config|
7
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
8
+ config.filter_run focus: true
9
+ config.run_all_when_everything_filtered = true
10
+ end
11
+
12
+ $:.push File.expand_path("../lib", __FILE__)
13
+ require 'active_record'
14
+ require "socialization"
15
+ require 'spec_support/data_stores'
16
+ require 'spec_support/matchers'
17
+ require 'logger'
18
+
19
+ ActiveSupport::Inflector.inflections do |inflect|
20
+ inflect.irregular 'cache', 'caches'
21
+ end
@@ -1,64 +1,10 @@
1
- $MOCK_REDIS = true
2
-
3
- require 'rubygems'
4
- require 'active_record'
5
- require 'shoulda'
6
- require 'test/unit'
7
- require 'logger'
8
1
  require 'mock_redis' if $MOCK_REDIS
9
2
  require 'redis' unless $MOCK_REDIS
10
- require 'mocha' # mocha always needs to be loaded last! http://stackoverflow.com/questions/3118866/mocha-mock-carries-to-another-test/4375296#4375296
11
- # require 'pry'
12
-
13
- $:.push File.expand_path("../lib", __FILE__)
14
- require "socialization"
15
3
 
16
4
  silence_warnings do
17
5
  Redis = MockRedis if $MOCK_REDIS # Magic!
18
6
  end
19
7
 
20
- module Test::Unit::Assertions
21
- def assert_true(object, message="")
22
- assert_equal(true, object, message)
23
- end
24
-
25
- def assert_false(object, message="")
26
- assert_equal(false, object, message)
27
- end
28
-
29
- def assert_array_similarity(expected, actual, message=nil)
30
- full_message = build_message(message, "<?> expected but was\n<?>.\n", expected, actual)
31
- assert_block(full_message) { (expected.size == actual.size) && (expected - actual == []) }
32
- end
33
-
34
- def assert_empty(obj, msg = nil)
35
- msg = "Expected #{obj.inspect} to be empty" unless msg
36
- assert_respond_to obj, :empty?
37
- assert obj.empty?, msg
38
- end
39
-
40
- def assert_method_public(obj, method, msg = nil)
41
- msg = "Expected method #{obj}.#{method} to be public."
42
- method = if RUBY_VERSION.match(/^1\.8/)
43
- method.to_s
44
- else
45
- method.to_s.to_sym
46
- end
47
-
48
- assert obj.public_methods.include?(method), msg
49
- end
50
- end
51
-
52
- class Test::Unit::TestCase
53
- def setup
54
- use_ar_store
55
- end
56
-
57
- def teardown
58
- clear_redis
59
- end
60
- end
61
-
62
8
  def use_redis_store
63
9
  Socialization.follow_model = Socialization::RedisStores::Follow
64
10
  Socialization.mention_model = Socialization::RedisStores::Mention
@@ -86,7 +32,7 @@ def clear_redis
86
32
  end
87
33
 
88
34
  ActiveRecord::Base.configurations = {'sqlite3' => {:adapter => 'sqlite3', :database => ':memory:'}}
89
- ActiveRecord::Base.establish_connection('sqlite3')
35
+ ActiveRecord::Base.establish_connection(:sqlite3)
90
36
 
91
37
  ActiveRecord::Base.logger = Logger.new(STDERR)
92
38
  ActiveRecord::Base.logger.level = Logger::WARN
@@ -136,44 +82,74 @@ ActiveRecord::Schema.define(:version => 0) do
136
82
  end
137
83
 
138
84
  create_table :im_a_followers do |t|
139
- t.timestamps
85
+ t.timestamps null: true
86
+ end
87
+
88
+ create_table :im_a_follower_with_counter_caches do |t|
89
+ t.integer :followees_count, default: 0
90
+ t.timestamps null: true
140
91
  end
141
92
 
142
93
  create_table :im_a_followables do |t|
143
- t.timestamps
94
+ t.timestamps null: true
95
+ end
96
+
97
+ create_table :im_a_followable_with_counter_caches do |t|
98
+ t.integer :followers_count, default: 0
99
+ t.timestamps null: true
144
100
  end
145
101
 
146
102
  create_table :im_a_likers do |t|
147
- t.timestamps
103
+ t.timestamps null: true
104
+ end
105
+
106
+ create_table :im_a_liker_with_counter_caches do |t|
107
+ t.integer :likees_count, default: 0
108
+ t.timestamps null: true
148
109
  end
149
110
 
150
111
  create_table :im_a_likeables do |t|
151
- t.timestamps
112
+ t.timestamps null: true
113
+ end
114
+
115
+ create_table :im_a_likeable_with_counter_caches do |t|
116
+ t.integer :likers_count, default: 0
117
+ t.timestamps null: true
152
118
  end
153
119
 
154
120
  create_table :im_a_mentioners do |t|
155
- t.timestamps
121
+ t.timestamps null: true
122
+ end
123
+
124
+ create_table :im_a_mentioner_with_counter_caches do |t|
125
+ t.integer :mentionees_count, default: 0
126
+ t.timestamps null: true
156
127
  end
157
128
 
158
129
  create_table :im_a_mentionables do |t|
159
- t.timestamps
130
+ t.timestamps null: true
131
+ end
132
+
133
+ create_table :im_a_mentionable_with_counter_caches do |t|
134
+ t.integer :mentioners_count, default: 0
135
+ t.timestamps null: true
160
136
  end
161
137
 
162
138
  create_table :im_a_mentioner_and_mentionables do |t|
163
- t.timestamps
139
+ t.timestamps null: true
164
140
  end
165
141
 
166
142
  create_table :vanillas do |t|
167
- t.timestamps
143
+ t.timestamps null: true
168
144
  end
169
145
  end
170
146
 
171
- class Celebrity < ActiveRecord::Base
147
+ class ::Celebrity < ActiveRecord::Base
172
148
  acts_as_followable
173
149
  acts_as_mentionable
174
150
  end
175
151
 
176
- class User < ActiveRecord::Base
152
+ class ::User < ActiveRecord::Base
177
153
  acts_as_follower
178
154
  acts_as_followable
179
155
  acts_as_liker
@@ -183,13 +159,13 @@ class User < ActiveRecord::Base
183
159
  has_many :comments
184
160
  end
185
161
 
186
- class Comment < ActiveRecord::Base
162
+ class ::Comment < ActiveRecord::Base
187
163
  acts_as_mentioner
188
164
  belongs_to :user
189
165
  belongs_to :movie
190
166
  end
191
167
 
192
- class Movie < ActiveRecord::Base
168
+ class ::Movie < ActiveRecord::Base
193
169
  acts_as_likeable
194
170
  has_many :comments
195
171
  end
@@ -198,40 +174,59 @@ end
198
174
  # class Like < Socialization::ActiveRecordStores::Like; end
199
175
  # class Mention < Socialization::ActiveRecordStores::Mention; end
200
176
 
201
- class ImAFollower < ActiveRecord::Base
177
+ class ::ImAFollower < ActiveRecord::Base
178
+ acts_as_follower
179
+ end
180
+ class ::ImAFollowerWithCounterCache < ActiveRecord::Base
202
181
  acts_as_follower
203
182
  end
204
- class ImAFollowerChild < ImAFollower; end
183
+ class ::ImAFollowerChild < ImAFollower; end
205
184
 
206
- class ImAFollowable < ActiveRecord::Base
185
+ class ::ImAFollowable < ActiveRecord::Base
207
186
  acts_as_followable
208
187
  end
209
- class ImAFollowableChild < ImAFollowable; end
188
+ class ::ImAFollowableWithCounterCache < ActiveRecord::Base
189
+ acts_as_followable
190
+ end
191
+ class ::ImAFollowableChild < ImAFollowable; end
210
192
 
211
- class ImALiker < ActiveRecord::Base
193
+ class ::ImALiker < ActiveRecord::Base
194
+ acts_as_liker
195
+ end
196
+ class ::ImALikerWithCounterCache < ActiveRecord::Base
212
197
  acts_as_liker
213
198
  end
214
- class ImALikerChild < ImALiker; end
199
+ class ::ImALikerChild < ImALiker; end
215
200
 
216
- class ImALikeable < ActiveRecord::Base
201
+ class ::ImALikeable < ActiveRecord::Base
202
+ acts_as_likeable
203
+ end
204
+ class ::ImALikeableWithCounterCache < ActiveRecord::Base
217
205
  acts_as_likeable
218
206
  end
219
- class ImALikeableChild < ImALikeable; end
207
+ class ::ImALikeableChild < ImALikeable; end
220
208
 
221
- class ImAMentioner < ActiveRecord::Base
209
+ class ::ImAMentioner < ActiveRecord::Base
222
210
  acts_as_mentioner
223
211
  end
224
- class ImAMentionerChild < ImAMentioner; end
212
+ class ::ImAMentionerWithCounterCache < ActiveRecord::Base
213
+ acts_as_mentioner
214
+ end
215
+ class ::ImAMentionerChild < ImAMentioner; end
225
216
 
226
- class ImAMentionable < ActiveRecord::Base
217
+ class ::ImAMentionable < ActiveRecord::Base
227
218
  acts_as_mentionable
228
219
  end
229
- class ImAMentionableChild < ImAMentionable; end
220
+ class ::ImAMentionableWithCounterCache < ActiveRecord::Base
221
+ acts_as_mentionable
222
+ end
223
+ class ::ImAMentionableChild < ImAMentionable; end
230
224
 
231
- class ImAMentionerAndMentionable < ActiveRecord::Base
225
+ class ::ImAMentionerAndMentionable < ActiveRecord::Base
232
226
  acts_as_mentioner
233
227
  acts_as_mentionable
234
228
  end
235
229
 
236
- class Vanilla < ActiveRecord::Base
230
+ class ::Vanilla < ActiveRecord::Base
237
231
  end
232
+
@@ -0,0 +1,54 @@
1
+ RSpec::Matchers.define :be_a_public_method_of do |obj|
2
+ match do |actual|
3
+ method = RUBY_VERSION.match(/^1\.8/) ? actual.to_s : actual.to_s.to_sym
4
+ obj.public_methods.include?(method)
5
+ end
6
+
7
+ failure_message do |actual|
8
+ "expected that #{actual} would be a public method of #{actual.class}"
9
+ end
10
+
11
+ failure_message_when_negated do |actual|
12
+ "expected that #{actual} would not be a public method of #{actual.class}"
13
+ end
14
+
15
+ description do
16
+ "be a public method"
17
+ end
18
+ end
19
+
20
+ RSpec::Matchers.define :match_follower do |expected|
21
+ match do |actual|
22
+ expected.follower_type == actual.class.to_s && expected.follower_id == actual.id
23
+ end
24
+ end
25
+
26
+ RSpec::Matchers.define :match_followable do |expected|
27
+ match do |actual|
28
+ expected.followable_type == actual.class.to_s && expected.followable_id == actual.id
29
+ end
30
+ end
31
+
32
+ RSpec::Matchers.define :match_liker do |expected|
33
+ match do |actual|
34
+ expected.liker_type == actual.class.to_s && expected.liker_id == actual.id
35
+ end
36
+ end
37
+
38
+ RSpec::Matchers.define :match_likeable do |expected|
39
+ match do |actual|
40
+ expected.likeable_type == actual.class.to_s && expected.likeable_id == actual.id
41
+ end
42
+ end
43
+
44
+ RSpec::Matchers.define :match_mentioner do |expected|
45
+ match do |actual|
46
+ expected.mentioner_type == actual.class.to_s && expected.mentioner_id == actual.id
47
+ end
48
+ end
49
+
50
+ RSpec::Matchers.define :match_mentionable do |expected|
51
+ match do |actual|
52
+ expected.mentionable_type == actual.class.to_s && expected.mentionable_id == actual.id
53
+ end
54
+ end
@@ -0,0 +1,147 @@
1
+ require 'spec_helper'
2
+
3
+ describe Socialization::ActiveRecordStores::Follow do
4
+ before do
5
+ @klass = Socialization::ActiveRecordStores::Follow
6
+ @klass.touch nil
7
+ @klass.after_follow nil
8
+ @klass.after_unfollow nil
9
+ @follower = ImAFollower.create
10
+ @followable = ImAFollowable.create
11
+ end
12
+
13
+ describe "data store" do
14
+ it "inherits Socialization::ActiveRecordStores::Follow" do
15
+ expect(Socialization.follow_model).to eq(Socialization::ActiveRecordStores::Follow)
16
+ end
17
+ end
18
+
19
+ describe "#follow!" do
20
+ it "creates a Follow record" do
21
+ @klass.follow!(@follower, @followable)
22
+ expect(@follower).to match_follower(@klass.last)
23
+ expect(@followable).to match_followable(@klass.last)
24
+ end
25
+
26
+ it "increments counter caches" do
27
+ follower = ImAFollowerWithCounterCache.create
28
+ followable = ImAFollowableWithCounterCache.create
29
+ @klass.follow!(follower, followable)
30
+ expect(follower.reload.followees_count).to eq(1)
31
+ expect(followable.reload.followers_count).to eq(1)
32
+ end
33
+
34
+ it "touches follower when instructed" do
35
+ @klass.touch :follower
36
+ expect(@follower).to receive(:touch).once
37
+ expect(@followable).to receive(:touch).never
38
+ @klass.follow!(@follower, @followable)
39
+ end
40
+
41
+ it "touches followable when instructed" do
42
+ @klass.touch :followable
43
+ expect(@follower).to receive(:touch).never
44
+ expect(@followable).to receive(:touch).once
45
+ @klass.follow!(@follower, @followable)
46
+ end
47
+
48
+ it "touches all when instructed" do
49
+ @klass.touch :all
50
+ expect(@follower).to receive(:touch).once
51
+ expect(@followable).to receive(:touch).once
52
+ @klass.follow!(@follower, @followable)
53
+ end
54
+
55
+ it "calls after follow hook" do
56
+ @klass.after_follow :after_follow
57
+ expect(@klass).to receive(:after_follow).once
58
+ @klass.follow!(@follower, @followable)
59
+ end
60
+
61
+ it "calls after unfollow hook" do
62
+ @klass.after_follow :after_unfollow
63
+ expect(@klass).to receive(:after_unfollow).once
64
+ @klass.follow!(@follower, @followable)
65
+ end
66
+ end
67
+
68
+ describe "#unfollow!" do
69
+ it "decrements counter caches" do
70
+ follower = ImAFollowerWithCounterCache.create
71
+ followable = ImAFollowableWithCounterCache.create
72
+ @klass.follow!(follower, followable)
73
+ @klass.unfollow!(follower, followable)
74
+ expect(follower.reload.followees_count).to eq(0)
75
+ expect(followable.reload.followers_count).to eq(0)
76
+ end
77
+ end
78
+
79
+ describe "#follows?" do
80
+ it "returns true when follow exists" do
81
+ @klass.create! do |f|
82
+ f.follower = @follower
83
+ f.followable = @followable
84
+ end
85
+ expect(@klass.follows?(@follower, @followable)).to be true
86
+ end
87
+
88
+ it "returns false when follow doesn't exist" do
89
+ expect(@klass.follows?(@follower, @followable)).to be false
90
+ end
91
+ end
92
+
93
+ describe "#followers" do
94
+ it "returns an array of followers" do
95
+ follower1 = ImAFollower.create
96
+ follower2 = ImAFollower.create
97
+ follower1.follow!(@followable)
98
+ follower2.follow!(@followable)
99
+ expect(@klass.followers(@followable, follower1.class)).to eq([follower1, follower2])
100
+ end
101
+
102
+ it "returns an array of follower ids when plucking" do
103
+ follower1 = ImAFollower.create
104
+ follower2 = ImAFollower.create
105
+ follower1.follow!(@followable)
106
+ follower2.follow!(@followable)
107
+ expect(@klass.followers(@followable, follower1.class, :pluck => :id)).to eq([follower1.id, follower2.id])
108
+ end
109
+ end
110
+
111
+ describe "#followables" do
112
+ it "returns an array of followers" do
113
+ followable1 = ImAFollowable.create
114
+ followable2 = ImAFollowable.create
115
+ @follower.follow!(followable1)
116
+ @follower.follow!(followable2)
117
+ expect(@klass.followables(@follower, followable1.class)).to eq([followable1, followable2])
118
+ end
119
+
120
+ it "returns an array of follower ids when plucking" do
121
+ followable1 = ImAFollowable.create
122
+ followable2 = ImAFollowable.create
123
+ @follower.follow!(followable1)
124
+ @follower.follow!(followable2)
125
+ expect(@klass.followables(@follower, followable1.class, :pluck => :id)).to eq([followable1.id, followable2.id])
126
+ end
127
+ end
128
+
129
+ describe "#remove_followers" do
130
+ it "deletes all followers relationships for a followable" do
131
+ @follower.follow!(@followable)
132
+ expect(@followable.followers(@follower.class).count).to eq(1)
133
+ @klass.remove_followers(@followable)
134
+ expect(@followable.followers(@follower.class).count).to eq(0)
135
+ end
136
+ end
137
+
138
+ describe "#remove_followables" do
139
+ it "deletes all followables relationships for a follower" do
140
+ @follower.follow!(@followable)
141
+ expect(@follower.followables(@followable.class).count).to eq(1)
142
+ @klass.remove_followables(@follower)
143
+ expect(@follower.followables(@followable.class).count).to eq(0)
144
+ end
145
+ end
146
+ end
147
+