Completed
Push — master ( e4617d...4b6b67 )
by Jasper
10s
created

MongoRepoTests.setupRepo()   A

Complexity

Conditions 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
import unittest
2
from mock import Mock, patch, sentinel
3
from datetime import timedelta
4
from tests.ditest import DependencyInjectionTestBase
5
6
7
class MongoRepoTests(DependencyInjectionTestBase):
8
9
    def setUp(self):
10
        super(MongoRepoTests, self).setUp()
11
        self.pictureCache.getBytes.return_value = None
12
        self.db = Mock()
13
        self.db.provenance.find_one.return_value = {}
14
        self.db.provenance.find.return_value = {}
15
        self.pymongo = None
16
17
    def setupRepo(self):
18
        from niprov.mongo import MongoRepository
19
        with patch('niprov.mongo.pymongo') as self.pymongo:
20
            self.repo = MongoRepository(dependencies=self.dependencies)
21
        self.repo.db = self.db
22
23
    def test_Connection(self):
24
        from niprov.mongo import MongoRepository
25
        with patch('niprov.mongo.pymongo') as pymongo:
26
            repo = MongoRepository(dependencies=self.dependencies)
27
        pymongo.MongoClient.assert_called_with(self.config.database_url)
28
        self.assertEqual(pymongo.MongoClient().get_default_database(), repo.db)
29
30
    def test_knowsByLocation(self):
31
        self.setupRepo()
32
        p = '/p/f1'
33
        self.db.provenance.find_one.return_value = None
34
        self.assertFalse(self.repo.knowsByLocation(p))
35
        self.db.provenance.find_one.assert_called_with({'location':p})
36
        self.db.provenance.find_one.return_value = 1
37
        self.assertTrue(self.repo.knowsByLocation(p))
38
39
    def test_byLocation_returns_img_from_record_with_path(self):
40
        self.setupRepo()
41
        p = '/p/f1'
42
        out = self.repo.byLocation(p)
43
        self.db.provenance.find_one.assert_called_with({'location':p})
44
        self.fileFactory.fromProvenance.assert_called_with(
45
            self.db.provenance.find_one())
46
        self.assertEqual(self.fileFactory.fromProvenance(), out)
47
48
    def test_getSeries(self):
49
        self.setupRepo()
50
        img = Mock()
51
        out = self.repo.getSeries(img)
52
        self.db.provenance.find_one.assert_called_with(
53
            {'seriesuid':img.getSeriesId()})
54
        self.fileFactory.fromProvenance.assert_called_with(
55
            self.db.provenance.find_one())
56
        self.assertEqual(self.fileFactory.fromProvenance(), out)
57
58
    def test_knowsSeries_returns_False_if_no_series_id(self):
59
        self.setupRepo()
60
        img = Mock()
61
        img.getSeriesId.return_value = None
62
        self.assertFalse(self.repo.knowsSeries(img))
63
64
    def test_knowsSeries(self):
65
        self.setupRepo()
66
        img = Mock()
67
        self.assertTrue(self.repo.knowsSeries(img))
68
        self.db.provenance.find_one.return_value = None
69
        self.assertFalse(self.repo.knowsSeries(img))
70
71
    def test_Add(self):
72
        self.setupRepo()
73
        img = Mock()
74
        img.provenance = {'a':1, 'b':2}
75
        self.repo.add(img)
76
        self.db.provenance.insert_one.assert_called_with({'a':1, 'b':2})
77
78
    def test_update(self):
79
        self.setupRepo()
80
        img = Mock()
81
        img.provenance = {'a':1, 'b':2}
82
        self.repo.update(img)
83
        self.db.provenance.update.assert_called_with(
84 View Code Duplication
            {'location':img.location.toString()}, {'a':1, 'b':2})
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
85
86
    def test_all(self):
87
        self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p
88
        self.db.provenance.find.return_value = ['p1', 'p2']
89
        self.setupRepo()
90
        out = self.repo.all()
91
        self.db.provenance.find.assert_called_with()
92
        self.fileFactory.fromProvenance.assert_any_call('p1')
93
        self.fileFactory.fromProvenance.assert_any_call('p2')
94
        self.assertEqual(['img_p1', 'img_p2'], out)
95
96
    def test_updateApproval(self):
97
        self.setupRepo()
98
        img = Mock()
99
        p = '/p/f1'
100
        newStatus = 'oh-oh'
101
        self.repo.updateApproval(p, newStatus)
102
        self.db.provenance.update.assert_called_with(
103
            {'location':p}, {'$set': {'approval': newStatus}})
104
105
    def test_latest(self):
106
        self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p
107
        self.db.provenance.find.return_value = Mock()
108
        self.db.provenance.find.return_value.sort.return_value.limit.return_value = ['px','py']
109
        self.setupRepo()
110
        out = self.repo.latest()
111
        self.db.provenance.find.assert_called_with()
112
        self.db.provenance.find().sort.assert_called_with('added', -1)
113
        self.db.provenance.find().sort().limit.assert_called_with(20)
114
        self.fileFactory.fromProvenance.assert_any_call('px')
115
        self.fileFactory.fromProvenance.assert_any_call('py')
116
        self.assertEqual(['img_px', 'img_py'], out)
117
118
    def test_statistics(self):
119
        self.db.provenance.aggregate.return_value = [sentinel.stats,]
120
        self.setupRepo()
121
        out = self.repo.statistics()
122
        self.db.provenance.aggregate.assert_called_with(
123
           [{'$group':
124
                 {
125
                   '_id': None,
126
                   'totalsize': { '$sum': '$size' },
127
                   'count': { '$sum': 1 }
128
                 }
129
            }])
130
        self.assertEqual(sentinel.stats, out)
131
132
    def test_statistics_if_no_records(self):
133
        self.db.provenance.aggregate.return_value = []
134
        self.setupRepo()
135
        out = self.repo.statistics()
136
        self.assertEqual({'count':0}, out)
137
138
    def test_byId(self):
139
        self.setupRepo()
140
        ID = 'abc123'
141
        out = self.repo.byId(ID)
142
        self.db.provenance.find_one.assert_called_with({'id':ID})
143
        self.fileFactory.fromProvenance.assert_called_with(
144
            self.db.provenance.find_one())
145
        self.assertEqual(self.fileFactory.fromProvenance(), out)
146
147
    def test_byLocations(self):
148
        self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p
149
        self.db.provenance.find.return_value = ['p1', 'p2']
150
        self.setupRepo()
151
        out = self.repo.byLocations(['l1','l2'])
152
        self.db.provenance.find.assert_called_with({'location':{'$in':['l1','l2']}})
153
        self.fileFactory.fromProvenance.assert_any_call('p1')
154
        self.fileFactory.fromProvenance.assert_any_call('p2')
155
        self.assertEqual(['img_p1', 'img_p2'], out)
156
157
    def test_byParents(self):
158
        self.fileFactory.fromProvenance.side_effect = lambda p: 'img_'+p
159
        self.db.provenance.find.return_value = ['p1', 'p2']
160
        self.setupRepo()
161
        out = self.repo.byParents(['x1','x2'])
162
        self.db.provenance.find.assert_called_with({'parents':{'$in':['x1','x2']}})
163
        self.fileFactory.fromProvenance.assert_any_call('p1')
164
        self.fileFactory.fromProvenance.assert_any_call('p2')
165
        self.assertEqual(['img_p1', 'img_p2'], out)
166
167 View Code Duplication
    def test_Converts_timedelta_to_float_when_serializing(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
168
        self.setupRepo()
169
        img = Mock()
170
        img.provenance = {'a':1, 'duration':timedelta(seconds=67.89)}
171
        self.repo.add(img)
172
        self.db.provenance.insert_one.assert_called_with(
173
            {'a':1, 'duration':67.89})
174
175
    def test_Converts_duration_to_timedelta_when_deserializing(self):
176
        self.setupRepo()
177 View Code Duplication
        self.db.provenance.find_one.return_value = {'a':3, 'duration':89.01}
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
178
        out = self.repo.byLocation('/p/f1')
179
        self.fileFactory.fromProvenance.assert_called_with(
180
            {'a':3, 'duration':timedelta(seconds=89.01)})
181
182
    def test_Obtains_optional_snapshot_data_from_cache_when_serializing(self):
183
        self.pictureCache.getBytes.return_value = sentinel.snapbytes
184
        with patch('niprov.mongo.bson') as bson:
185
            bson.Binary.return_value = sentinel.snapbson
186
            self.setupRepo()
187
            img = Mock()
188
            img.provenance = {'a':1}
189
            self.repo.add(img)
190
            self.pictureCache.getBytes.assert_called_with(for_=img)
191
            bson.Binary.assert_called_with(sentinel.snapbytes)
192
            self.db.provenance.insert_one.assert_called_with({'a':1, 
193
                '_snapshot-data':sentinel.snapbson})
194
195
    def test_If_no_snapshot_doesnt_add_data_field(self):
196
        self.pictureCache.getBytes.return_value = None
197
        with patch('niprov.mongo.bson') as bson:
198
            self.setupRepo()
199
            img = Mock()
200
            img.provenance = {'a':1}
201
            self.repo.add(img)
202
            assert not bson.Binary.called
203
            self.db.provenance.insert_one.assert_called_with({'a':1})
204
205
    def test_If_snapshotdata_hands_them_to_pictureCache_on_deserializing(self):
206
        img = Mock()
207
        self.fileFactory.fromProvenance.return_value = img
208
        self.setupRepo()
209
        self.db.provenance.find_one.return_value = {'a':3}
210
        out = self.repo.byLocation('/p/f1')
211
        assert not self.pictureCache.keep.called
212
        self.db.provenance.find_one.return_value = {'a':3, 
213
                                                    '_snapshot-data':'y7yUyS'}
214
        out = self.repo.byLocation('/p/f1')
215
        self.pictureCache.keep.assert_called_with('y7yUyS', for_=img)
216
217
    def test_If_no_record_returned_byLocation_byId_getSeries_raise_alarm(self):
218
        self.setupRepo()
219
        self.db.provenance.find_one.return_value = None
220
        out = self.repo.byLocation('nowhere')
221
        self.listener.unknownFile.assert_called_with('nowhere')
222
        out = self.repo.byId('xxxx')
223
        self.listener.unknownFile.assert_called_with('id: xxxx')
224
        img = Mock()
225
        img.getSeriesId.return_value = '123abc'
226
        out = self.repo.getSeries(img)
227
        self.listener.unknownFile.assert_called_with('seriesuid: 123abc')
228
229
    def test_Query(self):
230
        self.db.provenance.find.return_value = ['record1']
231
        self.setupRepo()
232
        q = Mock()
233
        field1 = Mock()
234
        field1.name = 'color'
235
        field1.value = 'red'
236
        q.getFields.return_value = [field1]
237
        out = self.repo.inquire(q)
238
        self.db.provenance.find.assert_called_with({'color':'red'})
239
        self.fileFactory.fromProvenance.assert_called_with('record1')
240
241
    def test_Ensures_text_index_for_search(self):
242
        self.setupRepo()
243
        self.repo.search('')
244
        searchfields = ['location','user','subject','project','protocol',
245
                  'transformation','technique','modality']
246
        indexspec = [(field, 'text') for field in searchfields]
247
        self.db.provenance.create_index.assert_called_with(indexspec)
248
249
    def test_Search(self):
250
        self.db.provenance.find.return_value = ['r1','r2']
251
        self.setupRepo()
252
        self.repo.search('xyz')
253
        self.db.provenance.find.assert_called_with({'$text':{'$search': 'xyz'}})
254
        self.fileFactory.fromProvenance.assert_any_call('r1')
255
        self.fileFactory.fromProvenance.assert_any_call('r2')
256
257
258