Completed
Push — master ( 6d0d49...6d6a7d )
by Jasper
02:25 queued 57s
created

MongoRepoTests   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 241
Duplicated Lines 19.5 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
dl 47
loc 241
rs 8.3999
c 6
b 0
f 0
wmc 38

26 Methods

Rating   Name   Duplication   Size   Complexity  
A test_Obtains_optional_snapshot_data_from_cache_when_serializing() 0 12 2
A test_latest() 0 12 2
A test_Converts_duration_to_timedelta_when_deserializing() 0 6 1
A test_If_snapshotdata_hands_them_to_pictureCache_on_deserializing() 0 10 2
A test_Connection() 0 6 2
A test_byParents() 8 9 2
A test_Add() 0 6 1
A setupRepo() 0 5 2
A test_knowsSeries() 0 6 1
A test_If_no_snapshot_doesnt_add_data_field() 0 9 3
A test_knowsSeries_returns_False_if_no_series_id() 0 5 1
A test_all() 8 9 2
A test_byId() 0 8 1
A test_byLocations() 8 9 2
A test_knowsByLocation() 0 8 1
A test_getSeries() 0 9 1
A test_statistics() 0 13 1
A test_Converts_timedelta_to_float_when_serializing() 0 7 1
A test_If_no_record_returned_byLocation_byId_getSeries_raise_alarm() 0 11 1
A test_update() 0 7 1
A test_byLocation_returns_img_from_record_with_path() 0 8 1
A test_updateApproval() 0 8 1
A test_byApproval() 9 10 2
A test_bySubject() 9 10 2
A setUp() 0 6 1
A test_statistics_if_no_records() 0 5 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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