recommendable 2.1.0.2 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/recommendable/rater/recommender.rb +4 -4
- data/lib/recommendable/version.rb +2 -2
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/models/book.rb +3 -0
- data/test/dummy/app/models/movie.rb +3 -0
- data/test/dummy/app/models/rock.rb +3 -0
- data/test/dummy/app/models/user.rb +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +62 -0
- data/test/dummy/config/boot.rb +6 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/recommendable.rb +6 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20121006052300_create_users.rb +9 -0
- data/test/dummy/db/migrate/20121006052339_create_movies.rb +10 -0
- data/test/dummy/db/migrate/20121007212545_create_rocks.rb +9 -0
- data/test/dummy/db/migrate/20121007213144_create_books.rb +10 -0
- data/test/dummy/db/schema.rb +42 -0
- data/test/dummy/db/seeds.rb +7 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/db/test.sqlite3-journal +0 -0
- data/test/dummy/log/test.log +37254 -0
- data/test/dummy/script/rails +6 -0
- data/test/factories.rb +17 -0
- data/test/recommendable/helpers/calculations_test.rb +69 -0
- data/test/recommendable/helpers/redis_key_mapper_test.rb +40 -0
- data/test/recommendable/ratable/dislikable_test.rb +31 -0
- data/test/recommendable/ratable/likable_test.rb +31 -0
- data/test/recommendable/ratable_test.rb +78 -0
- data/test/recommendable/rater/bookmarker_test.rb +122 -0
- data/test/recommendable/rater/disliker_test.rb +122 -0
- data/test/recommendable/rater/hider_test.rb +122 -0
- data/test/recommendable/rater/liker_test.rb +122 -0
- data/test/recommendable/rater/recommender_test.rb +115 -0
- data/test/recommendable/rater_test.rb +29 -0
- data/test/test_helper.rb +25 -0
- metadata +95 -4
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
+
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
6
|
+
require 'rails/commands'
|
data/test/factories.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Factory.define(:user) do |f|
|
2
|
+
f.email 'user%d@example.com'
|
3
|
+
end
|
4
|
+
|
5
|
+
Factory.define(:movie) do |f|
|
6
|
+
f.title '%{year}: A Space Odyssey'
|
7
|
+
f.year { '200%d'.to_i }
|
8
|
+
end
|
9
|
+
|
10
|
+
Factory.define(:book) do |f|
|
11
|
+
f.title 'Harry Potter Vol. %d'
|
12
|
+
f.author 'J.K. Rowling'
|
13
|
+
end
|
14
|
+
|
15
|
+
Factory.define(:rock) do |f|
|
16
|
+
f.name 'Boring Specimen No. %d'
|
17
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../test', __FILE__)
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class CalculationsTest < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@user = Factory(:user)
|
7
|
+
5.times { |x| instance_variable_set(:"@user#{x+1}", Factory(:user)) }
|
8
|
+
10.times { |x| instance_variable_set(:"@movie#{x+1}", Factory(:movie)) }
|
9
|
+
10.times { |x| instance_variable_set(:"@book#{x+1}", Factory(:book)) }
|
10
|
+
|
11
|
+
[@movie1, @movie2, @movie3, @book4, @book5, @book6].each { |obj| @user.like(obj) }
|
12
|
+
[@book1, @book2, @book3, @movie4, @movie5, @movie6].each { |obj| @user.dislike(obj) }
|
13
|
+
|
14
|
+
# @user.similarity_with(@user1) should == 1.0
|
15
|
+
[@movie1, @movie2, @movie3, @book4, @book5, @book6, @book7, @book8, @movie9, @movie10].each { |obj| @user1.like(obj) }
|
16
|
+
[@book1, @book2, @book3, @movie4, @movie5, @movie6, @movie7, @movie8, @book9, @book10].each { |obj| @user1.dislike(obj) }
|
17
|
+
|
18
|
+
# @user.similarity_with(@user2) should == 0.25
|
19
|
+
[@movie1, @movie2, @movie3, @book4, @book5, @book6].each { |obj| @user2.like(obj) }
|
20
|
+
[@book1, @book2, @book3].each { |obj| @user2.like(obj) }
|
21
|
+
|
22
|
+
# @user.similarity_with(@user3) should == 0.0
|
23
|
+
[@movie1, @movie2, @movie3].each { |obj| @user3.like(obj) }
|
24
|
+
[@book1, @book2, @book3].each { |obj| @user3.like(obj) }
|
25
|
+
|
26
|
+
# @user.similarity_with(@user4) should == -0.25
|
27
|
+
[@movie1, @movie2, @movie3].each { |obj| @user4.like(obj) }
|
28
|
+
[@book1, @book2, @book3, @movie4, @movie5, @movie6].each { |obj| @user4.like(obj) }
|
29
|
+
|
30
|
+
# @user.similarity_with(@user5) should == -1.0
|
31
|
+
[@movie1, @movie2, @movie3, @book4, @book5, @book6].each { |obj| @user5.dislike(obj) }
|
32
|
+
[@book1, @book2, @book3, @movie4, @movie5, @movie6].each { |obj| @user5.like(obj) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_similarity_between_calculates_correctly
|
36
|
+
assert_equal Recommendable::Helpers::Calculations.similarity_between(@user.id, @user1.id), 1.0
|
37
|
+
assert_equal Recommendable::Helpers::Calculations.similarity_between(@user.id, @user2.id), 0.25
|
38
|
+
assert_equal Recommendable::Helpers::Calculations.similarity_between(@user.id, @user3.id), 0
|
39
|
+
assert_equal Recommendable::Helpers::Calculations.similarity_between(@user.id, @user4.id), -0.25
|
40
|
+
assert_equal Recommendable::Helpers::Calculations.similarity_between(@user.id, @user5.id), -1.0
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_update_recommendations_ignores_rated_items
|
44
|
+
Recommendable::Helpers::Calculations.update_similarities_for(@user.id)
|
45
|
+
Recommendable::Helpers::Calculations.update_recommendations_for(@user.id)
|
46
|
+
|
47
|
+
movies = @user.liked_movies + @user.disliked_movies
|
48
|
+
books = @user.liked_books + @user.disliked_books
|
49
|
+
|
50
|
+
movies.each { |m| refute_includes @user.recommended_movies, m }
|
51
|
+
books.each { |b| refute_includes @user.recommended_books, b }
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_predict_for_returns_predictions
|
55
|
+
Recommendable::Helpers::Calculations.update_similarities_for(@user.id)
|
56
|
+
assert_equal Recommendable::Helpers::Calculations.predict_for(@user.id, @book7.class, @book7.id), 1.0
|
57
|
+
assert_equal Recommendable::Helpers::Calculations.predict_for(@user.id, @book8.class, @book8.id), 1.0
|
58
|
+
assert_equal Recommendable::Helpers::Calculations.predict_for(@user.id, @book9.class, @book9.id), -1.0
|
59
|
+
assert_equal Recommendable::Helpers::Calculations.predict_for(@user.id, @book10.class, @book10.id), -1.0
|
60
|
+
assert_equal Recommendable::Helpers::Calculations.predict_for(@user.id, @movie7.class, @movie7.id), -1.0
|
61
|
+
assert_equal Recommendable::Helpers::Calculations.predict_for(@user.id, @movie8.class, @movie8.id), -1.0
|
62
|
+
assert_equal Recommendable::Helpers::Calculations.predict_for(@user.id, @movie9.class, @movie9.id), 1.0
|
63
|
+
assert_equal Recommendable::Helpers::Calculations.predict_for(@user.id, @movie10.class, @movie10.id), 1.0
|
64
|
+
end
|
65
|
+
|
66
|
+
def teardown
|
67
|
+
Recommendable.redis.flushdb
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../test', __FILE__)
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class RedisKeyMapperTest < MiniTest::Unit::TestCase
|
5
|
+
def test_output_of_liked_set_for
|
6
|
+
assert_equal Recommendable::Helpers::RedisKeyMapper.liked_set_for(Movie, 1), 'recommendable:users:1:liked_movies'
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_output_of_disliked_set_for
|
10
|
+
assert_equal Recommendable::Helpers::RedisKeyMapper.disliked_set_for(Movie, 1), 'recommendable:users:1:disliked_movies'
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_output_of_hidden_set_for
|
14
|
+
assert_equal Recommendable::Helpers::RedisKeyMapper.hidden_set_for(Movie, 1), 'recommendable:users:1:hidden_movies'
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_output_of_bookmarked_set_for
|
18
|
+
assert_equal Recommendable::Helpers::RedisKeyMapper.bookmarked_set_for(Movie, 1), 'recommendable:users:1:bookmarked_movies'
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_output_of_recommended_set_for
|
22
|
+
assert_equal Recommendable::Helpers::RedisKeyMapper.recommended_set_for(Movie, 1), 'recommendable:users:1:recommended_movies'
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_output_of_similarity_set_for
|
26
|
+
assert_equal Recommendable::Helpers::RedisKeyMapper.similarity_set_for(1), 'recommendable:users:1:similarities'
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_output_of_liked_by_set_for
|
30
|
+
assert_equal Recommendable::Helpers::RedisKeyMapper.liked_by_set_for(Movie, 1), 'recommendable:movies:1:liked_by'
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_output_of_disliked_by_set_for
|
34
|
+
assert_equal Recommendable::Helpers::RedisKeyMapper.disliked_by_set_for(Movie, 1), 'recommendable:movies:1:disliked_by'
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_output_of_score_set_for
|
38
|
+
assert_equal Recommendable::Helpers::RedisKeyMapper.score_set_for(Movie), 'recommendable:movies:scores'
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../test', __FILE__)
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class DislikableTest < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@user = Factory(:user)
|
7
|
+
@friend = Factory(:user)
|
8
|
+
@movie = Factory(:movie)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_disliked_by_returns_relevant_users
|
12
|
+
assert_empty @movie.disliked_by
|
13
|
+
@user.dislike(@movie)
|
14
|
+
assert_includes @movie.disliked_by, @user
|
15
|
+
refute_includes @movie.disliked_by, @friend
|
16
|
+
@friend.dislike(@movie)
|
17
|
+
assert_includes @movie.disliked_by, @friend
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_disliked_by_count_returns_an_accurate_count
|
21
|
+
assert_empty @movie.disliked_by
|
22
|
+
@user.dislike(@movie)
|
23
|
+
assert_equal @movie.disliked_by_count, 1
|
24
|
+
@friend.dislike(@movie)
|
25
|
+
assert_equal @movie.disliked_by_count, 2
|
26
|
+
end
|
27
|
+
|
28
|
+
def teardown
|
29
|
+
Recommendable.redis.flushdb
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../test', __FILE__)
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class LikableTest < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@user = Factory(:user)
|
7
|
+
@friend = Factory(:user)
|
8
|
+
@movie = Factory(:movie)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_liked_by_returns_relevant_users
|
12
|
+
assert_empty @movie.liked_by
|
13
|
+
@user.like(@movie)
|
14
|
+
assert_includes @movie.liked_by, @user
|
15
|
+
refute_includes @movie.liked_by, @friend
|
16
|
+
@friend.like(@movie)
|
17
|
+
assert_includes @movie.liked_by, @friend
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_liked_by_count_returns_an_accurate_count
|
21
|
+
assert_empty @movie.liked_by
|
22
|
+
@user.like(@movie)
|
23
|
+
assert_equal @movie.liked_by_count, 1
|
24
|
+
@friend.like(@movie)
|
25
|
+
assert_equal @movie.liked_by_count, 2
|
26
|
+
end
|
27
|
+
|
28
|
+
def teardown
|
29
|
+
Recommendable.redis.flushdb
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../test', __FILE__)
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class RatableTest < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@movie = Factory(:movie)
|
7
|
+
@book = Factory(:book)
|
8
|
+
@rock = Factory(:rock)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_recommendable_predicate_works
|
12
|
+
assert Movie.recommendable?
|
13
|
+
assert @movie.recommendable?
|
14
|
+
assert Book.recommendable?
|
15
|
+
assert @book.recommendable?
|
16
|
+
refute Rock.recommendable?
|
17
|
+
refute @rock.recommendable?
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_rated_predicate_works
|
21
|
+
refute @movie.rated?
|
22
|
+
user = Factory(:user)
|
23
|
+
user.like(@movie)
|
24
|
+
assert @movie.rated?
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_top_scope_returns_best_things
|
28
|
+
@book2 = Factory(:book)
|
29
|
+
@book3 = Factory(:book)
|
30
|
+
@user = Factory(:user)
|
31
|
+
@friend = Factory(:user)
|
32
|
+
|
33
|
+
@user.like(@book2)
|
34
|
+
@friend.like(@book2)
|
35
|
+
@user.like(@book3)
|
36
|
+
@user.dislike(@book)
|
37
|
+
|
38
|
+
top = Book.top(3)
|
39
|
+
assert_equal top[0], @book2
|
40
|
+
assert_equal top[1], @book3
|
41
|
+
assert_equal top[2], @book
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_removed_from_recommendable_upon_destruction
|
45
|
+
@user = Factory(:user)
|
46
|
+
@friend = Factory(:user)
|
47
|
+
@buddy = Factory(:user)
|
48
|
+
@user.like(@movie)
|
49
|
+
@friend.dislike(@movie)
|
50
|
+
@user.dislike(@book)
|
51
|
+
@friend.like(@book)
|
52
|
+
@buddy.hide(@movie)
|
53
|
+
@buddy.bookmark(@book)
|
54
|
+
|
55
|
+
liked_by_sets = [@movie, @book].map { |obj| Recommendable::Helpers::RedisKeyMapper.liked_by_set_for(obj.class, obj.id) }
|
56
|
+
disliked_by_sets = [@movie, @book].map { |obj| Recommendable::Helpers::RedisKeyMapper.disliked_by_set_for(obj.class, obj.id) }
|
57
|
+
[liked_by_sets, disliked_by_sets].flatten.each { |set| assert_equal Recommendable.redis.scard(set), 1 }
|
58
|
+
|
59
|
+
assert @user.likes?(@movie)
|
60
|
+
assert @user.dislikes?(@book)
|
61
|
+
assert @friend.likes?(@book)
|
62
|
+
assert @friend.dislikes?(@movie)
|
63
|
+
assert @buddy.hides?(@movie)
|
64
|
+
assert @buddy.bookmarks?(@book)
|
65
|
+
|
66
|
+
@movie.destroy
|
67
|
+
@book.destroy
|
68
|
+
|
69
|
+
[liked_by_sets, disliked_by_sets].flatten.each { |set| assert_equal Recommendable.redis.scard(set), 0 }
|
70
|
+
|
71
|
+
assert_empty @buddy.hidden_movies
|
72
|
+
assert_empty @buddy.bookmarked_books
|
73
|
+
end
|
74
|
+
|
75
|
+
def teardown
|
76
|
+
Recommendable.redis.flushdb
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../test', __FILE__)
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class BookmarkerTest < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@user = Factory(:user)
|
7
|
+
@movie = Factory(:movie)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_that_bookmark_adds_to_bookmarked_set
|
11
|
+
refute_includes @user.bookmarked_movie_ids, @movie.id
|
12
|
+
@user.bookmark(@movie)
|
13
|
+
assert_includes @user.bookmarked_movie_ids, @movie.id
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_that_cant_bookmark_already_bookmarked_object
|
17
|
+
assert @user.bookmark(@movie)
|
18
|
+
assert_nil @user.bookmark(@movie)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_that_cant_bookmark_unratable_object
|
22
|
+
basic_obj = Object.new
|
23
|
+
rock = Factory(:rock)
|
24
|
+
|
25
|
+
assert_raises(ArgumentError) { @user.bookmark(basic_obj) }
|
26
|
+
assert_raises(ArgumentError) { @user.bookmark(rock) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_that_bookmarks_returns_true_if_bookmarked
|
30
|
+
refute @user.bookmarks?(@movie)
|
31
|
+
@user.bookmark(@movie)
|
32
|
+
assert @user.bookmarks?(@movie)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_that_unbookmark_removes_item_from_bookmarked_set
|
36
|
+
@user.bookmark(@movie)
|
37
|
+
assert_includes @user.bookmarked_movie_ids, @movie.id
|
38
|
+
@user.unbookmark(@movie)
|
39
|
+
refute_includes @user.bookmarked_movie_ids, @movie.id
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_that_cant_unbookmark_item_unless_bookmarked
|
43
|
+
assert_nil @user.unbookmark(@movie)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_that_bookmarks_returns_bookmarked_records
|
47
|
+
refute_includes @user.bookmarks, @movie
|
48
|
+
@user.bookmark(@movie)
|
49
|
+
assert_includes @user.bookmarks, @movie
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_that_dynamic_bookmarked_finder_only_returns_relevant_records
|
53
|
+
book = Factory(:book)
|
54
|
+
@user.bookmark(@movie)
|
55
|
+
@user.bookmark(book)
|
56
|
+
|
57
|
+
refute_includes @user.bookmarked_movies, book
|
58
|
+
refute_includes @user.bookmarked_books, @movie
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_that_bookmarks_count_counts_all_bookmarks
|
62
|
+
book = Factory(:book)
|
63
|
+
movie2 = Factory(:movie)
|
64
|
+
|
65
|
+
@user.bookmark(@movie)
|
66
|
+
@user.bookmark(movie2)
|
67
|
+
@user.bookmark(book)
|
68
|
+
|
69
|
+
assert_equal @user.bookmarks_count, 3
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_that_dynamic_bookmarked_count_methods_only_count_relevant_bookmarks
|
73
|
+
book = Factory(:book)
|
74
|
+
movie2 = Factory(:movie)
|
75
|
+
|
76
|
+
@user.bookmark(@movie)
|
77
|
+
@user.bookmark(movie2)
|
78
|
+
@user.bookmark(book)
|
79
|
+
|
80
|
+
assert_equal @user.bookmarked_movies_count, 2
|
81
|
+
assert_equal @user.bookmarked_books_count, 1
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_that_bookmarks_in_common_with_returns_all_common_bookmarks
|
85
|
+
friend = Factory(:user)
|
86
|
+
movie2 = Factory(:movie)
|
87
|
+
book = Factory(:book)
|
88
|
+
book2 = Factory(:book)
|
89
|
+
|
90
|
+
@user.bookmark(@movie)
|
91
|
+
@user.bookmark(book)
|
92
|
+
@user.bookmark(movie2)
|
93
|
+
friend.bookmark(@movie)
|
94
|
+
friend.bookmark(book)
|
95
|
+
friend.bookmark(book2)
|
96
|
+
|
97
|
+
assert_includes @user.bookmarks_in_common_with(friend), @movie
|
98
|
+
assert_includes @user.bookmarks_in_common_with(friend), book
|
99
|
+
refute_includes @user.bookmarks_in_common_with(friend), movie2
|
100
|
+
refute_includes friend.bookmarks_in_common_with(@user), book2
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_that_dynamic_bookmarked_in_common_with_only_returns_relevant_records
|
104
|
+
friend = Factory(:user)
|
105
|
+
movie2 = Factory(:movie)
|
106
|
+
book = Factory(:book)
|
107
|
+
|
108
|
+
@user.bookmark(@movie)
|
109
|
+
@user.bookmark(book)
|
110
|
+
friend.bookmark(@movie)
|
111
|
+
friend.bookmark(book)
|
112
|
+
|
113
|
+
assert_includes @user.bookmarked_movies_in_common_with(friend), @movie
|
114
|
+
assert_includes @user.bookmarked_books_in_common_with(friend), book
|
115
|
+
refute_includes @user.bookmarked_movies_in_common_with(friend), book
|
116
|
+
refute_includes @user.bookmarked_books_in_common_with(friend), @movie
|
117
|
+
end
|
118
|
+
|
119
|
+
def teardown
|
120
|
+
Recommendable.redis.flushdb
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../test', __FILE__)
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class DislikerTest < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@user = Factory(:user)
|
7
|
+
@movie = Factory(:movie)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_that_dislike_adds_to_disliked_set
|
11
|
+
refute_includes @user.disliked_movie_ids, @movie.id
|
12
|
+
@user.dislike(@movie)
|
13
|
+
assert_includes @user.disliked_movie_ids, @movie.id
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_that_cant_dislike_already_disliked_object
|
17
|
+
assert @user.dislike(@movie)
|
18
|
+
assert_nil @user.dislike(@movie)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_that_cant_dislike_unratable_object
|
22
|
+
basic_obj = Object.new
|
23
|
+
rock = Factory(:rock)
|
24
|
+
|
25
|
+
assert_raises(ArgumentError) { @user.dislike(basic_obj) }
|
26
|
+
assert_raises(ArgumentError) { @user.dislike(rock) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_that_dislikes_returns_true_if_disliked
|
30
|
+
refute @user.dislikes?(@movie)
|
31
|
+
@user.dislike(@movie)
|
32
|
+
assert @user.dislikes?(@movie)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_that_undislike_removes_item_from_disliked_set
|
36
|
+
@user.dislike(@movie)
|
37
|
+
assert_includes @user.disliked_movie_ids, @movie.id
|
38
|
+
@user.undislike(@movie)
|
39
|
+
refute_includes @user.disliked_movie_ids, @movie.id
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_that_cant_undislike_item_unless_disliked
|
43
|
+
assert_nil @user.undislike(@movie)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_that_dislikes_returns_disliked_records
|
47
|
+
refute_includes @user.dislikes, @movie
|
48
|
+
@user.dislike(@movie)
|
49
|
+
assert_includes @user.dislikes, @movie
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_that_dynamic_disliked_finder_only_returns_relevant_records
|
53
|
+
book = Factory(:book)
|
54
|
+
@user.dislike(@movie)
|
55
|
+
@user.dislike(book)
|
56
|
+
|
57
|
+
refute_includes @user.disliked_movies, book
|
58
|
+
refute_includes @user.disliked_books, @movie
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_that_dislikes_count_counts_all_dislikes
|
62
|
+
book = Factory(:book)
|
63
|
+
movie2 = Factory(:movie)
|
64
|
+
|
65
|
+
@user.dislike(@movie)
|
66
|
+
@user.dislike(movie2)
|
67
|
+
@user.dislike(book)
|
68
|
+
|
69
|
+
assert_equal @user.dislikes_count, 3
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_that_dynamic_disliked_count_methods_only_count_relevant_dislikes
|
73
|
+
book = Factory(:book)
|
74
|
+
movie2 = Factory(:movie)
|
75
|
+
|
76
|
+
@user.dislike(@movie)
|
77
|
+
@user.dislike(movie2)
|
78
|
+
@user.dislike(book)
|
79
|
+
|
80
|
+
assert_equal @user.disliked_movies_count, 2
|
81
|
+
assert_equal @user.disliked_books_count, 1
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_that_dislikes_in_common_with_returns_all_common_dislikes
|
85
|
+
friend = Factory(:user)
|
86
|
+
movie2 = Factory(:movie)
|
87
|
+
book = Factory(:book)
|
88
|
+
book2 = Factory(:book)
|
89
|
+
|
90
|
+
@user.dislike(@movie)
|
91
|
+
@user.dislike(book)
|
92
|
+
@user.dislike(movie2)
|
93
|
+
friend.dislike(@movie)
|
94
|
+
friend.dislike(book)
|
95
|
+
friend.dislike(book2)
|
96
|
+
|
97
|
+
assert_includes @user.dislikes_in_common_with(friend), @movie
|
98
|
+
assert_includes @user.dislikes_in_common_with(friend), book
|
99
|
+
refute_includes @user.dislikes_in_common_with(friend), movie2
|
100
|
+
refute_includes friend.dislikes_in_common_with(@user), book2
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_that_dynamic_disliked_in_common_with_only_returns_relevant_records
|
104
|
+
friend = Factory(:user)
|
105
|
+
movie2 = Factory(:movie)
|
106
|
+
book = Factory(:book)
|
107
|
+
|
108
|
+
@user.dislike(@movie)
|
109
|
+
@user.dislike(book)
|
110
|
+
friend.dislike(@movie)
|
111
|
+
friend.dislike(book)
|
112
|
+
|
113
|
+
assert_includes @user.disliked_movies_in_common_with(friend), @movie
|
114
|
+
assert_includes @user.disliked_books_in_common_with(friend), book
|
115
|
+
refute_includes @user.disliked_movies_in_common_with(friend), book
|
116
|
+
refute_includes @user.disliked_books_in_common_with(friend), @movie
|
117
|
+
end
|
118
|
+
|
119
|
+
def teardown
|
120
|
+
Recommendable.redis.flushdb
|
121
|
+
end
|
122
|
+
end
|