/* * Copyright 2012 Nodeable Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.streamreduce.util; import com.google.common.collect.ImmutableSet; import com.streamreduce.AbstractServiceTestCase; import com.streamreduce.ProviderIdConstants; import com.streamreduce.connections.AuthType; import com.streamreduce.connections.ConnectionProviderFactory; import com.streamreduce.connections.JiraProjectHostingProvider; import com.streamreduce.core.model.Account; import com.streamreduce.core.model.Connection; import com.streamreduce.core.model.ConnectionCredentials; import com.streamreduce.core.model.InventoryItem; import com.streamreduce.core.model.User; import junit.framework.Assert; import junit.framework.AssertionFailedError; import net.sf.json.JSONObject; import org.apache.abdera.model.Entry; import org.bson.types.ObjectId; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import javax.xml.namespace.QName; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.ResourceBundle; import java.util.Set; /** * Tests for {@link JiraClient}. */ public class JiraClientIT extends AbstractServiceTestCase { @Autowired ConnectionProviderFactory connectionProviderFactory; JiraProjectHostingProvider jiraProjectHostingProvider; private ResourceBundle jiraProperties = ResourceBundle.getBundle("jira"); private String jiraPassword = jiraProperties.getString("nodeable.jira.password"); private String jiraUrl = jiraProperties.getString("nodeable.jira.url"); private String jiraUsername = jiraProperties.getString("nodeable.jira.username"); private Set<String> monitoredProjects = new HashSet<>(); private Connection connection; private InventoryItem inventoryItem; private JiraClient jiraClient; @Before public void setUp() throws Exception { jiraProjectHostingProvider = (JiraProjectHostingProvider) connectionProviderFactory.connectionProviderFromId( ProviderIdConstants.JIRA_PROVIDER_ID); Account testAccount = new Account.Builder() .url("http://nodeable.com") .description("Nodeable Test Account") .name("Nodeable Testing") .build(); User testUser = new User.Builder() .account(testAccount) .accountLocked(false) .accountOriginator(true) .fullname("Nodeable Test User") .username("test_user_" + new Date().getTime() + "@nodeable.com") .build(); connection = new Connection.Builder() .provider(jiraProjectHostingProvider) .credentials(new ConnectionCredentials(jiraUsername, jiraPassword)) .url(jiraUrl) .alias("Test Jira Connection") .user(testUser) .authType(AuthType.USERNAME_PASSWORD) .build(); // Connection properties normally set by persistence/polling connection.setId(new ObjectId()); connection.setLastActivityPollDate(new Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24))); // Create a date a day in the past inventoryItem = new InventoryItem.Builder() .account(testAccount) .user(testUser) .connection(connection) .hashtags(ImmutableSet.of("#jira")) .build(); jiraClient = new JiraClient(connection); List<JSONObject> allProjects = jiraClient.getProjects(false); for (JSONObject project : allProjects) { monitoredProjects.add(project.getString("key")); } } @Test public void testJiraGetIssuePriorities() throws Exception { Assert.assertTrue(jiraClient.getIssuePriorities().size() > 0); } @Test public void testJiraGetIssueStatuses() throws Exception { Assert.assertTrue(jiraClient.getIssueStatuses().size() > 0); } @Test public void testJiraGetIssueTypes() throws Exception { Assert.assertTrue(jiraClient.getIssueTypes().size() > 0); } @Test public void testJiraGetSubTaskIssueTypes() throws Exception { // We can only check that the response doesn't error here Assert.assertTrue(jiraClient.getSubTaskIssueTypes().size() >= 0); } /** * Tests {@link JiraClient#getActivity(java.util.Set)}. * * @throws Exception if anything goes wrong */ @Test public void testJiraGetActivityParts() throws Exception { int maxResults = 100; List<Entry> testProjectActivity = jiraClient.getActivity(monitoredProjects, maxResults); Assert.assertTrue(testProjectActivity.size() > 0 && testProjectActivity.size() <= maxResults); for (Entry activity : testProjectActivity) { org.apache.abdera.model.Element activityObjectElement = activity.getFirstChild( new QName("http://activitystrea.ms/spec/1.0/", "object", "activity")); String projectKey = jiraClient.getProjectKeyOfEntry(activityObjectElement, monitoredProjects); // Prepare the inventory item inventoryItem.setExternalId(projectKey); Map<String, Object> activityParts = jiraClient.getPartsForActivity(inventoryItem, activity); Assert.assertNotNull(activityParts); String title = (String)activityParts.get("title"); String content = (String)activityParts.get("content"); Set<String> hashtags = (Set<String>)activityParts.get("hashtags"); int expectedHashtagCount = 2; // #jira and #[project.key] is always expected try { Assert.assertNotNull(title); Assert.assertTrue(hashtags.contains("#" + projectKey.toLowerCase())); Assert.assertTrue(hashtags.contains("#jira")); // No good way to test content since it can be null a few different ways if (hashtags.contains("#issue")) { // Issue related tests expectedHashtagCount += 4; // #issue #[issue-type] #[issue-priority] #[issue-status] // There is no good way to test the actual issue hashtags because they could outdated } else if (hashtags.contains("#source")) { // Source related tests expectedHashtagCount += 2; // #source #[activity] Assert.assertFalse(hashtags.contains("#file")); // This is an ignored hashtag Assert.assertTrue(hashtags.contains("#changeset") || hashtags.contains("#review")); } else if (hashtags.contains("#wiki")) { // Wiki related tests if (!hashtags.contains("#blog") && !hashtags.contains("#page")) { expectedHashtagCount += 1; // #wiki } else { expectedHashtagCount += 2; // #wiki #[target] } Assert.assertFalse(hashtags.contains("#space")); // This is an ignored hashtag Assert.assertFalse(hashtags.contains("#article")); // This is an ignored hashtag Assert.assertFalse(hashtags.contains("#file")); // This is an ignored hashtag } else { Assert.fail("All Jira activity hashtags should contain at least one of he following: " + "#issue, #source or #wiki"); } // For comments and attachments, expected hashtags is one extra if (hashtags.contains("#comment") || hashtags.contains("#attachment")) { expectedHashtagCount += 1; } if (hashtags.contains("#issue") || (hashtags.contains("#wiki") && !hashtags.contains("#blog"))) { Assert.assertTrue(hashtags.size() >= expectedHashtagCount); } else { Assert.assertEquals(expectedHashtagCount, hashtags.size()); } } catch (AssertionFailedError e) { // Add some extra output to make debugging easier System.out.println("Problematic title: " + activity.getTitle()); System.out.println("Hashtags (Expected: " + expectedHashtagCount + "):"); for (String hashtag : hashtags) { System.out.println(" " + hashtag); } throw e; } } } }