Commit 9a6545a8 authored by Alexandru Croitor's avatar Alexandru Croitor

Build jql with search and labels params

Add the ability to build jql when search and labels params are provided
parent 1e691756
......@@ -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