import random from sqlalchemy import desc from sqlalchemy.orm import Query from sqlalchemy.schema import Column from core_notifications.helpers.ordering import OrderingLink, QueryOrdering from tests.core_notifications.pytest_helpers import UrlForThisMixin class TestQueryOrdering(UrlForThisMixin): ENDPOINT = "core.health" def test_default_order(self, app, faker): columns = [ Column(faker.pystr()) for _ in range(faker.pyint(min_value=1, max_value=10)) ] order_column = columns[0] with app.test_request_context(self.url_for_this(app)): ordering = QueryOrdering(Query(columns), columns) expected_query = Query(columns).order_by(order_column) expected_links = { c.key: OrderingLink( c.key, self.url_for_this(app, order=c.key), False, True ) for c in columns } expected_links[order_column.key] = OrderingLink( order_column.key, self.url_for_this(app, order=f"-{order_column.key}"), True, False, ) assert ordering.order_string == "" assert str(ordering.query) == str(expected_query) assert ordering.links == expected_links def test_default_order_is_desc(self, app, faker): columns = [ Column(faker.pystr()) for _ in range(faker.pyint(min_value=1, max_value=10)) ] order_column = columns[0] with app.test_request_context(self.url_for_this(app)): ordering = QueryOrdering( Query(columns), columns, default_is_desc=True ) expected_query = Query(columns).order_by(order_column.desc()) expected_links = { c.key: OrderingLink( c.key, self.url_for_this(app, order=c.key), False, True ) for c in columns } expected_links[order_column.key] = OrderingLink( order_column.key, self.url_for_this(app), True, True, ) assert ordering.order_string == "" assert str(ordering.query) == str(expected_query) assert ordering.links == expected_links def test_custom_order(self, app, faker): columns = [ Column(faker.pystr()) for _ in range(faker.pyint(min_value=1, max_value=10)) ] order_column = random.choice(columns) order_string = f"{order_column.key}" with app.test_request_context(self.url_for_this(app)): ordering = QueryOrdering(Query(columns), columns, order_string) expected_query = Query(columns).order_by(order_column) expected_links = { c.key: OrderingLink( c.key, self.url_for_this(app, order=c.key), False, True ) for c in columns } expected_links[order_column.key] = OrderingLink( order_column.key, self.url_for_this(app, order=f"-{order_column.key}"), True, False, ) assert ordering.order_string == order_string assert str(ordering.query) == str(expected_query) assert ordering.links == expected_links def test_custom_order_desc(self, app, faker): columns = [ Column(faker.pystr()) for _ in range(faker.pyint(min_value=1, max_value=10)) ] order_column = random.choice(columns) order_string = f"-{order_column.key}" with app.test_request_context(self.url_for_this(app)): ordering = QueryOrdering(Query(columns), columns, order_string) expected_links = { c.key: OrderingLink( c.key, self.url_for_this(app, order=c.key), False, True ) for c in columns } expected_links[order_column.key] = OrderingLink( order_column.key, self.url_for_this(app), True, True, ) expected_query = Query(columns).order_by(desc(order_column)) assert ordering.order_string == order_string assert str(ordering.query) == str(expected_query) assert ordering.links == expected_links def test_custom_order_mapping(self, app, faker): columns = [ Column(f"{faker.pystr()}_{n}") for n in range(faker.pyint(min_value=1, max_value=10)) ] query_param = faker.pystr() order_column = random.choice(columns) fields_mapping = {query_param: order_column.key} order_string = f"-{query_param}" with app.test_request_context(self.url_for_this(app)): ordering = QueryOrdering( Query(columns), columns, order_string, fields_mapping ) expected_links = { c.key: OrderingLink( c.key, self.url_for_this(app, order=c.key), False, True ) for c in columns if c != order_column } expected_links[query_param] = OrderingLink( query_param, self.url_for_this(app), True, True, ) expected_query = Query(columns).order_by(desc(order_column)) assert ordering.order_string == order_string assert str(ordering.query) == str(expected_query) assert ordering.links == expected_links