"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const supertest_1 = __importDefault(require("supertest"));
const Datastore_1 = __importDefault(require("../../src/common/Datastore"));
const DealPreparationService_1 = __importDefault(require("../../src/deal-preparation/DealPreparationService"));
const ErrorCode_1 = __importDefault(require("../../src/deal-preparation/ErrorCode"));
const Utils_1 = __importDefault(require("../Utils"));
describe('DealPreparationService', () => {
    let service;
    const fakeId = '62429da5002efca9dd13d380';
    beforeAll(async () => {
        await Utils_1.default.initDatabase();
        service = new DealPreparationService_1.default();
    });
    beforeEach(async () => {
        await Datastore_1.default.ScanningRequestModel.remove();
        await Datastore_1.default.GenerationRequestModel.remove();
    });
    describe('cleanupHealthCheck', () => {
        it('should clean up scanningrequest and generationrequest table', async () => {
            await Datastore_1.default.ScanningRequestModel.create({
                workerId: 'a',
                name: 'a',
            });
            await Datastore_1.default.ScanningRequestModel.create({
                workerId: 'b',
                name: 'b',
            });
            await Datastore_1.default.GenerationRequestModel.create({
                workerId: 'c'
            });
            await Datastore_1.default.GenerationRequestModel.create({
                workerId: 'd'
            });
            await Datastore_1.default.HealthCheckModel.create({
                workerId: 'a'
            });
            await Datastore_1.default.HealthCheckModel.create({
                workerId: 'c'
            });
            await service['cleanupHealthCheck']();
            expect(await Datastore_1.default.ScanningRequestModel.findOne({ workerId: 'a' })).not.toBeNull();
            expect(await Datastore_1.default.ScanningRequestModel.findOne({ workerId: 'b' })).toBeNull();
            expect(await Datastore_1.default.GenerationRequestModel.findOne({ workerId: 'c' })).not.toBeNull();
            expect(await Datastore_1.default.GenerationRequestModel.findOne({ workerId: 'd' })).toBeNull();
        });
    });
    describe('GET /generation/:dataset/:id', () => {
        it('should return error if the id is not integer', async () => {
            const response = await ((0, supertest_1.default)(service['app']))
                .get(`/generation/name/not_number`);
            expect(response.status).toEqual(400);
            expect(response.body).toEqual({
                error: ErrorCode_1.default.INVALID_OBJECT_ID
            });
        });
        it('should return error if the id is not found', async () => {
            const response = await ((0, supertest_1.default)(service['app']))
                .get(`/generation/name/10`);
            expect(response.status).toEqual(400);
            expect(response.body).toEqual({
                error: ErrorCode_1.default.DATASET_GENERATION_REQUEST_NOT_FOUND
            });
        });
        it('should return found generation request by dataset name and index', async () => {
            await Datastore_1.default.GenerationRequestModel.create({
                datasetId: fakeId,
                datasetName: 'datasetName',
                status: 'active',
                index: 10,
                dataCid: 'dataCid',
                pieceCid: 'pieceCid',
                pieceSize: 10,
                fileList: [{
                        path: '/data/file1.mp4',
                        start: 0,
                        end: 0,
                        size: 100
                    }]
            });
            let response = await ((0, supertest_1.default)(service['app']))
                .get(`/generation/datasetName/10`);
            expect(response.status).toEqual(200);
            expect(response.body).toEqual(jasmine.objectContaining({
                datasetId: fakeId,
                datasetName: 'datasetName',
                status: 'active',
                index: 10,
                dataCid: 'dataCid',
                pieceCid: 'pieceCid',
                pieceSize: 10
            }));
            response = await ((0, supertest_1.default)(service['app']))
                .get(`/generation/${fakeId}/10`);
            expect(response.status).toEqual(200);
            expect(response.body).toEqual(jasmine.objectContaining({
                datasetId: fakeId,
                datasetName: 'datasetName',
                status: 'active',
                index: 10,
                dataCid: 'dataCid',
                pieceCid: 'pieceCid',
                pieceSize: 10
            }));
        });
    });
    describe('GET /generation/:id', () => {
        it('should return error if the id cannot be found', async () => {
            const response = await ((0, supertest_1.default)(service['app']))
                .get(`/generation/${fakeId}`);
            expect(response.status).toEqual(400);
            expect(response.body).toEqual({
                error: ErrorCode_1.default.DATASET_GENERATION_REQUEST_NOT_FOUND
            });
        });
        it('should return error if the id is not valid', async () => {
            const response = await ((0, supertest_1.default)(service['app']))
                .get('/generation/fakeid');
            expect(response.status).toEqual(400);
            expect(response.body).toEqual({
                error: ErrorCode_1.default.INVALID_OBJECT_ID
            });
        });
        it('should return file list of a specific generation request', async () => {
            const generationRequest = await Datastore_1.default.GenerationRequestModel.create({
                datasetId: 'datasetId',
                status: 'active',
                index: 0,
                dataCid: 'dataCid',
                pieceCid: 'pieceCid',
                pieceSize: 10,
                fileList: [{
                        path: '/data/file1.mp4',
                        start: 0,
                        end: 0,
                        size: 100
                    }]
            });
            const response = await ((0, supertest_1.default)(service['app']))
                .get('/generation/' + generationRequest.id);
            expect(response.status).toEqual(200);
            expect(response.body).toEqual(jasmine.objectContaining({
                datasetId: 'datasetId',
                status: 'active',
                index: 0,
                dataCid: 'dataCid',
                pieceCid: 'pieceCid',
                pieceSize: 10
            }));
            expect(response.body.fileList.length).toEqual(1);
            expect(response.body.fileList[0]).toEqual(jasmine.objectContaining({
                path: '/data/file1.mp4',
                start: 0,
                end: 0,
                size: 100
            }));
        });
    });
    describe('GET /preparation/:id', () => {
        it('should return error if the id cannot be found', async () => {
            const response = await ((0, supertest_1.default)(service['app']))
                .get(`/preparation/${fakeId}`);
            expect(response.status).toEqual(400);
            expect(response.body).toEqual({
                error: ErrorCode_1.default.DATASET_NOT_FOUND
            });
        });
        it('should return error if the id cannot be found', async () => {
            const response = await ((0, supertest_1.default)(service['app']))
                .get('/preparation/fakeid');
            expect(response.status).toEqual(400);
            expect(response.body).toEqual({
                error: ErrorCode_1.default.DATASET_NOT_FOUND
            });
        });
        it('should return all generation requests', async () => {
            const scanning = await Datastore_1.default.ScanningRequestModel.create({
                name: 'name',
                path: 'path',
                status: 'completed',
                minSize: 0,
                maxSize: 10
            });
            await Datastore_1.default.GenerationRequestModel.create({
                datasetId: scanning.id,
                status: 'active',
                index: 0,
                dataCid: 'dataCid',
                pieceCid: 'pieceCid',
                pieceSize: 10,
                fileList: [{
                        path: '/data/file1.mp4',
                        start: 0,
                        end: 0,
                        size: 100
                    }]
            });
            const response = await ((0, supertest_1.default)(service['app']))
                .get('/preparation/' + scanning.id);
            expect(response.status).toEqual(200);
            expect(response.body).toEqual(jasmine.objectContaining({
                name: 'name',
                path: 'path',
                scanningStatus: 'completed',
                minSize: 0,
                maxSize: 10
            }));
            expect(response.body.generationRequests.length).toEqual(1);
            expect(response.body.generationRequests[0]).toEqual(jasmine.objectContaining({
                index: 0,
                status: 'active',
                dataCid: 'dataCid',
                pieceCid: 'pieceCid',
                pieceSize: 10
            }));
        });
    });
    describe('GET /preparations', () => {
        it('should return all scanning requests with aggregated stats', async () => {
            const scanning = await Datastore_1.default.ScanningRequestModel.create({
                name: 'name',
                path: 'path',
                status: 'completed',
                minSize: 0,
                maxSize: 10
            });
            for (let i = 0; i <= 3; ++i) {
                await Datastore_1.default.GenerationRequestModel.create({
                    datasetId: scanning.id,
                    status: 'active'
                });
            }
            for (let i = 0; i <= 4; ++i) {
                await Datastore_1.default.GenerationRequestModel.create({
                    datasetId: scanning.id,
                    status: 'paused'
                });
            }
            for (let i = 0; i <= 5; ++i) {
                await Datastore_1.default.GenerationRequestModel.create({
                    datasetId: scanning.id,
                    status: 'completed'
                });
            }
            for (let i = 0; i <= 6; ++i) {
                await Datastore_1.default.GenerationRequestModel.create({
                    datasetId: scanning.id,
                    status: 'error'
                });
            }
            const response = await ((0, supertest_1.default)(service['app']))
                .get('/preparations');
            expect(response.status).toEqual(200);
            expect(response.body.length).toEqual(1);
            expect(response.body[0]).toEqual(jasmine.objectContaining({
                name: 'name',
                path: 'path',
                minSize: 0,
                maxSize: 10,
                scanningStatus: 'completed',
                generationTotal: 22,
                generationActive: 4,
                generationPaused: 5,
                generationCompleted: 6,
                generationError: 7
            }));
        });
    });
    describe('POST /preparation/:id', () => {
        it('should return error if action is not valid', async () => {
            const response = await (0, supertest_1.default)(service['app'])
                .post(`/preparation/${fakeId}`)
                .send({ action: 'invalid' }).set('Accept', 'application/json');
            expect(response.status).toEqual(400);
            expect(response.body).toEqual({
                error: ErrorCode_1.default.ACTION_INVALID
            });
        });
        it('should return error if database does not exist', async () => {
            const response = await (0, supertest_1.default)(service['app'])
                .post(`/preparation/${fakeId}`)
                .send({ action: 'resume' }).set('Accept', 'application/json');
            expect(response.status).toEqual(400);
            expect(response.body).toEqual({
                error: ErrorCode_1.default.DATASET_NOT_FOUND
            });
        });
        it('should change status for all generation requests if generation is not given', async () => {
            const scanning = await Datastore_1.default.ScanningRequestModel.create({
                name: 'name',
                status: 'active'
            });
            const r1 = await Datastore_1.default.GenerationRequestModel.create({
                datasetId: scanning.id,
                status: 'active'
            });
            const r2 = await Datastore_1.default.GenerationRequestModel.create({
                datasetId: scanning.id,
                status: 'completed'
            });
            const response = await (0, supertest_1.default)(service['app'])
                .post('/preparation/' + scanning.id)
                .send({ action: 'pause' }).set('Accept', 'application/json');
            expect(response.status).toEqual(200);
            expect(await Datastore_1.default.ScanningRequestModel.findById(scanning.id)).toEqual(jasmine.objectContaining({
                status: 'paused'
            }));
            expect(await Datastore_1.default.GenerationRequestModel.findById(r1.id)).toEqual(jasmine.objectContaining({
                status: 'paused'
            }));
            expect(await Datastore_1.default.GenerationRequestModel.findById(r2.id)).toEqual(jasmine.objectContaining({
                status: 'completed'
            }));
            expect(response.body).toEqual({
                scanningRequestsChanged: 1,
                generationRequestsChanged: 1
            });
        });
        it('should return 0 changed if generation does not exist', async () => {
            const scanning = await Datastore_1.default.ScanningRequestModel.create({
                name: 'name',
                status: 'active'
            });
            const response = await (0, supertest_1.default)(service['app'])
                .post(`/preparation/${scanning.id}/${fakeId}`)
                .send({ action: 'resume' }).set('Accept', 'application/json');
            expect(response.status).toEqual(200);
            expect(response.body).toEqual({
                scanningRequestsChanged: 0,
                generationRequestsChanged: 0
            });
        });
        it('should return error if generation is malformed', async () => {
            const scanning = await Datastore_1.default.ScanningRequestModel.create({
                name: 'name',
                status: 'active'
            });
            const response = await (0, supertest_1.default)(service['app'])
                .post(`/preparation/${scanning.id}/fffff`)
                .send({ action: 'resume' }).set('Accept', 'application/json');
            expect(response.status).toEqual(400);
            expect(response.body).toEqual({
                error: ErrorCode_1.default.INVALID_OBJECT_ID
            });
        });
        it('should change status for specific generation request', async () => {
            const scanning = await Datastore_1.default.ScanningRequestModel.create({
                name: 'name',
                status: 'completed'
            });
            const r1 = await Datastore_1.default.GenerationRequestModel.create({
                datasetId: scanning.id,
                status: 'active'
            });
            const r2 = await Datastore_1.default.GenerationRequestModel.create({
                datasetId: scanning.id,
                index: 5,
                status: 'active'
            });
            const response = await (0, supertest_1.default)(service['app'])
                .post(`/preparation/${scanning.id}/${r1.id}`)
                .send({ action: 'pause' }).set('Accept', 'application/json');
            expect(response.status).toEqual(200);
            expect(await Datastore_1.default.ScanningRequestModel.findById(scanning.id)).toEqual(jasmine.objectContaining({
                status: 'completed'
            }));
            expect(await Datastore_1.default.GenerationRequestModel.findById(r1.id)).toEqual(jasmine.objectContaining({
                status: 'paused'
            }));
            expect(await Datastore_1.default.GenerationRequestModel.findById(r2.id)).toEqual(jasmine.objectContaining({
                status: 'active'
            }));
            expect(response.body).toEqual({
                scanningRequestsChanged: 0,
                generationRequestsChanged: 1
            });
        });
    });
    it('should change status for specific generation request by index', async () => {
        const scanning = await Datastore_1.default.ScanningRequestModel.create({
            name: 'name',
            status: 'completed'
        });
        const r1 = await Datastore_1.default.GenerationRequestModel.create({
            datasetId: scanning.id,
            status: 'active'
        });
        const r2 = await Datastore_1.default.GenerationRequestModel.create({
            datasetId: scanning.id,
            index: 5,
            status: 'active'
        });
        const response = await (0, supertest_1.default)(service['app'])
            .post(`/preparation/${scanning.id}/${r2.index}`)
            .send({ action: 'pause' }).set('Accept', 'application/json');
        expect(response.status).toEqual(200);
        expect(await Datastore_1.default.ScanningRequestModel.findById(scanning.id)).toEqual(jasmine.objectContaining({
            status: 'completed'
        }));
        expect(await Datastore_1.default.GenerationRequestModel.findById(r1.id)).toEqual(jasmine.objectContaining({
            status: 'active'
        }));
        expect(await Datastore_1.default.GenerationRequestModel.findById(r2.id)).toEqual(jasmine.objectContaining({
            status: 'paused'
        }));
        expect(response.body).toEqual({
            scanningRequestsChanged: 0,
            generationRequestsChanged: 1
        });
    });
    describe('POST /preparation', () => {
        it('should return error if deal size is not allowed', async () => {
            const response = await (0, supertest_1.default)(service['app'])
                .post('/preparation').send({
                name: 'name',
                path: '.',
                dealSize: '123GiB'
            }).set('Accept', 'application/json');
            expect(response.status).toEqual(400);
            expect(response.body).toEqual({
                error: ErrorCode_1.default.DEAL_SIZE_NOT_ALLOWED
            });
        });
        it('should return error if path is not accessible', async () => {
            const response = await (0, supertest_1.default)(service['app'])
                .post('/preparation').send({
                name: 'name',
                path: '/probably/does/not/exist',
                dealSize: '32GiB'
            }).set('Accept', 'application/json');
            expect(response.status).toEqual(400);
            expect(response.body).toEqual({
                error: ErrorCode_1.default.PATH_NOT_ACCESSIBLE
            });
        });
        it('should return error if the dataset name is already taken', async () => {
            let response = await (0, supertest_1.default)(service['app'])
                .post('/preparation').send({
                name: 'name',
                path: '.',
                dealSize: '32GiB'
            }).set('Accept', 'application/json');
            expect(response.status).toEqual(200);
            response = await (0, supertest_1.default)(service['app'])
                .post('/preparation').send({
                name: 'name',
                path: '.',
                dealSize: '32GiB'
            }).set('Accept', 'application/json');
            expect(response.status).toEqual(400);
            expect(response.body).toEqual({
                error: ErrorCode_1.default.DATASET_NAME_CONFLICT
            });
        });
        it('should create scanning request', async () => {
            const response = await (0, supertest_1.default)(service['app'])
                .post('/preparation').send({
                name: 'name',
                path: '.',
                dealSize: '32GiB'
            }).set('Accept', 'application/json');
            expect(response.status).toEqual(200);
            const found = await Datastore_1.default.ScanningRequestModel.findOne({ name: 'name' });
            expect(found).not.toBeNull();
            expect(found).toEqual(jasmine.objectContaining({
                name: 'name',
                path: '.',
                minSize: 18897856102,
                maxSize: 32641751449,
            }));
            expect(found?.id).toBeDefined();
        });
    });
});
//# sourceMappingURL=DealPreparationService.spec.js.map