/* * JBoss, Home of Professional Open Source * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors * as indicated by the @authors tag. All rights reserved. */ package org.jboss.elasticsearch.river.jira; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.TimeZone; import junit.framework.Assert; import org.apache.http.NameValuePair; import org.elasticsearch.common.logging.ESLoggerFactory; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.river.RiverName; import org.junit.Test; import org.mockito.Mockito; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.when; /** * Unit test for {@link JIRA5RestClient}. * * @author Vlastimil Elias (velias at redhat dot com) */ public class JIRA5RestClientTest { /** * URL used for JIRA5RestClient constructor in unit tests. */ protected static final String TEST_JIRA_URL = "https://issues.jboss.org"; /** * Date formatter used to prepare {@link Date} instances for tests */ protected SimpleDateFormat JQL_TEST_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm"); protected TimeZone JQL_TEST_TIMEZONE = TimeZone.getTimeZone("GMT"); { JQL_TEST_DATE_FORMAT.setTimeZone(JQL_TEST_TIMEZONE); } /** * Main method used to run integration tests with real JIRA call. * * @param args not used * @throws Exception */ public static void main(String[] args) throws Exception { String username = null; String pwd = null; IJIRAClient tested = new JIRA5RestClient(mockEsIntegrationComponent(), "https://issues.jboss.org", username, pwd, 50000, null); // List<String> projects = tested.getAllJIRAProjects(); // System.out.println(projects); ChangedIssuesResults ret = tested.getJIRAChangedIssues("ORG", 0, DateTimeUtils.parseISODateTime("2014-09-01T01:00:00Z"), null); System.out.println("total: " + ret.getTotal()); // System.out.println(ret); } @Test public void constructor() { try { new JIRA5RestClient(mockEsIntegrationComponent(), null, null, null, 5000, null); Assert.fail("SettingsException not thrown"); } catch (SettingsException e) { // OK } try { new JIRA5RestClient(mockEsIntegrationComponent(), " ", null, null, 5000, null); Assert.fail("SettingsException not thrown"); } catch (SettingsException e) { // OK } try { new JIRA5RestClient(mockEsIntegrationComponent(), "nonsenseUrl", null, null, 5000, null); Assert.fail("SettingsException not thrown"); } catch (SettingsException e) { // OK } IESIntegration esMock = mockEsIntegrationComponent(); JIRA5RestClient tested = new JIRA5RestClient(esMock, "http://issues.jboss.org", null, null, 5000, null); Mockito.verify(esMock).createLogger(JIRA5RestClient.class); Assert.assertEquals(JIRA5RestClient.prepareAPIURLFromBaseURL("http://issues.jboss.org", null), tested.jiraRestAPIUrlBase); tested = new JIRA5RestClient(mockEsIntegrationComponent(), TEST_JIRA_URL, null, null, 5000, "latest"); Assert.assertEquals(JIRA5RestClient.prepareAPIURLFromBaseURL(TEST_JIRA_URL, "latest"), tested.jiraRestAPIUrlBase); Assert.assertFalse(tested.isAuthConfigured); tested = new JIRA5RestClient(mockEsIntegrationComponent(), TEST_JIRA_URL, "", "pwd", 5000, null); Assert.assertFalse(tested.isAuthConfigured); tested = new JIRA5RestClient(mockEsIntegrationComponent(), TEST_JIRA_URL, "uname", "pwd", 5000, null); Assert.assertTrue(tested.isAuthConfigured); } @Test public void getAllJIRAProjects() throws Exception { IJIRAClient tested = new JIRA5RestClient(mockEsIntegrationComponent(), TEST_JIRA_URL, null, null, 5000, null) { @Override protected byte[] performJIRAGetRESTCall(String restOperation, List<NameValuePair> params) throws Exception { Assert.assertEquals("project", restOperation); Assert.assertNull(params); return ("[{\"key\": \"ORG\", \"name\": \"ORG project\"},{\"key\": \"PPP\"}]").getBytes("UTF-8"); }; }; List<String> ret = tested.getAllJIRAProjects(); Assert.assertNotNull(ret); Assert.assertEquals(2, ret.size()); Assert.assertTrue(ret.contains("ORG")); Assert.assertTrue(ret.contains("PPP")); } @Test public void getJIRAChangedIssues() throws Exception { final Date ua = new Date(); final Date ub = new Date(); IJIRAClient tested = new JIRA5RestClient(mockEsIntegrationComponent(), TEST_JIRA_URL, null, null, 5000, null) { @Override protected byte[] performJIRAChangedIssuesREST(String projectKey, int startAt, Date updatedAfter, Date updatedBefore) throws Exception { Assert.assertEquals("ORG", projectKey); Assert.assertEquals(ua, updatedAfter); Assert.assertEquals(ub, updatedBefore); Assert.assertEquals(10, startAt); return "{\"startAt\": 5, \"maxResults\" : 10, \"total\" : 50, \"issues\" : [{\"key\" : \"ORG-45\"}]}" .getBytes("UTF-8"); }; }; ChangedIssuesResults ret = tested.getJIRAChangedIssues("ORG", 10, ua, ub); Assert.assertEquals(5, ret.getStartAt()); Assert.assertEquals(10, ret.getMaxResults()); Assert.assertEquals(50, ret.getTotal()); Assert.assertNotNull(ret.getIssues()); Assert.assertEquals(1, ret.getIssuesCount()); } @Test public void performJIRAChangedIssuesREST() throws Exception { final Date ua = new Date(); final Date ub = new Date(); JIRA5RestClient tested = new JIRA5RestClient(mockEsIntegrationComponent(), TEST_JIRA_URL, null, null, 5000, null) { @Override protected byte[] performJIRAGetRESTCall(String restOperation, List<NameValuePair> params) throws Exception { Assert.assertEquals("search", restOperation); Assert.assertNotNull(params); String mr = "-1"; String fields = ""; String expand = ""; String startAt = ""; for (NameValuePair param : params) { if (param.getName().equals("maxResults")) { mr = param.getValue(); } else if (param.getName().equals("jql")) { Assert.assertEquals("JQL string", param.getValue()); } else if (param.getName().equals("fields")) { fields = param.getValue(); } else if (param.getName().equals("expand")) { expand = param.getValue(); } else if (param.getName().equals("startAt")) { startAt = param.getValue(); } } if ("-1".equals(mr)) { Assert.assertEquals(3, params.size()); } else if ("10".equals(mr)) { Assert.assertEquals(4, params.size()); } else if ("20".equals(mr)) { Assert.assertEquals(3, params.size()); } return ("{\"maxResults\": " + mr + ", \"startAt\": " + startAt + ", \"fields\" : \"" + fields + "\"" + ", \"expand\" : \"" + expand + "\" }").getBytes("UTF-8"); }; @Override protected String prepareJIRAChangedIssuesJQL(String projectKey, Date updatedAfter, Date updatedBefore) { Assert.assertEquals("ORG", projectKey); Assert.assertEquals(ua, updatedAfter); Assert.assertEquals(ub, updatedBefore); return "JQL string"; } }; IJIRAIssueIndexStructureBuilder jiraIssueIndexStructureBuilderMock = mock(IJIRAIssueIndexStructureBuilder.class); tested.setIndexStructureBuilder(jiraIssueIndexStructureBuilderMock); when(jiraIssueIndexStructureBuilderMock.getRequiredJIRACallIssueFields()).thenReturn( "key,status,issuetype,created,updated,reporter,assignee,summary,description"); // case - no maxResults parameter defined byte[] ret = tested.performJIRAChangedIssuesREST("ORG", 10, ua, ub); Assert .assertEquals( "{\"maxResults\": -1, \"startAt\": 10, \"fields\" : \"key,status,issuetype,created,updated,reporter,assignee,summary,description\", \"expand\" : \"\" }", new String(ret, "UTF-8")); // case - maxResults parameter defined tested.listJIRAIssuesMax = 10; ret = tested.performJIRAChangedIssuesREST("ORG", 20, ua, ub); Assert .assertEquals( "{\"maxResults\": 10, \"startAt\": 20, \"fields\" : \"key,status,issuetype,created,updated,reporter,assignee,summary,description\", \"expand\" : \"\" }", new String(ret, "UTF-8")); // case - no fields defined reset(jiraIssueIndexStructureBuilderMock); tested.listJIRAIssuesMax = 20; ret = tested.performJIRAChangedIssuesREST("ORG", 30, ua, ub); Assert.assertEquals("{\"maxResults\": 20, \"startAt\": 30, \"fields\" : \"\", \"expand\" : \"\" }", new String(ret, "UTF-8")); // case - expand defines reset(jiraIssueIndexStructureBuilderMock); tested.listJIRAIssuesMax = 10; when(jiraIssueIndexStructureBuilderMock.getRequiredJIRACallIssueExpands()).thenReturn("changelog"); ret = tested.performJIRAChangedIssuesREST("ORG", 30, ua, ub); Assert.assertEquals("{\"maxResults\": 10, \"startAt\": 30, \"fields\" : \"\", \"expand\" : \"changelog\" }", new String(ret, "UTF-8")); } @Test public void prepareAPIURLFromBaseURL() { Assert.assertNull(JIRA5RestClient.prepareAPIURLFromBaseURL(null, null)); Assert.assertNull(JIRA5RestClient.prepareAPIURLFromBaseURL("", null)); Assert.assertNull(JIRA5RestClient.prepareAPIURLFromBaseURL(" ", null)); Assert.assertEquals("http://issues.jboss.org/rest/api/2/", JIRA5RestClient.prepareAPIURLFromBaseURL("http://issues.jboss.org", null)); Assert.assertEquals("https://issues.jboss.org/rest/api/2/", JIRA5RestClient.prepareAPIURLFromBaseURL("https://issues.jboss.org/", "")); Assert.assertEquals("https://issues.jboss.org/rest/api/2/", JIRA5RestClient.prepareAPIURLFromBaseURL("https://issues.jboss.org/", " ")); Assert.assertEquals("https://issues.jboss.org/rest/api/latest/", JIRA5RestClient.prepareAPIURLFromBaseURL("https://issues.jboss.org/", "latest")); } @Test public void formatJQLDate() throws Exception { JIRA5RestClient tested = new JIRA5RestClient(mockEsIntegrationComponent(), TEST_JIRA_URL, null, null, 5000, null); Assert.assertNull(tested.formatJQLDate(null)); Date date1 = JQL_TEST_DATE_FORMAT.parse("2012-08-10 10:52"); Date date2 = JQL_TEST_DATE_FORMAT.parse("2012-08-10 22:52"); tested.setJQLDateFormatTimezone(TimeZone.getTimeZone("GMT")); Assert.assertEquals("2012-08-10 10:52", tested.formatJQLDate(date1)); Assert.assertEquals("2012-08-10 22:52", tested.formatJQLDate(date2)); tested.setJQLDateFormatTimezone(TimeZone.getTimeZone("GMT+1:00")); Assert.assertEquals("2012-08-10 11:52", tested.formatJQLDate(date1)); Assert.assertEquals("2012-08-10 23:52", tested.formatJQLDate(date2)); } @Test public void prepareJIRAChangedIssuesJQL() throws Exception { JIRA5RestClient tested = new JIRA5RestClient(mockEsIntegrationComponent(), TEST_JIRA_URL, null, null, 5000, null); tested.setJQLDateFormatTimezone(JQL_TEST_TIMEZONE); tested.setJqlTemplate(JiraRiver.DEFAULT_JQL_TEMPLATE); try { tested.prepareJIRAChangedIssuesJQL(null, null, null); Assert.fail("IllegalArgumentException not thrown if project key is missing"); } catch (IllegalArgumentException e) { // OK } try { tested.prepareJIRAChangedIssuesJQL(" ", null, null); Assert.fail("IllegalArgumentException not thrown if project key is missing"); } catch (IllegalArgumentException e) { // OK } Assert.assertEquals("project='ORG' ORDER BY updated ASC", tested.prepareJIRAChangedIssuesJQL("ORG", null, null)); Assert.assertEquals("project='ORG' and updatedDate >= \"2012-08-10 22:52\" ORDER BY updated ASC", tested.prepareJIRAChangedIssuesJQL("ORG", JQL_TEST_DATE_FORMAT.parse("2012-08-10 22:52"), null)); Assert.assertEquals("project='ORG' and updatedDate <= \"2012-08-10 22:55\" ORDER BY updated ASC", tested.prepareJIRAChangedIssuesJQL("ORG", null, JQL_TEST_DATE_FORMAT.parse("2012-08-10 22:55"))); Assert .assertEquals( "project='ORG' and updatedDate >= \"2012-08-10 22:52\" and updatedDate <= \"2012-08-10 22:55\" ORDER BY updated ASC", tested.prepareJIRAChangedIssuesJQL("ORG", JQL_TEST_DATE_FORMAT.parse("2012-08-10 22:52"), JQL_TEST_DATE_FORMAT.parse("2012-08-10 22:55"))); } @Test public void prepareJIRAChangedIssuesJQLWithTemplate() throws Exception { JIRA5RestClient tested = new JIRA5RestClient(mockEsIntegrationComponent(), TEST_JIRA_URL, null, null, 5000, null); tested.setJQLDateFormatTimezone(JQL_TEST_TIMEZONE); tested.setJqlTemplate("assignee=currentUser() AND project='%s' AND issueType='Bug'%s AND priority='P1 - Critical'%s ORDER BY updated ASC"); try { tested.prepareJIRAChangedIssuesJQL(null, null, null); Assert.fail("IllegalArgumentException not thrown if project key is missing"); } catch (IllegalArgumentException e) { // OK } try { tested.prepareJIRAChangedIssuesJQL(" ", null, null); Assert.fail("IllegalArgumentException not thrown if project key is missing"); } catch (IllegalArgumentException e) { // OK } Date updatedAfter = JQL_TEST_DATE_FORMAT.parse("2012-08-10 22:52"); Date updatedBefore = JQL_TEST_DATE_FORMAT.parse("2012-08-10 22:55"); Assert.assertEquals( "assignee=currentUser() AND project='ORG' AND issueType='Bug' AND priority='P1 - Critical' ORDER BY updated ASC", tested.prepareJIRAChangedIssuesJQL("ORG", null, null)); Assert.assertEquals( "assignee=currentUser() AND project='ORG' AND issueType='Bug' and updatedDate >= \"2012-08-10 22:52\" AND priority='P1 - Critical' ORDER BY updated ASC", tested.prepareJIRAChangedIssuesJQL("ORG", updatedAfter, null)); Assert.assertEquals( "assignee=currentUser() AND project='ORG' AND issueType='Bug' AND priority='P1 - Critical' and updatedDate <= \"2012-08-10 22:55\" ORDER BY updated ASC", tested.prepareJIRAChangedIssuesJQL("ORG", null, updatedBefore)); Assert.assertEquals( "assignee=currentUser() AND project='ORG' AND issueType='Bug' and updatedDate >= \"2012-08-10 22:52\" AND priority='P1 - Critical' and updatedDate <= \"2012-08-10 22:55\" ORDER BY updated ASC", tested.prepareJIRAChangedIssuesJQL("ORG", updatedAfter, updatedBefore)); } protected static IESIntegration mockEsIntegrationComponent() { IESIntegration esIntegrationMock = mock(IESIntegration.class); Mockito.when(esIntegrationMock.createLogger(Mockito.any(Class.class))).thenReturn( ESLoggerFactory.getLogger(JIRAProjectIndexerCoordinator.class.getName())); RiverName riverName = new RiverName("jira", "my_river"); Mockito.when(esIntegrationMock.riverName()).thenReturn(riverName); return esIntegrationMock; } }