package com.metservice.kanban.csv; import static org.apache.commons.lang.SystemUtils.LINE_SEPARATOR; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; 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 java.io.IOException; import java.io.StringReader; import java.util.List; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import com.metservice.kanban.model.WorkItem; import com.metservice.kanban.model.WorkItemType; public class KanbanCsvReaderTest { private static final String ESCAPED_QUOTATION_MARK_CHARACTER = "\"\"\"\""; @Test public void readsWorkItems() throws IOException { StringReader input = new StringReader("column names" + LINE_SEPARATOR + "work item 1" + LINE_SEPARATOR + "work item 2"); WorkItemParser parser = mock(WorkItemParser.class); when(parser.parseWorkItem(anyColumnNames(), anyStringArray())).thenAnswer(new Answer<WorkItem>() { @Override public WorkItem answer(InvocationOnMock invocation) throws Throwable { String[] row = (String[]) invocation.getArguments()[1]; String name = row[0]; return createWorkItem(name); } }); KanbanCsvReader reader = new KanbanCsvReader(input, parser); List<WorkItem> workItems = reader.read(); assertThat(workItems.get(0).getName(), is("work item 1")); assertThat(workItems.get(1).getName(), is("work item 2")); } @Test public void parsesQuotedCsv() throws IOException { StringReader input = new StringReader("column names" + LINE_SEPARATOR + ESCAPED_QUOTATION_MARK_CHARACTER); WorkItemParser parser = stubWorkItemParser(); KanbanCsvReader reader = new KanbanCsvReader(input, parser); reader.read(); ArgumentCaptor<String[]> rowCaptor = ArgumentCaptor.forClass(String[].class); verify(parser).parseWorkItem(anyColumnNames(), rowCaptor.capture()); String[] row = rowCaptor.getValue(); assertThat(row[0], is("\"")); } @Test public void parsesAllCells() throws IOException { StringReader input = new StringReader("column names" + LINE_SEPARATOR + "a,b,c"); WorkItemParser parser = stubWorkItemParser(); KanbanCsvReader reader = new KanbanCsvReader(input, parser); reader.read(); ArgumentCaptor<String[]> rowCaptor = ArgumentCaptor.forClass(String[].class); verify(parser).parseWorkItem(anyColumnNames(), rowCaptor.capture()); String[] row = rowCaptor.getValue(); assertThat(row[0], is("a")); assertThat(row[1], is("b")); assertThat(row[2], is("c")); } @Test public void passesColumnNamesToParser() throws IOException { StringReader input = new StringReader("column 1,column 2,column 3" + LINE_SEPARATOR + "work item 1" + LINE_SEPARATOR + "work item 2"); WorkItemParser parser = stubWorkItemParser(); KanbanCsvReader reader = new KanbanCsvReader(input, parser); reader.read(); ArgumentCaptor<CsvColumnNames> columnNamesCaptor = ArgumentCaptor.forClass(CsvColumnNames.class); verify(parser, times(2)).parseWorkItem(columnNamesCaptor.capture(), anyStringArray()); CsvColumnNames columnNames = columnNamesCaptor.getValue(); assertThat(columnNames.getColumnIndex("column 1"), is(0)); assertThat(columnNames.getColumnIndex("column 3"), is(2)); List<CsvColumnNames> columnNamesList = columnNamesCaptor.getAllValues(); assertTrue(columnNamesList.get(0) == columnNamesList.get(1)); } private WorkItemParser stubWorkItemParser() { WorkItemParser parser = mock(WorkItemParser.class); when(parser.parseWorkItem(anyColumnNames(), anyStringArray())).thenReturn(createWorkItem("work item")); return parser; } private WorkItem createWorkItem(String name) { WorkItem workItem = new WorkItem(0, 0, new WorkItemType("feature")); workItem.setName(name); return workItem; } private static CsvColumnNames anyColumnNames() { return Mockito.any(CsvColumnNames.class); } private static String[] anyStringArray() { return Mockito.any(String[].class); } }