FEATURE: call hub API to update Discourse discover enrollment. (#25634)

Now forums can enroll their sites to be showcased in the Discourse [Discover](https://discourse.org/discover) directory. Once they enable the site setting `include_in_discourse_discover` to enroll their forum the `CallDiscourseHub` job will ping the `api.discourse.org/api/discover/enroll` endpoint. Then the Discourse Hub will fetch the basic details from the forum and add it to the review queue. If the site is approved then the forum details will be displayed in the `/discover` page.
This commit is contained in:
Vinoth Kannan 2024-02-23 11:42:28 +05:30 committed by GitHub
parent 207cb2052f
commit b3238bfc34
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 102 additions and 9 deletions

View File

@ -42,6 +42,8 @@ class SiteController < ApplicationController
results[:mobile_logo_url] = UrlHelper.absolute(mobile_logo_url) results[:mobile_logo_url] = UrlHelper.absolute(mobile_logo_url)
end end
results[:discourse_discover_enrolled] = true if SiteSetting.include_in_discourse_discover?
DiscourseHub.stats_fetched_at = Time.zone.now if request.user_agent == "Discourse Hub" DiscourseHub.stats_fetched_at = Time.zone.now if request.user_agent == "Discourse Hub"
# this info is always available cause it can be scraped from a 404 page # this info is always available cause it can be scraped from a 404 page

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
module Jobs module Jobs
class VersionCheck < ::Jobs::Scheduled class CallDiscourseHub < ::Jobs::Scheduled
every 1.day every 1.day
def execute(args) def execute(args)
@ -27,6 +27,8 @@ module Jobs
raise e unless Rails.env.development? # Fail version check silently in development mode raise e unless Rails.env.development? # Fail version check silently in development mode
end end
end end
DiscourseHub.discover_enrollment if SiteSetting.include_in_discourse_discover?
true true
end end
end end

View File

@ -46,6 +46,9 @@ class Stat
Stat.new("users", show_in_ui: true, expose_via_api: true) { Statistics.users }, Stat.new("users", show_in_ui: true, expose_via_api: true) { Statistics.users },
Stat.new("active_users", show_in_ui: true, expose_via_api: true) { Statistics.active_users }, Stat.new("active_users", show_in_ui: true, expose_via_api: true) { Statistics.active_users },
Stat.new("likes", show_in_ui: true, expose_via_api: true) { Statistics.likes }, Stat.new("likes", show_in_ui: true, expose_via_api: true) { Statistics.likes },
Stat.new("discourse_discover", show_in_ui: false, expose_via_api: true) do
Statistics.discourse_discover
end,
] ]
end end

View File

@ -23,7 +23,8 @@ class AboutSerializer < ApplicationSerializer
:https, :https,
:can_see_about_stats, :can_see_about_stats,
:contact_url, :contact_url,
:contact_email :contact_email,
:discourse_discover_enrolled
def include_stats? def include_stats?
can_see_about_stats can_see_about_stats
@ -49,6 +50,14 @@ class AboutSerializer < ApplicationSerializer
SiteSetting.contact_email SiteSetting.contact_email
end end
def discourse_discover_enrolled
SiteSetting.include_in_discourse_discover?
end
def include_discourse_discover_enrolled?
SiteSetting.include_in_discourse_discover?
end
private private
def can_see_about_stats def can_see_about_stats

View File

@ -14,6 +14,14 @@ module DiscourseHub
get("/version_check", version_check_payload) get("/version_check", version_check_payload)
end end
def self.discover_enrollment_payload
{ include_in_discourse_discover: SiteSetting.include_in_discourse_discover? }
end
def self.discover_enrollment
post("/discover/enroll", discover_enrollment_payload)
end
def self.stats_fetched_at=(time_with_zone) def self.stats_fetched_at=(time_with_zone)
Discourse.redis.set STATS_FETCHED_AT_KEY, time_with_zone.to_i Discourse.redis.set STATS_FETCHED_AT_KEY, time_with_zone.to_i
end end

View File

@ -41,7 +41,7 @@ module DiscourseUpdates
# Handle cases when version check data is old so we report something that makes sense # Handle cases when version check data is old so we report something that makes sense
if version_info.updated_at.nil? || last_installed_version != Discourse::VERSION::STRING || # never performed a version check # upgraded since the last version check if version_info.updated_at.nil? || last_installed_version != Discourse::VERSION::STRING || # never performed a version check # upgraded since the last version check
is_stale_data is_stale_data
Jobs.enqueue(:version_check, all_sites: true) Jobs.enqueue(:call_discourse_hub, all_sites: true)
version_info.version_check_pending = true version_info.version_check_pending = true
unless version_info.updated_at.nil? unless version_info.updated_at.nil?

View File

@ -47,4 +47,8 @@ class Statistics
count: User.real.count, count: User.real.count,
} }
end end
def self.discourse_discover
{ enrolled: SiteSetting.include_in_discourse_discover? }
end
end end

View File

@ -17,7 +17,7 @@ task periodical_updates: :environment do
end end
task version_check: :environment do task version_check: :environment do
Jobs::VersionCheck.new.execute(nil) Jobs::CallDiscourseHub.new.execute(nil)
end end
desc "run every task the scheduler knows about in that order, use only for debugging" desc "run every task the scheduler knows about in that order, use only for debugging"

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
RSpec.describe Jobs::CallDiscourseHub do
describe "#execute" do
context "when `include_in_discourse_discover setting` enabled" do
it "calls `discover_enrollment` method in DiscourseHub" do
SiteSetting.version_checks = false
SiteSetting.include_in_discourse_discover = true
DiscourseHub.stubs(:discover_enrollment).returns(true)
described_class.new.execute({})
end
end
end
end

View File

@ -17,6 +17,22 @@ RSpec.describe DiscourseHub do
end end
end end
describe ".discover_enrollment" do
it "should trigger a POST request to hub" do
stub_request(
:post,
(ENV["HUB_BASE_URL"] || "http://local.hub:3000/api") + "/discover/enroll",
).with(body: JSON[DiscourseHub.discover_enrollment_payload]).to_return(
status: 200,
body: "",
headers: {
},
)
DiscourseHub.discover_enrollment
end
end
describe ".version_check_payload" do describe ".version_check_payload" do
describe "when Discourse Hub has not fetched stats since past 7 days" do describe "when Discourse Hub has not fetched stats since past 7 days" do
it "should include stats" do it "should include stats" do

View File

@ -67,7 +67,7 @@ RSpec.describe DiscourseUpdates do
end end
it "queues a version check" do it "queues a version check" do
expect_enqueued_with(job: :version_check) { version } expect_enqueued_with(job: :call_discourse_hub) { version }
end end
end end
@ -76,7 +76,7 @@ RSpec.describe DiscourseUpdates do
context "with old version check data" do context "with old version check data" do
shared_examples "queue version check and report that version is ok" do shared_examples "queue version check and report that version is ok" do
it "queues a version check" do it "queues a version check" do
expect_enqueued_with(job: :version_check) { version } expect_enqueued_with(job: :call_discourse_hub) { version }
end end
it "reports 0 missing versions" do it "reports 0 missing versions" do
@ -105,7 +105,7 @@ RSpec.describe DiscourseUpdates do
shared_examples "when last_installed_version is old" do shared_examples "when last_installed_version is old" do
it "queues a version check" do it "queues a version check" do
expect_enqueued_with(job: :version_check) { version } expect_enqueued_with(job: :call_discourse_hub) { version }
end end
it "reports 0 missing versions" do it "reports 0 missing versions" do

View File

@ -103,6 +103,7 @@ TEXT
:likes_7_days, :likes_7_days,
:likes_30_days, :likes_30_days,
:likes_count, :likes_count,
:discourse_discover_enrolled,
) )
end end

View File

@ -48,6 +48,17 @@ RSpec.describe AboutController do
expect(response.parsed_body["about"].keys).to include("stats") expect(response.parsed_body["about"].keys).to include("stats")
end end
it "adds Discourse Discover status if enabled" do
get "/about.json"
expect(response.parsed_body["about"].keys).not_to include("discourse_discover_enrolled")
SiteSetting.include_in_discourse_discover = true
get "/about.json"
expect(response.parsed_body["about"]["discourse_discover_enrolled"]).to eq(true)
end
it "does not serialize stats when 'Guardian#can_see_about_stats?' is false" do it "does not serialize stats when 'Guardian#can_see_about_stats?' is false" do
Guardian.any_instance.stubs(:can_see_about_stats?).returns(false) Guardian.any_instance.stubs(:can_see_about_stats?).returns(false)
get "/about.json" get "/about.json"

View File

@ -7,7 +7,7 @@ RSpec.describe Admin::DashboardController do
before do before do
AdminDashboardData.stubs(:fetch_cached_stats).returns(reports: []) AdminDashboardData.stubs(:fetch_cached_stats).returns(reports: [])
Jobs::VersionCheck.any_instance.stubs(:execute).returns(true) Jobs::CallDiscourseHub.any_instance.stubs(:execute).returns(true)
end end
def populate_new_features(date1 = nil, date2 = nil) def populate_new_features(date1 = nil, date2 = nil)

View File

@ -6,7 +6,7 @@ RSpec.describe Admin::VersionsController do
fab!(:user) fab!(:user)
before do before do
Jobs::VersionCheck.any_instance.stubs(:execute).returns(true) Jobs::CallDiscourseHub.any_instance.stubs(:execute).returns(true)
DiscourseUpdates.stubs(:updated_at).returns(2.hours.ago) DiscourseUpdates.stubs(:updated_at).returns(2.hours.ago)
DiscourseUpdates.stubs(:latest_version).returns("1.2.33") DiscourseUpdates.stubs(:latest_version).returns("1.2.33")
DiscourseUpdates.stubs(:critical_updates_available?).returns(false) DiscourseUpdates.stubs(:critical_updates_available?).returns(false)

View File

@ -12,6 +12,7 @@ RSpec.describe SiteController do
SiteSetting.logo_small = upload SiteSetting.logo_small = upload
SiteSetting.apple_touch_icon = upload SiteSetting.apple_touch_icon = upload
SiteSetting.mobile_logo = upload SiteSetting.mobile_logo = upload
SiteSetting.include_in_discourse_discover = true
Theme.clear_default! Theme.clear_default!
get "/site/basic-info.json" get "/site/basic-info.json"
@ -28,6 +29,16 @@ RSpec.describe SiteController do
expect(json["header_primary_color"]).to eq("333333") expect(json["header_primary_color"]).to eq("333333")
expect(json["header_background_color"]).to eq("ffffff") expect(json["header_background_color"]).to eq("ffffff")
expect(json["login_required"]).to eq(true) expect(json["login_required"]).to eq(true)
expect(json["discourse_discover_enrolled"]).to eq(true)
end
it "skips `discourse_discover_enrolled` if `include_in_discourse_discover` setting disabled" do
SiteSetting.include_in_discourse_discover = false
get "/site/basic-info.json"
json = response.parsed_body
expect(json.keys).not_to include("discourse_discover_enrolled")
end end
end end
@ -56,6 +67,16 @@ RSpec.describe SiteController do
expect(json["likes_30_days"]).to be_present expect(json["likes_30_days"]).to be_present
end end
it "returns Discourse Discover stats" do
SiteSetting.include_in_discourse_discover = true
About.refresh_stats
get "/site/statistics.json"
json = response.parsed_body
expect(json["discourse_discover_enrolled"]).to be_truthy
end
it "is not visible if site setting share_anonymized_statistics is disabled" do it "is not visible if site setting share_anonymized_statistics is disabled" do
SiteSetting.share_anonymized_statistics = false SiteSetting.share_anonymized_statistics = false