Skip to content

Commit c1ed695

Browse files
authored
Merge pull request #176 from hotwired/fix-replace-visits
Maintain `replace` visit actions in the restore logic
2 parents 8ba14ae + 0fd1120 commit c1ed695

File tree

2 files changed

+90
-9
lines changed

2 files changed

+90
-9
lines changed

core/src/main/kotlin/dev/hotwire/core/turbo/session/Session.kt

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -623,25 +623,27 @@ class Session(
623623
// Private
624624

625625
private fun visitLocation(visit: Visit) {
626-
val restorationIdentifier = when (visit.options.action) {
627-
VisitAction.RESTORE -> restorationIdentifiers[visit.destinationIdentifier] ?: ""
628-
VisitAction.ADVANCE -> ""
629-
else -> ""
626+
val restorationIdentifier = if (visit.options.action == VisitAction.RESTORE) {
627+
restorationIdentifiers[visit.destinationIdentifier]
628+
} else {
629+
null
630630
}
631631

632-
val options = when (restorationIdentifier) {
633-
"" -> visit.options.copy(action = VisitAction.ADVANCE)
634-
else -> visit.options
632+
// Only initiate a restore visit if a restorationIdentifier is available
633+
val options = if (visit.options.action == VisitAction.RESTORE && restorationIdentifier == null) {
634+
visit.options.copy(action = VisitAction.ADVANCE)
635+
} else {
636+
visit.options
635637
}
636638

637639
logEvent(
638640
"visitLocation",
639641
"location" to visit.location,
640642
"options" to options,
641-
"restorationIdentifier" to restorationIdentifier
643+
"restorationIdentifier" to (restorationIdentifier ?: "")
642644
)
643645

644-
webView.visitLocation(visit.location, options, restorationIdentifier)
646+
webView.visitLocation(visit.location, options, restorationIdentifier ?: "")
645647
}
646648

647649
private fun visitLocationAsColdBoot(visit: Visit) {

core/src/test/kotlin/dev/hotwire/core/turbo/session/SessionTest.kt

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import dev.hotwire.core.turbo.errors.LoadError
1212
import dev.hotwire.core.turbo.errors.WebError
1313
import dev.hotwire.core.turbo.util.toJson
1414
import dev.hotwire.core.turbo.visit.Visit
15+
import dev.hotwire.core.turbo.visit.VisitAction
1516
import dev.hotwire.core.turbo.visit.VisitDestination
1617
import dev.hotwire.core.turbo.visit.VisitOptions
1718
import dev.hotwire.core.turbo.webview.HotwireWebView
@@ -290,6 +291,84 @@ class SessionTest : BaseRepositoryTest() {
290291
verify(callback, times(1)).visitCompleted(false)
291292
}
292293

294+
@Test
295+
fun `restore visit with restoration identifier uses restore visit`() {
296+
val visitIdentifier = "12345"
297+
val restorationIdentifier = "67890"
298+
val restoreVisit = visit.copy(
299+
options = VisitOptions(action = VisitAction.RESTORE)
300+
)
301+
302+
session.currentVisit = visit.copy(identifier = visitIdentifier)
303+
session.turboIsReady(true)
304+
session.pageLoaded(restorationIdentifier)
305+
session.visit(restoreVisit)
306+
307+
verify(webView, times(1)).visitLocation(
308+
location = restoreVisit.location,
309+
options = restoreVisit.options,
310+
restorationIdentifier = "67890"
311+
)
312+
}
313+
314+
@Test
315+
fun `restore visit with no restoration identifier uses advance visit`() {
316+
val visitIdentifier = "12345"
317+
val restoreVisit = visit.copy(
318+
options = VisitOptions(action = VisitAction.RESTORE)
319+
)
320+
321+
session.currentVisit = visit.copy(identifier = visitIdentifier)
322+
session.turboIsReady(true)
323+
session.visit(restoreVisit)
324+
325+
verify(webView, times(1)).visitLocation(
326+
location = restoreVisit.location,
327+
options = restoreVisit.options.copy(action = VisitAction.ADVANCE),
328+
restorationIdentifier = ""
329+
)
330+
}
331+
332+
@Test
333+
fun `advance visit does not use restoration identifier`() {
334+
val visitIdentifier = "12345"
335+
val restorationIdentifier = "67890"
336+
val advanceVisit = visit.copy(
337+
options = VisitOptions(action = VisitAction.ADVANCE)
338+
)
339+
340+
session.currentVisit = visit.copy(identifier = visitIdentifier)
341+
session.turboIsReady(true)
342+
session.pageLoaded(restorationIdentifier)
343+
session.visit(advanceVisit)
344+
345+
verify(webView, times(1)).visitLocation(
346+
location = advanceVisit.location,
347+
options = advanceVisit.options,
348+
restorationIdentifier = ""
349+
)
350+
}
351+
352+
@Test
353+
fun `replace visit does not use restoration identifier`() {
354+
val visitIdentifier = "12345"
355+
val restorationIdentifier = "67890"
356+
val replaceVisit = visit.copy(
357+
options = VisitOptions(action = VisitAction.REPLACE)
358+
)
359+
360+
session.currentVisit = visit.copy(identifier = visitIdentifier)
361+
session.turboIsReady(true)
362+
session.pageLoaded(restorationIdentifier)
363+
session.visit(replaceVisit)
364+
365+
verify(webView, times(1)).visitLocation(
366+
location = replaceVisit.location,
367+
options = replaceVisit.options,
368+
restorationIdentifier = ""
369+
)
370+
}
371+
293372
@Test
294373
fun `restore current visit fails with session not ready`() {
295374
val visitIdentifier = "12345"

0 commit comments

Comments
 (0)