mirror of
https://github.com/discourse/discourse.git
synced 2026-08-06 13:08:40 +08:00
RSpec setup becomes harder to follow at either extreme: trivial fixture wrappers hide lifecycle and intent, while forcing every named operation inline repeats low-level protocol and configuration details. This change documents and applies a test-setup hierarchy: - use `fab!`, `let`, `let!`, `subject`, and inline `Fabricate` according to lifecycle and role; - use a small example-group method when parameterized behavior gives one spec useful vocabulary; - move helpers into auto-loaded `spec/support` only when they are shared across spec files; - use fabricators and page objects for the data shapes and system-test interfaces they own. Core and plugin support files are loaded centrally by `rails_helper`, so plugin-specific support loaders are unnecessary. The migration specs encountered during the sweep are removed according to repository policy; production migrations are unchanged.
190 lines
6.3 KiB
Ruby
Vendored
190 lines
6.3 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
RSpec.describe Jobs::DeliverPushNotification do
|
|
fab!(:user)
|
|
fab!(:post)
|
|
|
|
let(:payload) do
|
|
{
|
|
"notification_type" => 1,
|
|
"post_url" => "/t/#{post.topic_id}/#{post.post_number}",
|
|
"excerpt" => "Hello you",
|
|
}
|
|
end
|
|
|
|
before do
|
|
freeze_time
|
|
SiteSetting.push_notification_time_window_mins = 5
|
|
end
|
|
|
|
describe "time window gate" do
|
|
fab!(:time_window_push_subscription) { Fabricate(:push_subscription, user: user) }
|
|
|
|
it "does not deliver when user is missing" do
|
|
PushNotificationPusher.expects(:push).never
|
|
HubPushNotificationPusher.expects(:push).never
|
|
Jobs::DeliverPushNotification.new.execute(user_id: -999, payload: payload)
|
|
end
|
|
|
|
it "does not deliver when user was recently seen" do
|
|
user.update!(last_seen_at: 1.minute.ago)
|
|
PushNotificationPusher.expects(:push).never
|
|
HubPushNotificationPusher.expects(:push).never
|
|
Jobs::DeliverPushNotification.new.execute(user_id: user.id, payload: payload)
|
|
end
|
|
|
|
it "delivers when user is offline" do
|
|
user.update!(last_seen_at: 10.minutes.ago)
|
|
PushNotificationPusher.expects(:push).with(user, payload)
|
|
HubPushNotificationPusher.expects(:push).with(user, payload)
|
|
Jobs::DeliverPushNotification.new.execute(user_id: user.id, payload: payload)
|
|
end
|
|
|
|
it "delivers when bypass_time_window is true despite user being active" do
|
|
user.update!(last_seen_at: 1.minute.ago)
|
|
PushNotificationPusher.expects(:push).with(user, payload)
|
|
HubPushNotificationPusher.expects(:push).with(user, payload)
|
|
|
|
Jobs::DeliverPushNotification.new.execute(
|
|
user_id: user.id,
|
|
bypass_time_window: true,
|
|
payload: payload,
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "web push delivery" do
|
|
before { user.update!(last_seen_at: 10.minutes.ago) }
|
|
|
|
it "calls PushNotificationPusher when user has push subscriptions" do
|
|
Fabricate(:push_subscription, user: user)
|
|
PushNotificationPusher.expects(:push).with(user, payload).once
|
|
Jobs::DeliverPushNotification.new.execute(user_id: user.id, payload: payload)
|
|
end
|
|
|
|
it "does not call PushNotificationPusher when user has no push subscriptions" do
|
|
PushNotificationPusher.expects(:push).never
|
|
Jobs::DeliverPushNotification.new.execute(user_id: user.id, payload: payload)
|
|
end
|
|
end
|
|
|
|
describe "hub push delivery" do
|
|
before { user.update!(last_seen_at: 10.minutes.ago) }
|
|
|
|
it "calls HubPushNotificationPusher" do
|
|
HubPushNotificationPusher.expects(:push).with(user, payload).once
|
|
Jobs::DeliverPushNotification.new.execute(user_id: user.id, payload: payload)
|
|
end
|
|
end
|
|
|
|
describe "both mechanisms" do
|
|
it "delivers via both pushers for the same user" do
|
|
user.update!(last_seen_at: 10.minutes.ago)
|
|
Fabricate(:push_subscription, user: user)
|
|
|
|
PushNotificationPusher.expects(:push).with(user, payload).once
|
|
HubPushNotificationPusher.expects(:push).with(user, payload).once
|
|
|
|
Jobs::DeliverPushNotification.new.execute(user_id: user.id, payload: payload)
|
|
end
|
|
end
|
|
|
|
describe "content localization" do
|
|
fab!(:topic) { Fabricate(:topic, title: "Original topic title") }
|
|
fab!(:localized_post) { Fabricate(:post, topic: topic, raw: "Original post content") }
|
|
|
|
let(:localizable_payload) do
|
|
{
|
|
"notification_type" => 1,
|
|
"post_url" => "/t/#{topic.id}/#{localized_post.post_number}",
|
|
"topic_title" => topic.title,
|
|
"topic_id" => topic.id,
|
|
"post_id" => localized_post.id,
|
|
"excerpt" => "Original post content",
|
|
"username" => "system",
|
|
"post_number" => localized_post.post_number,
|
|
}
|
|
end
|
|
|
|
before do
|
|
SiteSetting.content_localization_enabled = true
|
|
SiteSetting.allow_user_locale = true
|
|
user.update!(last_seen_at: 10.minutes.ago, locale: "ja")
|
|
end
|
|
|
|
it "localizes payload before delivering to web push" do
|
|
Fabricate(:push_subscription, user: user)
|
|
Fabricate(
|
|
:topic_localization,
|
|
topic: topic,
|
|
locale: "ja",
|
|
title: "ローカライズされたトピック",
|
|
fancy_title: "ローカライズされたトピック",
|
|
)
|
|
Fabricate(
|
|
:post_localization,
|
|
post: localized_post,
|
|
locale: "ja",
|
|
raw: "ローカライズされた投稿",
|
|
cooked: "<p>ローカライズされた投稿</p>",
|
|
)
|
|
|
|
PushNotificationPusher
|
|
.expects(:push)
|
|
.with { |u, p| p[:topic_title] == "ローカライズされたトピック" && p[:excerpt] == "ローカライズされた投稿" }
|
|
.once
|
|
|
|
Jobs::DeliverPushNotification.new.execute(user_id: user.id, payload: localizable_payload)
|
|
end
|
|
|
|
it "localizes payload before delivering to hub push" do
|
|
SiteSetting.allowed_user_api_push_urls = "https://hub.example.com/push"
|
|
client = Fabricate(:user_api_key_client)
|
|
Fabricate(
|
|
:user_api_key,
|
|
user: user,
|
|
scopes: ["notifications"].map { |name| UserApiKeyScope.new(name: name) },
|
|
push_url: "https://hub.example.com/push",
|
|
user_api_key_client_id: client.id,
|
|
)
|
|
Fabricate(
|
|
:topic_localization,
|
|
topic: topic,
|
|
locale: "ja",
|
|
title: "ローカライズされたトピック",
|
|
fancy_title: "ローカライズされたトピック",
|
|
)
|
|
|
|
body = nil
|
|
stub_request(:post, "https://hub.example.com/push").to_return do |request|
|
|
body = JSON.parse(request.body)
|
|
{ status: 200 }
|
|
end
|
|
|
|
Jobs::DeliverPushNotification.new.execute(user_id: user.id, payload: localizable_payload)
|
|
|
|
expect(body["notifications"].first["topic_title"]).to eq("ローカライズされたトピック")
|
|
end
|
|
|
|
it "does not localize when content_localization_enabled is false" do
|
|
SiteSetting.content_localization_enabled = false
|
|
Fabricate(:push_subscription, user: user)
|
|
Fabricate(
|
|
:topic_localization,
|
|
topic: topic,
|
|
locale: "ja",
|
|
title: "ローカライズされたトピック",
|
|
fancy_title: "ローカライズされたトピック",
|
|
)
|
|
|
|
PushNotificationPusher
|
|
.expects(:push)
|
|
.with do |u, p|
|
|
p[:topic_title] == "Original topic title" || p["topic_title"] == "Original topic title"
|
|
end
|
|
.once
|
|
|
|
Jobs::DeliverPushNotification.new.execute(user_id: user.id, payload: localizable_payload)
|
|
end
|
|
end
|
|
end
|