acts_as_amico 0.1.1 → 0.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.
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