diff --git a/flow-server/src/main/java/com/vaadin/flow/internal/StateNode.java b/flow-server/src/main/java/com/vaadin/flow/internal/StateNode.java index 97ae1dc1c19..7be5f3911e6 100644 --- a/flow-server/src/main/java/com/vaadin/flow/internal/StateNode.java +++ b/flow-server/src/main/java/com/vaadin/flow/internal/StateNode.java @@ -456,7 +456,10 @@ protected void prepareForResync() { stateNode.hasBeenAttached = false; stateNode.hasBeenDetached = false; }); - visitNodeTreeBottomUp(sn -> sn.fireAttachListeners(true)); + visitNodeTreeBottomUp(sn -> { + sn.hasBeenAttached = true; + sn.fireAttachListeners(true); + }); } /** diff --git a/flow-server/src/test/java/com/vaadin/flow/internal/StateTreeTest.java b/flow-server/src/test/java/com/vaadin/flow/internal/StateTreeTest.java index b012a99a2b9..604eeeb275e 100644 --- a/flow-server/src/test/java/com/vaadin/flow/internal/StateTreeTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/internal/StateTreeTest.java @@ -725,9 +725,13 @@ public void prepareForResync_nodeHasAttachAndDetachListeners_treeIsDirtyAndListe tree.collectChanges(c -> { }); Assert.assertEquals(0, tree.collectDirtyNodes().size()); + Assert.assertTrue(node2.isClientSideInitialized()); + Assert.assertTrue(node2.isAttached()); tree.getRootNode().prepareForResync(); + Assert.assertFalse(node2.isClientSideInitialized()); + Assert.assertTrue(node2.isAttached()); Assert.assertEquals(1, attachCount.get()); Assert.assertEquals(1, detachCount.get()); @@ -743,6 +747,16 @@ public void prepareForResync_nodeHasAttachAndDetachListeners_treeIsDirtyAndListe Assert.assertTrue( remaining.hasFeature(PushConfigurationParametersMap.class)); + tree.collectChanges(change -> { + }); + Assert.assertTrue(node2.isClientSideInitialized()); + + // Make sure detach listener is called when a resynced node is + // eventually detached + // In practice checks that node2.hasBeenAttached = true + node2.setParent(null); + Assert.assertEquals("Detach listener was not called on final detach", 2, + detachCount.get()); } @Test