Skip to content

Commit 0209b99

Browse files
authored
Merge pull request #720 from christopherstyles/710-make-user-owner-of-project
Make user an owner of a project directly
2 parents 6d6e297 + d089004 commit 0209b99

File tree

9 files changed

+74
-15
lines changed

9 files changed

+74
-15
lines changed

blueprint/api.apib

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2374,6 +2374,8 @@ This endpoint allows you to check whether a username is valid (by running a vali
23742374
+ relationships
23752375
+ organizations
23762376
+ data(Organization Resource Identifier) - Identifier of organization this project is being created for
2377+
+ owner
2378+
+ data(User Resource Identifier) - Identifier of owner (user) this project belongs to
23772379

23782380
## Project Resource (object)
23792381
+ include Project Resource Identifier
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
defmodule CodeCorps.Repo.Migrations.AddOwnerToProjects do
2+
use Ecto.Migration
3+
4+
def change do
5+
alter table(:projects) do
6+
add :owner_id, references(:users, on_delete: :nothing)
7+
end
8+
end
9+
end

priv/repo/structure.sql

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,8 @@ CREATE TABLE projects (
334334
total_monthly_donated integer DEFAULT 0,
335335
approved boolean DEFAULT false,
336336
cloudinary_public_id character varying(255),
337-
default_color character varying(255)
337+
default_color character varying(255),
338+
owner_id integer
338339
);
339340

340341

@@ -2227,6 +2228,14 @@ ALTER TABLE ONLY projects
22272228
ADD CONSTRAINT projects_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id);
22282229

22292230

2231+
--
2232+
-- Name: projects_owner_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
2233+
--
2234+
2235+
ALTER TABLE ONLY projects
2236+
ADD CONSTRAINT projects_owner_id_fkey FOREIGN KEY (owner_id) REFERENCES users(id);
2237+
2238+
22302239
--
22312240
-- Name: role_skills_role_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
22322241
--
@@ -2519,5 +2528,5 @@ ALTER TABLE ONLY user_tasks
25192528
-- PostgreSQL database dump complete
25202529
--
25212530

2522-
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);
2531+
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), (20170226050552);
25232532

test/controllers/project_controller_test.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ defmodule CodeCorps.ProjectControllerTest do
7272
@tag :authenticated
7373
test "creates and renders resource when attributes are valid", %{conn: conn, current_user: current_user} do
7474
organization = insert(:organization)
75+
user = insert(:user)
7576
insert(:organization_membership, role: "admin", member: current_user, organization: organization)
76-
attrs = @valid_attrs |> Map.merge(%{organization: organization})
77+
attrs = @valid_attrs |> Map.merge(%{organization: organization, owner_id: user.id})
7778
response = conn |> request_create(attrs)
7879
assert %{assigns: %{data: %{task_lists: [_inbox, _backlog, _in_progress, _done]}}} = response
7980
assert response |> json_response(201)

test/models/project_test.exs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ defmodule CodeCorps.ProjectTest do
33

44
alias CodeCorps.Project
55

6-
@valid_attrs %{title: "A title"}
7-
@invalid_attrs %{}
6+
describe "changeset" do
7+
@valid_attrs %{title: "A title"}
8+
@invalid_attrs %{}
89

9-
describe "changeset/2" do
10-
test "with valid attributes is valid" do
10+
test "with valid attributes" do
1111
changeset = Project.changeset(%Project{}, @valid_attrs)
1212
assert changeset.valid?
1313
end
1414

15-
test "with invalid attributes is invalid and has errors" do
15+
test "with invalid attributes" do
1616
changeset = Project.changeset(%Project{}, @invalid_attrs)
1717
refute changeset.valid?
1818

@@ -43,17 +43,31 @@ defmodule CodeCorps.ProjectTest do
4343
end
4444
end
4545

46-
describe "create_changeset/2" do
46+
describe "create_changeset" do
47+
@valid_attrs %{title: "A title", organization_id: 1, owner_id: 1}
48+
@invalid_attrs %{}
49+
50+
test "with valid attributes" do
51+
changeset = Project.create_changeset(%Project{}, @valid_attrs)
52+
assert changeset.valid?
53+
end
54+
55+
test "with invalid attributes" do
56+
changeset = Project.create_changeset(%Project{}, @invalid_attrs)
57+
refute changeset.valid?
58+
end
59+
4760
test "accepts setting of organization_id" do
4861
changeset = Project.create_changeset(%Project{}, %{organization_id: 1})
4962
assert {:ok, 1} == changeset |> fetch_change(:organization_id)
5063
end
5164

5265
test "associates the ordered default task lists to the project" do
5366
organization = insert(:organization)
67+
user = insert(:user)
5468
changeset = Project.create_changeset(
5569
%Project{},
56-
%{organization_id: organization.id, title: "Title"}
70+
%{organization_id: organization.id, title: "Title", owner_id: user.id}
5771
)
5872

5973
{_, project} = Repo.insert(changeset)
@@ -63,9 +77,21 @@ defmodule CodeCorps.ProjectTest do
6377
assert Enum.all?(task_list_orders), "some of the orders are not set (nil)"
6478
assert task_list_orders == Enum.sort(task_list_orders), "task lists order does not correspond to their position"
6579
end
80+
81+
test "ensures owner (user) actually exists" do
82+
organization = insert(:organization)
83+
attrs = Map.merge(@valid_attrs, %{organization_id: organization.id})
84+
85+
changeset = Project.create_changeset(%Project{}, attrs)
86+
87+
{result, changeset} = changeset |> Repo.insert
88+
89+
assert result == :error
90+
changeset |> assert_error_message(:owner, "does not exist")
91+
end
6692
end
6793

68-
describe "update_changeset/2" do
94+
describe "update_changeset" do
6995
test "rejects setting of organization id" do
7096
changeset = Project.update_changeset(%Project{}, %{organization_id: 1})
7197
assert :error == changeset |> fetch_change(:organization_id)

test/support/factories.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ defmodule CodeCorps.Factories do
7676
%CodeCorps.Project{
7777
title: sequence(:title, &"Project #{&1}"),
7878
slug: sequence(:slug, &"project-#{&1}"),
79-
organization: build(:organization)
79+
organization: build(:organization),
80+
owner: build(:user)
8081
}
8182
end
8283

test/views/project_view_test.exs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ defmodule CodeCorps.ProjectViewTest do
22
use CodeCorps.ViewCase
33

44
test "renders all attributes and relationships properly" do
5+
user = insert(:user)
56
organization = insert(:organization)
6-
project = insert(:project, organization: organization, total_monthly_donated: 5000, default_color: "blue")
7+
project = insert(:project, organization: organization, owner: user, total_monthly_donated: 5000, default_color: "blue")
78

89
donation_goal = insert(:donation_goal, project: project)
910
project_category = insert(:project_category, project: project)
@@ -47,6 +48,12 @@ defmodule CodeCorps.ProjectViewTest do
4748
"type" => "organization"
4849
}
4950
},
51+
"owner" => %{
52+
"data" => %{
53+
"id" => user.id |> Integer.to_string,
54+
"type" => "user"
55+
}
56+
},
5057
"project-categories" => %{
5158
"data" => [
5259
%{

web/models/project.ex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ defmodule CodeCorps.Project do
2626
field :total_monthly_donated, :integer, default: 0
2727

2828
belongs_to :organization, CodeCorps.Organization
29+
belongs_to :owner, CodeCorps.User
2930

3031
has_one :stripe_connect_plan, CodeCorps.StripeConnectPlan
3132

@@ -57,8 +58,10 @@ defmodule CodeCorps.Project do
5758
"""
5859
def create_changeset(struct, params) do
5960
struct
60-
|> cast(params, [:organization_id])
6161
|> changeset(params)
62+
|> cast(params, [:organization_id, :owner_id])
63+
|> validate_required(:owner_id)
64+
|> assoc_constraint(:owner)
6265
|> put_assoc(:task_lists, TaskList.default_task_lists())
6366
|> generate_icon_color(:default_color)
6467
end

web/views/project_view.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ defmodule CodeCorps.ProjectView do
55
use CodeCorps.PreloadHelpers,
66
default_preloads: [
77
:donation_goals, [organization: :stripe_connect_account],
8-
:project_categories, :project_skills, :stripe_connect_plan, :task_lists, :tasks
8+
:owner, :project_categories, :project_skills, :stripe_connect_plan, :task_lists, :tasks
99
]
1010
use CodeCorps.Web, :view
1111
use JaSerializer.PhoenixView
@@ -17,6 +17,7 @@ defmodule CodeCorps.ProjectView do
1717
:inserted_at, :total_monthly_donated, :updated_at]
1818

1919
has_one :organization, serializer: CodeCorps.OrganizationView
20+
has_one :owner, serializer: CodeCorps.UserView
2021
has_one :stripe_connect_plan, serializer: CodeCorps.StripeConnectPlanView
2122

2223
has_many :donation_goals, serializer: CodeCorps.DonationGoalView, identifiers: :always

0 commit comments

Comments
 (0)