Skip to content

Commit

Permalink
Merge pull request #115 from ctreminiom/feature/issue-search
Browse files Browse the repository at this point in the history
✨ Mapped the Jira Issue Search endpoints
  • Loading branch information
ctreminiom authored May 7, 2022
2 parents 6f45870 + d0392c4 commit c309175
Show file tree
Hide file tree
Showing 7 changed files with 410 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
uses: golangci/golangci-lint-action@v2
with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
version: v1.36
version: v1.38
# Optional: working directory, useful for monorepos
# working-directory: somedir

Expand All @@ -33,4 +33,4 @@ jobs:
# only-new-issues: true

# Optional: if set to true then the action will use pre-installed Go
# skip-go-installation: true
skip-go-installation: true
29 changes: 29 additions & 0 deletions jira/mocks/jira-issue-search-check.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"matches": [
{
"matchedIssues": [
10000,
10004
],
"errors": []
},
{
"matchedIssues": [
100134,
10025,
10236
],
"errors": []
},
{
"matchedIssues": [],
"errors": []
},
{
"matchedIssues": [],
"errors": [
"Invalid JQL: broken = value"
]
}
]
}
28 changes: 28 additions & 0 deletions jira/v2/issueSearch.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,31 @@ func (s *IssueSearchService) Post(ctx context.Context, jql string, fields, expan

return
}

// Checks checks whether one or more issues would be returned by one or more JQL queries.
// Docs: https://docs.go-atlassian.io/jira-software-cloud/issues/search#check-issues-against-jql
func (s *IssueSearchService) Checks(ctx context.Context, payload *models.IssueSearchCheckPayloadScheme) (result *models.IssueMatchesPageScheme,
response *ResponseScheme, err error) {

var endpoint = "rest/api/2/jql/match"

payloadAsReader, err := transformStructToReader(payload)
if err != nil {
return nil, nil, err
}

request, err := s.client.newRequest(ctx, http.MethodPost, endpoint, payloadAsReader)
if err != nil {
return
}

request.Header.Set("Accept", "application/json")
request.Header.Set("Content-Type", "application/json")

response, err = s.client.call(request, &result)
if err != nil {
return
}

return
}
154 changes: 154 additions & 0 deletions jira/v2/issueSearch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package v2
import (
"context"
"fmt"
"github.com/ctreminiom/go-atlassian/pkg/infra/models"
"github.com/stretchr/testify/assert"
"net/http"
"net/url"
Expand Down Expand Up @@ -446,3 +447,156 @@ func TestIssueSearchService_Post(t *testing.T) {
}

}

func TestIssueSearchService_Checks(t *testing.T) {

testCases := []struct {
name string
payload *models.IssueSearchCheckPayloadScheme
mockFile string
wantHTTPMethod string
endpoint string
context context.Context
wantHTTPCodeReturn int
wantErr bool
expectedError string
}{
{
name: "when the parameters are correct",
payload: &models.IssueSearchCheckPayloadScheme{
IssueIds: []int{1, 2, 3, 4},
JQLs: []string{"project = DUMMY"},
},
mockFile: "../mocks/jira-issue-search-check.json",
wantHTTPMethod: http.MethodPost,
endpoint: "/rest/api/2/jql/match",
context: context.Background(),
wantHTTPCodeReturn: http.StatusOK,
wantErr: false,
},

{
name: "when the payload is not provided",
payload: nil,
mockFile: "../mocks/jira-issue-search-check.json",
wantHTTPMethod: http.MethodPost,
endpoint: "/rest/api/2/jql/match",
context: context.Background(),
wantHTTPCodeReturn: http.StatusOK,
wantErr: true,
expectedError: "failed to parse the interface pointer, please provide a valid one",
},

{
name: "when the context is not provided",
payload: &models.IssueSearchCheckPayloadScheme{
IssueIds: []int{1, 2, 3, 4},
JQLs: []string{"project = DUMMY"},
},
mockFile: "../mocks/jira-issue-search-check.json",
wantHTTPMethod: http.MethodPost,
endpoint: "/rest/api/2/jql/match",
context: nil,
wantHTTPCodeReturn: http.StatusOK,
wantErr: true,
expectedError: "request creation failed: net/http: nil Context",
},

{
name: "when the response is invalid",
payload: &models.IssueSearchCheckPayloadScheme{
IssueIds: []int{1, 2, 3, 4},
JQLs: []string{"project = DUMMY"},
},
mockFile: "../mocks/jira-issue-search-check.json",
wantHTTPMethod: http.MethodPost,
endpoint: "/rest/api/2/jql/match",
context: context.Background(),
wantHTTPCodeReturn: http.StatusBadRequest,
wantErr: true,
expectedError: "request failed. Please analyze the request body for more details. Status Code: 400",
},

{
name: "when the response body is empty",
payload: &models.IssueSearchCheckPayloadScheme{
IssueIds: []int{1, 2, 3, 4},
JQLs: []string{"project = DUMMY"},
},
mockFile: "../mocks/empty-json.json",
wantHTTPMethod: http.MethodPost,
endpoint: "/rest/api/2/jql/match",
context: context.Background(),
wantHTTPCodeReturn: http.StatusOK,
wantErr: true,
expectedError: "unexpected end of JSON input",
},
}

for _, testCase := range testCases {

t.Run(testCase.name, func(t *testing.T) {

//Init a new HTTP mock server
mockOptions := mockServerOptions{
Endpoint: testCase.endpoint,
MockFilePath: testCase.mockFile,
MethodAccepted: testCase.wantHTTPMethod,
ResponseCodeWanted: testCase.wantHTTPCodeReturn,
}

mockServer, err := startMockServer(&mockOptions)
if err != nil {
t.Fatal(err)
}

defer mockServer.Close()

//Init the library instance
mockClient, err := startMockClient(mockServer.URL)
if err != nil {
t.Fatal(err)
}

i := &IssueSearchService{client: mockClient}

gotResult, gotResponse, err := i.Checks(testCase.context, testCase.payload)

if testCase.wantErr {

if err != nil {
t.Logf("error returned: %v", err.Error())
}

assert.EqualError(t, err, testCase.expectedError)

if gotResponse != nil {
t.Logf("HTTP Code Wanted: %v, HTTP Code Returned: %v", testCase.wantHTTPCodeReturn, gotResponse.Code)
}
} else {

assert.NoError(t, err)
assert.NotEqual(t, gotResponse, nil)
assert.NotEqual(t, gotResult, nil)

apiEndpoint, err := url.Parse(gotResponse.Endpoint)
if err != nil {
t.Fatal(err)
}

var endpointToAssert string

if apiEndpoint.Query().Encode() != "" {
endpointToAssert = fmt.Sprintf("%v?%v", apiEndpoint.Path, apiEndpoint.Query().Encode())
} else {
endpointToAssert = apiEndpoint.Path
}

t.Logf("HTTP Endpoint Wanted: %v, HTTP Endpoint Returned: %v", testCase.endpoint, endpointToAssert)
assert.Equal(t, testCase.endpoint, endpointToAssert)
}
})

}

}
28 changes: 28 additions & 0 deletions jira/v3/issueSearch.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,31 @@ func (s *IssueSearchService) Post(ctx context.Context, jql string, fields, expan

return
}

// Checks checks whether one or more issues would be returned by one or more JQL queries.
// Docs: https://docs.go-atlassian.io/jira-software-cloud/issues/search#check-issues-against-jql
func (s *IssueSearchService) Checks(ctx context.Context, payload *models.IssueSearchCheckPayloadScheme) (result *models.IssueMatchesPageScheme,
response *ResponseScheme, err error) {

var endpoint = "rest/api/3/jql/match"

payloadAsReader, err := transformStructToReader(payload)
if err != nil {
return nil, nil, err
}

request, err := s.client.newRequest(ctx, http.MethodPost, endpoint, payloadAsReader)
if err != nil {
return
}

request.Header.Set("Accept", "application/json")
request.Header.Set("Content-Type", "application/json")

response, err = s.client.call(request, &result)
if err != nil {
return
}

return
}
Loading

0 comments on commit c309175

Please sign in to comment.