Edit issue and PR descriptions in place, recorded in history

4d15a64 · Gabriel Morell · 2026-09-10 14:24

7 files +339 -34
Message
{commit_body(@commit)}

Files changed

modified lib/git_gud/events/event.ex
+1 −1
@@ -8,7 +8,7 @@ defmodule GitGud.Events.Event do
8 8
9 9 @valid_kinds ~w(
10 10 opened closed reopened merged
11 title_changed
11 + title_changed description_changed
12 12 pushed
13 13 labeled unlabeled
14 14 moderated unmoderated
modified lib/git_gud_web/components/event_components.ex
+5 −2
@@ -122,8 +122,8 @@ defmodule GitGudWeb.EventComponents do
122 122 """
123 123 end
124 124
125 defp diffable?(%{kind: "comment_edited", data: %{"from" => f, "to" => t}})
126 when is_binary(f) and is_binary(t),
125 + defp diffable?(%{kind: kind, data: %{"from" => f, "to" => t}})
126 + when kind in ["comment_edited", "description_changed"] and is_binary(f) and is_binary(t),
127 127 do: true
128 128
129 129 defp diffable?(_), do: false
@@ -148,6 +148,7 @@ defmodule GitGudWeb.EventComponents do
148 148 defp review_word("commented"), do: "commented"
149 149 defp review_word(_), do: nil
150 150
151 + defp dot_class("description_changed"), do: "bg-base-300"
151 152 defp dot_class("reviewed"), do: "bg-accent"
152 153 defp dot_class(k) when k in ["comment_added", "comment_edited"], do: "bg-info"
153 154 defp dot_class("comment_deleted"), do: "bg-error"
@@ -181,6 +182,8 @@ defmodule GitGudWeb.EventComponents do
181 182
182 183 defp describe(%{kind: "title_changed"}), do: "changed the title."
183 184
185 + defp describe(%{kind: "description_changed"}), do: "edited the description."
186 +
184 187 defp describe(%{kind: "pushed", data: data}) do
185 188 assigns = %{
186 189 from: short(data["from"]),
modified lib/git_gud_web/live/issue_live/show.ex
+85 −11
@@ -30,6 +30,7 @@ defmodule GitGudWeb.IssueLive.Show do
30 30 |> assign(:editing_title?, false)
31 31 |> assign(:editing_comment_id, nil)
32 32 |> assign(:title_error, nil)
33 + |> assign(:editing_body?, false)
33 34 |> assign(:event_count, Events.count_for(issue))
34 35 |> assign(:page_title, "##{issue.number} #{issue.title}")}
35 36 end
@@ -44,10 +45,10 @@ defmodule GitGudWeb.IssueLive.Show do
44 45 #
45 46 # The author can fix their own title; repo owners and org admins can
46 47 # fix anyone's. `can_admin?` comes from `assign_chrome/2`.
47 defp can_edit_title?(%{current_scope: %{user: %{id: uid}}} = assigns),
48 + defp can_edit?(%{current_scope: %{user: %{id: uid}}} = assigns),
48 49 do: assigns.can_admin? || assigns.issue.author_id == uid
49 50
50 defp can_edit_title?(_assigns), do: false
51 + defp can_edit?(_assigns), do: false
51 52
52 53 # Same rule as the title: the comment's author, or a repo admin. A
53 54 # deleted comment is nobody's to edit.
@@ -75,7 +76,7 @@ defmodule GitGudWeb.IssueLive.Show do
75 76 end
76 77
77 78 def handle_event("edit_title", _params, socket) do
78 if can_edit_title?(socket.assigns) do
79 + if can_edit?(socket.assigns) do
79 80 {:noreply, socket |> assign(:editing_title?, true) |> assign(:title_error, nil)}
80 81 else
81 82 {:noreply, socket}
@@ -90,7 +91,7 @@ defmodule GitGudWeb.IssueLive.Show do
90 91 issue = socket.assigns.issue
91 92
92 93 cond do
93 not can_edit_title?(socket.assigns) ->
94 + not can_edit?(socket.assigns) ->
94 95 {:noreply, put_flash(socket, :error, "You can't rename this issue.")}
95 96
96 97 String.trim(title) == issue.title ->
@@ -110,6 +111,7 @@ defmodule GitGudWeb.IssueLive.Show do
110 111 |> assign(:editing_title?, false)
111 112 |> assign(:editing_comment_id, nil)
112 113 |> assign(:title_error, nil)
114 + |> assign(:editing_body?, false)
113 115 |> assign(:event_count, Events.count_for(issue))
114 116 |> reload()}
115 117
@@ -263,6 +265,50 @@ defmodule GitGudWeb.IssueLive.Show do
263 265 end
264 266 end
265 267
268 + def handle_event("edit_body", _params, socket) do
269 + if can_edit?(socket.assigns) do
270 + {:noreply, assign(socket, :editing_body?, true)}
271 + else
272 + {:noreply, socket}
273 + end
274 + end
275 +
276 + def handle_event("cancel_edit_body", _params, socket) do
277 + {:noreply, assign(socket, :editing_body?, false)}
278 + end
279 +
280 + def handle_event("save_body", %{"body" => body}, socket) do
281 + target = socket.assigns.issue
282 + trimmed = String.trim(body)
283 +
284 + cond do
285 + not can_edit?(socket.assigns) ->
286 + {:noreply, put_flash(socket, :error, "You can't edit this description.")}
287 +
288 + trimmed == (target.body || "") ->
289 + {:noreply, assign(socket, :editing_body?, false)}
290 +
291 + true ->
292 + case Issues.update_issue(target, %{"body" => trimmed}) do
293 + {:ok, updated} ->
294 + :ok =
295 + Events.record(target, "description_changed", viewer(socket), %{
296 + from: target.body || "",
297 + to: updated.body || ""
298 + })
299 +
300 + {:noreply,
301 + socket
302 + |> assign(:editing_body?, false)
303 + |> assign(:event_count, Events.count_for(target))
304 + |> reload()}
305 +
306 + {:error, _cs} ->
307 + {:noreply, put_flash(socket, :error, "Could not save that description.")}
308 + end
309 + end
310 + end
311 +
266 312 defp changeset_error(cs, field) do
267 313 case cs.errors[field] do
268 314 {msg, _opts} -> msg
@@ -298,7 +344,7 @@ defmodule GitGudWeb.IssueLive.Show do
298 344 number={@issue.number}
299 345 title={@issue.title}
300 346 editing?={@editing_title?}
301 can_edit?={can_edit_title?(assigns)}
347 + can_edit?={can_edit?(assigns)}
302 348 error={@title_error}
303 349 />
304 350 <p class="text-xs opacity-60">
@@ -314,12 +360,40 @@ defmodule GitGudWeb.IssueLive.Show do
314 360 </header>
315 361
316 362 <section class="border border-base-300 rounded p-4">
317 <GitGudWeb.ModerationComponents.moderated_body
318 target={@issue}
319 viewer={@current_scope && @current_scope.user}
320 repo={@repo}
321 theme={@editor_theme}
322 />
363 + <%= if @editing_body? do %>
364 + <form phx-submit="save_body" class="space-y-2">
365 + <textarea
366 + name="body"
367 + rows="10"
368 + aria-label="Description"
369 + class="textarea textarea-bordered w-full font-mono text-sm"
370 + >{@issue.body}</textarea>
371 + <div class="flex justify-end gap-2">
372 + <button type="button" phx-click="cancel_edit_body" class="btn btn-xs btn-ghost">
373 + Cancel
374 + </button>
375 + <button type="submit" class="btn btn-xs btn-primary">Save</button>
376 + </div>
377 + </form>
378 + <% else %>
379 + <div class="flex justify-end">
380 + <button
381 + :if={can_edit?(assigns)}
382 + type="button"
383 + phx-click="edit_body"
384 + class="btn btn-xs btn-ghost opacity-60 hover:opacity-100"
385 + title="Edit description"
386 + >
387 + <.icon name="hero-pencil-square" class="size-3" /> Edit
388 + </button>
389 + </div>
390 + <GitGudWeb.ModerationComponents.moderated_body
391 + target={@issue}
392 + viewer={@current_scope && @current_scope.user}
393 + repo={@repo}
394 + theme={@editor_theme}
395 + />
396 + <% end %>
323 397 </section>
324 398
325 399 <section :if={@all_labels != []}>
modified lib/git_gud_web/live/pr_live/show.ex
+85 −11
@@ -62,6 +62,7 @@ defmodule GitGudWeb.PrLive.Show do
62 62 |> assign(:editing_comment_id, nil)
63 63 |> assign(:commenting_on, nil)
64 64 |> assign(:title_error, nil)
65 + |> assign(:editing_body?, false)
65 66 |> assign(:event_count, Events.count_for(pr))
66 67 |> assign(:page_title, "##{pr.number} #{pr.title}")}
67 68 end
@@ -70,10 +71,10 @@ defmodule GitGudWeb.PrLive.Show do
70 71
71 72 # Takes assigns rather than the socket so `render/1` and the event
72 73 # handlers can share it. Author or repo admin, same rule as issues.
73 defp can_edit_title?(%{current_scope: %{user: %{id: uid}}} = assigns),
74 + defp can_edit?(%{current_scope: %{user: %{id: uid}}} = assigns),
74 75 do: assigns.can_admin? || assigns.pr.author_id == uid
75 76
76 defp can_edit_title?(_assigns), do: false
77 + defp can_edit?(_assigns), do: false
77 78
78 79 # Closing and reopening are the author's or a maintainer's to do.
79 80 # `can_admin?` already covers repo owner and org admin.
@@ -211,7 +212,7 @@ defmodule GitGudWeb.PrLive.Show do
211 212 end
212 213
213 214 def handle_event("edit_title", _params, socket) do
214 if can_edit_title?(socket.assigns) do
215 + if can_edit?(socket.assigns) do
215 216 {:noreply, socket |> assign(:editing_title?, true) |> assign(:title_error, nil)}
216 217 else
217 218 {:noreply, socket}
@@ -226,7 +227,7 @@ defmodule GitGudWeb.PrLive.Show do
226 227 pr = socket.assigns.pr
227 228
228 229 cond do
229 not can_edit_title?(socket.assigns) ->
230 + not can_edit?(socket.assigns) ->
230 231 {:noreply, put_flash(socket, :error, "You can't rename this pull request.")}
231 232
232 233 String.trim(title) == pr.title ->
@@ -247,6 +248,7 @@ defmodule GitGudWeb.PrLive.Show do
247 248 |> assign(:editing_comment_id, nil)
248 249 |> assign(:commenting_on, nil)
249 250 |> assign(:title_error, nil)
251 + |> assign(:editing_body?, false)
250 252 |> assign(:event_count, Events.count_for(pr))
251 253 |> reload()}
252 254
@@ -477,6 +479,50 @@ defmodule GitGudWeb.PrLive.Show do
477 479 end
478 480 end
479 481
482 + def handle_event("edit_body", _params, socket) do
483 + if can_edit?(socket.assigns) do
484 + {:noreply, assign(socket, :editing_body?, true)}
485 + else
486 + {:noreply, socket}
487 + end
488 + end
489 +
490 + def handle_event("cancel_edit_body", _params, socket) do
491 + {:noreply, assign(socket, :editing_body?, false)}
492 + end
493 +
494 + def handle_event("save_body", %{"body" => body}, socket) do
495 + target = socket.assigns.pr
496 + trimmed = String.trim(body)
497 +
498 + cond do
499 + not can_edit?(socket.assigns) ->
500 + {:noreply, put_flash(socket, :error, "You can't edit this description.")}
501 +
502 + trimmed == (target.body || "") ->
503 + {:noreply, assign(socket, :editing_body?, false)}
504 +
505 + true ->
506 + case PullRequests.update_pull_request(target, %{"body" => trimmed}) do
507 + {:ok, updated} ->
508 + :ok =
509 + Events.record(target, "description_changed", viewer(socket), %{
510 + from: target.body || "",
511 + to: updated.body || ""
512 + })
513 +
514 + {:noreply,
515 + socket
516 + |> assign(:editing_body?, false)
517 + |> assign(:event_count, Events.count_for(target))
518 + |> reload()}
519 +
520 + {:error, _cs} ->
521 + {:noreply, put_flash(socket, :error, "Could not save that description.")}
522 + end
523 + end
524 + end
525 +
480 526 defp changeset_error(cs, field) do
481 527 case cs.errors[field] do
482 528 {msg, _opts} -> msg
@@ -515,7 +561,7 @@ defmodule GitGudWeb.PrLive.Show do
515 561 number={@pr.number}
516 562 title={@pr.title}
517 563 editing?={@editing_title?}
518 can_edit?={can_edit_title?(assigns)}
564 + can_edit?={can_edit?(assigns)}
519 565 error={@title_error}
520 566 />
521 567 </div>
@@ -566,12 +612,40 @@ defmodule GitGudWeb.PrLive.Show do
566 612 </header>
567 613
568 614 <section class="border border-base-300 rounded p-4">
569 <GitGudWeb.ModerationComponents.moderated_body
570 target={@pr}
571 viewer={@current_scope && @current_scope.user}
572 repo={@repo}
573 theme={@editor_theme}
574 />
615 + <%= if @editing_body? do %>
616 + <form phx-submit="save_body" class="space-y-2">
617 + <textarea
618 + name="body"
619 + rows="10"
620 + aria-label="Description"
621 + class="textarea textarea-bordered w-full font-mono text-sm"
622 + >{@pr.body}</textarea>
623 + <div class="flex justify-end gap-2">
624 + <button type="button" phx-click="cancel_edit_body" class="btn btn-xs btn-ghost">
625 + Cancel
626 + </button>
627 + <button type="submit" class="btn btn-xs btn-primary">Save</button>
628 + </div>
629 + </form>
630 + <% else %>
631 + <div class="flex justify-end">
632 + <button
633 + :if={can_edit?(assigns)}
634 + type="button"
635 + phx-click="edit_body"
636 + class="btn btn-xs btn-ghost opacity-60 hover:opacity-100"
637 + title="Edit description"
638 + >
639 + <.icon name="hero-pencil-square" class="size-3" /> Edit
640 + </button>
641 + </div>
642 + <GitGudWeb.ModerationComponents.moderated_body
643 + target={@pr}
644 + viewer={@current_scope && @current_scope.user}
645 + repo={@repo}
646 + theme={@editor_theme}
647 + />
648 + <% end %>
575 649 </section>
576 650
577 651 <section class="flex gap-4 text-sm">
added test/git_gud_web/live/description_edit_test.exs
+154 −0
@@ -0,0 +1,154 @@
1 +defmodule GitGudWeb.DescriptionEditTest do
2 + @moduledoc """
3 + Editing an issue or PR description in place, the same way titles are
4 + edited, with the change recorded as a collapsed diff in history.
5 + """
6 +
7 + use GitGudWeb.ConnCase, async: false
8 +
9 + import Phoenix.LiveViewTest
10 + import GitGud.AccountsFixtures
11 + import GitGud.ForgeFixtures
12 +
13 + alias GitGud.Events
14 + alias GitGud.Issues
15 + alias GitGud.PullRequests
16 + alias GitGud.Repositories
17 +
18 + defp handle(repo),
19 + do: Repositories.Storage.repo_handle(GitGud.Repo.preload(repo, [:owner, :organization]))
20 +
21 + defp issue_path(repo, issue),
22 + do: ~p"/r/#{handle(repo)}/#{repo.name}/issues/#{issue.number}"
23 +
24 + defp pr_path(repo, pr),
25 + do: ~p"/r/#{handle(repo)}/#{repo.name}/pulls/#{pr.number}"
26 +
27 + describe "issues" do
28 + test "the author can edit the description in place", %{conn: conn} do
29 + {user, repo} = repository_fixture()
30 + issue = issue_fixture(repo, user, %{"body" => "Original description"})
31 +
32 + {:ok, lv, _html} = live(log_in_user(conn, user), issue_path(repo, issue))
33 +
34 + _ = lv |> element("button[phx-click=edit_body]") |> render_click()
35 + html = lv |> form("form[phx-submit=save_body]", %{body: "Rewritten"}) |> render_submit()
36 +
37 + assert html =~ "Rewritten"
38 + assert Issues.get_issue!(repo, issue.number).body == "Rewritten"
39 + end
40 +
41 + test "an unrelated user gets no edit affordance", %{conn: conn} do
42 + {_owner, repo} = repository_fixture(%{visibility: "public"})
43 + author = user_fixture()
44 + issue = issue_fixture(repo, author, %{"body" => "Theirs"})
45 +
46 + outsider = user_fixture()
47 + {:ok, lv, _html} = live(log_in_user(conn, outsider), issue_path(repo, issue))
48 +
49 + refute has_element?(lv, "button[phx-click=edit_body]")
50 + end
51 +
52 + test "an unrelated user can't edit by sending the event", %{conn: conn} do
53 + {_owner, repo} = repository_fixture(%{visibility: "public"})
54 + author = user_fixture()
55 + issue = issue_fixture(repo, author, %{"body" => "Untouchable"})
56 +
57 + outsider = user_fixture()
58 + {:ok, lv, _html} = live(log_in_user(conn, outsider), issue_path(repo, issue))
59 +
60 + render_hook(lv, "save_body", %{"body" => "Hijacked"})
61 +
62 + assert Issues.get_issue!(repo, issue.number).body == "Untouchable"
63 + end
64 +
65 + test "a repo admin can edit someone else's description", %{conn: conn} do
66 + {owner, repo} = repository_fixture(%{visibility: "public"})
67 + author = user_fixture()
68 + issue = issue_fixture(repo, author, %{"body" => "Needs work"})
69 +
70 + {:ok, lv, _html} = live(log_in_user(conn, owner), issue_path(repo, issue))
71 +
72 + _ = lv |> element("button[phx-click=edit_body]") |> render_click()
73 + html = lv |> form("form[phx-submit=save_body]", %{body: "Tidied"}) |> render_submit()
74 +
75 + assert html =~ "Tidied"
76 + end
77 +
78 + test "an unchanged description records nothing", %{conn: conn} do
79 + {user, repo} = repository_fixture()
80 + issue = issue_fixture(repo, user, %{"body" => "Same"})
81 +
82 + {:ok, lv, _html} = live(log_in_user(conn, user), issue_path(repo, issue))
83 + _ = lv |> element("button[phx-click=edit_body]") |> render_click()
84 + _ = lv |> form("form[phx-submit=save_body]", %{body: "Same"}) |> render_submit()
85 +
86 + assert Events.list_for(issue) == []
87 + end
88 +
89 + test "the change shows in history as a collapsed diff", %{conn: conn} do
90 + {user, repo} = repository_fixture()
91 + issue = issue_fixture(repo, user, %{"body" => "line one\nline two"})
92 +
93 + {:ok, lv, _html} = live(log_in_user(conn, user), issue_path(repo, issue))
94 + _ = lv |> element("button[phx-click=edit_body]") |> render_click()
95 +
96 + _ =
97 + lv
98 + |> form("form[phx-submit=save_body]", %{body: "line one\nline three"})
99 + |> render_submit()
100 +
101 + {:ok, _hist, html} = live(log_in_user(conn, user), issue_path(repo, issue) <> "/history")
102 +
103 + assert html =~ "edited the description."
104 + assert html =~ "Show what changed"
105 + refute html =~ "<details open"
106 + assert html =~ "line two"
107 + assert html =~ "line three"
108 + end
109 + end
110 +
111 + describe "pull requests" do
112 + test "the author can edit the description in place", %{conn: conn} do
113 + {user, repo} = repository_fixture()
114 + pr = pr_with_branches(repo, user, %{"body" => "PR description"})
115 +
116 + {:ok, lv, _html} = live(log_in_user(conn, user), pr_path(repo, pr))
117 +
118 + _ = lv |> element("button[phx-click=edit_body]") |> render_click()
119 +
120 + html =
121 + lv |> form("form[phx-submit=save_body]", %{body: "Better description"}) |> render_submit()
122 +
123 + assert html =~ "Better description"
124 + assert PullRequests.get_pull_request!(repo, pr.number).body == "Better description"
125 + end
126 +
127 + test "the edit is recorded", %{conn: conn} do
128 + {user, repo} = repository_fixture()
129 + pr = pr_with_branches(repo, user, %{"body" => "before"})
130 +
131 + {:ok, lv, _html} = live(log_in_user(conn, user), pr_path(repo, pr))
132 + _ = lv |> element("button[phx-click=edit_body]") |> render_click()
133 + _ = lv |> form("form[phx-submit=save_body]", %{body: "after"}) |> render_submit()
134 +
135 + assert [%{kind: "description_changed", data: data}] = Events.list_for(pr)
136 + assert data["from"] == "before"
137 + assert data["to"] == "after"
138 + end
139 +
140 + test "an unrelated user can't edit it", %{conn: conn} do
141 + {_owner, repo} = repository_fixture(%{visibility: "public"})
142 + author = user_fixture()
143 + pr = pr_with_branches(repo, author, %{"body" => "Hands off"})
144 +
145 + outsider = user_fixture()
146 + {:ok, lv, _html} = live(log_in_user(conn, outsider), pr_path(repo, pr))
147 +
148 + refute has_element?(lv, "button[phx-click=edit_body]")
149 + render_hook(lv, "save_body", %{"body" => "Hijacked"})
150 +
151 + assert PullRequests.get_pull_request!(repo, pr.number).body == "Hands off"
152 + end
153 + end
154 +end
modified test/git_gud_web/live/issue_live/title_history_test.exs
+7 −7
@@ -27,7 +27,7 @@ defmodule GitGudWeb.IssueLive.TitleHistoryTest do
27 27
28 28 {:ok, lv, _html} = live(log_in_user(conn, user), issue_path(repo, issue))
29 29
30 html = lv |> element("button", "Edit") |> render_click()
30 + html = lv |> element("button[phx-click=edit_title]") |> render_click()
31 31 assert html =~ ~s(name="title")
32 32
33 33 html =
@@ -45,7 +45,7 @@ defmodule GitGudWeb.IssueLive.TitleHistoryTest do
45 45
46 46 {:ok, lv, _html} = live(log_in_user(conn, owner), issue_path(repo, issue))
47 47
48 _ = lv |> element("button", "Edit") |> render_click()
48 + _ = lv |> element("button[phx-click=edit_title]") |> render_click()
49 49
50 50 html =
51 51 lv |> form("form[phx-submit=save_title]", %{title: "Fixed by admin"}) |> render_submit()
@@ -92,7 +92,7 @@ defmodule GitGudWeb.IssueLive.TitleHistoryTest do
92 92 issue = issue_fixture(repo, user, %{"title" => "Keep me"})
93 93
94 94 {:ok, lv, _html} = live(log_in_user(conn, user), issue_path(repo, issue))
95 _ = lv |> element("button", "Edit") |> render_click()
95 + _ = lv |> element("button[phx-click=edit_title]") |> render_click()
96 96
97 97 render_hook(lv, "save_title", %{"title" => " "})
98 98
@@ -104,7 +104,7 @@ defmodule GitGudWeb.IssueLive.TitleHistoryTest do
104 104 issue = issue_fixture(repo, user, %{"title" => "Unchanged"})
105 105
106 106 {:ok, lv, _html} = live(log_in_user(conn, user), issue_path(repo, issue))
107 _ = lv |> element("button", "Edit") |> render_click()
107 + _ = lv |> element("button[phx-click=edit_title]") |> render_click()
108 108 _ = lv |> form("form[phx-submit=save_title]", %{title: "Unchanged"}) |> render_submit()
109 109
110 110 assert Events.list_for(issue) == []
@@ -115,8 +115,8 @@ defmodule GitGudWeb.IssueLive.TitleHistoryTest do
115 115 issue = issue_fixture(repo, user, %{"title" => "Still here"})
116 116
117 117 {:ok, lv, _html} = live(log_in_user(conn, user), issue_path(repo, issue))
118 _ = lv |> element("button", "Edit") |> render_click()
119 html = lv |> element("button", "Cancel") |> render_click()
118 + _ = lv |> element("button[phx-click=edit_title]") |> render_click()
119 + html = lv |> element("button[phx-click=cancel_edit_title]") |> render_click()
120 120
121 121 assert html =~ "Still here"
122 122 assert Events.list_for(issue) == []
@@ -129,7 +129,7 @@ defmodule GitGudWeb.IssueLive.TitleHistoryTest do
129 129 issue = issue_fixture(repo, user, %{"title" => "Before"})
130 130
131 131 {:ok, lv, _html} = live(log_in_user(conn, user), issue_path(repo, issue))
132 _ = lv |> element("button", "Edit") |> render_click()
132 + _ = lv |> element("button[phx-click=edit_title]") |> render_click()
133 133 _ = lv |> form("form[phx-submit=save_title]", %{title: "After"}) |> render_submit()
134 134
135 135 {:ok, _hist, html} = live(log_in_user(conn, user), issue_path(repo, issue) <> "/history")
modified test/git_gud_web/live/pr_live/title_history_test.exs
+2 −2
@@ -31,7 +31,7 @@ defmodule GitGudWeb.PrLive.TitleHistoryTest do
31 31
32 32 {:ok, lv, _html} = live(log_in_user(conn, user), pr_path(repo, pr))
33 33
34 _ = lv |> element("button", "Edit") |> render_click()
34 + _ = lv |> element("button[phx-click=edit_title]") |> render_click()
35 35 html = lv |> form("form[phx-submit=save_title]", %{title: "Renamed PR"}) |> render_submit()
36 36
37 37 assert html =~ "Renamed PR"
@@ -57,7 +57,7 @@ defmodule GitGudWeb.PrLive.TitleHistoryTest do
57 57 pr = open_pr!(repo, user, "PR before")
58 58
59 59 {:ok, lv, _html} = live(log_in_user(conn, user), pr_path(repo, pr))
60 _ = lv |> element("button", "Edit") |> render_click()
60 + _ = lv |> element("button[phx-click=edit_title]") |> render_click()
61 61 _ = lv |> form("form[phx-submit=save_title]", %{title: "PR after"}) |> render_submit()
62 62
63 63 {:ok, _hist, html} = live(log_in_user(conn, user), pr_path(repo, pr) <> "/history")

Parents: d1b9a04