Skip to content

Commit

Permalink
Test coverage for model str->datetime conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
mesozoic committed Sep 15, 2024
1 parent 57abe20 commit cc10c08
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 22 deletions.
1 change: 1 addition & 0 deletions pyairtable/models/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ class InterfaceCollaborators(
url="meta/bases/{base.id}/interfaces/{key}",
):
created_time: datetime
first_publish_time: Optional[datetime]
group_collaborators: List["GroupCollaborator"] = _FL()
individual_collaborators: List["IndividualCollaborator"] = _FL()
invite_links: List["InterfaceInviteLink"] = _FL()
Expand Down
11 changes: 9 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import importlib
import json
import re
from collections import OrderedDict
from pathlib import Path
from posixpath import join as urljoin
Expand Down Expand Up @@ -163,11 +165,16 @@ def schema_obj(api, sample_json):
"""

def _get_schema_obj(name: str, *, context: Any = None) -> Any:
from pyairtable.models import schema
if name.startswith("pyairtable."):
# pyairtable.models.Webhook.created_time -> ('pyairtable.models', 'Webhook.created_time')
match = re.match(r"(pyairtable\.[a-z_.]+)\.([A-Z].+)$", name)
modpath, name = match.groups()
else:
modpath = "pyairtable.models.schema"

obj_name, _, obj_path = name.partition(".")
obj_data = sample_json(obj_name)
obj_cls = getattr(schema, obj_name)
obj_cls = getattr(importlib.import_module(modpath), obj_name)

if context:
obj = obj_cls.from_api(obj_data, api, context=context)
Expand Down
39 changes: 39 additions & 0 deletions tests/sample_data/AuditLogResponse.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"events": [
{
"action": "createBase",
"actor": {
"type": "user",
"user": {
"email": "foo@bar.com",
"id": "usrL2PNC5o3H4lBEi",
"name": "Jane Doe"
}
},
"context": {
"actionId": "actxr1mLqZz1T35FA",
"baseId": "appLkNDICXNqxSDhG",
"enterpriseAccountId": "entUBq2RGdihxl3vU",
"interfaceId": "pbdyGA3PsOziEHPDE",
"workspaceId": "wspmhESAta6clCCwF"
},
"id": "01FYFFDE39BDDBC0HWK51R6GPF",
"modelId": "appLkNDICXNqxSDhG",
"modelType": "base",
"origin": {
"ipAddress": "1.2.3.4",
"sessionId": "sesE3ulSADiRNhqAv",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
},
"payload": {
"name": "My newly created base!"
},
"payloadVersion": "1.0",
"timestamp": "2022-02-01T21:25:05.663Z"
}
],
"pagination": {
"next": "MDFHUk5OMlM4MFhTNkY0R0M2QVlZTVZNNDQ=",
"previous": "MDFHUk5ITVhNMEE4UFozTlg1SlFaRlMyOFM="
}
}
18 changes: 18 additions & 0 deletions tests/sample_data/Comment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"author": {
"id": "usrLkNDICXNqxSDhG",
"email": "author@example.com"
},
"createdTime": "2019-01-03T12:33:12.421Z",
"id": "comLkNDICXNqxSDhG",
"lastUpdatedTime": "2019-01-03T12:33:12.421Z",
"text": "Hello, @[usr00000mentioned]!",
"mentioned": {
"usr00000mentioned": {
"displayName": "Alice Doe",
"id": "usr00000mentioned",
"email": "alice@example.com",
"type": "user"
}
}
}
2 changes: 1 addition & 1 deletion tests/sample_data/Webhook.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"success": false,
"willBeRetried": true
},
"lastSuccessfulNotificationTime": null,
"lastSuccessfulNotificationTime": "2022-02-01T21:25:05.663Z",
"notificationUrl": "https://example.com/receive-ping",
"specification": {
"options": {
Expand Down
33 changes: 33 additions & 0 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,36 @@ class Dummy(CanUpdateModel, url="{self.id}", writable=["timestamp"]):
obj.save()
assert m.call_count == 1
assert m.request_history[0].json() == {"timestamp": "2024-01-08T12:34:56.000Z"}


@pytest.mark.parametrize(
"attrpath",
[
"pyairtable.models.webhook.Webhook.last_successful_notification_time",
"pyairtable.models.webhook.Webhook.expiration_time",
"pyairtable.models.comment.Comment.created_time",
"pyairtable.models.comment.Comment.last_updated_time",
"pyairtable.models.webhook.WebhookNotification.timestamp",
"pyairtable.models.webhook.WebhookPayload.timestamp",
"pyairtable.models.audit.AuditLogResponse.events[0].timestamp",
"pyairtable.models.schema.BaseCollaborators.group_collaborators.via_base[0].created_time",
"pyairtable.models.schema.BaseCollaborators.individual_collaborators.via_base[0].created_time",
"pyairtable.models.schema.BaseCollaborators.interfaces['pbdLkNDICXNqxSDhG'].created_time",
"pyairtable.models.schema.BaseCollaborators.interfaces['pbdLkNDICXNqxSDhG'].first_publish_time",
"pyairtable.models.schema.BaseShares.shares[0].created_time",
"pyairtable.models.schema.WorkspaceCollaborators.invite_links.via_base[0].created_time",
"pyairtable.models.schema.EnterpriseInfo.created_time",
"pyairtable.models.schema.WorkspaceCollaborators.created_time",
"pyairtable.models.schema.WorkspaceCollaborators.invite_links.via_base[0].created_time",
"pyairtable.models.schema.UserGroup.created_time",
"pyairtable.models.schema.UserGroup.updated_time",
"pyairtable.models.schema.UserGroup.members[1].created_time",
"pyairtable.models.schema.UserInfo.created_time",
"pyairtable.models.schema.UserInfo.last_activity_time",
],
)
def test_datetime_models(attrpath, schema_obj):
"""
Test that specific models' fields are correctly converted to datetimes.
"""
assert isinstance(schema_obj(attrpath), datetime)
24 changes: 5 additions & 19 deletions tests/test_models_comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,8 @@


@pytest.fixture
def comment_json():
author = fake_user("author")
mentioned = fake_user("mentioned")
return {
"author": author,
"createdTime": NOW,
"id": fake_id("com"),
"lastUpdatedTime": None,
"text": f"Hello, @[{mentioned['id']}]!",
"mentioned": {
mentioned["id"]: {
"displayName": mentioned["name"],
"id": mentioned["id"],
"email": mentioned["email"],
"type": "user",
}
},
}
def comment_json(sample_json):
return sample_json("Comment")


@pytest.fixture
Expand All @@ -42,7 +26,9 @@ def comments_url(base, table):


def test_parse(comment_json):
Comment.parse_obj(comment_json)
c = Comment.parse_obj(comment_json)
assert isinstance(c.created_time, datetime.datetime)
assert isinstance(c.last_updated_time, datetime.datetime)


def test_missing_attributes(comment_json):
Expand Down

0 comments on commit cc10c08

Please sign in to comment.