From 309eb016a9692978318493b7c1617db037f847a1 Mon Sep 17 00:00:00 2001 From: Rachelcoll Date: Thu, 28 Mar 2024 14:18:56 +0800 Subject: [PATCH 1/3] create, get, delete shared links in database --- .tool-versions | 3 + lib/cadet/shared_programs.ex | 111 ++++++++++++++++++ lib/cadet/shared_programs/shared_program.ex | 34 ++++++ lib/cadet_web/controllers/changeset_json.ex | 25 ++++ .../controllers/fallback_controller.ex | 24 ++++ .../controllers/shared_program_controller.ex | 82 +++++++++++++ .../controllers/shared_program_json.ex | 25 ++++ lib/cadet_web/router.ex | 5 + .../templates/shared_program/show.json.eex | 7 ++ lib/cadet_web/views/shared_program_view.ex | 21 ++++ mix.exs | 3 +- mix.lock | 1 + .../20240303150357_create_shared_programs.exs | 12 ++ test/cadet/shared_programs_test.exs | 61 ++++++++++ .../shared_program_controller_test.exs | 88 ++++++++++++++ .../fixtures/shared_programs_fixtures.ex | 21 ++++ 16 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 .tool-versions create mode 100644 lib/cadet/shared_programs.ex create mode 100644 lib/cadet/shared_programs/shared_program.ex create mode 100644 lib/cadet_web/controllers/changeset_json.ex create mode 100644 lib/cadet_web/controllers/fallback_controller.ex create mode 100644 lib/cadet_web/controllers/shared_program_controller.ex create mode 100644 lib/cadet_web/controllers/shared_program_json.ex create mode 100644 lib/cadet_web/templates/shared_program/show.json.eex create mode 100644 lib/cadet_web/views/shared_program_view.ex create mode 100644 priv/repo/migrations/20240303150357_create_shared_programs.exs create mode 100644 test/cadet/shared_programs_test.exs create mode 100644 test/cadet_web/controllers/shared_program_controller_test.exs create mode 100644 test/support/fixtures/shared_programs_fixtures.ex diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 000000000..e3d24dc53 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,3 @@ +postgres 14.10 +elixir 1.13.3 +erlang 25.3.2 diff --git a/lib/cadet/shared_programs.ex b/lib/cadet/shared_programs.ex new file mode 100644 index 000000000..a29bc9be0 --- /dev/null +++ b/lib/cadet/shared_programs.ex @@ -0,0 +1,111 @@ +defmodule Cadet.SharedPrograms do + @moduledoc """ + The SharedPrograms context. + """ + + import Ecto.Query, warn: false + alias Cadet.Repo + + alias Cadet.SharedPrograms.SharedProgram + + @doc """ + Returns the list of shared_programs. + + ## Examples + + iex> list_shared_programs() + [%SharedProgram{}, ...] + + """ + def list_shared_programs do + Repo.all(SharedProgram) + end + + @doc """ + Gets a single shared_program. + + Raises `Ecto.NoResultsError` if the Shared program does not exist. + + ## Examples + + iex> get_shared_program!(123) + %SharedProgram{} + + iex> get_shared_program!(456) + ** (Ecto.NoResultsError) + + """ + def get_shared_program!(id), do: Repo.get!(SharedProgram, id) + + def get_shared_program_by_uuid!(uuid) do + case Repo.get_by(SharedProgram, uuid: uuid) do + nil -> raise "SharedProgram not found for UUID #{uuid}" + shared_program -> shared_program + end + end + + @doc """ + Creates a shared_program. + + ## Examples + + iex> create_shared_program(%{field: value}) + {:ok, %SharedProgram{}} + + iex> create_shared_program(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_shared_program(attrs \\ %{}) do + %SharedProgram{} + |> SharedProgram.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a shared_program. + + ## Examples + + iex> update_shared_program(shared_program, %{field: new_value}) + {:ok, %SharedProgram{}} + + iex> update_shared_program(shared_program, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_shared_program(%SharedProgram{} = shared_program, attrs) do + shared_program + |> SharedProgram.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a shared_program. + + ## Examples + + iex> delete_shared_program(shared_program) + {:ok, %SharedProgram{}} + + iex> delete_shared_program(shared_program) + {:error, %Ecto.Changeset{}} + + """ + def delete_shared_program(%SharedProgram{} = shared_program) do + Repo.delete(shared_program) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking shared_program changes. + + ## Examples + + iex> change_shared_program(shared_program) + %Ecto.Changeset{data: %SharedProgram{}} + + """ + def change_shared_program(%SharedProgram{} = shared_program, attrs \\ %{}) do + SharedProgram.changeset(shared_program, attrs) + end +end diff --git a/lib/cadet/shared_programs/shared_program.ex b/lib/cadet/shared_programs/shared_program.ex new file mode 100644 index 000000000..2e127c995 --- /dev/null +++ b/lib/cadet/shared_programs/shared_program.ex @@ -0,0 +1,34 @@ +defmodule Cadet.SharedPrograms.SharedProgram do + use Ecto.Schema + import Ecto.Changeset + + schema "shared_programs" do + field :data, :map + field :uuid, Ecto.UUID + + timestamps() + end + + @doc false + def changeset(shared_program, attrs) do + shared_program + |> cast(attrs, [:data]) + |> generate_uuid_if_nil() + |> validate_required([:uuid]) + end + + defp generate_uuid_if_nil(changeset) do + if get_change(changeset, :uuid) do + changeset + else + put_change(changeset, :uuid, Ecto.UUID.generate()) + end + end + + defimpl String.Chars, for: Cadet.SharedPrograms.SharedProgram do + def to_string(%Cadet.SharedPrograms.SharedProgram{uuid: uuid}) do + "SharedProgram with UUID: #{uuid}" + end + end + +end diff --git a/lib/cadet_web/controllers/changeset_json.ex b/lib/cadet_web/controllers/changeset_json.ex new file mode 100644 index 000000000..7c41e337a --- /dev/null +++ b/lib/cadet_web/controllers/changeset_json.ex @@ -0,0 +1,25 @@ +defmodule CadetWeb.ChangesetJSON do + @doc """ + Renders changeset errors. + """ + def error(%{changeset: changeset}) do + # When encoded, the changeset returns its errors + # as a JSON object. So we just pass it forward. + %{errors: Ecto.Changeset.traverse_errors(changeset, &translate_error/1)} + end + + defp translate_error({msg, opts}) do + # You can make use of gettext to translate error messages by + # uncommenting and adjusting the following code: + + # if count = opts[:count] do + # Gettext.dngettext(CadetWeb.Gettext, "errors", msg, msg, count, opts) + # else + # Gettext.dgettext(CadetWeb.Gettext, "errors", msg, opts) + # end + + Enum.reduce(opts, msg, fn {key, value}, acc -> + String.replace(acc, "%{#{key}}", fn _ -> to_string(value) end) + end) + end +end diff --git a/lib/cadet_web/controllers/fallback_controller.ex b/lib/cadet_web/controllers/fallback_controller.ex new file mode 100644 index 000000000..5a79b2c2e --- /dev/null +++ b/lib/cadet_web/controllers/fallback_controller.ex @@ -0,0 +1,24 @@ +defmodule CadetWeb.FallbackController do + @moduledoc """ + Translates controller action results into valid `Plug.Conn` responses. + + See `Phoenix.Controller.action_fallback/1` for more details. + """ + use CadetWeb, :controller + + # This clause handles errors returned by Ecto's insert/update/delete. + def call(conn, {:error, %Ecto.Changeset{} = changeset}) do + conn + |> put_status(:unprocessable_entity) + |> put_view(json: CadetWeb.ChangesetJSON) + |> render(:error, changeset: changeset) + end + + # This clause is an example of how to handle resources that cannot be found. + def call(conn, {:error, :not_found}) do + conn + |> put_status(:not_found) + |> put_view(html: CadetWeb.ErrorHTML, json: CadetWeb.ErrorJSON) + |> render(:"404") + end +end diff --git a/lib/cadet_web/controllers/shared_program_controller.ex b/lib/cadet_web/controllers/shared_program_controller.ex new file mode 100644 index 000000000..f0025e80a --- /dev/null +++ b/lib/cadet_web/controllers/shared_program_controller.ex @@ -0,0 +1,82 @@ +defmodule CadetWeb.SharedProgramController do + use CadetWeb, :controller + + alias Cadet.SharedPrograms + alias Cadet.SharedPrograms.SharedProgram + + action_fallback CadetWeb.FallbackController + + + def index(conn, _params) do + shared_programs = SharedPrograms.list_shared_programs() + render(conn, :index, shared_programs: shared_programs) + end + + def create(conn, %{"shared_program" => shared_program_params}) do + with {:ok, %SharedProgram{uuid: uuid} = shared_program} <- SharedPrograms.create_shared_program(shared_program_params) do + conn + |> put_status(:created) + |> put_resp_header("location", ~s"/api/shared_programs/#{shared_program}") + # |> render(:show, shared_program: shared_program) + |> render("show.json", %{uuid: uuid}) + + # case ping_url_shortener(uuid) do + # {:ok, shortened_url} -> + # conn + # |> put_status(:created) + # |> put_resp_header("location", ~s"/api/shared_programs/#{shared_program}") + # # |> render(:show, shared_program: shared_program) + # |> render("show.json", %{uuid: uuid, shortened_url: shortened_url}) + # {:error, reason} -> + # conn + # |> put_status(:internal_server_error) + # |> json(%{error: "Failed to shorten URL: #{reason}"}) + # end + end + end + + def show(conn, %{"id" => uuid}) do + shared_program = SharedPrograms.get_shared_program_by_uuid!(uuid) + render(conn, :show, shared_program: shared_program) + end + + def update(conn, %{"id" => id, "shared_program" => shared_program_params}) do + shared_program = SharedPrograms.get_shared_program!(id) + + with {:ok, %SharedProgram{} = shared_program} <- SharedPrograms.update_shared_program(shared_program, shared_program_params) do + render(conn, :show, shared_program: shared_program) + end + end + + def delete(conn, %{"id" => id}) do + shared_program = SharedPrograms.get_shared_program!(id) + + with {:ok, %SharedProgram{}} <- SharedPrograms.delete_shared_program(shared_program) do + send_resp(conn, :no_content, "") + end + end + + defp ping_url_shortener(uuid) do + url = "https://localhost:8000/yourls-api.php" + + params = %{ + signature: "5eef899abd", + action: "shorturl", + format: "json", + keyword: uuid, + url: "http://localhost:8000/playground#uuid=#{uuid}" + } + + case HTTPoison.post(url, {:form, params}) do + {:ok, %{status_code: 200, body: body}} -> + {:ok, body} + + {:error, %HTTPoison.Error{reason: reason}} -> + {:error, reason} + + other -> + {:error, "Unexpected response: #{inspect(other)}"} + end + end + +end diff --git a/lib/cadet_web/controllers/shared_program_json.ex b/lib/cadet_web/controllers/shared_program_json.ex new file mode 100644 index 000000000..9ff8cad1c --- /dev/null +++ b/lib/cadet_web/controllers/shared_program_json.ex @@ -0,0 +1,25 @@ +defmodule CadetWeb.SharedProgramJSON do + alias Cadet.SharedPrograms.SharedProgram + + @doc """ + Renders a list of shared_programs. + """ + def index(%{shared_programs: shared_programs}) do + %{data: for(shared_program <- shared_programs, do: data(shared_program))} + end + + @doc """ + Renders a single shared_program. + """ + def show(%{shared_program: shared_program}) do + %{data: data(shared_program)} + end + + defp data(%SharedProgram{} = shared_program) do + %{ + id: shared_program.id, + uuid: shared_program.uuid, + data: shared_program.data + } + end +end diff --git a/lib/cadet_web/router.ex b/lib/cadet_web/router.ex index 32e94eca2..c22c0dfd6 100644 --- a/lib/cadet_web/router.ex +++ b/lib/cadet_web/router.ex @@ -187,6 +187,11 @@ defmodule CadetWeb.Router do # pipe_through :api # end + scope "/api", CadetWeb do + pipe_through :api + resources "/shared_programs", SharedProgramController, only: [:index, :show, :create, :delete] + end + def swagger_info do %{ info: %{ diff --git a/lib/cadet_web/templates/shared_program/show.json.eex b/lib/cadet_web/templates/shared_program/show.json.eex new file mode 100644 index 000000000..013c4794b --- /dev/null +++ b/lib/cadet_web/templates/shared_program/show.json.eex @@ -0,0 +1,7 @@ +<%= Jason.encode!(%{ + id: @shared_program.id, + uuid: @shared_program.uuid, + data: @shared_program.data, + inserted_at: @shared_program.inserted_at, + updated_at: @shared_program.updated_at +}) %> diff --git a/lib/cadet_web/views/shared_program_view.ex b/lib/cadet_web/views/shared_program_view.ex new file mode 100644 index 000000000..f5a7af577 --- /dev/null +++ b/lib/cadet_web/views/shared_program_view.ex @@ -0,0 +1,21 @@ +defmodule CadetWeb.SharedProgramView do + use CadetWeb, :view + + def render("index.json", %{shared_programs: shared_programs}) do + %{ + data: Enum.map(shared_programs, &render_shared_program/1) + } + end + + def render("show.json", %{uuid: uuid}) do + %{uuid: uuid} + end + + defp render_shared_program(shared_program) do + %{ + uuid: shared_program.uuid, + json: shared_program.data + # Add other attributes as needed + } + end +end diff --git a/mix.exs b/mix.exs index 8a248575d..fbb0bb0c1 100644 --- a/mix.exs +++ b/mix.exs @@ -110,7 +110,8 @@ defmodule Cadet.Mixfile do # The following are indirect dependencies, but we need to override the # versions due to conflicts {:jsx, "~> 3.1", override: true}, - {:xml_builder, "~> 2.1", override: true} + {:xml_builder, "~> 2.1", override: true}, + {:uuid, "~> 1.1"} ] end diff --git a/mix.lock b/mix.lock index c09256325..a70a4aa7f 100644 --- a/mix.lock +++ b/mix.lock @@ -93,6 +93,7 @@ "timex": {:hex, :timex, "3.7.11", "bb95cb4eb1d06e27346325de506bcc6c30f9c6dea40d1ebe390b262fad1862d1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.20", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8b9024f7efbabaf9bd7aa04f65cf8dcd7c9818ca5737677c7b76acbc6a94d1aa"}, "tzdata": {:hex, :tzdata, "1.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, + "uuid": {:hex, :uuid, "1.1.8", "e22fc04499de0de3ed1116b770c7737779f226ceefa0badb3592e64d5cfb4eb9", [:mix], [], "hexpm", "c790593b4c3b601f5dc2378baae7efaf5b3d73c4c6456ba85759905be792f2ac"}, "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, "websock_adapter": {:hex, :websock_adapter, "0.5.5", "9dfeee8269b27e958a65b3e235b7e447769f66b5b5925385f5a569269164a210", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "4b977ba4a01918acbf77045ff88de7f6972c2a009213c515a445c48f224ffce9"}, "xml_builder": {:hex, :xml_builder, "2.2.0", "cc5f1eeefcfcde6e90a9b77fb6c490a20bc1b856a7010ce6396f6da9719cbbab", [:mix], [], "hexpm", "9d66d52fb917565d358166a4314078d39ef04d552904de96f8e73f68f64a62c9"}, diff --git a/priv/repo/migrations/20240303150357_create_shared_programs.exs b/priv/repo/migrations/20240303150357_create_shared_programs.exs new file mode 100644 index 000000000..3ba7f638c --- /dev/null +++ b/priv/repo/migrations/20240303150357_create_shared_programs.exs @@ -0,0 +1,12 @@ +defmodule Cadet.Repo.Migrations.CreateSharedPrograms do + use Ecto.Migration + + def change do + create table(:shared_programs) do + add :uuid, :uuid + add :data, :map + + timestamps() + end + end +end diff --git a/test/cadet/shared_programs_test.exs b/test/cadet/shared_programs_test.exs new file mode 100644 index 000000000..0fc2e30d9 --- /dev/null +++ b/test/cadet/shared_programs_test.exs @@ -0,0 +1,61 @@ +defmodule Cadet.SharedProgramsTest do + use Cadet.DataCase + + alias Cadet.SharedPrograms + + describe "shared_programs" do + alias Cadet.SharedPrograms.SharedProgram + + import Cadet.SharedProgramsFixtures + + @invalid_attrs %{data: nil, uuid: nil} + + test "list_shared_programs/0 returns all shared_programs" do + shared_program = shared_program_fixture() + assert SharedPrograms.list_shared_programs() == [shared_program] + end + + test "get_shared_program!/1 returns the shared_program with given id" do + shared_program = shared_program_fixture() + assert SharedPrograms.get_shared_program!(shared_program.id) == shared_program + end + + test "create_shared_program/1 with valid data creates a shared_program" do + valid_attrs = %{data: %{}, uuid: "7488a646-e31f-11e4-aace-600308960662"} + + assert {:ok, %SharedProgram{} = shared_program} = SharedPrograms.create_shared_program(valid_attrs) + assert shared_program.data == %{} + assert shared_program.uuid == "7488a646-e31f-11e4-aace-600308960662" + end + + test "create_shared_program/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = SharedPrograms.create_shared_program(@invalid_attrs) + end + + test "update_shared_program/2 with valid data updates the shared_program" do + shared_program = shared_program_fixture() + update_attrs = %{data: %{}, uuid: "7488a646-e31f-11e4-aace-600308960668"} + + assert {:ok, %SharedProgram{} = shared_program} = SharedPrograms.update_shared_program(shared_program, update_attrs) + assert shared_program.data == %{} + assert shared_program.uuid == "7488a646-e31f-11e4-aace-600308960668" + end + + test "update_shared_program/2 with invalid data returns error changeset" do + shared_program = shared_program_fixture() + assert {:error, %Ecto.Changeset{}} = SharedPrograms.update_shared_program(shared_program, @invalid_attrs) + assert shared_program == SharedPrograms.get_shared_program!(shared_program.id) + end + + test "delete_shared_program/1 deletes the shared_program" do + shared_program = shared_program_fixture() + assert {:ok, %SharedProgram{}} = SharedPrograms.delete_shared_program(shared_program) + assert_raise Ecto.NoResultsError, fn -> SharedPrograms.get_shared_program!(shared_program.id) end + end + + test "change_shared_program/1 returns a shared_program changeset" do + shared_program = shared_program_fixture() + assert %Ecto.Changeset{} = SharedPrograms.change_shared_program(shared_program) + end + end +end diff --git a/test/cadet_web/controllers/shared_program_controller_test.exs b/test/cadet_web/controllers/shared_program_controller_test.exs new file mode 100644 index 000000000..e61b0c4ea --- /dev/null +++ b/test/cadet_web/controllers/shared_program_controller_test.exs @@ -0,0 +1,88 @@ +defmodule CadetWeb.SharedProgramControllerTest do + use CadetWeb.ConnCase + + import Cadet.SharedProgramsFixtures + + alias Cadet.SharedPrograms.SharedProgram + + @create_attrs %{ + data: %{}, + uuid: "7488a646-e31f-11e4-aace-600308960662" + } + @update_attrs %{ + data: %{}, + uuid: "7488a646-e31f-11e4-aace-600308960668" + } + @invalid_attrs %{data: nil, uuid: nil} + + setup %{conn: conn} do + {:ok, conn: put_req_header(conn, "accept", "application/json")} + end + + describe "index" do + test "lists all shared_programs", %{conn: conn} do + conn = get(conn, ~p"/api/shared_programs") + assert json_response(conn, 200)["data"] == [] + end + end + + describe "create shared_program" do + test "renders shared_program when data is valid", %{conn: conn} do + conn = post(conn, ~p"/api/shared_programs", shared_program: @create_attrs) + assert %{"id" => id} = json_response(conn, 201)["data"] + + conn = get(conn, ~p"/api/shared_programs/#{id}") + + assert %{ + "id" => ^id, + "data" => %{}, + "uuid" => "7488a646-e31f-11e4-aace-600308960662" + } = json_response(conn, 200)["data"] + end + + test "renders errors when data is invalid", %{conn: conn} do + conn = post(conn, ~p"/api/shared_programs", shared_program: @invalid_attrs) + assert json_response(conn, 422)["errors"] != %{} + end + end + + describe "update shared_program" do + setup [:create_shared_program] + + test "renders shared_program when data is valid", %{conn: conn, shared_program: %SharedProgram{id: id} = shared_program} do + conn = put(conn, ~p"/api/shared_programs/#{shared_program}", shared_program: @update_attrs) + assert %{"id" => ^id} = json_response(conn, 200)["data"] + + conn = get(conn, ~p"/api/shared_programs/#{id}") + + assert %{ + "id" => ^id, + "data" => %{}, + "uuid" => "7488a646-e31f-11e4-aace-600308960668" + } = json_response(conn, 200)["data"] + end + + test "renders errors when data is invalid", %{conn: conn, shared_program: shared_program} do + conn = put(conn, ~p"/api/shared_programs/#{shared_program}", shared_program: @invalid_attrs) + assert json_response(conn, 422)["errors"] != %{} + end + end + + describe "delete shared_program" do + setup [:create_shared_program] + + test "deletes chosen shared_program", %{conn: conn, shared_program: shared_program} do + conn = delete(conn, ~p"/api/shared_programs/#{shared_program}") + assert response(conn, 204) + + assert_error_sent 404, fn -> + get(conn, ~p"/api/shared_programs/#{shared_program}") + end + end + end + + defp create_shared_program(_) do + shared_program = shared_program_fixture() + %{shared_program: shared_program} + end +end diff --git a/test/support/fixtures/shared_programs_fixtures.ex b/test/support/fixtures/shared_programs_fixtures.ex new file mode 100644 index 000000000..cfdfb76da --- /dev/null +++ b/test/support/fixtures/shared_programs_fixtures.ex @@ -0,0 +1,21 @@ +defmodule Cadet.SharedProgramsFixtures do + @moduledoc """ + This module defines test helpers for creating + entities via the `Cadet.SharedPrograms` context. + """ + + @doc """ + Generate a shared_program. + """ + def shared_program_fixture(attrs \\ %{}) do + {:ok, shared_program} = + attrs + |> Enum.into(%{ + data: %{}, + uuid: "7488a646-e31f-11e4-aace-600308960662" + }) + |> Cadet.SharedPrograms.create_shared_program() + + shared_program + end +end From 2a5823c2cbcff0ce80185ac672040b47ac6299be Mon Sep 17 00:00:00 2001 From: Rachelcoll Date: Fri, 12 Apr 2024 22:33:36 +0800 Subject: [PATCH 2/3] formatted --- lib/cadet/shared_programs/shared_program.ex | 8 +++++--- .../controllers/shared_program_controller.ex | 13 ++++++++----- lib/cadet_web/router.ex | 5 +++-- .../20240303150357_create_shared_programs.exs | 4 ++-- test/cadet/shared_programs_test.exs | 18 ++++++++++++++---- .../shared_program_controller_test.exs | 9 ++++++--- 6 files changed, 38 insertions(+), 19 deletions(-) diff --git a/lib/cadet/shared_programs/shared_program.ex b/lib/cadet/shared_programs/shared_program.ex index 2e127c995..0840a40b2 100644 --- a/lib/cadet/shared_programs/shared_program.ex +++ b/lib/cadet/shared_programs/shared_program.ex @@ -1,10 +1,13 @@ defmodule Cadet.SharedPrograms.SharedProgram do + @moduledoc """ + Contains methods for storing frontend programs to database with uuid. + """ use Ecto.Schema import Ecto.Changeset schema "shared_programs" do - field :data, :map - field :uuid, Ecto.UUID + field(:data, :map) + field(:uuid, Ecto.UUID) timestamps() end @@ -30,5 +33,4 @@ defmodule Cadet.SharedPrograms.SharedProgram do "SharedProgram with UUID: #{uuid}" end end - end diff --git a/lib/cadet_web/controllers/shared_program_controller.ex b/lib/cadet_web/controllers/shared_program_controller.ex index f0025e80a..2d77aa2fd 100644 --- a/lib/cadet_web/controllers/shared_program_controller.ex +++ b/lib/cadet_web/controllers/shared_program_controller.ex @@ -4,8 +4,7 @@ defmodule CadetWeb.SharedProgramController do alias Cadet.SharedPrograms alias Cadet.SharedPrograms.SharedProgram - action_fallback CadetWeb.FallbackController - + action_fallback(CadetWeb.FallbackController) def index(conn, _params) do shared_programs = SharedPrograms.list_shared_programs() @@ -13,7 +12,11 @@ defmodule CadetWeb.SharedProgramController do end def create(conn, %{"shared_program" => shared_program_params}) do - with {:ok, %SharedProgram{uuid: uuid} = shared_program} <- SharedPrograms.create_shared_program(shared_program_params) do + with {:ok, %SharedProgram{uuid: uuid} = shared_program} <- + SharedPrograms.create_shared_program(shared_program_params) do + # change to current server of source academy + # server = "http://localhost:8000" + # url = conn |> put_status(:created) |> put_resp_header("location", ~s"/api/shared_programs/#{shared_program}") @@ -43,7 +46,8 @@ defmodule CadetWeb.SharedProgramController do def update(conn, %{"id" => id, "shared_program" => shared_program_params}) do shared_program = SharedPrograms.get_shared_program!(id) - with {:ok, %SharedProgram{} = shared_program} <- SharedPrograms.update_shared_program(shared_program, shared_program_params) do + with {:ok, %SharedProgram{} = shared_program} <- + SharedPrograms.update_shared_program(shared_program, shared_program_params) do render(conn, :show, shared_program: shared_program) end end @@ -78,5 +82,4 @@ defmodule CadetWeb.SharedProgramController do {:error, "Unexpected response: #{inspect(other)}"} end end - end diff --git a/lib/cadet_web/router.ex b/lib/cadet_web/router.ex index c22c0dfd6..670807ed7 100644 --- a/lib/cadet_web/router.ex +++ b/lib/cadet_web/router.ex @@ -188,8 +188,9 @@ defmodule CadetWeb.Router do # end scope "/api", CadetWeb do - pipe_through :api - resources "/shared_programs", SharedProgramController, only: [:index, :show, :create, :delete] + pipe_through(:api) + + resources("/shared_programs", SharedProgramController, only: [:index, :show, :create, :delete]) end def swagger_info do diff --git a/priv/repo/migrations/20240303150357_create_shared_programs.exs b/priv/repo/migrations/20240303150357_create_shared_programs.exs index 3ba7f638c..569b66f99 100644 --- a/priv/repo/migrations/20240303150357_create_shared_programs.exs +++ b/priv/repo/migrations/20240303150357_create_shared_programs.exs @@ -3,8 +3,8 @@ defmodule Cadet.Repo.Migrations.CreateSharedPrograms do def change do create table(:shared_programs) do - add :uuid, :uuid - add :data, :map + add(:uuid, :uuid) + add(:data, :map) timestamps() end diff --git a/test/cadet/shared_programs_test.exs b/test/cadet/shared_programs_test.exs index 0fc2e30d9..889a4b2c2 100644 --- a/test/cadet/shared_programs_test.exs +++ b/test/cadet/shared_programs_test.exs @@ -23,7 +23,9 @@ defmodule Cadet.SharedProgramsTest do test "create_shared_program/1 with valid data creates a shared_program" do valid_attrs = %{data: %{}, uuid: "7488a646-e31f-11e4-aace-600308960662"} - assert {:ok, %SharedProgram{} = shared_program} = SharedPrograms.create_shared_program(valid_attrs) + assert {:ok, %SharedProgram{} = shared_program} = + SharedPrograms.create_shared_program(valid_attrs) + assert shared_program.data == %{} assert shared_program.uuid == "7488a646-e31f-11e4-aace-600308960662" end @@ -36,21 +38,29 @@ defmodule Cadet.SharedProgramsTest do shared_program = shared_program_fixture() update_attrs = %{data: %{}, uuid: "7488a646-e31f-11e4-aace-600308960668"} - assert {:ok, %SharedProgram{} = shared_program} = SharedPrograms.update_shared_program(shared_program, update_attrs) + assert {:ok, %SharedProgram{} = shared_program} = + SharedPrograms.update_shared_program(shared_program, update_attrs) + assert shared_program.data == %{} assert shared_program.uuid == "7488a646-e31f-11e4-aace-600308960668" end test "update_shared_program/2 with invalid data returns error changeset" do shared_program = shared_program_fixture() - assert {:error, %Ecto.Changeset{}} = SharedPrograms.update_shared_program(shared_program, @invalid_attrs) + + assert {:error, %Ecto.Changeset{}} = + SharedPrograms.update_shared_program(shared_program, @invalid_attrs) + assert shared_program == SharedPrograms.get_shared_program!(shared_program.id) end test "delete_shared_program/1 deletes the shared_program" do shared_program = shared_program_fixture() assert {:ok, %SharedProgram{}} = SharedPrograms.delete_shared_program(shared_program) - assert_raise Ecto.NoResultsError, fn -> SharedPrograms.get_shared_program!(shared_program.id) end + + assert_raise Ecto.NoResultsError, fn -> + SharedPrograms.get_shared_program!(shared_program.id) + end end test "change_shared_program/1 returns a shared_program changeset" do diff --git a/test/cadet_web/controllers/shared_program_controller_test.exs b/test/cadet_web/controllers/shared_program_controller_test.exs index e61b0c4ea..7f2a6edaf 100644 --- a/test/cadet_web/controllers/shared_program_controller_test.exs +++ b/test/cadet_web/controllers/shared_program_controller_test.exs @@ -49,7 +49,10 @@ defmodule CadetWeb.SharedProgramControllerTest do describe "update shared_program" do setup [:create_shared_program] - test "renders shared_program when data is valid", %{conn: conn, shared_program: %SharedProgram{id: id} = shared_program} do + test "renders shared_program when data is valid", %{ + conn: conn, + shared_program: %SharedProgram{id: id} = shared_program + } do conn = put(conn, ~p"/api/shared_programs/#{shared_program}", shared_program: @update_attrs) assert %{"id" => ^id} = json_response(conn, 200)["data"] @@ -75,9 +78,9 @@ defmodule CadetWeb.SharedProgramControllerTest do conn = delete(conn, ~p"/api/shared_programs/#{shared_program}") assert response(conn, 204) - assert_error_sent 404, fn -> + assert_error_sent(404, fn -> get(conn, ~p"/api/shared_programs/#{shared_program}") - end + end) end end From 5ae888bc55affe4f1edf77f28dd0d985066014ed Mon Sep 17 00:00:00 2001 From: Rachelcoll Date: Sat, 13 Apr 2024 20:49:52 +0800 Subject: [PATCH 3/3] change route to share link database --- lib/cadet_web/router.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cadet_web/router.ex b/lib/cadet_web/router.ex index 670807ed7..a209deb45 100644 --- a/lib/cadet_web/router.ex +++ b/lib/cadet_web/router.ex @@ -187,7 +187,7 @@ defmodule CadetWeb.Router do # pipe_through :api # end - scope "/api", CadetWeb do + scope "/v2", CadetWeb do pipe_through(:api) resources("/shared_programs", SharedProgramController, only: [:index, :show, :create, :delete])