Skip to content

feat: Add possibility to deal with Zis Job spec inside the zendesk ap… #136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions __tests__/services/zendesk-api-service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -594,4 +594,107 @@ describe("ZendeskService", () => {
expect(result).toEqual(zisIntegration);
});
});

describe("jobSpecs", () => {
const jobSpec = {
description: "Test Job",
event_source: "source",
event_type: "type",
flow_name: "flow",
installed: true,
integration: "integration",
name: "jobName",
uuid: "uuid"
};

it("should fetchs jobs and call Zendesk API multiple times if has more is true", async () => {
requestMock
.mockResolvedValueOnce({
job_specs: [jobSpec],
meta: {
has_more: true,
after: "1"
}
})
.mockResolvedValueOnce({
job_specs: [jobSpec],
meta: {
has_more: false
}
});

const data = await service.fetchZisJobSpecs("integrationName");

expect(requestMock).toHaveBeenNthCalledWith(1, {
url: "/api/services/zis/registry/integrationName/job_specs",
type: "GET",
data: {
page: {
size: "100"
}
}
});
expect(requestMock).toHaveBeenNthCalledWith(2, {
url: "/api/services/zis/registry/integrationName/job_specs",
type: "GET",
data: {
page: {
after: "1",
size: "100"
}
}
});
expect(requestMock).toHaveBeenCalledTimes(2);
expect(data).toHaveLength(2);
});

it("should fetchs jobs with correct data", async () => {
requestMock.mockResolvedValueOnce({
job_specs: [jobSpec],
meta: {
has_more: false
}
});

const data = await service.fetchZisJobSpecs("integrationName", {
page: {
size: "5"
}
});

expect(requestMock).toHaveBeenNthCalledWith(1, {
url: "/api/services/zis/registry/integrationName/job_specs",
type: "GET",
data: {
page: {
size: "5"
}
}
});
expect(requestMock).toHaveBeenCalledTimes(1);
expect(data).toHaveLength(1);
});

it("should create a job spec with correct data", async () => {
await service.createZisJobSpec("job_name_test");

expect(requestMock).toHaveBeenNthCalledWith(1, {
url: "/api/services/zis/registry/job_specs/install?job_spec_name=job_name_test",
type: "POST",
contentType: "application/json"
});
expect(requestMock).toHaveBeenCalledTimes(1);
});

it("should delete a job spec with correct data", async () => {
await service.deleteZisJobSpec("job_name_test");

expect(requestMock).toHaveBeenNthCalledWith(1, {
url: "/api/services/zis/registry/job_specs/install?job_spec_name=job_name_test",
type: "DELETE",
contentType: "application/json"
});
expect(requestMock).toHaveBeenCalledTimes(1);
});
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zendesk/zaf-toolbox",
"version": "0.6.0",
"version": "0.7.0",
"description": "A toolbox for ZAF application built with 🩷 by Zendesk Labs",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
Expand Down
4 changes: 2 additions & 2 deletions src/models/custom-objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export enum ListCutomObjectRecordsSortingOptions {
MINUS_UPDATED_AT = "-updated_at"
}

export interface IListCustomObjectRecordsFilter {
export interface IListFilter {
filter?: {
/**
* Comma separated list of external ids of records
Expand Down Expand Up @@ -141,7 +141,7 @@ export interface IListCustomObjectRecordsFilter {
sort?: ListCutomObjectRecordsSortingOptions;
}

export interface ISearchCustomObjectRecordsFilter extends IListCustomObjectRecordsFilter {
export interface ISearchCustomObjectRecordsFilter extends IListFilter {
query: string;
}

Expand Down
19 changes: 19 additions & 0 deletions src/models/zendesk-integration-services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,22 @@ export interface IZisIntegration {
export interface IZisIntegrationResponse {
integrations: IZisIntegration[];
}

export interface IZisJobspec {
description: string;
event_source: string;
event_type: string;
flow_name: string;
installed: boolean;
integration: string;
name: string;
uuid: string;
}
export interface IZisJobspecsResponse {
job_specs: IZisJobspec[];
meta: {
after: string;
before: string;
has_more: boolean;
};
}
10 changes: 5 additions & 5 deletions src/services/custom-object-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
IGetCustomObjectRecordsResponse,
IListCustomObjectsResponse,
ICreateCustomObjectRecordBody,
IListCustomObjectRecordsFilter,
IListFilter,
IListCustomObjectRecordsResponse,
ICustomObjectRecord,
ListCutomObjectRecordsSortingOptions,
Expand Down Expand Up @@ -124,7 +124,7 @@ export class CustomObjectService {
*/
public async listCustomObjectRecords<T extends ICustomObjectRecordField>(
key: string,
data?: IListCustomObjectRecordsFilter
data?: IListFilter
): Promise<ICustomObjectRecord<T>[]> {
const { custom_object_records } = await this.client.request<any, IListCustomObjectRecordsResponse<T>>({
url: `/api/v2/custom_objects/${key}/records`,
Expand All @@ -145,7 +145,7 @@ export class CustomObjectService {
): Promise<ICustomObjectRecord<T>[]> {
return this.fetchAllPaginatedRecords<T>(`/api/v2/custom_objects/${key}/records`, {
sort: sortOptions?.sort
} as IListCustomObjectRecordsFilter);
} as IListFilter);
}

/**
Expand Down Expand Up @@ -263,7 +263,7 @@ export class CustomObjectService {
*/
private async fetchAllPaginatedRecords<T extends ICustomObjectRecordField>(
url: string,
initialData: IListCustomObjectRecordsFilter
initialData: IListFilter
): Promise<ICustomObjectRecord<T>[]> {
let hasMore = true;
let data = initialData;
Expand All @@ -290,7 +290,7 @@ export class CustomObjectService {
sort: initialData.sort
}
: undefined)
} as IListCustomObjectRecordsFilter;
} as IListFilter;
}
} while (hasMore);

Expand Down
77 changes: 75 additions & 2 deletions src/services/zendesk-api-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,15 @@ import {
IZendeskResponse,
Line,
IMessage,
IMessagesResults
IMessagesResults,
IListFilter
} from "@models/index";
import { IZisIntegration, IZisIntegrationResponse } from "@models/zendesk-integration-services";
import {
IZisIntegration,
IZisIntegrationResponse,
IZisJobspec,
IZisJobspecsResponse
} from "@models/zendesk-integration-services";
import { convertContentMessageToHtml } from "@utils/convert-content-message-to-html";
import { getFromClient } from "@utils/get-from-client";
import { Client } from "@zendesk/sell-zaf-app-toolbox";
Expand Down Expand Up @@ -325,4 +331,71 @@ export class ZendeskApiService {
})
});
}

/**
* Fetch Zis job specs from an integration
*
* @param {string} integrationName Name of the Zis integration
* @returns {Promise<unknown>} List of Zis job specs
*/
public async fetchZisJobSpecs(integrationName: string, filterTheList?: IListFilter): Promise<IZisJobspec[]> {
let hasMore = true;
const numberOfJobSpecs = "100"; // Maximum number of job specs per page
let jobspecs: IZisJobspec[] = [];
let data: IListFilter = filterTheList ?? {
page: {
size: numberOfJobSpecs
}
};

do {
const response = await this.client.request<unknown, IZisJobspecsResponse>({
url: `/api/services/zis/registry/${integrationName}/job_specs`,
type: "GET",
data
});

jobspecs = [...jobspecs, ...response.job_specs];

hasMore = response.meta.has_more;
if (hasMore) {
data = {
page: {
after: response.meta.after,
size: numberOfJobSpecs
}
};
}
} while (hasMore);

return jobspecs;
}

/**
* Install a Zis job spec for an integration
*
* @param {string} jobSpecName Name of the Zis job spec to install
* @returns {Promise<void>} Resolves when the job spec is installed
*/
public async createZisJobSpec(jobSpecName: string): Promise<void> {
return await this.client.request({
url: `/api/services/zis/registry/job_specs/install?job_spec_name=${encodeURIComponent(jobSpecName)}`,
contentType: "application/json",
type: "POST"
});
}

/**
* Delete a Zis job spec for an integration
*
* @param {string} jobSpecName Name of the Zis job spec to delete
* @returns {Promise<void>} Resolves when the job spec is deleted
*/
public async deleteZisJobSpec(jobSpecName: string): Promise<void> {
return await this.client.request({
url: `/api/services/zis/registry/job_specs/install?job_spec_name=${encodeURIComponent(jobSpecName)}`,
contentType: "application/json",
type: "DELETE"
});
}
}