diff --git a/lib/code_corps/github/event/installation/repos.ex b/lib/code_corps/github/event/installation/repos.ex index 9ee88cd43..fcf55fbc7 100644 --- a/lib/code_corps/github/event/installation/repos.ex +++ b/lib/code_corps/github/event/installation/repos.ex @@ -97,30 +97,23 @@ defmodule CodeCorps.GitHub.Event.Installation.Repos do end @spec create(GithubAppInstallation.t, map) :: {:ok, GithubRepo.t} - defp create(%GithubAppInstallation{} = installation, %{} = repo_attributes) do + defp create(%GithubAppInstallation{id: installation_id}, %{} = repo_attributes) do + params = + repo_attributes + |> Map.put(:github_app_installation_id, installation_id) + %GithubRepo{} - |> changeset(repo_attributes) - |> Changeset.put_assoc(:github_app_installation, installation) + |> GithubRepo.changeset(params) |> Repo.insert() end @spec update(GithubRepo.t, map) :: {:ok, GithubRepo.t} defp update(%GithubRepo{} = github_repo, %{} = repo_attributes) do github_repo - |> changeset(repo_attributes) + |> GithubRepo.changeset(repo_attributes) |> Repo.update() end - @spec changeset(GithubRepo.t, map) :: Changeset.t - defp changeset(%GithubRepo{} = github_repo, %{} = repo_attributes) do - github_repo - |> Changeset.change(repo_attributes) - |> Changeset.validate_required([ - :github_id, :name, :github_account_id, - :github_account_avatar_url, :github_account_login, :github_account_type - ]) - end - # transaction step 5 @spec mark_processed(%{processing_installation: GithubAppInstallation.t}) :: {:ok, GithubAppInstallation.t} defp mark_processed(%{processing_installation: %GithubAppInstallation{} = installation}) do diff --git a/lib/code_corps/model/github_repo.ex b/lib/code_corps/model/github_repo.ex index d70a32755..6402c93e5 100644 --- a/lib/code_corps/model/github_repo.ex +++ b/lib/code_corps/model/github_repo.ex @@ -10,10 +10,51 @@ defmodule CodeCorps.GithubRepo do field :github_account_type, :string field :github_id, :integer field :name, :string + field :sync_state, :string, default: "unsynced" + field :syncing_comments_count, :integer, default: 0 + field :syncing_issues_count, :integer, default: 0 + field :syncing_pull_requests_count, :integer, default: 0 belongs_to :github_app_installation, CodeCorps.GithubAppInstallation has_many :project_github_repos, CodeCorps.ProjectGithubRepo timestamps() end + + @doc """ + Builds a changeset based on the `struct` and `params`. + """ + def changeset(struct, params \\ %{}) do + struct + |> cast(params, [ + :github_account_id, :github_account_avatar_url, :github_account_login, + :github_account_type, :github_app_installation_id, :github_id, :name, + :sync_state, :syncing_comments_count, :syncing_issues_count, + :syncing_pull_requests_count + ]) + |> validate_required([ + :github_account_id, :github_account_avatar_url, :github_account_login, + :github_account_type, :github_id, :name + ]) + |> assoc_constraint(:github_app_installation) + end + + def update_sync_changeset(struct, params) do + struct + |> changeset(params) + |> validate_inclusion(:sync_state, sync_states()) + end + + def sync_states do + ~w{ + unsynced + fetching_pull_requests errored_fetching_pull_requests + syncing_pull_requests errored_syncing_pull_requests + fetching_issues errored_fetching_issues + syncing_issues errored_syncing_issues + fetching_comments errored_fetching_comments + syncing_comments errored_syncing_comments + receiving_webhooks + } + end end diff --git a/priv/repo/migrations/20171030182857_add_sync_statuses_to_github_repo.exs b/priv/repo/migrations/20171030182857_add_sync_statuses_to_github_repo.exs new file mode 100644 index 000000000..31199c160 --- /dev/null +++ b/priv/repo/migrations/20171030182857_add_sync_statuses_to_github_repo.exs @@ -0,0 +1,14 @@ +defmodule CodeCorps.Repo.Migrations.AddSyncStatusesToGithubRepo do + use Ecto.Migration + + def change do + alter table(:github_repos) do + add :sync_state, :string, default: "unsynced" + add :syncing_comments_count, :integer, default: 0 + add :syncing_issues_count, :integer, default: 0 + add :syncing_pull_requests_count, :integer, default: 0 + end + + create index(:github_repos, [:sync_state]) + end +end diff --git a/priv/repo/structure.sql b/priv/repo/structure.sql index e3ca24a60..c8473dc5a 100644 --- a/priv/repo/structure.sql +++ b/priv/repo/structure.sql @@ -2,7 +2,7 @@ -- PostgreSQL database dump -- --- Dumped from database version 10.0 +-- Dumped from database version 9.5.9 -- Dumped by pg_dump version 10.0 SET statement_timeout = 0; @@ -425,7 +425,11 @@ CREATE TABLE github_repos ( github_account_type character varying(255), github_app_installation_id bigint, inserted_at timestamp without time zone NOT NULL, - updated_at timestamp without time zone NOT NULL + updated_at timestamp without time zone NOT NULL, + sync_state character varying(255) DEFAULT 'unsynced'::character varying, + syncing_comments_count integer DEFAULT 0, + syncing_issues_count integer DEFAULT 0, + syncing_pull_requests_count integer DEFAULT 0 ); @@ -2473,6 +2477,13 @@ CREATE INDEX github_repos_github_app_installation_id_index ON github_repos USING CREATE UNIQUE INDEX github_repos_github_id_index ON github_repos USING btree (github_id); +-- +-- Name: github_repos_sync_state_index; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX github_repos_sync_state_index ON github_repos USING btree (sync_state); + + -- -- Name: index_categories_on_slug; Type: INDEX; Schema: public; Owner: - -- @@ -3681,5 +3692,5 @@ ALTER TABLE ONLY user_tasks -- PostgreSQL database dump complete -- -INSERT INTO "schema_migrations" (version) VALUES (20160723215749), (20160804000000), (20160804001111), (20160805132301), (20160805203929), (20160808143454), (20160809214736), (20160810124357), (20160815125009), (20160815143002), (20160816020347), (20160816034021), (20160817220118), (20160818000944), (20160818132546), (20160820113856), (20160820164905), (20160822002438), (20160822004056), (20160822011624), (20160822020401), (20160822044612), (20160830081224), (20160830224802), (20160911233738), (20160912002705), (20160912145957), (20160918003206), (20160928232404), (20161003185918), (20161019090945), (20161019110737), (20161020144622), (20161021131026), (20161031001615), (20161121005339), (20161121014050), (20161121043941), (20161121045709), (20161122015942), (20161123081114), (20161123150943), (20161124085742), (20161125200620), (20161126045705), (20161127054559), (20161205024856), (20161207112519), (20161209192504), (20161212005641), (20161214005935), (20161215052051), (20161216051447), (20161218005913), (20161219160401), (20161219163909), (20161220141753), (20161221085759), (20161226213600), (20161231063614), (20170102130055), (20170102181053), (20170104113708), (20170104212623), (20170104235423), (20170106013143), (20170115035159), (20170115230549), (20170121014100), (20170131234029), (20170201014901), (20170201025454), (20170201035458), (20170201183258), (20170220032224), (20170224233516), (20170226050552), (20170228085250), (20170308214128), (20170308220713), (20170308222552), (20170313130611), (20170318032449), (20170318082740), (20170324194827), (20170424215355), (20170501225441), (20170505224222), (20170526095401), (20170602000208), (20170622205732), (20170626231059), (20170628092119), (20170628213609), (20170629183404), (20170630140136), (20170706132431), (20170707213648), (20170711122252), (20170717092127), (20170725060612), (20170727052644), (20170731130121), (20170814131722), (20170913114958), (20170921014405), (20170925214512), (20170925230419), (20170926134646), (20170927100300), (20170928234412), (20171003134956), (20171003225853), (20171006063358), (20171006161407), (20171012215106), (20171012221231), (20171016125229), (20171016125516), (20171016223356), (20171016235656), (20171017235433), (20171019191035), (20171025184225), (20171026010933), (20171027061833), (20171028011642), (20171028173508); +INSERT INTO "schema_migrations" (version) VALUES (20160723215749), (20160804000000), (20160804001111), (20160805132301), (20160805203929), (20160808143454), (20160809214736), (20160810124357), (20160815125009), (20160815143002), (20160816020347), (20160816034021), (20160817220118), (20160818000944), (20160818132546), (20160820113856), (20160820164905), (20160822002438), (20160822004056), (20160822011624), (20160822020401), (20160822044612), (20160830081224), (20160830224802), (20160911233738), (20160912002705), (20160912145957), (20160918003206), (20160928232404), (20161003185918), (20161019090945), (20161019110737), (20161020144622), (20161021131026), (20161031001615), (20161121005339), (20161121014050), (20161121043941), (20161121045709), (20161122015942), (20161123081114), (20161123150943), (20161124085742), (20161125200620), (20161126045705), (20161127054559), (20161205024856), (20161207112519), (20161209192504), (20161212005641), (20161214005935), (20161215052051), (20161216051447), (20161218005913), (20161219160401), (20161219163909), (20161220141753), (20161221085759), (20161226213600), (20161231063614), (20170102130055), (20170102181053), (20170104113708), (20170104212623), (20170104235423), (20170106013143), (20170115035159), (20170115230549), (20170121014100), (20170131234029), (20170201014901), (20170201025454), (20170201035458), (20170201183258), (20170220032224), (20170224233516), (20170226050552), (20170228085250), (20170308214128), (20170308220713), (20170308222552), (20170313130611), (20170318032449), (20170318082740), (20170324194827), (20170424215355), (20170501225441), (20170505224222), (20170526095401), (20170602000208), (20170622205732), (20170626231059), (20170628092119), (20170628213609), (20170629183404), (20170630140136), (20170706132431), (20170707213648), (20170711122252), (20170717092127), (20170725060612), (20170727052644), (20170731130121), (20170814131722), (20170913114958), (20170921014405), (20170925214512), (20170925230419), (20170926134646), (20170927100300), (20170928234412), (20171003134956), (20171003225853), (20171006063358), (20171006161407), (20171012215106), (20171012221231), (20171016125229), (20171016125516), (20171016223356), (20171016235656), (20171017235433), (20171019191035), (20171025184225), (20171026010933), (20171027061833), (20171028011642), (20171028173508), (20171030182857); diff --git a/test/lib/code_corps/model/github_repo_test.exs b/test/lib/code_corps/model/github_repo_test.exs index 53a12f9df..1cb4d9835 100644 --- a/test/lib/code_corps/model/github_repo_test.exs +++ b/test/lib/code_corps/model/github_repo_test.exs @@ -3,6 +3,45 @@ defmodule CodeCorps.GithubRepoTest do alias CodeCorps.GithubRepo + @valid_attrs %{ + github_account_avatar_url: "https://avatars.githubusercontent.com/u/6752317?v=3", + github_account_id: 6752317, + github_account_login: "baxterthehacker", + github_account_type: "User", + github_id: 35129377, + name: "public-repo", + } + @invalid_attrs %{} + + describe "changeset/2" do + test "with valid attributes" do + changeset = GithubRepo.changeset(%GithubRepo{}, @valid_attrs) + assert changeset.valid? + end + + test "with invalid attributes" do + changeset = GithubRepo.changeset(%GithubRepo{}, @invalid_attrs) + refute changeset.valid? + end + end + + describe "update_sync_changeset/2" do + test "with valid attributes" do + GithubRepo.sync_states |> Enum.each(fn state -> + attrs = @valid_attrs |> Map.put(:sync_state, state) + changeset = GithubRepo.update_sync_changeset(%GithubRepo{}, attrs) + assert changeset.valid? + end) + end + + test "with invalid attributes" do + attrs = @valid_attrs |> Map.put(:sync_state, "not_a_valid_sync_state") + changeset = GithubRepo.update_sync_changeset(%GithubRepo{}, attrs) + refute changeset.valid? + assert changeset.errors[:sync_state] == {"is invalid", [validation: :inclusion]} + end + end + test "deletes associated ProjectGithubRepo records when deleting GithubRepo" do github_repo = insert(:github_repo) insert_pair(:project_github_repo, github_repo: github_repo)