summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/WebService/Bug.pm43
-rw-r--r--Bugzilla/WebService/Server/REST/Resources/Bug.pm5
-rw-r--r--docs/en/rst/api/core/v1/bug.rst116
3 files changed, 159 insertions, 5 deletions
diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm
index c07454d7d..feb541c2e 100644
--- a/Bugzilla/WebService/Bug.pm
+++ b/Bugzilla/WebService/Bug.pm
@@ -35,6 +35,8 @@ use Bugzilla::Search::Quicksearch;
use List::Util qw(max);
use List::MoreUtils qw(uniq);
use Storable qw(dclone);
+use Types::Standard -all;
+use Type::Utils;
#############
# Constants #
@@ -656,9 +658,30 @@ sub possible_duplicates {
Bugzilla->switch_to_shadow_db();
- # Undo the array-ification that validate() does, for "summary".
- $params->{summary} || ThrowCodeError('param_required',
- { function => 'Bug.possible_duplicates', param => 'summary' });
+ state $params_type = Dict [
+ id => Optional [Int],
+ product => Optional [ ArrayRef [Str] ],
+ limit => Optional [Int],
+ summary => Optional [Str],
+ include_fields => Optional [ ArrayRef [Str] ],
+ Bugzilla_api_token => Optional [Str]
+ ];
+
+ ThrowCodeError( 'param_invalid', { function => 'Bug.possible_duplicates', param => 'A param' } )
+ if !$params_type->check($params);
+
+ my $summary;
+ if ($params->{id}) {
+ my $bug = Bugzilla::Bug->check({ id => $params->{id}, cache => 1 });
+ $summary = $bug->short_desc;
+ }
+ elsif ($params->{summary}) {
+ $summary = $params->{summary};
+ }
+ else {
+ ThrowCodeError('param_required',
+ { function => 'Bug.possible_duplicates', param => 'id or summary' });
+ }
my @products;
foreach my $name (@{ $params->{'product'} || [] }) {
@@ -667,8 +690,18 @@ sub possible_duplicates {
}
my $possible_dupes = Bugzilla::Bug->possible_duplicates(
- { summary => $params->{summary}, products => \@products,
- limit => $params->{limit} });
+ {
+ summary => $summary,
+ products => \@products,
+ limit => $params->{limit}
+ }
+ );
+
+ # If a bug id was used, remove the bug with the same id from the list.
+ if ($params->{id}) {
+ @$possible_dupes = grep { $_->id != $params->{id} } @$possible_dupes;
+ }
+
my @hashes = map { $self->_bug_to_hash($_, $params) } @$possible_dupes;
$self->_add_update_tokens($params, $possible_dupes, \@hashes);
return { bugs => \@hashes };
diff --git a/Bugzilla/WebService/Server/REST/Resources/Bug.pm b/Bugzilla/WebService/Server/REST/Resources/Bug.pm
index 33cf43321..26aec011c 100644
--- a/Bugzilla/WebService/Server/REST/Resources/Bug.pm
+++ b/Bugzilla/WebService/Server/REST/Resources/Bug.pm
@@ -34,6 +34,11 @@ sub _rest_resources {
method => 'get'
}
},
+ qr{^/bug/possible_duplicates$}, {
+ GET => {
+ method => 'possible_duplicates'
+ }
+ },
qr{^/bug/([^/]+)$}, {
GET => {
method => 'get',
diff --git a/docs/en/rst/api/core/v1/bug.rst b/docs/en/rst/api/core/v1/bug.rst
index 3c7605527..53f637a67 100644
--- a/docs/en/rst/api/core/v1/bug.rst
+++ b/docs/en/rst/api/core/v1/bug.rst
@@ -1087,3 +1087,119 @@ This method can throw all the same errors as :ref:`rest_single_bug`, plus:
You did not specify a valid for the "file_name" argument.
* 604 (Summary Required)
You did not specify a value for the "summary" argument.
+
+.. _rest_possible_duplicates:
+
+Possible Duplicates
+-------------------
+
+Gets a list of possible duplicate bugs.
+
+**Request**
+
+To search by similar bug.
+
+.. code-block:: text
+
+ GET /rest/bug/possible_duplicates?id=1234567
+
+To search by a similar bug summary directly.
+
+.. code-block:: text
+
+ GET /rest/bug/possible_duplicates?summary=Similar+Bug+Summary
+
+======= ====== ================================================================
+name type description
+======= ====== ================================================================
+id int The id of a bug to find duplicates of.
+summary string A summary to search for duplicates of, only used if no bug id is
+ given.
+product string A product group to limit the search in.
+limit int Limit the number of results returned. If the limit
+ is more than zero and higher than the maximum limit
+ set by the administrator, then the maximum limit will
+ be used instead. If you set the limit equal to zero,
+ then all matching results will be returned instead.
+======= ====== ================================================================
+
+**Response**
+
+.. code-block:: js
+
+ {
+ "bugs": [
+ {
+ "alias": [],
+ "history": [
+ {
+ "when": "2014-09-23T19:12:17Z",
+ "who": "user@bugzilla.org",
+ "changes": [
+ {
+ "added": "P1",
+ "field_name": "priority",
+ "removed": "P2"
+ },
+ {
+ "removed": "blocker",
+ "field_name": "severity",
+ "added": "critical"
+ }
+ ]
+ },
+ {
+ "when": "2014-09-28T21:03:47Z",
+ "who": "user@bugzilla.org",
+ "changes": [
+ {
+ "added": "blocker?",
+ "removed": "",
+ "field_name": "flagtypes.name"
+ }
+ ]
+ }
+ ],
+ "id": 35
+ }
+ ]
+ }
+
+``bugs`` (array) Bug objects each containing the following items. If a bug id was
+used to query this endpoint, that bug will not be in the list returned.
+
+======= ===== =================================================================
+name type description
+======= ===== =================================================================
+id int The numeric ID of the bug.
+alias array The unique aliases of this bug. An empty array will be returned
+ if this bug has no aliases.
+history array An array of History objects.
+======= ===== =================================================================
+
+History object:
+
+======= ======== ==============================================================
+name type description
+======= ======== ==============================================================
+when datetime The date the bug activity/change happened.
+who string The login name of the user who performed the bug change.
+changes array An array of Change objects which contain all the changes that
+ happened to the bug at this time (as specified by ``when``).
+======= ======== ==============================================================
+
+Change object:
+
+============= ====== ==========================================================
+name type description
+============= ====== ==========================================================
+field_name string The name of the bug field that has changed.
+removed string The previous value of the bug field which has been
+ deleted by the change.
+added string The new value of the bug field which has been added
+ by the change.
+attachment_id int The ID of the attachment that was changed.
+ This only appears if the change was to an attachment,
+ otherwise ``attachment_id`` will not be present in this
+ object.
+============= ====== ========================================================== \ No newline at end of file