/*
 * Copyright (c) 2019 by Filestack.
 * Some rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var _this = this;
import * as tslib_1 from "tslib";
import { config } from './../../config';
import { CloudClient, PICKER_KEY } from './cloud';
import * as nock from 'nock';
var testApiKey = 'API_KEY';
var testTokSession = 'TOK_SESSION';
var testTokArchiveId = 'ARCHIVE_ID';
var testCloudToken = 'testCloudToken';
var testSecurity = {
    policy: 'examplePolicy',
    signature: 'exampleSignature',
};
var sessionURls = config.urls;
var testSession = {
    apikey: testApiKey,
    urls: sessionURls,
};
var scope = nock(sessionURls.cloudApiUrl);
var mockTokInit = jest
    .fn()
    .mockName('tokInit')
    .mockReturnValue('init');
var mockTokStart = jest
    .fn()
    .mockName('tokStart')
    .mockReturnValue('start');
var mockTokStop = jest
    .fn()
    .mockName('tokStop')
    .mockReturnValue('stop');
var mockMetadata = jest
    .fn()
    .mockName('metadata')
    .mockReturnValue('metadata');
var mockPrefetch = jest
    .fn()
    .mockName('prefetch')
    .mockReturnValue('prefetch');
var mockList = jest
    .fn()
    .mockName('list')
    .mockImplementation(function (data) {
    if (data && data.clouds.token) {
        return { token: testCloudToken };
    }
    return data;
});
var mockLogout = jest
    .fn()
    .mockName('logout')
    .mockImplementation(function (url, data) {
    var params = data ? JSON.parse(data) : {};
    if (data && params.clouds && params.clouds.token) {
        return { token: testCloudToken };
    }
    return data;
});
var mockStore = jest
    .fn()
    .mockName('store')
    .mockImplementation(function (params) {
    if (params && params.clouds && params.clouds.token) {
        return JSON.stringify({ token: testCloudToken });
    }
    return JSON.stringify(params);
});
describe('cloud', function () {
    beforeEach(function () {
        scope
            .persist()
            .options(/.*/)
            .reply(204, '', {
            'access-control-allow-headers': 'filestack-source,filestack-trace-id,filestack-trace-span',
            'access-control-allow-methods': '*',
            'access-control-allow-origin': '*',
        });
        scope
            .get('/prefetch')
            .query({ apikey: testApiKey })
            .reply(200, mockPrefetch);
        scope.post('/auth/logout/').reply(200, mockLogout);
        scope.post('/folder/list').reply(200, function (_, data) { return mockList(JSON.parse(data)); });
        scope.post('/store/').reply(200, function (_, data) { return mockStore(JSON.parse(data)); });
        scope.post('/metadata/').reply(200, mockMetadata);
        scope.post(/\/recording\/(audio|video)\/init/).reply(200, mockTokInit);
        scope.post(/\/recording\/(audio|video)\/start/).reply(200, mockTokStart);
        scope.post(/\/recording\/(audio|video)\/stop/).reply(200, mockTokStop);
    });
    afterEach(function () {
        nock.cleanAll();
        jest.clearAllMocks();
        localStorage.clear();
    });
    describe('prefetch', function () {
        it('should make correct request to api', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var res;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, new CloudClient(testSession).prefetch()];
                    case 1:
                        res = _a.sent();
                        expect(mockPrefetch).toHaveBeenCalledWith(expect.any(String), '');
                        expect(res).toEqual('prefetch');
                        return [2 /*return*/];
                }
            });
        }); });
    });
    describe('list', function () {
        it('should make correct list request', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var clouds, res;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        clouds = { test: true };
                        return [4 /*yield*/, new CloudClient(testSession).list(tslib_1.__assign({}, clouds))];
                    case 1:
                        res = _a.sent();
                        expect(res).toEqual({
                            apikey: testApiKey,
                            flow: 'web',
                            clouds: clouds,
                        });
                        return [2 /*return*/];
                }
            });
        }); });
        it('should make correct list request with session cache', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var clouds, res;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        clouds = { test: true };
                        localStorage.setItem(PICKER_KEY, testCloudToken);
                        return [4 /*yield*/, new CloudClient(testSession, {
                                sessionCache: true,
                            }).list(tslib_1.__assign({}, clouds))];
                    case 1:
                        res = _a.sent();
                        expect(res).toEqual({
                            apikey: testApiKey,
                            flow: 'web',
                            token: testCloudToken,
                            clouds: clouds,
                        });
                        return [2 /*return*/];
                }
            });
        }); });
        it('should set token on api token response', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var clouds, res;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        clouds = { token: true };
                        return [4 /*yield*/, new CloudClient(testSession).list(tslib_1.__assign({}, clouds))];
                    case 1:
                        res = _a.sent();
                        expect(res).toEqual({ token: testCloudToken });
                        return [2 /*return*/];
                }
            });
        }); });
        it('should cache session token to local storage', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var clouds, res;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        clouds = { token: true };
                        return [4 /*yield*/, new CloudClient(testSession, { sessionCache: true }).list(tslib_1.__assign({}, clouds))];
                    case 1:
                        res = _a.sent();
                        expect(localStorage.setItem).toHaveBeenCalledWith(PICKER_KEY, testCloudToken);
                        expect(res).toEqual({ token: testCloudToken });
                        return [2 /*return*/];
                }
            });
        }); });
        it('should make correct list request with security', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var clouds, res;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        clouds = { test: true };
                        return [4 /*yield*/, new CloudClient(tslib_1.__assign({}, testSession, testSecurity)).list(tslib_1.__assign({}, clouds))];
                    case 1:
                        res = _a.sent();
                        expect(res).toEqual(tslib_1.__assign({ apikey: testApiKey, flow: 'web', clouds: clouds }, testSecurity));
                        return [2 /*return*/];
                }
            });
        }); });
    });
    describe('store', function () {
        it('should make correct basic request', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var res;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, new CloudClient(testSession).store('google', 'test', { filename: '1' })];
                    case 1:
                        res = _a.sent();
                        expect(res).toEqual({
                            apikey: testApiKey,
                            flow: 'web',
                            clouds: {
                                google: {
                                    path: 'test',
                                    store: {
                                        filename: '1',
                                        location: 's3',
                                    },
                                },
                            },
                        });
                        return [2 /*return*/];
                }
            });
        }); });
        it('should respect store location param', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var res;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, new CloudClient(testSession).store('google', 'test', { filename: '1', location: 'gcs' })];
                    case 1:
                        res = _a.sent();
                        expect(res).toEqual({
                            apikey: testApiKey,
                            flow: 'web',
                            clouds: {
                                google: {
                                    path: 'test',
                                    store: {
                                        filename: '1',
                                        location: 'gcs',
                                    },
                                },
                            },
                        });
                        return [2 /*return*/];
                }
            });
        }); });
        it('should make correct basic with security', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var res, excepted;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, new CloudClient(tslib_1.__assign({}, testSession, testSecurity)).store('token', 'test', { filename: '1' })];
                    case 1:
                        res = _a.sent();
                        excepted = tslib_1.__assign({}, testSecurity, { apikey: testApiKey, flow: 'web', clouds: {
                                token: {
                                    path: 'test',
                                    store: {
                                        filename: '1',
                                        location: 's3',
                                    },
                                },
                            } });
                        expect(mockStore).toHaveBeenCalledWith(excepted);
                        expect(res).toEqual(testCloudToken);
                        return [2 /*return*/];
                }
            });
        }); });
        it('should handle custom source', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var customSource, res;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        customSource = {
                            customSourcePath: 'cs_path',
                            customSourceContainer: 'cs_container',
                        };
                        return [4 /*yield*/, new CloudClient(testSession).store('customsource', 'test', { filename: '1' }, customSource)];
                    case 1:
                        res = _a.sent();
                        expect(res).toEqual({
                            apikey: testApiKey,
                            flow: 'web',
                            clouds: {
                                customsource: tslib_1.__assign({}, customSource, { path: 'test', store: {
                                        filename: '1',
                                        location: 's3',
                                    } }),
                            },
                        });
                        return [2 /*return*/];
                }
            });
        }); });
    });
    describe('logout', function () {
        it('should make correct request to logout', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var _a;
            return tslib_1.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        _a = expect;
                        return [4 /*yield*/, new CloudClient(testSession).logout()];
                    case 1:
                        _a.apply(void 0, [_b.sent()]).toEqual({ apikey: 'API_KEY', flow: 'web' });
                        return [2 /*return*/];
                }
            });
        }); });
        it('should make correct request to logout with provided cloud', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var _a;
            return tslib_1.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        _a = expect;
                        return [4 /*yield*/, new CloudClient(testSession).logout('google')];
                    case 1:
                        _a.apply(void 0, [_b.sent()]).toEqual({ apikey: 'API_KEY', flow: 'web', clouds: { google: {} } });
                        return [2 /*return*/];
                }
            });
        }); });
        it('should make correct request to logout and return correct response when cloud name is returned', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var _a;
            return tslib_1.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        _a = expect;
                        return [4 /*yield*/, new CloudClient(testSession).logout('token')];
                    case 1:
                        _a.apply(void 0, [_b.sent()]).toEqual('testCloudToken');
                        return [2 /*return*/];
                }
            });
        }); });
        it('should make correct request to logout and clean session cache ', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var res;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        localStorage.setItem(PICKER_KEY, testCloudToken);
                        return [4 /*yield*/, new CloudClient(testSession, { sessionCache: true }).logout()];
                    case 1:
                        res = _a.sent();
                        expect(localStorage.removeItem).toHaveBeenCalledWith(PICKER_KEY);
                        expect(res).toEqual({ apikey: 'API_KEY', flow: 'web', token: testCloudToken });
                        return [2 /*return*/];
                }
            });
        }); });
    });
    describe('metadata', function () {
        it('should make correct request', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var testUrl, res;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        testUrl = 'http://test.com';
                        return [4 /*yield*/, new CloudClient(testSession).metadata(testUrl)];
                    case 1:
                        res = _a.sent();
                        expect(mockMetadata).toHaveBeenCalledWith(expect.any(String), JSON.stringify({
                            apikey: testApiKey,
                            url: testUrl,
                        }));
                        expect(res).toEqual('metadata');
                        return [2 /*return*/];
                }
            });
        }); });
        it('should make correct request with security', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var testUrl, res;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        testUrl = 'http://test.com';
                        return [4 /*yield*/, new CloudClient(tslib_1.__assign({}, testSession, testSecurity)).metadata(testUrl)];
                    case 1:
                        res = _a.sent();
                        expect(mockMetadata).toHaveBeenCalledWith(expect.any(String), JSON.stringify(tslib_1.__assign({ apikey: testApiKey, url: testUrl }, testSecurity)));
                        expect(res).toEqual('metadata');
                        return [2 /*return*/];
                }
            });
        }); });
    });
    describe('OpenTok', function () {
        describe('tokInit', function () {
            it('should make correct request to api (audio)', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                var res;
                return tslib_1.__generator(this, function (_a) {
                    switch (_a.label) {
                        case 0: return [4 /*yield*/, new CloudClient(testSession).tokInit('audio')];
                        case 1:
                            res = _a.sent();
                            expect(mockTokInit).toHaveBeenCalledWith(expect.any(String), '');
                            expect(res).toEqual({ body: 'init' });
                            return [2 /*return*/];
                    }
                });
            }); });
            it('should make correct request to api (video)', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                var res;
                return tslib_1.__generator(this, function (_a) {
                    switch (_a.label) {
                        case 0: return [4 /*yield*/, new CloudClient(testSession).tokInit('audio')];
                        case 1:
                            res = _a.sent();
                            expect(mockTokInit).toHaveBeenCalledWith(expect.any(String), '');
                            expect(res).toEqual({ body: 'init' });
                            return [2 /*return*/];
                    }
                });
            }); });
            it('should throw on wrong type', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                return tslib_1.__generator(this, function (_a) {
                    expect(function () {
                        new CloudClient(testSession).tokInit('videoa').then(function () {
                            console.log('init');
                        }).catch(function () {
                            console.log('err');
                        });
                    }).toThrowError();
                    return [2 /*return*/];
                });
            }); });
        });
        describe('tokStart', function () {
            it('should make correct request to api (audio)', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                var res;
                return tslib_1.__generator(this, function (_a) {
                    switch (_a.label) {
                        case 0: return [4 /*yield*/, new CloudClient(testSession).tokStart('audio', 'key', testTokSession)];
                        case 1:
                            res = _a.sent();
                            expect(mockTokStart).toHaveBeenCalledWith(expect.any(String), JSON.stringify({ apikey: 'key', session_id: testTokSession }));
                            expect(res).toEqual({ body: 'start' });
                            return [2 /*return*/];
                    }
                });
            }); });
            it('should make correct request to api (video)', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                var res;
                return tslib_1.__generator(this, function (_a) {
                    switch (_a.label) {
                        case 0: return [4 /*yield*/, new CloudClient(testSession).tokStart('video', 'key', testTokSession)];
                        case 1:
                            res = _a.sent();
                            expect(mockTokStart).toHaveBeenCalledWith(expect.any(String), JSON.stringify({ apikey: 'key', session_id: testTokSession }));
                            expect(res).toEqual({ body: 'start' });
                            return [2 /*return*/];
                    }
                });
            }); });
            it('should throw on wrong type', function () {
                expect(function () { return new CloudClient(testSession).tokStart('videoa', 'key', testTokSession); }).toThrowError();
            });
        });
        describe('tokStop', function () {
            it('should make correct request to api (audio)', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                var res;
                return tslib_1.__generator(this, function (_a) {
                    switch (_a.label) {
                        case 0: return [4 /*yield*/, new CloudClient(testSession).tokStop('audio', 'key', testTokSession, testTokArchiveId)];
                        case 1:
                            res = _a.sent();
                            expect(mockTokStop).toHaveBeenCalledWith(expect.any(String), JSON.stringify({
                                apikey: 'key',
                                session_id: testTokSession,
                                archive_id: testTokArchiveId,
                            }));
                            expect(res).toEqual({ body: 'stop' });
                            return [2 /*return*/];
                    }
                });
            }); });
            it('should make correct request to api (video)', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                var res;
                return tslib_1.__generator(this, function (_a) {
                    switch (_a.label) {
                        case 0: return [4 /*yield*/, new CloudClient(testSession).tokStop('video', 'key', testTokSession, testTokArchiveId)];
                        case 1:
                            res = _a.sent();
                            expect(mockTokStop).toHaveBeenCalledWith(expect.any(String), JSON.stringify({
                                apikey: 'key',
                                session_id: testTokSession,
                                archive_id: testTokArchiveId,
                            }));
                            expect(res).toEqual({ body: 'stop' });
                            return [2 /*return*/];
                    }
                });
            }); });
            it('should throw on wrong type', function () {
                expect(function () { return new CloudClient(testSession).tokStop('videoa', 'key', testTokSession, testTokArchiveId); }).toThrowError();
            });
        });
    });
});
