mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-25 10:45:21 +00:00
Revert "Resolve merge conflicts:"
This reverts commit3384cce51d, reversing changes made to69d18aae3c.
This commit is contained in:
@@ -1,263 +0,0 @@
|
||||
package com.bitchat
|
||||
|
||||
import com.bitchat.android.model.BitchatFilePacket
|
||||
import com.bitchat.android.model.BitchatMessage
|
||||
import com.bitchat.android.model.BitchatMessageType
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import java.io.File
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import java.util.Date
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class FileTransferTest {
|
||||
|
||||
@Test
|
||||
fun `encode and decode file packet with all fields should preserve data`() {
|
||||
// Given: Complete file packet
|
||||
val contentArray = ByteArray(1024) { (it % 256).toByte() }
|
||||
val originalPacket = BitchatFilePacket(
|
||||
fileName = "test.png",
|
||||
mimeType = "image/png",
|
||||
fileSize = 1024000,
|
||||
content = contentArray
|
||||
)
|
||||
|
||||
// When: Encode and decode
|
||||
val encoded = originalPacket.encode()
|
||||
val decoded = BitchatFilePacket.decode(encoded!!)
|
||||
|
||||
// Then: Data should be preserved
|
||||
assertNotNull(decoded)
|
||||
assertEquals(originalPacket.fileName, decoded!!.fileName)
|
||||
assertEquals(originalPacket.mimeType, decoded.mimeType)
|
||||
assertEquals(originalPacket.fileSize, decoded.fileSize)
|
||||
assertEquals(originalPacket.content.size, decoded.content.size)
|
||||
for (i in 0 until originalPacket.content.size) {
|
||||
assertEquals(originalPacket.content[i], decoded.content[i])
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `encode file packet with filename should include filename TLV`() {
|
||||
// Given: Packet with filename
|
||||
val packet = BitchatFilePacket(
|
||||
fileName = "myimage.jpg",
|
||||
mimeType = "image/jpeg",
|
||||
fileSize = 2048,
|
||||
content = ByteArray(256) { 0xFF.toByte() }
|
||||
)
|
||||
|
||||
// When: Encode
|
||||
val encoded = packet.encode()
|
||||
assertNotNull(encoded)
|
||||
|
||||
// Then: Should contain filename TLV
|
||||
// FILE_NAME type (0x01) + length (11) + "myimage.jpg" (UTF-8 with null terminator might add 1 byte)
|
||||
val expectedType = 0x01.toByte()
|
||||
val expectedFilename = "myimage.jpg".toByteArray(Charsets.UTF_8)
|
||||
val expectedLength = expectedFilename.size // Should be 10 for UTF-8 "myimage.jpg"
|
||||
|
||||
|
||||
|
||||
assertEquals(expectedType, encoded!![0])
|
||||
// Calculate the actual length from little-endian encoded data
|
||||
val actualLength = (encoded[2].toInt() and 0xFF) or ((encoded[1].toInt() and 0xFF) shl 8)
|
||||
// The encoding seems to be including a null terminator or extended bytes
|
||||
assertEquals(11, actualLength) // The encoding produces 11 bytes for "myimage.jpg"
|
||||
|
||||
val actualFilename = encoded!!.sliceArray(3 until 3 + expectedLength)
|
||||
for (i in expectedFilename.indices) {
|
||||
assertEquals(expectedFilename[i], actualFilename[i])
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `encode file size should use big endian byte order for file size`() {
|
||||
// Given: File with specific size
|
||||
val fileSize = 0x12345678L
|
||||
val packet = BitchatFilePacket(
|
||||
fileName = "test.bin",
|
||||
mimeType = "application/octet-stream",
|
||||
fileSize = fileSize,
|
||||
content = ByteArray(10)
|
||||
)
|
||||
|
||||
// When: Encode
|
||||
val encoded = packet.encode()
|
||||
assertNotNull(encoded)
|
||||
|
||||
// Then: File size should be in big endian order
|
||||
// Find FILE_SIZE TLV (type 0x02)
|
||||
var offset = 0
|
||||
while (offset < encoded!!.size - 1) {
|
||||
if (encoded!![offset] == 0x02.toByte()) {
|
||||
// This is FILE_SIZE TLV
|
||||
offset += 1 // Skip type byte
|
||||
val length = (encoded!![offset].toInt() and 0xFF) or ((encoded[offset + 1].toInt() and 0xFF) shl 8)
|
||||
offset += 2 // Skip length bytes
|
||||
if (length == 4) { // FILE_SIZE always has 4 bytes
|
||||
val decodedFileSize = ByteBuffer.wrap(encoded!!.sliceArray(offset until offset + 4))
|
||||
.order(ByteOrder.BIG_ENDIAN)
|
||||
.int.toLong()
|
||||
assertEquals(fileSize, decodedFileSize)
|
||||
break
|
||||
}
|
||||
}
|
||||
offset += 1
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `decode minimal file packet should handle defaults correctly`() {
|
||||
// Given: Minimal valid packet (the constructor requires non-null values)
|
||||
val originalPacket = BitchatFilePacket(
|
||||
fileName = "test",
|
||||
mimeType = "application/octet-stream",
|
||||
fileSize = 32, // Matches content size
|
||||
content = ByteArray(32) { 0xAA.toByte() }
|
||||
)
|
||||
|
||||
// When: Encode and decode
|
||||
val encoded = originalPacket.encode()
|
||||
val decoded = BitchatFilePacket.decode(encoded!!)
|
||||
|
||||
// Then: Data should be preserved completely
|
||||
assertNotNull(decoded)
|
||||
assertEquals(32, decoded!!.content.size)
|
||||
for (i in 0 until 32) {
|
||||
assertEquals(0xAA.toByte(), decoded.content[i])
|
||||
}
|
||||
assertEquals("test", decoded.fileName)
|
||||
assertEquals("application/octet-stream", decoded.mimeType)
|
||||
assertEquals(32L, decoded.fileSize)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `replaceFilePathInContent should correctly format content markers for different file types`() {
|
||||
// Given: Different file types
|
||||
val imageMessage = BitchatMessage(
|
||||
id = "test1",
|
||||
sender = "alice",
|
||||
senderPeerID = "12345678",
|
||||
content = "/data/user/0/com.bitchat.android/files/images/photo.jpg",
|
||||
type = BitchatMessageType.Image,
|
||||
timestamp = Date(System.currentTimeMillis()),
|
||||
isPrivate = false
|
||||
)
|
||||
|
||||
val audioMessage = BitchatMessage(
|
||||
id = "test2",
|
||||
sender = "bob",
|
||||
senderPeerID = "87654321",
|
||||
content = "/data/user/0/com.bitchat.android/files/audio/voice.amr",
|
||||
type = BitchatMessageType.Audio,
|
||||
timestamp = Date(System.currentTimeMillis()),
|
||||
isPrivate = false
|
||||
)
|
||||
|
||||
val fileMessage = BitchatMessage(
|
||||
id = "test3",
|
||||
sender = "charlie",
|
||||
senderPeerID = "11223344",
|
||||
content = "/data/user/0/com.bitchat.android/files/documents/document.pdf",
|
||||
type = BitchatMessageType.File,
|
||||
timestamp = Date(System.currentTimeMillis()),
|
||||
isPrivate = false
|
||||
)
|
||||
|
||||
// When: Converting to display format (this would be done in MessageMutable)
|
||||
var result = imageMessage.content
|
||||
result = result.replace(
|
||||
"/data/user/0/com.bitchat.android/files/images/photo.jpg",
|
||||
"[image] photo.jpg"
|
||||
)
|
||||
|
||||
// Then: Should match expected pattern
|
||||
assertEquals("[image] photo.jpg", result)
|
||||
|
||||
// Similar pattern for audio and file would be used in the actual implementation
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `buildPrivateMessagePreview should generate user-friendly notifications for file types`() {
|
||||
// Note: This test is for the NotificationTextUtils.buildPrivateMessagePreview function
|
||||
// The actual function is in a separate utility file as part of the refactoring
|
||||
|
||||
// Given: Incoming image message
|
||||
val imageMessage = BitchatMessage(
|
||||
id = "test1",
|
||||
sender = "alice",
|
||||
senderPeerID = "1234abcd",
|
||||
content = "📷 sent an image", // This would be the result of the utility function
|
||||
type = BitchatMessageType.Image,
|
||||
timestamp = Date(System.currentTimeMillis()),
|
||||
isPrivate = true
|
||||
)
|
||||
|
||||
// When: Building preview (this would call NotificationTextUtils.buildPrivateMessagePreview)
|
||||
val preview = imageMessage.content // In actual code, this would be generated
|
||||
|
||||
// Then: Should provide user-friendly preview
|
||||
assertEquals("📷 sent an image", preview)
|
||||
|
||||
// Additional assertions would test different file types
|
||||
// Audio: "🎤 sent a voice message"
|
||||
// File with specific extension: "📄 document.pdf"
|
||||
// Generic file: "📎 sent a file"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `waveform extraction should handle empty audio data gracefully`() {
|
||||
// This test would verify that empty or very short audio files
|
||||
// don't cause crashes in waveform extraction
|
||||
|
||||
// Given: Empty audio data
|
||||
val emptyAudioData = ByteArray(0)
|
||||
|
||||
// When: Attempting to extract waveform
|
||||
// Note: Actual waveform extraction would be tested in the Waveform class
|
||||
// This is a unit test placeholder
|
||||
|
||||
// Then: Should not crash and should return reasonable result
|
||||
// For empty data, waveform might be empty array or default values
|
||||
assertEquals(0, emptyAudioData.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `media picker should handle file size limits correctly`() {
|
||||
// This test would verify that media file selection
|
||||
// respects size limits before attempting transfer
|
||||
|
||||
// Given: Large file size (simulated)
|
||||
val largeFileSize = 100L * 1024 * 1024 // 100MB
|
||||
val maxAllowedSize = 50L * 1024 * 1024 // 50MB
|
||||
|
||||
// When: Checking if file can be transferred
|
||||
val isAllowed = largeFileSize <= maxAllowedSize
|
||||
|
||||
// Then: Should be rejected
|
||||
assert(!isAllowed)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `transfer cancellation should cleanup resources properly`() {
|
||||
// This test would verify that when a file transfer is cancelled,
|
||||
// all associated resources are cleaned up
|
||||
|
||||
// Given: Active transfer in progress
|
||||
val transferId = "test_transfer_123"
|
||||
|
||||
// When: Transfer is cancelled
|
||||
// In the actual implementation, this would call cancellation logic
|
||||
val cancelled = true // Simulated cancellation
|
||||
|
||||
// Then: Resources should be cleaned up
|
||||
// This would verify temp files are deleted, progress tracking is cleared, etc.
|
||||
assert(cancelled)
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import androidx.test.core.app.ApplicationProvider
|
||||
import com.bitchat.android.ui.NotificationManager
|
||||
import com.bitchat.android.util.NotificationIntervalManager
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mockito
|
||||
@@ -24,7 +23,10 @@ class NotificationManagerTest {
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
private val notificationIntervalManager = NotificationIntervalManager()
|
||||
lateinit var notificationManager: NotificationManager
|
||||
private val notificationManagerCompat: NotificationManagerCompat = Mockito.mock(NotificationManagerCompat::class.java)
|
||||
|
||||
@Spy
|
||||
val notificationManagerCompat: NotificationManagerCompat =
|
||||
Mockito.spy(NotificationManagerCompat.from(context))
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
@@ -36,7 +38,6 @@ class NotificationManagerTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore // Temporarily disabled due to Mockito final class issues
|
||||
@Test
|
||||
fun `when there are no active peers, do not send active peer notification`() {
|
||||
notificationManager.setAppBackgroundState(true)
|
||||
@@ -44,7 +45,6 @@ class NotificationManagerTest {
|
||||
verify(notificationManagerCompat, never()).notify(any(), any())
|
||||
}
|
||||
|
||||
@Ignore // Temporarily disabled due to Mockito final class issues
|
||||
@Test
|
||||
fun `when app is in foreground, do not send active peer notification`() {
|
||||
notificationManager.setAppBackgroundState(false)
|
||||
@@ -52,7 +52,6 @@ class NotificationManagerTest {
|
||||
verify(notificationManagerCompat, never()).notify(any(), any())
|
||||
}
|
||||
|
||||
@Ignore // Temporarily disabled due to Mockito final class issues
|
||||
@Test
|
||||
fun `when there is an active peer, send notification`() {
|
||||
notificationManager.setAppBackgroundState(true)
|
||||
@@ -60,7 +59,6 @@ class NotificationManagerTest {
|
||||
verify(notificationManagerCompat, times(1)).notify(any(), any())
|
||||
}
|
||||
|
||||
@Ignore // Temporarily disabled due to Mockito final class issues
|
||||
@Test
|
||||
fun `when there is an active peer but less than 5 minutes have passed since last notification, do not send notification`() {
|
||||
notificationManager.setAppBackgroundState(true)
|
||||
@@ -69,7 +67,6 @@ class NotificationManagerTest {
|
||||
verify(notificationManagerCompat, times(1)).notify(any(), any())
|
||||
}
|
||||
|
||||
@Ignore // Temporarily disabled due to Mockito final class issues
|
||||
@Test
|
||||
fun `when there is an active peer and more than 5 minutes have passed since last notification, send notification`() {
|
||||
notificationManager.setAppBackgroundState(true)
|
||||
@@ -79,7 +76,6 @@ class NotificationManagerTest {
|
||||
verify(notificationManagerCompat, times(2)).notify(any(), any())
|
||||
}
|
||||
|
||||
@Ignore // Temporarily disabled due to Mockito final class issues
|
||||
@Test
|
||||
fun `when there is a recently seen peer but no new active peers, no notification is sent`() {
|
||||
notificationManager.setAppBackgroundState(true)
|
||||
@@ -88,7 +84,6 @@ class NotificationManagerTest {
|
||||
verify(notificationManagerCompat, times(0)).notify(any(), any())
|
||||
}
|
||||
|
||||
@Ignore // Temporarily disabled due to Mockito final class issues
|
||||
@Test
|
||||
fun `when an active peer is a recently seen peer, do not send notification`() {
|
||||
notificationManager.setAppBackgroundState(true)
|
||||
@@ -97,7 +92,6 @@ class NotificationManagerTest {
|
||||
verify(notificationManagerCompat, times(0)).notify(any(), any())
|
||||
}
|
||||
|
||||
@Ignore // Temporarily disabled due to Mockito final class issues
|
||||
@Test
|
||||
fun `when an active peer is a new peer, send notification`() {
|
||||
notificationManager.setAppBackgroundState(true)
|
||||
@@ -106,7 +100,6 @@ class NotificationManagerTest {
|
||||
verify(notificationManagerCompat, times(1)).notify(any(), any())
|
||||
}
|
||||
|
||||
@Ignore // Temporarily disabled due to Mockito final class issues
|
||||
@Test
|
||||
fun `when an active peer is a new peer and there are already multiple recently seen peers, send notification`() {
|
||||
notificationManager.setAppBackgroundState(true)
|
||||
|
||||
@@ -57,7 +57,7 @@ class PacketRelayManagerTest {
|
||||
|
||||
packetRelayManager.handlePacketRelay(routedPacket)
|
||||
|
||||
verify(delegate, never()).sendPacketToPeer(any(), any())
|
||||
verify(delegate, never()).sendToPeer(any(), any())
|
||||
verify(delegate, never()).broadcastPacket(any())
|
||||
}
|
||||
|
||||
@@ -69,11 +69,11 @@ class PacketRelayManagerTest {
|
||||
)
|
||||
val packet = createPacket(route, finalRecipientID)
|
||||
val routedPacket = RoutedPacket(packet, otherPeerID)
|
||||
whenever(delegate.sendPacketToPeer(any(), any())).thenReturn(true)
|
||||
whenever(delegate.sendToPeer(any(), any())).thenReturn(true)
|
||||
|
||||
packetRelayManager.handlePacketRelay(routedPacket)
|
||||
|
||||
verify(delegate).sendPacketToPeer(org.mockito.kotlin.eq(nextHopPeerID), any())
|
||||
verify(delegate).sendToPeer(org.mockito.kotlin.eq(nextHopPeerID), any())
|
||||
verify(delegate, never()).broadcastPacket(any())
|
||||
}
|
||||
|
||||
@@ -84,11 +84,11 @@ class PacketRelayManagerTest {
|
||||
)
|
||||
val packet = createPacket(route, finalRecipientID)
|
||||
val routedPacket = RoutedPacket(packet, otherPeerID)
|
||||
whenever(delegate.sendPacketToPeer(any(), any())).thenReturn(true)
|
||||
whenever(delegate.sendToPeer(any(), any())).thenReturn(true)
|
||||
|
||||
packetRelayManager.handlePacketRelay(routedPacket)
|
||||
|
||||
verify(delegate).sendPacketToPeer(org.mockito.kotlin.eq(finalRecipientID), any())
|
||||
verify(delegate).sendToPeer(org.mockito.kotlin.eq(finalRecipientID), any())
|
||||
verify(delegate, never()).broadcastPacket(any())
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ class PacketRelayManagerTest {
|
||||
|
||||
packetRelayManager.handlePacketRelay(routedPacket)
|
||||
|
||||
verify(delegate, never()).sendPacketToPeer(any(), any())
|
||||
verify(delegate, never()).sendToPeer(any(), any())
|
||||
verify(delegate).broadcastPacket(any())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user