acts_as_network 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ module ActsAsNetwork
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,3 @@
1
+ sqlite3:
2
+ :adapter: sqlite3
3
+ :database: test/acts_as_network.test.db
@@ -0,0 +1,15 @@
1
+ discovery:
2
+ id: 0
3
+ name: Discovery
4
+
5
+ usa:
6
+ id: 1
7
+ name: USA
8
+
9
+ amc:
10
+ id: 2
11
+ name: AMC
12
+
13
+ abc:
14
+ id: 3
15
+ name: ABC
@@ -0,0 +1,27 @@
1
+ carmen_helene:
2
+ id: 0
3
+ person_id: 4
4
+ person_id_target: 0
5
+ is_accepted: t
6
+
7
+ helene_stephen:
8
+ id: 1
9
+ person_id: 0
10
+ person_id_target: 1
11
+
12
+ helene_vincent:
13
+ id: 2
14
+ person_id: 0
15
+ person_id_target: 2
16
+ is_accepted: t
17
+
18
+ mary_stephen:
19
+ id: 3
20
+ person_id: 3
21
+ person_id_target: 1
22
+
23
+ stephen_vincent:
24
+ id: 4
25
+ person_id: 1
26
+ person_id_target: 2
27
+ is_accepted: f
@@ -0,0 +1,29 @@
1
+ helene:
2
+ id: 0
3
+ name: helene
4
+
5
+ stephen:
6
+ id: 1
7
+ name: stephen
8
+
9
+ vincent:
10
+ id: 2
11
+ name: vincent
12
+
13
+ mary:
14
+ id: 3
15
+ name: mary
16
+
17
+ carmen:
18
+ id: 4
19
+ name: carmen
20
+
21
+ billy:
22
+ id: 5
23
+ name: billy
24
+
25
+ brian:
26
+ id: 6
27
+ name: brian
28
+
29
+
@@ -0,0 +1,20 @@
1
+
2
+ carmen_helene:
3
+ person_id: 4
4
+ person_id_target: 0
5
+
6
+ helene_stephen:
7
+ person_id: 0
8
+ person_id_target: 1
9
+
10
+ helene_vincent:
11
+ person_id: 0
12
+ person_id_target: 2
13
+
14
+ mary_stephen:
15
+ person_id: 3
16
+ person_id_target: 1
17
+
18
+ stephen_vincent:
19
+ person_id: 1
20
+ person_id_target: 2
@@ -0,0 +1,47 @@
1
+ myth_busters:
2
+ id: 0
3
+ name: Myth Busters
4
+ channel_id: 0
5
+ package: premium
6
+
7
+ deadliest_catch:
8
+ id: 1
9
+ name: Deadliest Catch
10
+ channel_id: 0
11
+ package: mega
12
+
13
+ dirty_jobs:
14
+ id: 2
15
+ name: Dirty Jobs
16
+ channel_id: 0
17
+ package: mega
18
+
19
+ monk:
20
+ id: 3
21
+ name: Monk
22
+ channel_id: 1
23
+ package: basic
24
+
25
+ psych:
26
+ id: 4
27
+ name: Psych
28
+ channel_id: 1
29
+ package: basic
30
+
31
+ burn_notice:
32
+ id: 5
33
+ name: Burn Notice
34
+ channel_id: 1
35
+ package: premium
36
+
37
+ mad_men:
38
+ id: 6
39
+ name: Mad Men
40
+ channel_id: 2
41
+ package: premium
42
+
43
+ action_news:
44
+ id: 7
45
+ name: Action News
46
+ channel_id: 3
47
+ package: basic
@@ -0,0 +1,323 @@
1
+ require 'test_helper'
2
+
3
+ class Channel < ActiveRecord::Base
4
+ has_many :shows
5
+ has_many :premium_shows, :class_name => 'Show', :conditions => ['package = ?', 'premium']
6
+ has_many :mega_shows, :class_name => 'Show', :conditions => ['package = ?', 'mega']
7
+ acts_as_union :pay_shows, [ :premium_shows, :mega_shows ]
8
+ end
9
+
10
+ class Show < ActiveRecord::Base
11
+ belongs_to :channel
12
+ end
13
+
14
+
15
+ class Person < ActiveRecord::Base
16
+
17
+ # network relationship using has_many :through invites
18
+ acts_as_network :contacts, :through => :invites
19
+
20
+ # network relation through invotes with additional conditions
21
+ acts_as_network :acquaintances, :through => :invites, :conditions => ["invites.is_accepted = ?", true]
22
+
23
+ # simple network relation through a has_and_belongs_to_many table
24
+ acts_as_network :connections
25
+
26
+ # network relations has_and_belongs_to_many with custom table and foreign_key names
27
+ acts_as_network :friends, :join_table => :friends, :foreign_key => 'person_id',
28
+ :association_foreign_key => 'person_id_friend'
29
+
30
+ # network relationship with has_many_through and overrides
31
+ acts_as_network :colleagues, :through => :invites,
32
+ :foreign_key => 'person_id', :association_foreign_key => 'person_id_target',
33
+ :conditions => ["is_accepted = ?", true]
34
+
35
+ # simple usage of acts_as_union to combine friends and colleagues sets
36
+ acts_as_union :associates, [:friends, :colleagues]
37
+
38
+ end
39
+
40
+ class Invite < ActiveRecord::Base
41
+ belongs_to :person
42
+ belongs_to :person_target, :class_name => 'Person', :foreign_key => 'person_id_target'
43
+ validates_presence_of :person, :person_target
44
+ end
45
+
46
+ class Array
47
+ def ids
48
+ collect &:id
49
+ end
50
+ end
51
+
52
+ class UnionCollectionTest < ActiveSupport::TestCase
53
+
54
+ setup :build_union
55
+
56
+ def build_union
57
+ @union = ActsAsNetwork::UnionCollection.new(
58
+ channels(:discovery).shows,
59
+ channels(:usa).shows,
60
+ channels(:amc).shows
61
+ )
62
+ end
63
+
64
+ def test_union_non_collection
65
+ union = ActsAsNetwork::UnionCollection.new(
66
+ Person.find(:all, :conditions => "id <= 1"),
67
+ Person.find(:all, :conditions => "id >= 2 AND id <= 4"),
68
+ Person.find(:all, :conditions => "id >= 5")
69
+ )
70
+ assert_equal 7, @union.size
71
+ end
72
+
73
+ def test_standard_finder
74
+ set = channels(:usa).shows
75
+ assert_equal "Monk", set.find_by_name("Monk").name
76
+ assert_equal("Burn Notice", set.find(
77
+ :first, :conditions => "channel_id = 1",
78
+ :order => "name").name) # dynamic initial finder syntax
79
+ end
80
+
81
+ def test_union_finder_all
82
+ assert_equal 7, @union.size # check raw size of @union array
83
+ assert_equal 7, @union.find(:all).size # verify size returned from finder
84
+ end
85
+
86
+ def test_union_find_first
87
+ assert_equal "Monk", @union.find_by_name("Monk").name # dynamic initial finder syntax
88
+
89
+ assert_equal 3, @union.find_all_by_channel_id(0).size # dynamic all finder
90
+
91
+ assert_equal("Mad Men", @union.find(
92
+ :first, :conditions => "id = 6",
93
+ :order => "name").name) # dynamic initial finder syntax
94
+
95
+ assert_equal("Burn Notice", @union.find(
96
+ :first, :conditions => "channel_id = 1",
97
+ :order => "name").name) # dynamic initial finder syntax
98
+ end
99
+
100
+ def test_union_find_by_ids
101
+ assert_equal 7, @union.find(0,1,2,3,4,5,6).size # find by ids accross muliple collections
102
+ assert @union.find(0,1,2,3,4,5,6).kind_of?(Array)
103
+ assert @union.find(0).kind_of?(Show)
104
+ assert @union.find(0,0).kind_of?(Array)
105
+ assert_equal 1, @union.find(0,0).size
106
+
107
+ begin # verify that find by id for an unknown id fails
108
+ @union.find(2,3,4,900)
109
+ fail "should have failed with ActiveRecord::RecordNotFound error"
110
+ rescue ActiveRecord::RecordNotFound
111
+ end
112
+
113
+ end
114
+
115
+ def test_find_with_scope
116
+ Show.send(:with_scope, :find => {:conditions => "channel_id = 1"}) do
117
+ assert_not_nil @union.find(4)
118
+ assert_not_nil @union.find_by_name("Monk")
119
+ assert_not_nil @union.find(:first, :conditions => ["name = ?", "Psych"])
120
+
121
+ assert_nil @union.find(:first, :conditions => "id = 6", :order => "name")
122
+ begin # verify that find by id for an out of scope id fails
123
+ @union.find(2)
124
+ fail "should have failed with ActiveRecord::RecordNotFound error"
125
+ rescue ActiveRecord::RecordNotFound
126
+ end
127
+ end
128
+ end
129
+
130
+ def test_empty_sets
131
+ assert_equal ActsAsNetwork::UnionCollection.new().size, 0
132
+ assert_equal ActsAsNetwork::UnionCollection.new().to_ary, []
133
+ assert_equal ActsAsNetwork::UnionCollection.new([],[]).size, 0
134
+ assert_equal ActsAsNetwork::UnionCollection.new([],[]).to_ary, []
135
+ assert_equal ActsAsNetwork::UnionCollection.new(nil,nil).size, 0
136
+ assert_equal ActsAsNetwork::UnionCollection.new(nil,nil).to_ary, []
137
+ assert_equal ActsAsNetwork::UnionCollection.new([],nil).size, 0
138
+ assert_equal ActsAsNetwork::UnionCollection.new([],nil).to_ary, []
139
+ end
140
+
141
+ def test_mixed_sets
142
+ union = ActsAsNetwork::UnionCollection.new(
143
+ channels(:discovery).shows, # one populated set
144
+ channels(:discovery).shows.find_all_by_name("does not exist"),
145
+ nil
146
+ )
147
+
148
+ assert_equal "Dirty Jobs", union.find_by_name('Dirty Jobs').name
149
+ assert_equal channels(:discovery).shows.size, union.size
150
+ end
151
+
152
+ def test_unique
153
+ # adding the same set twice should not affect the size of the union
154
+ # collection or the results that are returned (no duplicates)
155
+ union = ActsAsNetwork::UnionCollection.new(
156
+ channels(:discovery).shows,
157
+ channels(:discovery).shows
158
+ )
159
+
160
+ assert_equal "Dirty Jobs", union.find_by_name('Dirty Jobs').name
161
+ assert_equal channels(:discovery).shows.size, union.size
162
+ assert_equal channels(:discovery).shows.size, union.find(:all).size
163
+ end
164
+
165
+ def test_lazy_load
166
+ # internal array should start out nil
167
+ assert_nil @union.instance_variable_get(:@arr)
168
+
169
+ # finder operations shouldn't affect state
170
+ @union.find(0)
171
+ assert_nil @union.instance_variable_get(:@arr)
172
+
173
+ # array operations should cause data load
174
+ @union.collect{|a| a}
175
+ assert !@union.instance_variable_get(:@arr).empty?
176
+ end
177
+ end
178
+
179
+ class ActsAsUnionTest < ActiveSupport::TestCase
180
+ def test_union_method
181
+ assert_equal 0, channels(:abc).pay_shows.length
182
+ assert_equal 3, channels(:discovery).pay_shows.length
183
+ end
184
+ end
185
+
186
+ class ActsAsNetworkTest < ActiveSupport::TestCase
187
+ def test_habtm_assignments
188
+ jane = Person.create(:name => 'Jane')
189
+ jack = Person.create(:name => 'Jack')
190
+
191
+ [jane, jack].each do |person|
192
+ assert person.respond_to?(:friends)
193
+ assert person.respond_to?(:friends_out)
194
+ assert person.respond_to?(:friends_in)
195
+ end
196
+
197
+ jane.friends_in << jack # Jane adds Jack as a friend
198
+
199
+ assert jane.friends_in.include?(jack)
200
+ assert jane.friends.include?(jack) # Jack is Janes friend
201
+
202
+ assert jack.friends_out.include?(jane)
203
+ assert jack.friends.include?(jane) # Jane is also Jack's friend!
204
+ end
205
+
206
+ def test_hmt_assignments
207
+ jane = Person.create(:name => 'Jane')
208
+ jack = Person.create(:name => 'Jack')
209
+
210
+ [jane, jack].each do |person|
211
+ assert person.respond_to?(:colleagues)
212
+ assert person.respond_to?(:invites_out)
213
+ assert person.respond_to?(:invites_in)
214
+ assert person.respond_to?(:colleagues_out)
215
+ assert person.respond_to?(:colleagues_in)
216
+ end
217
+
218
+ # Jane invites Jack to be friends
219
+ invite = Invite.create(:person => jane, :person_target => jack, :message => "let's be friends!")
220
+
221
+ assert jane.invites_out.include?(invite)
222
+ assert jack.invites_in.include?(invite)
223
+
224
+ assert !jane.colleagues.include?(jack) # Jack is not yet Jane's friend
225
+ assert !jack.colleagues.include?(jane) # Jane is not yet Jack's friend either
226
+
227
+ invite.is_accepted = true # Now Jack accepts the invite
228
+ invite.save
229
+
230
+ jane.reload and jack.reload
231
+
232
+ assert jane.colleagues.include?(jack) # Jack is Janes friend now
233
+ assert jack.colleagues.include?(jane) # Jane is also Jacks friend
234
+ end
235
+
236
+ def test_assigments_conditions
237
+ jane = Person.create(:name => 'Jane')
238
+ jack = Person.create(:name => 'Jack')
239
+ alex = Person.create(:name => 'Alex')
240
+
241
+ # Jane invited Jack to be friends
242
+ invite = Invite.create(:person => jane, :person_target => jack, :message => "let's be friends!", :is_accepted => true)
243
+
244
+ # Jack invited Alex to be friends
245
+ invite = Invite.create(:person => jack, :person_target => alex, :message => "let's be friends!", :is_accepted => true)
246
+
247
+ jane.reload and jack.reload and alex.reload
248
+
249
+ assert_equal [alex].to_ary, jack.colleagues.find(:all, :conditions => { :name => "Alex" }).to_ary
250
+ end
251
+
252
+ def test_outbound_habtm
253
+ assert_equal 2, people(:helene).connections_out.size
254
+ assert_equal 1, people(:mary).connections_out.size
255
+ assert_equal 1, people(:stephen).connections_out.size
256
+ assert_equal 0, people(:vincent).connections_out.size
257
+ assert_equal 1, people(:carmen).connections_out.size
258
+ end
259
+
260
+ def test_outbound_hmt
261
+ assert_equal 2, people(:helene).contacts_out.size
262
+ assert_equal 1, people(:mary).contacts_out.size
263
+ assert_equal 1, people(:stephen).contacts_out.size
264
+ assert_equal 0, people(:vincent).contacts_out.size
265
+ assert_equal 1, people(:carmen).contacts_out.size
266
+ end
267
+
268
+ def test_conditional_outbound_hmt
269
+ assert_equal 1, people(:helene).acquaintances_out.size
270
+ assert_equal 0, people(:mary).acquaintances_out.size
271
+ assert_equal 0, people(:stephen).acquaintances_out.size
272
+ assert_equal 0, people(:vincent).acquaintances_out.size
273
+ assert_equal 1, people(:carmen).acquaintances_out.size
274
+ end
275
+
276
+ def test_inbound_habtm
277
+ assert_equal 1, people(:helene).connections_in.size
278
+ assert_equal 0, people(:mary).connections_in.size
279
+ assert_equal 2, people(:stephen).connections_in.size
280
+ assert_equal 2, people(:vincent).connections_in.size
281
+ assert_equal 0, people(:carmen).connections_in.size
282
+ end
283
+
284
+ def test_inbound_hmt
285
+ assert_equal 1, people(:helene).contacts_in.size
286
+ assert_equal 0, people(:mary).contacts_in.size
287
+ assert_equal 2, people(:stephen).contacts_in.size
288
+ assert_equal 2, people(:vincent).contacts_in.size
289
+ assert_equal 0, people(:carmen).contacts_in.size
290
+ end
291
+
292
+ def test_conditional_inbound_hmt
293
+ assert_equal 1, people(:helene).acquaintances_in.size
294
+ assert_equal 0, people(:mary).acquaintances_in.size
295
+ assert_equal 0, people(:stephen).acquaintances_in.size
296
+ assert_equal 1, people(:vincent).acquaintances_in.size
297
+ assert_equal 0, people(:carmen).acquaintances_in.size
298
+ end
299
+
300
+ def test_union_habtm
301
+ assert_equal 3, people(:helene).connections.size
302
+ assert_equal 1, people(:mary).connections.size
303
+ assert_equal 3, people(:stephen).connections.size
304
+ assert_equal 2, people(:vincent).connections.size
305
+ assert_equal 1, people(:carmen).connections.size
306
+ end
307
+
308
+ def test_union_hmt
309
+ assert_equal 3, people(:helene).contacts.size
310
+ assert_equal 1, people(:mary).contacts.size
311
+ assert_equal 3, people(:stephen).contacts.size
312
+ assert_equal 2, people(:vincent).contacts.size
313
+ assert_equal 1, people(:carmen).contacts.size
314
+ end
315
+
316
+ def test_conditional_union_hmt
317
+ assert_equal 2, people(:helene).acquaintances.size
318
+ assert_equal 0, people(:mary).acquaintances.size
319
+ assert_equal 0, people(:stephen).acquaintances.size
320
+ assert_equal 1, people(:vincent).acquaintances.size
321
+ assert_equal 1, people(:carmen).acquaintances.size
322
+ end
323
+ end