diff --git a/src/services/__mocks__/triggerStateData.json b/src/services/__mocks__/triggerStateData.json new file mode 100644 index 0000000000000000000000000000000000000000..c0d19f45d3a1a6edaa92a3b4cbb0d85333e61c07 --- /dev/null +++ b/src/services/__mocks__/triggerStateData.json @@ -0,0 +1,11 @@ +{ + "trigger_id": "238ba37b8bc8130bd323edb5c1005c8f", + "status": "errored", + "last_execution": "2020-11-13T10:03:16.4121536Z", + "last_executed_job_id": "238ba37b8bc8130bd323edb5c1006b56", + "last_failure": "2020-11-13T10:03:16.4121536Z", + "last_failed_job_id": "238ba37b8bc8130bd323edb5c1006b56", + "last_error": "fork/exec : no such file or directory", + "last_manual_execution": "2020-11-13T10:03:16.4121536Z", + "last_manual_job_id": "238ba37b8bc8130bd323edb5c1006b56" +} diff --git a/src/services/triggers.service.spec.ts b/src/services/triggers.service.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..30be8e849e0829bc44483382d134f4ec59b104c4 --- /dev/null +++ b/src/services/triggers.service.spec.ts @@ -0,0 +1,97 @@ +import { QueryResult } from 'cozy-client' +import { TRIGGERS_DOCTYPE } from 'doctypes' +import { Trigger, TriggerState } from 'models' +import mockClient from './__mocks__/client' +import TriggerService from './triggers.service' +import accountsData from './__mocks__/accountsData.json' +import konnectorsData from './__mocks__/konnectorsData.json' +import triggersData from './__mocks__/triggersData.json' +import triggerStateData from './__mocks__/triggerStateData.json' + +describe('TriggerService service', () => { + const triggerService = new TriggerService(mockClient) + + describe('createTrigger method', () => { + it('shoud return created Trigger', async () => { + mockClient.collection(TRIGGERS_DOCTYPE).create.mockResolvedValueOnce({ + data: triggersData[0], + }) + const result: Trigger = await triggerService.createTrigger( + accountsData[0], + konnectorsData[0] + ) + expect(result).toEqual(triggersData[0]) + }) + }) + + describe('getTrigger method', () => { + it('shoud return Trigger', async () => { + const mockQueryResult: QueryResult<Trigger[]> = { + data: [triggersData[0]], + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) + const result: Trigger | null = await triggerService.getTrigger( + accountsData[0], + konnectorsData[0] + ) + expect(result).toEqual(triggersData[0]) + }) + + it('shoud return null when no trigger found', async () => { + const mockQueryResult: QueryResult<Trigger[]> = { + data: [], + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) + const result: Trigger | null = await triggerService.getTrigger( + accountsData[0], + konnectorsData[0] + ) + expect(result).toBe(null) + }) + }) + + describe('fetchTriggerState method', () => { + it('shoud return Trigger state', async () => { + const mockResult = { + data: { + attributes: { + // eslint-disable-next-line @typescript-eslint/camelcase + current_state: triggerStateData, + }, + }, + } + mockClient.getStackClient().fetchJSON.mockResolvedValueOnce(mockResult) + const result: TriggerState | null = await triggerService.fetchTriggerState( + triggersData[0] + ) + expect(result).toEqual(triggerStateData) + }) + + it('shoud return null when current_state is empty', async () => { + const mockResult = { + // eslint-disable-next-line @typescript-eslint/camelcase + data: { attributes: { current_state: null } }, + } + mockClient.getStackClient().fetchJSON.mockResolvedValueOnce(mockResult) + const result: TriggerState | null = await triggerService.fetchTriggerState( + triggersData[0] + ) + expect(result).toBe(null) + }) + + it('shoud throw an error', async () => { + mockClient.getStackClient().fetchJSON.mockRejectedValueOnce(new Error()) + try { + await triggerService.fetchTriggerState(triggersData[0]) + } catch (error) { + expect(error).toEqual(new Error('Fetch trigger state failed')) + } + }) + }) +}) diff --git a/src/services/triggers.service.ts b/src/services/triggers.service.ts index 5b4dee3cff160497ec43c3149d2a2cfe8521e408..9cc426c197292345af89ed65e9d37102f89d9383 100644 --- a/src/services/triggers.service.ts +++ b/src/services/triggers.service.ts @@ -1,4 +1,4 @@ -import { Client } from 'cozy-client' +import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client' import { Account, Konnector, @@ -9,6 +9,7 @@ import { import { buildAttributes } from 'cozy-harvest-lib/dist/helpers/triggers' import triggersMutations from 'cozy-harvest-lib/dist/connections/triggers' import ConfigService from 'services/fluidConfig.service' +import { TRIGGERS_DOCTYPE } from 'doctypes' export default class TriggerService { private _client: Client @@ -34,11 +35,6 @@ export default class TriggerService { konnector: Konnector ): Promise<Trigger> { const triggerAttributes = this.createTriggerAttributes(account, konnector) - if (!triggerAttributes) { - throw new Error( - 'TriggersServices : createTrigger - _triggerAttributes not found' - ) - } const trigger = await triggersMutations(this._client).createTrigger( triggerAttributes ) @@ -48,54 +44,34 @@ export default class TriggerService { public async getTrigger( account: Account, konnector: Konnector - ): Promise<Trigger> { - const query = this._client - .find('io.cozy.triggers') + ): Promise<Trigger | null> { + const query: QueryDefinition = Q(TRIGGERS_DOCTYPE) .where({ 'message.account': account._id, 'message.konnector': konnector.slug, }) .sortBy([{ 'cozyMetadata.updatedAt': 'desc' }]) .limitBy(1) - const result = await this._client.query(query) - return result.data[0] ? result.data[0] : null - } - - public static async fetchTriggerFromAccount( - client: Client, - account: Account - ) { - if (account == null) return null - const query = client - .find('io.cozy.triggers') - .where({ 'message.account': account._id }) - .sortBy([{ 'cozyMetadata.updatedAt': 'desc' }]) - .limitBy(1) - const result = await client.query(query) - return result.data[0] ? result.data[0] : null - } - - public async launchTrigger(trigger: Trigger): Promise<any> { - if (!trigger) { - throw new Error('TriggersServices : createTrigger - trigger not found') - } - console.log( - '%c Launched Trigger is : ' + trigger._id, - 'background: #222; color: white' + const { data: triggers }: QueryResult<Trigger[]> = await this._client.query( + query ) - const job = await triggersMutations(this._client).launchTrigger(trigger) - return job + return triggers[0] ? triggers[0] : null } public async fetchTriggerState( trigger: Trigger ): Promise<TriggerState | null> { - if (trigger == null) return null - const triggerState = await this._client - .getStackClient() - .fetchJSON('GET', `/jobs/triggers/${trigger._id}`) - return triggerState.data.attributes.current_state - ? triggerState.data.attributes.current_state - : null + try { + const triggerState = await this._client + .getStackClient() + .fetchJSON('GET', `/jobs/triggers/${trigger._id}`) + // eslint-disable-next-line @typescript-eslint/camelcase + return triggerState.data.attributes.current_state + ? triggerState.data.attributes.current_state + : null + } catch (error) { + console.log(error) + throw new Error('Fetch trigger state failed') + } } }