socialization-cassandra 0.0.1.pre.alpha
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.
- 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
|