diff --git a/tooling/.formatter.exs b/.formatter.exs similarity index 69% rename from tooling/.formatter.exs rename to .formatter.exs index 6fc82a9..92e5016 100644 --- a/tooling/.formatter.exs +++ b/.formatter.exs @@ -1,3 +1,5 @@ +# TODO: figure out why my vscode extension doesn't respect the formatter.exs file +# if it's in a subdirectory [ import_deps: [:ecto, :ecto_sql, :phoenix], subdirectories: ["priv/*/migrations"], diff --git a/lib/pinchflat/platform/app_notification.ex b/lib/pinchflat/platform/app_notification.ex new file mode 100644 index 0000000..b451931 --- /dev/null +++ b/lib/pinchflat/platform/app_notification.ex @@ -0,0 +1,38 @@ +defmodule Pinchflat.Platform.AppNotification do + @moduledoc """ + The AppNotification schema. + """ + + use Ecto.Schema + import Ecto.Changeset + + @allowed_fields ~w( + uuid + title + body + severity + notification_date + read_at + )a + + @required_fields ~w(uuid title severity notification_date)a + + schema "app_notifications" do + # NOTE: this is _not_ used as a primary key, but as a unique identifier for all installations + field :uuid, Ecto.UUID + field :title, :string + field :body, :string + field :severity, Ecto.Enum, values: Logger.levels() + field :notification_date, :date + field :read_at, :naive_datetime + + timestamps(type: :utc_datetime) + end + + @doc false + def changeset(app_notification, attrs) do + app_notification + |> cast(attrs, @allowed_fields) + |> validate_required(@required_fields) + end +end diff --git a/lib/pinchflat/platform/platform.ex b/lib/pinchflat/platform/platform.ex new file mode 100644 index 0000000..f50fb29 --- /dev/null +++ b/lib/pinchflat/platform/platform.ex @@ -0,0 +1,37 @@ +defmodule Pinchflat.Platform do + @moduledoc """ + The Platform context. + """ + + import Ecto.Query, warn: false + alias Pinchflat.Repo + + alias Pinchflat.Platform.AppNotification + + @doc """ + Returns the list of app_notifications. + + Returns [%AppNotification{}, ...] + """ + def list_app_notifications do + Repo.all(AppNotification) + end + + @doc """ + Creates a app_notification. + + Returns {:ok, %AppNotification{}} | {:error, %Ecto.Changeset{}} + """ + def create_app_notification(attrs \\ %{}) do + %AppNotification{} + |> AppNotification.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Returns `%Ecto.Changeset{}` + """ + def change_app_notification(%AppNotification{} = app_notification, attrs \\ %{}) do + AppNotification.changeset(app_notification, attrs) + end +end diff --git a/mix.exs b/mix.exs index 830e379..d5f3057 100644 --- a/mix.exs +++ b/mix.exs @@ -88,7 +88,6 @@ defmodule Pinchflat.MixProject do # See the documentation for `Mix` for more info on aliases. defp aliases do [ - format: "format --dot-formatter=tooling/.formatter.exs", check: "check --config=tooling/.check.exs", credo: "credo --config-file=tooling/.credo.exs", setup: ["deps.get", "ecto.setup", "assets.setup", "assets.build"], diff --git a/priv/notifications.json b/priv/notifications.json index 86faf3e..3b887c5 100644 --- a/priv/notifications.json +++ b/priv/notifications.json @@ -1,6 +1,6 @@ [ { - "id": "36cd0f0c-89bf-4284-bf1c-0bc5b39e6dfe", + "uuid": "36cd0f0c-89bf-4284-bf1c-0bc5b39e6dfe", "title": "`yt-dlp` recommends disabling YouTube Cookie auth", "body": "`yt-dlp` has discovered an increased rate of IP bans for users who use YouTube Cookie auth. It is recommended to remove the contents of `/config/extras/cookies.txt`.", "severity": "alert", diff --git a/priv/repo/erd.png b/priv/repo/erd.png index 365c7b4..e88df38 100644 Binary files a/priv/repo/erd.png and b/priv/repo/erd.png differ diff --git a/priv/repo/migrations/20240617182932_create_app_notifications.exs b/priv/repo/migrations/20240617182932_create_app_notifications.exs new file mode 100644 index 0000000..b20d488 --- /dev/null +++ b/priv/repo/migrations/20240617182932_create_app_notifications.exs @@ -0,0 +1,18 @@ +defmodule Pinchflat.Repo.Migrations.CreateAppNotifications do + use Ecto.Migration + + def change do + create table(:app_notifications) do + add :uuid, :string, null: false + add :title, :string, null: false + add :body, :string + add :severity, :string, null: false + add :notification_date, :date, null: false + add :read_at, :utc_datetime + + timestamps(type: :utc_datetime) + end + + create(unique_index(:app_notifications, [:uuid])) + end +end diff --git a/test/pinchflat/platform_test.exs b/test/pinchflat/platform_test.exs new file mode 100644 index 0000000..e2207f7 --- /dev/null +++ b/test/pinchflat/platform_test.exs @@ -0,0 +1,48 @@ +defmodule Pinchflat.PlatformTest do + use Pinchflat.DataCase + + import Pinchflat.PlatformFixtures + + alias Pinchflat.Platform + alias Pinchflat.Platform.AppNotification + + @invalid_attrs %{ + title: nil, + severity: nil, + uuid: nil, + notification_date: nil + } + + describe "list_app_notifications/0" do + test "returns all app_notifications" do + app_notification = app_notification_fixture() + assert Platform.list_app_notifications() == [app_notification] + end + end + + describe "create_app_notification/1" do + test "creation with valid data creates an app_notification" do + valid_attrs = %{ + title: "some title", + body: "some body", + severity: "info", + uuid: "a8a1f81b-1761-4b48-93e2-396a021c4ca6", + notification_date: "2024-06-10" + } + + assert {:ok, %AppNotification{} = app_notification} = Platform.create_app_notification(valid_attrs) + assert app_notification.title == "some title" + end + + test "creation with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Platform.create_app_notification(@invalid_attrs) + end + end + + describe "change_app_notification/1" do + test "returns a app_notification changeset" do + app_notification = app_notification_fixture() + assert %Ecto.Changeset{} = Platform.change_app_notification(app_notification) + end + end +end diff --git a/test/support/fixtures/platform_fixtures.ex b/test/support/fixtures/platform_fixtures.ex new file mode 100644 index 0000000..f049d8c --- /dev/null +++ b/test/support/fixtures/platform_fixtures.ex @@ -0,0 +1,25 @@ +defmodule Pinchflat.PlatformFixtures do + @moduledoc """ + This module defines test helpers for creating + entities via the `Pinchflat.Platform` context. + """ + + @doc """ + Generate a app_notification. + """ + def app_notification_fixture(attrs \\ %{}) do + {:ok, app_notification} = + attrs + |> Enum.into(%{ + title: "a cool title", + body: "a cool notification", + notification_date: ~D[2020-01-01], + read_at: nil, + severity: :alert, + uuid: Ecto.UUID.generate() + }) + |> Pinchflat.Platform.create_app_notification() + + app_notification + end +end