From b2c25a152d03731bef2a1d83598a41cef20e3762 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sat, 7 Feb 2026 10:55:19 -0600 Subject: [PATCH] cleanup --- .github/workflows/elixir.yaml | 23 -- AGENTS.md | 2 +- config/config.exs | 2 - config/prod.exs | 2 - config/test.exs | 29 -- mix.exs | 5 +- mix.lock | 29 +- .../historical_loading_integration_test.exs | 327 ------------------ test/integration/map_integration_test.exs | 42 --- test/integration/simple_integration_test.exs | 27 -- test/test_helper.exs | 3 - test/time_independence_fixes.md | 50 --- 12 files changed, 17 insertions(+), 524 deletions(-) delete mode 100644 test/integration/historical_loading_integration_test.exs delete mode 100644 test/integration/map_integration_test.exs delete mode 100644 test/integration/simple_integration_test.exs delete mode 100644 test/time_independence_fixes.md diff --git a/.github/workflows/elixir.yaml b/.github/workflows/elixir.yaml index c2c8901..bbc82ab 100644 --- a/.github/workflows/elixir.yaml +++ b/.github/workflows/elixir.yaml @@ -115,29 +115,6 @@ jobs: - name: Check Formatting run: mix format --check-formatted - # Step: Install ChromeDriver for integration tests - - name: Setup ChromeDriver - uses: nanasess/setup-chromedriver@v2 - # Note: Using latest stable version instead of pinned version for better compatibility - - # Step: Start ChromeDriver in the background - - name: Start ChromeDriver - run: | - chromedriver --port=4444 --url-base=/wd/hub & - sleep 2 - # Step: Execute the tests. - name: Run tests run: mix test - - # Step: Run integration tests separately with Wallaby - # TEMPORARILY DISABLED: Integration tests need further debugging - # TODO: Re-enable once Wallaby tests are fixed - # - name: Run integration tests - # run: mix test --only integration - # timeout-minutes: 10 - # env: - # # Increase timeouts for browser tests in CI environment - # WALLABY_SCREENSHOT_ON_FAILURE: true - # WALLABY_MAX_WAIT_TIME: 30000 - # CHROMEDRIVER_URL: http://localhost:4444/wd/hub diff --git a/AGENTS.md b/AGENTS.md index 975e253..0a73464 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,7 +10,7 @@ Run `mix setup` once to fetch dependencies and prepare the Postgres database. Us Follow idiomatic Elixir with 2-space indentation and modules in `PascalCase`. The top-level `.formatter.exs` enforces a 120-character line limit, imports Phoenix HTML formatting, and loads the Styler plugin—always run `mix format` before committing. Keep function names in `snake_case`, LiveView hooks under `assets/js` in `camelCase`, and CSS utilities organized by Tailwind conventions. Prefer contexts for new domain modules and colocate schemas with their contexts inside `lib/aprsme`. ## Testing Guidelines -The project uses ExUnit with database sandboxing; aliases ensure `ecto.create` and `ecto.migrate` run before tests. Property-based tests live alongside unit tests using `StreamData`, and browser flows use Wallaby helpers in `test/support`. Name test files `_test.exs` and ensure async-friendly tests opt in with `use ExUnit.Case, async: true`. Check coverage locally with `mix coveralls.html` and review the generated report in `cover/`. +The project uses ExUnit with database sandboxing; aliases ensure `ecto.create` and `ecto.migrate` run before tests. Property-based tests live alongside unit tests using `StreamData`. Name test files `_test.exs` and ensure async-friendly tests opt in with `use ExUnit.Case, async: true`. Check coverage locally with `mix coveralls.html` and review the generated report in `cover/`. ## Commit & Pull Request Guidelines Commit history favors short, imperative subjects with optional Conventional Commit prefixes (`fix:`, `refactor:`). Keep each commit focused, formatted, and passing the suite. PRs should outline the change, reference related issues, note DB or config impacts, and include screenshots or logs for UI-facing updates. Confirm that formatting, tests, and static analysis commands above complete successfully before requesting review. diff --git a/config/config.exs b/config/config.exs index 89b6b28..952b3e3 100644 --- a/config/config.exs +++ b/config/config.exs @@ -142,5 +142,3 @@ config :tailwind, ] import_config "#{config_env()}.exs" - -import_config "appsignal.exs" diff --git a/config/prod.exs b/config/prod.exs index 2b50818..7abf8ea 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -1,7 +1,5 @@ import Config -config :appsignal, :config, active: true - # For production, don't forget to configure the url host # to something meaningful, Phoenix uses this information # when generating URLs. diff --git a/config/test.exs b/config/test.exs index 8b1e927..da2324d 100644 --- a/config/test.exs +++ b/config/test.exs @@ -80,32 +80,3 @@ config :phoenix, :plug_init_mode, :runtime # Disable swoosh api client as it is only required for production adapters. config :swoosh, :api_client, false - -# Configure Wallaby -config :wallaby, - driver: Wallaby.Chrome, - chromedriver: [ - headless: true, - # Additional Chrome options for CI stability - args: [ - "--no-sandbox", - "--disable-dev-shm-usage", - "--disable-gpu", - "--disable-setuid-sandbox", - "--disable-extensions", - "--disable-background-timer-throttling", - "--disable-backgrounding-occluded-windows", - "--disable-renderer-backgrounding", - "--window-size=1280,720", - "--disable-features=MacAppCodeSignClone" - ] - ], - screenshot_on_failure: true, - screenshot_dir: "test/screenshots", - base_url: "http://localhost:4002", - # Increase default timeouts for CI environment - max_wait_time: "WALLABY_MAX_WAIT_TIME" |> System.get_env("5000") |> String.to_integer(), - # Pool configuration for concurrent tests - pool_size: 1, - # Use ChromeDriver URL from environment if available (for CI) - chromedriver_base_url: System.get_env("CHROMEDRIVER_URL") diff --git a/mix.exs b/mix.exs index 5f03052..f7e0e8f 100644 --- a/mix.exs +++ b/mix.exs @@ -94,6 +94,7 @@ defmodule Aprsme.MixProject do {:exvcr, "~> 0.15", only: :test}, {:faker, "~> 0.18", only: [:dev, :test]}, {:floki, ">= 0.30.0", only: :test}, + {:lazy_html, ">= 0.1.0", only: :test}, {:mix_test_watch, "~> 1.1", only: [:dev, :test]}, {:sobelow, "~> 0.8", only: :dev}, {:stream_data, "~> 1.2.0", only: [:dev, :test]}, @@ -103,9 +104,7 @@ defmodule Aprsme.MixProject do # {:httpoison, "~> 1.8"}, {:hammer, "~> 7.0"}, {:cachex, "~> 4.1"}, - {:gettext_pseudolocalize, "~> 0.1"}, - {:wallaby, "~> 0.30.10", only: :test}, - {:lazy_html, "~> 0.1.8", only: :test} + {:gettext_pseudolocalize, "~> 0.1"} ] end diff --git a/mix.lock b/mix.lock index ce1cc22..4600038 100644 --- a/mix.lock +++ b/mix.lock @@ -3,7 +3,7 @@ "appsignal_phoenix": {:hex, :appsignal_phoenix, "2.7.0", "9284b4dfe40fb9a78ff371e8c7e9d3aa01bc46aa20fe3d31240bb7f9944cd728", [:mix], [{:appsignal, ">= 2.15.0 and < 3.0.0", [hex: :appsignal, repo: "hexpm", optional: false]}, {:appsignal_plug, ">= 2.1.0 and < 3.0.0", [hex: :appsignal_plug, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.11 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_live_view, "~> 0.9 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b4df4ffce4c37e85a20e0e37e1a10e65b096f97608cec1dd5bd58dc365111a44"}, "appsignal_plug": {:hex, :appsignal_plug, "2.1.1", "2fc3a32712eb6e559bab2aaef0369d4c832f3541393c5e4ceefe10088fe71d2f", [:mix], [{:appsignal, ">= 2.15.0 and < 3.0.0", [hex: :appsignal, repo: "hexpm", optional: false]}, {:plug, ">= 1.1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bbcaf3f888f019d088123c843583daf81dd97c8a9bd3cad0df7858a0a85e065d"}, "aprs": {:git, "https://github.com/aprsme/aprs.git", "c2a544ba31bc1eced480f3321256d74bd15de62a", [branch: "main"]}, - "bandit": {:hex, :bandit, "1.10.0", "f8293b4a4e6c06b31655ae10bd3462f59d8c5dbd1df59028a4984f10c5961147", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.18", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "43ebceb7060a4d8273e47d83e703d01b112198624ba0826980caa3f5091243c4"}, + "bandit": {:hex, :bandit, "1.10.2", "d15ea32eb853b5b42b965b24221eb045462b2ba9aff9a0bda71157c06338cbff", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.18", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "27b2a61b647914b1726c2ced3601473be5f7aa6bb468564a688646a689b3ee45"}, "bcrypt_elixir": {:hex, :bcrypt_elixir, "3.3.2", "d50091e3c9492d73e17fc1e1619a9b09d6a5ef99160eb4d736926fd475a16ca3", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "471be5151874ae7931911057d1467d908955f93554f7a6cd1b7d804cac8cef53"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "cachex": {:hex, :cachex, "4.1.1", "574c5cd28473db313a0a76aac8c945fe44191659538ca6a1e8946ec300b1a19f", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:ex_hash_ring, "~> 6.0", [hex: :ex_hash_ring, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "d6b7449ff98d6bb92dda58bd4fc3189cae9f99e7042054d669596f56dc503cd8"}, @@ -14,8 +14,8 @@ "cowboy": {:hex, :cowboy, "2.14.2", "4008be1df6ade45e4f2a4e9e2d22b36d0b5aba4e20b0a0d7049e28d124e34847", [:make, :rebar3], [{:cowlib, ">= 2.16.0 and < 3.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, ">= 1.8.0 and < 3.0.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "569081da046e7b41b5df36aa359be71a0c8874e5b9cff6f747073fc57baf1ab9"}, "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.16.0", "54592074ebbbb92ee4746c8a8846e5605052f29309d3a873468d76cdf932076f", [:make, :rebar3], [], "hexpm", "7f478d80d66b747344f0ea7708c187645cfcc08b11aa424632f78e25bf05db51"}, - "credo": {:hex, :credo, "1.7.15", "283da72eeb2fd3ccf7248f4941a0527efb97afa224bcdef30b4b580bc8258e1c", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "291e8645ea3fea7481829f1e1eb0881b8395db212821338e577a90bf225c5607"}, - "db_connection": {:hex, :db_connection, "2.8.1", "9abdc1e68c34c6163f6fb96a96532272d13ad7ca45262156ae8b7ec6d9dc4bec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a61a3d489b239d76f326e03b98794fb8e45168396c925ef25feb405ed09da8fd"}, + "credo": {:hex, :credo, "1.7.16", "a9f1389d13d19c631cb123c77a813dbf16449a2aebf602f590defa08953309d4", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d0562af33756b21f248f066a9119e3890722031b6d199f22e3cf95550e4f1579"}, + "db_connection": {:hex, :db_connection, "2.9.0", "a6a97c5c958a2d7091a58a9be40caf41ab496b0701d21e1d1abff3fa27a7f371", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "17d502eacaf61829db98facf6f20808ed33da6ccf495354a41e64fe42f9c509c"}, "decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"}, "decorator": {:hex, :decorator, "1.4.0", "a57ac32c823ea7e4e67f5af56412d12b33274661bb7640ec7fc882f8d23ac419", [:mix], [], "hexpm", "0a07cedd9083da875c7418dea95b78361197cf2bf3211d743f6f7ce39656597f"}, "dialyxir": {:hex, :dialyxir, "1.4.7", "dda948fcee52962e4b6c5b4b16b2d8fa7d50d8645bbae8b8685c3f9ecb7f5f4d", [:mix], [{:erlex, ">= 0.2.8", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b34527202e6eb8cee198efec110996c25c5898f43a4094df157f8d28f27d9efe"}, @@ -35,7 +35,7 @@ "exvcr": {:hex, :exvcr, "0.17.1", "3bae83d698a464a48212ad87c8ea4bcfb6bd76d53b937129472764e557616228", [:mix], [{:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:finch, "~> 0.16", [hex: :finch, repo: "hexpm", optional: true]}, {:httpoison, "~> 1.0 or ~> 2.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 1.0", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "a39d86980da183011366a878972e0ed43a5441814b701edd2e11360564e7bcab"}, "faker": {:hex, :faker, "0.18.0", "943e479319a22ea4e8e39e8e076b81c02827d9302f3d32726c5bf82f430e6e14", [:mix], [], "hexpm", "bfbdd83958d78e2788e99ec9317c4816e651ad05e24cfd1196ce5db5b3e81797"}, "file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"}, - "finch": {:hex, :finch, "0.20.0", "5330aefb6b010f424dcbbc4615d914e9e3deae40095e73ab0c1bb0968933cadf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2658131a74d051aabfcba936093c903b8e89da9a1b63e430bee62045fa9b2ee2"}, + "finch": {:hex, :finch, "0.21.0", "b1c3b2d48af02d0c66d2a9ebfb5622be5c5ecd62937cf79a88a7f98d48a8290c", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "87dc6e169794cb2570f75841a19da99cfde834249568f2a5b121b809588a4377"}, "fine": {:hex, :fine, "0.1.4", "b19a89c1476c7c57afb5f9314aed5960b5bc95d5277de4cb5ee8e1d1616ce379", [:mix], [], "hexpm", "be3324cc454a42d80951cf6023b9954e9ff27c6daa255483b3e8d608670303f5"}, "floki": {:hex, :floki, "0.38.0", "62b642386fa3f2f90713f6e231da0fa3256e41ef1089f83b6ceac7a3fd3abf33", [:mix], [], "hexpm", "a5943ee91e93fb2d635b612caf5508e36d37548e84928463ef9dd986f0d1abd9"}, "gen_stage": {:hex, :gen_stage, "1.3.2", "7c77e5d1e97de2c6c2f78f306f463bca64bf2f4c3cdd606affc0100b89743b7b", [:mix], [], "hexpm", "0ffae547fa777b3ed889a6b9e1e64566217413d018cabd825f786e843ffe63e7"}, @@ -47,12 +47,12 @@ "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "gridsquare": {:hex, :gridsquare, "0.2.0", "c556a5b5101db89743264b0d728601023035863487bbe36e9e50e93839adb4d7", [:mix], [], "hexpm", "dbf0dbb484681a1e97819b0667bfeaa8c8a48cf06a54bf96a8f26ee4158ad31a"}, "hackney": {:hex, :hackney, "1.17.1", "08463f93d2cc1a03817bf28d8dae6021543f773bd436c9377047224856c4422c", [:rebar3], [{:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "~> 3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "d2cba9e3c8103ad0320623e9f1c33e8d378a15eaabe2ee8ae441898f3d35a18c"}, - "hammer": {:hex, :hammer, "7.1.0", "9b55acd9951035f330aa1556e575e72d93334e8732daf5f2f602793d16008fe9", [:mix], [], "hexpm", "0ef3f0b9b92ae10a01604ca58adc2bfc8df0af4414a3afcf2dd79e256bc94c17"}, + "hammer": {:hex, :hammer, "7.2.0", "73113eca87f0fd20a6d3679c1182e8c4c1778266f61de4e9dc8c589dee156c30", [:mix], [], "hexpm", "c50fa865ddfe7b3d4f8a6941f56940679e02a9a1465b00668a95d140b101d828"}, "heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized", depth: 1]}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, "httpoison": {:hex, :httpoison, "2.2.1", "87b7ed6d95db0389f7df02779644171d7319d319178f6680438167d7b69b1f3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "51364e6d2f429d80e14fe4b5f8e39719cacd03eb3f9a9286e61e216feac2d2df"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, - "igniter": {:hex, :igniter, "0.7.0", "6848714fa5afa14258c82924a57af9364745316241a409435cf39cbe11e3ae80", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "1e7254780dbf4b44c9eccd6d86d47aa961efc298d7f520c24acb0258c8e90ba9"}, + "igniter": {:hex, :igniter, "0.7.2", "81c132c0df95963c7a228f74a32d3348773743ed9651f24183bfce0fe6ff16d1", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "f4cab73ec31f4fb452de1a17037f8a08826105265aa2d76486fcb848189bef9b"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm", "fc3499fed7a726995aa659143a248534adc754ebd16ccd437cd93b649a95091f"}, "jumper": {:hex, :jumper, "1.0.2", "68cdcd84472a00ac596b4e6459a41b3062d4427cbd4f1e8c8793c5b54f1406a7", [:mix], [], "hexpm", "9b7782409021e01ab3c08270e26f36eb62976a38c1aa64b2eaf6348422f165e1"}, @@ -76,29 +76,29 @@ "phoenix_html": {:hex, :phoenix_html, "4.3.0", "d3577a5df4b6954cd7890c84d955c470b5310bb49647f0a114a6eeecc850f7ad", [:mix], [], "hexpm", "3eaa290a78bab0f075f791a46a981bbe769d94bc776869f4f3063a14f30497ad"}, "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.8.7", "405880012cb4b706f26dd1c6349125bfc903fb9e44d1ea668adaf4e04d4884b7", [: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]}, {:ecto_sqlite3_extras, "~> 1.1.7 or ~> 1.2.0", [hex: :ecto_sqlite3_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "3a8625cab39ec261d48a13b7468dc619c0ede099601b084e343968309bd4d7d7"}, "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.6.2", "b18b0773a1ba77f28c52decbb0f10fd1ac4d3ae5b8632399bbf6986e3b665f62", [:mix], [{:file_system, "~> 0.2.10 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "d1f89c18114c50d394721365ffb428cce24f1c13de0467ffa773e2ff4a30d5b9"}, - "phoenix_live_view": {:hex, :phoenix_live_view, "1.1.19", "c95e9acbc374fb796ee3e24bfecc8213123c74d9f9e45667ca40bb0a4d242953", [:mix], [{:igniter, ">= 0.6.16 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:lazy_html, "~> 0.1.0", [hex: :lazy_html, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0-rc", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [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]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d5ad357d6b21562a5b431f0ad09dfe76db9ce5648c6949f1aac334c8c4455d32"}, + "phoenix_live_view": {:hex, :phoenix_live_view, "1.1.22", "9b3c985bfe38e82668594a8ce90008548f30b9f23b718ebaea4701710ce9006f", [:mix], [{:igniter, ">= 0.6.16 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:lazy_html, "~> 0.1.0", [hex: :lazy_html, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0-rc", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [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]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e1395d5622d8bf02113cb58183589b3da6f1751af235768816e90cc3ec5f1188"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.2.0", "ff3a5616e1bed6804de7773b92cbccfc0b0f473faf1f63d7daf1206c7aeaaa6f", [:mix], [], "hexpm", "adc313a5bf7136039f63cfd9668fde73bba0765e0614cba80c06ac9460ff3e96"}, "phoenix_pubsub_redis": {:hex, :phoenix_pubsub_redis, "3.0.1", "d4d856b1e57a21358e448543e1d091e07e83403dde4383b8be04ed9d2c201cbc", [:mix], [{:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5.1 or ~> 1.6", [hex: :poolboy, repo: "hexpm", optional: false]}, {:redix, "~> 0.10.0 or ~> 1.0", [hex: :redix, repo: "hexpm", optional: false]}], "hexpm", "0b36a17ff6e9a56159f8df8933d62b5c1f0695eae995a02e0c86c035ace6a309"}, "phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"}, "plug": {:hex, :plug, "1.19.1", "09bac17ae7a001a68ae393658aa23c7e38782be5c5c00c80be82901262c394c0", [: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", "560a0017a8f6d5d30146916862aaf9300b7280063651dd7e532b8be168511e62"}, - "plug_cowboy": {:hex, :plug_cowboy, "2.7.5", "261f21b67aea8162239b2d6d3b4c31efde4daa22a20d80b19c2c0f21b34b270e", [: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", "20884bf58a90ff5a5663420f5d2c368e9e15ed1ad5e911daf0916ea3c57f77ac"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.8.0", "07789e9c03539ee51bb14a07839cc95aa96999fd8846ebfd28c97f0b50c7b612", [: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", "9cbfaaf17463334ca31aed38ea7e08a68ee37cabc077b1e9be6d2fb68e0171d0"}, "plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, - "postgrex": {:hex, :postgrex, "0.21.1", "2c5cc830ec11e7a0067dd4d623c049b3ef807e9507a424985b8dcf921224cd88", [: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", "27d8d21c103c3cc68851b533ff99eef353e6a0ff98dc444ea751de43eb48bdac"}, + "postgrex": {:hex, :postgrex, "0.22.0", "fb027b58b6eab1f6de5396a2abcdaaeb168f9ed4eccbb594e6ac393b02078cbd", [:mix], [{:db_connection, "~> 2.9", [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", "a68c4261e299597909e03e6f8ff5a13876f5caadaddd0d23af0d0a61afcc5d84"}, "ranch": {:hex, :ranch, "2.2.0", "25528f82bc8d7c6152c57666ca99ec716510fe0925cb188172f41ce93117b1b0", [:make, :rebar3], [], "hexpm", "fa0b99a1780c80218a4197a59ea8d3bdae32fbff7e88527d7d8a4787eff4f8e7"}, "redix": {:hex, :redix, "1.5.2", "ab854435a663f01ce7b7847f42f5da067eea7a3a10c0a9d560fa52038fd7ab48", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:nimble_options, "~> 0.5.0 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "78538d184231a5d6912f20567d76a49d1be7d3fca0e1aaaa20f4df8e1142dcb8"}, - "req": {:hex, :req, "0.5.16", "99ba6a36b014458e52a8b9a0543bfa752cb0344b2a9d756651db1281d4ba4450", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "974a7a27982b9b791df84e8f6687d21483795882a7840e8309abdbe08bb06f09"}, + "req": {:hex, :req, "0.5.17", "0096ddd5b0ed6f576a03dde4b158a0c727215b15d2795e59e0916c6971066ede", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0b8bc6ffdfebbc07968e59d3ff96d52f2202d0536f10fef4dc11dc02a2a43e39"}, "resend": {:hex, :resend, "0.4.5", "a4a0701c590d1363e9c8e85457b9a143481d35225b0a5f558d9091b3e71d3589", [:mix], [{:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.3", [hex: :swoosh, repo: "hexpm", optional: false]}, {:tesla, "~> 1.5", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm", "1a340ba442febfe0443386393f7c086875f0656e7b41df3758deb869f1b99df1"}, "rewrite": {:hex, :rewrite, "1.2.0", "80220eb14010e175b67c939397e1a8cdaa2c32db6e2e0a9d5e23e45c0414ce21", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "a1cd702bbb9d51613ab21091f04a386d750fc6f4516b81900df082d78b2d8c50"}, "sentry": {:hex, :sentry, "11.0.4", "60371c96cefd247e0fc98840bba2648f64f19aa0b8db8e938f5a98421f55b619", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: true]}, {:igniter, "~> 0.5", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_ownership, "~> 0.3.0 or ~> 1.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}, {:opentelemetry, ">= 0.0.0", [hex: :opentelemetry, repo: "hexpm", optional: true]}, {:opentelemetry_api, ">= 0.0.0", [hex: :opentelemetry_api, repo: "hexpm", optional: true]}, {:opentelemetry_exporter, ">= 0.0.0", [hex: :opentelemetry_exporter, repo: "hexpm", optional: true]}, {:opentelemetry_semantic_conventions, ">= 0.0.0", [hex: :opentelemetry_semantic_conventions, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_live_view, "~> 0.20 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.6", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "feaafc284dc204c82aadaddc884227aeaa3480decb274d30e184b9d41a700c66"}, "sleeplocks": {:hex, :sleeplocks, "1.1.3", "96a86460cc33b435c7310dbd27ec82ca2c1f24ae38e34f8edde97f756503441a", [:rebar3], [], "hexpm", "d3b3958552e6eb16f463921e70ae7c767519ef8f5be46d7696cc1ed649421321"}, "sobelow": {:hex, :sobelow, "0.14.1", "2f81e8632f15574cba2402bcddff5497b413c01e6f094bc0ab94e83c2f74db81", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8fac9a2bd90fdc4b15d6fca6e1608efb7f7c600fa75800813b794ee9364c87f2"}, - "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, - "spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"}, + "sourceror": {:hex, :sourceror, "1.10.1", "325753ed460fe9fa34ebb4deda76d57b2e1507dcd78a5eb9e1c41bfb78b7cdfe", [:mix], [], "hexpm", "288f3079d93865cd1e3e20df5b884ef2cb440e0e03e8ae393624ee8a770ba588"}, + "spitfire": {:hex, :spitfire, "0.3.2", "476b7b5151fd053a864dae7b5eaeed01811e8b2ff3f24f3c048af1c9dfee5e3d", [:mix], [], "hexpm", "014f7b8c6dd45d1e3b08103c7e61515a590efc872441cf3e933a20efa4b5c46c"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "stream_data": {:hex, :stream_data, "1.2.0", "58dd3f9e88afe27dc38bef26fce0c84a9e7a96772b2925c7b32cd2435697a52b", [:mix], [], "hexpm", "eb5c546ee3466920314643edf68943a5b14b32d1da9fe01698dc92b73f89a9ed"}, - "styler": {:hex, :styler, "1.10.0", "343f1f7bb19a8893c2841a9ae90665b68d2edf6cc37b964a5099e60c78815c2e", [:mix], [], "hexpm", "6a78876611869466139e63722df4cbbb56b18a842d88c19f23ca844d914ad91a"}, - "swoosh": {:hex, :swoosh, "1.20.0", "b04134c2b302da74c3a95ca4ddde191e4854d2847d6687783fecb023a9647598", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:idna, "~> 6.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "13e610f709bae54851d68afb6862882aa646e5c974bf49e3bf5edd84a73cf213"}, + "styler": {:hex, :styler, "1.10.1", "9229050c978bfaaab1d94e8673843576d0127d48fe64824a30babde3d6342475", [:mix], [], "hexpm", "d86cbcc70e8ab424393af313d1d885931ba9dc7c383d7dd30f4ab255a8d39f73"}, + "swoosh": {:hex, :swoosh, "1.20.1", "0f570fc03a87d71b4d74d64f33f57d6c3d69a6f0a6b3ae73f682acce1fdc5a7b", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:idna, "~> 6.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "08292f83045f57296398a8640bbd49cd44fe23eb8146351b14c8efdcee474454"}, "table_rex": {:hex, :table_rex, "4.1.0", "fbaa8b1ce154c9772012bf445bfb86b587430fb96f3b12022d3f35ee4a68c918", [:mix], [], "hexpm", "95932701df195d43bc2d1c6531178fc8338aa8f38c80f098504d529c43bc2601"}, "tailwind": {:hex, :tailwind, "0.4.1", "e7bcc222fe96a1e55f948e76d13dd84a1a7653fb051d2a167135db3b4b08d3e9", [:mix], [], "hexpm", "6249d4f9819052911120dbdbe9e532e6bd64ea23476056adb7f730aa25c220d1"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, @@ -111,7 +111,6 @@ "thousand_island": {:hex, :thousand_island, "1.4.3", "2158209580f633be38d43ec4e3ce0a01079592b9657afff9080d5d8ca149a3af", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6e4ce09b0fd761a58594d02814d40f77daff460c48a7354a15ab353bb998ea0b"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.1", "a48703a25c170eedadca83b11e88985af08d35f37c6f664d6dcfb106a97782fc", [:rebar3], [], "hexpm", "b3a917854ce3ae233619744ad1e0102e05673136776fb2fa76234f3e03b23642"}, "unsafe": {:hex, :unsafe, "1.0.2", "23c6be12f6c1605364801f4b47007c0c159497d0446ad378b5cf05f1855c0581", [:mix], [], "hexpm", "b485231683c3ab01a9cd44cb4a79f152c6f3bb87358439c6f68791b85c2df675"}, - "wallaby": {:hex, :wallaby, "0.30.11", "93b635bb3d01b11b5a80f83a5d9be59e87ccc8c8390136b7c526dd4fc7e485e3", [:mix], [{:ecto_sql, ">= 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}, {:httpoison, "~> 0.12 or ~> 1.0 or ~> 2.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix_ecto, ">= 3.0.0", [hex: :phoenix_ecto, repo: "hexpm", optional: true]}, {:web_driver_client, "~> 0.2.0", [hex: :web_driver_client, repo: "hexpm", optional: false]}], "hexpm", "407b50972e3827ce77e3b8292c36dcbd6b21b6837cc4f12ee8767e92a72610ac"}, "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.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, "websock_adapter": {:hex, :websock_adapter, "0.5.9", "43dc3ba6d89ef5dec5b1d0a39698436a1e856d000d84bf31a3149862b01a287f", [: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", "5534d5c9adad3c18a0f58a9371220d75a803bf0b9a3d87e6fe072faaeed76a08"}, diff --git a/test/integration/historical_loading_integration_test.exs b/test/integration/historical_loading_integration_test.exs deleted file mode 100644 index 4292bf7..0000000 --- a/test/integration/historical_loading_integration_test.exs +++ /dev/null @@ -1,327 +0,0 @@ -defmodule AprsmeWeb.HistoricalLoadingIntegrationTest do - @moduledoc """ - Integration tests for historical packet loading using Wallaby - Tests the complete user experience including initial page load behavior - """ - use ExUnit.Case, async: false - use Wallaby.Feature - - import Aprsme.PacketsFixtures - import Wallaby.Browser - import Wallaby.Query - - alias Aprsme.Repo - alias Ecto.Adapters.SQL.Sandbox - - setup do - :ok = Sandbox.checkout(Repo) - # Use shared mode for Wallaby tests - Sandbox.mode(Repo, {:shared, self()}) - - # Use real Packets module for integration tests - Application.put_env(:aprsme, :packets_module, Aprsme.Packets) - - on_exit(fn -> - # Restore mock for other tests - Application.put_env(:aprsme, :packets_module, Aprsme.PacketsMock) - end) - - {:ok, %{}} - end - - describe "historical packet loading on page load" do - @describetag :integration - @describetag timeout: 60_000 - feature "displays historical packets immediately after map loads", %{session: session} do - # Create test packets with known positions - # Make sure they're recent enough to be loaded - now = DateTime.utc_now() - - packet1 = - packet_fixture(%{ - sender: "INTTEST1", - base_callsign: "INTTEST1", - ssid: "0", - lat: Decimal.new("40.7128"), - lon: Decimal.new("-74.0060"), - received_at: DateTime.add(now, -20 * 60, :second), - comment: "Integration test station 1", - symbol_code: "k", - symbol_table_id: "/", - has_position: true, - data_type: "position" - }) - - packet2 = - packet_fixture(%{ - sender: "INTTEST2", - base_callsign: "INTTEST2", - ssid: "0", - lat: Decimal.new("40.7580"), - lon: Decimal.new("-73.9855"), - received_at: DateTime.add(now, -10 * 60, :second), - comment: "Integration test station 2", - symbol_code: "-", - symbol_table_id: "/", - has_position: true, - data_type: "position" - }) - - # Debug: Verify packets were created - IO.puts("Created packets: #{inspect([packet1.id, packet2.id])}") - - # Navigate to the map with the test location in view - # Center on New York area where our test packets are located - session - |> visit("/?lat=40.735&lon=-73.996&zoom=11") - |> assert_has(css("#aprs-map")) - - # Wait for map container to be present - assert_has(session, css(".leaflet-container")) - - # Wait for map to fully initialize - Process.sleep(2000) - - # Execute script to check map state and manually trigger historical loading - execute_script(session, """ - // Check if map is initialized - if (!window.aprsMap || !window.aprsMap.map) { - console.error('Map not initialized'); - return false; - } - - // Get the LiveView hook - const mapElement = document.getElementById('aprs-map'); - if (!mapElement || !mapElement.__hook__) { - console.error('Map hook not found'); - return false; - } - - // Manually push a bounds_changed event - mapElement.__hook__.pushEvent('bounds_changed', { - north: 40.9, - south: 40.6, - east: -73.8, - west: -74.2, - zoom: 11 - }); - - return true; - """) - - # Wait for packets to load and render - Process.sleep(5000) - - # Try to find markers with a more specific selector - # Leaflet markers have specific classes - markers = all(session, css(".leaflet-marker-icon")) - marker_count = length(markers) - - if marker_count == 0 do - # Take screenshot for debugging - take_screenshot(session, name: "no_markers_found") - - # Check if there are any error messages - page_text = Wallaby.Browser.text(session) - IO.puts("Page text: #{page_text}") - end - - # Check that markers are present on the map - assert marker_count > 0, "Expected to find markers on the map, but found #{marker_count}" - - # Verify at least 2 markers are present (our test packets) - marker_count = - session - |> all(css(".leaflet-marker-icon")) - |> length() - - assert marker_count >= 2, "Expected at least 2 markers, found #{marker_count}" - - # Click on a marker to verify it's one of our test packets - click(session, css(".leaflet-marker-icon", at: 0)) - - # Wait for popup to appear - Process.sleep(1000) - - # Verify popup contains one of our test callsigns - assert_has(session, css(".leaflet-popup-content", text: ~r/INTTEST[12]/)) - end - - feature "loads packets within specified historical time range", %{session: session} do - now = DateTime.utc_now() - - # Create packets at different times - _old_packet = - packet_fixture(%{ - sender: "OLDTEST", - base_callsign: "OLDTEST", - ssid: "0", - lat: 40.7128, - lon: -74.0060, - # 3 hours ago - received_at: DateTime.add(now, -3 * 60 * 60, :second), - comment: "Old packet - should not appear with hist=1" - }) - - _recent_packet = - packet_fixture(%{ - sender: "RECENTTEST", - base_callsign: "RECENTTEST", - ssid: "0", - lat: 40.7128, - lon: -74.0060, - # 30 minutes ago - received_at: DateTime.add(now, -30 * 60, :second), - comment: "Recent packet - should appear" - }) - - # Navigate to map with 1 hour historical range (default) - session - |> visit("/?hist=1&lat=39.8283&lon=-98.5795&zoom=6") - |> assert_has(css("#aprs-map")) - - # Wait for historical loading - Process.sleep(3000) - - # Click on the marker (should be the recent one) - click(session, css(".leaflet-marker-icon", at: 0)) - Process.sleep(1000) - - # Verify it's the recent packet, not the old one - assert_has(session, css(".leaflet-popup-content", text: "RECENTTEST")) - refute_has(session, css(".leaflet-popup-content", text: "OLDTEST")) - - # Now test with extended historical range - session - # 6 hours - |> visit("/?hist=6&lat=39.8283&lon=-98.5795&zoom=6") - |> assert_has(css("#aprs-map")) - - Process.sleep(3000) - - # Now both packets should be visible - marker_count = - session - |> all(css(".leaflet-marker-icon")) - |> length() - - assert marker_count >= 2, "Expected at least 2 markers with 6-hour range" - end - - feature "updates historical packets when bounds change", %{session: session} do - now = DateTime.utc_now() - - # Create packets in different locations - _nyc_packet = - packet_fixture(%{ - sender: "NYC1", - base_callsign: "NYC1", - ssid: "0", - lat: 40.7128, - lon: -74.0060, - received_at: DateTime.add(now, -30 * 60, :second), - comment: "NYC packet" - }) - - _la_packet = - packet_fixture(%{ - sender: "LA1", - base_callsign: "LA1", - ssid: "0", - lat: 34.0522, - lon: -118.2437, - received_at: DateTime.add(now, -30 * 60, :second), - comment: "LA packet" - }) - - # Start focused on NYC - session - |> visit("/?lat=40.7128&lng=-74.0060&z=10") - |> assert_has(css("#aprs-map")) - - Process.sleep(3000) - - # Should see NYC packet - click(session, css(".leaflet-marker-icon", at: 0)) - Process.sleep(1000) - - assert_has(session, css(".leaflet-popup-content", text: "NYC1")) - - # Close popup - send_keys(session, [:escape]) - - # Pan to LA (this would be done via map interaction in real usage) - # For testing, we'll navigate to new URL - visit(session, "/?lat=34.0522&lng=-118.2437&z=10") - Process.sleep(3000) - - # Should now see LA packet instead - click(session, css(".leaflet-marker-icon", at: 0)) - Process.sleep(1000) - - assert_has(session, css(".leaflet-popup-content", text: "LA1")) - end - end - - describe "historical loading with tracked callsigns" do - @describetag :integration - feature "loads all packets for tracked callsign regardless of bounds", %{session: session} do - now = DateTime.utc_now() - - # Create packets for tracked station at different locations - _packet1 = - packet_fixture(%{ - sender: "TRACK1-9", - base_callsign: "TRACK1", - ssid: "9", - lat: 40.7128, - lon: -74.0060, - received_at: DateTime.add(now, -45 * 60, :second), - comment: "NYC position" - }) - - _packet2 = - packet_fixture(%{ - sender: "TRACK1-9", - base_callsign: "TRACK1", - ssid: "9", - lat: 41.8781, - lon: -87.6298, - received_at: DateTime.add(now, -30 * 60, :second), - comment: "Chicago position" - }) - - _packet3 = - packet_fixture(%{ - sender: "TRACK1-9", - base_callsign: "TRACK1", - ssid: "9", - lat: 34.0522, - lon: -118.2437, - received_at: DateTime.add(now, -15 * 60, :second), - comment: "LA position" - }) - - # Navigate to tracked callsign URL - session - |> visit("/TRACK1-9?lat=39.8283&lon=-98.5795&zoom=4") - |> assert_has(css("#aprs-map")) - - # Wait for map to load and center on latest position - Process.sleep(3000) - - # Should see trail connecting all positions - # Verify we have markers (latest position + trail points) - marker_count = - session - |> all(css(".leaflet-marker-icon")) - |> length() - - # Should have at least 1 marker for current position - assert marker_count >= 1, "Expected markers for tracked station" - - # Verify polyline trail exists - assert_has(session, css(".leaflet-pane .leaflet-overlay-pane polyline")) - end - end -end diff --git a/test/integration/map_integration_test.exs b/test/integration/map_integration_test.exs deleted file mode 100644 index e82a43f..0000000 --- a/test/integration/map_integration_test.exs +++ /dev/null @@ -1,42 +0,0 @@ -defmodule AprsmeWeb.MapIntegrationTest do - @moduledoc """ - Integration tests for the main map interface using Wallaby - Tests the complete user experience including JavaScript interactions - """ - use ExUnit.Case, async: false - use Wallaby.Feature - - import Wallaby.Browser - - alias Aprsme.Repo - alias Ecto.Adapters.SQL.Sandbox - alias Wallaby.Query - - @moduletag :integration - - setup do - :ok = Sandbox.checkout(Repo) - # Use shared mode for Wallaby tests - Sandbox.mode(Repo, {:shared, self()}) - - {:ok, %{}} - end - - feature "user can view the main map interface", %{session: session} do - session - |> visit("/") - |> assert_has(Query.css("body")) - end - - feature "page loads successfully", %{session: session} do - session - |> visit("/") - |> assert_has(Query.css("body")) - end - - feature "can access different routes", %{session: session} do - session - |> visit("/info") - |> assert_has(Query.css("body")) - end -end diff --git a/test/integration/simple_integration_test.exs b/test/integration/simple_integration_test.exs deleted file mode 100644 index 62b54cd..0000000 --- a/test/integration/simple_integration_test.exs +++ /dev/null @@ -1,27 +0,0 @@ -defmodule AprsmeWeb.SimpleIntegrationTest do - @moduledoc """ - Simple integration test to verify Wallaby setup works - """ - use ExUnit.Case, async: false - use Wallaby.Feature - - import Wallaby.Browser - - alias Ecto.Adapters.SQL.Sandbox - alias Wallaby.Query - - @moduletag :integration - - setup do - :ok = Sandbox.checkout(Aprsme.Repo) - Sandbox.mode(Aprsme.Repo, {:shared, self()}) - - {:ok, %{}} - end - - feature "can visit homepage and see title", %{session: session} do - session - |> visit("/") - |> assert_has(Query.css("body")) - end -end diff --git a/test/test_helper.exs b/test/test_helper.exs index 596e6c3..dc3950b 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -26,6 +26,3 @@ Application.put_env(:aprsme, :aprsme_is_default_filter, "r/0/0/1") Application.put_env(:aprsme, :packets_module, Aprsme.PacketsMock) # AprsIsMock is automatically loaded from test/support via elixirc_paths - -# Configure Wallaby for integration tests -{:ok, _} = Application.ensure_all_started(:wallaby) diff --git a/test/time_independence_fixes.md b/test/time_independence_fixes.md deleted file mode 100644 index a789709..0000000 --- a/test/time_independence_fixes.md +++ /dev/null @@ -1,50 +0,0 @@ -# Time Independence Test Fixes - -This document summarizes the changes made to ensure tests pass regardless of when they are executed. - -## Fixed Issues - -### 1. TimeHelpers Tests (`test/aprsme_web/time_helpers_test.exs`) -- Changed exact string matches to flexible pattern matching -- Example: `"1 minute ago"` → `["1 minute ago", "about 1 minute ago"]` -- Added regex patterns for variable outputs - -### 2. Packets Oldest Tests (`test/aprsme/packets_oldest_test.exs`) -- Replaced hardcoded dates like `~U[2023-01-01 00:00:00Z]` -- Now uses relative dates: `DateTime.add(now, -365 * 24 * 60 * 60, :second)` -- All date calculations are now relative to current time - -### 3. Broadcast Task Supervisor Tests (`test/aprsme/broadcast_task_supervisor_test.exs`) -- Increased timing assertion from 100ms to 1000ms -- Makes tests less sensitive to system load and CI environment performance - -### 4. Movement Tests (`test/aprsme_web/live/map_live/movement_test.exs`) -- Increased `refute_push_event` timeout from 500ms to 2000ms -- Prevents false failures on slower systems - -### 5. Packet Consumer Tests (`test/aprsme/packet_consumer_test.exs`) -- Increased Process.sleep from 20ms to 100ms for async operations -- Increased assert_receive timeout from 1000ms to 5000ms - -### 6. Integration Tests (`test/integration/historical_loading_integration_test.exs`) -- Increased all Process.sleep calls: 500ms → 1000ms, 2000ms → 3000ms -- Gives Wallaby more time for browser operations - -### 7. Streaming Packets PubSub Tests (`test/aprsme/streaming_packets_pubsub_test.exs`) -- Increased assert_receive timeout from 100ms to 1000ms -- Increased refute_receive timeout from 100ms to 500ms - -## General Patterns Applied - -1. **Relative Time Calculations**: All date/time calculations now use offsets from `DateTime.utc_now()` -2. **Flexible Assertions**: String comparisons allow for slight variations in output -3. **Generous Timeouts**: Increased timeouts to handle slower CI environments -4. **No Hardcoded Dates**: Removed all specific date literals - -## Testing Strategy - -These changes ensure that: -- Tests pass regardless of the current date/time -- Tests are resilient to performance variations -- Tests work reliably in CI/CD environments -- Tests don't fail due to timezone differences \ No newline at end of file