Skip to content

Commit 48c8c26

Browse files
committed
fix: preserve bounty visibility when editing GitHub comments
- Fix bug where editing GitHub comments with /bounty commands set visibility to null - Update bounty update strategies (:set and :increase) to preserve existing visibility when no new visibility provided - Add comprehensive test suite covering all visibility types (public, community, exclusive) - Ensure bounties remain discoverable after comment edits - Maintain backward compatibility for explicit visibility overrides Fixes issue where bounties would disappear from app discovery after GitHub comment edits.
1 parent 46add68 commit 48c8c26

File tree

3 files changed

+213
-2
lines changed

3 files changed

+213
-2
lines changed

lib/algora/bounties/bounties.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ defmodule Algora.Bounties do
160160
existing
161161
|> Bounty.changeset(%{
162162
amount: amount,
163-
visibility: opts[:visibility],
163+
visibility: opts[:visibility] || existing.visibility,
164164
shared_with: shared_with
165165
})
166166
# |> Activity.put_activity(%Bounty{}, %{type: :bounty_updated, notify_users: []})
@@ -170,7 +170,7 @@ defmodule Algora.Bounties do
170170
existing
171171
|> Bounty.changeset(%{
172172
amount: Money.add!(existing.amount, amount),
173-
visibility: opts[:visibility],
173+
visibility: opts[:visibility] || existing.visibility,
174174
shared_with: shared_with
175175
})
176176
# |> Activity.put_activity(%Bounty{}, %{type: :bounty_updated, notify_users: []})

test/algora/bounties_test.exs

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,152 @@ defmodule Algora.BountiesTest do
221221
transfer = Repo.one(from t in Transaction, where: t.type == :transfer)
222222
assert is_nil(transfer)
223223
end
224+
225+
test "preserves visibility when editing bounty comment", %{owner: owner, creator: creator, ticket_ref: ticket_ref} do
226+
# Create initial bounty with explicit visibility
227+
{:ok, bounty} =
228+
Bounties.create_bounty(%{
229+
ticket_ref: ticket_ref,
230+
owner: owner |> change(%{bounty_mode: :public}) |> Repo.update!(),
231+
creator: creator,
232+
amount: ~M[100]usd,
233+
visibility: :public
234+
})
235+
236+
assert bounty.visibility == :public
237+
238+
# Simulate editing the bounty comment (like GitHub webhook would do)
239+
# This should preserve the existing visibility, not set it to nil
240+
{:ok, updated_bounty} =
241+
Bounties.create_bounty(
242+
%{
243+
ticket_ref: ticket_ref,
244+
owner: owner,
245+
creator: creator,
246+
amount: ~M[200]usd
247+
},
248+
strategy: :set
249+
)
250+
251+
assert updated_bounty.visibility == :public
252+
end
253+
254+
test "preserves visibility when increasing bounty amount", %{owner: owner, creator: creator, ticket_ref: ticket_ref} do
255+
# Create initial bounty with community visibility
256+
{:ok, bounty} =
257+
Bounties.create_bounty(%{
258+
ticket_ref: ticket_ref,
259+
owner: owner |> change(%{bounty_mode: :community}) |> Repo.update!(),
260+
creator: creator,
261+
amount: ~M[100]usd,
262+
visibility: :community
263+
})
264+
265+
assert bounty.visibility == :community
266+
267+
# Simulate adding to bounty amount (like GitHub webhook would do)
268+
{:ok, updated_bounty} =
269+
Bounties.create_bounty(
270+
%{
271+
ticket_ref: ticket_ref,
272+
owner: owner,
273+
creator: creator,
274+
amount: ~M[50]usd
275+
},
276+
strategy: :increase
277+
)
278+
279+
assert updated_bounty.visibility == :community
280+
end
281+
282+
test "preserves exclusive visibility when updating bounty", %{owner: owner, creator: creator, ticket_ref: ticket_ref} do
283+
# Create initial bounty with exclusive visibility
284+
{:ok, bounty} =
285+
Bounties.create_bounty(%{
286+
ticket_ref: ticket_ref,
287+
owner: owner |> change(%{bounty_mode: :exclusive}) |> Repo.update!(),
288+
creator: creator,
289+
amount: ~M[500]usd,
290+
visibility: :exclusive
291+
})
292+
293+
assert bounty.visibility == :exclusive
294+
295+
# Simulate webhook edit without visibility parameter
296+
{:ok, updated_bounty} =
297+
Bounties.create_bounty(
298+
%{
299+
ticket_ref: ticket_ref,
300+
owner: owner,
301+
creator: creator,
302+
amount: ~M[750]usd
303+
},
304+
strategy: :set
305+
)
306+
307+
assert updated_bounty.visibility == :exclusive
308+
end
309+
310+
test "handles nil visibility options without overriding existing value", %{
311+
owner: owner,
312+
creator: creator,
313+
ticket_ref: ticket_ref
314+
} do
315+
# Create initial bounty
316+
{:ok, bounty} =
317+
Bounties.create_bounty(%{
318+
ticket_ref: ticket_ref,
319+
owner: owner |> change(%{bounty_mode: :public}) |> Repo.update!(),
320+
creator: creator,
321+
amount: ~M[100]usd
322+
})
323+
324+
original_visibility = bounty.visibility
325+
326+
# Simulate what happens when GitHub webhook doesn't pass visibility option
327+
{:ok, updated_bounty} =
328+
Bounties.create_bounty(
329+
%{
330+
ticket_ref: ticket_ref,
331+
owner: owner,
332+
creator: creator,
333+
amount: ~M[200]usd
334+
},
335+
# Empty options - no visibility passed
336+
[]
337+
)
338+
339+
assert updated_bounty.visibility == original_visibility
340+
end
341+
342+
test "allows explicit visibility override when provided", %{owner: owner, creator: creator, ticket_ref: ticket_ref} do
343+
# Create initial bounty with public visibility
344+
{:ok, bounty} =
345+
Bounties.create_bounty(%{
346+
ticket_ref: ticket_ref,
347+
owner: owner |> change(%{bounty_mode: :public}) |> Repo.update!(),
348+
creator: creator,
349+
amount: ~M[100]usd,
350+
visibility: :public
351+
})
352+
353+
assert bounty.visibility == :public
354+
355+
# Explicitly change visibility to community
356+
{:ok, updated_bounty} =
357+
Bounties.create_bounty(
358+
%{
359+
ticket_ref: ticket_ref,
360+
owner: owner,
361+
creator: creator,
362+
amount: ~M[200]usd
363+
},
364+
strategy: :set,
365+
visibility: :community
366+
)
367+
368+
assert updated_bounty.visibility == :community
369+
end
224370
end
225371

226372
describe "tips" do

test/algora_web/controllers/webhooks/github_controller_test.exs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,71 @@ defmodule AlgoraWeb.Webhooks.GithubControllerTest do
191191

192192
assert Money.equal?(Repo.one(Bounty).amount, ~M[300]usd)
193193
end
194+
195+
test "editing GitHub comment with /bounty command preserves bounty visibility", ctx do
196+
comment_id = :rand.uniform(1000)
197+
198+
process_scenario!(ctx, [
199+
%{
200+
event_action: "issue_comment.created",
201+
user_type: :repo_admin,
202+
body: "/bounty $100",
203+
params: %{"comment" => %{"id" => comment_id}}
204+
}
205+
])
206+
207+
bounty = Repo.one(Bounty)
208+
original_visibility = bounty.visibility
209+
assert original_visibility != nil
210+
211+
process_scenario!(ctx, [
212+
%{
213+
event_action: "issue_comment.edited",
214+
user_type: :repo_admin,
215+
body: "/bounty $200",
216+
params: %{"comment" => %{"id" => comment_id}}
217+
}
218+
])
219+
220+
updated_bounty = Repo.one(Bounty)
221+
assert updated_bounty.visibility == original_visibility
222+
end
223+
224+
test "visibility preserved when adding to existing bounty via new comment", ctx do
225+
# Create initial bounty with exclusive visibility
226+
process_scenario!(ctx, [
227+
%{
228+
event_action: "issue_comment.created",
229+
user_type: :repo_admin,
230+
body: "/bounty $500",
231+
params: %{"comment" => %{"id" => 1}}
232+
}
233+
])
234+
235+
original_bounty = Repo.one(Bounty)
236+
# Set to exclusive mode for this test
237+
_updated_owner = ctx[:org] |> change(%{bounty_mode: :exclusive}) |> Repo.update!()
238+
updated_bounty = original_bounty |> change(%{visibility: :exclusive}) |> Repo.update!()
239+
240+
original_visibility = updated_bounty.visibility
241+
assert original_visibility == :exclusive
242+
243+
# Add to bounty with new comment (this increases the amount)
244+
process_scenario!(ctx, [
245+
%{
246+
event_action: "issue_comment.created",
247+
user_type: :repo_admin,
248+
body: "/bounty $100",
249+
params: %{"comment" => %{"id" => 2}}
250+
}
251+
])
252+
253+
final_bounty = Repo.one(Bounty)
254+
assert final_bounty.amount.amount >= 600
255+
256+
# This test should now PASS with the fix - visibility is preserved
257+
assert final_bounty.visibility == original_visibility
258+
end
194259
end
195260

196261
describe "create tips" do

0 commit comments

Comments
 (0)