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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/recommendable/rater/recommender.rb +4 -4
  3. data/lib/recommendable/version.rb +2 -2
  4. data/test/dummy/Rakefile +7 -0
  5. data/test/dummy/app/models/book.rb +3 -0
  6. data/test/dummy/app/models/movie.rb +3 -0
  7. data/test/dummy/app/models/rock.rb +3 -0
  8. data/test/dummy/app/models/user.rb +4 -0
  9. data/test/dummy/config.ru +4 -0
  10. data/test/dummy/config/application.rb +62 -0
  11. data/test/dummy/config/boot.rb +6 -0
  12. data/test/dummy/config/database.yml +25 -0
  13. data/test/dummy/config/environment.rb +5 -0
  14. data/test/dummy/config/environments/development.rb +37 -0
  15. data/test/dummy/config/environments/production.rb +67 -0
  16. data/test/dummy/config/environments/test.rb +37 -0
  17. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  18. data/test/dummy/config/initializers/inflections.rb +15 -0
  19. data/test/dummy/config/initializers/mime_types.rb +5 -0
  20. data/test/dummy/config/initializers/recommendable.rb +6 -0
  21. data/test/dummy/config/initializers/secret_token.rb +7 -0
  22. data/test/dummy/config/initializers/session_store.rb +8 -0
  23. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  24. data/test/dummy/config/routes.rb +58 -0
  25. data/test/dummy/db/development.sqlite3 +0 -0
  26. data/test/dummy/db/migrate/20121006052300_create_users.rb +9 -0
  27. data/test/dummy/db/migrate/20121006052339_create_movies.rb +10 -0
  28. data/test/dummy/db/migrate/20121007212545_create_rocks.rb +9 -0
  29. data/test/dummy/db/migrate/20121007213144_create_books.rb +10 -0
  30. data/test/dummy/db/schema.rb +42 -0
  31. data/test/dummy/db/seeds.rb +7 -0
  32. data/test/dummy/db/test.sqlite3 +0 -0
  33. data/test/dummy/db/test.sqlite3-journal +0 -0
  34. data/test/dummy/log/test.log +37254 -0
  35. data/test/dummy/script/rails +6 -0
  36. data/test/factories.rb +17 -0
  37. data/test/recommendable/helpers/calculations_test.rb +69 -0
  38. data/test/recommendable/helpers/redis_key_mapper_test.rb +40 -0
  39. data/test/recommendable/ratable/dislikable_test.rb +31 -0
  40. data/test/recommendable/ratable/likable_test.rb +31 -0
  41. data/test/recommendable/ratable_test.rb +78 -0
  42. data/test/recommendable/rater/bookmarker_test.rb +122 -0
  43. data/test/recommendable/rater/disliker_test.rb +122 -0
  44. data/test/recommendable/rater/hider_test.rb +122 -0
  45. data/test/recommendable/rater/liker_test.rb +122 -0
  46. data/test/recommendable/rater/recommender_test.rb +115 -0
  47. data/test/recommendable/rater_test.rb +29 -0
  48. data/test/test_helper.rb +25 -0
  49. 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