Skip to content

Commit 56b5920

Browse files
authored
DEV: Add multisite tests (#207)
1 parent 3aa3772 commit 56b5920

File tree

4 files changed

+155
-47
lines changed

4 files changed

+155
-47
lines changed

app/jobs/discourse_activity_pub_deliver.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ def perform_request
3434
if request&.post_json_ld
3535
@delivered = true
3636
else
37+
return if ENV["ACTIVITY_PUB_DISABLE_DELIVERY_RETRIES"]
38+
3739
retry_count += 1
3840
return if retry_count > MAX_RETRY_COUNT
3941

spec/integration/integration_cases_spec.rb

Lines changed: 25 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,9 @@
11
# frozen_string_literal: true
22
RSpec.describe "integration cases" do
3-
def read_json(case_name, file_name)
4-
JSON.parse(
5-
File.open(
6-
File.join(
7-
File.expand_path("../..", __dir__),
8-
"spec",
9-
"fixtures",
10-
"integration",
11-
case_name,
12-
"#{file_name}.json",
13-
),
14-
).read,
15-
).with_indifferent_access
16-
end
17-
183
describe "#case 1" do
194
let!(:actor) { Fabricate(:discourse_activity_pub_actor_group) }
205
let!(:remote_actor) do
21-
json = read_json("case_1", "group_actor")
6+
json = read_integration_json("case_1", "group_actor")
227
Fabricate(:discourse_activity_pub_actor_group, ap_id: json[:id], local: false)
238
end
249
let!(:follow) do
@@ -30,24 +15,24 @@ def read_json(case_name, file_name)
3015
Jobs.run_immediately!
3116
SiteSetting.activity_pub_require_signed_requests = false
3217

33-
stub_object_request(read_json("case_1", "group_actor"))
34-
stub_object_request(read_json("case_1", "actor_1"))
35-
stub_object_request(read_json("case_1", "actor_2"))
36-
stub_object_request(read_json("case_1", "actor_3"))
37-
stub_object_request(read_json("case_1", "actor_4"))
38-
stub_object_request(read_json("case_1", "actor_5"))
39-
stub_object_request(read_json("case_1", "context_1"))
18+
stub_object_request(read_integration_json("case_1", "group_actor"))
19+
stub_object_request(read_integration_json("case_1", "actor_1"))
20+
stub_object_request(read_integration_json("case_1", "actor_2"))
21+
stub_object_request(read_integration_json("case_1", "actor_3"))
22+
stub_object_request(read_integration_json("case_1", "actor_4"))
23+
stub_object_request(read_integration_json("case_1", "actor_5"))
24+
stub_object_request(read_integration_json("case_1", "context_1"))
4025

41-
post_to_inbox(actor, body: read_json("case_1", "received_1"))
42-
post_to_inbox(actor, body: read_json("case_1", "received_2"))
43-
post_to_inbox(actor, body: read_json("case_1", "received_3"))
44-
post_to_inbox(actor, body: read_json("case_1", "received_4"))
45-
post_to_inbox(actor, body: read_json("case_1", "received_5"))
46-
post_to_inbox(actor, body: read_json("case_1", "received_6"))
47-
post_to_inbox(actor, body: read_json("case_1", "received_7"))
48-
post_to_inbox(actor, body: read_json("case_1", "received_8"))
49-
post_to_inbox(actor, body: read_json("case_1", "received_9"))
50-
post_to_inbox(actor, body: read_json("case_1", "received_10"))
26+
post_to_inbox(actor, body: read_integration_json("case_1", "received_1"))
27+
post_to_inbox(actor, body: read_integration_json("case_1", "received_2"))
28+
post_to_inbox(actor, body: read_integration_json("case_1", "received_3"))
29+
post_to_inbox(actor, body: read_integration_json("case_1", "received_4"))
30+
post_to_inbox(actor, body: read_integration_json("case_1", "received_5"))
31+
post_to_inbox(actor, body: read_integration_json("case_1", "received_6"))
32+
post_to_inbox(actor, body: read_integration_json("case_1", "received_7"))
33+
post_to_inbox(actor, body: read_integration_json("case_1", "received_8"))
34+
post_to_inbox(actor, body: read_integration_json("case_1", "received_9"))
35+
post_to_inbox(actor, body: read_integration_json("case_1", "received_10"))
5136
end
5237

5338
it "creates the right Discourse objects" do
@@ -75,7 +60,7 @@ def read_json(case_name, file_name)
7560
describe "#case 2" do
7661
let!(:actor) { Fabricate(:discourse_activity_pub_actor_group) }
7762
let!(:remote_actor) do
78-
json = read_json("case_2", "group_actor")
63+
json = read_integration_json("case_2", "group_actor")
7964
Fabricate(:discourse_activity_pub_actor_group, ap_id: json[:id], local: false)
8065
end
8166
let!(:follow) do
@@ -87,22 +72,15 @@ def read_json(case_name, file_name)
8772
Jobs.run_immediately!
8873
SiteSetting.activity_pub_require_signed_requests = false
8974

90-
stub_object_request(read_json("case_2", "group_actor"))
91-
stub_object_request(read_json("case_2", "actor_1"))
92-
stub_object_request(read_json("case_2", "actor_2"))
93-
stub_object_request(read_json("case_2", "actor_3"))
94-
stub_object_request(read_json("case_2", "context_1"))
75+
stub_object_request(read_integration_json("case_2", "group_actor"))
76+
stub_object_request(read_integration_json("case_2", "actor_1"))
77+
stub_object_request(read_integration_json("case_2", "actor_2"))
78+
stub_object_request(read_integration_json("case_2", "actor_3"))
79+
stub_object_request(read_integration_json("case_2", "context_1"))
9580

96-
threads = []
97-
results = []
9881
6.times do |index|
99-
threads << Thread.new do
100-
post_to_inbox(actor, body: read_json("case_2", "received_#{index + 1}"))
101-
results << response
102-
sleep 0.01
103-
end
82+
post_to_inbox(actor, body: read_integration_json("case_2", "received_#{index + 1}"))
10483
end
105-
threads.each(&:join)
10684
end
10785

10886
it "creates the right Discourse objects" do
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe "ActivityPub Multisite", type: :multisite do
4+
before { Jobs.run_immediately! }
5+
6+
context "when processing" do
7+
def fabricate_follow(actor)
8+
remote_actor_json = read_integration_json("case_2", "group_actor")
9+
remote_actor =
10+
Fabricate(:discourse_activity_pub_actor_group, ap_id: remote_actor_json[:id], local: false)
11+
Fabricate(:discourse_activity_pub_follow, follower: actor, followed: remote_actor)
12+
end
13+
14+
def process_json(json, actor)
15+
Jobs::DiscourseActivityPubProcess.new.execute(json: json, delivered_to: actor.ap_id)
16+
end
17+
18+
def process_case(actor)
19+
stub_object_request(read_integration_json("case_2", "group_actor"))
20+
stub_object_request(read_integration_json("case_2", "actor_1"))
21+
stub_object_request(read_integration_json("case_2", "actor_2"))
22+
stub_object_request(read_integration_json("case_2", "actor_3"))
23+
stub_object_request(read_integration_json("case_2", "context_1"))
24+
25+
6.times do |index|
26+
process_json(read_integration_json("case_2", "received_#{index + 1}"), actor)
27+
end
28+
end
29+
30+
it "creates the right objects" do
31+
test_multisite_connection("default") do
32+
actor = Fabricate(:discourse_activity_pub_actor_group)
33+
fabricate_follow(actor)
34+
toggle_activity_pub(actor.model, publication_type: "full_topic")
35+
36+
process_case(actor)
37+
38+
posts = Post.all
39+
topics = Topic.all
40+
expect(posts.size).to eq(1)
41+
expect(topics.size).to eq(1)
42+
expect(posts.first.topic_id).to eq(topics.first.id)
43+
expect(topics.first.category_id).to eq(actor.model.id)
44+
expect(DiscourseActivityPubCollection.where(ap_type: "OrderedCollection").count).to eq(1)
45+
expect(DiscourseActivityPubObject.where(ap_type: "Note").count).to eq(1)
46+
expect(DiscourseActivityPubActor.where(ap_type: "Person").count).to eq(3)
47+
expect(DiscourseActivityPubActivity.where(ap_type: "Announce").count).to eq(3)
48+
end
49+
50+
test_multisite_connection("second") do
51+
actor = Fabricate(:discourse_activity_pub_actor_group)
52+
fabricate_follow(actor)
53+
toggle_activity_pub(actor.model, publication_type: "full_topic")
54+
55+
process_case(actor)
56+
57+
posts = Post.all
58+
topics = Topic.all
59+
expect(posts.size).to eq(1)
60+
expect(topics.size).to eq(1)
61+
expect(posts.first.topic_id).to eq(topics.first.id)
62+
expect(topics.first.category_id).to eq(actor.model.id)
63+
expect(DiscourseActivityPubCollection.where(ap_type: "OrderedCollection").count).to eq(1)
64+
expect(DiscourseActivityPubObject.where(ap_type: "Note").count).to eq(1)
65+
expect(DiscourseActivityPubActor.where(ap_type: "Person").count).to eq(3)
66+
expect(DiscourseActivityPubActivity.where(ap_type: "Announce").count).to eq(3)
67+
end
68+
end
69+
end
70+
71+
context "when publishing" do
72+
def fabricate_post(category)
73+
topic = Fabricate(:topic, category: category)
74+
Fabricate(:post, topic: topic)
75+
end
76+
77+
def fabricate_follower(category)
78+
follower = Fabricate(:discourse_activity_pub_actor_person)
79+
Fabricate(
80+
:discourse_activity_pub_follow,
81+
follower: follower,
82+
followed: category.activity_pub_actor,
83+
)
84+
follower
85+
end
86+
87+
before { ENV["ACTIVITY_PUB_DISABLE_DELIVERY_RETRIES"] = "true" }
88+
after { ENV.delete("ACTIVITY_PUB_DISABLE_DELIVERY_RETRIES") }
89+
90+
it "sends activities to followers" do
91+
test_multisite_connection("default") do
92+
category = Fabricate(:category)
93+
toggle_activity_pub(category, publication_type: "full_topic")
94+
follower = fabricate_follower(category)
95+
96+
expect_request(actor_id: category.activity_pub_actor.id, uri: follower.inbox)
97+
98+
post = fabricate_post(category)
99+
post.activity_pub_publish!
100+
end
101+
102+
test_multisite_connection("second") do
103+
category = Fabricate(:category)
104+
toggle_activity_pub(category, publication_type: "full_topic")
105+
follower = fabricate_follower(category)
106+
107+
expect_request(actor_id: category.activity_pub_actor.id, uri: follower.inbox)
108+
109+
post = fabricate_post(category)
110+
post.activity_pub_publish!
111+
end
112+
end
113+
end
114+
end

spec/plugin_helper.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,17 @@ def teardown_logging
342342
def parsed_body
343343
JSON.parse(response.body)
344344
end
345+
346+
def read_integration_json(case_name, file_name)
347+
JSON.parse(
348+
File.open(
349+
File.join(
350+
File.expand_path(__dir__),
351+
"fixtures",
352+
"integration",
353+
case_name,
354+
"#{file_name}.json",
355+
),
356+
).read,
357+
).with_indifferent_access
358+
end

0 commit comments

Comments
 (0)