From bc313deaae2fae3e5532a28245fe72fcf9aef9a6 Mon Sep 17 00:00:00 2001
From: Tim <tgaudette88@gmail.com>
Date: Sun, 26 Jun 2016 13:36:43 -0400
Subject: [PATCH] Added Bugzilla as external issue tracker option

Requested in #14669

Added note to changelog
---
 CHANGELOG                                     |  1 +
 app/models/project.rb                         |  1 +
 .../project_services/bugzilla_service.rb      | 37 ++++++++++++++
 app/models/service.rb                         |  1 +
 doc/integration/external-issue-tracker.md     |  3 +-
 doc/project_services/bugzilla.md              | 17 +++++++
 doc/project_services/project_services.md      |  1 +
 .../project_services/bugzilla_service_spec.rb | 49 +++++++++++++++++++
 8 files changed, 109 insertions(+), 1 deletion(-)
 create mode 100644 app/models/project_services/bugzilla_service.rb
 create mode 100644 doc/project_services/bugzilla.md
 create mode 100644 spec/models/project_services/bugzilla_service_spec.rb

diff --git a/CHANGELOG b/CHANGELOG
index 80f404423c7..f183539aa4f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -31,6 +31,7 @@ v 8.9.2
   - Fix visibility of snippets when searching.
   - Fix an information disclosure when requesting access to a group containing private projects.
   - Update omniauth-saml to 1.6.0 !4951
+  - Add Bugzilla integration
 
 v 8.9.1
   - Refactor labels documentation. !3347
diff --git a/app/models/project.rb b/app/models/project.rb
index 96837364423..73ded09c162 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -81,6 +81,7 @@ class Project < ActiveRecord::Base
   has_one :jira_service, dependent: :destroy
   has_one :redmine_service, dependent: :destroy
   has_one :custom_issue_tracker_service, dependent: :destroy
+  has_one :bugzilla_service, dependent: :destroy
   has_one :gitlab_issue_tracker_service, dependent: :destroy, inverse_of: :project
   has_one :external_wiki_service, dependent: :destroy
 
diff --git a/app/models/project_services/bugzilla_service.rb b/app/models/project_services/bugzilla_service.rb
new file mode 100644
index 00000000000..b84f9ebe479
--- /dev/null
+++ b/app/models/project_services/bugzilla_service.rb
@@ -0,0 +1,37 @@
+class BugzillaService < IssueTrackerService
+
+  prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
+
+  def title
+    if self.properties && self.properties['title'].present?
+      self.properties['title']
+    else
+      'Bugzilla'
+    end
+  end
+
+  def description
+    if self.properties && self.properties['description'].present?
+      self.properties['description']
+    else
+      'Bugzilla issue tracker'
+    end
+  end
+
+  def to_param
+    'bugzilla'
+  end
+
+  def fields
+    [
+      { type: 'text', name: 'description', placeholder: description },
+      { type: 'text', name: 'project_url', placeholder: 'http://bugzilla.example.com/describecomponents.cgi?product=PRODUCT_NAME' },
+      { type: 'text', name: 'issues_url', placeholder: 'http://bugzilla.example.com/show_bug.cgi?id=:id' },
+      { type: 'text', name: 'new_issue_url', placeholder: 'http://bugzilla.example.com/enter_bug.cgi?product=PRODUCT_NAME' }
+    ]
+  end
+
+  def initialize_properties
+    self.properties = {} if properties.nil?
+  end
+end
diff --git a/app/models/service.rb b/app/models/service.rb
index 40d39933ad8..d7a32c28267 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -170,6 +170,7 @@ class Service < ActiveRecord::Base
       bamboo
       buildkite
       builds_email
+      bugzilla
       campfire
       custom_issue_tracker
       drone_ci
diff --git a/doc/integration/external-issue-tracker.md b/doc/integration/external-issue-tracker.md
index a2d7e922aad..8d2c6351fb8 100644
--- a/doc/integration/external-issue-tracker.md
+++ b/doc/integration/external-issue-tracker.md
@@ -1,7 +1,7 @@
 # External issue tracker
 
 GitLab has a great issue tracker but you can also use an external one such as
-Jira or Redmine. Issue trackers are configurable per GitLab project and allow
+Jira, Redmine, or Bugzilla. Issue trackers are configurable per GitLab project and allow
 you to do the following:
 
 - the **Issues** link on the GitLab project pages takes you to the appropriate
@@ -20,6 +20,7 @@ Visit the links below for details:
 
 - [Redmine](../project_services/redmine.md)
 - [Jira](../project_services/jira.md)
+- [Bugzilla](../project_services/bugzilla.md)
 
 ### Service Template
 
diff --git a/doc/project_services/bugzilla.md b/doc/project_services/bugzilla.md
new file mode 100644
index 00000000000..215ed6fe9cc
--- /dev/null
+++ b/doc/project_services/bugzilla.md
@@ -0,0 +1,17 @@
+# Bugzilla Service
+
+Go to your project's **Settings > Services > Bugzilla** and fill in the required
+details as described in the table below.
+
+| Field | Description |
+| ----- | ----------- |
+| `description`   | A name for the issue tracker (to differentiate between instances, for example) |
+| `project_url`   | The URL to the project in Bugzilla which is being linked to this GitLab project. Note that the `project_url` requires PRODUCT_NAME to be updated with the product/project name in Bugzilla. |
+| `issues_url`    | The URL to the issue in Bugzilla project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the URL. This ID is used by GitLab as a placeholder to replace the issue number. |
+| `new_issue_url` | This is the URL to create a new issue in Bugzilla for the project linked to this GitLab project. Note that the `new_issue_url` requires PRODUCT_NAME to be updated with the product/project name in Bugzilla. |
+
+Once you have configured and enabled Bugzilla:
+
+- the **Issues** link on the GitLab project pages takes you to the appropriate
+  Bugzilla product page
+- clicking **New issue** on the project dashboard takes you to Bugzilla for entering a new issue
diff --git a/doc/project_services/project_services.md b/doc/project_services/project_services.md
index f81a035f70b..e15d5db3253 100644
--- a/doc/project_services/project_services.md
+++ b/doc/project_services/project_services.md
@@ -30,6 +30,7 @@ further configuration instructions and details. Contributions are welcome.
 | [Atlassian Bamboo CI](bamboo.md) | A continuous integration and build server |
 | Buildkite | Continuous integration and deployments |
 | [Builds emails](builds_emails.md) |	Email the builds status to a list of recipients |
+| [Bugzilla](bugzilla.md) | Bugzilla issue tracker |
 | Campfire | Simple web-based real-time group chat |
 | Custom Issue Tracker | Custom issue tracker |
 | Drone CI | Continuous Integration platform built on Docker, written in Go |
diff --git a/spec/models/project_services/bugzilla_service_spec.rb b/spec/models/project_services/bugzilla_service_spec.rb
new file mode 100644
index 00000000000..a6d9717ccb5
--- /dev/null
+++ b/spec/models/project_services/bugzilla_service_spec.rb
@@ -0,0 +1,49 @@
+# == Schema Information
+#
+# Table name: services
+#
+#  id                    :integer          not null, primary key
+#  type                  :string(255)
+#  title                 :string(255)
+#  project_id            :integer
+#  created_at            :datetime
+#  updated_at            :datetime
+#  active                :boolean          default(FALSE), not null
+#  properties            :text
+#  template              :boolean          default(FALSE)
+#  push_events           :boolean          default(TRUE)
+#  issues_events         :boolean          default(TRUE)
+#  merge_requests_events :boolean          default(TRUE)
+#  tag_push_events       :boolean          default(TRUE)
+#  note_events           :boolean          default(TRUE), not null
+#
+
+require 'spec_helper'
+
+describe BugzillaService, models: true do
+  describe 'Associations' do
+    it { is_expected.to belong_to :project }
+    it { is_expected.to have_one :service_hook }
+  end
+
+  describe 'Validations' do
+    context 'when service is active' do
+      before { subject.active = true }
+
+      it { is_expected.to validate_presence_of(:project_url) }
+      it { is_expected.to validate_presence_of(:issues_url) }
+      it { is_expected.to validate_presence_of(:new_issue_url) }
+      it_behaves_like 'issue tracker service URL attribute', :project_url
+      it_behaves_like 'issue tracker service URL attribute', :issues_url
+      it_behaves_like 'issue tracker service URL attribute', :new_issue_url
+    end
+
+    context 'when service is inactive' do
+      before { subject.active = false }
+
+      it { is_expected.not_to validate_presence_of(:project_url) }
+      it { is_expected.not_to validate_presence_of(:issues_url) }
+      it { is_expected.not_to validate_presence_of(:new_issue_url) }
+    end
+  end
+end
-- 
GitLab