acts_as_amico 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -34,7 +34,7 @@ Amico.configure do |configuration|
34
34
  end
35
35
  ```
36
36
 
37
- ### Amico module loadable methods:
37
+ ### Basic Usage
38
38
 
39
39
  ```ruby
40
40
  require 'amico'
@@ -130,12 +130,14 @@ usera.reciprocated
130
130
  => ["11"]
131
131
  ```
132
132
 
133
- You can also use non-id keys:
133
+ ### Non-ID Keys
134
+ You can also use non-id keys
134
135
 
135
136
  ```ruby
136
137
  class Admin < ActiveRecord::Base
137
- acts_as_amico :amico_key => "name"
138
- validates_uniqueness_of :name # -> do this or be sorry :)
138
+ acts_as_amico :amico_key => :name
139
+ validates_uniqueness_of :name # -> do this or be sorry
140
+ validates_presence_of :name # -> this too, you've been warned
139
141
  end
140
142
 
141
143
  usera = User.create
@@ -158,6 +160,37 @@ usera.followers
158
160
  => ["frank"]
159
161
  ```
160
162
 
163
+ ### ActiveResource Models
164
+
165
+ You can use active resource models as well
166
+
167
+ ```ruby
168
+ class RestObject < ActiveResource::Base
169
+ acts_as_amico :amico_key => :title
170
+ end
171
+
172
+ usera = User.create
173
+
174
+ rest_object = RestObject.find(123)
175
+
176
+ rest_object.title
177
+ => "Bread and Circus"
178
+
179
+ usera.follow! rest_object
180
+
181
+ usera.following? rest_object
182
+ => true
183
+
184
+ usera.following
185
+ => ["Bread and Circus"]
186
+ ```
187
+
188
+ One note about ActiveResource: You have to be careful what you use as the :amico_key. For
189
+ instance, using ```acts_as_amico :amico_key => :name``` is an exceptionally bad idea because
190
+ this will cause a ```SystemStackError: stack level too deep``` because acts_as_amico uses
191
+ the Rails::Object#send method to get the key, and for some reason if the send method even
192
+ *touches* the string/symbol "name" we get cascaded through the object graph.
193
+
161
194
  ## Documentation
162
195
 
163
196
  Acts_as_amico is feature complete with the amico gem. [The Amico API usage page](https://github.com/mettadore/amico/blob/master/API.md)
@@ -167,7 +200,7 @@ is well-documented. There are some simple examples in the method documentation.
167
200
 
168
201
  ## Future Plans
169
202
 
170
- Clean up the ActiveResource integration
203
+ Clean up the ActiveResource integration and figure out why :name is so dangerous.
171
204
 
172
205
  ## Contributing to acts_as_amico
173
206
 
data/lib/acts_as_amico.rb CHANGED
@@ -1,10 +1,14 @@
1
+ require 'rails/all'
1
2
  require 'redis'
2
3
  require 'amico'
3
4
  require 'acts_as_amico'
4
5
  require 'acts_as_amico/version'
5
6
 
6
7
  module ActsAsAmico
7
- autoload :AmicoUser, 'acts_as_amico/amico_user'
8
+ autoload :AmicoObject, 'acts_as_amico/amico_object'
8
9
 
9
10
  require 'acts_as_amico/railtie'
10
11
  end
12
+
13
+ ActiveRecord::Base.send :include, ActsAsAmico::AmicoObject
14
+ ActiveResource::Base.send :include, ActsAsAmico::AmicoObject
@@ -1,5 +1,5 @@
1
1
  module ActsAsAmico
2
- module AmicoUser
2
+ module AmicoObject
3
3
 
4
4
  def self.included(base)
5
5
  base.extend ClassMethods
@@ -8,7 +8,7 @@ module ActsAsAmico
8
8
  module ClassMethods
9
9
 
10
10
  def amico_key
11
- @amico_key ||= "id"
11
+ @amico_key ||= :id
12
12
  end
13
13
  def amico_key= value
14
14
  @amico_key = value
@@ -17,8 +17,8 @@ module ActsAsAmico
17
17
  def acts_as_amico *args
18
18
  options = args.extract_options!
19
19
  options.assert_valid_keys(:amico_key)
20
- @amico_key = options[:amico_key] ? options[:amico_key] : "id"
21
- include ActsAsAmico::AmicoUser::InstanceMethods
20
+ @amico_key = options[:amico_key] ? options[:amico_key] : :id
21
+ include ActsAsAmico::AmicoObject::InstanceMethods
22
22
  end
23
23
  end
24
24
 
@@ -6,13 +6,13 @@ module ActsAsAmico
6
6
 
7
7
  initializer "acts_as_amico.active_record" do |app|
8
8
  ActiveSupport.on_load :active_record do
9
- include ActsAsAmico::AmicoUser
9
+ include ActsAsAmico::AmicoObject
10
10
  end
11
11
  end
12
12
 
13
13
  initializer "acts_as_amico.active_resource" do |app|
14
14
  ActiveSupport.on_load :active_resource do
15
- include ActsAsAmico::AmicoUser
15
+ include ActsAsAmico::AmicoObject
16
16
  end
17
17
  end
18
18
 
@@ -1,3 +1,3 @@
1
1
  module ActsAsAmico
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActsAsAmico do
4
+ before :all do
5
+ FakeWeb.allow_net_connect = false
6
+ @all_resp = '<rest_objects type="array">
7
+ <rest_object><id>123</id><title>Blah</title><description>Some stuff</description></rest_object>
8
+ <rest_object><id>321</id><title>Blah</title><description>Some stuff</description></rest_object>
9
+ </rest_objects>'
10
+ @resp_123 = '<rest_object><id>123</id><title>Blah</title><description>Some stuff</description></rest_object>'
11
+ @resp_321 = '<rest_object><id>321</id><title>Blah</title><description>Some stuff</description></rest_object>'
12
+
13
+ FakeWeb.register_uri(:get, "http://api.sample.com/rest_objects/123.xml", :body => @resp_123, :status => ["200", "OK"])
14
+ FakeWeb.register_uri(:get, "http://api.sample.com/rest_objects/321.xml", :body => @resp_321, :status => ["200", "OK"])
15
+ end
16
+
17
+ after :all do
18
+ FakeWeb.allow_net_connect=true
19
+ end
20
+
21
+ before :each do
22
+ @usera = Factory :user
23
+ @admin = Factory :admin
24
+ @rest_object = RestObject.find(321)
25
+ end
26
+
27
+ it "should hold an amico_key" do
28
+ @rest_object.class.amico_key.should eq(:title)
29
+ end
30
+
31
+ it "should allow following an ActiveResource object" do
32
+ @usera.follow! @rest_object, 'rest_object'
33
+ # @usera.following?(@rest_object).should be_true
34
+
35
+ # @rest_object.followers.include?(@usera.id).should be_true
36
+ end
37
+ end
@@ -0,0 +1,698 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActsAsAmico do
4
+ before :each do
5
+ @usera = Factory :user
6
+ @userb = Factory :user
7
+ @admin = Factory :admin
8
+ @widget = Factory :widget
9
+ @thing = Factory :thing
10
+ end
11
+
12
+ it "should allow both id and non-id keys" do
13
+ @usera.class.amico_key.should eq(:id)
14
+ @admin.class.amico_key.should eq(:name)
15
+ end
16
+
17
+ describe '#follow' do
18
+ it 'should allow you to follow' do
19
+ @usera.follow(@userb)
20
+
21
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
22
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(1)
23
+ end
24
+
25
+ it 'should not allow you to follow yourself' do
26
+ @usera.follow(@usera)
27
+
28
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
29
+ end
30
+
31
+ it 'should add each individual to the reciprocated set if you both follow each other' do
32
+ @usera.follow(@userb)
33
+ @userb.follow(@usera)
34
+
35
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
36
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(1)
37
+ end
38
+ describe "with non-id key" do
39
+ it 'should allow you to follow' do
40
+ @usera.follow(@admin)
41
+
42
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
43
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{Amico.default_scope_key}:#{@admin.send(@admin.class.amico_key)}").should be(1)
44
+ end
45
+
46
+ it 'should add each individual to the reciprocated set if you both follow each other' do
47
+ @usera.follow(@admin)
48
+ @admin.follow(@usera)
49
+
50
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
51
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@admin.send(@admin.class.amico_key)}").should be(1)
52
+ end
53
+
54
+ end
55
+ end
56
+
57
+ describe '#unfollow' do
58
+ it 'should allow you to unfollow' do
59
+ @usera.follow(@userb)
60
+
61
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
62
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(1)
63
+
64
+ @usera.unfollow(@userb)
65
+
66
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
67
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
68
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
69
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
70
+ end
71
+
72
+ describe "non-id key" do
73
+ it 'should allow you to unfollow' do
74
+ @usera.follow(@admin)
75
+
76
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
77
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{Amico.default_scope_key}:#{@admin.send(@admin.class.amico_key)}").should be(1)
78
+
79
+ @usera.unfollow(@admin)
80
+
81
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
82
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{Amico.default_scope_key}:#{@admin.send(@admin.class.amico_key)}").should be(0)
83
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
84
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@admin.send(@admin.class.amico_key)}").should be(0)
85
+ end
86
+ end
87
+ end
88
+
89
+ describe '#block' do
90
+ it 'should allow you to block someone following you' do
91
+ @userb.follow(@usera)
92
+ @usera.block(@userb)
93
+
94
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
95
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
96
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
97
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
98
+ end
99
+
100
+ it 'should allow you to block someone who is not following you' do
101
+ @usera.block(@userb)
102
+
103
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
104
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
105
+ end
106
+
107
+ it 'should not allow someone you have blocked to follow you' do
108
+ @usera.block(@userb)
109
+
110
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
111
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
112
+
113
+ @userb.follow(@usera)
114
+
115
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
116
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
117
+ end
118
+
119
+ it 'should not allow you to block yourself' do
120
+ @usera.block(@usera)
121
+ @usera.blocked?(@usera).should be_false
122
+ end
123
+ describe "non-id key" do
124
+ it 'should allow you to block someone following you' do
125
+ @admin.follow(@usera)
126
+ @usera.block(@admin)
127
+
128
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@userb.send(@admin.class.amico_key)}").should be(0)
129
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
130
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
131
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@userb.send(@admin.class.amico_key)}").should be(0)
132
+ end
133
+
134
+ it 'should allow you to block someone who is not following you' do
135
+ @usera.block(@userb)
136
+
137
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@userb.send(@admin.class.amico_key)}").should be(0)
138
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
139
+ end
140
+
141
+ it 'should not allow someone you have blocked to follow you' do
142
+ @usera.block(@admin)
143
+
144
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@userb.send(@admin.class.amico_key)}").should be(0)
145
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
146
+
147
+ @admin.follow(@usera)
148
+
149
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@userb.send(@admin.class.amico_key)}").should be(0)
150
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
151
+ end
152
+
153
+ end
154
+ end
155
+
156
+ describe '#unblock' do
157
+ it 'should allow you to unblock someone you have blocked' do
158
+ @usera.block(@userb)
159
+ @usera.blocked?(@userb).should be_true
160
+ @usera.unblock(@userb)
161
+ @usera.blocked?(@userb).should be_false
162
+ end
163
+ it 'should allow you to unblock someone you have blocked with non-id keys' do
164
+ @usera.block(@admin)
165
+ @usera.blocked?(@admin).should be_true
166
+ @usera.unblock(@admin)
167
+ @usera.blocked?(@admin).should be_false
168
+ end
169
+ end
170
+
171
+ describe "destructive methods named with ! bang" do
172
+ describe '#follow' do
173
+ it 'should allow you to follow' do
174
+ @usera.follow!(@userb)
175
+
176
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
177
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(1)
178
+ end
179
+
180
+ it 'should not allow you to follow yourself' do
181
+ @usera.follow!(@usera)
182
+
183
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
184
+ end
185
+
186
+ it 'should add each individual to the reciprocated set if you both follow each other' do
187
+ @usera.follow!(@userb)
188
+ @userb.follow!(@usera)
189
+
190
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
191
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(1)
192
+ end
193
+ end
194
+
195
+ describe '#unfollow' do
196
+ it 'should allow you to unfollow' do
197
+ @usera.follow!(@userb)
198
+
199
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
200
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(1)
201
+
202
+ @usera.unfollow!(@userb)
203
+
204
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
205
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
206
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
207
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
208
+ end
209
+ end
210
+ describe '#block!' do
211
+ it 'should allow you to block someone following you' do
212
+ @userb.follow(@usera)
213
+ @usera.block!(@userb)
214
+
215
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
216
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
217
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
218
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
219
+ end
220
+
221
+ it 'should allow you to block someone who is not following you' do
222
+ @usera.block!(@userb)
223
+
224
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
225
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
226
+ end
227
+
228
+ it 'should not allow someone you have blocked to follow you' do
229
+ @usera.block!(@userb)
230
+
231
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
232
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
233
+
234
+ @userb.follow!(@usera)
235
+
236
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
237
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(1)
238
+ end
239
+
240
+ it 'should not allow you to block yourself' do
241
+ @usera.block!(@usera)
242
+ @usera.blocked?(@usera).should be_false
243
+ end
244
+ end
245
+ describe '#unblock!' do
246
+ it 'should allow you to unblock someone you have blocked' do
247
+ @usera.block!(@userb)
248
+ @usera.blocked?(@userb).should be_true
249
+ @usera.unblock!(@userb)
250
+ @usera.blocked?(@userb).should be_false
251
+ end
252
+ end
253
+
254
+ end
255
+
256
+ describe '#following?' do
257
+ it 'should return that you are following' do
258
+ @usera.follow(@userb)
259
+ @usera.following?(@userb).should be_true
260
+ @userb.following?(@usera).should be_false
261
+
262
+ @userb.follow(@usera)
263
+ @userb.following?(@usera).should be_true
264
+ end
265
+ describe "non-id keys" do
266
+ it 'should return that you are following' do
267
+ @usera.follow(@admin)
268
+ @usera.following?(@admin).should be_true
269
+ @admin.following?(@usera).should be_false
270
+
271
+ @admin.follow(@usera)
272
+ @admin.following?(@usera).should be_true
273
+ end
274
+ end
275
+ end
276
+
277
+ describe '#follower?' do
278
+ it 'should return that you are being followed' do
279
+ @userb.follow(@usera)
280
+ @usera.follower?(@userb).should be_true
281
+ @userb.follower?(@usera).should be_false
282
+
283
+ @usera.follow(@userb)
284
+ @userb.follower?(@usera).should be_true
285
+ end
286
+ describe "non-id keys" do
287
+ it 'should return that you are being followed' do
288
+ @admin.follow(@usera)
289
+ @usera.follower?(@admin).should be_true
290
+ @admin.follower?(@usera).should be_false
291
+
292
+ @usera.follow(@admin)
293
+ @admin.follower?(@usera).should be_true
294
+ end
295
+ end
296
+ end
297
+
298
+ describe '#blocked?' do
299
+ it 'should return that someone is being blocked' do
300
+ @usera.block(@userb)
301
+ @usera.blocked?(@userb).should be_true
302
+ @userb.following?(@usera).should be_false
303
+ end
304
+ describe "non-id keys" do
305
+ it 'should return that someone is being blocked' do
306
+ @usera.block(@admin)
307
+ @usera.blocked?(@admin).should be_true
308
+ @admin.following?(@usera).should be_false
309
+ end
310
+ end
311
+ end
312
+
313
+ describe '#reciprocated?' do
314
+ it 'should return true if both individuals are following each other' do
315
+ @usera.follow(@userb)
316
+ @userb.follow(@usera)
317
+ @usera.reciprocated?(@userb).should be_true
318
+ end
319
+
320
+ it 'should return false if both individuals are not following each other' do
321
+ @usera.follow(@userb)
322
+ @usera.reciprocated?(@userb).should be_false
323
+ end
324
+ describe "non-id keys" do
325
+ it 'should return true if both individuals are following each other' do
326
+ @usera.follow(@admin)
327
+ @admin.follow(@usera)
328
+ @usera.reciprocated?(@admin).should be_true
329
+ end
330
+
331
+ it 'should return false if both individuals are not following each other' do
332
+ @usera.follow(@admin)
333
+ @usera.reciprocated?(@admin).should be_false
334
+ end
335
+ end
336
+ end
337
+
338
+ describe '#following' do
339
+ it 'should return the correct list' do
340
+ userc = Factory :user
341
+ @usera.follow(@userb)
342
+ @usera.follow(userc)
343
+ @usera.following.should eql(["#{userc.id}", "#{@userb.send(@userb.class.amico_key)}"])
344
+ @usera.following(:page => 5).should eql(["#{userc.id}", "#{@userb.send(@userb.class.amico_key)}"])
345
+ end
346
+
347
+ it 'should page correctly' do
348
+ user = add_reciprocal_followers
349
+
350
+ user.following(:page => 1, :page_size => 5).size.should be(5)
351
+ user.following(:page => 1, :page_size => 10).size.should be(10)
352
+ user.following(:page => 1, :page_size => 25).size.should be(25)
353
+ end
354
+ describe "non-id keys" do
355
+ it 'should return the correct list' do
356
+ userc = Factory :user
357
+ @usera.follow(@admin)
358
+ @usera.follow(userc)
359
+ @usera.following.should =~ ["#{userc.id}", "#{@admin.send(@admin.class.amico_key)}"]
360
+ @usera.following(:page => 5).should =~ ["#{userc.id}", "#{@admin.send(@admin.class.amico_key)}"]
361
+ end
362
+ end
363
+ end
364
+
365
+ describe '#followers' do
366
+ it 'should return the correct list' do
367
+ userc = Factory :user
368
+ @usera.follow(@userb)
369
+ userc.follow(@userb)
370
+ @userb.followers.should eql(["#{userc.id}", "#{@usera.send(@usera.class.amico_key)}"])
371
+ @userb.followers(:page => 5).should eql(["#{userc.id}", "#{@usera.send(@usera.class.amico_key)}"])
372
+ end
373
+
374
+ it 'should page correctly' do
375
+ user = add_reciprocal_followers
376
+
377
+ user.followers(:page => 1, :page_size => 5).size.should be(5)
378
+ user.followers(:page => 1, :page_size => 10).size.should be(10)
379
+ user.followers(:page => 1, :page_size => 25).size.should be(25)
380
+ end
381
+ describe "non-id keys" do
382
+ it 'should return the correct list' do
383
+ userc = Factory :user
384
+ @usera.follow(@admin)
385
+ userc.follow(@admin)
386
+ @admin.followers.should eql(["#{userc.id}", "#{@usera.send(@usera.class.amico_key)}"])
387
+ @admin.followers(:page => 5).should eql(["#{userc.id}", "#{@usera.send(@usera.class.amico_key)}"])
388
+ end
389
+ end
390
+ end
391
+
392
+ describe '#blocked' do
393
+ it 'should return the correct list' do
394
+ userc = Factory :user
395
+ @usera.block(@userb)
396
+ @usera.block(userc)
397
+ @usera.blocked.should eql(["#{userc.id}", "#{@userb.send(@userb.class.amico_key)}"])
398
+ @usera.blocked(:page => 5).should eql(["#{userc.id}", "#{@userb.send(@userb.class.amico_key)}"])
399
+ end
400
+
401
+ it 'should page correctly' do
402
+ user = add_reciprocal_followers(26, true)
403
+
404
+ user.blocked(:page => 1, :page_size => 5).size.should be(5)
405
+ user.blocked(:page => 1, :page_size => 10).size.should be(10)
406
+ user.blocked(:page => 1, :page_size => 25).size.should be(25)
407
+ end
408
+ describe "non-id keys" do
409
+ it 'should return the correct list' do
410
+ userc = Factory :user
411
+ @usera.block(@admin)
412
+ @usera.block(userc)
413
+ @usera.blocked.should =~ ["#{userc.id}", "#{@admin.send(@admin.class.amico_key)}"]
414
+ @usera.blocked(:page => 5).should =~ ["#{userc.id}", "#{@admin.send(@admin.class.amico_key)}"]
415
+ end
416
+ end
417
+ end
418
+
419
+ describe '#reciprocated' do
420
+ it 'should return the correct list' do
421
+ @usera.follow(@userb)
422
+ @userb.follow(@usera)
423
+ @usera.reciprocated.should eql(["#{@userb.send(@userb.class.amico_key)}"])
424
+ @userb.reciprocated.should eql(["#{@usera.send(@usera.class.amico_key)}"])
425
+ end
426
+
427
+ it 'should page correctly' do
428
+ user = add_reciprocal_followers
429
+
430
+ user.reciprocated(:page => 1, :page_size => 5).size.should be(5)
431
+ user.reciprocated(:page => 1, :page_size => 10).size.should be(10)
432
+ user.reciprocated(:page => 1, :page_size => 25).size.should be(25)
433
+ end
434
+ describe "non-id keys" do
435
+ it 'should return the correct list' do
436
+ @usera.follow(@admin)
437
+ @admin.follow(@usera)
438
+ @usera.reciprocated.should eql(["#{@admin.send(@admin.class.amico_key)}"])
439
+ @admin.reciprocated.should eql(["#{@usera.send(@usera.class.amico_key)}"])
440
+ end
441
+ end
442
+ end
443
+
444
+ describe '#following_count' do
445
+ it 'should return the correct count' do
446
+ @usera.follow(@userb)
447
+ @usera.following_count.should be(1)
448
+ end
449
+ it 'should return the correct count for non-id keys' do
450
+ @usera.follow(@admin)
451
+ @usera.following_count.should be(1)
452
+ end
453
+ end
454
+
455
+ describe '#followers_count' do
456
+ it 'should return the correct count' do
457
+ @usera.follow(@userb)
458
+ @userb.followers_count.should be(1)
459
+ end
460
+ it 'should return the correct count for non-id keys' do
461
+ @usera.follow(@admin)
462
+ @admin.followers_count.should be(1)
463
+ end
464
+ end
465
+
466
+ describe '#blocked_count' do
467
+ it 'should return the correct count' do
468
+ @usera.block(@userb)
469
+ @usera.blocked_count.should be(1)
470
+ end
471
+ it 'should return the correct count for non-id keys' do
472
+ @usera.block(@admin)
473
+ @usera.blocked_count.should be(1)
474
+ end
475
+ end
476
+
477
+ describe '#reciprocated_count' do
478
+ it 'should return the correct count' do
479
+ userc = Factory :user
480
+ userd = Factory :user
481
+ @usera.follow(@userb)
482
+ @userb.follow(@usera)
483
+ @usera.follow(userc)
484
+ userc.follow(@usera)
485
+ @usera.follow(userd)
486
+ @usera.reciprocated_count.should be(2)
487
+ end
488
+ it 'should return the correct count for non-id keys' do
489
+ userc = Factory :user
490
+ userd = Factory :user
491
+ @usera.follow(@admin)
492
+ @admin.follow(@usera)
493
+ @usera.follow(userc)
494
+ userc.follow(@usera)
495
+ @usera.follow(userd)
496
+ @usera.reciprocated_count.should be(2)
497
+ end
498
+ end
499
+
500
+ describe 'pending_follow enabled' do
501
+ before(:each) do
502
+ Amico.pending_follow = true
503
+ end
504
+
505
+ after(:each) do
506
+ Amico.pending_follow = false
507
+ end
508
+
509
+ describe '#follow' do
510
+ it 'should allow you to follow but the relationship is initially pending' do
511
+ @usera.follow(@userb)
512
+
513
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
514
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
515
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.pending_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(1)
516
+ end
517
+
518
+ it 'should remove the pending relationship if you have a pending follow, but you unfollow' do
519
+ @usera.follow(@userb)
520
+
521
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
522
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
523
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.pending_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(1)
524
+
525
+ @usera.unfollow(@userb)
526
+
527
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{Amico.default_scope_key}:#{@usera.send(@usera.class.amico_key)}").should be(0)
528
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
529
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.pending_key}:#{Amico.default_scope_key}:#{@userb.send(@userb.class.amico_key)}").should be(0)
530
+ end
531
+
532
+ describe 'removing the pending relationship and add to following and followers if #accept is called' do
533
+ it "should work with non-bang-named methods" do
534
+ @usera.follow(@userb)
535
+ @usera.pending?(@userb).should be_true
536
+
537
+ @usera.accept(@userb)
538
+
539
+ @usera.pending?(@userb).should be_false
540
+ @usera.following?(@userb).should be_true
541
+ @userb.following?(@usera).should be_false
542
+ @userb.follower?(@usera).should be_true
543
+ @usera.follower?(@userb).should be_false
544
+ end
545
+ it "should work with ! bang-named methods" do
546
+ @usera.follow!(@userb)
547
+ @usera.pending?(@userb).should be_true
548
+
549
+ @usera.accept!(@userb)
550
+
551
+ @usera.pending?(@userb).should be_false
552
+ @usera.following?(@userb).should be_true
553
+ @userb.following?(@usera).should be_false
554
+ @userb.follower?(@usera).should be_true
555
+ @usera.follower?(@userb).should be_false
556
+ end
557
+ end
558
+
559
+ describe 'removing the pending relationship and add to following and followers if #accept is called and add to reciprocated relationship' do
560
+ it "should work with non-bang-named methods" do
561
+ @usera.follow(@userb)
562
+ @userb.follow(@usera)
563
+ @usera.pending?(@userb).should be_true
564
+ @userb.pending?(@usera).should be_true
565
+
566
+ @usera.accept(@userb)
567
+
568
+ @usera.pending?(@userb).should be_false
569
+ @userb.pending?(@usera).should be_true
570
+ @usera.following?(@userb).should be_true
571
+ @userb.following?(@usera).should be_false
572
+ @userb.follower?(@usera).should be_true
573
+ @usera.follower?(@userb).should be_false
574
+
575
+ @userb.accept(@usera)
576
+
577
+ @usera.pending?(@userb).should be_false
578
+ @userb.pending?(@usera).should be_false
579
+ @usera.following?(@userb).should be_true
580
+ @userb.following?(@usera).should be_true
581
+ @userb.follower?(@usera).should be_true
582
+ @usera.follower?(@userb).should be_true
583
+ @usera.reciprocated?(@userb).should be_true
584
+ end
585
+ it "should work with ! bang-named methods" do
586
+ @usera.follow!(@userb)
587
+ @userb.follow!(@usera)
588
+ @usera.pending?(@userb).should be_true
589
+ @userb.pending?(@usera).should be_true
590
+
591
+ @usera.accept!(@userb)
592
+
593
+ @usera.pending?(@userb).should be_false
594
+ @userb.pending?(@usera).should be_true
595
+ @usera.following?(@userb).should be_true
596
+ @userb.following?(@usera).should be_false
597
+ @userb.follower?(@usera).should be_true
598
+ @usera.follower?(@userb).should be_false
599
+
600
+ @userb.accept!(@usera)
601
+
602
+ @usera.pending?(@userb).should be_false
603
+ @userb.pending?(@usera).should be_false
604
+ @usera.following?(@userb).should be_true
605
+ @userb.following?(@usera).should be_true
606
+ @userb.follower?(@usera).should be_true
607
+ @usera.follower?(@userb).should be_true
608
+ @usera.reciprocated?(@userb).should be_true
609
+ end
610
+ end
611
+ end
612
+
613
+ describe '#block' do
614
+ it 'should remove the pending relationship if you block someone' do
615
+ @userb.follow(@usera)
616
+ @userb.pending?(@usera).should be_true
617
+ @usera.block(@userb)
618
+ @userb.pending?(@usera).should be_false
619
+ @usera.blocked?(@userb).should be_true
620
+ end
621
+ end
622
+
623
+ describe '#pending' do
624
+ it 'should return the correct list' do
625
+ @usera.follow(@userb)
626
+ @userb.follow(@usera)
627
+ @usera.pending.should eql(["#{@userb.send(@userb.class.amico_key)}"])
628
+ @userb.pending.should eql(["#{@usera.send(@usera.class.amico_key)}"])
629
+ end
630
+
631
+ it 'should page correctly' do
632
+ user = add_reciprocal_followers
633
+
634
+ user.pending(:page => 1, :page_size => 5).size.should be(5)
635
+ user.pending(:page => 1, :page_size => 10).size.should be(10)
636
+ user.pending(:page => 1, :page_size => 25).size.should be(25)
637
+ end
638
+ end
639
+
640
+ describe '#pending_count' do
641
+ it 'should return the correct count' do
642
+ userc = Factory :user
643
+ userd = Factory :user
644
+ @usera.follow(@userb)
645
+ @userb.follow(@usera)
646
+ @usera.follow(userc)
647
+ userc.follow(@usera)
648
+ @usera.follow(userd)
649
+ @usera.pending_count.should be(2)
650
+ end
651
+ end
652
+
653
+ describe '#pending_page_count' do
654
+ it 'should return the correct count' do
655
+ user = add_reciprocal_followers
656
+
657
+ user.pending_page_count.should be(2)
658
+ user.pending_page_count( 10).should be(3)
659
+ user.pending_page_count( 5).should be(6)
660
+ user.pending_page_count(2).should be(13)
661
+ end
662
+ end
663
+ end
664
+
665
+ describe 'scope' do
666
+ it 'should allow you to scope a call to follow a different thing' do
667
+ Amico.default_scope_key = 'user'
668
+ @usera.follow(@userb, 'user')
669
+ @usera.following?(@userb).should be_true
670
+ @usera.following?(@userb, 'user').should be_true
671
+ @usera.following.should eql(["#{@userb.send(@userb.class.amico_key)}"])
672
+ @usera.following( {:page_size => Amico.page_size, :page => 1}, 'user').should eql(["#{@userb.send(@userb.class.amico_key)}"])
673
+ @usera.following?(@userb, 'project').should be_false
674
+ @usera.follow(@userb, 'project')
675
+ @usera.following?(@userb, 'project').should be_true
676
+ @usera.following( {:page_size => Amico.page_size, :page => 1}, 'project').should eql(["#{@userb.send(@userb.class.amico_key)}"])
677
+ end
678
+ end
679
+
680
+ private
681
+
682
+ def add_reciprocal_followers(count = 26, block_relationship = false)
683
+ outer_user = nil
684
+ 1.upto(count) do
685
+ outer_user = Factory :user
686
+ 1.upto(count) do
687
+ inner_user = Factory :user
688
+ outer_user.follow! inner_user
689
+ inner_user.follow! outer_user
690
+ if block_relationship
691
+ outer_user.block! inner_user
692
+ inner_user.block! outer_user
693
+ end
694
+ end
695
+ end
696
+ outer_user
697
+ end
698
+ end