diff --git a/app/crud/crud_body.py b/app/crud/crud_body.py index 485b723..0479d89 100644 --- a/app/crud/crud_body.py +++ b/app/crud/crud_body.py @@ -117,14 +117,49 @@ def perform_name_search_filter( # Name: name = getattr(query_params, "name", None) - if name: - query = query.filter( - or_( - self.model.name.op("LIKE")("%{0}%".format(name)), - self.model.iau.op("LIKE")("%{0}%".format(name)), - ) + if not name: + return query + + # If the name starts with "M", then we need to + # filter by the Messier catalogue: + if ( + name.lower().strip().startswith("m") + and len(name) >= 2 + and name[1:].isdigit() + ): + return query.filter( + self.model.messier.op("LIKE")("%{0}%".format(name[1:])), + ) + + # If the name starts with "NGC", then we need to + # filter by the New General catalogue: + if ( + name.lower().strip().startswith("ngc") + and len(name) >= 4 + and name[3:].isdigit() + ): + return query.filter( + self.model.ngc.op("LIKE")("%{0}%".format(name[3:])), + ) + + # If the name starts with "IC", then we need to + # filter by the Index catalogue: + if ( + name.lower().strip().startswith("ic") + and len(name) >= 3 + and name[2:].isdigit() + ): + return query.filter( + self.model.ic.op("LIKE")("%{0}%".format(name[2:])), ) + query = query.filter( + or_( + self.model.name.op("LIKE")("%{0}%".format(name)), + self.model.iau.op("LIKE")("%{0}%".format(name)), + ) + ) + return query def perform_constellation_search_filter( diff --git a/app/tests/api/api_v1/test_bodies.py b/app/tests/api/api_v1/test_bodies.py index 26ecc3f..637c40e 100644 --- a/app/tests/api/api_v1/test_bodies.py +++ b/app/tests/api/api_v1/test_bodies.py @@ -99,6 +99,27 @@ async def test_list_bodies_with_the_partial_name_betel(client: AsyncClient) -> N assert body["results"][0]["iau"] == "Betelgeuse" +@pytest.mark.asyncio +async def test_list_bodies_with_the_name_M45(client: AsyncClient) -> None: + page = 1 + + response = await client.get( + f"{settings.API_V1_STR}/bodies/{page}?name=M45", + headers={"Host": "perseus.docker.localhost"}, + ) + + assert response.status_code == 200 + + body = response.json() + + assert body["count"] == 1 + assert body["next_page"] is None + assert body["previous_page"] is None + + assert body["results"][0]["name"] == "Pleiades" + assert body["results"][0]["iau"] == "Messier 45" + + @pytest.mark.asyncio async def test_list_bodies_with_specific_radial_search(client: AsyncClient) -> None: page = 1