From 59ce580b9964f0a72d2455cf81022c291ac92da5 Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Sat, 21 Mar 2026 09:21:21 +0000 Subject: [PATCH] Can filter records by release year --- lib/music_library/records.ex | 4 ++++ lib/music_library/records/search_parser.ex | 28 ++++++++++++++++++++-- test/music_library/collection_test.exs | 20 ++++++++++++++++ test/music_library/wishlist_test.exs | 11 +++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/lib/music_library/records.ex b/lib/music_library/records.ex index 1eb105b6..e05d033e 100644 --- a/lib/music_library/records.ex +++ b/lib/music_library/records.ex @@ -157,6 +157,10 @@ defmodule MusicLibrary.Records do ) ) + {:release_year, year}, search -> + search + |> where([r], fragment("substr(?, 1, 4) = ?", r.release_date, ^to_string(year))) + {:query, ""}, search -> search diff --git a/lib/music_library/records/search_parser.ex b/lib/music_library/records/search_parser.ex index f2b5344c..aca90d97 100644 --- a/lib/music_library/records/search_parser.ex +++ b/lib/music_library/records/search_parser.ex @@ -11,6 +11,7 @@ defmodule MusicLibrary.Records.SearchParser do - `format:value` — filter by format (e.g. `cd`, `vinyl`) - `type:value` — filter by type (e.g. `album`, `single`) - `purchase_year:YYYY` — filter by purchase year + - `release_year:YYYY` — filter by release year Multi-word values can be quoted: `artist:"the pineapple thief"`. Unrecognized format/type values are silently ignored. @@ -25,7 +26,8 @@ defmodule MusicLibrary.Records.SearchParser do optional(:genre) => String.t(), optional(:format) => atom(), optional(:type) => atom(), - optional(:purchase_year) => integer() + optional(:purchase_year) => integer(), + optional(:release_year) => integer() } import NimbleParsec @@ -54,6 +56,9 @@ defmodule MusicLibrary.Records.SearchParser do purchase_year_filter = ignore(string("purchase_year:")) purchase_year = concat(purchase_year_filter, year) |> tag(:purchase_year) + release_year_filter = ignore(string("release_year:")) + release_year = concat(release_year_filter, year) |> tag(:release_year) + genre_filter = ignore(string("genre:")) genre = concat(genre_filter, query) |> tag(:genre) @@ -86,7 +91,21 @@ defmodule MusicLibrary.Records.SearchParser do |> tag(:type) search = - repeat(choice([artist, album, mbid, genre, space, comma, format, type, purchase_year, query])) + repeat( + choice([ + artist, + album, + mbid, + genre, + space, + comma, + format, + type, + purchase_year, + release_year, + query + ]) + ) defparsecp(:search_parser, search) @@ -123,6 +142,8 @@ defmodule MusicLibrary.Records.SearchParser do {:ok, %{type: :album}} iex> MusicLibrary.Records.SearchParser.parse("purchase_year:2024") {:ok, %{purchase_year: 2024}} + iex> MusicLibrary.Records.SearchParser.parse("release_year:2024") + {:ok, %{release_year: 2024}} """ @spec parse(String.t()) :: {:ok, search_result()} def parse(""), do: {:ok, %{query: ""}} @@ -168,6 +189,9 @@ defmodule MusicLibrary.Records.SearchParser do {:purchase_year, [{:year, [value]}]}, acc -> Map.put(acc, :purchase_year, value) + {:release_year, [{:year, [value]}]}, acc -> + Map.put(acc, :release_year, value) + {:query, [value]}, acc -> Map.update(acc, :query, value, &(&1 <> " " <> value)) diff --git a/test/music_library/collection_test.exs b/test/music_library/collection_test.exs index 43d6441b..9312ba43 100644 --- a/test/music_library/collection_test.exs +++ b/test/music_library/collection_test.exs @@ -229,6 +229,26 @@ defmodule MusicLibrary.CollectionTest do end end + describe "search_records/2 with release_year" do + test "filters by release year" do + record_with_artist("Artist A", %{ + title: "Album 1994", + release_date: "1994-09-13", + purchased_at: ~U[2024-12-27 16:50:57Z] + }) + + record_with_artist("Artist B", %{ + title: "Album 2020", + release_date: "2020", + purchased_at: ~U[2024-12-28 16:50:57Z] + }) + + assert [%{title: "Album 1994"}] = Collection.search_records("release_year:1994") + assert [%{title: "Album 2020"}] = Collection.search_records("release_year:2020") + assert [] = Collection.search_records("release_year:2000") + end + end + describe "collected_artist_ids/0" do setup [:fill_collection] diff --git a/test/music_library/wishlist_test.exs b/test/music_library/wishlist_test.exs index 0250139a..ce46c8d5 100644 --- a/test/music_library/wishlist_test.exs +++ b/test/music_library/wishlist_test.exs @@ -42,6 +42,17 @@ defmodule MusicLibrary.WishlistTest do end end + describe "search_records/2 with release_year" do + test "filters by release year" do + record(%{purchased_at: nil, title: "Album 1994", release_date: "1994-09-13"}) + record(%{purchased_at: nil, title: "Album 2020", release_date: "2020"}) + + assert [%{title: "Album 1994"}] = Wishlist.search_records("release_year:1994") + assert [%{title: "Album 2020"}] = Wishlist.search_records("release_year:2020") + assert [] = Wishlist.search_records("release_year:2000") + end + end + describe "count/0" do setup [:fill_wishlist]