@Test
    public void testUpdateNodeTwice() throws Exception
    {
        // Setup test fixture.
        final CachingPubsubPersistenceProvider provider = new CachingPubsubPersistenceProvider();
        final Node mockOrigNode = Mockito.mock(Node.class);
        Mockito.lenient().when(mockOrigNode.getUniqueIdentifier()).thenReturn(new Node.UniqueIdentifier("mock-service-1", "mock-node-a"));
        Mockito.lenient().when(mockOrigNode.getCreationDate()).thenReturn(new Date(0));
        final Node mockReplaceNode = Mockito.mock(Node.class);
        Mockito.lenient().when(mockReplaceNode.getUniqueIdentifier()).thenReturn(new Node.UniqueIdentifier("mock-service-1", "mock-node-a"));
        Mockito.lenient().when(mockReplaceNode.getCreationDate()).thenReturn(new Date(1));

        // Execute system under test.
        provider.updateNode(mockOrigNode);
        provider.updateNode(mockReplaceNode);

        // Verify results.
        final List<CachingPubsubPersistenceProvider.NodeOperation> pending = provider.nodesToProcess.computeIfAbsent(mockOrigNode.getUniqueIdentifier(), id -> new ArrayList<>());
        assertEquals(1, pending.size());

        final CachingPubsubPersistenceProvider.NodeOperation nodeOperation = pending.get(0);
        assertEquals(mockReplaceNode.getUniqueIdentifier(), nodeOperation.node.getUniqueIdentifier());
        assertNotEquals(new Date(0), nodeOperation.node.getCreationDate());
        assertEquals(CachingPubsubPersistenceProvider.NodeOperation.Action.UPDATE, nodeOperation.action);
        assertNull(nodeOperation.subscription);
        assertNull(nodeOperation.affiliate);

        assertEquals(0, provider.itemsPending.size());
        assertEquals(0, provider.itemsToAdd.size());
        assertEquals(0, provider.itemsToDelete.size());
    }
Executes a test that, through {@link CachingPubsubPersistenceProvider#updateNode(Node)} attempts to update the
same node 'twice'.

Updates of a node are never partial. This allows the caching provider to optimize two sequential updates.

Therefor, this test asserts that after each invocation, only one operation, corresponding to the last update, is
scheduled.
xmppserver/src/test/java/org/jivesoftware/openfire/pubsub/CachingPubsubPersistenceProviderNodeOperationsTest.java