mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-09 08:10:08 +09:00
6e312c6028
Banning a user deletes their sessions and closes their connections but keeps their push subscriptions, and Room::MessagePusher chose recipients by membership alone. A banned user's browser or phone therefore went on receiving the room name, sender and text of new direct messages, mentions, and messages in rooms they had set to everything. Choose subscriptions from active users only. The subscriptions are kept, so unbanning brings notifications back without the user having to subscribe again (the client doesn't resubscribe while the browser still holds a subscription). Co-authored-by: Marcello Costagliola <176920116+namespaceMarcello@users.noreply.github.com>
121 lines
4.3 KiB
Ruby
121 lines
4.3 KiB
Ruby
require "test_helper"
|
|
|
|
class Room::PushTest < ActiveSupport::TestCase
|
|
include ActiveJob::TestHelper
|
|
|
|
setup do
|
|
stub_web_push_dns_resolution
|
|
end
|
|
|
|
test "deliver new message to other room users with push subscriptions" do
|
|
task_count = Push::Subscription.count - users(:david).push_subscriptions.count
|
|
perform_enqueued_jobs only: Room::PushMessageJob do
|
|
WebPush.expects(:payload_send).times(task_count)
|
|
rooms(:hq).messages.create! body: "This is from earth", client_message_id: "earth", creator: users(:david)
|
|
end
|
|
wait_for_web_push_delivery_pool_tasks(task_count)
|
|
end
|
|
|
|
test "notifies subscribed users" do
|
|
perform_enqueued_jobs only: Room::PushMessageJob do
|
|
WebPush.expects(:payload_send).times(2)
|
|
rooms(:designers).messages.create! body: "This is from earth", client_message_id: "earth", creator: users(:david)
|
|
end
|
|
wait_for_web_push_delivery_pool_tasks(2)
|
|
|
|
perform_enqueued_jobs only: Room::PushMessageJob do
|
|
WebPush.expects(:payload_send).times(3)
|
|
rooms(:designers).messages.create! body: "Hey #{mention_attachment_for(:kevin)}", client_message_id: "earth", creator: users(:david)
|
|
end
|
|
wait_for_web_push_delivery_pool_tasks(5)
|
|
end
|
|
|
|
test "does not notify for connected rooms" do
|
|
memberships(:kevin_designers).connected
|
|
|
|
perform_enqueued_jobs only: Room::PushMessageJob do
|
|
WebPush.expects(:payload_send).times(2)
|
|
rooms(:designers).messages.create! body: "Hey @kevin", client_message_id: "earth", creator: users(:david)
|
|
end
|
|
wait_for_web_push_delivery_pool_tasks(2)
|
|
end
|
|
|
|
test "does not notify for invisible rooms" do
|
|
memberships(:kevin_designers).update! involvement: "invisible"
|
|
|
|
perform_enqueued_jobs only: Room::PushMessageJob do
|
|
WebPush.expects(:payload_send).times(2)
|
|
rooms(:designers).messages.create! body: "Hey @kevin", client_message_id: "earth", creator: users(:david)
|
|
end
|
|
wait_for_web_push_delivery_pool_tasks(2)
|
|
end
|
|
|
|
test "destroys invalid subscriptions" do
|
|
memberships(:kevin_designers).update! involvement: "invisible"
|
|
|
|
assert_difference -> { Push::Subscription.count }, -2 do
|
|
perform_enqueued_jobs only: Room::PushMessageJob do
|
|
WebPush.expects(:payload_send).times(2).raises(WebPush::ExpiredSubscription.new(Struct.new(:body).new, "example.com"))
|
|
rooms(:designers).messages.create! body: "Hey @kevin", client_message_id: "earth", creator: users(:david)
|
|
end
|
|
wait_for_web_push_delivery_pool_tasks(2)
|
|
wait_for_invalidation_pool_tasks(2)
|
|
end
|
|
end
|
|
|
|
test "does not notify banned users" do
|
|
users(:kevin).ban
|
|
|
|
assert_not_includes pushed_users { post_to_designers_mentioning_kevin }, users(:kevin)
|
|
end
|
|
|
|
test "notifies users again once they're unbanned" do
|
|
users(:kevin).ban
|
|
users(:kevin).unban
|
|
|
|
assert_includes pushed_users { post_to_designers_mentioning_kevin }, users(:kevin)
|
|
end
|
|
|
|
test "does not notify banned users of direct messages" do
|
|
users(:kevin).ban
|
|
|
|
pushed = pushed_users do
|
|
rooms(:david_and_kevin).messages.create! body: "Just between us", client_message_id: "earth", creator: users(:david)
|
|
end
|
|
assert_not_includes pushed, users(:kevin)
|
|
end
|
|
|
|
test "notifies active users mentioned" do
|
|
assert_includes pushed_users { post_to_designers_mentioning_kevin }, users(:kevin)
|
|
end
|
|
|
|
private
|
|
def post_to_designers_mentioning_kevin
|
|
rooms(:designers).messages.create! body: "Hey #{mention_attachment_for(:kevin)}", client_message_id: "earth", creator: users(:david)
|
|
end
|
|
|
|
def pushed_users(&block)
|
|
queued = []
|
|
Rails.configuration.x.web_push_pool.stubs(:queue).with { |_payload, subscriptions| queued.concat subscriptions.to_a }
|
|
perform_enqueued_jobs(only: Room::PushMessageJob, &block)
|
|
queued.map(&:user).uniq
|
|
end
|
|
|
|
def wait_for_web_push_delivery_pool_tasks(count)
|
|
wait_for_pool_tasks(Rails.configuration.x.web_push_pool.delivery_pool, count)
|
|
end
|
|
|
|
def wait_for_invalidation_pool_tasks(count)
|
|
wait_for_pool_tasks(Rails.configuration.x.web_push_pool.invalidation_pool, count)
|
|
end
|
|
|
|
def wait_for_pool_tasks(pool, count)
|
|
start = Time.now
|
|
timeout = 0.2
|
|
while pool.completed_task_count < count
|
|
raise "Timeout waiting for pool tasks to complete" if Time.now - start > timeout
|
|
sleep timeout / 10.0
|
|
end
|
|
end
|
|
end
|