">
<% if params[:preview].truthy? %>
<%= post_preview(@post, show_deleted: true, compact: true) %>
diff --git a/app/views/user_upgrades/new.html.erb b/app/views/user_upgrades/new.html.erb
index f72ed032a..7e88565bb 100644
--- a/app/views/user_upgrades/new.html.erb
+++ b/app/views/user_upgrades/new.html.erb
@@ -70,6 +70,12 @@
2,000 |
5,000 |
+
+ | Private Favorites |
+ no |
+ yes |
+ yes |
+
| Favorite Groups |
3 |
diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb
index 557927ea3..0d7487658 100644
--- a/app/views/users/edit.html.erb
+++ b/app/views/users/edit.html.erb
@@ -63,7 +63,13 @@
<%= f.input :hide_deleted_posts, :as => :select, :label => "Deleted post filter", :hint => "Remove deleted posts from search results", :include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
<%= f.input :show_deleted_children, :as => :select, :label => "Show deleted children", :hint => "Show thumbnail borders on parent posts even if the children are deleted", :include_blank => false, :collection => [["Yes", "true"], ["No", "false"]] %>
<%= f.input :disable_categorized_saved_searches, :hint => "Don't show dialog box when creating a new saved search", :as => :select, :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false %>
- <%= f.input :enable_private_favorites, :as => :select, :hint => "Make your favorites private", :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false %>
+ <% if policy(@user).can_enable_private_favorites? %>
+ <%= f.input :enable_private_favorites, label: "Private favorites and votes", as: :select, hint: "Make your favorites and upvotes private", collection: { "No" => false, "Yes" => true }, include_blank: false %>
+ <% elsif @user.enable_private_favorites? %>
+ <%= f.input :enable_private_favorites, label: "Private favorites and votes", as: :select, hint: "Make your favorites and upvotes private. (Warning: if you disable this, you can't re-enable it without ".html_safe + link_to("upgrading to a Gold account", new_user_upgrade_path) + " first. (".html_safe + link_to_wiki("learn more", "help:privacy_mode") + ")".html_safe, collection: { "No" => false, "Yes" => true }, include_blank: false %>
+ <% else %>
+ <%= f.input :enable_private_favorites, label: "Private favorites and votes", as: :select, hint: link_to("Upgrade to Danbooru Gold to enable private favorites and upvotes", new_user_upgrade_path), collection: { "No" => false, "Yes" => true }, include_blank: false %>
+ <% end %>
<%= f.input :disable_tagged_filenames, :as => :select, :hint => "Don't include tags in image filenames", :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false %>
<%= f.input :disable_mobile_gestures, :as => :select, :hint => "Disable swipe left / swipe right gestures on mobile", :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false %>
<%= f.input :disable_post_tooltips, :as => :select, :hint => "Disable advanced tooltips when hovering over thumbnails", :collection => [["No", "false"], ["Yes", "true"]], :include_blank => false %>
diff --git a/config/routes.rb b/config/routes.rb
index b7e2287df..7d104b16e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -194,6 +194,7 @@ Rails.application.routes.draw do
# XXX Use `only: []` to avoid redefining post routes defined at top of file.
resources :posts, only: [] do
resources :events, :only => [:index], :controller => "post_events"
+ resources :favorites, only: [:index, :create, :destroy]
resources :replacements, :only => [:index, :new, :create], :controller => "post_replacements"
resource :artist_commentary, only: [:show] do
collection { put :create_or_update }
@@ -252,6 +253,7 @@ Rails.application.routes.draw do
end
end
resources :users do
+ resources :favorites, only: [:index, :create, :destroy]
resources :favorite_groups, controller: "favorite_groups", only: [:index], as: "favorite_groups"
resource :email, only: [:show, :edit, :update] do
get :verify
diff --git a/test/components/post_navbar_component_test.rb b/test/components/post_navbar_component_test.rb
index a27024ac0..60a37c0ec 100644
--- a/test/components/post_navbar_component_test.rb
+++ b/test/components/post_navbar_component_test.rb
@@ -7,7 +7,7 @@ class PostNavbarComponentTest < ViewComponent::TestCase
setup do
@post = create(:post)
- @user = create(:user)
+ @user = create(:gold_user)
end
context "The PostNavbarComponent" do
@@ -46,9 +46,8 @@ class PostNavbarComponentTest < ViewComponent::TestCase
context "for a post with favgroups" do
setup do
as(@user) do
- @favgroup1 = create(:favorite_group, creator: @user, is_public: true)
- @favgroup2 = create(:favorite_group, creator: @user, is_public: false)
- @post.update(tag_string: "favgroup:#{@favgroup1.id} favgroup:#{@favgroup2.id}")
+ @favgroup1 = create(:favorite_group, creator: @user, post_ids: [@post.id])
+ @favgroup2 = create(:private_favorite_group, creator: @user, post_ids: [@post.id])
end
end
diff --git a/test/components/post_votes_component_test.rb b/test/components/post_votes_component_test.rb
index df30aff6d..7a9118d56 100644
--- a/test/components/post_votes_component_test.rb
+++ b/test/components/post_votes_component_test.rb
@@ -11,12 +11,12 @@ class PostVotesComponentTest < ViewComponent::TestCase
end
context "for a user who can't vote" do
- should "not show the vote buttons" do
+ should "show the vote buttons" do
render_post_votes(@post, current_user: User.anonymous)
assert_css(".post-score")
- assert_no_css(".post-upvote-link")
- assert_no_css(".post-downvote-link")
+ assert_css(".post-upvote-link.inactive-link")
+ assert_css(".post-downvote-link.inactive-link")
end
end
@@ -34,8 +34,8 @@ class PostVotesComponentTest < ViewComponent::TestCase
context "for a downvoted post" do
should "highlight the downvote button as active" do
- @post.vote!(-1, @user)
- render_post_votes(@post, current_user: @user)
+ create(:post_vote, post: @post, user: @user, score: -1)
+ as(@user) { render_post_votes(@post, current_user: @user) }
assert_css(".post-upvote-link.inactive-link")
assert_css(".post-downvote-link.active-link")
@@ -44,8 +44,8 @@ class PostVotesComponentTest < ViewComponent::TestCase
context "for an upvoted post" do
should "highlight the upvote button as active" do
- @post.vote!(1, @user)
- render_post_votes(@post, current_user: @user)
+ create(:post_vote, post: @post, user: @user, score: 1)
+ as(@user) { render_post_votes(@post, current_user: @user) }
assert_css(".post-upvote-link.active-link")
assert_css(".post-downvote-link.inactive-link")
diff --git a/test/factories/favorite.rb b/test/factories/favorite.rb
index 441c6f4a9..40ef97b84 100644
--- a/test/factories/favorite.rb
+++ b/test/factories/favorite.rb
@@ -2,5 +2,9 @@ FactoryBot.define do
factory(:favorite) do
user
post
+
+ factory(:private_favorite) do
+ user factory: :gold_user, enable_private_favorites: true
+ end
end
end
diff --git a/test/factories/favorite_group.rb b/test/factories/favorite_group.rb
index 73104b22a..f03473a07 100644
--- a/test/factories/favorite_group.rb
+++ b/test/factories/favorite_group.rb
@@ -2,5 +2,10 @@ FactoryBot.define do
factory :favorite_group do
creator
name { SecureRandom.uuid }
+
+ factory :private_favorite_group do
+ creator factory: :gold_user
+ is_public { false }
+ end
end
end
diff --git a/test/factories/user.rb b/test/factories/user.rb
index dc6cf0942..a9bbe1c77 100644
--- a/test/factories/user.rb
+++ b/test/factories/user.rb
@@ -8,6 +8,7 @@ FactoryBot.define do
factory(:banned_user) do
transient { ban_duration {3} }
is_banned {true}
+ active_ban factory: :ban
end
factory(:restricted_user) do
diff --git a/test/functional/favorite_groups_controller_test.rb b/test/functional/favorite_groups_controller_test.rb
index f9d0d32bb..bba7a91ce 100644
--- a/test/functional/favorite_groups_controller_test.rb
+++ b/test/functional/favorite_groups_controller_test.rb
@@ -10,7 +10,7 @@ class FavoriteGroupsControllerTest < ActionDispatch::IntegrationTest
context "index action" do
setup do
@mod_favgroup = create(:favorite_group, name: "monochrome", creator: build(:moderator_user, name: "fumimi"))
- @private_favgroup = create(:favorite_group, creator: @user, is_public: false)
+ @private_favgroup = create(:private_favorite_group)
end
should "render" do
@@ -28,7 +28,7 @@ class FavoriteGroupsControllerTest < ActionDispatch::IntegrationTest
context "for private favorite groups as the creator" do
setup do
- CurrentUser.user = @user
+ CurrentUser.user = @private_favgroup.creator
end
should respond_to_search(is_public: "false").with { @private_favgroup }
@@ -42,13 +42,13 @@ class FavoriteGroupsControllerTest < ActionDispatch::IntegrationTest
end
should "show private favgroups to the creator" do
- @favgroup.update!(is_public: false)
+ @favgroup.update_columns(is_public: false)
get_auth favorite_group_path(@favgroup), @user
assert_response :success
end
should "not show private favgroups to other users" do
- @favgroup = create(:favorite_group, is_public: false)
+ @favgroup = create(:private_favorite_group)
get_auth favorite_group_path(@favgroup), create(:user)
assert_response 403
end
@@ -91,6 +91,13 @@ class FavoriteGroupsControllerTest < ActionDispatch::IntegrationTest
assert_response 403
assert_not_equal("foo", @favgroup.reload.name)
end
+
+ should "not allow non-Gold users to enable private favgroups" do
+ put_auth favorite_group_path(@favgroup), @user, params: { favorite_group: { is_private: true } }
+
+ assert_response :success
+ assert_equal(false, @favgroup.is_private?)
+ end
end
context "destroy action" do
diff --git a/test/functional/favorites_controller_test.rb b/test/functional/favorites_controller_test.rb
index 61e94cffe..936e69e48 100644
--- a/test/functional/favorites_controller_test.rb
+++ b/test/functional/favorites_controller_test.rb
@@ -10,25 +10,35 @@ class FavoritesControllerTest < ActionDispatch::IntegrationTest
end
context "index action" do
- should "redirect the user_id param to an ordfav: search" do
- get favorites_path(user_id: @user.id)
- assert_redirected_to posts_path(tags: "ordfav:#{@user.name}", format: "html")
- end
-
- should "redirect members to an ordfav: search" do
- get_auth favorites_path, @user
- assert_redirected_to posts_path(tags: "ordfav:#{@user.name}", format: "html")
- end
-
- should "redirect anonymous users to the posts index" do
- get favorites_path
- assert_redirected_to posts_path(format: "html")
- end
-
should "render for json" do
get favorites_path, as: :json
assert_response :success
end
+
+ should "render for html" do
+ get favorites_path
+ assert_response :success
+ end
+
+ should "render for /favorites?variant=tooltip" do
+ get post_favorites_path(@post, variant: "tooltip")
+ assert_response :success
+ end
+
+ should "render for /users/:id/favorites" do
+ get user_favorites_path(@user)
+ assert_response :success
+ end
+
+ should "render for /posts/:id/favorites" do
+ get post_favorites_path(@faved_post)
+ assert_response :success
+ end
+
+ should "render for /favorites?search[user_name]=" do
+ get favorites_path(search: { user_name: @user.name })
+ assert_response :success
+ end
end
context "create action" do
@@ -48,12 +58,21 @@ class FavoritesControllerTest < ActionDispatch::IntegrationTest
end
end
- should "allow banned users to create favorites" do
+ should "not allow banned users to create favorites" do
@banned_user = create(:banned_user)
- assert_difference [-> { @post.favorites.count }, -> { @post.reload.fav_count }, -> { @banned_user.reload.favorite_count }], 1 do
+ assert_difference [-> { @post.favorites.count }, -> { @post.reload.fav_count }, -> { @banned_user.reload.favorite_count }], 0 do
post_auth favorites_path(post_id: @post.id), @banned_user, as: :javascript
- assert_response :redirect
+ assert_response 403
+ end
+ end
+
+ should "not allow restricted users to create favorites" do
+ @restricted_user = create(:restricted_user)
+
+ assert_difference [-> { @post.favorites.count }, -> { @post.reload.fav_count }, -> { @restricted_user.reload.favorite_count }], 0 do
+ post_auth favorites_path(post_id: @post.id), @restricted_user, as: :javascript
+ assert_response 403
end
end
diff --git a/test/functional/moderator/post/posts_controller_test.rb b/test/functional/moderator/post/posts_controller_test.rb
index 7b13dc163..6aff77f78 100644
--- a/test/functional/moderator/post/posts_controller_test.rb
+++ b/test/functional/moderator/post/posts_controller_test.rb
@@ -43,8 +43,8 @@ module Moderator
@parent.reload
@child.reload
as(@admin) do
- assert_equal(users.map(&:id).sort, @parent.favorited_users.map(&:id).sort)
- assert_equal([], @child.favorited_users.map(&:id))
+ assert_equal(users.map(&:id).sort, @parent.favorites.map(&:user_id).sort)
+ assert_equal([], @child.favorites.map(&:user_id))
end
end
end
diff --git a/test/functional/post_votes_controller_test.rb b/test/functional/post_votes_controller_test.rb
index ffe2f92e8..ff5c47605 100644
--- a/test/functional/post_votes_controller_test.rb
+++ b/test/functional/post_votes_controller_test.rb
@@ -9,59 +9,167 @@ class PostVotesControllerTest < ActionDispatch::IntegrationTest
context "index action" do
setup do
- @admin = create(:admin_user)
- as(@user) { @post_vote = create(:post_vote, post: @post, user: @user) }
- as(@admin) { @admin_vote = create(:post_vote, post: @post, user: @admin) }
- @unrelated_vote = create(:post_vote)
+ @user = create(:user, enable_private_favorites: true)
+ @upvote = create(:post_vote, user: @user, score: 1)
+ @downvote = create(:post_vote, user: @user, score: -1)
end
should "render" do
- get_auth post_votes_path, @user
+ get post_votes_path
+ assert_response :success
+ end
+
+ should "render for a compact view" do
+ get post_votes_path(variant: "compact")
+ assert_response :success
+ end
+
+ should "render for a tooltip" do
+ get post_votes_path(search: { post_id: @upvote.post_id }, variant: "tooltip")
assert_response :success
end
context "as a user" do
- setup do
- CurrentUser.user = @user
+ should "show the user all their own votes" do
+ get_auth post_votes_path, @user
+ assert_response :success
+ assert_select "tbody tr", 2
+
+ get_auth post_votes_path(search: { user_id: @user.id }), @user
+ assert_response :success
+ assert_select "tbody tr", 2
+
+ get_auth post_votes_path(search: { user_name: @user.name }), @user
+ assert_response :success
+ assert_select "tbody tr", 2
end
- should respond_to_search({}).with { @post_vote }
+ should "not show private upvotes to other users" do
+ get_auth post_votes_path, create(:user)
+ assert_response :success
+ assert_select "tbody tr", 0
+
+ get_auth post_votes_path(search: { user_id: @user.id }), create(:user)
+ assert_response :success
+ assert_select "tbody tr", 0
+
+ get_auth post_votes_path(search: { user_name: @user.name }), create(:user)
+ assert_response :success
+ assert_select "tbody tr", 0
+ end
+
+ should "not show downvotes to other users" do
+ @user.update!(enable_private_favorites: false)
+
+ get_auth post_votes_path, create(:user)
+ assert_response :success
+ assert_select "tbody tr[data-score=1]", 1
+ assert_select "tbody tr[data-score=-1]", 0
+
+ get_auth post_votes_path(search: { user_id: @user.id }), create(:user)
+ assert_response :success
+ assert_select "tbody tr[data-score=1]", 1
+ assert_select "tbody tr[data-score=-1]", 0
+
+ get_auth post_votes_path(search: { user_name: @user.name }), create(:user)
+ assert_response :success
+ assert_select "tbody tr[data-score=1]", 1
+ assert_select "tbody tr[data-score=-1]", 0
+ end
end
- context "as a moderator" do
- setup do
- CurrentUser.user = @admin
- end
+ context "as an admin" do
+ should "show all votes by other users" do
+ @admin = create(:admin_user)
- should respond_to_search({}).with { [@unrelated_vote, @admin_vote, @post_vote] }
- should respond_to_search(score: 1).with { [@unrelated_vote, @admin_vote, @post_vote].select{ |v| v.score == 1 } }
+ get_auth post_votes_path, @admin
+ assert_response :success
+ assert_select "tbody tr", 2
- context "using includes" do
- should respond_to_search(post_tags_match: "dragon").with { [@admin_vote, @post_vote] }
- should respond_to_search(user_name: "meiling").with { @post_vote }
- should respond_to_search(user: {level: User::Levels::ADMIN}).with { @admin_vote }
+ get_auth post_votes_path(search: { user_id: @user.id }), @admin
+ assert_response :success
+ assert_select "tbody tr", 2
+
+ get_auth post_votes_path(search: { user_name: @user.name }), @admin
+ assert_response :success
+ assert_select "tbody tr", 2
+
+ get_auth post_votes_path(search: { user: { level: @user.level }}), @admin
+ assert_response :success
+ assert_select "tbody tr", 2
end
end
end
context "show action" do
- setup do
- @post_vote = create(:post_vote, post: @post, user: @user)
+ context "for a public upvote" do
+ setup do
+ @user = create(:user, enable_private_favorites: false)
+ @post_vote = create(:post_vote, user: @user, score: 1)
+ end
+
+ should "show the voter to everyone" do
+ get post_vote_path(@post_vote), as: :json
+
+ assert_response :success
+ assert_equal(@user.id, response.parsed_body["user_id"])
+ end
end
- should "show the vote to the voter" do
- get_auth post_vote_path(@post_vote), @user, as: :json
- assert_response :success
+ context "for a private upvote" do
+ setup do
+ @user = create(:user, enable_private_favorites: true)
+ @post_vote = create(:post_vote, user: @user, score: 1)
+ end
+
+ should "show the voter to themselves" do
+ get_auth post_vote_path(@post_vote), @user, as: :json
+
+ assert_response :success
+ assert_equal(@user.id, response.parsed_body["user_id"])
+ end
+
+ should "show the voter to admins" do
+ get_auth post_vote_path(@post_vote), create(:admin_user), as: :json
+
+ assert_response :success
+ assert_equal(@user.id, response.parsed_body["user_id"])
+ end
+
+ should "not show the voter to other users" do
+ get post_vote_path(@post_vote), as: :json
+
+ assert_response 403
+ assert_nil(response.parsed_body["user_id"])
+ end
end
- should "show the vote to admins" do
- get_auth post_vote_path(@post_vote), create(:admin_user), as: :json
- assert_response :success
- end
+ context "for a downvote" do
+ setup do
+ @user = create(:user, enable_private_favorites: false)
+ @post_vote = create(:post_vote, user: @user, score: -1)
+ end
- should "not show the vote to other users" do
- get_auth post_vote_path(@post_vote), create(:user), as: :json
- assert_response 403
+ should "show the voter to themselves" do
+ get_auth post_vote_path(@post_vote), @user, as: :json
+
+ assert_response :success
+ assert_equal(@user.id, response.parsed_body["user_id"])
+ end
+
+ should "show the voter to admins" do
+ get_auth post_vote_path(@post_vote), create(:admin_user), as: :json
+
+ assert_response :success
+ assert_equal(@user.id, response.parsed_body["user_id"])
+ end
+
+ should "not show the voter to other users" do
+ get post_vote_path(@post_vote), as: :json
+
+ assert_response 403
+ assert_nil(response.parsed_body["user_id"])
+ end
end
end
@@ -87,13 +195,20 @@ class PostVotesControllerTest < ActionDispatch::IntegrationTest
assert_equal(0, @post.reload.score)
end
- should "not allow members to vote" do
- post_auth post_post_votes_path(post_id: @post.id), create(:user), params: { score: 1, format: "js" }
+ should "not allow restricted users to vote" do
+ post_auth post_post_votes_path(post_id: @post.id), create(:restricted_user), params: { score: 1, format: "js"}
assert_response 403
assert_equal(0, @post.reload.score)
end
+ should "allow members to vote" do
+ post_auth post_post_votes_path(post_id: @post.id), create(:user), params: { score: 1, format: "js" }
+
+ assert_response :success
+ assert_equal(1, @post.reload.score)
+ end
+
should "not allow invalid scores" do
post_auth post_post_votes_path(post_id: @post.id), @user, params: { score: 3, format: "js" }
diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb
index e71d27c12..8053f0ddb 100644
--- a/test/functional/users_controller_test.rb
+++ b/test/functional/users_controller_test.rb
@@ -420,6 +420,34 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
assert_equal("xyz", @user.favorite_tags)
end
+ context "for a Member-level user" do
+ should "allow disabling the private favorites option" do
+ @user = create(:user, enable_private_favorites: true)
+ put_auth user_path(@user), @user, params: { user: { enable_private_favorites: false }}
+
+ assert_redirected_to edit_user_path(@user)
+ assert_equal(false, @user.reload.enable_private_favorites)
+ end
+
+ should "not allow enabling the private favorites option" do
+ @user = create(:user, enable_private_favorites: false)
+ put_auth user_path(@user), @user, params: { user: { enable_private_favorites: true }}
+
+ assert_redirected_to edit_user_path(@user)
+ assert_equal(false, @user.reload.enable_private_favorites)
+ end
+ end
+
+ context "for a Gold-level user" do
+ should "allow enabling the private favorites option" do
+ @user = create(:gold_user, enable_private_favorites: false)
+ put_auth user_path(@user), @user, params: { user: { enable_private_favorites: true }}
+
+ assert_redirected_to edit_user_path(@user)
+ assert_equal(true, @user.reload.enable_private_favorites)
+ end
+ end
+
context "changing the level" do
should "not work" do
@owner = create(:owner_user)
diff --git a/test/unit/favorite_test.rb b/test/unit/favorite_test.rb
index 9c0bed69b..8273dc8af 100644
--- a/test/unit/favorite_test.rb
+++ b/test/unit/favorite_test.rb
@@ -11,10 +11,13 @@ class FavoriteTest < ActiveSupport::TestCase
context "Favorites: " do
context "removing a favorite" do
should "update the post and user favorite counts" do
+ @user1 = create(:restricted_user)
fav = Favorite.create!(post: @p1, user: @user1)
assert_equal(1, @user1.reload.favorite_count)
assert_equal(1, @p1.reload.fav_count)
+ assert_equal(0, @p1.reload.score)
+ refute(PostVote.positive.exists?(post: @p1, user: @user))
Favorite.destroy_by(post: @p1, user: @user1)
@@ -42,14 +45,8 @@ class FavoriteTest < ActiveSupport::TestCase
end
context "adding a favorite" do
- should "update the post and user favorite counts" do
- Favorite.create!(post: @p1, user: @user1)
-
- assert_equal(1, @user1.reload.favorite_count)
- assert_equal(1, @p1.reload.fav_count)
- end
-
should "not upvote the post if the user can't vote" do
+ @user1 = create(:restricted_user)
Favorite.create!(post: @p1, user: @user1)
assert_equal(1, @user1.reload.favorite_count)
@@ -89,7 +86,7 @@ class FavoriteTest < ActiveSupport::TestCase
assert_equal(["You have already favorited this post"], @f2.errors.full_messages)
assert_equal(1, @user1.reload.favorite_count)
assert_equal(1, @p1.reload.fav_count)
- assert_equal(0, @p1.reload.score)
+ assert_equal(1, @p1.reload.score)
end
end
end
diff --git a/test/unit/post_query_builder_test.rb b/test/unit/post_query_builder_test.rb
index 5bd7fcb10..a0706f543 100644
--- a/test/unit/post_query_builder_test.rb
+++ b/test/unit/post_query_builder_test.rb
@@ -390,7 +390,7 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
favgroup1 = create(:favorite_group, creator: CurrentUser.user, post_ids: [post1.id])
favgroup2 = create(:favorite_group, creator: CurrentUser.user, post_ids: [post2.id])
- favgroup3 = create(:favorite_group, creator: create(:user), post_ids: [post3.id], is_public: false)
+ favgroup3 = create(:private_favorite_group, post_ids: [post3.id])
assert_tag_match([post1], "favgroup:#{favgroup1.id}")
assert_tag_match([post2], "favgroup:#{favgroup2.name}")
@@ -421,7 +421,7 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
post3 = create(:post)
favgroup1 = create(:favorite_group, creator: CurrentUser.user, post_ids: [post1.id, post2.id])
- favgroup2 = create(:favorite_group, creator: create(:user), post_ids: [post2.id, post3.id], is_public: false)
+ favgroup2 = create(:private_favorite_group, post_ids: [post2.id, post3.id])
assert_tag_match([post1, post2], "ordfavgroup:#{favgroup1.id}")
assert_tag_match([post1, post2], "ordfavgroup:#{favgroup1.name}")
@@ -973,6 +973,75 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
assert_tag_match(all - [e], "-rating:e")
end
+ context "for the upvote: metatag" do
+ setup do
+ @user = create(:gold_user)
+ @upvote = create(:post_vote, user: @user, score: 1)
+ @downvote = create(:post_vote, user: @user, score: -1)
+ end
+
+ should "show public upvotes to all users" do
+ as(User.anonymous) do
+ assert_tag_match([@upvote.post], "upvote:#{@user.name}")
+ assert_tag_match([@downvote.post], "-upvote:#{@user.name}")
+ end
+ end
+
+ should "not show private upvotes to other users" do
+ @user.update!(enable_private_favorites: true)
+
+ as(User.anonymous) do
+ assert_tag_match([], "upvote:#{@user.name}")
+ assert_tag_match([@downvote.post, @upvote.post], "-upvote:#{@user.name}")
+ end
+ end
+
+ should "show private upvotes to admins" do
+ @user.update!(enable_private_favorites: true)
+
+ as(create(:admin_user)) do
+ assert_tag_match([@upvote.post], "upvote:#{@user.name}")
+ assert_tag_match([@downvote.post], "-upvote:#{@user.name}")
+ end
+ end
+
+ should "show private upvotes to the voter themselves" do
+ as(@user) do
+ assert_tag_match([@upvote.post], "upvote:#{@user.name}")
+ assert_tag_match([@downvote.post], "-upvote:#{@user.name}")
+ end
+ end
+ end
+
+ context "for the downvote: metatag" do
+ setup do
+ @user = create(:user, enable_private_favorites: true)
+ @upvote = create(:post_vote, user: @user, score: 1)
+ @downvote = create(:post_vote, user: @user, score: -1)
+ end
+
+ should "not show downvotes to other users" do
+ as(User.anonymous) do
+ assert_tag_match([], "downvote:#{@user.name}")
+ assert_tag_match([@downvote.post, @upvote.post], "-downvote:#{@user.name}")
+ end
+ end
+
+ should "show downvotes to admins" do
+ as(create(:admin_user)) do
+ assert_tag_match([@downvote.post], "downvote:#{@user.name}")
+ assert_tag_match([@upvote.post], "-downvote:#{@user.name}")
+ end
+ end
+
+ should "show downvotes to the voter themselves" do
+ as(@user) do
+ assert_tag_match([@downvote.post], "downvote:#{@user.name}")
+ assert_tag_match([@upvote.post], "-downvote:#{@user.name}")
+ end
+ end
+ end
+
should "return posts for a upvote:, downvote: metatag" do
CurrentUser.scoped(create(:mod_user)) do
upvoted = create(:post, tag_string: "upvote:self")
@@ -1342,8 +1411,7 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
end
should "return the correct favorite count for a fav: search for a user with private favorites" do
- fav = create(:favorite)
- fav.user.update!(favorite_count: 1, enable_private_favorites: true)
+ fav = create(:private_favorite)
assert_fast_count(0, "fav:#{fav.user.name}")
assert_fast_count(0, "ordfav:#{fav.user.name}")
diff --git a/test/unit/post_test.rb b/test/unit/post_test.rb
index a4f0a6f53..2721c52a9 100644
--- a/test/unit/post_test.rb
+++ b/test/unit/post_test.rb
@@ -699,10 +699,34 @@ class PostTest < ActiveSupport::TestCase
context "for a fav" do
should "add/remove the current user to the post's favorite listing" do
@post.update(tag_string: "aaa fav:self")
+ assert_equal(1, @post.reload.score)
assert_equal(1, @post.favorites.where(user: @user).count)
+ assert_equal(1, @post.votes.positive.where(user: @user).count)
@post.update(tag_string: "aaa -fav:self")
+ assert_equal(0, @post.reload.score)
assert_equal(0, @post.favorites.count)
+ assert_equal(0, @post.votes.positive.where(user: @user).count)
+ end
+
+ should "not allow banned users to fav" do
+ assert_raises(User::PrivilegeError) do
+ as(create(:banned_user)) { @post.update(tag_string: "aaa fav:self") }
+ end
+
+ assert_raises(User::PrivilegeError) do
+ as(create(:banned_user)) { @post.update(tag_string: "aaa -fav:self") }
+ end
+ end
+
+ should "not allow restricted users to fav" do
+ assert_raises(User::PrivilegeError) do
+ as(create(:restricted_user)) { @post.update(tag_string: "aaa fav:self") }
+ end
+
+ assert_raises(User::PrivilegeError) do
+ as(create(:restricted_user)) { @post.update(tag_string: "aaa -fav:self") }
+ end
end
should "not fail when the fav: metatag is used twice" do
@@ -870,20 +894,20 @@ class PostTest < ActiveSupport::TestCase
context "upvote:self or downvote:self" do
context "by a member" do
- should "not upvote the post" do
- assert_no_difference("PostVote.count") do
+ should "upvote the post" do
+ assert_difference("PostVote.count") do
@post.update(tag_string: "upvote:self")
end
- assert_equal(0, @post.reload.score)
+ assert_equal(1, @post.reload.score)
end
- should "not downvote the post" do
- assert_no_difference("PostVote.count") do
+ should "downvote the post" do
+ assert_difference("PostVote.count") do
@post.update(tag_string: "downvote:self")
end
- assert_equal(0, @post.reload.score)
+ assert_equal(-1, @post.reload.score)
end
end
@@ -1476,7 +1500,8 @@ class PostTest < ActiveSupport::TestCase
should "create a vote for each user who can vote" do
assert(@parent.votes.where(user: @gold1).exists?)
- assert_equal(1, @parent.score)
+ assert(@parent.votes.where(user: @user1).exists?)
+ assert_equal(2, @parent.score)
end
end
end
@@ -1523,13 +1548,13 @@ class PostTest < ActiveSupport::TestCase
end
context "Voting:" do
- should "not allow members to vote" do
+ should "allow members to vote" do
user = create(:user)
post = create(:post)
assert_nothing_raised { post.vote!(1, user) }
- assert_equal(0, post.votes.count)
- assert_equal(0, post.reload.score)
+ assert_equal(1, post.votes.count)
+ assert_equal(1, post.reload.score)
end
should "not allow duplicate votes" do