Files
sanasto-wiki/test/integration/entry_request_flow_test.rb
Runar Ingebrigtsen 530021960e
CI / scan_ruby (push) Failing after 12s
CI / scan_js (push) Successful in 11s
CI / lint (push) Failing after 19s
CI / test (push) Successful in 34s
add entry requests, invite new users
2026-01-30 01:28:53 +01:00

241 lines
6.0 KiB
Ruby

require "test_helper"
class EntryRequestFlowTest < ActionDispatch::IntegrationTest
test "complete flow: request -> admin approve -> user accepts -> entry active" do
# Step 1: Public user submits entry request
assert_difference(["User.count", "Entry.count"], 1) do
post requests_path, params: {
entry: {
name: "Flow Test User",
email: "flowtest@example.com",
category: "word",
fi: "testi",
en: "test",
notes: "Testing complete flow"
}
}
end
assert_redirected_to root_path
follow_redirect!
assert_response :success
entry = Entry.last
user = User.last
assert_equal "requested", entry.status
assert_equal user, entry.requested_by
assert_nil user.invitation_token
# Step 2: Admin reviews and approves request
admin = users(:admin_user)
login_as(admin)
get admin_requests_path
assert_response :success
assert_select "td", text: entry.fi
# View the request
get admin_request_path(entry)
assert_response :success
assert_select "div", text: entry.fi
# Approve the request
assert_enqueued_emails 1 do
post approve_admin_request_path(entry)
end
entry.reload
user.reload
assert_equal "approved", entry.status
assert_not_nil user.invitation_token
assert_not_nil user.invitation_sent_at
assert_equal admin, user.invited_by
# Verify the invitation email includes entry information
perform_enqueued_jobs
sent_email = ActionMailer::Base.deliveries.last
assert_match "Your entry request has been approved", sent_email.subject
assert_match entry.fi, sent_email.body.encoded
assert_match entry.en, sent_email.body.encoded
logout
# Step 3: User accepts invitation
get invitation_path(user.invitation_token)
assert_response :success
patch accept_invitation_path(user.invitation_token), params: {
user: {
password: "securepassword123",
password_confirmation: "securepassword123"
}
}
entry.reload
user.reload
# Entry should now be active
assert_equal "active", entry.status
assert_not_nil user.invitation_accepted_at
assert_nil user.invitation_token
assert_equal user.id, session[:user_id]
# Step 4: Verify entry is visible on public site
get root_path
assert_response :success
# Entry should be in search results
end
test "rejected request removes entry and user" do
# Create a request
post requests_path, params: {
entry: {
name: "To Be Rejected",
email: "rejected@example.com",
category: "word",
fi: "hylätty",
en: "rejected"
}
}
assert_redirected_to root_path
entry = Entry.last
user = User.last
entry_id = entry.id
user_id = user.id
# Admin rejects it
login_as(users(:admin_user))
assert_difference(["User.count", "Entry.count"], -1) do
delete reject_admin_request_path(entry)
end
assert_not Entry.exists?(entry_id)
assert_not User.exists?(user_id)
end
test "requested and approved entries not visible on public site" do
requested = entries(:requested_entry)
approved = entries(:approved_entry)
active = entries(:one)
get root_path
assert_response :success
# Active entry should be counted
assert_match /#{Entry.active_entries.count}/, response.body
# Verify counts exclude requested/approved entries
total_entries = Entry.count
active_entries = Entry.active_entries.count
assert total_entries > active_entries, "Should have non-active entries in fixtures"
end
test "multiple entries by same requester all activated on invitation acceptance" do
# Create user with multiple approved entries
user = User.create!(
name: "Multi Entry User",
email: "multi@example.com",
password: SecureRandom.alphanumeric(32),
role: :contributor,
invitation_token: "multi_token_123",
invitation_sent_at: 1.day.ago,
invited_by: users(:admin_user)
)
entry1 = Entry.create!(
category: :word,
fi: "sana1",
en: "word1",
status: :approved,
requested_by: user
)
entry2 = Entry.create!(
category: :phrase,
fi: "fraasi1",
en: "phrase1",
status: :approved,
requested_by: user
)
# User accepts invitation
patch accept_invitation_path("multi_token_123"), params: {
user: {
password: "securepassword123",
password_confirmation: "securepassword123"
}
}
entry1.reload
entry2.reload
assert_equal "active", entry1.status
assert_equal "active", entry2.status
end
test "admin can edit entry details before approval" do
# Create a request
post requests_path, params: {
entry: {
name: "Needs Editing",
email: "edit@example.com",
category: "word",
fi: "väärin kirjoitettu",
en: "wrong spelling"
}
}
assert_redirected_to root_path
entry = Entry.last
# Admin edits the entry
login_as(users(:admin_user))
get edit_admin_request_path(entry)
assert_response :success
patch admin_request_path(entry), params: {
entry: {
fi: "oikein kirjoitettu",
en: "correct spelling",
category: "phrase"
}
}
entry.reload
assert_equal "oikein kirjoitettu", entry.fi
assert_equal "correct spelling", entry.en
assert_equal "phrase", entry.category
# Then approve with corrected details
post approve_admin_request_path(entry)
entry.reload
assert_equal "approved", entry.status
assert_equal "oikein kirjoitettu", entry.fi
end
test "cannot submit request with existing user email" do
existing_user = users(:contributor_user)
post requests_path, params: {
entry: {
name: "Test",
email: existing_user.email,
category: "word",
fi: "test"
}
}
assert_redirected_to login_path
assert_match(/already exists/i, flash[:alert])
end
end