diff --git a/components/ambee/ambee.app.mjs b/components/ambee/ambee.app.mjs index d51dc478ea059..6d294f1c7e090 100644 --- a/components/ambee/ambee.app.mjs +++ b/components/ambee/ambee.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/columns_ai/columns_ai.app.mjs b/components/columns_ai/columns_ai.app.mjs index 7ca69db8f2d66..0111513c3f0a3 100644 --- a/components/columns_ai/columns_ai.app.mjs +++ b/components/columns_ai/columns_ai.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/fullenrich/fullenrich.app.mjs b/components/fullenrich/fullenrich.app.mjs index afed55df7f4ca..45df43e97572a 100644 --- a/components/fullenrich/fullenrich.app.mjs +++ b/components/fullenrich/fullenrich.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/mitra/mitra.app.mjs b/components/mitra/mitra.app.mjs index 0eb51b3f45a3f..dca7dd079de66 100644 --- a/components/mitra/mitra.app.mjs +++ b/components/mitra/mitra.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/ngrok/ngrok.app.mjs b/components/ngrok/ngrok.app.mjs index c9bb2fdb1731a..8207685709577 100644 --- a/components/ngrok/ngrok.app.mjs +++ b/components/ngrok/ngrok.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/ollama/ollama.app.mjs b/components/ollama/ollama.app.mjs index d68ec62d87e1c..fd8f8a2f806a0 100644 --- a/components/ollama/ollama.app.mjs +++ b/components/ollama/ollama.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/sms_fusion/sms_fusion.app.mjs b/components/sms_fusion/sms_fusion.app.mjs index c5000cd2ba2d3..2fd7e3cded014 100644 --- a/components/sms_fusion/sms_fusion.app.mjs +++ b/components/sms_fusion/sms_fusion.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/spider/spider.app.mjs b/components/spider/spider.app.mjs index 98004efd50fdd..bc6076e3894ff 100644 --- a/components/spider/spider.app.mjs +++ b/components/spider/spider.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/stealthgpt/stealthgpt.app.mjs b/components/stealthgpt/stealthgpt.app.mjs index f3a0c1bdbb9d4..2814835f94524 100644 --- a/components/stealthgpt/stealthgpt.app.mjs +++ b/components/stealthgpt/stealthgpt.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/the_magic_drip/the_magic_drip.app.mjs b/components/the_magic_drip/the_magic_drip.app.mjs index 34e2097efbef1..0f4fb3f401b86 100644 --- a/components/the_magic_drip/the_magic_drip.app.mjs +++ b/components/the_magic_drip/the_magic_drip.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/tricentis_qtest/actions/create-requirement/create-requirement.mjs b/components/tricentis_qtest/actions/create-requirement/create-requirement.mjs new file mode 100644 index 0000000000000..a9a3543e7a14f --- /dev/null +++ b/components/tricentis_qtest/actions/create-requirement/create-requirement.mjs @@ -0,0 +1,61 @@ +import { + getFieldProps as additionalProps, getProperties, +} from "../../common/utils.mjs"; +import tricentisQtest from "../../tricentis_qtest.app.mjs"; + +export default { + key: "tricentis_qtest-create-requirement", + name: "Create Requirement", + description: "Create a new requirement. [See the documentation](https://documentation.tricentis.com/qtest/od/en/content/apis/apis/requirement_apis.htm#CreateARequirement)", + version: "0.0.1", + type: "action", + props: { + tricentisQtest, + projectId: { + propDefinition: [ + tricentisQtest, + "projectId", + ], + }, + parentId: { + propDefinition: [ + tricentisQtest, + "parentId", + ({ projectId }) => ({ + projectId, + }), + ], + reloadProps: true, + }, + name: { + type: "string", + label: "Name", + description: "Requirement name", + }, + }, + additionalProps, + methods: { + getDataFields() { + return this.tricentisQtest.getRequirementFields(this.projectId); + }, + getProperties, + }, + async run({ $ }) { + const { // eslint-disable-next-line no-unused-vars + tricentisQtest, projectId, parentId, name, getProperties, getDataFields, ...fields + } = this; + const response = await tricentisQtest.createRequirement({ + $, + projectId, + params: { + parentId, + }, + data: { + name, + properties: getProperties(fields), + }, + }); + $.export("$summary", `Successfully created requirement (ID: ${response.id})`); + return response; + }, +}; diff --git a/components/tricentis_qtest/actions/get-defect/get-defect.mjs b/components/tricentis_qtest/actions/get-defect/get-defect.mjs new file mode 100644 index 0000000000000..484cced52d4a1 --- /dev/null +++ b/components/tricentis_qtest/actions/get-defect/get-defect.mjs @@ -0,0 +1,38 @@ +import tricentisQtest from "../../tricentis_qtest.app.mjs"; + +export default { + key: "tricentis_qtest-get-defect", + name: "Get Defect", + description: "Get details of a defect. [See the documentation](https://documentation.tricentis.com/qtest/od/en/content/apis/apis/defect_apis.htm#GetRecentlyUpdatedDefects)", + version: "0.0.1", + type: "action", + props: { + tricentisQtest, + projectId: { + propDefinition: [ + tricentisQtest, + "projectId", + ], + }, + defectId: { + propDefinition: [ + tricentisQtest, + "defectId", + ({ projectId }) => ({ + projectId, + }), + ], + }, + }, + async run({ $ }) { + const { + tricentisQtest, ...args + } = this; + const response = await tricentisQtest.getDefect({ + $, + ...args, + }); + $.export("$summary", `Successfully fetched defect (ID: ${args.defectId})`); + return response; + }, +}; diff --git a/components/tricentis_qtest/actions/get-requirement/get-requirement.mjs b/components/tricentis_qtest/actions/get-requirement/get-requirement.mjs new file mode 100644 index 0000000000000..69ab98b6c3ff3 --- /dev/null +++ b/components/tricentis_qtest/actions/get-requirement/get-requirement.mjs @@ -0,0 +1,38 @@ +import tricentisQtest from "../../tricentis_qtest.app.mjs"; + +export default { + key: "tricentis_qtest-get-requirement", + name: "Get Requirement", + description: "Get details of a requirement. [See the documentation](https://documentation.tricentis.com/qtest/od/en/content/apis/apis/requirement_apis.htm#GetARequirementByItsID)", + version: "0.0.1", + type: "action", + props: { + tricentisQtest, + projectId: { + propDefinition: [ + tricentisQtest, + "projectId", + ], + }, + requirementId: { + propDefinition: [ + tricentisQtest, + "requirementId", + ({ projectId }) => ({ + projectId, + }), + ], + }, + }, + async run({ $ }) { + const { + tricentisQtest, ...args + } = this; + const response = await tricentisQtest.getRequirement({ + $, + ...args, + }); + $.export("$summary", `Successfully fetched requirement (ID: ${args.requirementId})`); + return response; + }, +}; diff --git a/components/tricentis_qtest/actions/submit-defect/submit-defect.mjs b/components/tricentis_qtest/actions/submit-defect/submit-defect.mjs new file mode 100644 index 0000000000000..c086243414e77 --- /dev/null +++ b/components/tricentis_qtest/actions/submit-defect/submit-defect.mjs @@ -0,0 +1,43 @@ +import { + getFieldProps as additionalProps, getProperties, +} from "../../common/utils.mjs"; +import tricentisQtest from "../../tricentis_qtest.app.mjs"; + +export default { + key: "tricentis_qtest-submit-defect", + name: "Submit Defect", + description: "Submit a new defect. [See the documentation](https://documentation.tricentis.com/qtest/od/en/content/apis/apis/defect_apis.htm#SubmitaDefect)", + version: "0.0.1", + type: "action", + props: { + tricentisQtest, + projectId: { + propDefinition: [ + tricentisQtest, + "projectId", + ], + reloadProps: true, + }, + }, + additionalProps, + methods: { + getDataFields() { + return this.tricentisQtest.getDefectFields(this.projectId); + }, + getProperties, + }, + async run({ $ }) { + const { // eslint-disable-next-line no-unused-vars + tricentisQtest, projectId, getProperties, getDataFields, ...fields + } = this; + const response = await tricentisQtest.createDefect({ + $, + projectId, + data: { + properties: getProperties(fields), + }, + }); + $.export("$summary", `Successfully submitted defect (ID: ${response.id})`); + return response; + }, +}; diff --git a/components/tricentis_qtest/actions/update-defect/update-defect.mjs b/components/tricentis_qtest/actions/update-defect/update-defect.mjs new file mode 100644 index 0000000000000..221b1df64ee5b --- /dev/null +++ b/components/tricentis_qtest/actions/update-defect/update-defect.mjs @@ -0,0 +1,53 @@ +import { + getFieldProps as additionalProps, getProperties, +} from "../../common/utils.mjs"; +import tricentisQtest from "../../tricentis_qtest.app.mjs"; + +export default { + key: "tricentis_qtest-update-defect", + name: "Update Defect", + description: "Update a defect. [See the documentation](https://documentation.tricentis.com/qtest/od/en/content/apis/apis/defect_apis.htm#UpdateADefect)", + version: "0.0.1", + type: "action", + props: { + tricentisQtest, + projectId: { + propDefinition: [ + tricentisQtest, + "projectId", + ], + }, + defectId: { + propDefinition: [ + tricentisQtest, + "defectId", + ({ projectId }) => ({ + projectId, + }), + ], + reloadProps: true, + }, + }, + additionalProps, + methods: { + getDataFields() { + return this.tricentisQtest.getDefectFields(this.projectId); + }, + getProperties, + }, + async run({ $ }) { + const { // eslint-disable-next-line no-unused-vars + tricentisQtest, projectId, defectId, getProperties, getDataFields, ...fields + } = this; + const response = await tricentisQtest.updateDefect({ + $, + projectId, + defectId, + data: { + properties: getProperties(fields), + }, + }); + $.export("$summary", `Successfully updated defect (ID: ${defectId})`); + return response; + }, +}; diff --git a/components/tricentis_qtest/actions/update-requirement/update-requirement.mjs b/components/tricentis_qtest/actions/update-requirement/update-requirement.mjs new file mode 100644 index 0000000000000..0b8daabe2263c --- /dev/null +++ b/components/tricentis_qtest/actions/update-requirement/update-requirement.mjs @@ -0,0 +1,65 @@ +import { + getFieldProps as additionalProps, getProperties, +} from "../../common/utils.mjs"; +import tricentisQtest from "../../tricentis_qtest.app.mjs"; + +export default { + key: "tricentis_qtest-update-requirement", + name: "Update Requirement", + description: "Update a requirement. [See the documentation](https://documentation.tricentis.com/qtest/od/en/content/apis/apis/requirement_apis.htm#UpdateARequirement)", + version: "0.0.1", + type: "action", + props: { + tricentisQtest, + projectId: { + propDefinition: [ + tricentisQtest, + "projectId", + ], + }, + requirementId: { + propDefinition: [ + tricentisQtest, + "requirementId", + ({ projectId }) => ({ + projectId, + }), + ], + reloadProps: true, + }, + name: { + type: "string", + label: "Name", + description: "Requirement name", + }, + }, + additionalProps, + methods: { + getDataFields() { + return this.tricentisQtest.getRequirementFields(this.projectId); + }, + getProperties, + }, + async run({ $ }) { + const { /* eslint-disable no-unused-vars */ + tricentisQtest, + projectId, + requirementId, + name, + getProperties, + getDataFields, + ...fields + } = this; /* eslint-enable no-unused-vars */ + const response = await tricentisQtest.updateRequirement({ + $, + projectId, + requirementId, + data: { + name, + properties: getProperties(fields), + }, + }); + $.export("$summary", `Successfully updated requirement (ID: ${requirementId})`); + return response; + }, +}; diff --git a/components/tricentis_qtest/common/utils.mjs b/components/tricentis_qtest/common/utils.mjs new file mode 100644 index 0000000000000..33b88936dc8c3 --- /dev/null +++ b/components/tricentis_qtest/common/utils.mjs @@ -0,0 +1,53 @@ +export async function getFieldProps() { + if (this.useFields === false) return {}; + + const fields = await this.getDataFields(); + + function getFieldType(type) { + switch (type) { + case "Number": + return "integer"; + case "ArrayNumber": + return "integer[]"; + default: + return "string"; + } + } + + const result = {}; + const isUpdate = !!(this.requirementId || this.defectId); + + fields?.forEach(({ + id, label, attribute_type: fieldType, allowed_values: options, required, + }) => { + const type = getFieldType(fieldType); + result[`field_${id}`] = { + label, + type, + description: `Field ID: ${id} (type: ${fieldType})`, + optional: isUpdate || !required, + ...(options && { + options: options.map(({ + label, value, + }) => ({ + label, + value: (type === "string" && typeof value !== "string") + ? value.toString() + : value, + })), + }), + }; + }); + + return result; +} + +export function getProperties(fields) { + return fields && Object.entries(fields).map(([ + id, + value, + ]) => ({ + field_id: id.split("_").pop(), + field_value: value, + })); +} diff --git a/components/tricentis_qtest/package.json b/components/tricentis_qtest/package.json index f98b0564572c9..6ca738085ce8e 100644 --- a/components/tricentis_qtest/package.json +++ b/components/tricentis_qtest/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/tricentis_qtest", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Tricentis qTest Components", "main": "tricentis_qtest.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.3" } -} \ No newline at end of file +} diff --git a/components/tricentis_qtest/tricentis_qtest.app.mjs b/components/tricentis_qtest/tricentis_qtest.app.mjs index e8b10fb7a1289..a6fe4c2c92dbb 100644 --- a/components/tricentis_qtest/tricentis_qtest.app.mjs +++ b/components/tricentis_qtest/tricentis_qtest.app.mjs @@ -1,11 +1,196 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "tricentis_qtest", - propDefinitions: {}, + propDefinitions: { + projectId: { + type: "string", + label: "Project ID", + description: "The ID of a project", + async options() { + const projects = await this.getProjects(); + return (projects ?? []).map(({ + id, name, + }) => ({ + label: name, + value: id, + })); + }, + }, + parentId: { + type: "string", + label: "Parent ID", + description: "The parent module which will contain the newly created requirement", + async options({ projectId }) { + const modules = await this.getModules(projectId); + return (modules ?? []).map(({ + id, name, + }) => ({ + label: name, + value: id, + })); + }, + }, + requirementId: { + type: "string", + label: "Requirement ID", + description: "The ID of a requirement", + async options({ + page = 0, projectId, + }) { + const requirements = await this.getRequirements({ + projectId, + params: { + page: page + 1, + }, + }); + return (requirements ?? []).map(({ + id, name, + }) => ({ + label: name, + value: id, + })); + }, + }, + defectId: { + type: "string", + label: "Defect ID", + description: "The ID of a defect. The listed options are defects that have been updated in the last 30 days.", + async options({ + page = 0, projectId, prevContext: { startTime }, + }) { + if (!startTime) { + const date = new Date(); + date.setDate(date.getDate() - 30); + startTime = date.toISOString(); + } + const fields = await this.getDefectFields(projectId); + const summaryId = fields.find(({ label }) => label === "Summary")?.id; + const defects = await this.getDefects({ + projectId, + params: { + page: page + 1, + startTime, + }, + }); + return { + options: (defects ?? []).map(({ + id, properties, + }) => ({ + label: properties.find((f) => f.field_id === summaryId)?.field_value ?? id, + value: id, + })), + context: { + startTime, + }, + }; + }, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return `https://${this.$auth.qtest_base_uri}/api/v3`; + }, + async _makeRequest({ + $ = this, headers, ...otherOpts + }) { + return axios($, { + ...otherOpts, + baseURL: this._baseUrl(), + headers: { + ...headers, + Authorization: `Bearer ${this.$auth.oauth_access_token}`, + }, + }); + }, + getProjects() { + return this._makeRequest({ + url: "/projects", + }); + }, + getModules(projectId) { + return this._makeRequest({ + url: `/projects/${projectId}/modules`, + }); + }, + createRequirement({ + projectId, ...args + }) { + return this._makeRequest({ + method: "POST", + url: `/projects/${projectId}/requirements`, + ...args, + }); + }, + getRequirement({ + projectId, requirementId, ...args + }) { + return this._makeRequest({ + url: `/projects/${projectId}/requirements/${requirementId}`, + ...args, + }); + }, + getRequirements({ + projectId, ...args + }) { + return this._makeRequest({ + url: `/projects/${projectId}/requirements`, + ...args, + }); + }, + updateRequirement({ + projectId, requirementId, ...args + }) { + return this._makeRequest({ + method: "PUT", + url: `/projects/${projectId}/requirements/${requirementId}`, + ...args, + }); + }, + getRequirementFields(projectId) { + return this._makeRequest({ + url: `/projects/${projectId}/settings/requirements/fields`, + }); + }, + createDefect({ + projectId, ...args + }) { + return this._makeRequest({ + method: "POST", + url: `/projects/${projectId}/defects`, + ...args, + }); + }, + getDefect({ + projectId, defectId, ...args + }) { + return this._makeRequest({ + url: `/projects/${projectId}/defects/${defectId}`, + ...args, + }); + }, + getDefects({ + projectId, ...args + }) { + return this._makeRequest({ + url: `/projects/${projectId}/defects/last-change`, + ...args, + }); + }, + updateDefect({ + projectId, defectId, ...args + }) { + return this._makeRequest({ + method: "PUT", + url: `/projects/${projectId}/defects/${defectId}`, + ...args, + }); + }, + getDefectFields(projectId) { + return this._makeRequest({ + url: `/projects/${projectId}/settings/defects/fields`, + }); }, }, }; diff --git a/components/tuesday/tuesday.app.mjs b/components/tuesday/tuesday.app.mjs index c1db9f8b59a1e..d448255862932 100644 --- a/components/tuesday/tuesday.app.mjs +++ b/components/tuesday/tuesday.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed825eed80aef..08488204f3136 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10321,7 +10321,10 @@ importers: specifiers: {} components/tricentis_qtest: - specifiers: {} + specifiers: + '@pipedream/platform': ^3.0.3 + dependencies: + '@pipedream/platform': 3.0.3 components/triggercmd: specifiers: {}