/* * 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 . */ // eslint-disable-next-line unicorn/prevent-abbreviations import { SCBulkAddResponse, SCBulkAddRoute, SCBulkDoneResponse, SCBulkDoneRoute, SCBulkResponse, SCBulkRoute, SCSearchResponse, SCSearchRoute, SCThings, } from '@openstapps/core'; import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import chaiSpies from 'chai-spies'; import {existsSync, mkdirSync, rmdirSync, unlinkSync} from 'fs'; import {createFileSync} from 'fs-extra'; import {HttpClient, HttpClientRequest, HttpClientResponse} from '@openstapps/api'; import {RecursivePartial} from './copy.spec.js'; import {expect} from 'chai'; import path from 'path'; import {fileURLToPath} from 'url'; // eslint-disable-next-line unicorn/prevent-abbreviations import {e2eRun, getItemsFromSamples} from '../src/e2e.js'; chai.should(); chai.use(chaiSpies); chai.use(chaiAsPromised); const sandbox = chai.spy.sandbox(); const bulkRoute = new SCBulkRoute(); const bulkAddRoute = new SCBulkAddRoute(); const bulkDoneRoute = new SCBulkDoneRoute(); const searchRoute = new SCSearchRoute(); const httpClient = new HttpClient(); const storedThings: Map = new Map(); describe('e2e Connector', function () { afterEach(function () { sandbox.restore(); }); it('should get core test samples', async function () { const items = await getItemsFromSamples('./node_modules/@openstapps/core/test/resources'); expect(items).to.not.be.empty; }); it('should fail to get core test samples', async function () { await chai.expect(getItemsFromSamples('./non-existent-directory')).to.be.rejectedWith(Error); }); it('should run e2e simulation', async function () { type responses = HttpClientResponse< SCBulkAddResponse | SCBulkDoneResponse | SCBulkResponse | SCSearchResponse >; let failOnCompare = false; let failOnLookup = false; sandbox.on( httpClient, 'request', async (request: HttpClientRequest): Promise> => { if (request.url.toString() === `http://localhost${bulkRoute.getUrlPath().toString()}`) { return { body: { state: 'in progress', uid: 'foo', }, statusCode: bulkRoute.statusCodeSuccess, }; } if ( request.url.toString() === `http://localhost${bulkAddRoute.getUrlPath({UID: 'foo'}).toString()}` ) { const thing = request.body as SCThings; storedThings.set(thing.uid, structuredClone(thing)); return { body: {}, statusCode: bulkAddRoute.statusCodeSuccess, }; } if ( request.url.toString() === `http://localhost${bulkDoneRoute.getUrlPath({UID: 'foo'}).toString()}` ) { return { body: {}, statusCode: bulkDoneRoute.statusCodeSuccess, }; } if (request.url.toString() === `http://localhost${searchRoute.getUrlPath().toString()}`) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const thing = storedThings.get((request.body as any).filter.arguments.value); if (failOnCompare) { thing!.origin!.modified = 'altered'; } const returnThing = failOnLookup ? [] : [thing]; const returnBody = { data: returnThing, facets: [], pagination: { count: returnThing.length, offset: 0, total: returnThing.length, }, stats: { time: 42, }, }; return { body: returnBody, statusCode: searchRoute.statusCodeSuccess, }; } return { body: {}, statusCode: searchRoute.statusCodeSuccess, }; }, ); await e2eRun(httpClient, { to: 'http://localhost', samplesLocation: './node_modules/@openstapps/core/test/resources', }).should.eventually.have.length(0); failOnLookup = true; failOnCompare = false; await e2eRun(httpClient, { to: 'http://localhost', samplesLocation: './node_modules/@openstapps/core/test/resources', }).should.eventually.include( 'Search for single SCThing with uid: 184b717a-d020-46f5-995c-03023670cc62 returned 0 results', ); failOnLookup = false; failOnCompare = true; await e2eRun(httpClient, { to: 'http://localhost', samplesLocation: './node_modules/@openstapps/core/test/resources', }).should.eventually.satisfy((errors: string[]) => { return errors.every(error => { return error.startsWith('Unexpected difference between original and retrieved sample'); }); }); }); it('should fail to index', async function () { type responses = HttpClientResponse; sandbox.on(httpClient, 'request', async (): Promise> => { return { body: {}, statusCode: Number.MAX_SAFE_INTEGER, }; }); return e2eRun(httpClient, { to: 'http://localhost', samplesLocation: './node_modules/@openstapps/core/test/resources', }).should.eventually.include(''); }); it('should fail to index directory without data', async function () { const emptyDirectoryPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'emptyDir'); if (!existsSync(emptyDirectoryPath)) { mkdirSync(emptyDirectoryPath); } await e2eRun(httpClient, { to: 'http://localhost', samplesLocation: emptyDirectoryPath, }).should.be.rejectedWith('Could not index samples. None were retrieved from the file system.'); rmdirSync(emptyDirectoryPath); }); it('should fail to index directory without json data', async function () { const somewhatFilledDirectoryPath = path.join( path.dirname(fileURLToPath(import.meta.url)), 'somewhatFilledDir', ); if (!existsSync(somewhatFilledDirectoryPath)) { mkdirSync(somewhatFilledDirectoryPath); } const nonJsonFile = path.join(somewhatFilledDirectoryPath, 'nonjson.txt'); createFileSync(nonJsonFile); await e2eRun(httpClient, { to: 'http://localhost', samplesLocation: somewhatFilledDirectoryPath, }).should.be.rejectedWith('Could not index samples. None were retrieved from the file system.'); unlinkSync(nonJsonFile); rmdirSync(somewhatFilledDirectoryPath); }); });