Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Sawicki2012-06-12 15:49:35 +0000
committerKevin Sawicki2012-06-12 15:49:35 +0000
commite2f0f666748f7f2c634ddcaf02e9b77657606c95 (patch)
treedea1857a422df62b442e104cb0f24677958a6ad4
parent2056b1f217eebf7c862c0995a5026ccb491de9a4 (diff)
downloadegit-github-e2f0f666748f7f2c634ddcaf02e9b77657606c95.tar.gz
egit-github-e2f0f666748f7f2c634ddcaf02e9b77657606c95.tar.xz
egit-github-e2f0f666748f7f2c634ddcaf02e9b77657606c95.zip
Add legacy support for searching issues
IssueService now supports searching for opened or closed issues in a repository that match a given query. Change-Id: I054614b685726f9261a898f2e94215fbb460c728
-rw-r--r--org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/AllHeadlessTests.java1
-rw-r--r--org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/IssueServiceTest.java84
-rw-r--r--org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/SearchIssueTest.java73
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/SearchIssue.java259
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/IssueService.java56
5 files changed, 473 insertions, 0 deletions
diff --git a/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/AllHeadlessTests.java b/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/AllHeadlessTests.java
index c1509c1c..5d50e1fd 100644
--- a/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/AllHeadlessTests.java
+++ b/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/AllHeadlessTests.java
@@ -86,6 +86,7 @@ import org.junit.runners.Suite.SuiteClasses;
RepositoryTest.class, //
RequestErrorTest.class, //
RequestExceptionTest.class, //
+ SearchIssueTest.class, //
SearchRepositoryTest.class, //
ShaResourceTest.class, //
TagTest.class, //
diff --git a/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/IssueServiceTest.java b/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/IssueServiceTest.java
index b249c226..17b9f816 100644
--- a/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/IssueServiceTest.java
+++ b/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/IssueServiceTest.java
@@ -830,4 +830,88 @@ public class IssueServiceTest {
verify(gitHubClient).post("/repos/user/repo/issues/comments/44",
comment, Comment.class);
}
+
+ /**
+ * Search issues with null repository
+ *
+ * @throws IOException
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void searchIssuesNullRepository() throws IOException {
+ issueService.searchIssues(null, "open", "test");
+ }
+
+ /**
+ * Search issues with null query
+ *
+ * @throws IOException
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void searchIssueNullQuery() throws IOException {
+ RepositoryId id = new RepositoryId("user", "repo");
+ issueService.searchIssues(id, "open", null);
+ }
+
+ /**
+ * Search issues with empty query
+ *
+ * @throws IOException
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void searchIssueEmptyQuery() throws IOException {
+ RepositoryId id = new RepositoryId("user", "repo");
+ issueService.searchIssues(id, "open", "");
+ }
+
+ /**
+ * Search issues with null state
+ *
+ * @throws IOException
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void searchIssueNullState() throws IOException {
+ RepositoryId id = new RepositoryId("user", "repo");
+ issueService.searchIssues(id, null, "test");
+ }
+
+ /**
+ * Search issues with empty state
+ *
+ * @throws IOException
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void searchIssueEmptyState() throws IOException {
+ RepositoryId id = new RepositoryId("user", "repo");
+ issueService.searchIssues(id, "", "test");
+ }
+
+ /**
+ * Search issues
+ *
+ * @throws IOException
+ */
+ @Test
+ public void searchIssues() throws IOException {
+ RepositoryId id = new RepositoryId("user", "repo");
+ issueService.searchIssues(id, "closed", "test");
+ GitHubRequest request = new GitHubRequest();
+ request.setUri(Utils
+ .page("/legacy/issues/search/user/repo/closed/test"));
+ verify(gitHubClient).get(request);
+ }
+
+ /**
+ * Search issues with query that needs escaping
+ *
+ * @throws IOException
+ */
+ @Test
+ public void searchEscaped() throws IOException {
+ RepositoryId id = new RepositoryId("user", "repo");
+ issueService.searchIssues(id, "open", "a and a.");
+ GitHubRequest request = new GitHubRequest();
+ request.setUri(Utils
+ .page("/legacy/issues/search/user/repo/open/a%20and%20a%2E"));
+ verify(gitHubClient).get(request);
+ }
}
diff --git a/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/SearchIssueTest.java b/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/SearchIssueTest.java
new file mode 100644
index 00000000..a7f8b1f6
--- /dev/null
+++ b/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/SearchIssueTest.java
@@ -0,0 +1,73 @@
+/******************************************************************************
+ * Copyright (c) 2012 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.github.core.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import org.eclipse.egit.github.core.SearchIssue;
+import org.junit.Test;
+
+/**
+ * Unit tests of {@link SearchIssue}
+ */
+public class SearchIssueTest {
+
+ /**
+ * Test default state of search issue
+ */
+ @Test
+ public void defaultState() {
+ SearchIssue issue = new SearchIssue();
+ assertNull(issue.getBody());
+ assertNull(issue.getCreatedAt());
+ assertNull(issue.getGravatarId());
+ assertNull(issue.getHtmlUrl());
+ assertNull(issue.getLabels());
+ assertEquals(0, issue.getComments());
+ assertEquals(0, issue.getPosition());
+ assertNull(issue.getState());
+ assertNull(issue.getTitle());
+ assertNull(issue.getUpdatedAt());
+ assertNull(issue.getUser());
+ assertEquals(0, issue.getVotes());
+ assertEquals(0, issue.getNumber());
+ }
+
+ /**
+ * Test updating search issue fields
+ */
+ @Test
+ public void updateFields() {
+ SearchIssue issue = new SearchIssue();
+ assertEquals("body", issue.setBody("body").getBody());
+ assertEquals(new Date(1234), issue.setCreatedAt(new Date(1234))
+ .getCreatedAt());
+ assertEquals("gravatar", issue.setGravatarId("gravatar")
+ .getGravatarId());
+ assertEquals("html", issue.setHtmlUrl("html").getHtmlUrl());
+ List<String> labels = Arrays.asList("a", "b");
+ assertEquals(labels, issue.setLabels(labels).getLabels());
+ assertEquals(5, issue.setComments(5).getComments());
+ assertEquals(6, issue.setPosition(6).getPosition());
+ assertEquals("open", issue.setState("open").getState());
+ assertEquals("title", issue.setTitle("title").getTitle());
+ assertEquals(new Date(2345), issue.setUpdatedAt(new Date(2345))
+ .getUpdatedAt());
+ assertEquals("defunkt", issue.setUser("defunkt").getUser());
+ assertEquals(10, issue.setVotes(10).getVotes());
+ assertEquals(500, issue.setNumber(500).getNumber());
+ }
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/SearchIssue.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/SearchIssue.java
new file mode 100644
index 00000000..133ce835
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/SearchIssue.java
@@ -0,0 +1,259 @@
+/******************************************************************************
+ * Copyright (c) 2012 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.github.core;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+import org.eclipse.egit.github.core.util.DateUtils;
+
+/**
+ * GitHub v2 issue model class.
+ */
+public class SearchIssue implements Serializable {
+
+ private static final long serialVersionUID = 4853048031771824016L;
+
+ private Date createdAt;
+
+ private Date updatedAt;
+
+ private int comments;
+
+ private int number;
+
+ private int position;
+
+ private int votes;
+
+ private List<String> labels;
+
+ private String body;
+
+ private String gravatarId;
+
+ private String htmlUrl;
+
+ private String state;
+
+ private String title;
+
+ private String user;
+
+ /**
+ * @return createdAt
+ */
+ public Date getCreatedAt() {
+ return DateUtils.clone(createdAt);
+ }
+
+ /**
+ * @param createdAt
+ * @return this issue
+ */
+ public SearchIssue setCreatedAt(Date createdAt) {
+ this.createdAt = DateUtils.clone(createdAt);
+ return this;
+ }
+
+ /**
+ * @return updatedAt
+ */
+ public Date getUpdatedAt() {
+ return DateUtils.clone(updatedAt);
+ }
+
+ /**
+ * @param updatedAt
+ * @return this issue
+ */
+ public SearchIssue setUpdatedAt(Date updatedAt) {
+ this.updatedAt = DateUtils.clone(updatedAt);
+ return this;
+ }
+
+ /**
+ * @return comments
+ */
+ public int getComments() {
+ return comments;
+ }
+
+ /**
+ * @param comments
+ * @return this issue
+ */
+ public SearchIssue setComments(int comments) {
+ this.comments = comments;
+ return this;
+ }
+
+ /**
+ * @return number
+ */
+ public int getNumber() {
+ return number;
+ }
+
+ /**
+ * @param number
+ * @return this issue
+ */
+ public SearchIssue setNumber(int number) {
+ this.number = number;
+ return this;
+ }
+
+ /**
+ * @return position
+ */
+ public int getPosition() {
+ return position;
+ }
+
+ /**
+ * @param position
+ * @return this issue
+ */
+ public SearchIssue setPosition(int position) {
+ this.position = position;
+ return this;
+ }
+
+ /**
+ * @return votes
+ */
+ public int getVotes() {
+ return votes;
+ }
+
+ /**
+ * @param votes
+ * @return this issue
+ */
+ public SearchIssue setVotes(int votes) {
+ this.votes = votes;
+ return this;
+ }
+
+ /**
+ * @return labels
+ */
+ public List<String> getLabels() {
+ return labels;
+ }
+
+ /**
+ * @param labels
+ * @return this issue
+ */
+ public SearchIssue setLabels(List<String> labels) {
+ this.labels = labels;
+ return this;
+ }
+
+ /**
+ * @return body
+ */
+ public String getBody() {
+ return body;
+ }
+
+ /**
+ * @param body
+ * @return this issue
+ */
+ public SearchIssue setBody(String body) {
+ this.body = body;
+ return this;
+ }
+
+ /**
+ * @return gravatarId
+ */
+ public String getGravatarId() {
+ return gravatarId;
+ }
+
+ /**
+ * @param gravatarId
+ * @return this issue
+ */
+ public SearchIssue setGravatarId(String gravatarId) {
+ this.gravatarId = gravatarId;
+ return this;
+ }
+
+ /**
+ * @return htmlUrl
+ */
+ public String getHtmlUrl() {
+ return htmlUrl;
+ }
+
+ /**
+ * @param htmlUrl
+ * @return this issue
+ */
+ public SearchIssue setHtmlUrl(String htmlUrl) {
+ this.htmlUrl = htmlUrl;
+ return this;
+ }
+
+ /**
+ * @return state
+ */
+ public String getState() {
+ return state;
+ }
+
+ /**
+ * @param state
+ * @return this issue
+ */
+ public SearchIssue setState(String state) {
+ this.state = state;
+ return this;
+ }
+
+ /**
+ * @return title
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * @param title
+ * @return this issue
+ */
+ public SearchIssue setTitle(String title) {
+ this.title = title;
+ return this;
+ }
+
+ /**
+ * @return user
+ */
+ public String getUser() {
+ return user;
+ }
+
+ /**
+ * @param user
+ * @return this issue
+ */
+ public SearchIssue setUser(String user) {
+ this.user = user;
+ return this;
+ }
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/IssueService.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/IssueService.java
index 71888ecf..c4e137d8 100644
--- a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/IssueService.java
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/IssueService.java
@@ -10,16 +10,20 @@
*******************************************************************************/
package org.eclipse.egit.github.core.service;
+import static org.eclipse.egit.github.core.client.IGitHubConstants.CHARSET_UTF8;
import static org.eclipse.egit.github.core.client.IGitHubConstants.SEGMENT_COMMENTS;
import static org.eclipse.egit.github.core.client.IGitHubConstants.SEGMENT_EVENTS;
import static org.eclipse.egit.github.core.client.IGitHubConstants.SEGMENT_ISSUES;
+import static org.eclipse.egit.github.core.client.IGitHubConstants.SEGMENT_LEGACY;
import static org.eclipse.egit.github.core.client.IGitHubConstants.SEGMENT_REPOS;
+import static org.eclipse.egit.github.core.client.IGitHubConstants.SEGMENT_SEARCH;
import static org.eclipse.egit.github.core.client.PagedRequest.PAGE_FIRST;
import static org.eclipse.egit.github.core.client.PagedRequest.PAGE_SIZE;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
+import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -27,11 +31,13 @@ import java.util.Map;
import org.eclipse.egit.github.core.Comment;
import org.eclipse.egit.github.core.IRepositoryIdProvider;
+import org.eclipse.egit.github.core.IResourceProvider;
import org.eclipse.egit.github.core.Issue;
import org.eclipse.egit.github.core.IssueEvent;
import org.eclipse.egit.github.core.Label;
import org.eclipse.egit.github.core.Milestone;
import org.eclipse.egit.github.core.RepositoryIssue;
+import org.eclipse.egit.github.core.SearchIssue;
import org.eclipse.egit.github.core.User;
import org.eclipse.egit.github.core.client.GitHubClient;
import org.eclipse.egit.github.core.client.GitHubRequest;
@@ -152,6 +158,19 @@ public class IssueService extends GitHubService {
*/
public static final String SORT_COMMENTS = "comments"; //$NON-NLS-1$
+ private static class IssueContainer implements
+ IResourceProvider<SearchIssue> {
+
+ private List<SearchIssue> issues;
+
+ /**
+ * @see org.eclipse.egit.github.core.IResourceProvider#getResources()
+ */
+ public List<SearchIssue> getResources() {
+ return issues;
+ }
+ }
+
/**
* Create issue service
*/
@@ -1069,4 +1088,41 @@ public class IssueService extends GitHubService {
request.setType(IssueEvent.class);
return (IssueEvent) client.get(request).getBody();
}
+
+ /**
+ * Search issues in the given repository using the given query
+ *
+ * @param repository
+ * @param state
+ * {@link #STATE_OPEN} or {@link #STATE_CLOSED}
+ * @param query
+ * @return issues matching query
+ * @throws IOException
+ */
+ public List<SearchIssue> searchIssues(IRepositoryIdProvider repository,
+ String state, String query) throws IOException {
+ String id = getId(repository);
+ if (state == null)
+ throw new IllegalArgumentException("State cannot be null"); //$NON-NLS-1$
+ if (state.length() == 0)
+ throw new IllegalArgumentException("State cannot be empty"); //$NON-NLS-1$
+ if (query == null)
+ throw new IllegalArgumentException("Query cannot be null"); //$NON-NLS-1$
+ if (query.length() == 0)
+ throw new IllegalArgumentException("Query cannot be empty"); //$NON-NLS-1$
+
+ StringBuilder uri = new StringBuilder(SEGMENT_LEGACY + SEGMENT_ISSUES
+ + SEGMENT_SEARCH);
+ uri.append('/').append(id);
+ uri.append('/').append(state);
+ final String encodedQuery = URLEncoder.encode(query, CHARSET_UTF8)
+ .replace("+", "%20") //$NON-NLS-1$ //$NON-NLS-2$
+ .replace(".", "%2E"); //$NON-NLS-1$ //$NON-NLS-2$
+ uri.append('/').append(encodedQuery);
+
+ PagedRequest<SearchIssue> request = createPagedRequest();
+ request.setUri(uri);
+ request.setType(IssueContainer.class);
+ return getAll(request);
+ }
}

Back to the top