Skip to content

Commit 555f234

Browse files
committed
full test coverage
1 parent 527d579 commit 555f234

27 files changed

+2520
-678
lines changed

TODO.md

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
## TODO
44

5-
- [ ] Finish method naming and typing documentation.
6-
75
- [ ] Complete coverage
86

7+
- [ ] Get rid of deprecation warnings from test coverage
8+
9+
- [ ] Finish method naming and typing documentation.
10+
911
- [ ] Confront MyPy. See https://stackoverflow.com/a/51294709 for json help
1012

1113
- [ ] When typing resource, wrap the actual response type around the JSONType,,
@@ -19,23 +21,12 @@
1921

2022
- [ ] Set up CI!
2123

22-
- [ ] validate Calories From Fat:
23-
`fitbit_client.exceptions.ValidationException: Calories From Fat must be a valid non-negative number. Currently it is "146.79".`
24-
It needs to be a positive int!
25-
26-
- [ ] Should mocks have type annotations?
27-
28-
- [ ] consolidate fixures where possible
29-
3024
- [ ] Consider a "replace_food_log" helper that does a delete + an add in one.
3125
(there might be several of these that make sense--just take an ID and then the
3226
signature of the "create" method)
3327

3428
- Docs! https://www.sphinx-doc.org/en/master/#get-started (put on github pages?)
3529

36-
- [ ] bring back the aliases! in client.py also put the resource initializations
37-
in the mixin
38-
3930
- [ ] Why does this log twice:
4031

4132
```log
@@ -69,35 +60,18 @@
6960
https://dev.fitbit.com/build/reference/web-api/developer-guide/best-practices/
7061
in README--they still apply!
7162

72-
- [ ] Form to chang scopes are part of OAuth flow? Maybe get rid of the cut and
63+
- [ ] Form to change scopes are part of OAuth flow? Maybe get rid of the cut and
7364
paste method altogether? It's less to test...
7465

75-
- [ ] Response validation? Accidentally doing a GET instead of a POST on, e.g.
76-
`food.json` will yield a response, but not the one you want!
77-
7866
- [ ] Make the food download_food_logs (rename to `get_food_logs`) and food log
7967
to CSV part of one helper package. It should expand the foods to have their
80-
complete nutrition (a separate call for each unique food)
81-
82-
- [ ] Accept "yesterday" keyword for dates?
83-
84-
- [ ] `raise NotImplementedError` for
85-
[intraday methods](https://dev.fitbit.com/build/reference/web-api/intraday/)
86-
87-
- Impelement them and comment them out with a note that they are theoretical
88-
unused/untested
89-
- Note that they are in Resource classses AND have their own module
90-
91-
- [ ] Figure out throttling when making multiple requests.
92-
93-
- Can we make this more elegant than just putting in explict `sleep(.3)`
94-
statements as needed?
95-
- Can we handle it and retry a few times before erroring out?
68+
complete nutrition (a separate call for each unique food) (put this in a
69+
`tools` package??)
9670

9771
- [ ] PyPI deployment
9872

99-
- [ ] Extension: ?PRIVATE filters on methods that return PUBLIC and PRIVATE
100-
stuff (API doesn't seem to have this)
73+
- [ ] Extension: PRIVATE filters on methods that return PUBLIC and PRIVATE stuff
74+
(API doesn't seem to have this). Maybe a sidecar database?
10175

10276
- [ ] Enum for units? (it'll be big, maybe just common ones?)
10377

fitbit_client/auth/callback_server.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,13 @@ def start(self) -> None:
180180
error_type="system",
181181
)
182182

183-
except SystemException:
184-
raise
185183
except Exception as e:
186-
error_msg = f"Failed to start callback server: {str(e)}"
187-
self.logger.error(error_msg)
188-
raise SystemException(message=error_msg, status_code=500, error_type="system")
184+
# Only catch non-SystemException exceptions here
185+
if not isinstance(e, SystemException):
186+
error_msg = f"Failed to start callback server: {str(e)}"
187+
self.logger.error(error_msg)
188+
raise SystemException(message=error_msg, status_code=500, error_type="system")
189+
raise
189190

190191
def wait_for_callback(self, timeout: int = 300) -> Optional[str]:
191192
"""Wait for OAuth callback

fitbit_client/auth/oauth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def __init__(
6262
token_cache_path: str,
6363
use_callback_server: bool = True,
6464
) -> None:
65-
self.logger = getLogger("fitbit_client.oauth") # Add this line
65+
self.logger = getLogger("fitbit_client.oauth")
6666
self.client_id = client_id
6767
self.client_secret = client_secret
6868
self.redirect_uri = redirect_uri

fitbit_client/utils/helpers.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ def to_camel_case(snake_str: str, cap_first: bool = False) -> str:
2424
snake_str: a snake_case string
2525
cap_first: if True, returns CamelCase, otherwise camelCase (default is False)
2626
"""
27+
if not snake_str: # handle empty string case
28+
return ""
29+
2730
camel_string = "".join(l.capitalize() for l in snake_str.lower().split("_"))
2831
if cap_first:
2932
return camel_string
@@ -33,13 +36,13 @@ def to_camel_case(snake_str: str, cap_first: bool = False) -> str:
3336

3437
def print_json(obj: JSONType, f: TextIO = stdout):
3538
"""
36-
Prett print JSON-serializable objects.
39+
Pretty print JSON-serializable objects.
3740
3841
Args:
3942
obj: Any JSON serializable object
4043
f: A file-like object to which the object should be serialized. Default: stdout
4144
"""
42-
print(dumps(obj, ensure_ascii=False, indent=2), file=f)
45+
print(dumps(obj, ensure_ascii=False, indent=2), file=f, flush=True)
4346

4447

4548
def date_range(start_date: str, end_date: str) -> Iterator[str]:
@@ -67,5 +70,5 @@ def date_range(start_date: str, end_date: str) -> Iterator[str]:
6770
while start <= end:
6871
yield start.isoformat()
6972
start += timedelta(days=1)
70-
else: # Handles start == end
73+
else: # start == end
7174
yield start.isoformat()

fitbit_client/utils/pagination_validation.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717

1818
def validate_pagination_params(
19-
*,
2019
before_field: str = "before_date",
2120
after_field: str = "after_date",
2221
sort_field: str = "sort",

0 commit comments

Comments
 (0)