Napraw synchronizację kursu w aplikacji kierowcy
This commit is contained in:
@@ -2,12 +2,27 @@ package pl.firmatpp.kierowca.data
|
||||
|
||||
import java.io.IOException
|
||||
import java.net.UnknownHostException
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertSame
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Assert.fail
|
||||
import org.junit.Test
|
||||
|
||||
class ApiErrorMapperTest {
|
||||
@Test
|
||||
fun rethrowsWorkerCancellationInsteadOfMappingItAsApplicationFailure() {
|
||||
val cancellation = CancellationException("Job was cancelled")
|
||||
|
||||
try {
|
||||
cancellation.rethrowIfCancellation()
|
||||
fail("CancellationException should be rethrown")
|
||||
} catch (thrown: CancellationException) {
|
||||
assertSame(cancellation, thrown)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mapsNetworkFailuresToRetryableOfflineMessage() {
|
||||
val error = ApiErrorMapper.map(IOException("timeout"))
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package pl.firmatpp.kierowca.data.upload
|
||||
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class OfflineOutboxManagerTest {
|
||||
@Test
|
||||
fun recognizesLegacyCancellationFailureDetails() {
|
||||
assertTrue(isWorkerCancellationFailure("Typ: błąd aplikacji\nKomunikat: Job was cancelled"))
|
||||
assertTrue(isWorkerCancellationFailure("kotlinx.coroutines.JobCancellationException"))
|
||||
assertFalse(isWorkerCancellationFailure("HTTP 422: Niepoprawne zdjęcie"))
|
||||
assertFalse(isWorkerCancellationFailure(null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun repairsInterruptedAndRetryablePhotoUploadsButNotRealPermanentFailures() {
|
||||
assertTrue(shouldRepairPhotoUpload(PhotoUploadStatus.Pending.storageValue, null))
|
||||
assertTrue(shouldRepairPhotoUpload(PhotoUploadStatus.Uploading.storageValue, null))
|
||||
assertTrue(shouldRepairPhotoUpload(PhotoUploadStatus.Verifying.storageValue, null))
|
||||
assertTrue(shouldRepairPhotoUpload(PhotoUploadStatus.FailedRetryable.storageValue, "timeout"))
|
||||
assertTrue(shouldRepairPhotoUpload(PhotoUploadStatus.FailedPermanent.storageValue, "Job was cancelled"))
|
||||
assertFalse(shouldRepairPhotoUpload(PhotoUploadStatus.FailedPermanent.storageValue, "HTTP 422"))
|
||||
assertFalse(shouldRepairPhotoUpload(PhotoUploadStatus.Cancelled.storageValue, null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun repairsInterruptedRouteActionWithItsOriginalIdempotencyKey() {
|
||||
assertTrue(shouldRepairRouteAction(RouteActionStatus.Pending, null))
|
||||
assertTrue(shouldRepairRouteAction(RouteActionStatus.WaitingForPhotos, null))
|
||||
assertTrue(shouldRepairRouteAction(RouteActionStatus.Syncing, null))
|
||||
assertTrue(shouldRepairRouteAction(RouteActionStatus.FailedRetryable, "timeout"))
|
||||
assertTrue(shouldRepairRouteAction(RouteActionStatus.FailedPermanent, "Job was cancelled"))
|
||||
assertTrue(
|
||||
shouldRepairRouteAction(
|
||||
RouteActionStatus.FailedPermanent,
|
||||
"Wymagane zdjęcie nie zostało wysłane. Popraw zdjęcie i ponów potwierdzenie etapu.",
|
||||
),
|
||||
)
|
||||
assertFalse(shouldRepairRouteAction(RouteActionStatus.FailedPermanent, "Brakuje zdjęcia"))
|
||||
assertFalse(shouldRepairRouteAction(RouteActionStatus.FailedConflict, "Kurs już rozpoczęty"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package pl.firmatpp.kierowca.data.upload
|
||||
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import pl.firmatpp.kierowca.data.model.RoutePhotoDto
|
||||
|
||||
class PhotoUploadReconciliationTest {
|
||||
@Test
|
||||
fun serverReceiptIdentityClearsFalseLocalFailure() {
|
||||
val upload = upload(
|
||||
clientRequestId = "request-1",
|
||||
contentSha256 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
)
|
||||
|
||||
assertTrue(serverPhotoConfirmsUpload(upload, serverPhoto("request-1", upload.contentSha256.uppercase())))
|
||||
assertFalse(serverPhotoConfirmsUpload(upload, serverPhoto("request-2", upload.contentSha256)))
|
||||
assertFalse(serverPhotoConfirmsUpload(upload, serverPhoto("request-1", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun legacyServerPhotoWithoutHashStillConfirmsMatchingRequestId() {
|
||||
val upload = upload("request-1", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
|
||||
|
||||
assertTrue(serverPhotoConfirmsUpload(upload, serverPhoto("request-1", null)))
|
||||
}
|
||||
|
||||
private fun upload(clientRequestId: String, contentSha256: String): PhotoUploadEntity =
|
||||
PhotoUploadEntity(
|
||||
clientRequestId = clientRequestId,
|
||||
routeId = "10",
|
||||
localPath = "/tmp/$clientRequestId.jpg",
|
||||
source = "camera",
|
||||
takenAt = null,
|
||||
latitude = null,
|
||||
longitude = null,
|
||||
locationAccuracyMeters = null,
|
||||
mimeType = "image/jpeg",
|
||||
size = 100,
|
||||
contentSha256 = contentSha256,
|
||||
status = PhotoUploadStatus.FailedPermanent.storageValue,
|
||||
lastError = "Typ: błąd aplikacji\nKomunikat: Job was cancelled",
|
||||
)
|
||||
|
||||
private fun serverPhoto(clientRequestId: String, contentSha256: String?): RoutePhotoDto =
|
||||
RoutePhotoDto(
|
||||
id = "42",
|
||||
routeId = "10",
|
||||
clientRequestId = clientRequestId,
|
||||
contentSha256 = contentSha256,
|
||||
source = "camera",
|
||||
stage = "loading",
|
||||
mimeType = "image/jpeg",
|
||||
size = 100,
|
||||
url = "https://example.test/photo/42",
|
||||
takenAt = null,
|
||||
latitude = null,
|
||||
longitude = null,
|
||||
locationAccuracyMeters = null,
|
||||
createdAt = null,
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user