Skip to content

Commit 7ec536e

Browse files
authored
#94: Remove permissions field from response schemas (#95)
* Change zoneinfo importing to fix type hints * Remove field email from PUT me integration test to avoid flaky test * Fix flaky project update test by removing check for old and new values inequality * Fix invalid timeframe format in Project's integration tests
1 parent 3d7ac49 commit 7ec536e

14 files changed

+36
-39
lines changed

tests/factories/base.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import sys
34
from typing import TYPE_CHECKING, Dict, List, Union
45

56
from tests.conftest import fake
@@ -10,10 +11,11 @@
1011
from pydantic_core import TzInfo
1112

1213

13-
try:
14-
import zoneinfo
15-
except ImportError:
14+
if sys.version_info < (3, 9):
1615
from backports import zoneinfo
16+
else:
17+
import zoneinfo
18+
1719

1820

1921
def datetime_repr_factory(timezone: Union[ZoneInfo, TzInfo, None] = None) -> str:

tests/factories/project.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
11
from __future__ import annotations
22

3+
import sys
34
from typing import Dict, Optional, Union
45

56
from tests.conftest import fake
67
from tests.factories.base import datetime_repr_factory
78

89

9-
try:
10-
import zoneinfo
11-
except ImportError:
10+
if sys.version_info < (3, 9):
1211
from backports import zoneinfo
12+
else:
13+
import zoneinfo
1314

1415

15-
def project_request_factory() -> Dict[str, Union[str, bool, int, None]]:
16-
start_date = fake.past_date()
16+
def project_request_factory() -> Dict[str, Union[str, bool, int]]:
17+
start_date = fake.future_date()
1718

1819
request_body = {
1920
"active": fake.boolean(),
2021
"auto_estimates": fake.boolean(),
2122
"currency": fake.currency_code(),
22-
"end_date": fake.date_between(start_date=start_date).isoformat(),
23+
"end_date": fake.date_between(start_date=start_date, end_date="+90d").isoformat(),
2324
"estimated_hours": fake.random_int(),
2425
"is_private": fake.boolean(),
2526
"is_shared": fake.boolean(),
26-
"name": fake.uuid4(),
27+
"name": str(fake.uuid4()),
2728
"start_date": start_date.isoformat(),
2829
"template": fake.boolean(),
2930
}
@@ -63,7 +64,6 @@ def project_response_factory(
6364
"is_private": fake.boolean(),
6465
"is_shared": fake.boolean(),
6566
"name": fake.word(),
66-
"permissions": None,
6767
"rate": fake.random_int() if fake.boolean() else None,
6868
"rate_last_updated": datetime_repr_factory(timezone) if fake.boolean() else None,
6969
"recurring": fake.boolean(),

tests/factories/time_entry.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import sys
34
from datetime import datetime, timedelta
45
from typing import TYPE_CHECKING, Dict, List, Optional, Union
56

@@ -12,10 +13,10 @@
1213
from pydantic_core import TzInfo
1314

1415

15-
try:
16-
import zoneinfo
17-
except ImportError:
16+
if sys.version_info < (3, 9):
1817
from backports import zoneinfo
18+
else:
19+
import zoneinfo
1920

2021

2122
def _stop_datetime_repr_factory(
@@ -88,7 +89,6 @@ def time_entry_response_factory(
8889
"duration": duration or fake.random_int(),
8990
"duronly": fake.boolean(),
9091
"id": fake.random_number(digits=11, fix_len=True),
91-
"permissions": None,
9292
"project_id": project_id or fake.random_int(),
9393
"server_deleted_at": (
9494
fake.date_time_this_month(tzinfo=tz).isoformat(timespec="seconds")

tests/factories/workspace.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
from __future__ import annotations
22

3+
import sys
34
from typing import Dict, List, Optional, Set, Union
45

56
from tests.conftest import fake
67
from tests.factories.base import datetime_repr_factory
78

89

9-
try:
10-
import zoneinfo
11-
except ImportError:
10+
if sys.version_info < (3, 9):
1211
from backports import zoneinfo
12+
else:
13+
import zoneinfo
1314

1415

1516
def workspace_request_factory(
@@ -55,7 +56,6 @@ def workspace_response_factory(
5556
"only_admins_see_billable_rates": fake.boolean(),
5657
"only_admins_see_team_dashboard": fake.boolean(),
5758
"organization_id": 8364520,
58-
"permissions": None,
5959
"premium": fake.boolean(),
6060
"projects_billable_by_default": fake.boolean(),
6161
"projects_enforce_billable": fake.boolean(),

tests/integration/test_project.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def test_create_project__without_query_params(i_authed_workspace: Workspace) ->
2727
optional_fields = {"end_date", "status"}
2828
expected_result = set(ProjectResponse.model_fields.keys()) - optional_fields
2929

30-
result = i_authed_workspace.create_project(workspace_id, name=fake.uuid4())
30+
result = i_authed_workspace.create_project(workspace_id, name=str(fake.uuid4()))
3131

3232
assert result.model_fields_set == expected_result
3333

@@ -52,7 +52,7 @@ def test_create_project__all_params(i_authed_workspace: Workspace) -> None:
5252

5353
def test_get_projects__without_query_params(i_authed_workspace: Workspace) -> None:
5454
workspace_id = int(os.environ["WORKSPACE_ID"])
55-
project = i_authed_workspace.create_project(workspace_id, name=fake.uuid4())
55+
project = i_authed_workspace.create_project(workspace_id, name=str(fake.uuid4()))
5656
# Field `status` is set to `archived` after first fetch request, `end_date` is still absent
5757
optional_fields = {"end_date"}
5858
expected_result = set(ProjectResponse.model_fields.keys()) - optional_fields
@@ -411,18 +411,16 @@ def test_me_get_paginated_projects__per_page(
411411

412412
def test_update_project(i_authed_workspace: Workspace) -> None:
413413
workspace_id = int(os.environ["WORKSPACE_ID"])
414-
project = i_authed_workspace.create_project(workspace_id, name=fake.uuid4())
414+
project = i_authed_workspace.create_project(workspace_id, name=str(fake.uuid4()))
415415
full_request_body = project_request_factory()
416416
random_param = fake.random_element(full_request_body.keys())
417417
request_body = {random_param: full_request_body[random_param]}
418-
old_param_value = getattr(project, random_param)
419418
optional_fields = {"end_date"}
420419
expected_result = set(ProjectResponse.model_fields.keys()) - optional_fields
421420

422421
result = i_authed_workspace.update_project(workspace_id, project.id, **request_body)
423422

424423
assert result.model_fields_set == expected_result
425-
assert getattr(result, random_param) != old_param_value
426424

427425
_ = i_authed_workspace.delete_project(workspace_id, project.id)
428426

tests/integration/test_report_time_entry.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import os
4+
import sys
45
from datetime import timedelta
56
from typing import TYPE_CHECKING
67

@@ -20,10 +21,11 @@
2021
from toggl_python.entities.workspace import Workspace
2122

2223

23-
try:
24-
import zoneinfo
25-
except ImportError:
24+
if sys.version_info < (3, 9):
2625
from backports import zoneinfo
26+
else:
27+
import zoneinfo
28+
2729

2830

2931
@pytest.mark.parametrize(

tests/integration/test_time_entry.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import os
4+
import sys
45
from datetime import timedelta
56
from typing import TYPE_CHECKING
67

@@ -16,10 +17,11 @@
1617
from tests.integration import pytestmark # noqa: F401 - imported but unused
1718

1819

19-
try:
20-
import zoneinfo
21-
except ImportError:
20+
if sys.version_info < (3, 9):
2221
from backports import zoneinfo
22+
else:
23+
import zoneinfo
24+
2325

2426

2527
if TYPE_CHECKING:
@@ -52,7 +54,7 @@ def test_create_time_entry__all_fields(i_authed_workspace: Workspace) -> None:
5254
workspace_id = int(os.environ["WORKSPACE_ID"])
5355
request_body = time_entry_extended_request_factory(workspace_id)
5456
expected_result = set(MeTimeEntryResponse.model_fields.keys())
55-
project = i_authed_workspace.create_project(workspace_id, name=fake.uuid4())
57+
project = i_authed_workspace.create_project(workspace_id, name=str(fake.uuid4()))
5658

5759
result = i_authed_workspace.create_time_entry(
5860
workspace_id,

tests/integration/test_user.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,12 @@ def test_me__with_related_data(i_authed_user: CurrentUser) -> None:
6666
argvalues=[
6767
("beginning_of_week", fake.random_int(min=0, max=6)),
6868
("country_id", fake.random_int(min=100, max=200)),
69-
("email", fake.email()),
7069
("fullname", fake.name()),
7170
("timezone", fake.timezone()),
7271
],
7372
ids=(
7473
"beginning_of_week",
7574
"country_id",
76-
"email",
7775
"fullname",
7876
"timezone",
7977
),
@@ -85,6 +83,7 @@ def test_update_me__ok(
8583
field_value: Union[str, int],
8684
) -> None:
8785
# default_workspace_id is not tested because it requires method to create and delete workspace
86+
# `email` is skipped because changing it leads to flaky tests
8887
update_body = {field_name: field_value}
8988
current_state_body = {field_name: getattr(me_response, field_name)}
9089

tests/responses/project_get.py

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"is_private": True,
2424
"is_shared": False,
2525
"name": "test project",
26-
"permissions": None,
2726
"rate": None,
2827
"rate_last_updated": None,
2928
"recurring": False,

tests/responses/time_entry_get.py

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
"duration": 22,
3030
"duronly": True,
3131
"id": 3544298808,
32-
"permissions": None,
3332
"project_id": None,
3433
"server_deleted_at": None,
3534
"start": "2024-07-29T12:28:33+00:00",

tests/responses/workspace_get.py

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"only_admins_see_billable_rates": False,
2424
"only_admins_see_team_dashboard": False,
2525
"organization_id": 8364520,
26-
"permissions": None,
2726
"premium": False,
2827
"profile": 0,
2928
"projects_billable_by_default": True,

toggl_python/schemas/project.py

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ class ProjectResponse(BaseSchema):
3030
is_private: bool
3131
is_shared: bool
3232
name: str
33-
permissions: Optional[str]
3433
rate: Optional[int]
3534
rate_last_updated: Optional[datetime]
3635
recurring: bool

toggl_python/schemas/time_entry.py

-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ class MeTimeEntryResponse(MeTimeEntryResponseBase):
4545
duration: int
4646
duronly: bool
4747
id: int
48-
permissions: Optional[List]
4948
server_deleted_at: Optional[datetime]
5049
start: datetime
5150
stop: Optional[datetime]

toggl_python/schemas/workspace.py

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class WorkspaceResponseBase(BaseSchema):
2727
only_admins_see_billable_rates: bool
2828
only_admins_see_team_dashboard: bool
2929
organization_id: int
30-
permissions: Optional[List[str]]
3130
premium: bool
3231
projects_billable_by_default: bool
3332
projects_enforce_billable: bool

0 commit comments

Comments
 (0)