spec for showing users faving post

This commit is contained in:
Dylan Knutson
2025-08-16 19:09:48 +00:00
parent 87fda1a475
commit fd97d145cb
3 changed files with 223 additions and 4 deletions

View File

@@ -14,7 +14,11 @@ dependencies: []
Users need to quickly see how many files are contained in each post when browsing the gallery view, without having to click into each post to see the details.
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 File count is visually displayed on each post in gallery view,Count accurately reflects the actual number of files in the post,Count is clearly visible and doesn't interfere with existing UI elements,Count updates dynamically when post files are added or removed
- [ ] #2 File count is visually displayed on each post in gallery view,Count accurately reflects the actual number of files in the post,Count is clearly visible and doesn't interfere with existing UI elements,Count updates dynamically when post files are added or removed
- [ ] #1 File count is visually displayed on each post in gallery view
- [ ] #2 Count accurately reflects the actual number of files in the post
- [ ] #3 Count is clearly visible and doesn't interfere with existing UI elements
- [ ] #4 Count updates dynamically when post files are added or removed
<!-- AC:END -->

View File

@@ -14,7 +14,13 @@ dependencies: []
Clean up duplicate post files that have the same file_order value within a post by keeping only the most recent file with a successful 200 HTTP response code. This addresses data inconsistencies from multiple scraping attempts of the same file.
## Acceptance Criteria
<!-- AC:BEGIN -->
- [ ] #1 System identifies posts with multiple files having same file_order,System merges duplicates keeping most recent file with 200 status code,Duplicate files are properly deleted with cascading cleanup,File associations and metadata are preserved for kept files,Process handles edge cases like no files with 200 status,Data integrity is maintained throughout merge process
- [ ] #2 System identifies posts with multiple files having same file_order,System merges duplicates keeping most recent file with 200 status code,Duplicate files are properly deleted with cascading cleanup,File associations and metadata are preserved for kept files,Process handles edge cases like no files with 200 status code,Data integrity is maintained throughout merge process
- [ ] #1 System identifies posts with multiple files having same file_order
- [ ] #2 System merges duplicates keeping most recent file with 200 status code
- [ ] #3 Duplicate files are properly deleted with cascading cleanup
- [ ] #4 File associations and metadata are preserved for kept files
- [ ] #5 Process handles edge cases like no files with 200 status code
- [ ] #6 Data integrity is maintained throughout merge process
<!-- AC:END -->

View File

@@ -103,4 +103,213 @@ RSpec.describe Domain::UsersController, type: :controller do
end
end
end
describe "GET #users_faving_post" do
before do
# Mock authorization to allow all actions for these tests
allow(controller).to receive(:authorize).and_return(true)
end
# Shared examples for common users_faving_post behavior across all post types
shared_examples "users_faving_post action for post type" do |post_factory, param_prefix, param_attr|
let(:domain_post) { create(post_factory) }
let(:composite_param) do
"#{param_prefix}@#{domain_post.send(param_attr)}"
end
context "when post exists" do
context "with no faving users" do
it "returns a successful response" do
get :users_faving_post, params: { domain_post_id: composite_param }
expect(response).to be_successful
end
it "renders the index template" do
get :users_faving_post, params: { domain_post_id: composite_param }
expect(response).to render_template(:index)
end
it "sets the @post instance variable" do
get :users_faving_post, params: { domain_post_id: composite_param }
expect(assigns(:post)).to eq(domain_post)
end
it "sets the @index_type to users_faving_post" do
get :users_faving_post, params: { domain_post_id: composite_param }
expect(assigns(:index_type)).to eq(:users_faving_post)
end
it "sets empty @users collection" do
get :users_faving_post, params: { domain_post_id: composite_param }
expect(assigns(:users)).to be_empty
end
it "authorizes the post" do
expect(controller).to receive(:authorize).with(domain_post)
get :users_faving_post, params: { domain_post_id: composite_param }
end
end
context "with faving users" do
before { setup_faving_users }
it "returns users who have faved the post" do
get :users_faving_post, params: { domain_post_id: composite_param }
expect(assigns(:users)).to match_array(expected_faving_users)
end
it "includes avatar associations" do
get :users_faving_post, params: { domain_post_id: composite_param }
# Test that the query includes avatar associations (won't cause N+1)
expect(assigns(:users).first.association(:avatar)).to be_loaded
end
end
end
context "when post does not exist" do
let(:invalid_param) { "#{param_prefix}@999999" }
it "raises ActiveRecord::RecordNotFound" do
expect {
get :users_faving_post, params: { domain_post_id: invalid_param }
}.to raise_error(ActiveRecord::RecordNotFound)
end
end
context "with invalid composite parameter format" do
it "raises ActionController::BadRequest for malformed param" do
expect {
get :users_faving_post, params: { domain_post_id: "invalid_format" }
}.to raise_error(ActionController::BadRequest, /invalid id/)
end
it "raises ActionController::BadRequest for unknown model type" do
expect {
get :users_faving_post, params: { domain_post_id: "unknown@test" }
}.to raise_error(ActionController::BadRequest, /unknown model type/)
end
end
end
context "for Domain::Post::FaPost" do
let(:faving_user1) { create(:domain_user_fa_user) }
let(:faving_user2) { create(:domain_user_fa_user) }
let(:expected_faving_users) { [faving_user1, faving_user2] }
def setup_faving_users
# Create FA-specific user-post-fav relationships
Domain::UserPostFav::FaUserPostFav.create!(
user: faving_user1,
post: domain_post,
)
Domain::UserPostFav::FaUserPostFav.create!(
user: faving_user2,
post: domain_post,
)
end
include_examples "users_faving_post action for post type",
:domain_post_fa_post,
"fa",
:fa_id
end
context "for Domain::Post::E621Post" do
let(:faving_user1) { create(:domain_user_e621_user) }
let(:faving_user2) { create(:domain_user_e621_user) }
let(:expected_faving_users) { [faving_user1, faving_user2] }
def setup_faving_users
# Create E621-specific user-post-fav relationships
Domain::UserPostFav.create!(user: faving_user1, post: domain_post)
Domain::UserPostFav.create!(user: faving_user2, post: domain_post)
end
include_examples "users_faving_post action for post type",
:domain_post_e621_post,
"e621",
:e621_id
end
context "for Domain::Post::InkbunnyPost" do
let(:faving_user1) { create(:domain_user_inkbunny_user) }
let(:faving_user2) { create(:domain_user_inkbunny_user) }
let(:expected_faving_users) { [faving_user1, faving_user2] }
def setup_faving_users
# Create Inkbunny-specific user-post-fav relationships
Domain::UserPostFav.create!(user: faving_user1, post: domain_post)
Domain::UserPostFav.create!(user: faving_user2, post: domain_post)
end
include_examples "users_faving_post action for post type",
:domain_post_inkbunny_post,
"ib",
:ib_id
end
context "for Domain::Post::BlueskyPost" do
let(:faving_user_with_display_name) do
create(:domain_user_bluesky_user, display_name: "Cool Artist")
end
let(:faving_user_without_display_name) do
create(:domain_user_bluesky_user, display_name: nil)
end
let(:expected_faving_users) do
[faving_user_with_display_name, faving_user_without_display_name]
end
def setup_faving_users
# Create Bluesky-specific user-post-fav relationships
Domain::UserPostFav.create!(
user: faving_user_with_display_name,
post: domain_post,
)
Domain::UserPostFav.create!(
user: faving_user_without_display_name,
post: domain_post,
)
end
include_examples "users_faving_post action for post type",
:domain_post_bluesky_post,
"bsky",
:rkey
context "with display name variations" do
before do
# Create Bluesky-specific user-post-fav relationships
Domain::UserPostFav.create!(
user: faving_user_with_display_name,
post: domain_post,
)
Domain::UserPostFav.create!(
user: faving_user_without_display_name,
post: domain_post,
)
end
it "includes users with display names" do
get :users_faving_post,
params: {
domain_post_id: "bsky@#{domain_post.rkey}",
}
users = assigns(:users)
user_with_display = users.find { |u| u.display_name.present? }
expect(user_with_display.display_name).to eq("Cool Artist")
end
it "includes users without display names" do
get :users_faving_post,
params: {
domain_post_id: "bsky@#{domain_post.rkey}",
}
users = assigns(:users)
user_without_display = users.find { |u| u.display_name.blank? }
expect(user_without_display.display_name).to be_blank
expect(user_without_display.handle).to be_present
end
end
end
end
end