Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e7dd231a authored by Hari's avatar Hari
Browse files

Fix tests

parent 81f85c69
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -524,7 +524,7 @@ public class ImapFolder extends Folder<ImapMessage> {
                .build();
        try {
            UidSearchResponse searchResponse = connection.executeSelectedStateCommand(searchCommand);
            return getMessages(searchResponse, null);
            return getMessages(searchResponse, listener);
        } catch (IOException ioe) {
            throw ioExceptionHandler(connection, ioe);
        }
@@ -580,7 +580,7 @@ public class ImapFolder extends Folder<ImapMessage> {
                .build();
        try {
            UidSearchResponse searchResponse = connection.executeSelectedStateCommand(searchCommand);
            return getMessages(searchResponse, null);
            return getMessages(searchResponse, listener);
        } catch (IOException ioe) {
            throw ioExceptionHandler(connection, ioe);
        }
+79 −83
Original line number Diff line number Diff line
package com.fsck.k9.mail.store.imap;


import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

import com.fsck.k9.mail.Body;
import com.fsck.k9.mail.DefaultBodyFactory;
import com.fsck.k9.mail.FetchProfile;
@@ -16,7 +26,12 @@ import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.internet.BinaryTempFileBody;
import com.fsck.k9.mail.internet.MimeHeader;
import com.fsck.k9.mail.store.StoreConfig;

import com.fsck.k9.mail.store.imap.selectedstate.command.FolderSelectedStateCommand;
import com.fsck.k9.mail.store.imap.selectedstate.command.UidCopyCommand;
import com.fsck.k9.mail.store.imap.selectedstate.command.UidSearchCommand;
import com.fsck.k9.mail.store.imap.selectedstate.response.UidCopyResponse;
import com.fsck.k9.mail.store.imap.selectedstate.response.UidSearchResponse;
import okio.Buffer;
import org.apache.james.mime4j.util.MimeUtil;
import org.junit.Before;
import org.junit.Test;
@@ -26,18 +41,6 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.robolectric.RuntimeEnvironment;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

import okio.Buffer;

import static com.fsck.k9.mail.Folder.OPEN_MODE_RO;
import static com.fsck.k9.mail.Folder.OPEN_MODE_RW;
import static com.fsck.k9.mail.store.imap.ImapResponseHelper.createImapResponse;
@@ -52,6 +55,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -66,6 +70,7 @@ public class ImapFolderTest {
    private ImapStore imapStore;
    private ImapConnection imapConnection;
    private StoreConfig storeConfig;
    private ArgumentCaptor<? extends FolderSelectedStateCommand> commandCaptor;

    @Before
    public void setUp() throws Exception {
@@ -77,6 +82,7 @@ public class ImapFolderTest {
        when(imapStore.getStoreConfig()).thenReturn(storeConfig);

        imapConnection = mock(ImapConnection.class);
        commandCaptor = ArgumentCaptor.forClass(FolderSelectedStateCommand.class);
    }

    @Test
@@ -330,10 +336,7 @@ public class ImapFolderTest {
        prepareImapFolderForOpen(OPEN_MODE_RW);
        ImapFolder destinationFolder = createFolder("Destination");
        List<ImapMessage> messages = singletonList(createImapMessage("1"));
        List<ImapResponse> copyResponses = singletonList(
                createImapResponse("x OK [COPYUID 23 1 101] Success")
        );
        when(imapConnection.executeSimpleCommand("UID COPY 1 \"Destination\"")).thenReturn(copyResponses);
        setupCopyResponse("x OK [COPYUID 23 1 101] Success");
        sourceFolder.open(OPEN_MODE_RW);

        Map<String, String> uidMapping = sourceFolder.copyMessages(messages, destinationFolder);
@@ -348,10 +351,7 @@ public class ImapFolderTest {
        prepareImapFolderForOpen(OPEN_MODE_RW);
        ImapFolder destinationFolder = createFolder("Destination");
        List<ImapMessage> messages = singletonList(createImapMessage("1"));
        List<ImapResponse> copyResponses = singletonList(
                createImapResponse("x OK [COPYUID 23 1 101] Success")
        );
        when(imapConnection.executeSimpleCommand("UID COPY 1 \"Destination\"")).thenReturn(copyResponses);
        setupCopyResponse("x OK [COPYUID 23 1 101] Success");
        sourceFolder.open(OPEN_MODE_RW);

        Map<String, String> uidMapping = sourceFolder.moveMessages(messages, destinationFolder);
@@ -366,15 +366,11 @@ public class ImapFolderTest {
        prepareImapFolderForOpen(OPEN_MODE_RW);
        ImapFolder destinationFolder = createFolder("Destination");
        List<ImapMessage> messages = singletonList(createImapMessage("1"));
        List<ImapResponse> copyResponses = singletonList(
                createImapResponse("x OK [COPYUID 23 1 101] Success")
        );
        when(imapConnection.executeSimpleCommand("UID COPY 1 \"Destination\"")).thenReturn(copyResponses);
        sourceFolder.open(OPEN_MODE_RW);

        sourceFolder.moveMessages(messages, destinationFolder);

        verify(imapConnection).executeSimpleCommand("UID STORE 1 +FLAGS.SILENT (\\Deleted)");
        assertCommandIssued("UID STORE 1 +FLAGS.SILENT (\\Deleted)");
    }

    @Test
@@ -407,7 +403,7 @@ public class ImapFolderTest {

        folder.delete(messages, "Folder");

        verify(imapConnection).executeSimpleCommand("UID STORE 23 +FLAGS.SILENT (\\Deleted)");
        assertCommandIssued("UID STORE 23 +FLAGS.SILENT (\\Deleted)");
    }

    @Test
@@ -417,15 +413,12 @@ public class ImapFolderTest {
        ImapFolder trashFolder = createFolder("Trash");
        when(imapStore.getFolder("Trash")).thenReturn(trashFolder);
        List<ImapMessage> messages = singletonList(createImapMessage("2"));
        List<ImapResponse> copyResponses = singletonList(
                createImapResponse("x OK [COPYUID 23 2 102] Success")
        );
        when(imapConnection.executeSimpleCommand("UID COPY 2 \"Trash\"")).thenReturn(copyResponses);
        setupCopyResponse("x OK [COPYUID 23 2 102] Success");
        folder.open(OPEN_MODE_RW);

        folder.delete(messages, "Trash");

        verify(imapConnection).executeSimpleCommand("UID STORE 2 +FLAGS.SILENT (\\Deleted)");
        assertCommandIssued("UID STORE 2 +FLAGS.SILENT (\\Deleted)");
    }

    @Test
@@ -465,7 +458,7 @@ public class ImapFolderTest {
    public void getUnreadMessageCount_connectionThrowsIOException_shouldThrowMessagingException() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        when(imapConnection.executeSimpleCommand("UID SEARCH 1:* NOT SEEN NOT DELETED")).thenThrow(new IOException());
        when(imapConnection.executeSelectedStateCommand(any(UidSearchCommand.class))).thenThrow(new IOException());
        folder.open(OPEN_MODE_RW);

        try {
@@ -480,8 +473,7 @@ public class ImapFolderTest {
    public void getUnreadMessageCount() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 1 2 3"));
        when(imapConnection.executeSimpleCommand("UID SEARCH 1:* NOT SEEN NOT DELETED")).thenReturn(imapResponses);
        setupSearchResponse("* SEARCH 1 2 3");
        folder.open(OPEN_MODE_RW);

        int unreadMessageCount = folder.getUnreadMessageCount();
@@ -506,11 +498,7 @@ public class ImapFolderTest {
    public void getFlaggedMessageCount() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        List<ImapResponse> imapResponses = asList(
                createImapResponse("* SEARCH 1 2"),
                createImapResponse("* SEARCH 23 42")
        );
        when(imapConnection.executeSimpleCommand("UID SEARCH 1:* FLAGGED NOT DELETED")).thenReturn(imapResponses);
        setupSearchResponse("* SEARCH 1 2", "* SEARCH 23 42");
        folder.open(OPEN_MODE_RW);

        int flaggedMessageCount = folder.getFlaggedMessageCount();
@@ -522,8 +510,7 @@ public class ImapFolderTest {
    public void getHighestUid() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 42"));
        when(imapConnection.executeSimpleCommand("UID SEARCH *:*")).thenReturn(imapResponses);
        setupSearchResponse("* SEARCH 42");
        folder.open(OPEN_MODE_RW);

        long highestUid = folder.getHighestUid();
@@ -535,7 +522,8 @@ public class ImapFolderTest {
    public void getHighestUid_imapConnectionThrowsNegativesResponse_shouldReturnMinusOne() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        doThrow(NegativeImapResponseException.class).when(imapConnection).executeSimpleCommand("UID SEARCH *:*");
        doThrow(NegativeImapResponseException.class).when(imapConnection)
                .executeSelectedStateCommand(any(UidSearchCommand.class));
        folder.open(OPEN_MODE_RW);

        long highestUid = folder.getHighestUid();
@@ -547,7 +535,7 @@ public class ImapFolderTest {
    public void getHighestUid_imapConnectionThrowsIOException_shouldThrowMessagingException() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        doThrow(IOException.class).when(imapConnection).executeSimpleCommand("UID SEARCH *:*");
        doThrow(IOException.class).when(imapConnection).executeSelectedStateCommand(any(UidSearchCommand.class));
        folder.open(OPEN_MODE_RW);

        try {
@@ -562,12 +550,7 @@ public class ImapFolderTest {
    public void getMessages_withoutDateConstraint() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        List<ImapResponse> imapResponses = asList(
                createImapResponse("* SEARCH 3"),
                createImapResponse("* SEARCH 5"),
                createImapResponse("* SEARCH 6")
        );
        when(imapConnection.executeSimpleCommand("UID SEARCH 1:10 NOT DELETED")).thenReturn(imapResponses);
        setupSearchResponse("* SEARCH 3", "* SEARCH 5", "* SEARCH 6");
        folder.open(OPEN_MODE_RW);

        List<ImapMessage> messages = folder.getMessages(1, 10, null, null);
@@ -581,12 +564,7 @@ public class ImapFolderTest {
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        List<ImapResponse> imapResponses = asList(
                createImapResponse("* SEARCH 47"),
                createImapResponse("* SEARCH 18")
        );
        when(imapConnection.executeSimpleCommand("UID SEARCH 1:10 SINCE 06-Feb-2016 NOT DELETED"))
                .thenReturn(imapResponses);
        setupSearchResponse("* SEARCH 47", "* SEARCH 18");
        folder.open(OPEN_MODE_RW);

        List<ImapMessage> messages = folder.getMessages(1, 10, new Date(1454719826000L), null);
@@ -599,8 +577,7 @@ public class ImapFolderTest {
    public void getMessages_withListener_shouldCallListener() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 99"));
        when(imapConnection.executeSimpleCommand("UID SEARCH 1:10 NOT DELETED")).thenReturn(imapResponses);
        setupSearchResponse("* SEARCH 99");
        folder.open(OPEN_MODE_RW);
        MessageRetrievalListener<ImapMessage> listener = createMessageRetrievalListener();

@@ -678,13 +655,7 @@ public class ImapFolderTest {
    public void getMessages_sequenceNumbers() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        List<ImapResponse> imapResponses = asList(
                createImapResponse("* SEARCH 17"),
                createImapResponse("* SEARCH 18"),
                createImapResponse("* SEARCH 49")
        );
        when(imapConnection.executeSimpleCommand("UID SEARCH 5,1:2 NOT DELETED"))
                .thenReturn(imapResponses);
        setupSearchResponse("* SEARCH 17", "* SEARCH 18", "* SEARCH 49");
        folder.open(OPEN_MODE_RW);

        List<ImapMessage> messages = folder.getMessages(newSet(1L, 2L, 5L), false, null);
@@ -697,8 +668,7 @@ public class ImapFolderTest {
    public void getMessages_sequenceNumbers_withListener_shouldCallListener() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 99"));
        when(imapConnection.executeSimpleCommand("UID SEARCH 1")).thenReturn(imapResponses);
        setupSearchResponse("* SEARCH 99");
        folder.open(OPEN_MODE_RW);
        MessageRetrievalListener<ImapMessage> listener = createMessageRetrievalListener();

@@ -727,12 +697,7 @@ public class ImapFolderTest {
    public void getMessagesFromUids() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        List<ImapResponse> imapResponses = asList(
                createImapResponse("* SEARCH 11"),
                createImapResponse("* SEARCH 22"),
                createImapResponse("* SEARCH 25")
        );
        when(imapConnection.executeSimpleCommand("UID SEARCH UID 11,22,25")).thenReturn(imapResponses);
        setupSearchResponse("* SEARCH 11", "* SEARCH 22", "* SEARCH 25");
        folder.open(OPEN_MODE_RW);

        List<ImapMessage> messages = folder.getMessagesFromUids(asList("11", "22", "25"));
@@ -758,8 +723,7 @@ public class ImapFolderTest {
    public void areMoreMessagesAvailable_withAdditionalMessages_shouldReturnTrue() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        List<ImapResponse> imapResponses = singletonList(createImapResponse("* SEARCH 42"));
        when(imapConnection.executeSimpleCommand("UID SEARCH 1:9 NOT DELETED")).thenReturn(imapResponses);
        setupSearchResponse("* SEARCH 42");
        folder.open(OPEN_MODE_RW);

        boolean areMoreMessagesAvailable = folder.areMoreMessagesAvailable(10, null);
@@ -771,6 +735,7 @@ public class ImapFolderTest {
    public void areMoreMessagesAvailable_withoutAdditionalMessages_shouldReturnFalse() throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        setupSearchResponse("1 OK SEARCH completed");
        folder.open(OPEN_MODE_RW);

        boolean areMoreMessagesAvailable = folder.areMoreMessagesAvailable(600, null);
@@ -796,12 +761,13 @@ public class ImapFolderTest {
            throws Exception {
        ImapFolder folder = createFolder("Folder");
        prepareImapFolderForOpen(OPEN_MODE_RW);
        setupSearchResponse("1 OK SEARCH Completed");
        folder.open(OPEN_MODE_RW);

        folder.areMoreMessagesAvailable(600, null);

        verify(imapConnection).executeSimpleCommand("UID SEARCH 100:599 NOT DELETED");
        verify(imapConnection).executeSimpleCommand("UID SEARCH 1:99 NOT DELETED");
        assertCommandIssued("UID SEARCH 100:599 NOT DELETED");
        assertCommandIssued("UID SEARCH 1:99 NOT DELETED");
    }

    @Test
@@ -1008,10 +974,11 @@ public class ImapFolderTest {
        folder.open(OPEN_MODE_RW);
        ImapMessage message = createImapMessage("2");
        when(message.getHeader("Message-ID")).thenReturn(new String[] { "<00000000.0000000@example.org>" });
        setupSearchResponse("1 OK SEARCH Completed");

        folder.getUidFromMessageId(message);

        verify(imapConnection).executeSimpleCommand("UID SEARCH HEADER MESSAGE-ID \"<00000000.0000000@example.org>\"");
        assertCommandIssued("UID SEARCH HEADER MESSAGE-ID \"<00000000.0000000@example.org>\"");
    }

    @Test
@@ -1021,8 +988,7 @@ public class ImapFolderTest {
        folder.open(OPEN_MODE_RW);
        ImapMessage message = createImapMessage("2");
        when(message.getHeader("Message-ID")).thenReturn(new String[] { "<00000000.0000000@example.org>" });
        when(imapConnection.executeSimpleCommand("UID SEARCH HEADER MESSAGE-ID \"<00000000.0000000@example.org>\""))
                .thenReturn(singletonList(createImapResponse("* SEARCH 23")));
        setupSearchResponse("* SEARCH 23");

        String uid = folder.getUidFromMessageId(message);

@@ -1046,7 +1012,7 @@ public class ImapFolderTest {

        folder.setFlags(newSet(Flag.SEEN), true);

        verify(imapConnection).executeSimpleCommand("UID STORE 1:* +FLAGS.SILENT (\\Seen)");
        assertCommandIssued("UID STORE 1:* +FLAGS.SILENT (\\Seen)");
    }

    @Test
@@ -1077,10 +1043,11 @@ public class ImapFolderTest {
        prepareImapFolderForOpen(OPEN_MODE_RO);
        when(storeConfig.allowRemoteSearch()).thenReturn(true);
        when(storeConfig.isRemoteSearchFullText()).thenReturn(true);
        setupSearchResponse("1 OK SEARCH completed");

        folder.search("query", newSet(Flag.SEEN), Collections.<Flag>emptySet());

        verify(imapConnection).executeSimpleCommand("UID SEARCH TEXT \"query\" SEEN");
        assertCommandIssued("UID SEARCH TEXT \"query\" SEEN");
    }

    @Test
@@ -1089,10 +1056,11 @@ public class ImapFolderTest {
        prepareImapFolderForOpen(OPEN_MODE_RO);
        when(storeConfig.allowRemoteSearch()).thenReturn(true);
        when(storeConfig.isRemoteSearchFullText()).thenReturn(false);
        setupSearchResponse("1 OK SEARCH completed");

        folder.search("query", Collections.<Flag>emptySet(), Collections.<Flag>emptySet());

        verify(imapConnection).executeSimpleCommand("UID SEARCH OR SUBJECT \"query\" FROM \"query\"");
        assertCommandIssued("UID SEARCH OR SUBJECT \"query\" FROM \"query\"");
    }

    @Test
@@ -1243,4 +1211,32 @@ public class ImapFolderTest {
    private void assertCheckOpenErrorMessage(String folderName, MessagingException e) {
        assertEquals("Folder " + folderName + " is not open.", e.getMessage());
    }

    @SuppressWarnings("unchecked")
    private void assertCommandIssued(String command) throws MessagingException, IOException {
        verify(imapConnection, atLeastOnce()).executeSelectedStateCommand(commandCaptor.capture());
        List<? extends FolderSelectedStateCommand> issuedCommands = commandCaptor.getAllValues();
        List<String> stringCommands = new ArrayList<>(issuedCommands.size());
        for (FolderSelectedStateCommand issuedCommand : issuedCommands) {
            stringCommands.addAll(issuedCommand.optimizeAndSplit(false));
        }
        assertEquals(stringCommands.contains(command), true);
    }

    private void setupSearchResponse(String... responses) throws MessagingException, IOException {
        List<ImapResponse> imapResponses = new ArrayList<>(responses.length);
        for (String response : responses) {
            imapResponses.add(createImapResponse(response));
        }
        UidSearchResponse searchResponse = UidSearchResponse.parse(singletonList(imapResponses));
        when(imapConnection.executeSelectedStateCommand(any(UidSearchCommand.class)))
                .thenReturn(searchResponse);
    }

    private void setupCopyResponse(String response) throws MessagingException, IOException {
        List<ImapResponse> imapResponse = singletonList(createImapResponse(response));
        UidCopyResponse uidCopyResponse = UidCopyResponse.parse(singletonList(imapResponse));
        when(imapConnection.executeSelectedStateCommand(any(UidCopyCommand.class)))
                .thenReturn(uidCopyResponse);
    }
}
+9 −12
Original line number Diff line number Diff line
package com.fsck.k9.mail.store.imap.selectedstate.command;


import java.util.Collections;
import java.util.List;

import com.fsck.k9.mail.store.imap.ImapConnection;
import com.fsck.k9.mail.store.imap.ImapFolder;
import com.fsck.k9.mail.store.imap.ImapResponseHelper;
import org.junit.Before;
import org.junit.Test;

import java.util.Collections;

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.internal.util.collections.Sets.newSet;

@@ -80,21 +77,21 @@ public class FolderSelectedStateCommandTest {
    }

    @Test
    public void executeInternal_withShortCommand_shouldNotSplitCommand() throws Exception {
    public void optimizeAndSplit_withShortCommand_shouldNotSplitCommand() throws Exception {
        TestCommand command = TestCommand.createWithIdSet(newSet(1L, 2L, 3L));

        command.executeInternal(imapConnection, imapFolder);
        List<String> splitCommands = command.optimizeAndSplit(false);

        verify(imapFolder, times(1)).executeSimpleCommand(anyString());
        assertEquals(splitCommands.size(), 1);
    }

    @Test
    public void executeInternal_withLongCommand_shouldSplitCommand() throws Exception {
    public void optimizeAndSplit_withLongCommand_shouldSplitCommand() throws Exception {
        TestCommand command = TestCommand.createWithIdSet(ImapResponseHelper
                .createNonContiguousIdSet(10000L, 10500L, 2));

        command.executeInternal(imapConnection, imapFolder);
        List<String> splitCommands = command.optimizeAndSplit(false);

        verify(imapFolder, atLeast(2)).executeSimpleCommand(anyString());
        assertEquals(splitCommands.size(), 2);
    }
}
+10 −1
Original line number Diff line number Diff line
package com.fsck.k9.mail.store.imap.selectedstate.command;

import java.util.Collections;
import java.util.List;
import java.util.Set;

class TestCommand extends FolderSelectedStateCommand {
import com.fsck.k9.mail.store.imap.selectedstate.response.SelectedStateResponse;


class TestCommand extends FolderSelectedStateCommand<SelectedStateResponse> {

    private TestCommand(Set<Long> ids) {
        super(ids);
@@ -14,6 +18,11 @@ class TestCommand extends FolderSelectedStateCommand {
        return String.format("TEST %s", createCombinedIdString()).trim();
    }

    @Override
    public SelectedStateResponse parseResponses(List unparsedResponses) {
        return null;
    }

    static TestCommand createWithIdSetAndGroup(Set<Long> ids, Long start, Long end) {
        TestCommand command = new TestCommand(ids);
        command.addIdGroup(start, end);