Skip to content

Commit 7e0ad35

Browse files
committed
OneDrive & Outlook unit tests improvements
1 parent 1951be0 commit 7e0ad35

File tree

14 files changed

+188
-42
lines changed

14 files changed

+188
-42
lines changed

office365/outlook/mail/messages/message.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from office365.outlook.mail.messages.followup_flag import FollowupFlag
1818
from office365.outlook.mail.messages.internet_header import InternetMessageHeader
1919
from office365.outlook.mail.recipient import Recipient
20+
from office365.runtime.client_object import persist_property
2021
from office365.runtime.client_result import ClientResult
2122
from office365.runtime.client_value_collection import ClientValueCollection
2223
from office365.runtime.paths.resource_path import ResourcePath
@@ -229,10 +230,10 @@ def has_attachments(self):
229230
return self.properties.get("hasAttachments", None)
230231

231232
@property
233+
@persist_property()
232234
def attachments(self):
233235
# type: () -> AttachmentCollection
234236
"""The fileAttachment and itemAttachment attachments for the message."""
235-
self._persist_changes("attachments")
236237
return self.properties.setdefault(
237238
"attachments",
238239
AttachmentCollection(

office365/outlook/mail/messages/rules/rule.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from office365.entity import Entity
44
from office365.outlook.mail.messages.rules.actions import MessageRuleActions
55
from office365.outlook.mail.messages.rules.predicates import MessageRulePredicates
6+
from office365.runtime.client_object import persist_property
67

78

89
class MessageRule(Entity):
@@ -12,6 +13,7 @@ class MessageRule(Entity):
1213
upon certain conditions."""
1314

1415
@property
16+
@persist_property()
1517
def actions(self):
1618
"""Actions to be taken on a message when the corresponding conditions are fulfilled."""
1719
return self.properties.get("actions", MessageRuleActions())

office365/runtime/client_object.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,34 @@
2525
"""Property Type."""
2626

2727

28+
def persist_property(property_name=None):
29+
# type: (Optional[str]) -> Callable[[Callable[..., P_T]], Callable[..., P_T]]
30+
"""Decorator to automatically track property access for persistence"""
31+
32+
def decorator(method):
33+
# type: (Callable[..., P_T]) -> Callable[..., P_T]
34+
def wrapper(self, *args, **kwargs):
35+
# type: (ClientObject, *Any, **Any) -> P_T
36+
name = property_name if property_name is not None else method.__name__
37+
if name not in self._properties_to_persist:
38+
self._properties_to_persist.append(name)
39+
return method(self, *args, **kwargs)
40+
41+
return wrapper
42+
43+
return decorator
44+
45+
2846
class ClientObject(Generic[T]):
2947
def __init__(self, context, resource_path=None, parent_collection=None):
3048
# type: (ClientRuntimeContext, Optional[ResourcePath], Optional[ClientObjectCollection]) -> None
3149
"""Base client object which define named properties and relationships of an entity."""
32-
self._properties = {}
33-
self._properties_to_persist = []
50+
self._properties = {} # type: dict[str, Any]
51+
self._properties_to_persist = [] # type: list[str]
3452
self._query_options = QueryOptions()
3553
self._parent_collection = parent_collection
3654
self._context = context
37-
self._entity_type_name = None
55+
self._entity_type_name = None # type: Optional[str]
3856
self._resource_path = resource_path
3957

4058
def clear_state(self):

tests/decorators.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ def _get_cached_permissions(client, client_id):
1919
return result.value
2020

2121

22-
def requires_app_permission(app_role):
23-
# type: (str) -> Callable[[T], T]
22+
def requires_app_permission(*app_roles):
23+
# type: (*str) -> Callable[[T], T]
2424
def decorator(test_method):
2525
# type: (T) -> T
2626
@wraps(test_method)
@@ -32,8 +32,9 @@ def wrapper(self, *args, **kwargs):
3232

3333
permissions = _get_cached_permissions(client, test_client_id)
3434

35-
if not any(role.value == app_role for role in permissions):
36-
self.skipTest(f"Required app permission '{app_role}' not granted")
35+
if not any(role.value in app_roles for role in permissions):
36+
required_roles = ", ".join(f"'{role}'" for role in app_roles)
37+
self.skipTest(f"Required app permission '{required_roles}' not granted")
3738

3839
return test_method(self, *args, **kwargs)
3940

tests/onedrive/test_column.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from office365.onedrive.columns.definition import ColumnDefinition
22
from tests import create_unique_name
3+
from tests.decorators import requires_delegated_permission
34
from tests.graph_case import GraphTestCase
45

56

@@ -11,24 +12,33 @@ def setUpClass(cls):
1112
super(TestColumn, cls).setUpClass()
1213
cls.doclib = cls.client.sites.root.lists["Documents"]
1314

14-
def test1_get_list_columns(self):
15+
@requires_delegated_permission(
16+
"Sites.Read.All",
17+
"Sites.Manage.All",
18+
"Sites.FullControl.All",
19+
"Sites.ReadWrite.All",
20+
)
21+
def test1_list_list_columns(self):
1522
columns = self.doclib.columns.get().execute_query()
1623
self.assertGreater(len(columns), 0)
1724

18-
def test2_create_text_column(self):
25+
@requires_delegated_permission("Sites.Manage.All", "Sites.FullControl.All")
26+
def test2_create_text_column_for_list(self):
1927
column_name = create_unique_name("TextColumn")
2028
column = self.doclib.columns.add_text(column_name).execute_query()
2129
self.assertIsNotNone(column.resource_path)
2230
self.__class__.list_columns.append(column)
2331

24-
def test3_create_lookup_column(self):
32+
@requires_delegated_permission("Sites.Manage.All", "Sites.FullControl.All")
33+
def test3_create_lookup_column_for_list(self):
2534
column_name = create_unique_name("LookupColumn")
2635
column = self.doclib.columns.add_lookup(
2736
column_name, self.doclib
2837
).execute_query()
2938
self.assertIsNotNone(column.resource_path)
3039
self.__class__.list_columns.append(column)
3140

41+
@requires_delegated_permission("Sites.Manage.All", "Sites.FullControl.All")
3242
def test3_delete_list_columns(self):
3343
for col_to_del in self.__class__.list_columns:
3444
col_to_del.delete_object().execute_query()

tests/onedrive/test_content_type.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from office365.graph_client import GraphClient
55
from office365.onedrive.contenttypes.content_type import ContentType
66
from tests import test_client_id, test_password, test_tenant, test_username
7+
from tests.decorators import requires_delegated_permission
78

89

910
class TestContentType(TestCase):
@@ -26,6 +27,7 @@ def test1_get_compatible_hub_content_types(self):
2627
)
2728
self.assertIsNotNone(cts.resource_path)
2829

30+
@requires_delegated_permission("Sites.Manage.All", "Sites.FullControl.All")
2931
def test2_create_site_content_type(self):
3032
name = "docSet" + uuid.uuid4().hex
3133
ct = self.client.sites.root.content_types.add(
@@ -34,19 +36,33 @@ def test2_create_site_content_type(self):
3436
self.assertIsNotNone(ct.resource_path)
3537
self.__class__.target_ct = ct
3638

37-
# def test3_publish_and_verify_if_published(self):
38-
# result = self.__class__.target_ct.publish().is_published().execute_query()
39-
# self.assertTrue(result.value)
39+
@requires_delegated_permission("Sites.FullControl.All")
40+
def test3_publish(self):
41+
result = self.__class__.target_ct.publish().execute_query()
42+
self.assertFalse(result.resource_path)
4043

41-
# def test4_unpublish(self):
42-
# result = self.__class__.target_ct.unpublish().is_published().execute_query()
43-
# self.assertFalse(result.value)
44+
@requires_delegated_permission("Sites.FullControl.All")
45+
def test4_is_published(self):
46+
result = self.__class__.target_ct.is_published().execute_query()
47+
self.assertTrue(result.value)
4448

45-
def test5_delete(self):
49+
@requires_delegated_permission("Sites.FullControl.All")
50+
def test5_unpublish(self):
51+
result = self.__class__.target_ct.unpublish().is_published().execute_query()
52+
self.assertFalse(result.value)
53+
54+
@requires_delegated_permission("Sites.Manage.All", "Sites.FullControl.All")
55+
def test6_delete_site_content_type(self):
4656
ct_to_del = self.__class__.target_ct
4757
ct_to_del.delete_object().execute_query()
4858

49-
def test6_get_applicable_content_types_for_list(self):
59+
@requires_delegated_permission(
60+
"Sites.Read.All",
61+
"Sites.FullControl.All",
62+
"Sites.Manage.All",
63+
"Sites.ReadWrite.All",
64+
)
65+
def test7_get_applicable_content_types_for_list(self):
5066
site = self.client.sites.root
5167
doc_lib = site.lists["Documents"].get().execute_query()
5268
cts = site.get_applicable_content_types_for_list(doc_lib.id).execute_query()

tests/onedrive/test_drive.py

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,59 @@
1+
from tests.decorators import requires_delegated_permission
12
from tests.graph_case import GraphTestCase
23

34

45
class TestDrive(GraphTestCase):
56
"""OneDrive specific test case base class"""
67

7-
def test1_get_drives(self):
8+
@requires_delegated_permission(
9+
"Files.Read",
10+
"Files.Read.All",
11+
"Files.ReadWrite",
12+
"Files.ReadWrite.All",
13+
"Sites.Read.All",
14+
"Sites.ReadWrite.All",
15+
)
16+
def test1_list_drives(self):
817
drives = self.client.drives.top(2).get().execute_query()
918
self.assertLessEqual(len(drives), 2)
1019
for drive in drives:
1120
self.assertIsNotNone(drive.web_url)
1221

13-
def test2_get_drives_alt(self):
22+
@requires_delegated_permission(
23+
"Files.Read",
24+
"Files.Read.All",
25+
"Files.ReadWrite",
26+
"Files.ReadWrite.All",
27+
"Sites.Read.All",
28+
"Sites.ReadWrite.All",
29+
)
30+
def test2_list_drives_alt(self):
1431
resp = self.client.execute_request_direct("drives?$top=2")
1532
drives = resp.json()["value"]
1633
self.assertLessEqual(len(drives), 2)
1734
for drive in drives:
1835
self.assertIsNotNone(drive["webUrl"])
1936

20-
def test3_get_first_drive(self):
21-
drives = self.client.drives.get().top(10).execute_query()
22-
self.assertGreaterEqual(len(drives), 1)
23-
target_drive_id = drives[0].id
24-
25-
target_drive = self.client.drives[target_drive_id].get().execute_query()
26-
self.assertEqual(target_drive.id, target_drive_id)
27-
28-
def test4_get_site(self):
29-
site = self.client.sites.root.get().execute_query()
30-
self.assertIsNotNone(site.resource_path)
37+
@requires_delegated_permission(
38+
"Files.Read",
39+
"Files.Read.All",
40+
"Files.ReadWrite",
41+
"Files.ReadWrite.All",
42+
"Sites.Read.All",
43+
"Sites.ReadWrite.All",
44+
)
45+
def test4_get_drive_root(self):
46+
result = self.client.me.drive.root.get().execute_query()
47+
self.assertIsNotNone(result.resource_path)
3148

49+
@requires_delegated_permission(
50+
"Files.Read",
51+
"Files.Read.All",
52+
"Files.ReadWrite",
53+
"Files.ReadWrite.All",
54+
"Sites.Read.All",
55+
"Sites.ReadWrite.All",
56+
)
3257
def test5_get_recent(self):
3358
items = self.client.me.drive.recent().execute_query()
3459
self.assertIsNotNone(items.resource_path)

tests/onedrive/test_sitepage.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from office365.onedrive.sitepages.site_page import SitePage
22
from tests import create_unique_name, test_team_site_url
3+
from tests.decorators import requires_delegated_permission
34
from tests.graph_case import GraphTestCase
45

56

@@ -43,6 +44,7 @@ def test4_get_site_page_pub_state(self):
4344
# result = page.publish().execute_query()
4445
# self.assertIsNotNone(result.resource_path)
4546

47+
@requires_delegated_permission("Sites.Read.All", "Sites.ReadWrite.All")
4648
def test6_list_site_pages(self):
4749
result = self.test_site.pages.top(10).get().execute_query()
4850
self.assertIsNotNone(result.resource_path)

tests/onedrive/test_term_store.py renamed to tests/onedrive/test_taxonomy.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ def setUpClass(cls):
2727
def tearDownClass(cls):
2828
pass
2929

30-
def test1_get_groups(self):
31-
groups = self.target_store.groups.top(1).get().execute_query()
32-
self.assertLessEqual(len(groups), 1)
33-
for group in groups:
30+
def test1_list_groups(self):
31+
result = self.target_store.groups.top(1).get().execute_query()
32+
self.assertLessEqual(len(result), 1)
33+
for group in result:
3434
self.assertIsNotNone(group.resource_path)
3535

3636
def test2_create_group(self):

tests/outlook/test_message_rules.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,47 @@
11
from office365.outlook.mail.messages.rules.actions import MessageRuleActions
22
from office365.outlook.mail.messages.rules.rule import MessageRule
33
from office365.outlook.mail.recipient import Recipient
4+
from tests.decorators import requires_delegated_permission
45
from tests.graph_case import GraphTestCase
56

67

78
class TestMessageRules(GraphTestCase):
89
target_message_rule = None # type: MessageRule
910

11+
@requires_delegated_permission("MailboxSettings.ReadWrite")
1012
def test1_create_rule(self):
1113
actions = MessageRuleActions(
1214
forward_to=[Recipient.from_email("[email protected]")],
1315
stop_processing_rules=True,
16+
mark_importance="normal",
1417
)
15-
message_rules = (
18+
result = (
1619
self.client.me.mail_folders["inbox"]
1720
.message_rules.add("From partner", 2, actions)
1821
.execute_query()
1922
)
20-
self.assertIsNotNone(message_rules.resource_path)
23+
self.assertIsNotNone(result.resource_path)
24+
self.__class__.target_message_rule = result
2125

26+
@requires_delegated_permission("MailboxSettings.Read", "MailboxSettings.ReadWrite")
2227
def test2_list_rules(self):
2328
message_rules = (
2429
self.client.me.mail_folders["inbox"].message_rules.get().execute_query()
2530
)
2631
self.assertIsNotNone(message_rules.resource_path)
32+
33+
@requires_delegated_permission("MailboxSettings.ReadWrite")
34+
def test3_update_rule(self):
35+
rule = self.__class__.target_message_rule
36+
rule.actions.markImportance = "high"
37+
rule.update().execute_query()
38+
39+
@requires_delegated_permission("MailboxSettings.Read", "MailboxSettings.ReadWrite")
40+
def test4_get_rule(self):
41+
result = self.__class__.target_message_rule.get().execute_query()
42+
self.assertEqual(result.actions.markImportance, "high")
43+
44+
@requires_delegated_permission("MailboxSettings.ReadWrite")
45+
def test5_delete_rule(self):
46+
rule =self.__class__.target_message_rule
47+
rule.delete_object().execute_query()

0 commit comments

Comments
 (0)