1
+ package fr.free.nrw.commons.upload
2
+
3
+ import android.content.Context
4
+ import android.content.Intent
5
+ import android.content.res.Resources
6
+ import androidx.core.app.NotificationCompat.Builder
7
+ import androidx.core.app.NotificationManagerCompat
8
+ import fr.free.nrw.commons.CommonsApplication
9
+ import fr.free.nrw.commons.contributions.ChunkInfo
10
+ import fr.free.nrw.commons.contributions.Contribution
11
+ import fr.free.nrw.commons.contributions.ContributionDao
12
+ import fr.free.nrw.commons.kvstore.JsonKvStore
13
+ import fr.free.nrw.commons.media.MediaClient
14
+ import fr.free.nrw.commons.upload.UploadService.ACTION_START_SERVICE
15
+ import fr.free.nrw.commons.wikidata.WikidataEditService
16
+ import io.reactivex.Completable
17
+ import io.reactivex.Scheduler
18
+ import io.reactivex.Single
19
+ import io.reactivex.disposables.CompositeDisposable
20
+ import io.reactivex.processors.PublishProcessor
21
+ import org.junit.Before
22
+ import org.junit.Test
23
+ import org.mockito.InjectMocks
24
+ import org.mockito.Mock
25
+ import org.mockito.Mockito.*
26
+ import org.mockito.MockitoAnnotations
27
+ import org.powermock.api.mockito.PowerMockito
28
+ import java.lang.reflect.Field
29
+ import java.lang.reflect.Method
30
+
31
+ class UploadServiceUnitTests {
32
+
33
+ @Mock
34
+ private lateinit var contribution: Contribution
35
+
36
+ @Mock
37
+ private lateinit var uploadClient: UploadClient
38
+
39
+ @Mock
40
+ private lateinit var compositeDisposable: CompositeDisposable
41
+
42
+ @Mock
43
+ private lateinit var ioThreadScheduler: Scheduler
44
+
45
+ @Mock
46
+ private lateinit var completable: Completable
47
+
48
+ @Mock
49
+ private lateinit var defaultKvStore: JsonKvStore
50
+
51
+ @Mock
52
+ private lateinit var curNotification: Builder
53
+
54
+ @Mock
55
+ private lateinit var contributionDao: ContributionDao
56
+
57
+ @Mock
58
+ private lateinit var contributionsToUpload: PublishProcessor <Contribution >
59
+
60
+ @Mock
61
+ private lateinit var single: Single <Int >
62
+
63
+ @Mock
64
+ private lateinit var singleBool: Single <Boolean >
65
+
66
+ @Mock
67
+ private lateinit var intent: Intent
68
+
69
+ @Mock
70
+ private lateinit var mediaClient: MediaClient
71
+
72
+ @Mock
73
+ private lateinit var notificationManager: NotificationManagerCompat
74
+
75
+ @Mock
76
+ private lateinit var chunkInfo: ChunkInfo
77
+
78
+ @Mock
79
+ private lateinit var resources: Resources
80
+
81
+ @InjectMocks
82
+ private lateinit var wikidataEditService: WikidataEditService
83
+
84
+
85
+ private lateinit var mockContext: Context
86
+ private lateinit var uploadService: UploadService
87
+ private lateinit var notificationUpdateProgressListener: UploadService .NotificationUpdateProgressListener
88
+
89
+ @Before
90
+ @Throws(Exception ::class )
91
+ fun setUp () {
92
+ MockitoAnnotations .initMocks(this )
93
+ uploadService = UploadService ()
94
+ notificationUpdateProgressListener = uploadService.NotificationUpdateProgressListener (
95
+ " " ,
96
+ " " ,
97
+ " " ,
98
+ contribution
99
+ )
100
+
101
+ mockContext = PowerMockito .mock(Context ::class .java)
102
+
103
+ `when `(contributionDao.update(contribution)).thenReturn(completable)
104
+ `when `(contributionDao.save(contribution)).thenReturn(completable)
105
+ `when `(contributionDao.update(contribution).subscribeOn(ioThreadScheduler)).thenReturn(
106
+ completable
107
+ )
108
+ `when `(contributionDao.save(contribution).subscribeOn(ioThreadScheduler)).thenReturn(
109
+ completable
110
+ )
111
+ `when `(contributionDao.getPendingUploads(any())).thenReturn(single)
112
+ `when `(contributionDao.updateStates(anyInt(), any())).thenReturn(single)
113
+ `when `(contributionDao.updateStates(anyInt(), any()).observeOn(any())).thenReturn(single)
114
+ `when `(
115
+ contributionDao.updateStates(anyInt(), any()).observeOn(any()).subscribeOn(
116
+ ioThreadScheduler
117
+ )
118
+ ).thenReturn(single)
119
+
120
+ val compositeDisposableField: Field =
121
+ UploadService ::class .java.getDeclaredField(" compositeDisposable" )
122
+ compositeDisposableField.isAccessible = true
123
+ compositeDisposableField.set(uploadService, compositeDisposable)
124
+
125
+ val uploadClientField: Field =
126
+ UploadService ::class .java.getDeclaredField(" uploadClient" )
127
+ uploadClientField.isAccessible = true
128
+ uploadClientField.set(uploadService, uploadClient)
129
+
130
+ val contributionDaoField: Field =
131
+ UploadService ::class .java.getDeclaredField(" contributionDao" )
132
+ contributionDaoField.isAccessible = true
133
+ contributionDaoField.set(uploadService, contributionDao)
134
+
135
+ val ioThreadSchedulerField: Field =
136
+ UploadService ::class .java.getDeclaredField(" ioThreadScheduler" )
137
+ ioThreadSchedulerField.isAccessible = true
138
+ ioThreadSchedulerField.set(uploadService, ioThreadScheduler)
139
+
140
+ val curNotificationField: Field =
141
+ UploadService ::class .java.getDeclaredField(" curNotification" )
142
+ curNotificationField.isAccessible = true
143
+ curNotificationField.set(uploadService, curNotification)
144
+
145
+ val defaultKvStoreField: Field =
146
+ UploadService ::class .java.getDeclaredField(" defaultKvStore" )
147
+ defaultKvStoreField.isAccessible = true
148
+ defaultKvStoreField.set(uploadService, defaultKvStore)
149
+
150
+ val contributionsToUploadField: Field =
151
+ UploadService ::class .java.getDeclaredField(" contributionsToUpload" )
152
+ contributionsToUploadField.isAccessible = true
153
+ contributionsToUploadField.set(uploadService, contributionsToUpload)
154
+
155
+ val notificationManagerdField: Field =
156
+ UploadService ::class .java.getDeclaredField(" notificationManager" )
157
+ notificationManagerdField.isAccessible = true
158
+ notificationManagerdField.set(uploadService, notificationManager)
159
+
160
+ val wikidataEditServiceField: Field =
161
+ UploadService ::class .java.getDeclaredField(" wikidataEditService" )
162
+ wikidataEditServiceField.isAccessible = true
163
+ wikidataEditServiceField.set(uploadService, wikidataEditService)
164
+
165
+ val mediaClientField: Field =
166
+ UploadService ::class .java.getDeclaredField(" mediaClient" )
167
+ mediaClientField.isAccessible = true
168
+ mediaClientField.set(uploadService, mediaClient)
169
+ }
170
+
171
+ @Test
172
+ fun testPauseUpload () {
173
+ uploadService.pauseUpload(contribution)
174
+ }
175
+
176
+ @Test
177
+ fun testOnDestroy () {
178
+ uploadService.onDestroy()
179
+ }
180
+
181
+ @Test
182
+ fun testOnBind () {
183
+ uploadService.onBind(null )
184
+ }
185
+
186
+ @Test
187
+ fun testQueueCaseTrue () {
188
+ `when `(
189
+ defaultKvStore.getBoolean(
190
+ CommonsApplication .IS_LIMITED_CONNECTION_MODE_ENABLED ,
191
+ false
192
+ )
193
+ ).thenReturn(true )
194
+ uploadService.queue(contribution)
195
+ }
196
+
197
+ @Test
198
+ fun testQueueCaseFalse () {
199
+ `when `(
200
+ defaultKvStore.getBoolean(
201
+ CommonsApplication .IS_LIMITED_CONNECTION_MODE_ENABLED ,
202
+ false
203
+ )
204
+ ).thenReturn(false )
205
+ uploadService.queue(contribution)
206
+ }
207
+
208
+ @Test
209
+ fun testOnStartCommandCaseTrue () {
210
+ `when `(intent.action).thenReturn(ACTION_START_SERVICE )
211
+ uploadService.onStartCommand(intent, 0 , 0 )
212
+ }
213
+
214
+ @Test
215
+ fun testSetServiceCallback () {
216
+ uploadService.setServiceCallback(null )
217
+ }
218
+
219
+ @Test
220
+ fun testGetNotificationBuilder () {
221
+ `when `(mockContext.resources).thenReturn(resources)
222
+ val method: Method = UploadService ::class .java.getDeclaredMethod(
223
+ " getNotificationBuilder" , String ::class .java
224
+ )
225
+ method.isAccessible = true
226
+ method.invoke(uploadService, " " )
227
+ }
228
+
229
+ @Test
230
+ fun testHandleUploadCaseFalse () {
231
+ `when `(mockContext.resources).thenReturn(resources)
232
+ uploadService.handleUpload(contribution)
233
+ }
234
+
235
+ @Test
236
+ fun testUploadContributionCaseNull () {
237
+ val method: Method = UploadService ::class .java.getDeclaredMethod(
238
+ " uploadContribution" , Contribution ::class .java
239
+ )
240
+ method.isAccessible = true
241
+ method.invoke(uploadService, contribution)
242
+ }
243
+
244
+ @Test
245
+ fun testClearChunks () {
246
+ val method: Method = UploadService ::class .java.getDeclaredMethod(
247
+ " clearChunks" , Contribution ::class .java
248
+ )
249
+ method.isAccessible = true
250
+ method.invoke(uploadService, contribution)
251
+ }
252
+
253
+ @Test
254
+ fun testFindUniqueFilename () {
255
+ `when `(mediaClient.checkPageExistsUsingTitle(any())).thenReturn(singleBool)
256
+ `when `(mediaClient.checkPageExistsUsingTitle(any()).blockingGet()).thenReturn(false )
257
+ val method: Method = UploadService ::class .java.getDeclaredMethod(
258
+ " findUniqueFilename" , String ::class .java
259
+ )
260
+ method.isAccessible = true
261
+ method.invoke(uploadService, " ." )
262
+ }
263
+
264
+ @Test
265
+ fun testOnChunkUploaded () {
266
+ notificationUpdateProgressListener.onChunkUploaded(contribution, chunkInfo)
267
+ }
268
+
269
+ @Test
270
+ fun testOnProgressCaseFalse () {
271
+ `when `(curNotification.setProgress(anyInt(), anyInt(), anyBoolean())).thenReturn(
272
+ curNotification
273
+ )
274
+ notificationUpdateProgressListener.onProgress(0 , 1 )
275
+ }
276
+
277
+ @Test
278
+ fun testOnProgressCaseTrue () {
279
+ `when `(curNotification.setContentTitle(anyString())).thenReturn(curNotification)
280
+ `when `(curNotification.setContentTitle(anyString()).setTicker(anyString())).thenReturn(
281
+ curNotification
282
+ )
283
+ `when `(curNotification.setProgress(anyInt(), anyInt(), anyBoolean())).thenReturn(
284
+ curNotification
285
+ )
286
+ notificationUpdateProgressListener.onProgress(0 , 0 )
287
+ }
288
+
289
+ @Test
290
+ fun testGetService () {
291
+ uploadService.UploadServiceLocalBinder ().service
292
+ }
293
+
294
+ }
0 commit comments