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)
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"
# this info is always available cause it can be scraped from a 404 page

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
module Jobs
class VersionCheck < ::Jobs::Scheduled
class CallDiscourseHub < ::Jobs::Scheduled
every 1.day
def execute(args)
@ -27,6 +27,8 @@ module Jobs
raise e unless Rails.env.development? # Fail version check silently in development mode
end
end
DiscourseHub.discover_enrollment if SiteSetting.include_in_discourse_discover?
true
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("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("discourse_discover", show_in_ui: false, expose_via_api: true) do
Statistics.discourse_discover
end,
]
end

View File

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

View File

@ -14,6 +14,14 @@ module DiscourseHub
get("/version_check", version_check_payload)
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)
Discourse.redis.set STATS_FETCHED_AT_KEY, time_with_zone.to_i
end

View File

@ -41,7 +41,7 @@ module DiscourseUpdates
# 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
is_stale_data
Jobs.enqueue(:version_check, all_sites: true)
Jobs.enqueue(:call_discourse_hub, all_sites: true)
version_info.version_check_pending = true
unless version_info.updated_at.nil?

View File

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

View File

@ -17,7 +17,7 @@ task periodical_updates: :environment do
end
task version_check: :environment do
Jobs::VersionCheck.new.execute(nil)
Jobs::CallDiscourseHub.new.execute(nil)
end
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
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 "when Discourse Hub has not fetched stats since past 7 days" do
it "should include stats" do

View File

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

View File

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

View File

@ -48,6 +48,17 @@ RSpec.describe AboutController do
expect(response.parsed_body["about"].keys).to include("stats")
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
Guardian.any_instance.stubs(:can_see_about_stats?).returns(false)
get "/about.json"

View File

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

View File

@ -6,7 +6,7 @@ RSpec.describe Admin::VersionsController do
fab!(:user)
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(:latest_version).returns("1.2.33")
DiscourseUpdates.stubs(:critical_updates_available?).returns(false)

View File

@ -12,6 +12,7 @@ RSpec.describe SiteController do
SiteSetting.logo_small = upload
SiteSetting.apple_touch_icon = upload
SiteSetting.mobile_logo = upload
SiteSetting.include_in_discourse_discover = true
Theme.clear_default!
get "/site/basic-info.json"
@ -28,6 +29,16 @@ RSpec.describe SiteController do
expect(json["header_primary_color"]).to eq("333333")
expect(json["header_background_color"]).to eq("ffffff")
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
@ -56,6 +67,16 @@ RSpec.describe SiteController do
expect(json["likes_30_days"]).to be_present
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
SiteSetting.share_anonymized_statistics = false