diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 038d12f..4118256 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -18,6 +18,12 @@ jobs: run: npm install - name: Run eslint run: npm run lint + - name: Run tests + run: npm run test + env: + BOTCITY_SERVER: ${{ secrets.BOTCITY_SERVER }} + BOTCITY_LOGIN: ${{ secrets.BOTCITY_LOGIN }} + BOTCITY_KEY: ${{ secrets.BOTCITY_KEY }} - name: Execute build 🔧 run: npm run build - name: Publish package on NPM 📦 diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index 577bd3a..719e937 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -13,4 +13,12 @@ jobs: - name: Install dependencies run: npm install - name: Run eslint - run: npm run lint \ No newline at end of file + run: npm run lint + - name: Run tests + run: npm run test + env: + BOTCITY_SERVER: ${{ secrets.BOTCITY_SERVER }} + BOTCITY_LOGIN: ${{ secrets.BOTCITY_LOGIN }} + BOTCITY_KEY: ${{ secrets.BOTCITY_KEY }} + - name: Execute build 🔧 + run: npm run build \ No newline at end of file diff --git a/.gitignore b/.gitignore index ccb2c80..9a30b15 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ -package-lock.json \ No newline at end of file +package-lock.json +.env \ No newline at end of file diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..b413e10 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,5 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', +}; \ No newline at end of file diff --git a/package.json b/package.json index eb725b2..40b0d79 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "lint:fix": "eslint --fix src/**/*.{js,ts,json}", "format": "prettier --write src/**/*.{js,ts,md,json} --config ./.prettierrc", "commit": "git-cz", - "prepare": "husky install" + "prepare": "husky install", + "test": "jest" }, "release-it": { "npm": { @@ -44,7 +45,10 @@ "@commitlint/cli": "17.1.2", "@commitlint/config-conventional": "17.1.0", "@rocketseat/eslint-config": "1.1.3", + "@types/jest": "^29.5.12", "@types/node": "^14.18.33", + "@types/tmp": "^0.2.6", + "@types/uuid": "^9.0.8", "@typescript-eslint/eslint-plugin": "^5.36.2", "@typescript-eslint/parser": "5.36.2", "commitizen": "4.2.5", @@ -58,13 +62,19 @@ "eslint-plugin-prettier": "4.2.1", "eslint-plugin-promise": "^6.0.1", "husky": "8.0.1", + "jest": "^29.7.0", + "moment": "^2.30.1", "prettier": "2.7.1", "release-it": "^15.4.1", "rimraf": "^3.0.2", - "typescript": "^4.8.2" + "tmp": "^0.2.3", + "ts-jest": "^29.1.2", + "typescript": "^4.8.2", + "uuid": "^9.0.1" }, "dependencies": { "axios": "^1.6.0", + "dotenv": "^16.4.5", "form-data": "^4.0.0" }, "engines": { diff --git a/src/botcity/maestro/interfaces/task.ts b/src/botcity/maestro/interfaces/task.ts index ed57efb..8d5c9b6 100644 --- a/src/botcity/maestro/interfaces/task.ts +++ b/src/botcity/maestro/interfaces/task.ts @@ -3,15 +3,27 @@ export interface Task { state: string parameters: object activityId: number + userEmail: string | null agentId: string userCreationName: string + organizationLabel: string | null organizationCreationId: number dateCreation: string // TODO: Transform in date dateLastModified: string // TODO: Transform in date finishStatus?: string finishMessage?: string test: boolean + interrupted: boolean | null + machineId: string | number | null activityLabel?: string + minExecutionDate: string | Date + killed: boolean | null + dateStartRunning: string | Date + priority: number | null + repositoryLabel: string + processedItems: number | null + failedItems: number | null + totalItems: number | null } // TODO: Implement endpoint getTasks diff --git a/src/botcity/maestro/sdk.ts b/src/botcity/maestro/sdk.ts index 0adf32d..e2befaf 100644 --- a/src/botcity/maestro/sdk.ts +++ b/src/botcity/maestro/sdk.ts @@ -1,7 +1,17 @@ import axios, { AxiosResponse } from 'axios' -import { ensureAccessToken, catchError, getMessageInError, getStackInError, getTypeInError, getDefaultTags, createNpmList, verifyUrlServer } from './utils' +import { + ensureAccessToken, + catchError, + getMessageInError, + getStackInError, + getTypeInError, + getDefaultTags, + createNpmList, + verifyUrlServer +} from './utils' import { Alert, DataLog, Log, Logs, Task, Artifact, Artifacts } from './interfaces' import fs from 'fs' +import https from 'https' import FormData from 'form-data' import { Column } from './columns' import { basename } from 'path' @@ -11,12 +21,14 @@ export class BotMaestroSdk { private _login: string private _key: string private _accessToken: string + private _verifySSLCert: boolean - constructor (server: string, login: string, key: string) { + constructor (server: string, login: string, key: string, verifySSLCert: boolean = true) { this._server = verifyUrlServer(server) this._login = login this._key = key this._accessToken = '' + this._verifySSLCert = verifySSLCert } get server (): string { @@ -28,7 +40,10 @@ export class BotMaestroSdk { } private get headers (): Object { - return { headers: { token: this.accessToken, organization: this._login } } + return { + headers: { token: this.accessToken, organization: this._login }, + httpsAgent: this._getHttpsAgent() + } } get accessToken (): string { @@ -39,6 +54,72 @@ export class BotMaestroSdk { this._accessToken = accessToken } + get verify (): string { + return this._accessToken + } + + set verifySSLCert (verifySSLCert: boolean) { + this._verifySSLCert = verifySSLCert + } + + get verifySSLCert (): boolean { + return this._verifySSLCert + } + + get isOnline (): boolean { + return this.accessToken !== '' + } + + private _getHttpsAgent (): https.Agent { + return new https.Agent({ + rejectUnauthorized: this.verifySSLCert + }) + } + + private _validateItems ( + totalItems: number | null, + processedItems: number | null, + failedItems: number | null + ): any[] { + if (totalItems === null && processedItems === null && failedItems === null) { + console.warn( + `Attention: this task is not reporting items. Please inform the total, processed and failed items. + Reporting items is a crucial step to calculate the ROI, success rate and other metrics for your automation + via BotCity Insights.` + ) + return [null, null, null] + } + + if (totalItems === null && processedItems !== null && failedItems !== null) { + totalItems = processedItems + failedItems + } + + if (totalItems !== null && processedItems !== null && failedItems === null) { + failedItems = totalItems - processedItems + } + + if (totalItems !== null && processedItems === null && failedItems !== null) { + processedItems = totalItems - failedItems + } + + if (totalItems === null || processedItems === null || failedItems === null) { + throw new Error( + 'You must inform at least two of the following parameters: totalItems, processedItems, failedItems.' + ) + } + + totalItems = Math.max(0, totalItems) + processedItems = Math.max(0, processedItems) + failedItems = Math.max(0, failedItems) + + if (totalItems !== null && processedItems !== null && failedItems !== null) { + if (totalItems !== processedItems + failedItems) { + throw new Error('Total items is not equal to the sum of processed and failed items.') + } + } + return [totalItems, processedItems, failedItems] + } + async login (server: string = '', login: string = '', key: string = ''): Promise { try { if (server !== '') { @@ -62,7 +143,9 @@ export class BotMaestroSdk { const url = `${this.server}/api/v2/workspace/login` const data = { login: this._login, key: this._key } - const response: AxiosResponse = await axios.post(url, data) + const response: AxiosResponse = await axios.post(url, data, { + httpsAgent: this._getHttpsAgent() + }) this.accessToken = response.data.accessToken } catch (error) { console.error(error) @@ -79,13 +162,22 @@ export class BotMaestroSdk { async createTask ( activityLabel: string, parameters: Object, - test: boolean = false + test: boolean = false, + priority: number = 0, + minExecutionDate: Date | null = null ): Promise { const url = `${this.server}/api/v2/task` - const data = { activityLabel, test, parameters } + const data = { + activityLabel, + test, + parameters, + priority, + minExecutionDate: minExecutionDate instanceof Date ? minExecutionDate.toISOString() : null + } const response: AxiosResponse = await axios .post(url, data, this.headers) .catch((error: any) => { + console.log(error) throw new Error(error.response.data.message) }) return response.data @@ -96,10 +188,25 @@ export class BotMaestroSdk { async finishTask ( taskId: string | number, finishStatus: Object, - finishMessage: string = '' + finishMessage: string = '', + totalItems: number | null = null, + processedItems: number | null = null, + failedItems: number | null = null ): Promise { const url = `${this.server}/api/v2/task/${taskId}` - const data = { state: 'FINISHED', finishStatus, finishMessage } + const [validTotalItems, validProcessedItems, validFailedItems] = this._validateItems( + totalItems, + processedItems, + failedItems + ) + const data = { + state: 'FINISHED', + finishStatus, + finishMessage, + totalItems: validTotalItems, + processedItems: validProcessedItems, + failedItems: validFailedItems + } const response: AxiosResponse = await axios .post(url, data, this.headers) .catch((error: any) => { @@ -120,9 +227,7 @@ export class BotMaestroSdk { @ensureAccessToken @catchError - async restartTask ( - taskId: string | number - ): Promise { + async restartTask (taskId: string | number): Promise { const url = `${this.server}/api/v2/task/${taskId}` const data = { state: 'START' } const response: AxiosResponse = await axios @@ -135,9 +240,7 @@ export class BotMaestroSdk { @ensureAccessToken @catchError - async interruptTask ( - taskId: string | number - ): Promise { + async interruptTask (taskId: string | number): Promise { const url = `${this.server}/api/v2/task/${taskId}` const data = { interrupted: true } const response: AxiosResponse = await axios @@ -176,6 +279,7 @@ export class BotMaestroSdk { async getLog (idLog: string): Promise { const url = `${this.server}/api/v2/log/${idLog}` const response: AxiosResponse = await axios.get(url, this.headers).catch((error: any) => { + console.log(error) throw new Error(error.response.data.message) }) return response.data @@ -225,7 +329,12 @@ export class BotMaestroSdk { @ensureAccessToken @catchError - async createAlert (taskId: string, title: string, message: string, type: string): Promise { + async createAlert ( + taskId: string | number, + title: string, + message: string, + type: string + ): Promise { const url = `${this.server}/api/v2/alerts` const data = { taskId, title, message, type } const response: AxiosResponse = await axios @@ -254,7 +363,7 @@ export class BotMaestroSdk { @ensureAccessToken @catchError - async createArtifact (taskId: string, name: string, filename: string): Promise { + async createArtifact (taskId: string | number, name: string, filename: string): Promise { const url = `${this.server}/api/v2/artifact` const data = { taskId, name, filename } const response: AxiosResponse = await axios @@ -285,7 +394,7 @@ export class BotMaestroSdk { @ensureAccessToken @catchError async uploadArtifact ( - taskId: string, + taskId: string | number, name: string, filename: string, filepath: string @@ -329,7 +438,13 @@ export class BotMaestroSdk { @ensureAccessToken @catchError - async createError (taskId: string, error: Error, tags: object = {}, screenshot: string = '', attachments: string[] = []): Promise { + async createError ( + taskId: string | number, + error: Error, + tags: object = {}, + screenshot: string = '', + attachments: string[] = [] + ): Promise { const message: string = getMessageInError(error) const type: string = getTypeInError(error) const stackTrace: string = getStackInError(error) @@ -359,10 +474,7 @@ export class BotMaestroSdk { } } - async getCredential ( - label: string, - key: string - ): Promise { + async getCredential (label: string, key: string): Promise { const url = `${this.server}/api/v2/credential/${label}/key/${key}` const response: AxiosResponse = await axios.get(url, this.headers).catch((error: any) => { throw new Error(error.response.data.message) @@ -391,9 +503,7 @@ export class BotMaestroSdk { } } - async getCredentialByLabel ( - label: string - ): Promise { + async getCredentialByLabel (label: string): Promise { const url = `${this.server}/api/v2/credential/${label}` try { const response: AxiosResponse = await axios.get(url, this.headers) @@ -426,16 +536,10 @@ export class BotMaestroSdk { } } - async createCredentialByLabel ( - label: string, - key: string, - value: any - ): Promise { + async createCredentialByLabel (label: string, key: string, value: any): Promise { const data = { label, - secrets: [ - { key, value, valid: true } - ] + secrets: [{ key, value, valid: true }] } const url = `${this.server}/api/v2/credential` const credential = await axios.post(url, data, this.headers).catch((error: any) => { @@ -446,11 +550,7 @@ export class BotMaestroSdk { @ensureAccessToken @catchError - async createCredential ( - label: string, - key: string, - value: any - ): Promise { + async createCredential (label: string, key: string, value: any): Promise { let credential = await this.getCredentialByLabel(label) if (credential == null) { credential = await this.createCredentialByLabel(label, key, value) diff --git a/src/botcity/maestro/utils.ts b/src/botcity/maestro/utils.ts index 11c67b2..da37267 100644 --- a/src/botcity/maestro/utils.ts +++ b/src/botcity/maestro/utils.ts @@ -94,10 +94,7 @@ export const createNpmList = async (): Promise => { } const tmpFile = (filename: string): string => { - return path.join( - os.tmpdir(), - filename - ).toString() + return path.join(os.tmpdir(), filename).toString() } export const verifyUrlServer = (server: string): string => { diff --git a/tests/index.ts b/tests/index.ts deleted file mode 100644 index 6b45765..0000000 --- a/tests/index.ts +++ /dev/null @@ -1,121 +0,0 @@ -// import { BotMaestroSdk } from "../src/botcity" - -// const sdk = new BotMaestroSdk( -// ) - -// const tasks = async () => { - // await sdk.login() - // const parametersCreateTask = { - // "param1": "value1", - // "param2": 2, - // "paramN": "etc" - // } - // const createTask = await sdk.createTask("atv_teste_demo", parametersCreateTask, true) - // console.log({createTask}) - - // const finishTask = await sdk.finishTask("27191", "FINISHED", "SUCCESS", "Your custom finish message here!") - // console.log({finishTask}) - - // const getTask = await sdk.getTask("26948") - // console.log({getTask}) -// } - -// const logs = async () => { -// await sdk.login() - // const columnsLog= [ - // {"name": "Column 1", "label": "col1", "width": 100}, - // {"name": "Column 2", "label": "col2", "width": 200}, - // {"name": "Column 3", "label": "col3", "width": 150} - // ] - - // const deleteLog = await sdk.deleteLog("botJavaGabriel") - // console.log({deleteLog}) - - // const createLog = await sdk.createLog("botJavaGabriel", columnsLog) - // console.log({createLog}) - - // const getLogs = await sdk.getLogs() - // console.log({getLogs}) - // console.log({"machines": getLogs[0].machines, notification: getLogs[0].notification}) - - // const getLog = await sdk.getLog("botJavaGabriel") - // console.log({ getLog }) - - // const logEntry = await sdk.logEntry("botJavaGabriel", {"name": "Column 1", "label": "col1", "width": 100}) - // console.log({logEntry}) - - // const fetchDataLog = await sdk.fetchDataLog("botJavaGabriel") - // console.log({fetchDataLog, _id: fetchDataLog[0]._id, columns: fetchDataLog[0].columns}) - - // const downloadCsvLog = await sdk.downloadCsvLog("botJavaGabriel", "test.csv") - // console.log({downloadCsvLog}) -// } - - -// const alerts = async () => { -// await sdk.login() - -// const createAlert = await sdk.createAlert("26137", "My Alert Title", "My message", "INFO") -// console.log({ createAlert }) - -// } - -// const messages = async () => { -// await sdk.login() - -// const createMessage = await sdk.createMessage(["govetrikayque@gmail.com"], [], "Subject of the E-mail", "This is the e-mail body", "TEXT") -// console.log({ createMessage }) - -// } - -// const artifacts = async () => { - // await sdk.login() - - // const createArtifact = await sdk.createArtifact("26137", "User Facing Name.txt", "filename.txt") - // console.log({ createArtifact }) - - - // const uploadFile = await sdk.uploadFile(`${createArtifact.id}`, "C:\\Users\\Kayque\\Pictures\\botcity.png") - // console.log({ uploadFile }) - - // const uploadArticact = await sdk.uploadArtifact("26137", "Botcity", "botcity.png", "C:\\Users\\Kayque\\Pictures\\botcity.png") - // console.log({ uploadArticact }) - - // const getArtifacts = await sdk.getArtifacts("50", "0") - // console.log({getArtifacts, content: getArtifacts.content, sort: getArtifacts.pageable.sort}) - - // const downloadArtifacts = await sdk.downloadArtifact(`${createArtifact.id}`, "test.png") - // console.log({downloadArtifacts}) -// } - -// const errors = async () => { -// await sdk.login() - -// try { -// eval("hoo bar"); -// } catch (error: any) { -// const createError = await sdk.createError( -// '31057', error, {'teste': 123}, '/home/kayque/Imagens/kkkkk.png', ['/home/kayque/Imagens/kkkkk.png'] -// ) -// console.log({ createError }) - -// } -// const credentials = async () => { -// await sdk.login() - - -// const createCredential = await sdk.createCredential("testJs", "js", "javascript") -// console.log({ createCredential }) - -// const getCredential = await sdk.getCredential("testJs", "js") -// console.log({ getCredential }) - -// } - -// tasks() -// logs() -// alerts() -// messages() -// artifacts() -// errors() -// credentials() diff --git a/tests/integration/alert.test.ts b/tests/integration/alert.test.ts new file mode 100644 index 0000000..cd87e61 --- /dev/null +++ b/tests/integration/alert.test.ts @@ -0,0 +1,40 @@ +import dotenv from "dotenv" +import { BotMaestroSdk } from "../../src/botcity"; +import { Task } from "../../src/botcity/maestro/interfaces"; + +dotenv.config() + +const SERVER = process.env.BOTCITY_SERVER || "" +const LOGIN = process.env.BOTCITY_LOGIN || "" +const KEY = process.env.BOTCITY_KEY || "" + +let sdk: BotMaestroSdk; +let task: Task; + +describe("Testing alerts cases", () => { + beforeAll(async () => { + sdk = new BotMaestroSdk(SERVER, LOGIN, KEY); + await sdk.login() + const parameters = { + "test_to_test": "testing", + "integer_to_test": 123, + "double_to_test": 1.0 + } + task = await sdk.createTask("TestCI", parameters, false) + }, 10000); + + test("Create Alert Info", async () => { + const alert = await sdk.createAlert(task.id, "Info Warn", "This is an info alert", "INFO") + expect(alert.type).toEqual("INFO") + }, 10000) + + test("Create Alert Warn", async () => { + const alert = await sdk.createAlert(task.id, "Info Warn", "This is an info warn", "WARN") + expect(alert.type).toEqual("WARN") + }, 10000) + + test("Create Alert Error", async () => { + const alert = await sdk.createAlert(task.id, "Info Error", "This is an info error", "ERROR") + expect(alert.type).toEqual("ERROR") + }, 10000) +}) \ No newline at end of file diff --git a/tests/integration/artifact.test.ts b/tests/integration/artifact.test.ts new file mode 100644 index 0000000..dd3384f --- /dev/null +++ b/tests/integration/artifact.test.ts @@ -0,0 +1,40 @@ +import dotenv from "dotenv" +import { BotMaestroSdk } from "../../src/botcity"; +import tmp from 'tmp' +import { Task } from "../../src/botcity/maestro/interfaces"; + +dotenv.config() + +const SERVER = process.env.BOTCITY_SERVER || "" +const LOGIN = process.env.BOTCITY_LOGIN || "" +const KEY = process.env.BOTCITY_KEY || "" + +let sdk: BotMaestroSdk; +let task: Task; + +describe("Testing Artifact cases", () => { + beforeAll(async () => { + sdk = new BotMaestroSdk(SERVER, LOGIN, KEY); + await sdk.login() + const parameters = { + "test_to_test": "testing", + "integer_to_test": 123, + "double_to_test": 1.0 + } + task = await sdk.createTask("TestCI", parameters, false) + }, 10000); + + test("Post Artifact", async () => { + const tmpobj = tmp.fileSync({ mode: 0o644, prefix: 'prefix-', postfix: '.txt' }); + try { + await sdk.uploadArtifact(task.id, "My Artifact", "My artificat", tmpobj.name) + } finally { + tmpobj.removeCallback(); + } + }, 10000) + + test("Get Artifacts", async () => { + const listArtifacts = await sdk.getArtifacts("1", "1", [], "1") + expect(listArtifacts) + }, 10000) +}) \ No newline at end of file diff --git a/tests/integration/credential.test.ts b/tests/integration/credential.test.ts new file mode 100644 index 0000000..f0ac2eb --- /dev/null +++ b/tests/integration/credential.test.ts @@ -0,0 +1,29 @@ +import dotenv from "dotenv" +import { BotMaestroSdk } from "../../src/botcity"; +import { v4 as uuid4} from 'uuid'; + +dotenv.config() + +const SERVER = process.env.BOTCITY_SERVER || "" +const LOGIN = process.env.BOTCITY_LOGIN || "" +const KEY = process.env.BOTCITY_KEY || "" + +let sdk: BotMaestroSdk; +let credentialLabel = `testing-${uuid4()}` +let credentialKey = `testing-${uuid4()}` + +describe("Testing Credential cases", () => { + beforeAll(async () => { + sdk = new BotMaestroSdk(SERVER, LOGIN, KEY); + await sdk.login() + }, 10000); + + test("Create Credential", async () => { + await sdk.createCredential(credentialLabel, credentialKey, "testing") + }, 10000) + + test("Get Credential", async () => { + const credential = await sdk.getCredential(credentialLabel, credentialKey) + expect(credential).toEqual("testing") + }, 10000) +}) \ No newline at end of file diff --git a/tests/integration/error.test.ts b/tests/integration/error.test.ts new file mode 100644 index 0000000..e1be8ad --- /dev/null +++ b/tests/integration/error.test.ts @@ -0,0 +1,38 @@ +import dotenv from "dotenv" +import { BotMaestroSdk } from "../../src/botcity"; +import path from "path"; +import { Task } from "../../src/botcity/maestro/interfaces"; + +dotenv.config() + +const SERVER = process.env.BOTCITY_SERVER || "" +const LOGIN = process.env.BOTCITY_LOGIN || "" +const KEY = process.env.BOTCITY_KEY || "" + +const screenshotFilepath = path.resolve("tests/screenshot.png") + +let sdk: BotMaestroSdk; +let task: Task; + +describe("Testing Error cases", () => { + beforeAll(async () => { + sdk = new BotMaestroSdk(SERVER, LOGIN, KEY); + await sdk.login() + const parameters = { + "test_to_test": "testing", + "integer_to_test": 123, + "double_to_test": 1.0 + } + task = await sdk.createTask("TestCI", parameters, false) + }, 10000); + + test("Create Error", async () => { + try { + eval("hoo bar"); + } catch (error: any) { + const attachments: string[] = [screenshotFilepath] + await sdk.createError(task.id, error, {}, screenshotFilepath, attachments) + } + }, 10000) + +}) \ No newline at end of file diff --git a/tests/integration/log.test.ts b/tests/integration/log.test.ts new file mode 100644 index 0000000..da58e35 --- /dev/null +++ b/tests/integration/log.test.ts @@ -0,0 +1,49 @@ +import dotenv from "dotenv" +import { BotMaestroSdk, Column } from "../../src/botcity"; +import { v4 as uuid4} from 'uuid'; + +dotenv.config() + +const SERVER = process.env.BOTCITY_SERVER || "" +const LOGIN = process.env.BOTCITY_LOGIN || "" +const KEY = process.env.BOTCITY_KEY || "" + +let sdk: BotMaestroSdk; + +const activityLabelToLog = `TestCI-${uuid4()}` + +const columns = [ + new Column("Date/Time", "timestamp", 300), + new Column("# Records", "records", 200), + new Column("Status", "status", 100), +] + +describe("Testing log cases", () => { + beforeAll(async () => { + sdk = new BotMaestroSdk(SERVER, LOGIN, KEY); + await sdk.login() + }, 10000); + + test("Create log", async () => { + const log = await sdk.createLog(activityLabelToLog, columns) + expect(log.activityLabel).toEqual(activityLabelToLog) + }, 10000) + + test("Create new log entry", async () => { + await sdk.logEntry(activityLabelToLog, { + "timestamp": new Date().toISOString(), + "records": 10, + "status": "SUCCESS" +, }) + }, 10000) + + test("Get log", async () => { + const log = await sdk.getLog(activityLabelToLog) + console.log({ log }) + expect(log.id).toBe(`botcity-${activityLabelToLog}`) + }, 10000) + + test("Delete log", async () => { + await sdk.deleteLog(activityLabelToLog) + }, 10000) +}) \ No newline at end of file diff --git a/tests/integration/login.test.ts b/tests/integration/login.test.ts new file mode 100644 index 0000000..ecf977a --- /dev/null +++ b/tests/integration/login.test.ts @@ -0,0 +1,44 @@ +import dotenv from "dotenv" +import { BotMaestroSdk } from "../../src/botcity"; + +dotenv.config() + +const SERVER = process.env.BOTCITY_SERVER || "" +const LOGIN = process.env.BOTCITY_LOGIN || "" +const KEY = process.env.BOTCITY_KEY || "" + +let sdk: BotMaestroSdk; + + +describe("Testing logins cases", () => { + beforeAll(async () => { + sdk = new BotMaestroSdk(SERVER, LOGIN, KEY); + }, 10000); + + test("Error server not found", async () => { + const expected = async () => { + await new BotMaestroSdk("", LOGIN, KEY).login() + } + expect(expected()).rejects.toThrow("Server is required.") + }, 10000) + + test("Error in login", async () => { + const expected = async () => { + await new BotMaestroSdk(SERVER, "", KEY).login() + } + expect(expected()).rejects.toThrow("Login is required.") + }, 10000) + + test("Error in key", async () => { + const expected = async () => { + await new BotMaestroSdk(SERVER, LOGIN, "").login() + } + expect(expected()).rejects.toThrow("Key is required.") + }, 10000) + + test("Login Success", async () => { + await sdk.login() + expect(sdk.accessToken).not.toBe("") + expect(sdk.isOnline).toBe(true) + }, 10000) +}) \ No newline at end of file diff --git a/tests/integration/task.test.ts b/tests/integration/task.test.ts new file mode 100644 index 0000000..25bd793 --- /dev/null +++ b/tests/integration/task.test.ts @@ -0,0 +1,106 @@ +import dotenv from "dotenv" +import { BotMaestroSdk } from "../../src/botcity"; +import { Task } from "../../src/botcity/maestro/interfaces"; + +dotenv.config() + +const SERVER = process.env.BOTCITY_SERVER || "" +const LOGIN = process.env.BOTCITY_LOGIN || "" +const KEY = process.env.BOTCITY_KEY || "" + +let sdk: BotMaestroSdk; +let task: Task; + + +describe("Testing tasks cases", () => { + beforeAll(async () => { + sdk = new BotMaestroSdk(SERVER, LOGIN, KEY); + await sdk.login() + const parameters = { + "test_to_test": "testing", + "integer_to_test": 123, + "double_to_test": 1.0 + } + const priority = Math.floor(Math.random() * (Math.floor(10) - Math.ceil(1) + 1)) + Math.ceil(1); + const now = new Date() + now.setHours(now.getHours() - 1) + task = await sdk.createTask("TestCI", parameters, false, priority, now) + }, 10000); + + test("Create Task", async () => { + const parameters = { + "test_to_test": "testing", + "integer_to_test": 123, + "double_to_test": 1.0 + } + const priority = Math.floor(Math.random() * (Math.floor(10) - Math.ceil(1) + 1)) + Math.ceil(1); + const now = new Date() + now.setHours(now.getHours() - 1) + const actualTask = await sdk.createTask("TestCI", parameters, false, priority, now) + expect(actualTask) + }, 10000) + + test("Get Task", async () => { + const actualTask = await sdk.getTask(task.id) + expect(actualTask.activityLabel).toBe("TestCI") + }, 10000) + + test("Interrupting Task", async () => { + const actualTask = await sdk.interruptTask(task.id) + expect(actualTask.interrupted).toBeTruthy() + }, 10000) + + test("Finish Task to Success", async () => { + const actualTask = await sdk.finishTask(task.id, "SUCCESS", "Task Finished with Success.") + expect(actualTask.finishStatus).toEqual("SUCCESS") + }, 10000) + + test("Finish Task to Partially Completed", async () => { + const actualTask = await sdk.finishTask(task.id, "PARTIALLY_COMPLETED", "Task Finished with partially completed.") + expect(actualTask.finishStatus).toEqual("PARTIALLY_COMPLETED") + }, 10000) + + test("Finish Task to Failed", async () => { + const actualTask = await sdk.finishTask(task.id, "FAILED", "Task Finished with failed.") + expect(actualTask.finishStatus).toEqual("FAILED") + }, 10000) + + test("Finish Task no report items", async () => { + const actualTask = await sdk.finishTask(task.id, "SUCCESS", "Task Finished with Success.") + expect(actualTask.totalItems).toBeNull() + expect(actualTask.processedItems).toBeNull() + expect(actualTask.failedItems).toBeNull() + }, 10000) + + test("Finish Task to report items", async () => { + const createdTask = await sdk.createTask("TestCI", {}) + const actualTask = await sdk.finishTask(createdTask.id, "SUCCESS", "Task Finished with Success.", 10, 5, 5) + expect(actualTask.totalItems).toEqual(10) + expect(actualTask.processedItems).toEqual(5) + expect(actualTask.failedItems).toEqual(5) + }, 10000) + + test("Finish Task to report processed and failed items", async () => { + const createdTask = await sdk.createTask("TestCI", {}) + const actualTask = await sdk.finishTask(createdTask.id, "SUCCESS", "Task Finished with Success.", null, 5, 5) + expect(actualTask.totalItems).toEqual(10) + expect(actualTask.processedItems).toEqual(5) + expect(actualTask.failedItems).toEqual(5) + }, 10000) + + test("Finish Task to report error invalid total items", async () => { + const createdTask = await sdk.createTask("TestCI", {}) + const expected = async () => { + await sdk.finishTask(createdTask.id, "SUCCESS", "Task Finished with Success.", 10, 6, 5) + } + expect(expected()).rejects.toThrow("Total items is not equal to the sum of processed and failed items.") + }, 10000) + + test("Finish Task to report error invalid total items", async () => { + const createdTask = await sdk.createTask("TestCI", {}) + const expected = async () => { + await sdk.finishTask(createdTask.id, "SUCCESS", "Task Finished with Success.", 10) + } + expect(expected()).rejects.toThrow("You must inform at least two of the following parameters: totalItems, processedItems, failedItems.") + }, 10000) +}) \ No newline at end of file diff --git a/tests/screenshot.png b/tests/screenshot.png new file mode 100644 index 0000000..656029f Binary files /dev/null and b/tests/screenshot.png differ