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
|
/***************************************************************************************************
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
**************************************************************************************************/
package at.bitfire.vcard4android.contactrow
import android.Manifest
import android.accounts.Account
import android.content.ContentProviderClient
import android.content.ContentUris
import android.graphics.BitmapFactory
import android.net.Uri
import android.provider.ContactsContract
import android.provider.ContactsContract.RawContacts
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import at.bitfire.vcard4android.AndroidContact
import at.bitfire.vcard4android.Contact
import at.bitfire.vcard4android.impl.TestAddressBook
import org.apache.commons.io.IOUtils
import org.junit.Assert
import org.junit.Assert.*
import org.junit.BeforeClass
import org.junit.ClassRule
import org.junit.Test
import kotlin.random.Random
class PhotoBuilderTest {
companion object {
@JvmField
@ClassRule
val permissionRule = GrantPermissionRule.grant(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS)!!
private val testAccount = Account("AndroidContactTest", "at.bitfire.vcard4android")
val testContext = InstrumentationRegistry.getInstrumentation().context
private lateinit var provider: ContentProviderClient
private lateinit var addressBook: TestAddressBook
@BeforeClass
@JvmStatic
fun connect() {
provider = testContext.contentResolver.acquireContentProviderClient(ContactsContract.AUTHORITY)!!
Assert.assertNotNull(provider)
addressBook = TestAddressBook(testAccount, provider)
}
@BeforeClass
@JvmStatic
fun disconnect() {
@Suppress("DEPRECATION")
provider.release()
}
}
@Test
fun testBuild_NoPhoto() {
PhotoBuilder(Uri.EMPTY, null, Contact()).build().also { result ->
assertEquals(0, result.size)
}
}
@Test
fun testBuild_Photo() {
val blob = ByteArray(1024) { Random.nextInt().toByte() }
PhotoBuilder(Uri.EMPTY, null, Contact().apply {
photo = blob
}).build().also { result ->
// no row because photos have to be inserted with a separate call to insertPhoto()
assertEquals(0, result.size)
}
}
@Test
fun testInsertPhoto() {
val contact = AndroidContact(addressBook, Contact().apply { displayName = "Contact with photo" }, null, null)
val contactUri = contact.add()
val rawContactId = ContentUris.parseId(contactUri)
try {
val photo = IOUtils.resourceToByteArray("/large.jpg")
val photoUri = PhotoBuilder.insertPhoto(provider, testAccount, rawContactId, photo)
assertNotNull(photoUri)
// the photo is processed and often resized by the contacts provider
val contact2 = addressBook.findContactById(rawContactId)
val photo2 = contact2.getContact().photo!!
// verify that the image is in JPEG format (some Samsung devices seem to save as PNG)
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeByteArray(photo2, 0, photo2.size, options)
assertEquals("image/jpeg", options.outMimeType)
// verify that contact is not dirty
provider.query(
ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
arrayOf(RawContacts.DIRTY),
null, null, null
)!!.use { cursor ->
assertTrue(cursor.moveToNext())
assertEquals(0, cursor.getInt(0))
}
} finally {
contact.delete()
}
}
@Test(expected = IllegalArgumentException::class)
fun testInsertPhoto_Invalid() {
val contact = AndroidContact(addressBook, Contact().apply { displayName = "Contact with photo" }, null, null)
contact.add()
try {
val photoUri = PhotoBuilder.insertPhoto(provider, testAccount, contact.id!!, ByteArray(100) /* invalid photo */)
} finally {
contact.delete()
}
}
}
|