@Test
    public void testRemoveAndSavePublishedItem() throws Exception
    {
        // Setup test fixture.
        final CachingPubsubPersistenceProvider provider = new CachingPubsubPersistenceProvider();
        final LeafNode mockNode = Mockito.mock(LeafNode.class);
        Mockito.lenient().when(mockNode.getUniqueIdentifier()).thenReturn(new Node.UniqueIdentifier("mock-service-1", "mock-node-a"));
        final JID publisher = new JID("test-user-1", "example.org", null);
        final PublishedItem item = new PublishedItem(mockNode, publisher, UUID.randomUUID().toString(), new Date());

        // Execute system under test.
        provider.removePublishedItem(item);
        provider.savePublishedItem(item);

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

        assertEquals(1, provider.itemsToAdd.size());
        assertEquals(0, provider.itemsToDelete.size());
    }
Asserts that an invocation of {@link CachingPubsubPersistenceProvider#removePublishedItem(PublishedItem)} followed
by an invocation of {@link CachingPubsubPersistenceProvider#savePublishedItem(PublishedItem)} to represent
removal and then creation of the same item causes the provider to optimize: the removal can be discarded.

Note that the XML content can be different in both items. The latter save will still overwrite what would've been
otherwise explicitly been deleted first.
xmppserver/src/test/java/org/jivesoftware/openfire/pubsub/CachingPubsubPersistenceProviderItemOperationsTest.java