Phoenix 1.8 app that scrapes ammunition retailers (Lucky Gunner, SGAmmo) for price data and displays historical price trends. - Data model: retailers, calibers, products, price snapshots - Scraper infrastructure with Req, Floki, realistic browser headers - Oban-scheduled scrape jobs (every 4h with randomized delays) - LiveView pages: homepage with category cards, caliber detail with price table, Chart.js price history, and price stats banner - 18 seeded calibers across handgun/rifle/rimfire/shotgun categories - 77 tests
37 lines
1.2 KiB
Elixir
37 lines
1.2 KiB
Elixir
defmodule Ammoprices.Scraping.CaliberMatcherTest do
|
|
use Ammoprices.DataCase, async: true
|
|
|
|
import Ammoprices.Fixtures
|
|
|
|
alias Ammoprices.Scraping.CaliberMatcher
|
|
|
|
describe "match/2" do
|
|
test "matches by caliber name" do
|
|
caliber = caliber_fixture(%{name: "9mm Luger", slug: "9mm-luger", aliases: ["9mm", "9x19"]})
|
|
calibers = [caliber]
|
|
|
|
assert CaliberMatcher.match("Federal 9mm Luger 115gr FMJ", calibers) == caliber
|
|
end
|
|
|
|
test "matches by alias" do
|
|
caliber = caliber_fixture(%{name: "9mm Luger", slug: "9mm-luger", aliases: ["9mm", "9x19"]})
|
|
calibers = [caliber]
|
|
|
|
assert CaliberMatcher.match("Wolf 9x19 124gr FMJ", calibers) == caliber
|
|
end
|
|
|
|
test "returns nil when no match" do
|
|
caliber = caliber_fixture(%{name: "9mm Luger", slug: "9mm-luger", aliases: ["9mm", "9x19"]})
|
|
calibers = [caliber]
|
|
|
|
assert CaliberMatcher.match("Some .45 ACP Ammo", calibers) == nil
|
|
end
|
|
|
|
test "match is case insensitive" do
|
|
caliber = caliber_fixture(%{name: "9mm Luger", slug: "9mm-luger", aliases: ["9mm", "9x19"]})
|
|
calibers = [caliber]
|
|
|
|
assert CaliberMatcher.match("WOLF 9MM LUGER 115GR", calibers) == caliber
|
|
end
|
|
end
|
|
end
|