From badf632f0b3022f91cbe8cecb523a5b2b8e1bddf Mon Sep 17 00:00:00 2001 From: hassaku63 Date: Sat, 7 Sep 2024 10:42:20 +0900 Subject: [PATCH] feat: add export search api support --- zendesk/mock/client.go | 16 ++++++++++++++++ zendesk/search.go | 41 +++++++++++++++++++++++++++++++++++++++++ zendesk/search_test.go | 25 +++++++++++++++++++++++++ 3 files changed, 82 insertions(+) diff --git a/zendesk/mock/client.go b/zendesk/mock/client.go index fe8720fb..5efb1ef3 100644 --- a/zendesk/mock/client.go +++ b/zendesk/mock/client.go @@ -2548,6 +2548,22 @@ func (mr *ClientMockRecorder) SearchCustomObjectRecords(ctx, customObjectKey, op return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchCustomObjectRecords", reflect.TypeOf((*Client)(nil).SearchCustomObjectRecords), ctx, customObjectKey, opts) } +// SearchExport mocks base method. +func (m *Client) SearchExport(ctx context.Context, opts *zendesk.SearchExportOptions) (zendesk.SearchResults, zendesk.CursorPaginationMeta, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SearchExport", ctx, opts) + ret0, _ := ret[0].(zendesk.SearchResults) + ret1, _ := ret[1].(zendesk.CursorPaginationMeta) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// SearchExport indicates an expected call of SearchExport. +func (mr *ClientMockRecorder) SearchExport(ctx, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchExport", reflect.TypeOf((*Client)(nil).SearchExport), ctx, opts) +} + // SearchUsers mocks base method. func (m *Client) SearchUsers(ctx context.Context, opts *zendesk.SearchUsersOptions) ([]zendesk.User, zendesk.Page, error) { m.ctrl.T.Helper() diff --git a/zendesk/search.go b/zendesk/search.go index 92497301..b838a721 100644 --- a/zendesk/search.go +++ b/zendesk/search.go @@ -23,9 +23,19 @@ type CountOptions struct { Query string `url:"query"` } +// SearchExportOptions are the options that can be provided to the export search API +// +// https://developer.zendesk.com/api-reference/ticketing/ticket-management/search/#export-search-results +type SearchExportOptions struct { + CursorPagination + Query string `url:"query"` + Filter string `url:"filter[type],omitempty"` +} + type SearchAPI interface { Search(ctx context.Context, opts *SearchOptions) (SearchResults, Page, error) SearchCount(ctx context.Context, opts *CountOptions) (int, error) + SearchExport(ctx context.Context, opts *SearchExportOptions) (SearchResults, CursorPaginationMeta, error) GetSearchIterator(ctx context.Context, opts *PaginationOptions) *Iterator[SearchResults] GetSearchOBP(ctx context.Context, opts *OBPOptions) ([]SearchResults, Page, error) GetSearchCBP(ctx context.Context, opts *CBPOptions) ([]SearchResults, CursorPaginationMeta, error) @@ -181,3 +191,34 @@ func (z *Client) SearchCount(ctx context.Context, opts *CountOptions) (int, erro return data.Count, nil } + +// SearchExport allows users to query zendesk's unified export search api. +// +// ref: https://developer.zendesk.com/api-reference/ticketing/ticket-management/search/#export-search-results +func (z *Client) SearchExport(ctx context.Context, opts *SearchExportOptions) (SearchResults, CursorPaginationMeta, error) { + var data struct { + Results SearchResults `json:"results"` + Meta CursorPaginationMeta `json:"meta"` + } + + if opts == nil { + return SearchResults{}, CursorPaginationMeta{}, &OptionsError{opts} + } + + u, err := addOptions("/search/export", opts) + if err != nil { + return SearchResults{}, CursorPaginationMeta{}, err + } + + body, err := z.get(ctx, u) + if err != nil { + return SearchResults{}, CursorPaginationMeta{}, err + } + + err = json.Unmarshal(body, &data) + if err != nil { + return SearchResults{}, CursorPaginationMeta{}, err + } + + return data.Results, data.Meta, nil +} diff --git a/zendesk/search_test.go b/zendesk/search_test.go index 29422ba9..88981ba6 100644 --- a/zendesk/search_test.go +++ b/zendesk/search_test.go @@ -49,6 +49,31 @@ func TestCountTickets(t *testing.T) { } } +func TestSearchExportTickets(t *testing.T) { + mockAPI := newMockAPI(http.MethodGet, "search_ticket.json") + client := newTestClient(mockAPI) + defer mockAPI.Close() + + results, _, err := client.SearchExport(ctx, &SearchExportOptions{}) + if err != nil { + t.Fatalf("Failed to get export search results: %s", err) + } + + list := results.List() + if len(list) != 1 { + t.Fatalf("expected length of sla policies is , but got %d", len(list)) + } + + ticket, ok := list[0].(Ticket) + if !ok { + t.Fatalf("Cannot assert %v as a ticket", list[0]) + } + + if ticket.ID != 4 { + t.Fatalf("Ticket did not have the expected id %v", ticket) + } +} + func BenchmarkUnmarshalSearchResults(b *testing.B) { file := readFixture("ticket_result.json") for i := 0; i < b.N; i++ {