mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-14 14:19:57 +02:00
fix(saved-devices): preserve targeted transfer direction
This commit is contained in:
@@ -44,6 +44,8 @@ class SavedDeviceCoreContractBindingHygieneTest {
|
||||
assertTrue(
|
||||
source.contains("public expect fun `savedDeviceCapabilities`(): SavedDeviceCapabilities"),
|
||||
)
|
||||
assertTrue(source.contains("var `role`: TargetedTransferRole"))
|
||||
assertTrue(source.contains("public enum class TargetedTransferRole"))
|
||||
assertTrue(
|
||||
source.contains("SavedDevice"),
|
||||
"SavedDevice model must remain on the public surface",
|
||||
|
||||
@@ -33,6 +33,7 @@ import uniffi.vnidrop.SourceKind
|
||||
import uniffi.vnidrop.StoredTransfer
|
||||
import uniffi.vnidrop.TargetedOfferResponse
|
||||
import uniffi.vnidrop.TargetedTransfer
|
||||
import uniffi.vnidrop.TargetedTransferRole
|
||||
import uniffi.vnidrop.TargetedTransferState
|
||||
import uniffi.vnidrop.TicketInspection
|
||||
import uniffi.vnidrop.TransferMetadata
|
||||
@@ -643,6 +644,7 @@ private fun PendingTargetedOffer.toModel(): PendingTargetedOfferModel = PendingT
|
||||
|
||||
private fun TargetedTransfer.toModel(): TargetedTransferModel = TargetedTransferModel(
|
||||
id = id,
|
||||
role = role.toModel(),
|
||||
senderEndpointId = senderEndpointId,
|
||||
receiverEndpointId = receiverEndpointId,
|
||||
manifestId = manifestId,
|
||||
@@ -655,6 +657,11 @@ private fun TargetedTransfer.toModel(): TargetedTransferModel = TargetedTransfer
|
||||
updatedAt = updatedAt,
|
||||
)
|
||||
|
||||
private fun TargetedTransferRole.toModel(): TargetedTransferRoleModel = when (this) {
|
||||
TargetedTransferRole.SENDER -> TargetedTransferRoleModel.Sender
|
||||
TargetedTransferRole.RECEIVER -> TargetedTransferRoleModel.Receiver
|
||||
}
|
||||
|
||||
private fun TargetedTransferState.toModel(): TargetedTransferStateModel = when (this) {
|
||||
TargetedTransferState.PREPARING -> TargetedTransferStateModel.Preparing
|
||||
TargetedTransferState.OFFERING -> TargetedTransferStateModel.Offering
|
||||
|
||||
@@ -68,8 +68,14 @@ enum class TargetedTransferStateModel {
|
||||
Deleted,
|
||||
}
|
||||
|
||||
enum class TargetedTransferRoleModel {
|
||||
Sender,
|
||||
Receiver,
|
||||
}
|
||||
|
||||
data class TargetedTransferModel(
|
||||
val id: String,
|
||||
val role: TargetedTransferRoleModel,
|
||||
val senderEndpointId: String,
|
||||
val receiverEndpointId: String,
|
||||
val manifestId: String,
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.vnidrop.app.core.ReceiveFolder
|
||||
import com.vnidrop.app.core.SavedDeviceModel
|
||||
import com.vnidrop.app.core.TargetedOfferResponseModel
|
||||
import com.vnidrop.app.core.TargetedTransferModel
|
||||
import com.vnidrop.app.core.TargetedTransferRoleModel
|
||||
import com.vnidrop.app.core.TargetedTransferStateModel
|
||||
import com.vnidrop.app.preferences.PreferencesRepository
|
||||
import com.vnidrop.app.ui.feedback.UiMessage
|
||||
@@ -365,8 +366,7 @@ class SavedDevicesViewModel(
|
||||
}
|
||||
|
||||
private fun TargetedTransferModel.toExperienceItem(savedNames: Map<String, String>): SavedDeviceTransferItem {
|
||||
val localEndpointId = repository.state.value.status?.endpointId
|
||||
val outgoing = senderEndpointId == localEndpointId
|
||||
val outgoing = role == TargetedTransferRoleModel.Sender
|
||||
val peerEndpointId = if (outgoing) receiverEndpointId else senderEndpointId
|
||||
return SavedDeviceTransferItem(
|
||||
id = id,
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.vnidrop.app.core.ReceiveFolderKind
|
||||
import com.vnidrop.app.core.SavedDeviceModel
|
||||
import com.vnidrop.app.core.TargetedOfferResponseModel
|
||||
import com.vnidrop.app.core.TargetedTransferModel
|
||||
import com.vnidrop.app.core.TargetedTransferRoleModel
|
||||
import com.vnidrop.app.core.TargetedTransferStateModel
|
||||
import com.vnidrop.app.preferences.AppPreferences
|
||||
import com.vnidrop.app.support.FakeCoreGateway
|
||||
@@ -49,7 +50,15 @@ class SavedDevicesViewModelTest {
|
||||
deviceRelationships = listOf(incoming("incoming"))
|
||||
savedDevices = listOf(device("peer", "Office PC", "Authenticated PC"))
|
||||
pendingTargetedOffers = listOf(offer("offer", "peer"))
|
||||
targetedTransfers = listOf(transfer("history", "local", "peer", TargetedTransferStateModel.AwaitingApproval))
|
||||
targetedTransfers = listOf(
|
||||
transfer(
|
||||
"history",
|
||||
TargetedTransferRoleModel.Sender,
|
||||
"local",
|
||||
"peer",
|
||||
TargetedTransferStateModel.AwaitingApproval,
|
||||
),
|
||||
)
|
||||
}
|
||||
val viewModel = createViewModel(core)
|
||||
runCurrent()
|
||||
@@ -74,6 +83,29 @@ class SavedDevicesViewModelTest {
|
||||
assertEquals(false, state.loadFailed)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun persistedOutgoingTransferKeepsDirectionAfterIdentityReset() = runTest {
|
||||
Dispatchers.setMain(StandardTestDispatcher(testScheduler))
|
||||
val core = initializedCore().apply {
|
||||
targetedTransfers = listOf(
|
||||
transfer(
|
||||
id = "past-send",
|
||||
role = TargetedTransferRoleModel.Sender,
|
||||
sender = "retired-local-identity",
|
||||
receiver = "peer",
|
||||
state = TargetedTransferStateModel.Completed,
|
||||
),
|
||||
)
|
||||
}
|
||||
val viewModel = createViewModel(core)
|
||||
runCurrent()
|
||||
advanceUntilIdle()
|
||||
|
||||
val transfer = viewModel.state.value.targetedTransfers.single()
|
||||
assertEquals(SavedDeviceTransferDirection.Outgoing, transfer.direction)
|
||||
assertEquals("peer", transfer.peerEndpointId)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun pairingPromptCommandsAndDismissalUseTheSameDurableLists() = runTest {
|
||||
Dispatchers.setMain(StandardTestDispatcher(testScheduler))
|
||||
@@ -158,7 +190,15 @@ class SavedDevicesViewModelTest {
|
||||
fun interruptedTransferResumeUsesThePlatformSinkWhenAvailable() = runTest {
|
||||
Dispatchers.setMain(StandardTestDispatcher(testScheduler))
|
||||
val core = initializedCore().apply {
|
||||
targetedTransfers = listOf(transfer("resume-sink", "peer", "local", TargetedTransferStateModel.Interrupted))
|
||||
targetedTransfers = listOf(
|
||||
transfer(
|
||||
"resume-sink",
|
||||
TargetedTransferRoleModel.Receiver,
|
||||
"peer",
|
||||
"local",
|
||||
TargetedTransferStateModel.Interrupted,
|
||||
),
|
||||
)
|
||||
}
|
||||
val viewModel = createViewModel(
|
||||
core,
|
||||
@@ -180,9 +220,9 @@ class SavedDevicesViewModelTest {
|
||||
Dispatchers.setMain(StandardTestDispatcher(testScheduler))
|
||||
val core = initializedCore().apply {
|
||||
targetedTransfers = listOf(
|
||||
transfer("resume", "peer", "local", TargetedTransferStateModel.Interrupted),
|
||||
transfer("cancel", "local", "peer", TargetedTransferStateModel.AwaitingApproval),
|
||||
transfer("delete", "peer", "local", TargetedTransferStateModel.Completed),
|
||||
transfer("resume", TargetedTransferRoleModel.Receiver, "peer", "local", TargetedTransferStateModel.Interrupted),
|
||||
transfer("cancel", TargetedTransferRoleModel.Sender, "local", "peer", TargetedTransferStateModel.AwaitingApproval),
|
||||
transfer("delete", TargetedTransferRoleModel.Receiver, "peer", "local", TargetedTransferStateModel.Completed),
|
||||
)
|
||||
}
|
||||
val viewModel = createViewModel(core)
|
||||
@@ -336,11 +376,13 @@ class SavedDevicesViewModelTest {
|
||||
|
||||
private fun transfer(
|
||||
id: String,
|
||||
role: TargetedTransferRoleModel,
|
||||
sender: String,
|
||||
receiver: String,
|
||||
state: TargetedTransferStateModel,
|
||||
) = TargetedTransferModel(
|
||||
id = id,
|
||||
role = role,
|
||||
senderEndpointId = sender,
|
||||
receiverEndpointId = receiver,
|
||||
manifestId = "manifest-$id",
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.vnidrop.app.core.SavedDeviceModel
|
||||
import com.vnidrop.app.core.Share
|
||||
import com.vnidrop.app.core.ShareAccessPolicy
|
||||
import com.vnidrop.app.core.TargetedTransferModel
|
||||
import com.vnidrop.app.core.TargetedTransferRoleModel
|
||||
import com.vnidrop.app.core.TargetedTransferStateModel
|
||||
import com.vnidrop.app.support.FakeCoreGateway
|
||||
import com.vnidrop.app.support.FakeFilePreviewRepository
|
||||
@@ -235,6 +236,7 @@ class TransferDraftViewModelTest {
|
||||
|
||||
private fun targeted(id: String, peerId: String) = TargetedTransferModel(
|
||||
id = id,
|
||||
role = TargetedTransferRoleModel.Sender,
|
||||
senderEndpointId = "me",
|
||||
receiverEndpointId = peerId,
|
||||
manifestId = "manifest",
|
||||
|
||||
@@ -44,6 +44,8 @@ class SavedDeviceCoreContractBindingHygieneTest {
|
||||
assertTrue(
|
||||
source.contains("public expect fun `savedDeviceCapabilities`(): SavedDeviceCapabilities"),
|
||||
)
|
||||
assertTrue(source.contains("var `role`: TargetedTransferRole"))
|
||||
assertTrue(source.contains("public enum class TargetedTransferRole"))
|
||||
assertTrue(
|
||||
source.contains("SavedDevice"),
|
||||
"SavedDevice model must remain on the public surface",
|
||||
|
||||
Reference in New Issue
Block a user