From 2f46e9f08aa63bc0b82bf3321081d2ea4046aceb Mon Sep 17 00:00:00 2001 From: Toben Archer Date: Tue, 6 Nov 2018 09:23:52 -0600 Subject: [PATCH 1/7] This should get tests working. I believe the reason why my tests were failing previously is because if no tests are run, pytest returns a none zero result. So then Travis CI see it as a failure. Now that I've got some basic tests in place, that problem should be solved. --- tests/test_account.py | 16 ++++++++++++++++ tests/test_mailbox.py | 25 +++++++++++++++++++++++-- tests/test_message.py | 2 +- 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 tests/test_account.py diff --git a/tests/test_account.py b/tests/test_account.py new file mode 100644 index 000000000000..a91f8614a5b0 --- /dev/null +++ b/tests/test_account.py @@ -0,0 +1,16 @@ +from O365 import Account +from O365 import Message + + +class TestAccount: + + def setup_class(self): + credentials = ("client id","client secret") + self.account = Account(credentials) + + def teardown_class(self): + pass + + def test_get_message(self): + message = self.account.new_message() + assert isinstance(message,Message) diff --git a/tests/test_mailbox.py b/tests/test_mailbox.py index 864e0abfd62f..a72b09679e97 100644 --- a/tests/test_mailbox.py +++ b/tests/test_mailbox.py @@ -1,10 +1,31 @@ -#from O365 import Account +from O365 import Account +import json +class MockConnection: + + ret_value = None + + def get(self, url, params=None, **kwargs): + self.url = url + self.kwargs = kwargs class TestMailBox: def setup_class(self): - pass + credentials = ("client id","client secret") + self.account = Account(credentials) + self.mailbox = self.account.mailbox() + self.mailbox.con = MockConnection() def teardown_class(self): pass + + def test_mailbox(self): + assert self.mailbox.root + +# def test_get_mailbox_folders(self): +# self.mailbox.con.ret_value = ['Inbox','Drafts'] +# +# folders = self.mailbox.get_folders(limit=5) +# +# assert len(folders) > 0 diff --git a/tests/test_message.py b/tests/test_message.py index ca41e56899c3..ea35c4fa96d3 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -1,5 +1,5 @@ from pathlib import Path -#from O365 import Account +from O365 import Account class TestMessage: From 592ae419050875925f5780ca2e010e036c77a9b1 Mon Sep 17 00:00:00 2001 From: Toben Archer Date: Tue, 6 Nov 2018 09:43:30 -0600 Subject: [PATCH 2/7] Maybe I just need to install the library... --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 90cfbae89d0e..baedf81f4718 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,9 @@ python: - "3.5" - "3.6" -install: pip install -r requirements-dev.txt +install: + pip install -r requirements-dev.txt + python setup.py install script: pytest From 07da9a0d026c1b519bf497b84b996f64a2f20afe Mon Sep 17 00:00:00 2001 From: Toben Archer Date: Tue, 6 Nov 2018 09:46:17 -0600 Subject: [PATCH 3/7] Gotta seperate the steps. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index baedf81f4718..2f2e1d3c8566 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,8 @@ python: - "3.6" install: - pip install -r requirements-dev.txt - python setup.py install + - pip install -r requirements-dev.txt + - python setup.py install script: pytest From 97e0a8e5e744f3029767fed23988e4fcf6522a60 Mon Sep 17 00:00:00 2001 From: Toben Archer Date: Fri, 9 Nov 2018 16:58:45 -0600 Subject: [PATCH 4/7] Started working on coverage of the connection file. Slow going. --- tests/test_connection.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/test_connection.py diff --git a/tests/test_connection.py b/tests/test_connection.py new file mode 100644 index 000000000000..70a6390ca235 --- /dev/null +++ b/tests/test_connection.py @@ -0,0 +1,34 @@ +from O365.connection import Connection, Protocol, MSGraphProtocol, MSOffice365Protocol +import pytest +import json + +class TestProtocol: + + def setup_class(self): + self.proto = Protocol(protocol_url="testing", api_version="0.0") + + def teardown_class(self): + pass + + def test_blank_protocol(self): + with pytest.raises(ValueError): + p = Protocol() + + def test_to_api_case(self): + assert(self.proto.to_api_case("CaseTest") == "case_test") + + def test_get_iana_tz(self): + assert(self.proto.get_iana_tz('Greenwich Standard Time') == 'Atlantic/St_Helena') + +class TestConnection: + + def setup_class(self): + pass + + def teardown_class(self): + pass + + def test_blank_connection(self): + with pytest.raises(TypeError): + c1 = Connection() + From 3dd984fb62f01b9467d691f670ee3725e02bc626 Mon Sep 17 00:00:00 2001 From: Toben Archer Date: Thu, 15 Nov 2018 10:42:12 -0600 Subject: [PATCH 5/7] Protocols covered. I've also added to the release script to include a convenience method for running tests. It includes levels of verbosity and the option to produce annotated code files to let you know where the coverage is lacking. I've decided to make seperate test files for each class and depending on the circumstances it's decendants. Some classes will have have decendants bigger than themselves so those decendants will go into their own test. But protocol's decendants were pretty small so I just included them in protocol's tests. What ever makes sense is basically what I'm going for. --- release.py | 24 ++++++++++ tests/test_connection.py | 18 +------- tests/test_protocol.py | 99 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 17 deletions(-) create mode 100644 tests/test_protocol.py diff --git a/release.py b/release.py index 85e3b28e056b..1fafc138d711 100644 --- a/release.py +++ b/release.py @@ -76,6 +76,30 @@ def check(): subprocess.check_call(['twine', 'check', 'dist/*']) +@cli.command() +@click.option('--annotate/--no-annotate',default=False) +@click.option('--coverage/--no-coverage',default=False) +@click.option('-v/-nv',default=False) +@click.option('-vv/-nvv',default=False) +def test(annotate,coverage,v,vv): + """ runs tests and optionally creates annotated files of coverage. """ + args = ["python3","-m","pytest","tests/"] + if coverage: + args.append("--cov=O365") + if annotate: + args.append("--cov-report") + args.append("annotate") + if v:#Verbose + args.append("-v") + if vv and not v:#Very verbose + args.append("-vv") + + env = os.environ.copy() + + p = subprocess.Popen(args,env=env) + + p.wait() + if __name__ == "__main__": cli() diff --git a/tests/test_connection.py b/tests/test_connection.py index 70a6390ca235..5a9214578da2 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -1,24 +1,8 @@ -from O365.connection import Connection, Protocol, MSGraphProtocol, MSOffice365Protocol import pytest import json -class TestProtocol: +from O365.connection import Connection, Protocol, MSGraphProtocol, MSOffice365Protocol, DEFAULT_SCOPES - def setup_class(self): - self.proto = Protocol(protocol_url="testing", api_version="0.0") - - def teardown_class(self): - pass - - def test_blank_protocol(self): - with pytest.raises(ValueError): - p = Protocol() - - def test_to_api_case(self): - assert(self.proto.to_api_case("CaseTest") == "case_test") - - def test_get_iana_tz(self): - assert(self.proto.get_iana_tz('Greenwich Standard Time') == 'Atlantic/St_Helena') class TestConnection: diff --git a/tests/test_protocol.py b/tests/test_protocol.py new file mode 100644 index 000000000000..c0e944bc263f --- /dev/null +++ b/tests/test_protocol.py @@ -0,0 +1,99 @@ +import pytest +import json + +from pytz import UnknownTimeZoneError +from tzlocal import get_localzone + +from O365.connection import Connection, Protocol, MSGraphProtocol, MSOffice365Protocol, DEFAULT_SCOPES +from O365.utils import ME_RESOURCE, IANA_TO_WIN, WIN_TO_IANA + +TEST_SCOPES = ['Contacts.Read.Shared', 'Mail.Send.Shared', 'User.Read', 'Contacts.ReadWrite.Shared', 'Mail.ReadWrite.Shared', 'Mail.Read.Shared', 'Contacts.Read', 'Sites.ReadWrite.All', 'Mail.Send', 'Mail.ReadWrite', 'offline_access', 'Mail.Read', 'Contacts.ReadWrite', 'Files.ReadWrite.All', 'Calendars.ReadWrite', 'User.ReadBasic.All'] + +class TestProtocol: + + def setup_class(self): + self.proto = Protocol(protocol_url="testing", api_version="0.0") + + def teardown_class(self): + pass + + def test_blank_protocol(self): + with pytest.raises(ValueError): + p = Protocol() + + def test_to_api_case(self): + assert(self.proto.to_api_case("CaseTest") == "case_test") + + def test_get_iana_tz(self): + assert(self.proto.get_iana_tz('Greenwich Standard Time') == 'Atlantic/St_Helena') + + def test_get_iana_tz_standard_time(self): + assert(self.proto.get_iana_tz('Greenwich') == 'Atlantic/St_Helena') + + def test_get_iana_tz_not_found(self): + with pytest.raises(UnknownTimeZoneError): + self.proto.get_iana_tz('No existo') + + def test_get_scopes_for(self): + + + with pytest.raises(ValueError): + self.proto.get_scopes_for(123) # should error sicne it's not a list or tuple. + + assert(self.proto.get_scopes_for(['mailbox']) == ['mailbox']) + + assert(self.proto.get_scopes_for(None) == []) + + assert(self.proto.get_scopes_for('mailbox') == ['mailbox']) + + self.proto._oauth_scopes = DEFAULT_SCOPES + + assert(self.proto.get_scopes_for(['mailbox']) == ['Mail.Read']) + + # This test verifies that the scopes in the default list don't change + #without us noticing. It makes sure that all the scopes we get back are + #in the current set of scopes we expect. And all the scopes that we are + #expecting are in the scopes we are getting back. The list contains the + #same stuff but may not be in the same order and are therefore not equal + scopes = self.proto.get_scopes_for(None) + for scope in scopes: + assert(scope in TEST_SCOPES) + for scope in TEST_SCOPES: + assert(scope in scopes) + + assert(self.proto.get_scopes_for('mailbox') == ['Mail.Read']) + + def test_prefix_scope(self): + assert(self.proto._prefix_scope('Mail.Read') == 'Mail.Read') + + assert(self.proto._prefix_scope(('Mail.Read',)) == 'Mail.Read') + + self.proto.protocol_scope_prefix = 'test_prefix_' + + assert(self.proto._prefix_scope(('Mail.Read',)) == 'Mail.Read') + + assert(self.proto._prefix_scope('test_prefix_Mail.Read') == 'test_prefix_Mail.Read') + + assert(self.proto._prefix_scope('Mail.Read') == 'test_prefix_Mail.Read') + + def test_get_windows_tz(self): + assert(self.proto.get_windows_tz() == IANA_TO_WIN.get(get_localzone().zone)) + + self.proto.timezone = 'UTC' + + assert(self.proto.get_windows_tz() == 'UTC') + + fake = get_localzone() + fake.zone = 'No existo' + with pytest.raises(UnknownTimeZoneError): + self.proto.get_windows_tz(fake) + + def test_decendant_MSOffice365Protocol(self): + # Basically we just test that it can create the class w/o erroring. + msp = MSOffice365Protocol() + + # Make sure these don't change without going noticed. + assert(msp.keyword_data_store['message_type'] == 'Microsoft.OutlookServices.Message') + assert(msp.keyword_data_store['file_attachment_type'] == '#Microsoft.OutlookServices.FileAttachment') + assert(msp.keyword_data_store['item_attachment_type'] == '#Microsoft.OutlookServices.ItemAttachment') + assert(msp.max_top_value == 999) From b447be6db859ed1517c1c0e44fcd49e4375d0bcc Mon Sep 17 00:00:00 2001 From: Toben Archer Date: Thu, 15 Nov 2018 10:55:04 -0600 Subject: [PATCH 6/7] Adjusted to remove abiguity. I changed the time zone that is used in the testing to remove abiguity on what the result is. The timezone now used has a 1 to 1 relationship between windows and Iana. --- tests/test_protocol.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_protocol.py b/tests/test_protocol.py index c0e944bc263f..b9e49183c715 100644 --- a/tests/test_protocol.py +++ b/tests/test_protocol.py @@ -25,10 +25,10 @@ def test_to_api_case(self): assert(self.proto.to_api_case("CaseTest") == "case_test") def test_get_iana_tz(self): - assert(self.proto.get_iana_tz('Greenwich Standard Time') == 'Atlantic/St_Helena') + assert(self.proto.get_iana_tz('Sudan Standard Time') == 'Africa/Khartoum') def test_get_iana_tz_standard_time(self): - assert(self.proto.get_iana_tz('Greenwich') == 'Atlantic/St_Helena') + assert(self.proto.get_iana_tz('Sudan') == 'Africa/Khartoum') def test_get_iana_tz_not_found(self): with pytest.raises(UnknownTimeZoneError): From 1740c3142834cba2e767ad8fc020e93eb8ce08cd Mon Sep 17 00:00:00 2001 From: Toben Archer Date: Thu, 15 Nov 2018 13:11:48 -0600 Subject: [PATCH 7/7] Removed Timezone tests. Timezones have been moved out of the protocol class. --- tests/test_protocol.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/tests/test_protocol.py b/tests/test_protocol.py index b9e49183c715..5c1a66869f24 100644 --- a/tests/test_protocol.py +++ b/tests/test_protocol.py @@ -5,7 +5,6 @@ from tzlocal import get_localzone from O365.connection import Connection, Protocol, MSGraphProtocol, MSOffice365Protocol, DEFAULT_SCOPES -from O365.utils import ME_RESOURCE, IANA_TO_WIN, WIN_TO_IANA TEST_SCOPES = ['Contacts.Read.Shared', 'Mail.Send.Shared', 'User.Read', 'Contacts.ReadWrite.Shared', 'Mail.ReadWrite.Shared', 'Mail.Read.Shared', 'Contacts.Read', 'Sites.ReadWrite.All', 'Mail.Send', 'Mail.ReadWrite', 'offline_access', 'Mail.Read', 'Contacts.ReadWrite', 'Files.ReadWrite.All', 'Calendars.ReadWrite', 'User.ReadBasic.All'] @@ -23,20 +22,8 @@ def test_blank_protocol(self): def test_to_api_case(self): assert(self.proto.to_api_case("CaseTest") == "case_test") - - def test_get_iana_tz(self): - assert(self.proto.get_iana_tz('Sudan Standard Time') == 'Africa/Khartoum') - - def test_get_iana_tz_standard_time(self): - assert(self.proto.get_iana_tz('Sudan') == 'Africa/Khartoum') - - def test_get_iana_tz_not_found(self): - with pytest.raises(UnknownTimeZoneError): - self.proto.get_iana_tz('No existo') def test_get_scopes_for(self): - - with pytest.raises(ValueError): self.proto.get_scopes_for(123) # should error sicne it's not a list or tuple. @@ -76,18 +63,6 @@ def test_prefix_scope(self): assert(self.proto._prefix_scope('Mail.Read') == 'test_prefix_Mail.Read') - def test_get_windows_tz(self): - assert(self.proto.get_windows_tz() == IANA_TO_WIN.get(get_localzone().zone)) - - self.proto.timezone = 'UTC' - - assert(self.proto.get_windows_tz() == 'UTC') - - fake = get_localzone() - fake.zone = 'No existo' - with pytest.raises(UnknownTimeZoneError): - self.proto.get_windows_tz(fake) - def test_decendant_MSOffice365Protocol(self): # Basically we just test that it can create the class w/o erroring. msp = MSOffice365Protocol()