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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/.travis.yml +2 -1
- data/Appraisals +13 -1
- data/CHANGELOG.md +12 -0
- data/Guardfile +12 -0
- data/LICENSE +2 -2
- data/README.md +46 -1
- data/Rakefile +8 -10
- data/lib/socialization/stores/active_record/follow.rb +4 -0
- data/lib/socialization/stores/active_record/like.rb +4 -0
- data/lib/socialization/stores/active_record/mention.rb +4 -0
- data/lib/socialization/stores/active_record/mixins/base.rb +4 -0
- data/lib/socialization/stores/mixins/follow.rb +1 -1
- data/lib/socialization/version.rb +1 -1
- data/socialization.gemspec +5 -3
- data/spec/actors/follower_spec.rb +113 -0
- data/spec/actors/liker_spec.rb +105 -0
- data/spec/actors/mentioner_spec.rb +105 -0
- data/spec/spec_helper.rb +21 -0
- data/{test/test_helper.rb → spec/spec_support/data_stores.rb} +76 -81
- data/spec/spec_support/matchers.rb +54 -0
- data/spec/stores/active_record/follow_store_spec.rb +147 -0
- data/spec/stores/active_record/like_store_spec.rb +146 -0
- data/spec/stores/active_record/mention_store_spec.rb +148 -0
- data/spec/stores/active_record/mixins/base_spec.rb +25 -0
- data/spec/stores/redis/base_spec.rb +195 -0
- data/spec/stores/redis/config_spec.rb +28 -0
- data/spec/stores/redis/follow_store_spec.rb +26 -0
- data/spec/stores/redis/like_store_spec.rb +23 -0
- data/spec/stores/redis/mention_store_spec.rb +23 -0
- data/spec/string_spec.rb +13 -0
- data/spec/victims/followable_spec.rb +59 -0
- data/spec/victims/likeable_spec.rb +58 -0
- data/spec/victims/mentionable_spec.rb +59 -0
- data/spec/world_spec.rb +107 -0
- metadata +79 -42
- data/test/actors/follower_test.rb +0 -114
- data/test/actors/liker_test.rb +0 -106
- data/test/actors/mentioner_test.rb +0 -106
- data/test/stores/active_record/follow_store_test.rb +0 -138
- data/test/stores/active_record/like_store_test.rb +0 -139
- data/test/stores/active_record/mention_store_test.rb +0 -138
- data/test/stores/redis/base_test.rb +0 -203
- data/test/stores/redis/config_test.rb +0 -30
- data/test/stores/redis/follow_store_test.rb +0 -27
- data/test/stores/redis/like_store_test.rb +0 -25
- data/test/stores/redis/mention_store_test.rb +0 -25
- data/test/string_test.rb +0 -13
- data/test/victims/followable_test.rb +0 -60
- data/test/victims/likeable_test.rb +0 -60
- data/test/victims/mentionable_test.rb +0 -60
- 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
|
data/spec/spec_helper.rb
ADDED
@@ -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(
|
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
|
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
|
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
|
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
|
+
|