File: test_collections.py

package info (click to toggle)
python-etesync 0.12.1-1.4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 272 kB
  • sloc: python: 1,352; sh: 3; makefile: 2
file content (178 lines) | stat: -rw-r--r-- 6,915 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# Copyright © 2017 Tom Hacohen
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, version 3.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import pytest
import binascii

import etesync as api
from etesync import exceptions
from etesync.crypto import hmac256


USER_EMAIL = 'test@localhost'
TEST_REMOTE = 'http://localhost:8000'
TEST_DB = ':memory:'


# Gets fake (consistent between tests) random numbers
def get_random_uid(context):
    context._rand = getattr(context, '_rand', 0)
    context._rand = context._rand + 1
    return binascii.hexlify(hmac256(b'', str(context._rand).encode())).decode()


@pytest.fixture(scope="module")
def etesync():
    return api.EteSync(USER_EMAIL, '', remote=TEST_REMOTE, db_path=TEST_DB)


class TestCollection:
    @pytest.fixture(autouse=True)
    def transact(self, request, etesync):
        etesync._init_db(TEST_DB)
        yield

    def test_crud(self, etesync):
        # Empty collections
        assert len(list(etesync.list())) == 0

        # Create
        a = api.Calendar.create(etesync, get_random_uid(self), {'displayName': 'Test', 'description': 'Test desc'})
        b = api.AddressBook.create(etesync, get_random_uid(self), {'displayName': 'Test 2'})
        assert a is not None
        assert b is not None

        # Description is what we expect
        assert a.description == 'Test desc'

        # Still empty because we haven't saved
        assert len(list(etesync.list())) == 0

        # Fetch before saved:
        with pytest.raises(exceptions.DoesNotExist):
            etesync.get(a.journal.uid)

        a.save()
        assert 'Test' == list(etesync.list())[0].collection.display_name
        assert len(list(etesync.list())) == 1
        b.save()
        assert len(list(etesync.list())) == 2

        # Get
        assert a.journal.uid == etesync.get(a.journal.uid).uid
        assert b.journal.uid == etesync.get(b.journal.uid).uid

        # Check version is correct
        assert a.journal.version > 0

        # Delete
        a.delete()
        assert len(list(etesync.list())) == 1
        b.delete()
        assert len(list(etesync.list())) == 0

        # Try saving two collections with the same uid
        c = api.Calendar.create(etesync, a.journal.uid, {'displayName': 'Test'})
        with pytest.raises(exceptions.AlreadyExists):
            c.save()

    def test_content_crud(self, etesync):
        a = api.Calendar.create(etesync, get_random_uid(self), {'displayName': 'Test'})
        b = api.AddressBook.create(etesync, get_random_uid(self), {'displayName': 'Test 2'})
        c = api.Calendar.create(etesync, get_random_uid(self), {'displayName': 'Test 3'})

        ev = api.Event.create(a,
                              'BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:+//Yo\r\nBEGIN:VEVENT\r\nDTSTAMP:20170324T164' +
                              '747Z\r\nUID:2cd64f22-1111-44f5-bc45-53440af38cec\r\nDTSTART;VALUE\u003dDATE:20170324' +
                              '\r\nDTEND;VALUE\u003dDATE:20170325\r\nSUMMARY:Feed cat\r\nSTATUS:CONFIRMED\r\nTRANSP:' +
                              'TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n')

        # Try saving before the journal is saved
        with pytest.raises(exceptions.DoesNotExist):
            ev.save()

        # Create the event
        a.save()
        ev.save()

        assert ev.uid == a.get('2cd64f22-1111-44f5-bc45-53440af38cec').uid

        # Fail to create another event with the same uid
        ev = api.Event.create(a,
                              'BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:+//Yo\r\nBEGIN:VEVENT\r\nDTSTAMP:20170324T164' +
                              '747Z\r\nUID:2cd64f22-1111-44f5-bc45-53440af38cec\r\nDTSTART;VALUE\u003dDATE:20170324' +
                              '\r\nDTEND;VALUE\u003dDATE:20170325\r\nSUMMARY:Feed cat\r\nSTATUS:CONFIRMED\r\nTRANSP:' +
                              'TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n')
        with pytest.raises(exceptions.AlreadyExists):
            ev.save()

        # Trying to add an Event into an AddressBook
        b.save()

        # Wrong child in collection
        with pytest.raises(exceptions.TypeMismatch):
            api.Event.create(b, (
                  'BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:+//Yo\r\nBEGIN:VEVENT\r\nDTSTAMP:20170324T164' +
                  '747Z\r\nUID:2cd64f22-2222-44f5-bc45-53440af38cec\r\nDTSTART;VALUE\u003dDATE:20170324' +
                  '\r\nDTEND;VALUE\u003dDATE:20170325\r\nSUMMARY:Feed cat\r\nSTATUS:CONFIRMED\r\nTRANSP:' +
                  'TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n'))

        # Same uid in different collections
        c.save()
        ev2 = api.Event.create(c, ev.content)
        ev2.save()

        # Check it's actually there
        assert len(list(c.list())) == 1

        # # First is still here even after we delete the new one
        ev2.delete()
        assert len(list(c.list())) == 0

        assert ev.uid == a.get('2cd64f22-1111-44f5-bc45-53440af38cec').uid

        # Check fetching a non-existent item
        with pytest.raises(exceptions.DoesNotExist):
            c.get('bla')

        # Fail creating an event without a uid.
        ev = api.Event.create(a,
                              'BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:+//Yo\r\nBEGIN:VEVENT\r\nDTSTAMP:20170324T164' +
                              '747Z\r\nDTSTART;VALUE\u003dDATE:20170324' +
                              '\r\nDTEND;VALUE\u003dDATE:20170325\r\nSUMMARY:Feed cat\r\nSTATUS:CONFIRMED\r\nTRANSP:' +
                              'TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n')
        assert ev is None

    def test_unicode(self, etesync):
        a = api.Calendar.create(etesync, get_random_uid(self), {'displayName': 'יוניקוד'})

        # Create the event
        a.save()

        a2 = etesync.get(a.journal.uid)

        assert a.display_name == a2.collection.display_name

        ev = api.Event.create(a, (
              'BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:+//Yo\r\nBEGIN:VEVENT\r\nDTSTAMP:20170324T164' +
              '747Z\r\nUID:2cd64f22-2222-44f5-bc45-53440af38cec\r\nDTSTART;VALUE\u003dDATE:20170324' +
              '\r\nDTEND;VALUE\u003dDATE:20170325\r\nSUMMARY:יוניקוד\r\nSTATUS:CONFIRMED\r\nTRANSP:' +
              'TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n'))

        ev.save()

        assert ev.content == a.get(ev.uid).content

        # Test repr works
        repr(ev)