Skip to content

Commit 300a292

Browse files
committed
Test outcomes for IssueComment event on pull request.
Rewrite Sync.IssueComment
1 parent dc9c2a4 commit 300a292

File tree

4 files changed

+326
-97
lines changed

4 files changed

+326
-97
lines changed

lib/code_corps/github/sync/github_comment/github_comment.ex

Lines changed: 57 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,35 @@ defmodule CodeCorps.GitHub.Sync.GithubComment do
1717
}
1818
alias Ecto.Changeset
1919

20-
@type result :: {:ok, GithubComment.t} | {:error, Changeset.t}
20+
@type result :: {:ok, GithubComment.t()} | {:error, Changeset.t()}
2121

2222
@doc ~S"""
2323
Finds or creates a `CodeCorps.GithubComment` using the data in a GitHub
2424
IssueComment payload.
2525
2626
The process is as follows:
2727
28-
- Search for the issue in our database with the payload data.
28+
- Search for the comment in our database with the payload data.
2929
- If found, update it with payload data
3030
- If not found, create it from payload data
3131
3232
`CodeCorps.GitHub.Adapters.Comment.to_github_comment/1` is used to adapt the
3333
payload data.
3434
"""
3535
@spec create_or_update_comment(GithubIssue.t, map) :: result
36-
def create_or_update_comment(%GithubIssue{} = github_issue, %{} = %{"id" => github_comment_id} = attrs) do
37-
params = to_params(attrs, github_issue)
38-
case Repo.get_by(GithubComment, github_id: github_comment_id) do
39-
nil -> create_comment(params)
40-
%GithubComment{} = github_comment -> github_comment |> update_comment(params)
36+
def create_or_update_comment(%GithubIssue{} = github_issue, %{} = attrs) do
37+
with {:ok, %GithubUser{} = github_user} <- Sync.GithubUser.create_or_update_github_user(attrs),
38+
params <- attrs |> Adapters.Comment.to_github_comment()
39+
do
40+
case attrs |> find_comment() do
41+
nil ->
42+
params |> create_comment(github_issue |> find_repo(), github_issue, github_user)
43+
44+
%GithubComment{} = github_comment ->
45+
github_comment |> update_comment(params)
46+
end
47+
else
48+
{:error, error} -> {:error, error}
4149
end
4250
end
4351

@@ -49,36 +57,53 @@ defmodule CodeCorps.GitHub.Sync.GithubComment do
4957
`issue_url` property of the payload.
5058
"""
5159
@spec create_or_update_comment(GithubRepo.t, map) :: result
52-
def create_or_update_comment(%GithubRepo{} = github_repo, %{"id" => _, "issue_url" => _} = attrs) do
60+
def create_or_update_comment(%GithubRepo{} = github_repo, %{} = attrs) do
5361
with {:ok, %GithubUser{} = github_user} <- Sync.GithubUser.create_or_update_github_user(attrs),
54-
{:ok, %GithubComment{} = github_comment} <- do_create_or_update_comment(github_repo, attrs, github_user) do
55-
{:ok, github_comment}
62+
params <- attrs |> Adapters.Comment.to_github_comment()
63+
do
64+
case attrs |> find_comment() do
65+
nil ->
66+
params
67+
|> create_comment(github_repo, attrs |> find_issue(), github_user)
68+
69+
%GithubComment{} = github_comment ->
70+
github_comment |> update_comment(params)
71+
end
5672
else
5773
{:error, error} -> {:error, error}
5874
end
5975
end
6076

61-
defp do_create_or_update_comment(
62-
%GithubRepo{} = github_repo,
63-
%{"id" => github_id, "issue_url" => issue_url} = attrs,
64-
%GithubUser{} = github_user) do
65-
66-
case Repo.get_by(GithubComment, github_id: github_id) |> Repo.preload([:github_issue, :github_repo, :github_user]) do
67-
nil ->
68-
%GithubComment{}
69-
|> GithubComment.create_changeset(attrs |> Adapters.Comment.to_github_comment)
70-
|> Changeset.put_assoc(:github_issue, GithubIssue |> Repo.get_by(url: issue_url))
71-
|> Changeset.put_assoc(:github_repo, github_repo)
72-
|> Changeset.put_assoc(:github_user, github_user)
73-
|> Repo.insert
74-
%GithubComment{} = github_comment ->
75-
github_comment
76-
|> GithubComment.update_changeset(attrs |> Adapters.Comment.to_github_comment)
77-
|> Changeset.put_assoc(:github_issue, GithubIssue |> Repo.get_by(url: issue_url))
78-
|> Changeset.put_assoc(:github_repo, github_repo)
79-
|> Changeset.put_assoc(:github_user, github_user)
80-
|> Repo.update
81-
end
77+
78+
@spec find_comment(map) :: GithubComment.t() | nil
79+
defp find_comment(%{"id" => github_id}) do
80+
GithubComment |> Repo.get_by(github_id: github_id)
81+
end
82+
83+
@spec find_issue(map) :: GithubIssue.t() | nil
84+
defp find_issue(%{"issue_url" => issue_url}) do
85+
GithubIssue |> Repo.get_by(url: issue_url)
86+
end
87+
88+
@spec find_repo(GithubIssue.t()) :: GithubRepo.t() | nil
89+
defp find_repo(%GithubIssue{github_repo_id: github_repo_id}) do
90+
GithubRepo |> Repo.get(github_repo_id)
91+
end
92+
93+
@spec create_comment(map, GithubRepo.t() | nil, GithubIssue.t() | nil, GithubUser.t() | nil) :: result()
94+
defp create_comment(%{} = params, github_repo, github_issue, github_user) do
95+
%GithubComment{}
96+
|> GithubComment.create_changeset(params)
97+
|> Changeset.put_assoc(:github_issue, github_issue)
98+
|> Changeset.put_assoc(:github_repo, github_repo)
99+
|> Changeset.put_assoc(:github_user, github_user)
100+
|> Changeset.validate_required([:github_issue, :github_repo, :github_user])
101+
|> Repo.insert()
102+
end
103+
104+
@spec update_comment(GitHubComment.t(), map) :: result()
105+
defp update_comment(%GithubComment{} = github_comment, %{} = params) do
106+
github_comment |> GithubComment.update_changeset(params) |> Repo.update()
82107
end
83108

84109
@doc ~S"""
@@ -88,33 +113,12 @@ defmodule CodeCorps.GitHub.Sync.GithubComment do
88113
Returns the deleted `CodeCorps.GithubComment` record or an empty
89114
`CodeCorps.GithubComment` record if no such record existed.
90115
"""
91-
@spec delete(String.t) :: {:ok, GithubComment.t}
116+
@spec delete(String.t) :: {:ok, GithubComment.t()}
92117
def delete(github_id) do
93118
comment = Repo.get_by(GithubComment, github_id: github_id)
94119
case comment do
95120
nil -> {:ok, %GithubComment{}}
96121
_ -> Repo.delete(comment, returning: true)
97122
end
98123
end
99-
100-
@spec create_comment(map) :: result
101-
defp create_comment(params) do
102-
%GithubComment{}
103-
|> GithubComment.create_changeset(params)
104-
|> Repo.insert
105-
end
106-
107-
@spec update_comment(GithubComment.t, map) :: result
108-
defp update_comment(%GithubComment{} = github_comment, %{} = params) do
109-
github_comment
110-
|> GithubComment.update_changeset(params)
111-
|> Repo.update
112-
end
113-
114-
@spec to_params(map, GithubIssue.t) :: map
115-
defp to_params(attrs, %GithubIssue{id: github_issue_id}) do
116-
attrs
117-
|> Adapters.Comment.to_github_comment()
118-
|> Map.put(:github_issue_id, github_issue_id)
119-
end
120124
end

lib/code_corps/github/sync/sync.ex

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ defmodule CodeCorps.GitHub.Sync do
1313
GitHub.Sync.Utils.Finder,
1414
GitHub.Utils.ResultAggregator,
1515
GithubAppInstallation,
16+
GithubComment,
1617
GithubIssue,
18+
GithubPullRequest,
1719
GithubRepo,
1820
GithubUser,
1921
Repo,
@@ -26,7 +28,7 @@ defmodule CodeCorps.GitHub.Sync do
2628
{:error, :repo_not_found} |
2729
{:error, :validating_github_issue, Changeset.t()} |
2830
{:error, :validating_user, Changeset.t()} |
29-
{:error, :multiple_issue_users_match} |
31+
{:error, :multiple_task_users_match} |
3032
{:error, :validating_task, Changeset.t()} |
3133
{:error, :unexpected_transaction_outcome, any}
3234

@@ -47,10 +49,10 @@ defmodule CodeCorps.GitHub.Sync do
4749
issue_payload
4850
|> Sync.GithubIssue.create_or_update_issue(github_repo)
4951
end)
50-
|> Multi.run(:issue_user, fn %{github_issue: github_issue} ->
52+
|> Multi.run(:task_user, fn %{github_issue: github_issue} ->
5153
github_issue |> Sync.User.RecordLinker.link_to(issue_payload)
5254
end)
53-
|> Multi.run(:task, fn %{github_issue: github_issue, issue_user: user} ->
55+
|> Multi.run(:task, fn %{github_issue: github_issue, task_user: user} ->
5456
github_issue |> Sync.Task.sync_github_issue(user)
5557
end)
5658

@@ -66,11 +68,11 @@ defmodule CodeCorps.GitHub.Sync do
6668
{:error, :github_issue, %Changeset{data: %GithubUser{}} = changeset, _steps} ->
6769
{:error, :validating_github_user, changeset}
6870

69-
{:error, :issue_user, %Changeset{} = changeset, _steps} ->
71+
{:error, :task_user, %Changeset{} = changeset, _steps} ->
7072
{:error, :validating_user, changeset}
7173

72-
{:error, :issue_user, :multiple_users, _steps} ->
73-
{:error, :multiple_issue_users_match}
74+
{:error, :task_user, :multiple_users, _steps} ->
75+
{:error, :multiple_task_users_match}
7476

7577
{:error, :task, %Changeset{} = changeset, _steps} ->
7678
{:error, :validating_task, changeset}
@@ -86,19 +88,22 @@ defmodule CodeCorps.GitHub.Sync do
8688
{:ok, Comment.t()} |
8789
{:error, :repo_not_found} |
8890
{:error, :validating_github_issue, Changeset.t()} |
89-
{:error, :validating_user, Changeset.t()} |
90-
{:error, :multiple_issue_users_match} |
91+
{:error, :validating_github_user_on_github_issue, Changeset.t()} |
92+
{:error, :validating_task_user, Changeset.t()} |
93+
{:error, :multiple_task_users_match} |
9194
{:error, :validating_task, Changeset.t()} |
9295
{:error, :validating_github_comment, Changeset.t()} |
93-
{:error, :validating_user, Changeset.t()} |
96+
{:error, :validating_github_user_on_github_comment, Changeset.t()} |
97+
{:error, :validating_comment_user, Changeset.t()} |
9498
{:error, :multiple_comment_users_match} |
9599
{:error, :validating_comment, Changeset.t()} |
96100
{:error, :unexpected_transaction_outcome, any}
97101

98102
@type pull_request_comment_outcome ::
99103
issue_comment_outcome() |
100104
{:error, :fetching_pull_request, struct} |
101-
{:error, :validating_github_pull_request, Changeset.t()}
105+
{:error, :validating_github_pull_request, Changeset.t()} |
106+
{:error, :validating_github_user_on_github_pull_request, Changeset.t()}
102107

103108
@type issue_comment_event_outcome ::
104109
comment_deleted_outcome() |
@@ -151,10 +156,10 @@ defmodule CodeCorps.GitHub.Sync do
151156
issue_payload
152157
|> Sync.GithubIssue.create_or_update_issue(github_repo, github_pull_request)
153158
end)
154-
|> Multi.run(:issue_user, fn %{github_issue: github_issue} ->
159+
|> Multi.run(:task_user, fn %{github_issue: github_issue} ->
155160
github_issue |> Sync.User.RecordLinker.link_to(issue_payload)
156161
end)
157-
|> Multi.run(:task, fn %{github_issue: github_issue, issue_user: user} ->
162+
|> Multi.run(:task, fn %{github_issue: github_issue, task_user: user} ->
158163
github_issue |> Sync.Task.sync_github_issue(user)
159164
end)
160165
|> Multi.run(:github_comment, fn %{github_issue: github_issue} ->
@@ -177,26 +182,35 @@ defmodule CodeCorps.GitHub.Sync do
177182
{:error, :fetch_pull_request, error, _steps} ->
178183
{:error, :fetching_pull_request, error}
179184

180-
{:error, :github_pull_request, %Ecto.Changeset{} = changeset, _steps} ->
185+
{:error, :github_pull_request, %Changeset{data: %GithubPullRequest{}} = changeset, _steps} ->
181186
{:error, :validating_github_pull_request, changeset}
182187

183-
{:error, :github_issue, %Ecto.Changeset{} = changeset, _steps} ->
188+
{:error, :github_pull_request, %Changeset{data: %GithubUser{}} = changeset, _steps} ->
189+
{:error, :validating_github_user_on_github_pull_request, changeset}
190+
191+
{:error, :github_issue, %Changeset{data: %GithubIssue{}} = changeset, _steps} ->
184192
{:error, :validating_github_issue, changeset}
185193

186-
{:error, :issue_user, %Changeset{} = changeset, _steps} ->
187-
{:error, :validating_user, changeset}
194+
{:error, :github_issue, %Changeset{data: %GithubUser{}} = changeset, _steps} ->
195+
{:error, :validating_github_user_on_github_issue, changeset}
188196

189-
{:error, :issue_user, :multiple_users, _steps} ->
190-
{:error, :multiple_issue_users_match}
197+
{:error, :task_user, %Changeset{} = changeset, _steps} ->
198+
{:error, :validating_task_user, changeset}
199+
200+
{:error, :task_user, :multiple_users, _steps} ->
201+
{:error, :multiple_task_users_match}
191202

192203
{:error, :task, %Changeset{} = changeset, _steps} ->
193204
{:error, :validating_task, changeset}
194205

195-
{:error, :github_comment, %Changeset{} = changeset, _steps} ->
206+
{:error, :github_comment, %Changeset{data: %GithubComment{}} = changeset, _steps} ->
196207
{:error, :validating_github_comment, changeset}
197208

209+
{:error, :github_comment, %Changeset{data: %GithubUser{}} = changeset, _steps} ->
210+
{:error, :validating_github_user_on_github_comment, changeset}
211+
198212
{:error, :comment_user, %Changeset{} = changeset, _steps} ->
199-
{:error, :validating_user, changeset}
213+
{:error, :validating_comment_user, changeset}
200214

201215
{:error, :comment_user, :multiple_users, _steps} ->
202216
{:error, :multiple_comment_users_match}
@@ -215,10 +229,10 @@ defmodule CodeCorps.GitHub.Sync do
215229
|> Multi.run(:github_issue, fn %{repo: github_repo} ->
216230
issue_payload |> Sync.GithubIssue.create_or_update_issue(github_repo)
217231
end)
218-
|> Multi.run(:issue_user, fn %{github_issue: github_issue} ->
232+
|> Multi.run(:task_user, fn %{github_issue: github_issue} ->
219233
github_issue |> Sync.User.RecordLinker.link_to(issue_payload)
220234
end)
221-
|> Multi.run(:task, fn %{github_issue: github_issue, issue_user: user} ->
235+
|> Multi.run(:task, fn %{github_issue: github_issue, task_user: user} ->
222236
github_issue |> Sync.Task.sync_github_issue(user)
223237
end)
224238
|> Multi.run(:github_comment, fn %{github_issue: github_issue} ->
@@ -238,14 +252,17 @@ defmodule CodeCorps.GitHub.Sync do
238252
{:error, :repo, :unmatched_repository, _steps} ->
239253
{:error, :repo_not_found}
240254

241-
{:error, :github_issue, %Changeset{} = changeset, _steps} ->
255+
{:error, :github_issue, %Changeset{data: %GithubIssue{}} = changeset, _steps} ->
242256
{:error, :validating_github_issue, changeset}
243257

244-
{:error, :issue_user, %Changeset{} = changeset, _steps} ->
245-
{:error, :validating_user, changeset}
258+
{:error, :github_issue, %Changeset{data: %GithubUser{}} = changeset, _steps} ->
259+
{:error, :validating_github_user_on_github_issue, changeset}
246260

247-
{:error, :issue_user, :multiple_users, _steps} ->
248-
{:error, :multiple_issue_users_match}
261+
{:error, :task_user, %Changeset{} = changeset, _steps} ->
262+
{:error, :validating_task_user, changeset}
263+
264+
{:error, :task_user, :multiple_users, _steps} ->
265+
{:error, :multiple_task_users_match}
249266

250267
{:error, :task, %Changeset{} = changeset, _steps} ->
251268
{:error, :validating_task, changeset}
@@ -254,7 +271,7 @@ defmodule CodeCorps.GitHub.Sync do
254271
{:error, :validating_github_comment, changeset}
255272

256273
{:error, :comment_user, %Changeset{} = changeset, _steps} ->
257-
{:error, :validating_user, changeset}
274+
{:error, :validating_comment_user, changeset}
258275

259276
{:error, :comment_user, :multiple_users, _steps} ->
260277
{:error, :multiple_comment_users_match}

lib/code_corps/github/sync/user/record_linker.ex

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,31 +38,29 @@ defmodule CodeCorps.GitHub.Sync.User.RecordLinker do
3838
- If there are multiple matching users, this is an unexpected scenario and
3939
should error out.
4040
"""
41-
@spec link_to(GithubComment.t | GithubIssue.t, map) :: result
41+
@spec link_to(GithubComment.t() | GithubIssue.t(), map) :: result
4242
def link_to(%GithubComment{} = comment, %{"user" => user}), do: do_link_to(comment, user)
4343
def link_to(%GithubIssue{} = issue, %{"user" => user}), do: do_link_to(issue, user)
4444

4545
defp do_link_to(record, user_attrs) do
46-
record
47-
|> match_users
48-
|> marshall_response(user_attrs)
46+
record |> match_users() |> marshall_response(user_attrs)
4947
end
5048

51-
@spec match_users(GithubComment.t | GithubIssue.t) :: list(User.t)
49+
@spec match_users(GithubComment.t() | GithubIssue.t()) :: list(User.t())
5250
defp match_users(%GithubComment{github_id: github_id}) do
5351
query = from u in User,
5452
distinct: u.id,
5553
join: c in Comment, on: u.id == c.user_id,
5654
join: gc in GithubComment, on: gc.id == c.github_comment_id, where: gc.github_id == ^github_id
5755

58-
query |> Repo.all
56+
query |> Repo.all()
5957
end
6058
defp match_users(%GithubIssue{id: github_issue_id}) do
6159
query = from u in User,
6260
distinct: u.id,
6361
join: t in Task, on: u.id == t.user_id, where: t.github_issue_id == ^github_issue_id
6462

65-
query |> Repo.all
63+
query |> Repo.all()
6664
end
6765

6866
@spec marshall_response(list, map) :: result
@@ -75,7 +73,7 @@ defmodule CodeCorps.GitHub.Sync.User.RecordLinker do
7573
@spec find_or_create_disassociated_user(map) :: {:ok, User.t}
7674
def find_or_create_disassociated_user(%{"id" => github_id} = attrs) do
7775
case User |> Repo.get_by(github_id: github_id) do
78-
nil -> attrs |> Accounts.create_from_github
76+
nil -> attrs |> Accounts.create_from_github()
7977
%User{} = user -> {:ok, user}
8078
end
8179
end

0 commit comments

Comments
 (0)