Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.

Commit 2404b9d

Browse files
Merge branch 'rvinnakota/update-ai-repo' of https://github.com/codecov/codecov-api into rvinnakota/update-ai-repo
2 parents 662df84 + a54ff4f commit 2404b9d

File tree

4 files changed

+35
-4
lines changed

4 files changed

+35
-4
lines changed

graphql_api/helpers/connection.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import enum
2+
from base64 import b64decode
23
from dataclasses import dataclass
34
from functools import cached_property
45
from typing import Any, Dict, List, Optional
56

6-
from cursor_pagination import CursorPage, CursorPaginator
7+
from cursor_pagination import CursorPage, CursorPaginator, InvalidCursor
78
from django.db.models import QuerySet
89

910
from codecov.commands.exceptions import ValidationError
@@ -181,6 +182,7 @@ def page_info(self) -> Dict[str, Any]:
181182

182183

183184
class DictCursorPaginator(CursorPaginator):
185+
NULL_VALUE_REPR = "\x1f"
184186
"""
185187
WARNING: DictCursorPaginator does not work for dict objects where a key contains the following string: "__"
186188
TODO: if instance is a dictionary and not an object, don't split the ordering
@@ -205,6 +207,17 @@ class DictCursorPaginator(CursorPaginator):
205207
if the dict access fails then it throws an exception, although it would be a different
206208
"""
207209

210+
def decode_cursor(self, cursor):
211+
try:
212+
orderings = b64decode(cursor.encode("ascii")).decode("utf8")
213+
orderings = orderings.split(self.delimiter)
214+
return [
215+
None if ordering == self.NULL_VALUE_REPR else ordering
216+
for ordering in orderings
217+
]
218+
except (TypeError, ValueError):
219+
raise InvalidCursor(self.invalid_cursor_message)
220+
208221
def position_from_instance(self, instance):
209222
position = []
210223
for order in self.ordering:
@@ -219,7 +232,7 @@ def position_from_instance(self, instance):
219232
except (KeyError, TypeError):
220233
raise attr_err from None
221234
parts.pop(0)
222-
position.append(str(attr))
235+
position.append(self.NULL_VALUE_REPR if attr is None else str(attr))
223236
return position
224237

225238

graphql_api/helpers/tests/test_connection.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,21 @@ def test_invalid_cursors(self):
155155

156156
with self.assertRaises(ValidationError):
157157
queryset_to_connection_sync(data, first=3, after="invalid")
158+
159+
def test_dict_cursor_paginator_null_encoding(self):
160+
from graphql_api.helpers.connection import DictCursorPaginator, field_order
161+
162+
repo_1 = RepositoryFactory(name="a", active=None)
163+
repo_2 = RepositoryFactory(name="b", active=True)
164+
repo_3 = RepositoryFactory(name="c", active=False)
165+
r = Repository.objects.all()
166+
167+
ordering = tuple(
168+
field_order(field, OrderingDirection.ASC) for field in ("active",)
169+
)
170+
171+
paginator = DictCursorPaginator(r, ordering=ordering)
172+
173+
assert paginator.position_from_instance(repo_1) == ["\x1f"]
174+
assert paginator.position_from_instance(repo_2) == ["True"]
175+
assert paginator.position_from_instance(repo_3) == ["False"]

graphql_api/tests/test_test_analytics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ def test_test_results_pagination_asc(
468468
def test_test_analytics_term_filter(self, repository, store_in_redis, mock_storage):
469469
test_results = generate_test_results(
470470
repoid=repository.repoid,
471-
term=rows[0]["name"],
471+
term=rows[0]["name"][2:],
472472
ordering=TestResultsOrderingParameter.UPDATED_AT,
473473
ordering_direction=OrderingDirection.DESC,
474474
measurement_interval=MeasurementInterval.INTERVAL_30_DAY,

graphql_api/types/test_analytics/test_analytics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ def generate_test_results(
198198
)
199199

200200
if term:
201-
table = table.filter(pl.col("name").str.starts_with(term))
201+
table = table.filter(pl.col("name").str.contains(term))
202202

203203
if testsuites:
204204
table = table.filter(

0 commit comments

Comments
 (0)