Commit 92fdc71b authored by Markus Koller's avatar Markus Koller

Merge branch 'add-search-support-to-jql-builder' into 'master'

Build jql with search and labels params

See merge request gitlab-org/gitlab!35865
parents d9fa04df 9a6545a8
......@@ -2,29 +2,66 @@
module Jira
class JqlBuilderService
DEFAULT_SORT = "created"
DEFAULT_SORT_DIRECTION = "DESC"
DEFAULT_SORT = 'created'
DEFAULT_SORT_DIRECTION = 'DESC'
# https://confluence.atlassian.com/jirasoftwareserver082/search-syntax-for-text-fields-974359692.html
JQL_SPECIAL_CHARS = %w[" + . , ; ? | * / % ^ $ # @ [ ] \\].freeze
def initialize(jira_project_key, params = {})
@jira_project_key = jira_project_key
@search = params[:search]
@labels = params[:labels]
@sort = params[:sort] || DEFAULT_SORT
@sort_direction = params[:sort_direction] || DEFAULT_SORT_DIRECTION
end
def execute
[by_project, order_by].join(' ')
[
jql_filters,
order_by
].join(' ')
end
private
attr_reader :jira_project_key, :sort, :sort_direction
attr_reader :jira_project_key, :sort, :sort_direction, :search, :labels
def jql_filters
[
by_project,
by_labels,
by_summary_and_description
].compact.join(' AND ')
end
def by_summary_and_description
return if search.blank?
escaped_search = remove_special_chars(search)
%Q[(summary ~ "#{escaped_search}" OR description ~ "#{escaped_search}")]
end
def by_project
"project = #{jira_project_key}"
end
def by_labels
return if labels.blank?
labels.map { |label| %Q[labels = "#{escape_quotes(label)}"] }.join(' AND ')
end
def order_by
"order by #{sort} #{sort_direction}"
end
def escape_quotes(param)
param.gsub('\\', '\\\\\\').gsub('"', '\\"')
end
def remove_special_chars(param)
param.delete(JQL_SPECIAL_CHARS.join).downcase.squish
end
end
end
......@@ -10,7 +10,47 @@ RSpec.describe Jira::JqlBuilderService do
let(:params) { {} }
it 'builds jql with default ordering' do
expect(subject).to eq("project = PROJECT_KEY order by created DESC")
expect(subject).to eq('project = PROJECT_KEY order by created DESC')
end
end
context 'with search param' do
let(:params) { { search: 'new issue' } }
it 'builds jql' do
expect(subject).to eq("project = PROJECT_KEY AND (summary ~ \"new issue\" OR description ~ \"new issue\") order by created DESC")
end
context 'search param with single qoutes' do
let(:params) { { search: "new issue's" } }
it 'builds jql' do
expect(subject).to eq("project = PROJECT_KEY AND (summary ~ \"new issue's\" OR description ~ \"new issue's\") order by created DESC")
end
end
context 'search param with single double qoutes' do
let(:params) { { search: '"one \"more iss\'ue"' } }
it 'builds jql' do
expect(subject).to eq("project = PROJECT_KEY AND (summary ~ \"one more iss'ue\" OR description ~ \"one more iss'ue\") order by created DESC")
end
end
context 'search param with special characters' do
let(:params) { { search: 'issues' + Jira::JqlBuilderService::JQL_SPECIAL_CHARS.join(" AND ") } }
it 'builds jql' do
expect(subject).to eq("project = PROJECT_KEY AND (summary ~ \"issues and and and and and and and and and and and and and and and and\" OR description ~ \"issues and and and and and and and and and and and and and and and and\") order by created DESC")
end
end
end
context 'with labels param' do
let(:params) { { labels: ['label1', 'label2', "\"'try\"some'more\"quote'here\""] } }
it 'builds jql' do
expect(subject).to eq("project = PROJECT_KEY AND labels = \"label1\" AND labels = \"label2\" AND labels = \"\\\"'try\\\"some'more\\\"quote'here\\\"\" order by created DESC")
end
end
......@@ -18,7 +58,7 @@ RSpec.describe Jira::JqlBuilderService do
let(:params) { { sort: 'updated', sort_direction: 'ASC' } }
it 'builds jql' do
expect(subject).to eq("project = PROJECT_KEY order by updated ASC")
expect(subject).to eq('project = PROJECT_KEY order by updated ASC')
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment