amico 1.0.0 → 1.1.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/.gitignore CHANGED
@@ -2,3 +2,5 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ .yardoc
6
+ doc
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use --create ruby-1.9.3-p0@amico_gem
@@ -1,3 +1,8 @@
1
- # 1.0.0
1
+ # 1.1.0
2
+
3
+ * Added blocking to relationships
4
+ * Added reciprocated to relationships
5
+
6
+ # 1.0.0 (2012-01-11)
2
7
 
3
8
  * Initial release
data/README.md CHANGED
@@ -25,6 +25,8 @@ Amico.configure do |configuration|
25
25
  configuration.namespace = 'amico'
26
26
  configuration.following_key = 'following'
27
27
  configuration.followers_key = 'followers'
28
+ configuration.blocked_key = 'blocked'
29
+ configuration.reciprocated_key = 'reciprocated'
28
30
  configuration.page_size = 25
29
31
  end
30
32
  ```
@@ -40,6 +42,8 @@ Amico.configure do |configuration|
40
42
  configuration.namespace = 'amico'
41
43
  configuration.following_key = 'following'
42
44
  configuration.followers_key = 'followers'
45
+ configuration.blocked_key = 'blocked'
46
+ configuration.reciprocated_key = 'reciprocated'
43
47
  configuration.page_size = 25
44
48
  end
45
49
 
@@ -78,9 +82,39 @@ Amico.follower?(1, 11)
78
82
 
79
83
  Amico.following(1)
80
84
  => ["11"]
85
+
86
+ Amico.block(1, 11)
87
+ => [1, 1, 1, 1, 1]
88
+
89
+ Amico.following?(11, 1)
90
+ => false
91
+
92
+ Amico.blocked?(1, 11)
93
+ => true
94
+
95
+ Amico.unblock(1, 11)
96
+ => true
97
+
98
+ Amico.blocked?(1, 11)
99
+ => false
100
+
101
+ Amico.follow(11, 1)
102
+ => nil
103
+
104
+ Amico.follow(1, 11)
105
+ => [1, 1]
106
+
107
+ Amico.reciprocated?(1, 11)
108
+ => true
109
+
110
+ Amico.reciprocated(1)
111
+ => ["11"]
81
112
  ```
82
113
 
83
- You can pass `:page => 1` and `:page_size => 25` options into the `following` and `followers` methods. Set the values as appropriate.
114
+ ## Documentation
115
+
116
+ The source for the [relationships module](https://github.com/agoragames/amico/blob/master/lib/amico/relationships.rb) is well-documented. There are some
117
+ simple examples in the method documentation. You can also refer to the [online documentation](http://rubydoc.info/gems/amico/).
84
118
 
85
119
  ## Contributing to amico
86
120
 
@@ -1,27 +1,82 @@
1
1
  module Amico
2
+ # Configuration settings for Amico.
2
3
  module Configuration
4
+ # Public: Redis instance.
3
5
  attr_accessor :redis
6
+
7
+ # Public: Amico namespace for Redis.
4
8
  attr_accessor :namespace
9
+
10
+ # Public: Key used in Redis for tracking who an individual is following.
5
11
  attr_accessor :following_key
12
+
13
+ # Public: Key used in Redis for tracking the followers of an individual.
6
14
  attr_accessor :followers_key
15
+
16
+ # Public: Key used in Redis for tracking who an individual blocks.
17
+ attr_accessor :blocked_key
18
+
19
+ # Public: Key used in Redis for tracking who has reciprocated a follow for an individual.
20
+ attr_accessor :reciprocated_key
21
+
22
+ # Public: Page size to be used when paging through the various types of relationships.
7
23
  attr_accessor :page_size
8
24
 
25
+ # Public: Yield self to be able to configure Amico with block-style configuration.
26
+ #
27
+ # Example:
28
+ #
29
+ # Amico.configure do |configuration|
30
+ # configuration.redis = Redis.new
31
+ # configuration.namespace = 'amico'
32
+ # configuration.following_key = 'following'
33
+ # configuration.followers_key = 'followers'
34
+ # configuration.blocked_key = 'blocked'
35
+ # configuration.reciprocated_key = 'reciprocated'
36
+ # configuration.page_size = 25
37
+ # end
9
38
  def configure
10
39
  yield self
11
40
  end
12
41
 
42
+ # Public: Amico namespace for Redis.
43
+ #
44
+ # Returns the Amico namespace or the default of 'amico' if not set.
13
45
  def namespace
14
46
  @namespace ||= 'amico'
15
47
  end
16
48
 
49
+ # Public: Key used in Redis for tracking who an individual is following.
50
+ #
51
+ # Returns the key used in Redis for tracking who an individual is following or the default of 'following' if not set.
17
52
  def following_key
18
53
  @following_key ||= 'following'
19
54
  end
20
55
 
56
+ # Public: Key used in Redis for tracking the followers of an individual.
57
+ #
58
+ # Returns the key used in Redis for tracking the followers of an individual or the default of 'followers' if not set.
21
59
  def followers_key
22
60
  @followers_key ||= 'followers'
23
61
  end
24
62
 
63
+ # Public: Key used in Redis for tracking who an individual blocks.
64
+ #
65
+ # Returns the key used in Redis for tracking who an individual blocks or the default of 'blocked' if not set.
66
+ def blocked_key
67
+ @blocked_key ||= 'blocked'
68
+ end
69
+
70
+ # Public: Key used in Redis for tracking who has reciprocated a follow for an individual.
71
+ #
72
+ # Returns the key used in Redis for tracking who has reciprocated a follow for an individual or the default of 'reciprocated' if not set.
73
+ def reciprocated_key
74
+ @reciprocated_key ||= 'reciprocated'
75
+ end
76
+
77
+ # Public: Page size to be used when paging through the various types of relationships.
78
+ #
79
+ # Returns the page size to be used when paging through the various types of relationships or the default of 25 if not set.
25
80
  def page_size
26
81
  @page_size ||= 25
27
82
  end
@@ -1,63 +1,370 @@
1
1
  module Amico
2
2
  module Relationships
3
+ # Public: Establish a follow relationship between two IDs. After adding the follow
4
+ # relationship, it checks to see if the relationship is reciprocated and establishes that
5
+ # relationship if so.
6
+ #
7
+ # from_id - The ID of the individual establishing the follow relationship.
8
+ # to_id - The ID of the individual to be followed.
9
+ #
10
+ # Examples
11
+ #
12
+ # Amico.follow(1, 11)
3
13
  def follow(from_id, to_id)
4
14
  return if from_id == to_id
15
+ return if blocked?(to_id, from_id)
5
16
 
6
17
  Amico.redis.multi do
7
18
  Amico.redis.zadd("#{Amico.namespace}:#{Amico.following_key}:#{from_id}", Time.now.to_i, to_id)
8
19
  Amico.redis.zadd("#{Amico.namespace}:#{Amico.followers_key}:#{to_id}", Time.now.to_i, from_id)
9
20
  end
21
+
22
+ if reciprocated?(from_id, to_id)
23
+ Amico.redis.multi do
24
+ Amico.redis.zadd("#{Amico.namespace}:#{Amico.reciprocated_key}:#{from_id}", Time.now.to_i, to_id)
25
+ Amico.redis.zadd("#{Amico.namespace}:#{Amico.reciprocated_key}:#{to_id}", Time.now.to_i, from_id)
26
+ end
27
+ end
10
28
  end
11
29
 
30
+ # Public: Remove a follow relationship between two IDs. After removing the follow
31
+ # relationship, if a reciprocated relationship was established, it is
32
+ # also removed.
33
+ #
34
+ # from_id - The ID of the individual removing the follow relationship.
35
+ # to_id - The ID of the individual to be unfollowed.
36
+ #
37
+ # Examples
38
+ #
39
+ # Amico.follow(1, 11)
40
+ # Amico.unfollow(1, 11)
12
41
  def unfollow(from_id, to_id)
42
+ return if from_id == to_id
43
+
44
+ Amico.redis.multi do
45
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.following_key}:#{from_id}", to_id)
46
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.followers_key}:#{to_id}", from_id)
47
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{from_id}", to_id)
48
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{to_id}", from_id)
49
+ end
50
+ end
51
+
52
+ # Public: Block a relationship between two IDs. This method also has the side effect
53
+ # of removing any follower or following relationship between the two IDs.
54
+ #
55
+ # from_id - The ID of the individual blocking the relationship.
56
+ # to_id - The ID of the individual being blocked.
57
+ #
58
+ # Examples
59
+ #
60
+ # Amico.block(1, 11)
61
+ def block(from_id, to_id)
62
+ return if from_id == to_id
63
+
13
64
  Amico.redis.multi do
14
65
  Amico.redis.zrem("#{Amico.namespace}:#{Amico.following_key}:#{from_id}", to_id)
66
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.following_key}:#{to_id}", from_id)
15
67
  Amico.redis.zrem("#{Amico.namespace}:#{Amico.followers_key}:#{to_id}", from_id)
68
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.followers_key}:#{from_id}", to_id)
69
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{from_id}", to_id)
70
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{to_id}", from_id)
71
+ Amico.redis.zadd("#{Amico.namespace}:#{Amico.blocked_key}:#{from_id}", Time.now.to_i, to_id)
16
72
  end
17
73
  end
18
74
 
75
+ # Public: Unblock a relationship between two IDs.
76
+ #
77
+ # from_id - The ID of the individual unblocking the relationship.
78
+ # to_id - The ID of the blocked individual.
79
+ #
80
+ # Examples
81
+ #
82
+ # Amico.block(1, 11)
83
+ # Amico.unblock(1, 11)
84
+ def unblock(from_id, to_id)
85
+ return if from_id == to_id
86
+
87
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.blocked_key}:#{from_id}", to_id)
88
+ end
89
+
90
+ # Public: Count the number of individuals that someone is following.
91
+ #
92
+ # id - ID of the individual to retrieve following count for.
93
+ #
94
+ # Examples
95
+ #
96
+ # Amico.follow(1, 11)
97
+ # Amico.following_count(1)
98
+ #
99
+ # Returns the count of the number of individuals that someone is following.
19
100
  def following_count(id)
20
101
  Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{id}")
21
102
  end
22
103
 
104
+ # Public: Count the number of individuals that are following someone.
105
+ #
106
+ # id - ID of the individual to retrieve followers count for.
107
+ #
108
+ # Examples
109
+ #
110
+ # Amico.follow(11, 1)
111
+ # Amico.followers_count(1)
112
+ #
113
+ # Returns the count of the number of individuals that are following someone.
23
114
  def followers_count(id)
24
115
  Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{id}")
25
116
  end
26
117
 
118
+ # Public: Count the number of individuals that someone has blocked.
119
+ #
120
+ # id - ID of the individual to retrieve blocked count for.
121
+ #
122
+ # Examples
123
+ #
124
+ # Amico.block(1, 11)
125
+ # Amico.blocked_count(1)
126
+ #
127
+ # Returns the count of the number of individuals that someone has blocked.
128
+ def blocked_count(id)
129
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{id}")
130
+ end
131
+
132
+ # Public: Count the number of individuals that have reciprocated a following relationship.
133
+ #
134
+ # id - ID of the individual to retrieve reciprocated following count for.
135
+ #
136
+ # Examples
137
+ #
138
+ # Amico.follow(1, 11)
139
+ # Amico.follow(11, 1)
140
+ # Amico.reciprocated_count(1)
141
+ #
142
+ # Returns the count of the number of individuals that have reciprocated a following relationship.
143
+ def reciprocated_count(id)
144
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{id}")
145
+ end
146
+
147
+ # Public: Check to see if one individual is following another individual.
148
+ #
149
+ # id - ID of the individual checking the following status.
150
+ # following_id - ID of the individual to see if they are being followed by id.
151
+ #
152
+ # Examples
153
+ #
154
+ # Amico.follow(1, 11)
155
+ # Amico.following?(1, 11)
156
+ #
157
+ # Returns true if id is following following_id, false otherwise
27
158
  def following?(id, following_id)
28
159
  !Amico.redis.zscore("#{Amico.namespace}:#{Amico.following_key}:#{id}", following_id).nil?
29
160
  end
30
161
 
162
+ # Public: Check to see if one individual is a follower of another individual.
163
+ #
164
+ # id - ID of the individual checking the follower status.
165
+ # following_id - ID of the individual to see if they are following id.
166
+ #
167
+ # Examples
168
+ #
169
+ # Amico.follow(11, 1)
170
+ # Amico.follower?(1, 11)
171
+ # Returns true if follower_id is following id, false otherwise
31
172
  def follower?(id, follower_id)
32
173
  !Amico.redis.zscore("#{Amico.namespace}:#{Amico.followers_key}:#{id}", follower_id).nil?
33
174
  end
34
175
 
176
+ # Public: Check to see if one individual has blocked another individual.
177
+ #
178
+ # id - ID of the individual checking the blocked status.
179
+ # blocked_id - ID of the individual to see if they are blocked by id.
180
+ #
181
+ # Examples
182
+ #
183
+ # Amico.block(1, 11)
184
+ # Amico.blocked?(1, 11)
185
+ #
186
+ # Returns true if id has blocked blocked_id, false otherwise
187
+ def blocked?(id, blocked_id)
188
+ !Amico.redis.zscore("#{Amico.namespace}:#{Amico.blocked_key}:#{id}", blocked_id).nil?
189
+ end
190
+
191
+ # Public: Check to see if one individual has reciprocated in following another individual.
192
+ #
193
+ # from_id - ID of the individual checking the reciprocated relationship.
194
+ # to_id - ID of the individual to see if they are following from_id.
195
+ #
196
+ # Examples
197
+ #
198
+ # Amico.follow(1, 11)
199
+ # Amico.follow(11, 1)
200
+ # Amico.reciprocated?(1, 11)
201
+ #
202
+ # Returns true if both individuals are following each other, false otherwise
203
+ def reciprocated?(from_id, to_id)
204
+ following?(from_id, to_id) && following?(to_id, from_id)
205
+ end
206
+
207
+ # Public: Retrieve a page of followed individuals for a given ID.
208
+ #
209
+ # id - ID of the individual.
210
+ # options - Options to be passed for retrieving a page of followed individuals.
211
+ # default({:page_size => Amico.page_size, :page => 1})
212
+ #
213
+ # Examples
214
+ #
215
+ # Amico.follow(1, 11)
216
+ # Amico.follow(1, 12)
217
+ # Amico.following(1, :page => 1)
218
+ #
219
+ # Returns a page of followed individuals for a given ID.
35
220
  def following(id, options = default_options)
36
221
  members("#{Amico.namespace}:#{Amico.following_key}:#{id}", options)
37
222
  end
38
223
 
224
+ # Public: Retrieve a page of followers for a given ID.
225
+ #
226
+ # id - ID of the individual.
227
+ # options - Options to be passed for retrieving a page of followers.
228
+ # default({:page_size => Amico.page_size, :page => 1})
229
+ #
230
+ # Examples
231
+ #
232
+ # Amico.follow(11, 1)
233
+ # Amico.follow(12, 1)
234
+ # Amico.followers(1, :page => 1)
235
+ #
236
+ # Returns a page of followers for a given ID.
39
237
  def followers(id, options = default_options)
40
238
  members("#{Amico.namespace}:#{Amico.followers_key}:#{id}", options)
41
239
  end
42
240
 
241
+ # Public: Retrieve a page of blocked individuals for a given ID.
242
+ #
243
+ # id - ID of the individual.
244
+ # options - Options to be passed for retrieving a page of blocked individuals.
245
+ # default({:page_size => Amico.page_size, :page => 1})
246
+ #
247
+ # Examples
248
+ #
249
+ # Amico.block(1, 11)
250
+ # Amico.block(1, 12)
251
+ # Amico.blocked(1, :page => 1)
252
+ #
253
+ # Returns a page of blocked individuals for a given ID.
254
+ def blocked(id, options = default_options)
255
+ members("#{Amico.namespace}:#{Amico.blocked_key}:#{id}", options)
256
+ end
257
+
258
+ # Public: Retrieve a page of individuals that have reciprocated a follow for a given ID.
259
+ #
260
+ # id - ID of the individual.
261
+ # options - Options to be passed for retrieving a page of individuals that have reciprocated a follow.
262
+ # default({:page_size => Amico.page_size, :page => 1})
263
+ #
264
+ # Examples
265
+ #
266
+ # Amico.follow(1, 11)
267
+ # Amico.follow(1, 12)
268
+ # Amico.follow(11, 1)
269
+ # Amico.follow(12, 1)
270
+ # Amico.reciprocated(1, :page => 1)
271
+ #
272
+ # Returns a page of individuals that have reciprocated a follow for a given ID.
273
+ def reciprocated(id, options = default_options)
274
+ members("#{Amico.namespace}:#{Amico.reciprocated_key}:#{id}", options)
275
+ end
276
+
277
+ # Public: Count the number of pages of following relationships for an individual.
278
+ #
279
+ # id - ID of the individual.
280
+ # page_size - Page size (default: Amico.page_size).
281
+ #
282
+ # Examples
283
+ #
284
+ # Amico.follow(1, 11)
285
+ # Amico.follow(1, 12)
286
+ # Amico.following_page_count(1)
287
+ #
288
+ # Returns the number of pages of following relationships for an individual.
43
289
  def following_page_count(id, page_size = Amico.page_size)
44
290
  total_pages("#{Amico.namespace}:#{Amico.following_key}:#{id}", page_size)
45
291
  end
46
292
 
293
+ # Public: Count the number of pages of follower relationships for an individual.
294
+ #
295
+ # id - ID of the individual.
296
+ # page_size - Page size (default: Amico.page_size).
297
+ #
298
+ # Examples
299
+ #
300
+ # Amico.follow(11, 1)
301
+ # Amico.follow(12, 1)
302
+ # Amico.followers_page_count(1)
303
+ #
304
+ # Returns the number of pages of follower relationships for an individual.
47
305
  def followers_page_count(id, page_size = Amico.page_size)
48
306
  total_pages("#{Amico.namespace}:#{Amico.followers_key}:#{id}", page_size)
49
307
  end
50
308
 
309
+ # Public: Count the number of pages of blocked relationships for an individual.
310
+ #
311
+ # id - ID of the individual.
312
+ # page_size - Page size (default: Amico.page_size).
313
+ #
314
+ # Examples
315
+ #
316
+ # Amico.block(1, 11)
317
+ # Amico.block(1, 12)
318
+ # Amico.blocked_page_count(1)
319
+ #
320
+ # Returns the number of pages of blocked relationships for an individual.
321
+ def blocked_page_count(id, page_size = Amico.page_size)
322
+ total_pages("#{Amico.namespace}:#{Amico.blocked_key}:#{id}", page_size)
323
+ end
324
+
325
+ # Public: Count the number of pages of reciprocated relationships for an individual.
326
+ #
327
+ # id - ID of the individual.
328
+ # page_size - Page size (default: Amico.page_size).
329
+ #
330
+ # Examples
331
+ #
332
+ # Amico.follow(1, 11)
333
+ # Amico.follow(1, 12)
334
+ # Amico.follow(11, 1)
335
+ # Amico.follow(12, 1)
336
+ # Amico.reciprocated_page_count(1)
337
+ #
338
+ # Returns the number of pages of reciprocated relationships for an individual.
339
+ def reciprocated_page_count(id, page_size = Amico.page_size)
340
+ total_pages("#{Amico.namespace}:#{Amico.reciprocated_key}:#{id}", page_size)
341
+ end
342
+
51
343
  private
52
344
 
345
+ # Internal: Default options for doing, for example, paging.
346
+ #
347
+ # Returns a hash of the default options.
53
348
  def default_options
54
349
  {:page_size => Amico.page_size, :page => 1}
55
350
  end
56
351
 
352
+ # Internal: Count the total number of pages for a given key in a Redis sorted set.
353
+ #
354
+ # key - Redis key.
355
+ # page_size - Page size from which to calculate total pages.
356
+ #
357
+ # Returns total number of pages for a given key in a Redis sorted set.
57
358
  def total_pages(key, page_size)
58
359
  (Amico.redis.zcard(key) / page_size.to_f).ceil
59
360
  end
60
361
 
362
+ # Internal: Retrieve a page of items from a Redis sorted set without scores.
363
+ #
364
+ # key - Redis key.
365
+ # options - Default options for paging (default: {:page_size => Amico.page_size, :page => 1})
366
+ #
367
+ # Returns a page of items from a Redis sorted set without scores.
61
368
  def members(key, options = default_options)
62
369
  options = default_options.dup.merge!(options)
63
370
  if options[:page] < 1
@@ -1,3 +1,3 @@
1
1
  module Amico
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -7,6 +7,8 @@ describe Amico::Configuration do
7
7
  configuration.namespace.should eql('amico')
8
8
  configuration.following_key.should eql('following')
9
9
  configuration.followers_key.should eql('followers')
10
+ configuration.blocked_key.should eql('blocked')
11
+ configuration.reciprocated_key.should eql('reciprocated')
10
12
  configuration.page_size.should be(25)
11
13
  end
12
14
  end
@@ -15,10 +15,18 @@ describe Amico::Relationships do
15
15
  Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:1").should be(0)
16
16
  Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:1").should be(0)
17
17
  end
18
+
19
+ it 'should add each individual to the reciprocated set if you both follow each other' do
20
+ Amico.follow(1, 11)
21
+ Amico.follow(11, 1)
22
+
23
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:1").should be(1)
24
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:11").should be(1)
25
+ end
18
26
  end
19
27
 
20
28
  describe '#unfollow' do
21
- it 'should allow you to follow' do
29
+ it 'should allow you to unfollow' do
22
30
  Amico.follow(1, 11)
23
31
 
24
32
  Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:1").should be(1)
@@ -28,20 +36,53 @@ describe Amico::Relationships do
28
36
 
29
37
  Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:1").should be(0)
30
38
  Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:11").should be(0)
39
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:1").should be(0)
40
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:11").should be(0)
31
41
  end
32
42
  end
33
43
 
34
- describe '#following_count' do
35
- it 'should return the correct count' do
36
- Amico.follow(1, 11)
37
- Amico.following_count(1).should be(1)
44
+ describe '#block' do
45
+ it 'should allow you to block someone following you' do
46
+ Amico.follow(11, 1)
47
+ Amico.block(1, 11)
48
+
49
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:11").should be(0)
50
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:1").should be(1)
51
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:1").should be(0)
52
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:11").should be(0)
53
+ end
54
+
55
+ it 'should allow you to block someone who is not following you' do
56
+ Amico.block(1, 11)
57
+
58
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:11").should be(0)
59
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:1").should be(1)
60
+ end
61
+
62
+ it 'should not allow someone you have blocked to follow you' do
63
+ Amico.block(1, 11)
64
+
65
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:11").should be(0)
66
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:1").should be(1)
67
+
68
+ Amico.follow(11, 1)
69
+
70
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:11").should be(0)
71
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:1").should be(1)
72
+ end
73
+
74
+ it 'should not allow you to block yourself' do
75
+ Amico.block(1, 1)
76
+ Amico.blocked?(1, 1).should be_false
38
77
  end
39
78
  end
40
79
 
41
- describe '#followers_count' do
42
- it 'should return the correct count' do
43
- Amico.follow(1, 11)
44
- Amico.followers_count(11).should be(1)
80
+ describe '#unblock' do
81
+ it 'should allow you to unblock someone you have blocked' do
82
+ Amico.block(1, 11)
83
+ Amico.blocked?(1, 11).should be_true
84
+ Amico.unblock(1, 11)
85
+ Amico.blocked?(1, 11).should be_false
45
86
  end
46
87
  end
47
88
 
@@ -67,6 +108,27 @@ describe Amico::Relationships do
67
108
  end
68
109
  end
69
110
 
111
+ describe '#blocked?' do
112
+ it 'should return that someone is being blocked' do
113
+ Amico.block(1, 11)
114
+ Amico.blocked?(1, 11).should be_true
115
+ Amico.following?(11, 1).should be_false
116
+ end
117
+ end
118
+
119
+ describe '#reciprocated?' do
120
+ it 'should return true if both individuals are following each other' do
121
+ Amico.follow(1, 11)
122
+ Amico.follow(11, 1)
123
+ Amico.reciprocated?(1, 11).should be_true
124
+ end
125
+
126
+ it 'should return false if both individuals are not following each other' do
127
+ Amico.follow(1, 11)
128
+ Amico.reciprocated?(1, 11).should be_false
129
+ end
130
+ end
131
+
70
132
  describe '#following' do
71
133
  it 'should return the correct list' do
72
134
  Amico.follow(1, 11)
@@ -101,6 +163,72 @@ describe Amico::Relationships do
101
163
  end
102
164
  end
103
165
 
166
+ describe '#blocked' do
167
+ it 'should return the correct list' do
168
+ Amico.block(1, 11)
169
+ Amico.block(1, 12)
170
+ Amico.blocked(1).should eql(["12", "11"])
171
+ Amico.blocked(1, :page => 5).should eql(["12", "11"])
172
+ end
173
+
174
+ it 'should page correctly' do
175
+ add_reciprocal_followers(26, true)
176
+
177
+ Amico.blocked(1, :page => 1, :page_size => 5).size.should be(5)
178
+ Amico.blocked(1, :page => 1, :page_size => 10).size.should be(10)
179
+ Amico.blocked(1, :page => 1, :page_size => 26).size.should be(25)
180
+ end
181
+ end
182
+
183
+ describe '#reciprocated' do
184
+ it 'should return the correct list' do
185
+ Amico.follow(1, 11)
186
+ Amico.follow(11, 1)
187
+ Amico.reciprocated(1).should eql(["11"])
188
+ Amico.reciprocated(11).should eql(["1"])
189
+ end
190
+
191
+ it 'should page correctly' do
192
+ add_reciprocal_followers
193
+
194
+ Amico.reciprocated(1, :page => 1, :page_size => 5).size.should be(5)
195
+ Amico.reciprocated(1, :page => 1, :page_size => 10).size.should be(10)
196
+ Amico.reciprocated(1, :page => 1, :page_size => 26).size.should be(25)
197
+ end
198
+ end
199
+
200
+ describe '#following_count' do
201
+ it 'should return the correct count' do
202
+ Amico.follow(1, 11)
203
+ Amico.following_count(1).should be(1)
204
+ end
205
+ end
206
+
207
+ describe '#followers_count' do
208
+ it 'should return the correct count' do
209
+ Amico.follow(1, 11)
210
+ Amico.followers_count(11).should be(1)
211
+ end
212
+ end
213
+
214
+ describe '#blocked_count' do
215
+ it 'should return the correct count' do
216
+ Amico.block(1, 11)
217
+ Amico.blocked_count(1).should be(1)
218
+ end
219
+ end
220
+
221
+ describe '#reciprocated_count' do
222
+ it 'should return the correct count' do
223
+ Amico.follow(1, 11)
224
+ Amico.follow(11, 1)
225
+ Amico.follow(1, 12)
226
+ Amico.follow(12, 1)
227
+ Amico.follow(1, 13)
228
+ Amico.reciprocated_count(1).should be(2)
229
+ end
230
+ end
231
+
104
232
  describe '#following_page_count' do
105
233
  it 'should return the correct count' do
106
234
  add_reciprocal_followers
@@ -121,14 +249,38 @@ describe Amico::Relationships do
121
249
  end
122
250
  end
123
251
 
252
+ describe '#blocked_page_count' do
253
+ it 'should return the correct count' do
254
+ add_reciprocal_followers(26, true)
255
+
256
+ Amico.blocked_page_count(1).should be(1)
257
+ Amico.blocked_page_count(1, 10).should be(3)
258
+ Amico.blocked_page_count(1, 5).should be(5)
259
+ end
260
+ end
261
+
262
+ describe '#reciprocated_page_count' do
263
+ it 'should return the correct count' do
264
+ add_reciprocal_followers
265
+
266
+ Amico.reciprocated_page_count(1).should be(1)
267
+ Amico.reciprocated_page_count(1, 10).should be(3)
268
+ Amico.reciprocated_page_count(1, 5).should be(5)
269
+ end
270
+ end
271
+
124
272
  private
125
273
 
126
- def add_reciprocal_followers(count = 26)
274
+ def add_reciprocal_followers(count = 26, block_relationship = false)
127
275
  1.upto(count) do |outer_index|
128
276
  1.upto(count) do |inner_index|
129
277
  if outer_index != inner_index
130
278
  Amico.follow(outer_index, inner_index + 1000)
131
279
  Amico.follow(inner_index + 1000, outer_index)
280
+ if block_relationship
281
+ Amico.block(outer_index, inner_index + 1000)
282
+ Amico.block(inner_index + 1000, outer_index)
283
+ end
132
284
  end
133
285
  end
134
286
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amico
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-11 00:00:00.000000000 Z
12
+ date: 2012-01-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
16
- requirement: &2160263060 !ruby/object:Gem::Requirement
16
+ requirement: &2164475940 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2160263060
24
+ version_requirements: *2164475940
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &2160261920 !ruby/object:Gem::Requirement
27
+ requirement: &2164475520 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2160261920
35
+ version_requirements: *2164475520
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &2160260960 !ruby/object:Gem::Requirement
38
+ requirement: &2164475100 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2160260960
46
+ version_requirements: *2164475100
47
47
  description: Relationships (e.g. friendships) backed by Redis
48
48
  email:
49
49
  - dczarnecki@agoragames.com
@@ -53,6 +53,7 @@ extra_rdoc_files: []
53
53
  files:
54
54
  - .gitignore
55
55
  - .rspec
56
+ - .rvmrc
56
57
  - CHANGELOG.md
57
58
  - Gemfile
58
59
  - LICENSE.txt
@@ -80,7 +81,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
80
81
  version: '0'
81
82
  segments:
82
83
  - 0
83
- hash: -2423888867059560591
84
+ hash: 2967547926380313375
84
85
  required_rubygems_version: !ruby/object:Gem::Requirement
85
86
  none: false
86
87
  requirements:
@@ -89,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
90
  version: '0'
90
91
  segments:
91
92
  - 0
92
- hash: -2423888867059560591
93
+ hash: 2967547926380313375
93
94
  requirements: []
94
95
  rubyforge_project: amico
95
96
  rubygems_version: 1.8.10