Add settings model (#54)

* Adds a basic settings model

* Added more settings methods; Hooked up initial settings runner to app boot

* Update onboarding flow to use settings model instead of session data
This commit is contained in:
Kieran
2024-03-07 17:32:12 -08:00
committed by GitHub
parent ef4a5cc99f
commit 0948bebb9d
18 changed files with 381 additions and 76 deletions
+108
View File
@@ -0,0 +1,108 @@
defmodule Pinchflat.SettingsTest do
use Pinchflat.DataCase
alias Pinchflat.Settings
alias Pinchflat.Settings.Setting
# NOTE: We're treating some of these tests differently
# than in other modules because certain settings
# are always created on app boot (including in the test env),
# so we can't treat these like a clean slate.
describe "list_settings/0" do
test "returns all settings" do
Settings.set!("foo", "bar")
results = Settings.list_settings()
assert Enum.all?(results, fn setting -> match?(%Setting{}, setting) end)
end
end
describe "set/2" do
test "creates a new setting if one does not exist" do
original = Repo.aggregate(Setting, :count, :id)
Settings.set!("foo", "bar")
assert Repo.aggregate(Setting, :count, :id) == original + 1
end
test "updates an existing setting if one exists" do
Settings.set!("foo", "bar")
original = Repo.aggregate(Setting, :count, :id)
Settings.set!("foo", "baz")
assert Repo.aggregate(Setting, :count, :id) == original
assert Settings.get!("foo") == "baz"
end
test "returns the parsed value" do
assert Settings.set!("foo", true) == true
assert Settings.set!("foo", false) == false
assert Settings.set!("foo", 123) == 123
assert Settings.set!("foo", 12.34) == 12.34
assert Settings.set!("foo", "bar") == "bar"
end
test "allows for atom keys" do
assert Settings.set!(:foo, "bar") == "bar"
end
test "blows up when an unsupported datatype is used" do
assert_raise FunctionClauseError, fn ->
Settings.set!("foo", nil)
end
end
end
describe "set/3" do
test "allows manual specification of datatype" do
assert Settings.set!("foo", "true", :boolean) == true
assert Settings.set!("foo", "false", :boolean) == false
assert Settings.set!("foo", "123", :integer) == 123
assert Settings.set!("foo", "12.34", :float) == 12.34
end
end
describe "get/1" do
test "returns the value of the setting" do
Settings.set!("str", "bar")
Settings.set!("bool", true)
Settings.set!("int", 123)
Settings.set!("float", 12.34)
assert Settings.get!("str") == "bar"
assert Settings.get!("bool") == true
assert Settings.get!("int") == 123
assert Settings.get!("float") == 12.34
end
test "allows for atom keys" do
Settings.set!("str", "bar")
assert Settings.get!(:str) == "bar"
end
test "blows up when the setting does not exist" do
assert_raise Ecto.NoResultsError, fn ->
Settings.get!("foo")
end
end
end
describe "fetch/2" do
test "creates a setting if one doesn't exist" do
original = Repo.aggregate(Setting, :count, :id)
assert Settings.fetch!("foo", "bar") == "bar"
assert Repo.aggregate(Setting, :count, :id) == original + 1
end
test "returns an existing setting if one does exist" do
Settings.set!("foo", "bar")
assert Settings.fetch!("foo", "baz") == "bar"
end
end
describe "fetch/3" do
test "allows manual specification of datatype" do
assert Settings.fetch!("foo", "true", :boolean) == true
end
end
end
+16
View File
@@ -0,0 +1,16 @@
defmodule Pinchflat.StartupTasksTest do
use Pinchflat.DataCase
alias Pinchflat.Settings
# Since this runs on app boot (even in the test env),
# any actions in the `init/1` function will already have
# run. So we can only test the side effects of those actions,
# rather than the actions themselves.
describe "apply_default_settings" do
test "sets default settings" do
assert Settings.get!(:onboarding) == true
end
end
end
@@ -6,6 +6,7 @@ defmodule PinchflatWeb.MediaProfileControllerTest do
import Pinchflat.ProfilesFixtures
alias Pinchflat.Repo
alias Pinchflat.Settings
@create_attrs %{name: "some name", output_path_template: "some output_path_template"}
@update_attrs %{
@@ -14,6 +15,12 @@ defmodule PinchflatWeb.MediaProfileControllerTest do
}
@invalid_attrs %{name: nil, output_path_template: nil}
setup do
Settings.set!(:onboarding, false)
:ok
end
describe "index" do
test "lists all media_profiles", %{conn: conn} do
conn = get(conn, ~p"/media_profiles")
@@ -27,13 +34,11 @@ defmodule PinchflatWeb.MediaProfileControllerTest do
assert html_response(conn, 200) =~ "New Media Profile"
end
test "renders correct layout when onboarding", %{session_conn: session_conn} do
session_conn =
session_conn
|> put_session(:onboarding, true)
|> get(~p"/media_profiles/new")
test "renders correct layout when onboarding", %{conn: conn} do
Settings.set!(:onboarding, true)
conn = get(conn, ~p"/media_profiles/new")
refute html_response(session_conn, 200) =~ "MENU"
refute html_response(conn, 200) =~ "MENU"
end
end
@@ -53,22 +58,18 @@ defmodule PinchflatWeb.MediaProfileControllerTest do
assert html_response(conn, 200) =~ "New Media Profile"
end
test "redirects to onboarding when onboarding", %{session_conn: session_conn} do
session_conn =
session_conn
|> put_session(:onboarding, true)
|> post(~p"/media_profiles", media_profile: @create_attrs)
test "redirects to onboarding when onboarding", %{conn: conn} do
Settings.set!(:onboarding, true)
conn = post(conn, ~p"/media_profiles", media_profile: @create_attrs)
assert redirected_to(session_conn) == ~p"/?onboarding=1"
assert redirected_to(conn) == ~p"/?onboarding=1"
end
test "renders correct layout on error when onboarding", %{session_conn: session_conn} do
session_conn =
session_conn
|> put_session(:onboarding, true)
|> post(~p"/media_profiles", media_profile: @invalid_attrs)
test "renders correct layout on error when onboarding", %{conn: conn} do
Settings.set!(:onboarding, true)
conn = post(conn, ~p"/media_profiles", media_profile: @invalid_attrs)
refute html_response(session_conn, 200) =~ "MENU"
refute html_response(conn, 200) =~ "MENU"
end
end
@@ -4,10 +4,12 @@ defmodule PinchflatWeb.PageControllerTest do
import Pinchflat.ProfilesFixtures
import Pinchflat.SourcesFixtures
alias Pinchflat.Settings
describe "GET / when testing onboarding" do
test "sets the onboarding session to true when onboarding", %{conn: conn} do
conn = get(conn, ~p"/")
assert get_session(conn, :onboarding)
_conn = get(conn, ~p"/")
assert Settings.get!(:onboarding)
end
test "displays the onboarding page when no media profiles exist", %{conn: conn} do
@@ -32,13 +34,13 @@ defmodule PinchflatWeb.PageControllerTest do
test "sets the onboarding session to false when not onboarding", %{conn: conn} do
conn = get(conn, ~p"/")
assert get_session(conn, :onboarding)
assert Settings.get!(:onboarding)
_ = media_profile_fixture()
_ = source_fixture()
conn = get(conn, ~p"/")
refute get_session(conn, :onboarding)
_conn = get(conn, ~p"/")
refute Settings.get!(:onboarding)
end
test "displays the home page when not onboarding", %{conn: conn} do
@@ -7,9 +7,11 @@ defmodule PinchflatWeb.SourceControllerTest do
import Pinchflat.ProfilesFixtures
alias Pinchflat.Repo
alias Pinchflat.Settings
setup do
media_profile = media_profile_fixture()
Settings.set!(:onboarding, false)
{
:ok,
@@ -42,13 +44,11 @@ defmodule PinchflatWeb.SourceControllerTest do
assert html_response(conn, 200) =~ "New Source"
end
test "renders correct layout when onboarding", %{session_conn: session_conn} do
session_conn =
session_conn
|> put_session(:onboarding, true)
|> get(~p"/sources/new")
test "renders correct layout when onboarding", %{conn: conn} do
Settings.set!(:onboarding, true)
conn = get(conn, ~p"/sources/new")
refute html_response(session_conn, 200) =~ "MENU"
refute html_response(conn, 200) =~ "MENU"
end
end
@@ -69,24 +69,20 @@ defmodule PinchflatWeb.SourceControllerTest do
assert html_response(conn, 200) =~ "New Source"
end
test "redirects to onboarding when onboarding", %{session_conn: session_conn, create_attrs: create_attrs} do
test "redirects to onboarding when onboarding", %{conn: conn, create_attrs: create_attrs} do
expect(YtDlpRunnerMock, :run, 1, &runner_function_mock/3)
session_conn =
session_conn
|> put_session(:onboarding, true)
|> post(~p"/sources", source: create_attrs)
Settings.set!(:onboarding, true)
conn = post(conn, ~p"/sources", source: create_attrs)
assert redirected_to(session_conn) == ~p"/?onboarding=1"
assert redirected_to(conn) == ~p"/?onboarding=1"
end
test "renders correct layout on error when onboarding", %{session_conn: session_conn, invalid_attrs: invalid_attrs} do
session_conn =
session_conn
|> put_session(:onboarding, true)
|> post(~p"/sources", source: invalid_attrs)
test "renders correct layout on error when onboarding", %{conn: conn, invalid_attrs: invalid_attrs} do
Settings.set!(:onboarding, true)
conn = post(conn, ~p"/sources", source: invalid_attrs)
refute html_response(session_conn, 200) =~ "MENU"
refute html_response(conn, 200) =~ "MENU"
end
end