socialization-cassandra 0.0.1.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +144 -0
- data/Rakefile +10 -0
- data/init.rb +1 -0
- data/lib/generators/socialization/socialization_generator.rb +17 -0
- data/lib/generators/socialization/templates/cassandra/model_comment.rb +2 -0
- data/lib/generators/socialization/templates/cassandra/model_follow.rb +2 -0
- data/lib/generators/socialization/templates/cassandra/model_like.rb +2 -0
- data/lib/generators/socialization/templates/cassandra/model_share.rb +2 -0
- data/lib/generators/socialization/templates/socialization_cassandra_migrations.rake +141 -0
- data/lib/socialization/actors/commenter.rb +79 -0
- data/lib/socialization/actors/follower.rb +79 -0
- data/lib/socialization/actors/liker.rb +79 -0
- data/lib/socialization/actors/mentioner.rb +79 -0
- data/lib/socialization/actors/sharer.rb +79 -0
- data/lib/socialization/config/config.rb +51 -0
- data/lib/socialization/helpers/acts_as_helpers.rb +49 -0
- data/lib/socialization/helpers/string.rb +17 -0
- data/lib/socialization/lib/exceptions.rb +3 -0
- data/lib/socialization/stores/cassandra/base.rb +149 -0
- data/lib/socialization/stores/cassandra/comment.rb +28 -0
- data/lib/socialization/stores/cassandra/config.rb +29 -0
- data/lib/socialization/stores/cassandra/follow.rb +36 -0
- data/lib/socialization/stores/cassandra/like.rb +35 -0
- data/lib/socialization/stores/cassandra/mixins/base.rb +8 -0
- data/lib/socialization/stores/cassandra/share.rb +28 -0
- data/lib/socialization/stores/mixins/base.rb +22 -0
- data/lib/socialization/stores/mixins/follow.rb +39 -0
- data/lib/socialization/stores/mixins/like.rb +40 -0
- data/lib/socialization/stores/mixins/mention.rb +40 -0
- data/lib/socialization/version.rb +3 -0
- data/lib/socialization/victims/commentable.rb +51 -0
- data/lib/socialization/victims/followable.rb +50 -0
- data/lib/socialization/victims/likeable.rb +51 -0
- data/lib/socialization/victims/shareable.rb +51 -0
- data/lib/socialization.rb +17 -0
- data/socialization-cassandra.gemspec +30 -0
- data/test/actors/follower_test.rb +129 -0
- data/test/actors/liker_test.rb +121 -0
- data/test/stores/cassandra/base_test.rb +186 -0
- data/test/stores/cassandra/config_test.rb +36 -0
- data/test/stores/cassandra/follow_store_test.rb +28 -0
- data/test/stores/cassandra/like_store_test.rb +26 -0
- data/test/string_test.rb +13 -0
- data/test/test_helper.rb +259 -0
- data/test/victims/followable_test.rb +65 -0
- data/test/victims/likeable_test.rb +67 -0
- data/test/world_test.rb +107 -0
- metadata +209 -0
@@ -0,0 +1,186 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__))+'/../../test_helper'
|
2
|
+
|
3
|
+
class CassandraBaseStoreTest < TestCase
|
4
|
+
include Assertions
|
5
|
+
# Testing through CassandraStores::Follow for easy testing
|
6
|
+
context "CassandraStores::Base through CassandraStores::Follow" do
|
7
|
+
setup do
|
8
|
+
use_cassandra_store
|
9
|
+
@klass = Socialization::CassandraStores::Follow
|
10
|
+
@klass.touch nil
|
11
|
+
@klass.after_follow nil
|
12
|
+
@klass.after_unfollow nil
|
13
|
+
@follower1 = ImAFollower.create
|
14
|
+
@follower2 = ImAFollower.create
|
15
|
+
@followable1 = ImAFollowable.create
|
16
|
+
@followable2 = ImAFollowable.create
|
17
|
+
end
|
18
|
+
|
19
|
+
context "Stores" do
|
20
|
+
should "inherit Socialization::CassandraStores::Follow" do
|
21
|
+
assert_equal Socialization::CassandraStores::Follow, Socialization.follow_model
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "#follow!" do
|
26
|
+
should "create follow records" do
|
27
|
+
@klass.follow!(@follower1, @followable1)
|
28
|
+
row = Socialization.cassandra_session.execute("SELECT actor_type, actor_id FROM #{@klass.forward_table_name} where victim_type='#{@followable1.class}' AND victim_id=#{@followable1.id} ALLOW FILTERING").rows.to_a.first
|
29
|
+
assert_array_similarity ["#{@follower1.class}:#{@follower1.id}"], ["#{row['actor_type']}:#{row['actor_id']}"]
|
30
|
+
row = Socialization.cassandra_session.execute("SELECT victim_type, victim_id FROM #{@klass.backward_table_name} where actor_type='#{@follower1.class}' AND actor_id=#{@follower1.id} ALLOW FILTERING").rows.to_a.last
|
31
|
+
assert_array_similarity ["#{@followable1.class}:#{@followable1.id}"], ["#{row['victim_type']}:#{row['victim_id']}"]
|
32
|
+
|
33
|
+
@klass.follow!(@follower2, @followable1)
|
34
|
+
rows = Socialization.cassandra_session.execute("SELECT actor_type, actor_id FROM #{@klass.forward_table_name} where victim_type='#{@followable1.class}' AND victim_id=#{@followable1.id} ALLOW FILTERING").rows
|
35
|
+
assert_array_similarity ["#{@follower1.class}:#{@follower1.id}", "#{@follower2.class}:#{@follower2.id}"], (rows.collect {|i| "#{i['actor_type']}:#{i['actor_id']}"})
|
36
|
+
|
37
|
+
row = Socialization.cassandra_session.execute("SELECT victim_type, victim_id FROM #{@klass.backward_table_name} where actor_type='#{@follower1.class}' AND actor_id=#{@follower1.id} ALLOW FILTERING").rows.to_a.last
|
38
|
+
assert_array_similarity ["#{@followable1.class}:#{@followable1.id}"], ["#{row['victim_type']}:#{row['victim_id']}"]
|
39
|
+
row = Socialization.cassandra_session.execute("SELECT victim_type, victim_id FROM #{@klass.backward_table_name} where actor_type='#{@follower2.class}' AND actor_id=#{@follower2.id} ALLOW FILTERING").rows.to_a.first
|
40
|
+
assert_array_similarity ["#{@followable1.class}:#{@followable1.id}"], ["#{row['victim_type']}:#{row['victim_id']}"]
|
41
|
+
end
|
42
|
+
|
43
|
+
should "touch follower when instructed" do
|
44
|
+
@klass.touch :follower
|
45
|
+
assert_send([@follower1, :touch])
|
46
|
+
assert_send([@followable1, :touch])
|
47
|
+
@klass.follow!(@follower1, @followable1)
|
48
|
+
end
|
49
|
+
|
50
|
+
should "touch followable when instructed" do
|
51
|
+
@klass.touch :followable
|
52
|
+
!assert_send([@follower1, :touch])
|
53
|
+
assert_send([@followable1, :touch])
|
54
|
+
@klass.follow!(@follower1, @followable1)
|
55
|
+
end
|
56
|
+
|
57
|
+
should "touch all when instructed" do
|
58
|
+
@klass.touch :all
|
59
|
+
assert_send([@follower1, :touch])
|
60
|
+
assert_send([@followable1, :touch])
|
61
|
+
@klass.follow!(@follower1, @followable1)
|
62
|
+
end
|
63
|
+
|
64
|
+
# should "call after follow hook" do
|
65
|
+
# @klass.after_follow :after_follow
|
66
|
+
# assert_send([@klass, :after_follow])
|
67
|
+
# @klass.follow!(@follower1, @followable1)
|
68
|
+
# end
|
69
|
+
|
70
|
+
# should "call after unfollow hook" do
|
71
|
+
# @klass.after_follow :after_unfollow
|
72
|
+
# assert_send([@klass, :after_unfollow])
|
73
|
+
# @klass.follow!(@follower1, @followable1)
|
74
|
+
# end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "#unfollow!" do
|
78
|
+
setup do
|
79
|
+
@klass.follow!(@follower1, @followable1)
|
80
|
+
end
|
81
|
+
|
82
|
+
should "remove follow records" do
|
83
|
+
@klass.unfollow!(@follower1, @followable1)
|
84
|
+
assert_empty Socialization.cassandra_session.execute("SELECT * FROM #{@klass.backward_table_name} where actor_type='#{@follower1.class}' AND actor_id=#{@follower1.id} ALLOW FILTERING").rows.to_a
|
85
|
+
assert_empty Socialization.cassandra_session.execute("SELECT * FROM #{@klass.forward_table_name} where victim_type='#{@followable1.class}' AND victim_id=#{@followable1.id} ALLOW FILTERING").rows.to_a
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "#follows?" do
|
90
|
+
should "return true when follow exists" do
|
91
|
+
@klass.follow!(@follower1, @followable1)
|
92
|
+
assert_true @klass.follows?(@follower1, @followable1)
|
93
|
+
end
|
94
|
+
|
95
|
+
should "return false when follow doesn't exist" do
|
96
|
+
assert_false @klass.follows?(@follower1, @followable1)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "#followers" do
|
101
|
+
should "return an array of followers" do
|
102
|
+
follower1 = ImAFollower.create
|
103
|
+
follower2 = ImAFollower.create
|
104
|
+
follower1.follow!(@followable1)
|
105
|
+
follower2.follow!(@followable1)
|
106
|
+
assert_array_similarity [follower1, follower2], @klass.followers(@followable1, follower1.class)
|
107
|
+
end
|
108
|
+
|
109
|
+
should "return an array of follower ids when plucking" do
|
110
|
+
follower1 = ImAFollower.create
|
111
|
+
follower2 = ImAFollower.create
|
112
|
+
follower1.follow!(@followable1)
|
113
|
+
follower2.follow!(@followable1)
|
114
|
+
assert_array_similarity [follower1.id, follower2.id], @klass.followers(@followable1, follower1.class, :pluck => :id)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "#followables" do
|
119
|
+
should "return an array of followables" do
|
120
|
+
followable1 = ImAFollowable.create
|
121
|
+
followable2 = ImAFollowable.create
|
122
|
+
@follower1.follow!(followable1)
|
123
|
+
@follower1.follow!(followable2)
|
124
|
+
|
125
|
+
assert_array_similarity [followable1, followable2], @klass.followables(@follower1, followable1.class)
|
126
|
+
end
|
127
|
+
|
128
|
+
should "return an array of followables ids when plucking" do
|
129
|
+
followable1 = ImAFollowable.create
|
130
|
+
followable2 = ImAFollowable.create
|
131
|
+
@follower1.follow!(followable1)
|
132
|
+
@follower1.follow!(followable2)
|
133
|
+
assert_array_similarity [followable1.id, followable2.id], @klass.followables(@follower1, followable1.class, :pluck => :id)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "#remove_followers" do
|
138
|
+
should "delete all followers relationships for a followable" do
|
139
|
+
@follower1.follow!(@followable1)
|
140
|
+
@follower2.follow!(@followable1)
|
141
|
+
assert_equal 2, @followable1.followers(@follower1.class).count
|
142
|
+
|
143
|
+
@klass.remove_followers(@followable1)
|
144
|
+
assert_equal 0, @followable1.followers(@follower1.class).count
|
145
|
+
assert_empty Socialization.cassandra_session.execute("SELECT * FROM #{@klass.forward_table_name} where victim_type='#{@followable1.class}' AND victim_id=#{@followable1.id} ALLOW FILTERING").rows.to_a
|
146
|
+
assert_empty Socialization.cassandra_session.execute("SELECT * FROM #{@klass.backward_table_name} where actor_type='#{@follower1.class}' AND actor_id=#{@follower1.id} ALLOW FILTERING").rows.to_a
|
147
|
+
assert_empty Socialization.cassandra_session.execute("SELECT * FROM #{@klass.backward_table_name} where actor_type='#{@follower2.class}' AND actor_id=#{@follower2.id} ALLOW FILTERING").rows.to_a
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "#remove_followables" do
|
152
|
+
should "delete all followables relationships for a follower" do
|
153
|
+
@follower1.follow!(@followable1)
|
154
|
+
@follower1.follow!(@followable2)
|
155
|
+
assert_equal 2, @follower1.followables(@followable1.class).count
|
156
|
+
|
157
|
+
@klass.remove_followables(@follower1)
|
158
|
+
assert_equal 0, @follower1.followables(@followable1.class).count
|
159
|
+
assert_empty Socialization.cassandra_session.execute("SELECT * FROM #{@klass.forward_table_name} where victim_type='#{@followable1.class}' AND victim_id=#{@followable1.id} ALLOW FILTERING").rows.to_a
|
160
|
+
assert_empty Socialization.cassandra_session.execute("SELECT * FROM #{@klass.backward_table_name} where actor_type='#{@follower1.class}' AND actor_id=#{@follower1.id} ALLOW FILTERING").rows.to_a
|
161
|
+
assert_empty Socialization.cassandra_session.execute("SELECT * FROM #{@klass.backward_table_name} where actor_type='#{@follower2.class}' AND actor_id=#{@follower2.id} ALLOW FILTERING").rows.to_a
|
162
|
+
# assert_empty Socialization.redis.smembers backward_key(@followable1)
|
163
|
+
# assert_empty Socialization.redis.smembers backward_key(@follower2)
|
164
|
+
# assert_empty Socialization.redis.smembers forward_key(@follower1)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
# Helpers
|
171
|
+
def assert_match_follower(follow_record, follower)
|
172
|
+
assert follow_record.follower_type == follower.class.to_s && follow_record.follower_id == follower.id
|
173
|
+
end
|
174
|
+
|
175
|
+
def assert_match_followable(follow_record, followable)
|
176
|
+
assert follow_record.followable_type == followable.class.to_s && follow_record.followable_id == followable.id
|
177
|
+
end
|
178
|
+
|
179
|
+
def forward_key(followable)
|
180
|
+
Socialization::CassandraStores::Follow.send(:forward_table_name)
|
181
|
+
end
|
182
|
+
|
183
|
+
def backward_key(follower)
|
184
|
+
Socialization::CassandraStores::Follow.send(:backward_table_name)
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__))+'/../../test_helper'
|
2
|
+
|
3
|
+
class CassandraStoreConfigTest < Minitest::Test
|
4
|
+
context "cassandra" do
|
5
|
+
setup do
|
6
|
+
Socialization.instance_eval {
|
7
|
+
@cassandra = nil
|
8
|
+
@cas_keyspace = nil
|
9
|
+
@cassandra_session = nil
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
should "return a new cassandra object when none were specified" do
|
14
|
+
assert_instance_of Cassandra::Session, Socialization.cassandra_session
|
15
|
+
end
|
16
|
+
|
17
|
+
#should "always return the same Cassandra object when none were specified" do
|
18
|
+
# cassandra_session = Socialization.cassandra_session
|
19
|
+
# assert_same cassandra_session, Socialization.cassandra_session
|
20
|
+
#end
|
21
|
+
|
22
|
+
# should "be able to set and get a cassandra instance" do
|
23
|
+
# cluster = Cassandra.cluster
|
24
|
+
# Socialization.cassandra = cluster
|
25
|
+
# Socialization.keyspace = 'system'
|
26
|
+
# session = cluster.connect('system')
|
27
|
+
# assert_same session, Socialization.cassandra_session
|
28
|
+
# end
|
29
|
+
|
30
|
+
#should "always return the same Redis object when it was specified" do
|
31
|
+
# redis = Redis.new
|
32
|
+
# Socialization.redis = redis
|
33
|
+
# assert_same redis, Socialization.redis
|
34
|
+
#end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__))+'/../../test_helper'
|
2
|
+
# require './../../test_helper'
|
3
|
+
|
4
|
+
class CassandraFollowStoreTest < Minitest::Test
|
5
|
+
include Assertions
|
6
|
+
context "CassandraStores::Follow" do
|
7
|
+
setup do
|
8
|
+
@klass = Socialization::CassandraStores::Follow
|
9
|
+
@base = Socialization::CassandraStores::Base
|
10
|
+
end
|
11
|
+
|
12
|
+
context "method aliases" do
|
13
|
+
should "be set properly and made public" do
|
14
|
+
# TODO: Can't figure out how to test method aliases properly. The following doesn't work:
|
15
|
+
# assert @klass.method(:follow!) == @base.method(:relation!)
|
16
|
+
assert_method_public @klass, :follow!
|
17
|
+
assert_method_public @klass, :unfollow!
|
18
|
+
assert_method_public @klass, :follows?
|
19
|
+
assert_method_public @klass, :followers_relation
|
20
|
+
assert_method_public @klass, :followers
|
21
|
+
assert_method_public @klass, :followables_relation
|
22
|
+
assert_method_public @klass, :followables
|
23
|
+
assert_method_public @klass, :remove_followers
|
24
|
+
assert_method_public @klass, :remove_followables
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__))+'/../../test_helper'
|
2
|
+
|
3
|
+
|
4
|
+
class CassandraLikeStoreTest < Minitest::Test
|
5
|
+
include Assertions
|
6
|
+
context "CassandraStores::Like" do
|
7
|
+
setup do
|
8
|
+
@klass = Socialization::CassandraStores::Like
|
9
|
+
@base = Socialization::CassandraStores::Base
|
10
|
+
end
|
11
|
+
|
12
|
+
context "method aliases" do
|
13
|
+
should "be set properly and made public" do
|
14
|
+
assert_method_public @klass, :like!
|
15
|
+
assert_method_public @klass, :unlike!
|
16
|
+
assert_method_public @klass, :likes?
|
17
|
+
assert_method_public @klass, :likers_relation
|
18
|
+
assert_method_public @klass, :likers
|
19
|
+
assert_method_public @klass, :likeables_relation
|
20
|
+
assert_method_public @klass, :likeables
|
21
|
+
assert_method_public @klass, :remove_likers
|
22
|
+
assert_method_public @klass, :remove_likeables
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/test/string_test.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__))+'/test_helper'
|
2
|
+
|
3
|
+
class StringTest < Minitest::Test
|
4
|
+
context "#deep_const_get" do
|
5
|
+
should "return a class" do
|
6
|
+
assert_equal Socialization, "Socialization".deep_const_get
|
7
|
+
assert_equal Socialization::CassandraStores, "Socialization::CassandraStores".deep_const_get
|
8
|
+
assert_equal Socialization::CassandraStores::Follow, "Socialization::CassandraStores::Follow".deep_const_get
|
9
|
+
|
10
|
+
assert_raises(NameError) { "Foo::Bar".deep_const_get }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
$MOCK_REDIS = true
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'active_record'
|
5
|
+
require 'shoulda'
|
6
|
+
# require 'test/unit'
|
7
|
+
require 'logger'
|
8
|
+
require 'mocha' # mocha always needs to be loaded last! http://stackoverflow.com/questions/3118866/mocha-mock-carries-to-another-test/4375296#4375296
|
9
|
+
# require 'pry'
|
10
|
+
require 'minitest/autorun'
|
11
|
+
require 'cassandra'
|
12
|
+
|
13
|
+
$:.push File.expand_path("../lib", __FILE__)
|
14
|
+
require "socialization"
|
15
|
+
|
16
|
+
module Assertions
|
17
|
+
def assert_true(object, message="")
|
18
|
+
assert_equal(true, object, message)
|
19
|
+
end
|
20
|
+
|
21
|
+
def assert_false(object, message="")
|
22
|
+
assert_equal(false, object, message)
|
23
|
+
end
|
24
|
+
|
25
|
+
def build_message(head, template=nil, *arguments) #:nodoc:
|
26
|
+
template &&= template.chomp
|
27
|
+
template.gsub(/\G((?:[^\\]|\\.)*?)(\\)?\?/) { $1 + ($2 ? "?" : mu_pp(arguments.shift)) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def assert_array_similarity(expected, actual, message=nil)
|
31
|
+
full_message = build_message(message, "<?> expected but was\n<?>.\n", expected, actual)
|
32
|
+
assert((expected.size == actual.size) && (expected - actual == []), full_message)
|
33
|
+
# assert_block(full_message) { (expected.size == actual.size) && (expected - actual == []) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def assert_empty(obj, msg = nil)
|
37
|
+
msg = "Expected #{obj.inspect} to be empty" unless msg
|
38
|
+
assert_respond_to obj, :empty?
|
39
|
+
assert obj.empty?, msg
|
40
|
+
end
|
41
|
+
|
42
|
+
def assert_method_public(obj, method, msg = nil)
|
43
|
+
msg = "Expected method #{obj}.#{method} to be public."
|
44
|
+
method = if RUBY_VERSION.match(/^1\.8/)
|
45
|
+
method.to_s
|
46
|
+
else
|
47
|
+
method.to_s.to_sym
|
48
|
+
end
|
49
|
+
|
50
|
+
assert obj.public_methods.include?(method), msg
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class TestCase < Minitest::Test
|
55
|
+
def setup
|
56
|
+
use_cassandra_store
|
57
|
+
end
|
58
|
+
|
59
|
+
def teardown
|
60
|
+
session = Socialization.cassandra_session
|
61
|
+
# ['likes', 'likers', 'liker_counter', 'followings', 'followers', 'following_counter', 'follower_counter', 'comments', 'comment_counter', 'shares', 'share_counter'].each {|t| session.execute("TRUNCATE #{t}")}
|
62
|
+
['likes', 'likers', 'liker_counter', 'followings', 'followers', 'following_counter', 'follower_counter'].each {|t| session.execute("TRUNCATE #{t}")}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def use_cassandra_store
|
67
|
+
Socialization.follow_model = Socialization::CassandraStores::Follow
|
68
|
+
Socialization.comment_model = Socialization::CassandraStores::Comment
|
69
|
+
Socialization.share_model = Socialization::CassandraStores::Share
|
70
|
+
Socialization.like_model = Socialization::CassandraStores::Like
|
71
|
+
setup_model_shortcuts
|
72
|
+
end
|
73
|
+
|
74
|
+
def setup_model_shortcuts
|
75
|
+
$Follow = Socialization.follow_model
|
76
|
+
$Comment = Socialization.comment_model
|
77
|
+
$Share = Socialization.share_model
|
78
|
+
$Like = Socialization.like_model
|
79
|
+
end
|
80
|
+
|
81
|
+
ActiveRecord::Base.configurations = {'sqlite3' => {:adapter => 'sqlite3', :database => ':memory:'}}
|
82
|
+
ActiveRecord::Base.establish_connection(:sqlite3)
|
83
|
+
|
84
|
+
ActiveRecord::Base.logger = Logger.new(STDERR)
|
85
|
+
ActiveRecord::Base.logger.level = Logger::WARN
|
86
|
+
|
87
|
+
ActiveRecord::Migration.verbose = false
|
88
|
+
ActiveRecord::Schema.define(:version => 0) do
|
89
|
+
create_table :users do |t|
|
90
|
+
t.string :name
|
91
|
+
end
|
92
|
+
|
93
|
+
create_table :celebrities do |t|
|
94
|
+
t.string :name
|
95
|
+
end
|
96
|
+
|
97
|
+
create_table :movies do |t|
|
98
|
+
t.string :name
|
99
|
+
end
|
100
|
+
|
101
|
+
create_table :follows do |t|
|
102
|
+
t.string :follower_type
|
103
|
+
t.integer :follower_id
|
104
|
+
t.string :followable_type
|
105
|
+
t.integer :followable_id
|
106
|
+
t.datetime :created_at
|
107
|
+
end
|
108
|
+
|
109
|
+
create_table :likes do |t|
|
110
|
+
t.string :liker_type
|
111
|
+
t.integer :liker_id
|
112
|
+
t.string :likeable_type
|
113
|
+
t.integer :likeable_id
|
114
|
+
t.datetime :created_at
|
115
|
+
end
|
116
|
+
|
117
|
+
create_table :comments do |t|
|
118
|
+
t.string :commenter_type
|
119
|
+
t.integer :commenter_id
|
120
|
+
t.string :commentable_type
|
121
|
+
t.integer :commentable_id
|
122
|
+
t.datetime :created_at
|
123
|
+
end
|
124
|
+
|
125
|
+
create_table :shares do |t|
|
126
|
+
t.string :sharer_type
|
127
|
+
t.integer :sharer_id
|
128
|
+
t.string :shareable_type
|
129
|
+
t.integer :shareable_id
|
130
|
+
t.datetime :created_at
|
131
|
+
end
|
132
|
+
|
133
|
+
create_table :im_a_followers do |t|
|
134
|
+
t.datetime :created_at
|
135
|
+
t.datetime :updated_at
|
136
|
+
end
|
137
|
+
|
138
|
+
create_table :im_a_followables do |t|
|
139
|
+
t.datetime :created_at
|
140
|
+
t.datetime :updated_at
|
141
|
+
end
|
142
|
+
|
143
|
+
create_table :im_a_likers do |t|
|
144
|
+
t.datetime :created_at
|
145
|
+
t.datetime :updated_at
|
146
|
+
end
|
147
|
+
|
148
|
+
create_table :im_a_likeables do |t|
|
149
|
+
t.datetime :created_at
|
150
|
+
t.datetime :updated_at
|
151
|
+
end
|
152
|
+
|
153
|
+
create_table :im_a_commenters do |t|
|
154
|
+
t.datetime :created_at
|
155
|
+
t.datetime :updated_at
|
156
|
+
end
|
157
|
+
|
158
|
+
create_table :im_a_commentables do |t|
|
159
|
+
t.datetime :created_at
|
160
|
+
t.datetime :updated_at
|
161
|
+
end
|
162
|
+
|
163
|
+
create_table :im_a_commenter_and_commentables do |t|
|
164
|
+
t.datetime :created_at
|
165
|
+
t.datetime :updated_at
|
166
|
+
end
|
167
|
+
|
168
|
+
create_table :im_a_sharers do |t|
|
169
|
+
t.datetime :created_at
|
170
|
+
t.datetime :updated_at
|
171
|
+
end
|
172
|
+
|
173
|
+
create_table :im_a_shareables do |t|
|
174
|
+
t.datetime :created_at
|
175
|
+
t.datetime :updated_at
|
176
|
+
end
|
177
|
+
|
178
|
+
create_table :im_a_sharer_and_shareables do |t|
|
179
|
+
t.datetime :created_at
|
180
|
+
t.datetime :updated_at
|
181
|
+
end
|
182
|
+
|
183
|
+
create_table :vanillas do |t|
|
184
|
+
t.datetime :created_at
|
185
|
+
t.datetime :updated_at
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
class Celebrity < ActiveRecord::Base
|
190
|
+
acts_as_followable
|
191
|
+
end
|
192
|
+
|
193
|
+
class User < ActiveRecord::Base
|
194
|
+
acts_as_follower
|
195
|
+
acts_as_followable
|
196
|
+
acts_as_liker
|
197
|
+
acts_as_likeable
|
198
|
+
acts_as_commenter
|
199
|
+
acts_as_sharer
|
200
|
+
end
|
201
|
+
|
202
|
+
class Movie < ActiveRecord::Base
|
203
|
+
acts_as_likeable
|
204
|
+
acts_as_commentable
|
205
|
+
acts_as_shareable
|
206
|
+
end
|
207
|
+
|
208
|
+
class ImAFollower < ActiveRecord::Base
|
209
|
+
acts_as_follower
|
210
|
+
end
|
211
|
+
class ImAFollowerChild < ImAFollower; end
|
212
|
+
|
213
|
+
class ImAFollowable < ActiveRecord::Base
|
214
|
+
acts_as_followable
|
215
|
+
end
|
216
|
+
class ImAFollowableChild < ImAFollowable; end
|
217
|
+
|
218
|
+
class ImALiker < ActiveRecord::Base
|
219
|
+
acts_as_liker
|
220
|
+
end
|
221
|
+
class ImALikerChild < ImALiker; end
|
222
|
+
|
223
|
+
class ImALikeable < ActiveRecord::Base
|
224
|
+
acts_as_likeable
|
225
|
+
end
|
226
|
+
class ImALikeableChild < ImALikeable; end
|
227
|
+
|
228
|
+
class ImACommenter < ActiveRecord::Base
|
229
|
+
acts_as_commenter
|
230
|
+
end
|
231
|
+
class ImACommenterChild < ImACommenter; end
|
232
|
+
|
233
|
+
class ImACommentable < ActiveRecord::Base
|
234
|
+
acts_as_commentable
|
235
|
+
end
|
236
|
+
class ImACommentableChild < ImACommentable; end
|
237
|
+
|
238
|
+
class ImACommenterAndCommentable < ActiveRecord::Base
|
239
|
+
acts_as_commenter
|
240
|
+
acts_as_commentable
|
241
|
+
end
|
242
|
+
|
243
|
+
class ImASharer < ActiveRecord::Base
|
244
|
+
acts_as_sharer
|
245
|
+
end
|
246
|
+
class ImASharerChild < ImASharer; end
|
247
|
+
|
248
|
+
class ImAShareable < ActiveRecord::Base
|
249
|
+
acts_as_shareable
|
250
|
+
end
|
251
|
+
class ImAShareableChild < ImAShareable; end
|
252
|
+
|
253
|
+
class ImASharerAndShareable < ActiveRecord::Base
|
254
|
+
acts_as_sharer
|
255
|
+
acts_as_shareable
|
256
|
+
end
|
257
|
+
|
258
|
+
class Vanilla < ActiveRecord::Base
|
259
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
class FollowableTest < TestCase
|
4
|
+
include Assertions
|
5
|
+
context "Followable" do
|
6
|
+
setup do
|
7
|
+
# @follower = ImAFollower.new
|
8
|
+
@follower = ImAFollower.create
|
9
|
+
@followable = ImAFollowable.create
|
10
|
+
end
|
11
|
+
|
12
|
+
context "#is_followable?" do
|
13
|
+
should "return true" do
|
14
|
+
assert_true @followable.is_followable?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "#followable?" do
|
19
|
+
should "return true" do
|
20
|
+
assert_true @followable.followable?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "#followed_by?" do
|
25
|
+
should "not accept non-followers" do
|
26
|
+
assert_raises(Socialization::ArgumentError) { @followable.followed_by?(:foo) }
|
27
|
+
end
|
28
|
+
|
29
|
+
should "call $Follow.follows?" do
|
30
|
+
Minitest::Mock.new.expect(:check, false) do
|
31
|
+
$Follow.follows?(@follower, @followable)
|
32
|
+
end
|
33
|
+
# assert_send([$Follow, :follows?, *[@follower, @followable]])
|
34
|
+
@followable.followed_by?(@follower)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "#followers" do
|
39
|
+
should "call $Follow.followers" do
|
40
|
+
assert_send([$Follow, :followers, *[@followable, @follower.class, { :foo => :bar }]])
|
41
|
+
@followable.followers(@follower.class, { :foo => :bar })
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "#followers_relation" do
|
46
|
+
should "call $Follow.followers_relation" do
|
47
|
+
assert_send([$Follow, :followers_relation, *[@followable, @follower.class, { :foo => :bar }]])
|
48
|
+
@followable.followers_relation(@follower.class, { :foo => :bar })
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "deleting a followable" do
|
53
|
+
setup do
|
54
|
+
@follower = ImAFollower.create
|
55
|
+
@follower.follow!(@followable)
|
56
|
+
end
|
57
|
+
|
58
|
+
should "remove follow relationships" do
|
59
|
+
assert_send([Socialization.follow_model, :remove_followers, *[@followable]])
|
60
|
+
@followable.destroy
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__))+'/../test_helper'
|
2
|
+
|
3
|
+
class LikeableTest < TestCase
|
4
|
+
include Assertions
|
5
|
+
context "Likeable" do
|
6
|
+
setup do
|
7
|
+
#@liker = ImALiker.new
|
8
|
+
@liker = ImALiker.create
|
9
|
+
@likeable = ImALikeable.create
|
10
|
+
end
|
11
|
+
|
12
|
+
context "#is_likeable?" do
|
13
|
+
should "return true" do
|
14
|
+
assert @likeable.is_likeable?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "#likeable?" do
|
19
|
+
should "return true" do
|
20
|
+
assert @likeable.likeable?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "#liked_by?" do
|
25
|
+
should "not accept non-likers" do
|
26
|
+
assert_raises(Socialization::ArgumentError) { @likeable.liked_by?(:foo) }
|
27
|
+
end
|
28
|
+
|
29
|
+
# should "call $Like.likes?" do
|
30
|
+
# # $Like.expect(:likes?).with(@liker, @likeable).once
|
31
|
+
# assert_send([$Like, :likes?, *[@liker, @likeable]])
|
32
|
+
# @likeable.liked_by?(@liker)
|
33
|
+
# end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "#likers" do
|
37
|
+
should "call $Like.likers" do
|
38
|
+
# $Like.expect(:likers).with(@likeable, @liker.class, { :foo => :bar })
|
39
|
+
assert_send([$Like, :likers, *[@likeable, @liker.class, { :foo => :bar }]])
|
40
|
+
@likeable.likers(@liker.class, { :foo => :bar })
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "#likers_relation" do
|
45
|
+
should "call $Like.likers_relation" do
|
46
|
+
# $Like.expect(:likers_relation).with(@likeable, @liker.class, { :foo => :bar })
|
47
|
+
assert_send([$Like, :likers_relation, *[@likeable, @liker.class, { :foo => :bar }]])
|
48
|
+
@likeable.likers_relation(@liker.class, { :foo => :bar })
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "deleting a likeable" do
|
53
|
+
setup do
|
54
|
+
@liker = ImALiker.create
|
55
|
+
@liker.save!
|
56
|
+
@liker.like!(@likeable)
|
57
|
+
end
|
58
|
+
|
59
|
+
should "remove like relationships" do
|
60
|
+
assert_send([Socialization.like_model, :remove_likers, *[@likeable]])
|
61
|
+
# Socialization.like_model.expect(:remove_likers).with(@likeable)
|
62
|
+
@likeable.destroy
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|