diff --git a/lib/code_corps/transition/user_state.ex b/lib/code_corps/transition/user_state.ex index 621f79cfc..e7b3169dd 100644 --- a/lib/code_corps/transition/user_state.ex +++ b/lib/code_corps/transition/user_state.ex @@ -1,8 +1,24 @@ defmodule CodeCorps.Transition.UserState do def next(_current, nil), do: nil + def next("signed_up", "edit_profile"), do: {:ok, "edited_profile"} + + # Select/skip categories def next("edited_profile", "select_categories"), do: {:ok, "selected_categories"} + def next("edited_profile", "skip_categories"), do: {:ok, "skipped_categories"} + + # Select/skip roles def next("selected_categories", "select_roles"), do: {:ok, "selected_roles"} + def next("selected_categories", "skip_roles"), do: {:ok, "skipped_roles"} + def next("skipped_categories", "select_roles"), do: {:ok, "selected_roles"} + def next("skipped_categories", "skip_roles"), do: {:ok, "skipped_roles"} + + # Select/skip skills def next("selected_roles", "select_skills"), do: {:ok, "selected_skills"} + def next("selected_roles", "skip_skills"), do: {:ok, "skipped_skills"} + def next("skipped_roles", "select_skills"), do: {:ok, "selected_skills"} + def next("skipped_roles", "skip_skills"), do: {:ok, "skipped_skills"} + + # Invalid transitions def next(current, invalid_transition), do: {:error, "invalid transition #{invalid_transition} from #{current}"} end diff --git a/priv/repo/migrations/20170324194827_add_sign_up_context_to_users.exs b/priv/repo/migrations/20170324194827_add_sign_up_context_to_users.exs new file mode 100644 index 000000000..f2b087f61 --- /dev/null +++ b/priv/repo/migrations/20170324194827_add_sign_up_context_to_users.exs @@ -0,0 +1,9 @@ +defmodule CodeCorps.Repo.Migrations.AddSignUpContextToUsers do + use Ecto.Migration + + def change do + alter table(:users) do + add :sign_up_context, :string, default: "default" + end + end +end diff --git a/priv/repo/structure.sql b/priv/repo/structure.sql index 7b30647db..2bd949af7 100644 --- a/priv/repo/structure.sql +++ b/priv/repo/structure.sql @@ -1319,7 +1319,8 @@ CREATE TABLE users ( admin boolean DEFAULT false NOT NULL, state character varying(255) DEFAULT 'signed_up'::character varying, cloudinary_public_id character varying(255), - default_color character varying(255) + default_color character varying(255), + sign_up_context character varying(255) DEFAULT 'default'::character varying ); @@ -2593,5 +2594,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); +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); diff --git a/test/lib/code_corps/transition/user_state_test.exs b/test/lib/code_corps/transition/user_state_test.exs new file mode 100644 index 000000000..f719aa6ea --- /dev/null +++ b/test/lib/code_corps/transition/user_state_test.exs @@ -0,0 +1,34 @@ +defmodule CodeCorps.Transition.UserStateTest do + use ExUnit.Case, async: true + + alias CodeCorps.Transition.UserState + + describe "next/2" do + test "returns nil if state_transition is nil" do + assert UserState.next("foo", nil) == nil + end + + test "returns {:ok, next_state} for valid transitions" do + assert UserState.next("signed_up", "edit_profile") == {:ok, "edited_profile"} + + assert UserState.next("edited_profile", "select_categories") == {:ok, "selected_categories"} + assert UserState.next("edited_profile", "skip_categories") == {:ok, "skipped_categories"} + + assert UserState.next("selected_categories", "select_roles") == {:ok, "selected_roles"} + assert UserState.next("selected_categories", "skip_roles") == {:ok, "skipped_roles"} + + assert UserState.next("skipped_categories", "select_roles") == {:ok, "selected_roles"} + assert UserState.next("skipped_categories", "skip_roles") == {:ok, "skipped_roles"} + + assert UserState.next("selected_roles", "select_skills") == {:ok, "selected_skills"} + assert UserState.next("selected_roles", "skip_skills") == {:ok, "skipped_skills"} + + assert UserState.next("skipped_roles", "select_skills") == {:ok, "selected_skills"} + assert UserState.next("skipped_roles", "skip_skills") == {:ok, "skipped_skills"} + end + + test "returns {:error, message} for invalid transitions" do + assert UserState.next("foo", "bar") == {:error, "invalid transition bar from foo"} + end + end +end diff --git a/test/models/user_test.exs b/test/models/user_test.exs index 0ee9f768a..f3f10041c 100644 --- a/test/models/user_test.exs +++ b/test/models/user_test.exs @@ -64,15 +64,11 @@ defmodule CodeCorps.UserTest do assert_error_message(changeset, :username, "has already been taken") end - test "allows setting state to 'signed_up_donating'" do - attrs = @valid_attrs |> Map.put(:state, "signed_up_donating") + test "allows setting sign_up_context to 'donation'" do + attrs = @valid_attrs |> Map.put(:sign_up_context, "donation") changeset = User.registration_changeset(%User{}, attrs) assert changeset.valid? - assert changeset |> Ecto.Changeset.get_change(:state) == "signed_up_donating" - - attrs = @valid_attrs |> Map.put(:state, "selected_skills") - changeset = User.registration_changeset(%User{}, attrs) - refute changeset.valid? + assert changeset |> Ecto.Changeset.get_change(:sign_up_context) == "donation" end end diff --git a/test/views/user_view_test.exs b/test/views/user_view_test.exs index 410264402..a03293f42 100644 --- a/test/views/user_view_test.exs +++ b/test/views/user_view_test.exs @@ -33,6 +33,7 @@ defmodule CodeCorps.UserViewTest do "name" => "First Last", "photo-large-url" => "#{host}/icons/user_default_large_blue.png", "photo-thumb-url" => "#{host}/icons/user_default_thumb_blue.png", + "sign-up-context" => "default", "state" => "signed_up", "state-transition" => nil, "twitter" => user.twitter, diff --git a/web/models/user.ex b/web/models/user.ex index 28279cd44..e5d294c70 100644 --- a/web/models/user.ex +++ b/web/models/user.ex @@ -26,6 +26,7 @@ defmodule CodeCorps.User do field :last_name, :string field :password, :string, virtual: true field :password_confirmation, :string, virtual: true + field :sign_up_context, :string, default: "default" field :twitter, :string field :username, :string field :website, :string @@ -71,11 +72,11 @@ defmodule CodeCorps.User do def registration_changeset(struct, params) do struct |> changeset(params) - |> cast(params, [:password, :username, :state]) + |> cast(params, [:password, :sign_up_context, :username]) |> validate_required([:password, :username]) |> validate_length(:password, min: 6) |> validate_length(:username, min: 1, max: 39) - |> validate_inclusion(:state, ["signed_up_donating"]) + |> validate_inclusion(:sign_up_context, ["default", "donation"]) |> validate_slug(:username) |> unique_constraint(:username, name: :users_lower_username_index) |> unique_constraint(:email) diff --git a/web/views/user_view.ex b/web/views/user_view.ex index 72c82162f..83594c63e 100644 --- a/web/views/user_view.ex +++ b/web/views/user_view.ex @@ -12,8 +12,8 @@ defmodule CodeCorps.UserView do attributes [ :biography, :cloudinary_public_id, :email, :first_name, :last_name, :name, - :photo_large_url, :photo_thumb_url, :state, :state_transition, - :twitter, :username, :website, :inserted_at, :updated_at + :photo_large_url, :photo_thumb_url, :sign_up_context, :state, + :state_transition, :twitter, :username, :website, :inserted_at, :updated_at ] has_one :slugged_route, serializer: CodeCorps.SluggedRouteView