Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions lib/code_corps/github/adapters/app_installation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ defmodule CodeCorps.GitHub.Adapters.AppInstallation do
`GithubAppInstallation`.
"""

alias CodeCorps.{
Adapter.MapTransformer,
GithubAppInstallation
}

@installation_event_mapping [
{:github_account_avatar_url, ["installation", "account", "avatar_url"]},
{:github_account_id, ["installation", "account", "id"]},
Expand All @@ -22,4 +27,22 @@ defmodule CodeCorps.GitHub.Adapters.AppInstallation do
payload
|> CodeCorps.Adapter.MapTransformer.transform(@installation_event_mapping)
end

@github_app_installation_to_repo_mapping [
{:github_account_avatar_url, [:github_account_avatar_url]},
{:github_account_id, [:github_account_id]},
{:github_account_login, [:github_account_login]},
{:github_account_type, [:github_account_type]}
]

@doc ~S"""
Converts a `GithubAppInstallation` record attributes into a map of attributes
that can be used for a `GithubRepo` record.
"""
@spec to_github_repo_attrs(GithubAppInstallation.t) :: map
def to_github_repo_attrs(%GithubAppInstallation{} = installation) do
installation
|> Map.from_struct
|> MapTransformer.transform(@github_app_installation_to_repo_mapping)
end
end
8 changes: 4 additions & 4 deletions lib/code_corps/github/event/installation/changeset_builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ defmodule CodeCorps.GitHub.Event.Installation.ChangesetBuilder do
github_app_installation
|> Changeset.change(attrs)
|> Changeset.put_change(:installed, true)
|> inferr_origin()
|> infer_origin()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops! That one's on me.

|> Changeset.unique_constraint(:github_id, name: :github_app_installations_github_id_index)
end

Expand All @@ -47,12 +47,12 @@ defmodule CodeCorps.GitHub.Event.Installation.ChangesetBuilder do
|> Changeset.assoc_constraint(:user)
end

@spec inferr_origin(Changeset.t) :: Changeset.t
defp inferr_origin(%Changeset{
@spec infer_origin(Changeset.t) :: Changeset.t
defp infer_origin(%Changeset{
data: %GithubAppInstallation{id: nil}} = changeset) do

changeset
|> Changeset.put_change(:origin, "github")
end
defp inferr_origin(%Changeset{} = changeset), do: changeset
defp infer_origin(%Changeset{} = changeset), do: changeset
end
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ defmodule CodeCorps.GitHub.Event.InstallationRepositories do
Repo
}

alias CodeCorps.GitHub.Adapters.AppInstallation, as: AppInstallationAdapter
alias Ecto.{Changeset, Multi}

@type outcome :: {:ok, list(GithubRepo.t)} |
Expand Down Expand Up @@ -91,11 +92,19 @@ defmodule CodeCorps.GitHub.Event.InstallationRepositories do
end

@spec find_or_create(GithubAppInstallation.t, map) :: {:ok, GithubRepo.t} | {:error, Changeset.t}
defp find_or_create(%GithubAppInstallation{} = installation, %{"id" => github_id, "name" => name} = attrs) do
defp find_or_create(%GithubAppInstallation{} = installation, %{"id" => id, "name" => name} = attrs) do
case find_repo(installation, attrs) do
nil ->
installation_repo_attributes =
installation
|> AppInstallationAdapter.to_github_repo_attrs()

params =
%{github_id: id, name: name}
|> Map.merge(installation_repo_attributes)

%GithubRepo{}
|> Changeset.change(%{github_id: github_id, name: name})
|> Changeset.change(params)
|> Changeset.put_assoc(:github_app_installation, installation)
|> Repo.insert()
%GithubRepo{} = github_repo ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,32 +32,56 @@ defmodule CodeCorps.GitHub.Event.InstallationRepositoriesTest do

test "creates repos" do
%{
"installation" => %{"id" => installation_github_id},
"installation" => %{
"account" => %{
"avatar_url" => installation_account_avatar_url,
"id" => installation_account_id,
"login" => installation_account_login,
"type" => installation_account_type
},
"id" => installation_github_id
},
"repositories_added" => [repo_1_payload, repo_2_payload]
} = @payload

%{id: installation_id} = insert(:github_app_installation, github_id: installation_github_id)
%{id: installation_id} = insert(:github_app_installation, github_account_avatar_url: installation_account_avatar_url, github_account_id: installation_account_id, github_account_login: installation_account_login, github_account_type: installation_account_type, github_id: installation_github_id)

{:ok, [%GithubRepo{}, %GithubRepo{}]} = InstallationRepositories.handle(@payload)

github_repo_1 = Repo.get_by(GithubRepo, github_id: repo_1_payload["id"])
assert github_repo_1
assert github_repo_1.name == repo_1_payload["name"]
assert github_repo_1.github_account_avatar_url == installation_account_avatar_url
assert github_repo_1.github_account_id == installation_account_id
assert github_repo_1.github_account_login == installation_account_login
assert github_repo_1.github_account_type == installation_account_type
assert github_repo_1.github_app_installation_id == installation_id

github_repo_2 = Repo.get_by(GithubRepo, github_id: repo_2_payload["id"])
assert github_repo_2
assert github_repo_2.name == repo_2_payload["name"]
assert github_repo_2.github_account_avatar_url == installation_account_avatar_url
assert github_repo_2.github_account_id == installation_account_id
assert github_repo_2.github_account_login == installation_account_login
assert github_repo_2.github_account_type == installation_account_type
assert github_repo_2.github_app_installation_id == installation_id
end

test "skips creating existing repos" do
%{
"installation" => %{"id" => installation_github_id},
"installation" => %{
"account" => %{
"avatar_url" => installation_account_avatar_url,
"id" => installation_account_id,
"login" => installation_account_login,
"type" => installation_account_type
},
"id" => installation_github_id
},
"repositories_added" => [repo_1_payload, repo_2_payload]
} = @payload

installation = insert(:github_app_installation, github_id: installation_github_id)
installation = insert(:github_app_installation, github_account_avatar_url: installation_account_avatar_url, github_account_id: installation_account_id, github_account_login: installation_account_login, github_account_type: installation_account_type, github_id: installation_github_id)
preinserted_repo = insert(:github_repo, github_app_installation: installation, github_id: repo_1_payload["id"])

{:ok, [%GithubRepo{}, %GithubRepo{}]} = InstallationRepositories.handle(@payload)
Expand All @@ -68,6 +92,10 @@ defmodule CodeCorps.GitHub.Event.InstallationRepositoriesTest do
github_repo_2 = Repo.get_by(GithubRepo, github_id: repo_2_payload["id"])
assert github_repo_2
assert github_repo_2.name == repo_2_payload["name"]
assert github_repo_2.github_account_avatar_url == installation_account_avatar_url
assert github_repo_2.github_account_id == installation_account_id
assert github_repo_2.github_account_login == installation_account_login
assert github_repo_2.github_account_type == installation_account_type
assert github_repo_2.github_app_installation_id == installation.id

assert Repo.aggregate(GithubRepo, :count, :id) == 2
Expand Down