diff --git a/src/cli.ts b/src/cli.ts index 11228d6c..5882a6b2 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -18,6 +18,7 @@ import {readFileSync} from 'fs'; import {join} from 'path'; import {URL} from 'url'; import {copy} from './copy'; +import {indexSamples} from './e2e'; import {HttpClient} from './httpClient'; const logger = new Logger(); @@ -31,6 +32,27 @@ process.on('unhandledRejection', (error) => { logger.error('unhandledRejection', error); }); +commander + .command('e2e ') + .description('Run in end to end test mode. Indexing all test files from @openstapp/core to the backend') + .option('-s --samples [path]', 'Path to @openstapp/core test files', './node_modules/@openstapps/core/test/resources') + .action((to, e2eCommand) => { + // validate url + try { + to = (new URL(to)).toString(); + } catch (err) { + logger.error('expected parameter "to" to be valid url', err); + e2eCommand.outputHelp(); + process.exit(-1); + } + + actionDone = true; + + indexSamples(client, {to: to, samples: e2eCommand.samples}).then(() => { + logger.ok('Done'); + }); + }); + commander .command('copy ') .version(pkgJson.version) diff --git a/src/e2e.ts b/src/e2e.ts new file mode 100644 index 00000000..eed7cec9 --- /dev/null +++ b/src/e2e.ts @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2019 StApps + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +import {SCThings} from '@openstapps/core'; +import {readdir, readFile} from 'fs'; +import {join} from 'path'; +import {promisify} from 'util'; +import {Bulk} from './bulk'; +import {ConnectorClient} from './connectorClient'; +import {HttpClientInterface} from './httpClientInterface'; + +/** + * Options to set up indexing core test files to backend + */ +export interface E2EOptions { + /** + * File path of the directory containing core test files + */ + samples: string; + + /** + * URL of the backend to index to + */ + to: string; +} + +/** + * Function to add all the SCThings that getItemsFromSamples() returns to the backend + * + * @param client HTTP client + * @param options Map of options + */ +export async function indexSamples(client: HttpClientInterface, options: E2EOptions): Promise { + const api = new ConnectorClient(client, options.to); + + const items = await getItemsFromSamples(options.samples); + + if (items.length === 0) { + throw new Error('Could not index samples. None were retrived from the file system.'); + } + + items.sort((a, b) => (a.type.localeCompare(b.type))); + + let currentBulkType; + let currentBulk: Bulk | undefined; + + try { + // Add items depending on their type property with one type per bulk + for (const item of items) { + if (currentBulkType !== item.type) { + if (typeof currentBulk !== 'undefined') { + await currentBulk.done(); + } + currentBulk = await api.bulk(item.type, 'stapps-core-sample-data'); + currentBulkType = item.type; + } + await currentBulk!.add(item); + } + // close the last open bulk + if (typeof currentBulk !== 'undefined') { + await currentBulk.done(); + } + } catch (err) { + throw err; + } +} + +/** + * Get all SCThings from the predefined core test json files + * + * @param samplesDirectory Filepath to the directory containing to the core test json files + * @returns an Array of all the SCThings specified for test usage + */ +export async function getItemsFromSamples(samplesDirectory: string): Promise { + const readDirPromised = promisify(readdir); + const readFilePromised = promisify(readFile); + + const things: T[] = []; + try { + const fileNames = await readDirPromised(samplesDirectory); + for (const fileName of fileNames) { + const filePath = join(samplesDirectory, fileName); + const fileContent = await readFilePromised(filePath, {encoding: 'utf8'}); + const schemaObject = JSON.parse(fileContent); + if (schemaObject.errorNames.length === 0 && typeof schemaObject.instance.type === 'string') { + things.push(schemaObject.instance); + } + } + } catch (error) { + return error; + } + return things; +}