@Test
    public void testDeleteAffiliationAfterCreateDifferentAffiliation() throws Exception
    {
        // Setup test fixture.
        final CachingPubsubPersistenceProvider provider = new CachingPubsubPersistenceProvider();
        final Node mockNode = Mockito.mock(Node.class);
        Mockito.lenient().when(mockNode.getUniqueIdentifier()).thenReturn(new Node.UniqueIdentifier("mock-service-1", "mock-node-a"));
        final JID firstAffiliateAddress = new JID("test-user-1", "example.org", null);
        final NodeAffiliate firstAffiliate = new NodeAffiliate(mockNode, firstAffiliateAddress);
        final NodeAffiliate.Affiliation firstAffiliation = NodeAffiliate.Affiliation.publisher;
        firstAffiliate.setAffiliation(firstAffiliation);
        final JID secondAffiliateAddress = new JID("test-user-2", "example.org", null);
        final NodeAffiliate secondAffiliate = new NodeAffiliate(mockNode, secondAffiliateAddress);
        final NodeAffiliate.Affiliation secondAffiliation = NodeAffiliate.Affiliation.outcast;
        secondAffiliate.setAffiliation(secondAffiliation);

        // Execute system under test.
        provider.createAffiliation(mockNode, firstAffiliate);
        provider.removeAffiliation(mockNode, secondAffiliate);

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

        final CachingPubsubPersistenceProvider.NodeOperation firstNodeOperation = pending.get(0);
        assertEquals(mockNode.getUniqueIdentifier(), firstNodeOperation.node.getUniqueIdentifier());
        assertEquals(CachingPubsubPersistenceProvider.NodeOperation.Action.CREATE_AFFILIATION, firstNodeOperation.action);
        assertEquals(firstAffiliateAddress, firstNodeOperation.affiliate.getJID());
        assertEquals(firstAffiliation, firstNodeOperation.affiliate.getAffiliation());
        assertNull(firstNodeOperation.subscription);

        final CachingPubsubPersistenceProvider.NodeOperation secondNodeOperation = pending.get(1);
        assertEquals(mockNode.getUniqueIdentifier(), secondNodeOperation.node.getUniqueIdentifier());
        assertEquals(CachingPubsubPersistenceProvider.NodeOperation.Action.REMOVE_AFFILIATION, secondNodeOperation.action);
        assertEquals(secondAffiliateAddress, secondNodeOperation.affiliate.getJID());
        assertEquals(secondAffiliation, secondNodeOperation.affiliate.getAffiliation());
        assertNull(secondNodeOperation.subscription);

        assertEquals(0, provider.itemsPending.size());
        assertEquals(0, provider.itemsToAdd.size());
        assertEquals(0, provider.itemsToDelete.size());
    }
Executes a test that, through {@link CachingPubsubPersistenceProvider#createAffiliation(Node, NodeAffiliate)}
and {@link CachingPubsubPersistenceProvider#removeAffiliation(Node, NodeAffiliate)} creates an affiliation, and
then removes a different affiliation.

As these operations relate to two different affiliations, the caching provider MUST NOT optimize these two
operations (where the 'net effect' of them would be to have no operation).

Therefor, this test asserts that after both invocations, two operations are scheduled.
xmppserver/src/test/java/org/jivesoftware/openfire/pubsub/CachingPubsubPersistenceProviderAffiliationOperationsTest.java