diff --git a/assets/js/launch-cart-additem.ts b/assets/js/launch-cart-additem.ts index ae07d50..55df28e 100644 --- a/assets/js/launch-cart-additem.ts +++ b/assets/js/launch-cart-additem.ts @@ -6,7 +6,7 @@ import cartStyles from '../css/cart.lit.scss'; @customElement('launch-cart-additem') @liveState({ events: { - send: ['add_cart_item'] + send: ['add_cart_item'], receive: ['livestate-error'] }, context: 'cartState' }) @@ -22,6 +22,9 @@ export class LaunchCartAddItemElement extends LitElement { console.log(event); this.dispatchEvent(new CustomEvent('add_cart_item', {detail: {stripe_price: this.priceId}})) }); + this.addEventListener('livestate-error', (e: CustomEvent<{ }>) => { + console.error(e.detail); + }); } render() { diff --git a/assets/js/launch-cart.ts b/assets/js/launch-cart.ts index b8f5fc5..2cd0aeb 100644 --- a/assets/js/launch-cart.ts +++ b/assets/js/launch-cart.ts @@ -90,8 +90,8 @@ export class LaunchCartElement extends LitElement { console.log('cart created') window.localStorage.setItem('cart_id', e.detail.cart_id); }); - this.addEventListener('livestate-error', (e: CustomEvent<{ error: string }>) => { - console.error(e); + this.addEventListener('livestate-error', (e: CustomEvent<{ message: string }>) => { + console.error(e.detail); }); } diff --git a/assets/package-lock.json b/assets/package-lock.json index bbb3aba..85dede8 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -1,12 +1,12 @@ { "name": "launch-elements", - "version": "0.2.0", + "version": "0.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "launch-elements", - "version": "0.2.0", + "version": "0.4.0", "dependencies": { "api-viewer-element": "^1.0.0-pre.7", "lit": "^2.4.0", @@ -14,7 +14,7 @@ "phoenix_html": "file:../deps/phoenix_html", "phoenix_live_view": "file:../deps/phoenix_live_view", "phoenix-custom-event-hook": "^0.0.6", - "phx-live-state": "0.10.2" + "phx-live-state": "0.10.3" }, "devDependencies": { "@custom-elements-manifest/analyzer": "^0.6.8", @@ -57,11 +57,11 @@ } }, "../deps/phoenix": { - "version": "1.7.1", + "version": "1.7.7", "license": "MIT" }, "../deps/phoenix_html": { - "version": "3.3.1" + "version": "3.3.2" }, "../deps/phoenix_live_view": { "version": "0.18.18", @@ -2855,9 +2855,9 @@ } }, "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "peer": true }, "node_modules/fast-glob": { @@ -3599,9 +3599,9 @@ "dev": true }, "node_modules/json-joy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/json-joy/-/json-joy-1.18.1.tgz", - "integrity": "sha512-j6M1VpnR/z5qAIc2DvBlxyOsE26Yzr7bedgrYFITW+O1U2DqJuACOPhrN86+hdq7hZ+Sah3pAvMzDiecwfrJ8w==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/json-joy/-/json-joy-1.19.0.tgz", + "integrity": "sha512-oILIyxHJu52hQ9BFs1yFMXVKrP2cTYOdljRiNRElHzpcSnA03sSf+VKzwqEE2hGKKL1Zvml71b1wPTAQUl8CHQ==", "dependencies": { "arg": "^5.0.2", "hyperdyperid": "^1.2.0" @@ -4658,9 +4658,9 @@ } }, "node_modules/phx-live-state": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/phx-live-state/-/phx-live-state-0.10.2.tgz", - "integrity": "sha512-G+ztR0mJL+w9zcPYouHj36a+P277sE2ivdLEFvvngseJ65g3xWSbc3MiL3H692dNZx8MMJnKuJXBFDWbyDPseQ==", + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/phx-live-state/-/phx-live-state-0.10.3.tgz", + "integrity": "sha512-HeCMcOTZ+GC7J/Cbvxb2mC9KdUPla4b4Cp73sEenCszFtCtyk88yfo5Y6SS26rBm7Gzh60QzFZfVQx77AQbn1g==", "dependencies": { "json-joy": "^1.18.1", "lit": "^2.2.6", @@ -5060,12 +5060,12 @@ ] }, "node_modules/quill-delta": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.0.0.tgz", - "integrity": "sha512-lVORU8dBPJdxPmwtdGhfRcz2cekn8Osuj5kwHoPMQ3MNlDT/IZ0CGUnQ/tLsAaTn31LWcDC1KyL+gkiGbBlBBw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz", + "integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==", "peer": true, "dependencies": { - "fast-diff": "1.2.0", + "fast-diff": "^1.3.0", "lodash.clonedeep": "^4.5.0", "lodash.isequal": "^4.5.0" }, @@ -5302,9 +5302,9 @@ } }, "node_modules/rxjs": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", - "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "peer": true, "dependencies": { "tslib": "^2.1.0" @@ -8044,9 +8044,9 @@ } }, "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "peer": true }, "fast-glob": { @@ -8587,9 +8587,9 @@ "dev": true }, "json-joy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/json-joy/-/json-joy-1.18.1.tgz", - "integrity": "sha512-j6M1VpnR/z5qAIc2DvBlxyOsE26Yzr7bedgrYFITW+O1U2DqJuACOPhrN86+hdq7hZ+Sah3pAvMzDiecwfrJ8w==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/json-joy/-/json-joy-1.19.0.tgz", + "integrity": "sha512-oILIyxHJu52hQ9BFs1yFMXVKrP2cTYOdljRiNRElHzpcSnA03sSf+VKzwqEE2hGKKL1Zvml71b1wPTAQUl8CHQ==", "requires": { "arg": "^5.0.2", "hyperdyperid": "^1.2.0" @@ -9402,9 +9402,9 @@ } }, "phx-live-state": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/phx-live-state/-/phx-live-state-0.10.2.tgz", - "integrity": "sha512-G+ztR0mJL+w9zcPYouHj36a+P277sE2ivdLEFvvngseJ65g3xWSbc3MiL3H692dNZx8MMJnKuJXBFDWbyDPseQ==", + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/phx-live-state/-/phx-live-state-0.10.3.tgz", + "integrity": "sha512-HeCMcOTZ+GC7J/Cbvxb2mC9KdUPla4b4Cp73sEenCszFtCtyk88yfo5Y6SS26rBm7Gzh60QzFZfVQx77AQbn1g==", "requires": { "json-joy": "^1.18.1", "lit": "^2.2.6", @@ -9682,12 +9682,12 @@ "dev": true }, "quill-delta": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.0.0.tgz", - "integrity": "sha512-lVORU8dBPJdxPmwtdGhfRcz2cekn8Osuj5kwHoPMQ3MNlDT/IZ0CGUnQ/tLsAaTn31LWcDC1KyL+gkiGbBlBBw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz", + "integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==", "peer": true, "requires": { - "fast-diff": "1.2.0", + "fast-diff": "^1.3.0", "lodash.clonedeep": "^4.5.0", "lodash.isequal": "^4.5.0" } @@ -9859,9 +9859,9 @@ } }, "rxjs": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", - "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "peer": true, "requires": { "tslib": "^2.1.0" diff --git a/assets/package.json b/assets/package.json index 18c15fd..b56f93f 100644 --- a/assets/package.json +++ b/assets/package.json @@ -28,7 +28,7 @@ "phoenix_html": "file:../deps/phoenix_html", "phoenix_live_view": "file:../deps/phoenix_live_view", "phoenix-custom-event-hook": "^0.0.6", - "phx-live-state": "0.10.2" + "phx-live-state": "0.10.3" }, "devDependencies": { "@custom-elements-manifest/analyzer": "^0.6.8", diff --git a/lib/launch_cart/carts.ex b/lib/launch_cart/carts.ex index 6c206f0..a2f9366 100644 --- a/lib/launch_cart/carts.ex +++ b/lib/launch_cart/carts.ex @@ -119,7 +119,7 @@ defmodule LaunchCart.Carts do end def checkout(return_url, %Cart{items: items, store_id: store_id} = cart) do - %Store{stripe_account: %StripeAccount{stripe_id: stripe_id}} = Stores.get_store!(store_id) + %Store{stripe_account: %StripeAccount{stripe_id: stripe_id}} = Stores.get_store(store_id) case @create_checkout_session.( %{ diff --git a/lib/launch_cart/stores.ex b/lib/launch_cart/stores.ex index 097fd82..aa8572a 100644 --- a/lib/launch_cart/stores.ex +++ b/lib/launch_cart/stores.ex @@ -30,20 +30,23 @@ defmodule LaunchCart.Stores do end @doc """ - Gets a single store. - - Raises `Ecto.NoResultsError` if the Store does not exist. + Gets a single store. Returns nil if store does not exists ## Examples - iex> get_store!(123) + iex> get_store(123) %Store{} - iex> get_store!(456) - ** (Ecto.NoResultsError) + iex> get_store(456) + nil """ - def get_store!(id), do: Repo.get!(Store, id) |> Repo.preload(:stripe_account) + def get_store(id) do + case Ecto.UUID.cast(id) do + {:ok, id} -> Repo.get(Store, id) |> Repo.preload(:stripe_account) + _ -> nil + end + end @doc """ Creates a store. diff --git a/lib/launch_cart_web/channels/stripe_cart_channel.ex b/lib/launch_cart_web/channels/stripe_cart_channel.ex index e8c7d8b..0ed5cca 100644 --- a/lib/launch_cart_web/channels/stripe_cart_channel.ex +++ b/lib/launch_cart_web/channels/stripe_cart_channel.ex @@ -8,7 +8,7 @@ defmodule LaunchCartWeb.LaunchCartChannel do alias LiveState.Event def init("launch_cart:" <> store_id, %{"cart_id" => ""}, socket) do - case Stores.get_store!(store_id) do + case Stores.get_store(store_id) do %Store{id: store_id} -> {:ok, %{}, socket |> assign(:store_id, store_id)} nil -> {:error, "Store not found"} end @@ -37,7 +37,7 @@ defmodule LaunchCartWeb.LaunchCartChannel do "add_cart_item", %{"stripe_price" => stripe_price}, %{cart: cart} = state, - _socket + socket ) do case Carts.add_item(cart, stripe_price) do {:ok, cart} -> {:noreply, Map.put(state, :cart, cart)} @@ -48,12 +48,16 @@ defmodule LaunchCartWeb.LaunchCartChannel do "add_cart_item", %{"stripe_price" => stripe_price}, state, - %{assigns: %{store_id: store_id}} + %{assigns: %{store_id: store_id}} = socket ) do with {:ok, cart} <- Carts.create_cart(store_id), {:ok, cart} <- Carts.add_item(cart, stripe_price) do {:reply, %Event{name: "cart_created", detail: %{cart_id: cart.id}}, Map.put(state, :cart, cart)} + else + {:error, error} -> + push(socket, "error", %{message: error}) + {:noreply, state} end end diff --git a/lib/launch_cart_web/controllers/page_controller.ex b/lib/launch_cart_web/controllers/page_controller.ex index 4e82406..fc63e2d 100644 --- a/lib/launch_cart_web/controllers/page_controller.ex +++ b/lib/launch_cart_web/controllers/page_controller.ex @@ -18,7 +18,7 @@ defmodule LaunchCartWeb.PageController do end def fake_store(conn, %{"store_id" => store_id}) do - store = Stores.get_store!(store_id) + store = Stores.get_store(store_id) url = "#{String.replace(Endpoint.url(), "http:", "ws:")}/socket" render(conn, "fake_store.html", products: Carts.list_products(), url: url, store: store) end diff --git a/lib/launch_cart_web/live/store_live/index.ex b/lib/launch_cart_web/live/store_live/index.ex index 235ad61..ca4466c 100644 --- a/lib/launch_cart_web/live/store_live/index.ex +++ b/lib/launch_cart_web/live/store_live/index.ex @@ -17,7 +17,7 @@ defmodule LaunchCartWeb.StoreLive.Index do defp apply_action(socket, :edit, %{"id" => id}) do socket |> assign(:page_title, "Edit Store") - |> assign(:store, Stores.get_store!(id)) + |> assign(:store, Stores.get_store(id)) end defp apply_action(socket, :new, _params) do @@ -34,7 +34,7 @@ defmodule LaunchCartWeb.StoreLive.Index do @impl true def handle_event("delete", %{"id" => id}, %{assigns: %{current_user: user}} = socket) do - store = Stores.get_store!(id) + store = Stores.get_store(id) {:ok, _} = Stores.delete_store(store) {:noreply, assign(socket, :stores, list_stores(user))} diff --git a/lib/launch_cart_web/live/store_live/show.ex b/lib/launch_cart_web/live/store_live/show.ex index e08e5c8..f9daf57 100644 --- a/lib/launch_cart_web/live/store_live/show.ex +++ b/lib/launch_cart_web/live/store_live/show.ex @@ -16,7 +16,7 @@ defmodule LaunchCartWeb.StoreLive.Show do socket |> assign(:page_title, page_title(socket.assigns.live_action)) |> assign(:url, "#{wsurl}/socket") - |> assign(:store, Stores.get_store!(id))} + |> assign(:store, Stores.get_store(id))} end defp page_title(:show), do: "Show Store" diff --git a/mix.exs b/mix.exs index a3f5d77..751a662 100644 --- a/mix.exs +++ b/mix.exs @@ -45,7 +45,7 @@ defmodule LaunchCart.MixProject do {:floki, ">= 0.30.0", only: :test}, {:gettext, "~> 0.18"}, {:jason, "~> 1.2"}, - {:live_state, "~> 0.6.0"}, + {:live_state, "~> 0.7.2"}, {:mix_test_watch, "~> 1.0", only: [:dev, :test], runtime: false}, {:phoenix, "~> 1.7.1"}, {:phoenix_ecto, "~> 4.4"}, diff --git a/mix.lock b/mix.lock index fac5326..60c7fe0 100644 --- a/mix.lock +++ b/mix.lock @@ -7,19 +7,19 @@ "comeonin": {:hex, :comeonin, "5.3.3", "2c564dac95a35650e9b6acfe6d2952083d8a08e4a89b93a481acb552b325892e", [:mix], [], "hexpm", "3e38c9c2cb080828116597ca8807bb482618a315bfafd98c90bc22a821cc84df"}, "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"}, "cors_plug": {:hex, :cors_plug, "3.0.3", "7c3ac52b39624bc616db2e937c282f3f623f25f8d550068b6710e58d04a0e330", [:mix], [{:plug, "~> 1.13", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3f2d759e8c272ed3835fab2ef11b46bddab8c1ab9528167bd463b6452edf830d"}, - "cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"}, + "cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, - "cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"}, + "cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"}, "dart_sass": {:hex, :dart_sass, "0.5.1", "d45f20a8e324313689fb83287d4702352793ce8c9644bc254155d12656ade8b6", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "24f8a1c67e8b5267c51a33cbe6c0b5ebf12c2c83ace88b5ac04947d676b4ec81"}, "db_connection": {:hex, :db_connection, "2.5.0", "bb6d4f30d35ded97b29fe80d8bd6f928a1912ca1ff110831edcd238a1973652c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c92d5ba26cd69ead1ff7582dbb860adeedfff39774105a4f1c92cbb654b55aa2"}, "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.28", "0bf6546eb7cd6185ae086cbc5d20cd6dbb4b428aad14c02c49f7b554484b4586", [:mix], [], "hexpm", "501cef12286a3231dc80c81352a9453decf9586977f917a96e619293132743fb"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.37", "2ad73550e27c8946648b06905a57e4d454e4d7229c2dafa72a0348c99d8be5f7", [:mix], [], "hexpm", "6b19783f2802f039806f375610faa22da130b8edc21209d0bff47918bb48360e"}, "ecto": {:hex, :ecto, "3.10.3", "eb2ae2eecd210b4eb8bece1217b297ad4ff824b4384c0e3fdd28aaf96edd6135", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "44bec74e2364d491d70f7e42cd0d690922659d329f6465e89feb8a34e8cd3433"}, "ecto_sql": {:hex, :ecto_sql, "3.10.2", "6b98b46534b5c2f8b8b5f03f126e75e2a73c64f3c071149d32987a5378b0fdbd", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.10.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "68c018debca57cb9235e3889affdaec7a10616a4e3a80c99fa1d01fdafaa9007"}, "elixir_make": {:hex, :elixir_make, "0.6.3", "bc07d53221216838d79e03a8019d0839786703129599e9619f4ab74c8c096eac", [:mix], [], "hexpm", "f5cbd651c5678bcaabdbb7857658ee106b12509cd976c2c2fca99688e1daf716"}, "esbuild": {:hex, :esbuild, "0.5.0", "d5bb08ff049d7880ee3609ed5c4b864bd2f46445ea40b16b4acead724fb4c4a3", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "f183a0b332d963c4cfaf585477695ea59eef9a6f2204fdd0efa00e099694ffe5"}, "eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"}, - "ex_doc": {:hex, :ex_doc, "0.28.5", "3e52a6d2130ce74d096859e477b97080c156d0926701c13870a4e1f752363279", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "d2c4b07133113e9aa3e9ba27efb9088ba900e9e51caa383919676afdf09ab181"}, + "ex_doc": {:hex, :ex_doc, "0.30.6", "5f8b54854b240a2b55c9734c4b1d0dd7bdd41f71a095d42a70445c03cf05a281", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "bd48f2ddacf4e482c727f9293d9498e0881597eae6ddc3d9562bd7923375109f"}, "ex_machina": {:hex, :ex_machina, "2.7.0", "b792cc3127fd0680fecdb6299235b4727a4944a09ff0fa904cc639272cd92dc7", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "419aa7a39bde11894c87a615c4ecaa52d8f107bbdd81d810465186f783245bf8"}, "faker": {:hex, :faker, "0.17.0", "671019d0652f63aefd8723b72167ecdb284baf7d47ad3a82a15e9b8a6df5d1fa", [:mix], [], "hexpm", "a7d4ad84a93fd25c5f5303510753789fc2433ff241bf3b4144d3f6f291658a6a"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, @@ -33,26 +33,26 @@ "json_diff": {:hex, :json_diff, "0.1.3", "c80d5ca5416e785867e765e906e9a91b7efc35bfd505af276654d108f4995736", [:mix], [], "hexpm", "a5332e8293e7e9f384d34ea44645d7961334db73739165178fd4a7728d06f7d1"}, "jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"}, "live_elements": {:hex, :live_elements, "0.1.1", "294aab658293a4266a3790837cf735183670df9d68d29a445a1b63c8c8a5f3cd", [:mix], [{:ex_doc, ">= 0.0.0", [hex: :ex_doc, repo: "hexpm", optional: false]}, {:jason, ">= 0.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.7.1", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.18.15", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "82b900e93d2e34d26a05993e11108e9560a8e3e49b80671b7dbb3ef98b43c86d"}, - "live_state": {:hex, :live_state, "0.6.0", "a252bb09a427e106afbb4965d5da7d0f6eea875fe0e1eada03d20fe675d1d7ca", [:mix], [{:ex_doc, ">= 0.0.0", [hex: :ex_doc, repo: "hexpm", optional: false]}, {:json_diff, ">= 0.0.0", [hex: :json_diff, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.5.7", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "20e13b20fca121fe2be83fed07c8d329f61ab101ff391a2c8176d619352d7419"}, + "live_state": {:hex, :live_state, "0.7.2", "9757523a056fec8229e1de89f151533ed81eef34c389a0ae1bfca32291931295", [:mix], [{:ex_doc, ">= 0.0.0", [hex: :ex_doc, repo: "hexpm", optional: false]}, {:json_diff, ">= 0.0.0", [hex: :json_diff, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.5.7", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "324ec77109c5d2337262a4c86008a1d4e30637bfbf1699d501af0937569524c0"}, "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"}, - "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.2", "ad87296a092a46e03b7e9b0be7631ddcf64c790fa68a9ef5323b6cbb36affc72", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f3f5a1ca93ce6e092d92b6d9c049bcda58a3b617a8d888f8e7231c85630e8108"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, - "mime": {:hex, :mime, "2.0.3", "3676436d3d1f7b81b5a2d2bd8405f412c677558c81b1c92be58c00562bb59095", [:mix], [], "hexpm", "27a30bf0db44d25eecba73755acf4068cbfe26a4372f9eb3e4ea3a45956bff6b"}, + "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, "mix_test_watch": {:hex, :mix_test_watch, "1.1.0", "330bb91c8ed271fe408c42d07e0773340a7938d8a0d281d57a14243eae9dc8c3", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "52b6b1c476cbb70fd899ca5394506482f12e5f6b0d6acff9df95c7f1e0812ec3"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, - "phoenix": {:hex, :phoenix, "1.7.1", "a029bde19d9c3b559e5c3d06c78b76e81396bedd456a6acedb42f9c7b2e535a9", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.4", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "ea9d4a85c3592e37efa07d0dc013254fda445885facaefddcbf646375c116457"}, + "phoenix": {:hex, :phoenix, "1.7.7", "4cc501d4d823015007ba3cdd9c41ecaaf2ffb619d6fb283199fa8ddba89191e0", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "8966e15c395e5e37591b6ed0bd2ae7f48e961f0f60ac4c733f9566b519453085"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"}, - "phoenix_html": {:hex, :phoenix_html, "3.3.1", "4788757e804a30baac6b3fc9695bf5562465dd3f1da8eb8460ad5b404d9a2178", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "bed1906edd4906a15fd7b412b85b05e521e1f67c9a85418c55999277e553d0d3"}, + "phoenix_html": {:hex, :phoenix_html, "3.3.2", "d6ce982c6d8247d2fc0defe625255c721fb8d5f1942c5ac051f6177bffa5973f", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "44adaf8e667c1c20fb9d284b6b0fa8dc7946ce29e81ce621860aa7e96de9a11d"}, "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.7.2", "97cc4ff2dba1ebe504db72cb45098cb8e91f11160528b980bd282cc45c73b29c", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.18.3", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "0e5fdf063c7a3b620c566a30fcf68b7ee02e5e46fe48ee46a6ec3ba382dc05b7"}, "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"}, "phoenix_live_view": {:hex, :phoenix_live_view, "0.18.18", "1f38fbd7c363723f19aad1a04b5490ff3a178e37daaf6999594d5f34796c47fc", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a5810d0472f3189ede6d2a95bda7f31c6113156b91784a3426cb0ab6a6d85214"}, - "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"}, - "phoenix_template": {:hex, :phoenix_template, "1.0.1", "85f79e3ad1b0180abb43f9725973e3b8c2c3354a87245f91431eec60553ed3ef", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "157dc078f6226334c91cb32c1865bf3911686f8bcd6bcff86736f6253e6993ee"}, + "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"}, + "phoenix_template": {:hex, :phoenix_template, "1.0.3", "32de561eefcefa951aead30a1f94f1b5f0379bc9e340bb5c667f65f1edfa4326", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "16f4b6588a4152f3cc057b9d0c0ba7e82ee23afa65543da535313ad8d25d8e2c"}, "phoenix_view": {:hex, :phoenix_view, "2.0.2", "6bd4d2fd595ef80d33b439ede6a19326b78f0f1d8d62b9a318e3d9c1af351098", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "a929e7230ea5c7ee0e149ffcf44ce7cf7f4b6d2bfe1752dd7c084cdff152d36f"}, - "plug": {:hex, :plug, "1.14.1", "3148623796853ae96c628960b833bf6b6a894d6bdc8c199ef7160c41149b71f2", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a0e789be21a576b11ec55a0983e4e8f7c7b07d88dfb3b8da9e97767132271d40"}, + "plug": {:hex, :plug, "1.15.1", "b7efd81c1a1286f13efb3f769de343236bd8b7d23b4a9f40d3002fc39ad8f74c", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "459497bd94d041d98d948054ec6c0b76feacd28eec38b219ca04c0de13c79d30"}, "plug_cowboy": {:hex, :plug_cowboy, "2.6.1", "9a3bbfceeb65eff5f39dab529e5cd79137ac36e913c02067dba3963a26efe9b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "de36e1a21f451a18b790f37765db198075c25875c64834bcc82d90b309eb6613"}, "plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"}, "postgrex": {:hex, :postgrex, "0.17.3", "c92cda8de2033a7585dae8c61b1d420a1a1322421df84da9a82a6764580c503d", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "946cf46935a4fdca7a81448be76ba3503cff082df42c6ec1ff16a4bdfbfb098d"}, @@ -70,6 +70,6 @@ "uri_query": {:hex, :uri_query, "0.1.2", "ae35b83b472f3568c2c159eee3f3ccf585375d8a94fb5382db1ea3589e75c3b4", [:mix], [], "hexpm", "e3bc81816c98502c36498b9b2f239b89c71ce5eadfff7ceb2d6c0a2e6ae2ea0c"}, "wallaby": {:git, "https://github.com/launchscout/wallaby.git", "80f5959080b7dfd0f248124c7af9a2ed02402cb5", [branch: "shadow-dom"]}, "web_driver_client": {:hex, :web_driver_client, "0.2.0", "63b76cd9eb3b0716ec5467a0f8bead73d3d9612e63f7560d21357f03ad86e31a", [:mix], [{:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:tesla, "~> 1.3", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm", "83cc6092bc3e74926d1c8455f0ce927d5d1d36707b74d9a65e38c084aab0350f"}, - "websock": {:hex, :websock, "0.5.0", "f6bbce90226121d62a0715bca7c986c5e43de0ccc9475d79c55381d1796368cc", [:mix], [], "hexpm", "b51ac706df8a7a48a2c622ee02d09d68be8c40418698ffa909d73ae207eb5fb8"}, - "websock_adapter": {:hex, :websock_adapter, "0.5.0", "cea35d8bbf1a6964e32d4b02ceb561dfb769c04f16d60d743885587e7d2ca55b", [:mix], [{:bandit, "~> 0.6", [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", "16318b124effab8209b1eb7906c636374f623dc9511a8278ad09c083cea5bb83"}, + "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, + "websock_adapter": {:hex, :websock_adapter, "0.5.4", "7af8408e7ed9d56578539594d1ee7d8461e2dd5c3f57b0f2a5352d610ddde757", [: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", "d2c238c79c52cbe223fcdae22ca0bb5007a735b9e933870e241fce66afb4f4ab"}, } diff --git a/test/launch_cart/stores_test.exs b/test/launch_cart/stores_test.exs index 97b8798..07a6f8e 100644 --- a/test/launch_cart/stores_test.exs +++ b/test/launch_cart/stores_test.exs @@ -6,81 +6,93 @@ defmodule LaunchCart.StoresTest do import LaunchCart.Factory - describe "stores" do + @invalid_attrs %{name: nil} + + test "list_stores/0 returns all stores for a user" do + user = insert(:user) + other_user = insert(:user) + store = insert(:store, user: user) + store2 = insert(:store, user: other_user) + assert Stores.list_stores(user) |> Enum.map(& &1.id) == [store.id] + end - @invalid_attrs %{name: nil} + describe "get_store/1" do + test "returns the store with given id" do + store = insert(:store) + assert Stores.get_store(store.id) + end - test "list_stores/0 returns all stores for a user" do - user = insert(:user) - other_user = insert(:user) - store = insert(:store, user: user) - store2 = insert(:store, user: other_user) - assert Stores.list_stores(user) |> Enum.map(& &1.id) == [store.id] + test "returns nil with a made up id" do + assert Stores.get_store(Ecto.UUID.generate()) == nil end - test "get_store!/1 returns the store with given id" do - store = insert(:store) - assert Stores.get_store!(store.id) + test "returns nil with an invalid id" do + assert Stores.get_store("garbage") == nil end + end - test "create_store/1 with valid data creates a store" do - user = insert(:user) - valid_attrs = %{name: "some name", user_id: user.id} + test "create_store/1 with valid data creates a store" do + user = insert(:user) + valid_attrs = %{name: "some name", user_id: user.id} - assert {:ok, %Store{} = store} = Stores.create_store(valid_attrs) - assert store.name == "some name" - end + assert {:ok, %Store{} = store} = Stores.create_store(valid_attrs) + assert store.name == "some name" + end - test "create_store with stripe account loads products" do - stripe_account = insert(:stripe_account, stripe_id: "acc_valid_account") - user = insert(:user) - valid_attrs = %{name: "some name", user_id: user.id, stripe_account_id: stripe_account.id} - assert {:ok, %Store{}} = Stores.create_store(valid_attrs) - assert {:ok, %{product: %{name: "Happy mug"}, amount: 1100}} = Cachex.get(:stripe_products, "price_345") - Cachex.clear!(:stripe_products) - end + test "create_store with stripe account loads products" do + stripe_account = insert(:stripe_account, stripe_id: "acc_valid_account") + user = insert(:user) + valid_attrs = %{name: "some name", user_id: user.id, stripe_account_id: stripe_account.id} + assert {:ok, %Store{}} = Stores.create_store(valid_attrs) - test "create_store/1 with invalid data returns error changeset" do - assert {:error, %Ecto.Changeset{}} = Stores.create_store(@invalid_attrs) - end + assert {:ok, %{product: %{name: "Happy mug"}, amount: 1100}} = + Cachex.get(:stripe_products, "price_345") - test "update_store/2 with valid data updates the store" do - store = insert(:store) - update_attrs = %{name: "some updated name"} + Cachex.clear!(:stripe_products) + end - assert {:ok, %Store{} = updated_store} = Stores.update_store(store, update_attrs) - assert updated_store.name == "some updated name" - end + test "create_store/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Stores.create_store(@invalid_attrs) + end - test "update_store with a stripe account loads products" do - store = insert(:store) - stripe_account = insert(:stripe_account, stripe_id: "acc_valid_account") - assert {:ok, _store} = Stores.update_store(store, %{stripe_account_id: stripe_account.id}) - assert {:ok, %{product: %{name: "Happy mug"}, amount: 1100}} = Cachex.get(:stripe_products, "price_345") - Cachex.clear!(:stripe_products) - end + test "update_store/2 with valid data updates the store" do + store = insert(:store) + update_attrs = %{name: "some updated name"} - test "update_store/2 with invalid data returns error changeset" do - store = insert(:store) - assert {:error, %Ecto.Changeset{}} = Stores.update_store(store, @invalid_attrs) - end + assert {:ok, %Store{} = updated_store} = Stores.update_store(store, update_attrs) + assert updated_store.name == "some updated name" + end - test "delete_store/1 deletes the store" do - store = insert(:store) - assert {:ok, %Store{}} = Stores.delete_store(store) - assert_raise Ecto.NoResultsError, fn -> Stores.get_store!(store.id) end - end + test "update_store with a stripe account loads products" do + store = insert(:store) + stripe_account = insert(:stripe_account, stripe_id: "acc_valid_account") + assert {:ok, _store} = Stores.update_store(store, %{stripe_account_id: stripe_account.id}) - test "change_store/1 returns a store changeset" do - store = insert(:store) - assert %Ecto.Changeset{} = Stores.change_store(store) - end + assert {:ok, %{product: %{name: "Happy mug"}, amount: 1100}} = + Cachex.get(:stripe_products, "price_345") - test "delete_store cascades deleting" do - store = insert(:store) - cart = insert(:cart, store: store) - assert {:ok, %Store{}} = Stores.delete_store(store) - end + Cachex.clear!(:stripe_products) end + test "update_store/2 with invalid data returns error changeset" do + store = insert(:store) + assert {:error, %Ecto.Changeset{}} = Stores.update_store(store, @invalid_attrs) + end + + test "delete_store/1 deletes the store" do + store = insert(:store) + assert {:ok, %Store{}} = Stores.delete_store(store) + refute Stores.get_store(store.id) + end + + test "change_store/1 returns a store changeset" do + store = insert(:store) + assert %Ecto.Changeset{} = Stores.change_store(store) + end + + test "delete_store cascades deleting" do + store = insert(:store) + cart = insert(:cart, store: store) + assert {:ok, %Store{}} = Stores.delete_store(store) + end end diff --git a/test/launch_cart_web/channels/stripe_cart_channel_test.exs b/test/launch_cart_web/channels/stripe_cart_channel_test.exs index 5bafab5..2376276 100644 --- a/test/launch_cart_web/channels/stripe_cart_channel_test.exs +++ b/test/launch_cart_web/channels/stripe_cart_channel_test.exs @@ -48,6 +48,12 @@ defmodule LaunchCartWeb.LaunchCartChannelTest do assert %{store_id: ^store_id} = Carts.get_cart!(cart_id) end + + test "add non existent item", %{socket: socket, store: %{id: store_id}} do + push(socket, "lvs_evt:add_cart_item", %{"stripe_price" => "garbage"}) + + assert_push("error", %{message: "Product not found"}) + end end describe "joining with existing cart" do @@ -72,7 +78,10 @@ defmodule LaunchCartWeb.LaunchCartChannelTest do }) end - test "increase and decrease quantity", %{cart: %{id: cart_id, items: [%{id: item_id}]}, socket: socket} do + test "increase and decrease quantity", %{ + cart: %{id: cart_id, items: [%{id: item_id}]}, + socket: socket + } do push(socket, "lvs_evt:increase_quantity", %{"item_id" => item_id}) assert_push("state:change", %{ @@ -88,7 +97,6 @@ defmodule LaunchCartWeb.LaunchCartChannelTest do }) end - test "checking out", %{cart: %{id: cart_id}, socket: socket} do push(socket, "lvs_evt:checkout", %{"return_url" => "http://foo.bar"}) @@ -129,4 +137,19 @@ defmodule LaunchCartWeb.LaunchCartChannelTest do assert_push("state:change", %{state: %{}}) assert_push("checkout_complete", %{}) end + + test "joining non existant store" do + {:ok, _, socket} = + LaunchCartWeb.UserSocket + |> socket("my_socket", %{}) + |> subscribe_and_join( + LaunchCartWeb.LaunchCartChannel, + "launch_cart:#{Ecto.UUID.generate()}", + %{ + "cart_id" => "" + } + ) + + assert_push("error", %{message: "Store not found"}) + end end