"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const auth = require("../auth");
const TestServer_1 = require("../TestServer");
const Token_1 = require("../shared/Token");
const util_1 = require("../shared/util");
const chai_1 = require("chai");
const chai = require("chai");
const superagent = require("superagent");
const Realm = require("realm");
const uuid = require("uuid");
const path = require("path");
const URI = require("urijs");
const faker = require("faker");
const tmp = require("tmp");
const index_1 = require("../index");
chai.use(require("chai-as-promised"));
class RemoteServer {
    constructor(address) {
        this.address = address;
        this.tmpDir = tmp.dirSync();
        Realm.Sync.setLogLevel("off");
    }
    get url() {
        return `http://${this.address}`;
    }
    get secureUrl() {
        return `https://${this.address}`;
    }
    get dataPath() {
        return this.tmpDir.name;
    }
    shutdown() {
        return __awaiter(this, void 0, void 0, function* () {
        });
    }
}
class Product {
}
Product.ProductSchema = {
    name: 'Product',
    primaryKey: 'productId',
    properties: {
        productId: { type: 'int', optional: false },
        name: { type: 'string', optional: false },
        price: { type: 'float', optional: false }
    }
};
describe('Realm-JS integration', function () {
    const openRealm = (config) => {
        return new Promise((resolve, reject) => {
            config.sync.error = (session, err) => reject(err);
            Realm.open(config)
                .then(resolve)
                .catch(reject);
        });
    };
    function waitAsync(getter, verifier, timeout = 5000) {
        return __awaiter(this, void 0, void 0, function* () {
            const msDelay = 50;
            if (!verifier) {
                verifier = (res) => !!res;
            }
            let result;
            for (let i = 0; i < timeout / msDelay; i++) {
                result = yield Promise.resolve(getter());
                if (verifier(result)) {
                    return result;
                }
                else {
                    yield util_1.delay(msDelay);
                }
            }
            throw new index_1.TimeoutError(timeout);
        });
    }
    let server;
    before(() => __awaiter(this, void 0, void 0, function* () {
        if (process.env.REMOTE_ROS) {
            server = new RemoteServer(process.env.REMOTE_ROS);
        }
        else {
            server = new TestServer_1.TestServer();
            yield server.start({
                authProviders: [new auth.PasswordAuthProvider({ autoCreateAdminUser: true, iterations: 1 })],
                https: true,
                httpsKeyPath: path.join(__dirname, "..", "..", "fixtures", "https.key"),
                httpsCertChainPath: path.join(__dirname, "..", "..", "fixtures", "https.crt"),
                logLevel: 'off',
            });
        }
    }));
    after(() => __awaiter(this, void 0, void 0, function* () {
        if (server) {
            yield server.shutdown();
        }
    }));
    function describeBasicTests(secure) {
        describe(`Basic tests secure=${secure}`, () => {
            let url;
            beforeEach(() => {
                url = secure ? server.secureUrl : server.url;
                process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
            });
            it('should be able to register to realm-js', function () {
                return __awaiter(this, void 0, void 0, function* () {
                    yield chai_1.assert.isFulfilled(Realm.Sync.User.register(url, faker.internet.userName(), faker.internet.password()));
                });
            });
            it('should be able to login to realm-js', function () {
                return __awaiter(this, void 0, void 0, function* () {
                    const username = faker.internet.userName();
                    const password = faker.internet.password();
                    const registeredUser = yield Realm.Sync.User.register(url, username, password);
                    registeredUser.logout();
                    yield chai_1.assert.isFulfilled(Realm.Sync.User.login(url, username, password));
                });
            });
            it('should be able to login to realm-js with an empty string password', function () {
                return __awaiter(this, void 0, void 0, function* () {
                    yield chai_1.assert.isFulfilled(Realm.Sync.User.login(url, 'realm-admin', ''));
                });
            });
            it.skip('should create error when trying to login with an unknown username', function () {
                return __awaiter(this, void 0, void 0, function* () {
                    yield chai_1.assert.isRejected(Realm.Sync.User.login(url, faker.internet.userName(), faker.internet.password()), 'The provided credentials are invalid or the user does not exist.');
                });
            });
            it('should create error when trying to register an existing username', function () {
                return __awaiter(this, void 0, void 0, function* () {
                    const username = faker.internet.userName();
                    const registeredUser = yield Realm.Sync.User.register(url, username, faker.internet.password());
                    registeredUser.logout();
                    yield chai_1.assert.isRejected(Realm.Sync.User.register(url, username, faker.internet.password()), 'The provided credentials are invalid or the user does not exist.');
                });
            });
            it('should be able to write to a realm', () => __awaiter(this, void 0, void 0, function* () {
                const username = faker.internet.userName();
                const localPath1 = path.join(server.dataPath, `${uuid.v4()}.realm`);
                const realm1 = yield registerAndGetRealm(url, username, 'samplepassword', localPath1);
                const localPath2 = path.join(server.dataPath, `${uuid.v4()}.realm`);
                const realm2 = yield loginAndGetRealm(url, username, 'samplepassword', localPath2);
                yield new Promise((resolve, reject) => {
                    let obj1;
                    realm2.addListener('change', (realm, event) => {
                        const obj2 = realm2.objectForPrimaryKey('Product', 0);
                        chai_1.assert.equal(obj1.name, obj2.name);
                        chai_1.assert.equal(obj1.price, obj2.price);
                        realm1.close();
                        realm2.close();
                        resolve();
                    });
                    realm1.write(() => {
                        obj1 = realm1.create('Product', {
                            productId: 0,
                            name: faker.commerce.productName(),
                            price: faker.random.number({ min: 12, max: 7000 })
                        }, true);
                    });
                });
            }));
            it('should be able to open a partial sync Realm even if not created', () => __awaiter(this, void 0, void 0, function* () {
                const adminUser = yield Realm.Sync.User.login(server.url, "realm-admin", "");
                const localPath1 = path.join(server.dataPath, `${uuid.v4()}.realm`);
                const localPath2 = path.join(server.dataPath, `${uuid.v4()}.realm`);
                const realm1 = yield openRealm({
                    path: localPath1,
                    sync: {
                        user: adminUser,
                        url: `realm://${server.address}/products`,
                        partial: true
                    },
                    schema: [Product.ProductSchema]
                });
                const realm2 = yield openRealm({
                    path: localPath2,
                    sync: {
                        user: adminUser,
                        url: `realm://${server.address}/products`
                    },
                    schema: [Product.ProductSchema]
                });
                yield new Promise((resolve, reject) => {
                    let obj1;
                    realm2.addListener('change', (realm, event) => {
                        if (obj1) {
                            const obj2 = realm2.objectForPrimaryKey('Product', 0);
                            chai_1.assert.equal(obj1.name, obj2.name);
                            chai_1.assert.equal(obj1.price, obj2.price);
                            realm1.close();
                            realm2.close();
                            resolve();
                        }
                    });
                    const products = realm1.objects('Product').filtered('productId == 0');
                    products.subscribe().addListener((subscription) => {
                        if (subscription.state === Realm.Sync.SubscriptionState.Complete && !obj1) {
                            realm1.write(() => {
                                obj1 = realm1.create('Product', {
                                    productId: 0,
                                    name: faker.commerce.productName(),
                                    price: faker.random.number({ min: 12, max: 7000 })
                                }, true);
                            });
                        }
                    });
                });
            }));
        });
    }
    function registerAndGetRealm(url, username, password, localPath) {
        return __awaiter(this, void 0, void 0, function* () {
            const user = yield Realm.Sync.User.register(url, username, password);
            const uri = URI.parse(url);
            const scheme = uri.protocol === "https" ? "realms" : "realm";
            return new Realm({
                path: localPath,
                sync: {
                    url: `${scheme}://${uri.hostname}:${uri.port}/~/products`,
                    user,
                    validate_ssl: false,
                },
                schema: [Product.ProductSchema]
            });
        });
    }
    function loginAndGetRealm(url, username, password, localPath) {
        return __awaiter(this, void 0, void 0, function* () {
            const user = yield Realm.Sync.User.login(url, username, password);
            const uri = URI.parse(url);
            const scheme = uri.protocol === "https" ? "realms" : "realm";
            return new Realm({
                path: localPath,
                sync: {
                    url: `${scheme}://${uri.hostname}:${uri.port}/~/products`,
                    user,
                    validate_ssl: false,
                },
                schema: [Product.ProductSchema]
            });
        });
    }
    describe("permissions", () => {
        let userA;
        let realmA;
        let userB;
        let userBProviderId;
        let realmAProduct;
        let adminUser;
        let permissionRealms = new Array();
        beforeEach(() => __awaiter(this, void 0, void 0, function* () {
            userA = yield Realm.Sync.User.register(server.url, faker.internet.userName(), faker.internet.password());
            userBProviderId = faker.internet.userName();
            userB = yield Realm.Sync.User.register(server.url, userBProviderId, faker.internet.password());
            adminUser = yield Realm.Sync.User.login(server.url, "realm-admin", "");
            realmA = yield openRealm({
                sync: {
                    user: userA,
                    url: `realm://${server.address}/~/products`
                },
                schema: [Product.ProductSchema]
            });
            realmA.write(() => {
                realmAProduct = realmA.create('Product', {
                    productId: 0,
                    name: faker.commerce.productName(),
                    price: faker.random.number({ min: 12, max: 7000 })
                });
            });
        }));
        afterEach(() => {
            if (realmA) {
                realmA.close();
            }
            for (const realm of permissionRealms) {
                realm.close();
            }
            permissionRealms = [];
        });
        function assertAppliedPermissions(permission, expected) {
            chai_1.assert.equal(permission.statusCode, 0, `Expected statusCode=0, but got ${permission.statusCode} instead`);
            chai_1.assert.equal(permission.mayRead, expected.mayRead, `Expected mayRead=${expected.mayRead}, but got ${permission.mayRead} instead`);
            chai_1.assert.equal(permission.mayWrite, expected.mayWrite, `Expected mayWrite=${expected.mayWrite}, but got ${permission.mayWrite} instead`);
            chai_1.assert.equal(permission.mayManage, expected.mayManage, `Expected mayRead=${expected.mayManage}, but got ${permission.mayManage} instead`);
            chai_1.assert.equal(permission.userId, expected.userId, `Expected userId=${expected.userId}, but got ${permission.userId} instead`);
            chai_1.assert.equal(permission.realmUrl, expected.path, `Expected realmUrl=${expected.path}, but got ${permission.realmUrl} instead`);
            if (expected.metadataKey) {
                chai_1.assert.equal(permission.metadataKey, expected.metadataKey);
            }
            if (expected.metadataValue) {
                chai_1.assert.equal(permission.metadataValue, expected.metadataValue);
            }
        }
        function applyAndAssertPermission(user, condition, path, level, expected) {
            return __awaiter(this, void 0, void 0, function* () {
                const permission = yield user.applyPermissions(condition, path, level);
                assertAppliedPermissions(permission, expected);
            });
        }
        function getGrantedPermissions(user, legacy = false) {
            return __awaiter(this, void 0, void 0, function* () {
                const filterString = 'NOT path ENDSWITH "__permission" AND NOT path ENDSWITH "__management" AND NOT path ENDSWITH "__perm"';
                if (legacy) {
                    return (yield user.getGrantedPermissions('any')).filtered(filterString);
                }
                else {
                    const realm = yield openRealm({
                        sync: {
                            user,
                            url: `realm://${server.address}/~/__perm`,
                        },
                    });
                    yield waitAsync(() => realm.schema.find(s => s.name === 'Permission'), undefined, 20000);
                    permissionRealms.push(realm);
                    return realm.objects('Permission').filtered(filterString);
                }
            });
        }
        function assertInsertionInUserPermissions(user, expected, legacy = null) {
            if (legacy === null) {
                const [subscribedLeg, updatedLeg] = assertInsertionInUserPermissions(user, expected, true);
                const [subscribed, updated] = assertInsertionInUserPermissions(user, expected, false);
                return [
                    Promise.all([subscribedLeg, subscribed]).then(() => { }),
                    Promise.all([updatedLeg, updated]).then(() => { }),
                ];
            }
            let resolveUpdated, rejectUpdated;
            const updated = new Promise((resolve, reject) => {
                resolveUpdated = resolve;
                rejectUpdated = reject;
            });
            const check = function (perm) {
                try {
                    chai_1.assert.equal(perm.mayRead, expected.mayRead, `Expected user to have mayRead=${expected.mayRead}`);
                    chai_1.assert.equal(perm.mayWrite, expected.mayWrite, `Expected user to have mayWrite=${expected.mayWrite}`);
                    chai_1.assert.equal(perm.mayManage, expected.mayManage, `Expected user to have mayManage=${expected.mayManage}`);
                    resolveUpdated();
                }
                catch (e) {
                    rejectUpdated(e);
                }
            };
            const subscribed = getGrantedPermissions(user, legacy).then((perms) => {
                const matchingPermissions = perms.filtered([
                    "userId = $0", "path = $1", "mayRead = $2",
                    "mayWrite = $3", "mayManage = $4",
                ].join(" AND "), expected.userId, expected.path, expected.mayRead, expected.mayWrite, expected.mayManage);
                const handler = (permissions, changes) => {
                    if (changes.modifications.length > 0) {
                        matchingPermissions.removeAllListeners();
                        check(matchingPermissions[0]);
                    }
                    if (changes.insertions.length > 0) {
                        matchingPermissions.removeAllListeners();
                        check(matchingPermissions[0]);
                    }
                };
                matchingPermissions.addListener(handler);
            });
            return [subscribed, updated];
        }
        function assertDeletionInUserPermissions(user, expected, legacy = null) {
            if (legacy == null) {
                const [subscribedLeg, updatedLeg] = assertDeletionInUserPermissions(user, expected, true);
                const [subscribed, updated] = assertDeletionInUserPermissions(user, expected, false);
                return [
                    Promise.all([subscribedLeg, subscribed]),
                    Promise.all([updatedLeg, updated]),
                ];
            }
            let resolveUpdated;
            const updated = new Promise((resolve, reject) => {
                resolveUpdated = resolve;
            });
            const subscribed = getGrantedPermissions(user, legacy).then((perms) => {
                const matchingPermissions = perms.filtered([
                    "userId = $0", "path = $1", "mayRead = $2",
                    "mayWrite = $3", "mayManage = $4",
                ].join(" AND "), expected.userId, expected.path, expected.mayRead, expected.mayWrite, expected.mayManage);
                const numMatchingPermissions = matchingPermissions.length;
                const handler = (permissions, changes) => {
                    if (changes.deletions.length > 0) {
                        matchingPermissions.removeAllListeners();
                        resolveUpdated();
                    }
                    else if (changes.insertions.length === 0 && changes.modifications.length === 0) {
                        if (matchingPermissions.length < numMatchingPermissions || numMatchingPermissions === 0) {
                            matchingPermissions.removeAllListeners();
                            resolveUpdated();
                        }
                    }
                };
                matchingPermissions.addListener(handler);
            });
            return [subscribed, updated];
        }
        function assertUserPermissionsConcrete(user, expected, legacy = null) {
            return __awaiter(this, void 0, void 0, function* () {
                const result = yield getGrantedPermissions(user, legacy);
                for (const e of expected) {
                    const perm = result.slice().filter((p) => {
                        return p.userId === e.userId;
                    }).find((p) => {
                        return p.path === e.path;
                    });
                    chai_1.assert.isDefined(perm);
                    chai_1.assert.equal(perm.mayRead, e.mayRead, `Expected user to have mayRead=${e.mayRead}`);
                    chai_1.assert.equal(perm.mayWrite, e.mayWrite, `Expected user to have mayWrite=${e.mayWrite}`);
                    chai_1.assert.equal(perm.mayManage, e.mayManage, `Expected user to have mayManage=${e.mayManage}`);
                }
            });
        }
        function assertUserPermissions(user, ...expected) {
            return __awaiter(this, void 0, void 0, function* () {
                yield Promise.all([
                    assertUserPermissionsConcrete(user, expected, true),
                    assertUserPermissionsConcrete(user, expected, false),
                ]);
            });
        }
        function assertWildcardPermission(user, expected, legacy = null) {
            return __awaiter(this, void 0, void 0, function* () {
                if (legacy == null) {
                    yield assertWildcardPermission(user, expected, true);
                    yield assertWildcardPermission(user, expected, false);
                    return;
                }
                const urlPath = legacy ? '__wildcardpermissions' : '__perm';
                const wildcardPermissionRealm = yield openRealm({
                    sync: {
                        user: user,
                        url: `realm://${server.address}/${urlPath}`,
                    },
                });
                try {
                    const perm = yield waitAsync(() => wildcardPermissionRealm.objects('Permission').filtered('path = $0', expected.path)[0]);
                    chai_1.assert.isDefined(perm);
                    chai_1.assert.equal(perm.mayRead, expected.mayRead, `Expected wildcard permission to have mayRead=${expected.mayRead}`);
                    chai_1.assert.equal(perm.mayWrite, expected.mayWrite, `Expected wildcard permission to have mayWrite=${expected.mayWrite}`);
                    chai_1.assert.equal(perm.mayManage, expected.mayManage, `Expected wildcard permission to have mayManage=${expected.mayManage}`);
                }
                finally {
                    wildcardPermissionRealm.close();
                }
            });
        }
        describe("default permissions", () => {
            describe("with 10 new realms", () => {
                beforeEach(() => __awaiter(this, void 0, void 0, function* () {
                    for (let i = 0; i < 10; i++) {
                        const realm = yield openRealm({
                            sync: {
                                user: userA,
                                url: `realm://${server.address}/~/products${i}`
                            },
                            schema: [Product.ProductSchema]
                        });
                        realm.close();
                    }
                }));
                it("should receive all 10 permissions", () => __awaiter(this, void 0, void 0, function* () {
                    const result = yield waitAsync(() => userA.getGrantedPermissions('any'), p => p.length >= 10);
                    for (let i = 0; i < 10; i++) {
                        const permission = result.slice().find((p) => {
                            return p.path === `/${userA.identity}/products${i}`;
                        });
                        chai_1.assert.isDefined(permission, `Could not find default permission for /~/products${i}`);
                        chai_1.assert.equal(permission.userId, userA.identity);
                        chai_1.assert.equal(permission.mayRead, true);
                        chai_1.assert.equal(permission.mayWrite, true);
                        chai_1.assert.equal(permission.mayManage, true);
                    }
                }));
            });
        });
        describe("changes", function () {
            this.timeout(30000);
            describe("wildcard", () => {
                describe("userA granting read to all users on /~/products", () => {
                    it("userB should be able to read", () => __awaiter(this, void 0, void 0, function* () {
                        yield applyAndAssertPermission(userA, { userId: "*" }, '/~/products', 'read', {
                            mayRead: true,
                            mayWrite: false,
                            mayManage: false,
                            userId: "*",
                            path: "/~/products",
                        });
                        const realm = yield chai_1.assert.isFulfilled(openRealm({
                            sync: {
                                url: `realm://${server.address}/${userA.identity}/products`,
                                user: userB,
                            },
                            schema: [Product.ProductSchema]
                        }));
                        realm.close();
                    }));
                });
                describe("userA granting read to userB on all realms", () => {
                    it("userB should be able to read /~/products2", () => __awaiter(this, void 0, void 0, function* () {
                        const userARealm = yield chai_1.assert.isFulfilled(openRealm({
                            sync: {
                                url: `realm://${server.address}/${userA.identity}/products2`,
                                user: userA,
                            },
                            schema: [Product.ProductSchema]
                        }));
                        userARealm.close();
                        yield applyAndAssertPermission(userA, { userId: userB.identity }, '*', 'read', {
                            mayRead: true,
                            mayWrite: false,
                            mayManage: false,
                            userId: userB.identity,
                            path: "*",
                        });
                        const userBRealm = yield chai_1.assert.isFulfilled(openRealm({
                            sync: {
                                url: `realm://${server.address}/${userA.identity}/products2`,
                                user: userB,
                            },
                            schema: [Product.ProductSchema]
                        }));
                        userBRealm.close();
                    }));
                });
                describe("userA granting read to all users on all realms", () => {
                    it("userB should be able to read /~/products", () => __awaiter(this, void 0, void 0, function* () {
                        yield applyAndAssertPermission(userA, { userId: "*" }, '*', 'read', {
                            mayRead: true,
                            mayWrite: false,
                            mayManage: false,
                            userId: "*",
                            path: "*",
                        });
                        const userBRealm = yield chai_1.assert.isFulfilled(openRealm({
                            sync: {
                                url: `realm://${server.address}/${userA.identity}/products`,
                                user: userB,
                            },
                            schema: [Product.ProductSchema]
                        }));
                        userBRealm.close();
                    }));
                });
            });
            describe("with an invalid user in the path", () => {
                it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () {
                    const token = Token_1.generateAdminToken({
                        privateKey: server.privateKey,
                    });
                    const tokenUser = Realm.Sync.User.adminUser(token, server.url);
                    yield chai_1.assert.isRejected(tokenUser.applyPermissions({ userId: "*" }, "/__auth/products", "read"), "Your request parameters did not validate.");
                }));
            });
            describe("to an email address", () => {
                let userBEmailAddress;
                beforeEach(() => __awaiter(this, void 0, void 0, function* () {
                    userBEmailAddress = faker.internet.email();
                }));
                describe("invalid email address", () => {
                    it("should throw", () => __awaiter(this, void 0, void 0, function* () {
                        const error = yield chai_1.assert.isRejected(userA.applyPermissions({ metadataKey: "email", metadataValue: userBEmailAddress }, "/~/products", 'read'), "Your request parameters did not validate.");
                        chai_1.assert.equal(error.statusCode, 601);
                    }));
                });
                describe("userA granting read to userB with just email and no metadata on user", () => {
                    let userB;
                    let userBEmailAddress;
                    beforeEach(() => __awaiter(this, void 0, void 0, function* () {
                        userBEmailAddress = faker.internet.email();
                        userB = yield Realm.Sync.User.register(server.url, userBEmailAddress, faker.internet.password());
                    }));
                    it("should be successful", () => __awaiter(this, void 0, void 0, function* () {
                        const [subscribed, updated] = assertInsertionInUserPermissions(userB, {
                            userId: userB.identity,
                            mayRead: true,
                            mayWrite: false,
                            mayManage: false,
                            path: `/${userA.identity}/products`
                        });
                        yield subscribed;
                        const applied = applyAndAssertPermission(userA, {
                            metadataKey: 'email',
                            metadataValue: userBEmailAddress
                        }, '/~/products', 'read', {
                            mayRead: true,
                            mayWrite: false,
                            mayManage: false,
                            metadataKey: "email",
                            metadataValue: userBEmailAddress,
                            userId: "",
                            path: "/~/products",
                        });
                        yield Promise.all([updated, applied]);
                    }));
                });
                describe("userA granting read to userB's email address (metadata)", () => {
                    let adminUser;
                    beforeEach(() => __awaiter(this, void 0, void 0, function* () {
                        adminUser = yield Realm.Sync.User.login(server.url, "realm-admin", "");
                        yield superagent.put(`${server.url}/auth/users`).set({
                            Authorization: adminUser.token,
                        })
                            .send({
                            provider_id: userBProviderId,
                            provider: "password",
                            metadata: {
                                email: userBEmailAddress
                            },
                            user_id: userB.identity
                        });
                    }));
                    it("should be successful", () => __awaiter(this, void 0, void 0, function* () {
                        const [subscribed, updated] = assertInsertionInUserPermissions(userB, {
                            userId: userB.identity,
                            mayRead: true,
                            mayWrite: false,
                            mayManage: false,
                            path: `/${userA.identity}/products`
                        });
                        yield subscribed;
                        const applied = applyAndAssertPermission(userA, {
                            metadataKey: "email",
                            metadataValue: userBEmailAddress
                        }, '/~/products', 'read', {
                            mayRead: true,
                            mayWrite: false,
                            mayManage: false,
                            metadataKey: "email",
                            metadataValue: userBEmailAddress,
                            userId: "",
                            path: "/~/products",
                        });
                        yield Promise.all([updated, applied]);
                    }));
                });
            });
            describe("userA granting read to userB to own __permission realm", () => {
                it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () {
                    const error = yield chai_1.assert.isRejected(userA.applyPermissions({ userId: userB.identity }, "/~/__permission", 'read'), "Your request parameters did not validate.");
                    chai_1.assert.equal(error.statusCode, 601);
                }));
            });
            describe("userA granting read to userB to own __management realm", () => {
                it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () {
                    const error = yield chai_1.assert.isRejected(userA.applyPermissions({ userId: userB.identity }, "/~/__management", 'read'), "Your request parameters did not validate.");
                    chai_1.assert.equal(error.statusCode, 601);
                }));
            });
            describe("userA granting read to userB", () => {
                it("should be successful", () => __awaiter(this, void 0, void 0, function* () {
                    const [subscribedAB, updatedAB] = assertInsertionInUserPermissions(userA, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: false,
                        mayManage: false,
                        path: `/${userA.identity}/products`
                    });
                    const [subscribedBB, updatedBB] = assertInsertionInUserPermissions(userB, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: false,
                        mayManage: false,
                        path: `/${userA.identity}/products`
                    });
                    yield Promise.all([subscribedAB, subscribedBB]);
                    const applied = applyAndAssertPermission(userA, { userId: userB.identity }, "/~/products", 'read', {
                        mayRead: true,
                        mayWrite: false,
                        mayManage: false,
                        userId: userB.identity,
                        path: "/~/products",
                    });
                    yield Promise.all([updatedAB, updatedBB, applied]);
                }));
            });
            describe("userA granting write to userB", () => {
                it("should be successful", () => __awaiter(this, void 0, void 0, function* () {
                    const [subscribedAB, updatedAB] = assertInsertionInUserPermissions(userA, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: true,
                        mayManage: false,
                        path: `/${userA.identity}/products`
                    });
                    const [subscribedBB, updatedBB] = assertInsertionInUserPermissions(userB, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: true,
                        mayManage: false,
                        path: `/${userA.identity}/products`
                    });
                    yield Promise.all([subscribedAB, subscribedBB]);
                    const applied = applyAndAssertPermission(userA, { userId: userB.identity }, "/~/products", 'write', {
                        mayRead: true,
                        mayWrite: true,
                        mayManage: false,
                        userId: userB.identity,
                        path: "/~/products",
                    });
                    yield Promise.all([updatedAB, updatedBB, applied]);
                }));
            });
            describe("userA granting admin to userB", () => {
                it("should be successful", () => __awaiter(this, void 0, void 0, function* () {
                    const [subscribedAB, updatedAB] = assertInsertionInUserPermissions(userA, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: true,
                        mayManage: true,
                        path: `/${userA.identity}/products`
                    });
                    const [subscribedBB, updatedBB] = assertInsertionInUserPermissions(userB, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: true,
                        mayManage: true,
                        path: `/${userA.identity}/products`
                    });
                    yield Promise.all([subscribedAB, subscribedBB]);
                    const applied = applyAndAssertPermission(userA, { userId: userB.identity }, "/~/products", 'admin', {
                        mayRead: true,
                        mayWrite: true,
                        mayManage: true,
                        userId: userB.identity,
                        path: "/~/products",
                    });
                    yield Promise.all([updatedAB, updatedBB, applied]);
                }));
            });
            describe("userA decreasing userB's admin privileges", () => {
                beforeEach(() => __awaiter(this, void 0, void 0, function* () {
                    const [subscribedAB, updatedAB] = assertInsertionInUserPermissions(userA, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: true,
                        mayManage: true,
                        path: `/${userA.identity}/products`
                    });
                    const [subscribedBB, updatedBB] = assertInsertionInUserPermissions(userB, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: true,
                        mayManage: true,
                        path: `/${userA.identity}/products`
                    });
                    yield Promise.all([subscribedAB, subscribedBB]);
                    const applied = applyAndAssertPermission(userA, { userId: userB.identity }, "/~/products", 'admin', {
                        mayRead: true,
                        mayWrite: true,
                        mayManage: true,
                        userId: userB.identity,
                        path: "/~/products",
                    });
                    yield Promise.all([updatedAB, updatedBB, applied]);
                }));
                it("to read-only permissions", () => __awaiter(this, void 0, void 0, function* () {
                    const [subscribedAB, updatedAB] = assertInsertionInUserPermissions(userA, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: false,
                        mayManage: false,
                        path: `/${userA.identity}/products`
                    });
                    const [subscribedBB, updatedBB] = assertInsertionInUserPermissions(userB, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: false,
                        mayManage: false,
                        path: `/${userA.identity}/products`
                    });
                    yield Promise.all([subscribedAB, subscribedBB]);
                    const applied = applyAndAssertPermission(userA, { userId: userB.identity }, "/~/products", 'read', {
                        mayRead: true,
                        mayWrite: false,
                        mayManage: false,
                        userId: userB.identity,
                        path: "/~/products",
                    });
                    yield Promise.all([updatedAB, updatedBB, applied]);
                }));
                it("to no permissions at all", () => __awaiter(this, void 0, void 0, function* () {
                    const [subscribedAB, updatedAB] = assertDeletionInUserPermissions(userA, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: true,
                        mayManage: true,
                        path: `/${userA.identity}/products`,
                    });
                    const [subscribedBB, updatedBB] = assertDeletionInUserPermissions(userB, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: true,
                        mayManage: true,
                        path: `/${userA.identity}/products`
                    });
                    yield Promise.all([subscribedAB, subscribedBB]);
                    const applied = userA.applyPermissions({ userId: userB.identity }, "/~/products", 'none');
                    yield Promise.all([updatedAB, updatedBB, applied]);
                }));
            });
            describe("userA granting write to userB with userC's Realm", () => {
                it("should fail", () => __awaiter(this, void 0, void 0, function* () {
                    const userC = yield Realm.Sync.User.register(server.url, faker.internet.userName(), faker.internet.password());
                    const userCRealm = yield openRealm({
                        sync: {
                            url: `realm://${server.address}/~/products`,
                            user: userC,
                        },
                        schema: [Product.ProductSchema]
                    });
                    userCRealm.close();
                    const err = yield chai_1.assert.isRejected(userA.applyPermissions({ userId: userB.identity }, `/${userC.identity}/products`, 'write'), "The path is invalid or current user has no access.");
                    chai_1.assert.equal(err.statusCode, 614);
                }));
            });
            describe("userA granting read to all", () => {
                it("should be successful for userB to open", () => __awaiter(this, void 0, void 0, function* () {
                    const response = yield userA.applyPermissions({ userId: "*" }, "/~/products", 'read');
                    const realm = yield chai_1.assert.isFulfilled(openRealm({
                        sync: {
                            url: `realm://${server.address}/${userA.identity}/products`,
                            user: userB,
                        },
                        schema: [Product.ProductSchema]
                    }));
                    realm.close();
                }));
            });
            describe("userA granting admin to all", () => {
                it("should allow userB to change permission to write", () => __awaiter(this, void 0, void 0, function* () {
                    const response = yield userA.applyPermissions({ userId: "*" }, "/~/products", 'admin');
                    assertAppliedPermissions(yield userB.applyPermissions({ userId: "*" }, `/${userA.identity}/products`, 'write'), {
                        mayRead: true,
                        mayWrite: true,
                        mayManage: false,
                        userId: "*",
                        path: `/${userA.identity}/products`,
                    });
                }));
            });
            describe("adminUser granting write to all for userA's realm", () => {
                it("should generate a wildcard permission", () => __awaiter(this, void 0, void 0, function* () {
                    const response = yield adminUser.applyPermissions({ userId: "*" }, `/${userA.identity}/products`, 'write');
                    yield assertWildcardPermission(adminUser, {
                        mayRead: true,
                        mayWrite: true,
                        mayManage: false,
                        path: `/${userA.identity}/products`
                    });
                }));
            });
            describe("userA granting read to all", () => {
                it("should allow userB to see wildcard permission", () => __awaiter(this, void 0, void 0, function* () {
                    const response = yield userA.applyPermissions({ userId: "*" }, "/~/products", 'read');
                    yield assertWildcardPermission(userB, {
                        mayRead: true,
                        mayWrite: false,
                        mayManage: false,
                        path: `/${userA.identity}/products`
                    });
                }));
            });
        });
        describe("Admin token user", () => {
            let userA;
            let adminTokenUser;
            beforeEach(() => __awaiter(this, void 0, void 0, function* () {
                const userNameA = uuid.v4();
                const passwordA = faker.internet.password();
                userA = yield Realm.Sync.User.register(server.url, userNameA, passwordA);
                const token = Token_1.generateAdminToken({
                    privateKey: server.privateKey,
                });
                adminTokenUser = Realm.Sync.User.adminUser(token, server.url);
                const realmA = yield openRealm({
                    sync: {
                        user: userA,
                        url: `realm://${server.address}/~/products`
                    },
                    schema: [Product.ProductSchema]
                });
            }));
            describe("adminTokenUser granting write to all for userA's realm", () => {
                it("should generate a wildcard permission", () => __awaiter(this, void 0, void 0, function* () {
                    const response = yield adminTokenUser.applyPermissions({ userId: "*" }, `/${userA.identity}/products`, 'write');
                    yield assertWildcardPermission(adminTokenUser, {
                        mayRead: true,
                        mayWrite: true,
                        mayManage: false,
                        path: `/${userA.identity}/products`
                    });
                }));
            });
        });
        describe("offers", () => {
            describe("with an invalid user in the path", () => {
                it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () {
                    const token = Token_1.generateAdminToken({
                        privateKey: server.privateKey,
                    });
                    const tokenUser = Realm.Sync.User.adminUser(token, server.url);
                    yield chai_1.assert.isRejected(tokenUser.offerPermissions("/__auth/products", "read"), "Your request parameters did not validate.");
                }));
            });
            describe("userA offers read permission to Realm that doesn't exist", () => {
                it("should fail", () => __awaiter(this, void 0, void 0, function* () {
                    const error = yield chai_1.assert.isRejected(userA.offerPermissions(`/~/products-no-exist`, 'read'), "Your request parameters did not validate.");
                    chai_1.assert.equal(error.statusCode, 601);
                }));
            });
            describe("userA offers read permissions to a Realm without manage access", () => {
                it("should fail", () => __awaiter(this, void 0, void 0, function* () {
                    const realm = yield chai_1.assert.isFulfilled(openRealm({
                        sync: {
                            url: `realm://${server.address}/~/products`,
                            user: userB,
                        },
                        schema: [Product.ProductSchema]
                    }));
                    const error = yield chai_1.assert.isRejected(userA.offerPermissions(`/${userB.identity}/products`, 'read'), "The path is invalid or current user has no access.");
                    chai_1.assert.equal(error.statusCode, 614);
                }));
            });
            describe("userA offers read permissions", () => {
                let token;
                beforeEach(() => __awaiter(this, void 0, void 0, function* () {
                    token = yield userA.offerPermissions(`/~/products`, 'read');
                }));
                describe("userB accepts permission offer", () => {
                    let offeredPath;
                    beforeEach(() => __awaiter(this, void 0, void 0, function* () {
                        offeredPath = (yield chai_1.assert.isFulfilled(userB.acceptPermissionOffer(token)));
                    }));
                    it("should be successful", () => __awaiter(this, void 0, void 0, function* () {
                        chai_1.assert.equal(offeredPath, `/${userA.identity}/products`);
                        yield assertUserPermissions(userA, {
                            userId: userB.identity,
                            mayRead: true,
                            mayWrite: false,
                            mayManage: false,
                            path: `/${userA.identity}/products`
                        });
                        yield assertUserPermissions(userB, {
                            userId: userB.identity,
                            mayRead: true,
                            mayWrite: false,
                            mayManage: false,
                            path: `/${userA.identity}/products`
                        });
                        const realm = yield chai_1.assert.isFulfilled(openRealm({
                            sync: {
                                url: `realm://${server.address}${offeredPath}`,
                                user: userB,
                            },
                        }));
                        const p = realm.objects("Product")[0];
                        chai_1.assert.equal(p.productId, realmAProduct.productId);
                        chai_1.assert.equal(p.name, realmAProduct.name);
                        chai_1.assert.equal(p.price, realmAProduct.price);
                        realm.write(() => {
                            realm.create('Product', {
                                productId: 1,
                                name: faker.commerce.productName(),
                                price: faker.random.number({ min: 12, max: 7000 })
                            });
                        });
                        realm.close();
                    }));
                    it("userB should not be able to offer permissions to it (no manage)", () => __awaiter(this, void 0, void 0, function* () {
                        const error = yield chai_1.assert.isRejected(userB.offerPermissions(`/${userA.identity}/products`, 'read'), "The path is invalid or current user has no access.");
                        chai_1.assert.equal(error.statusCode, 614);
                    }));
                });
                describe("userA then invalidates the offer", () => {
                    beforeEach(() => __awaiter(this, void 0, void 0, function* () {
                        yield userA.invalidatePermissionOffer(token);
                    }));
                    it("userB should not be able to accept the offer", () => __awaiter(this, void 0, void 0, function* () {
                        yield chai_1.assert.isRejected(userB.acceptPermissionOffer(token), "The permission offer is expired.");
                        const error = yield chai_1.assert.isRejected(openRealm({
                            sync: {
                                url: `realm://${server.address}/${userA.identity}/products`,
                                user: userB,
                            },
                            schema: [Product.ProductSchema]
                        }), "The path is invalid or current user has no access.");
                        chai_1.assert.equal(error.status, 403);
                        chai_1.assert.equal(error.code, 614);
                    }));
                });
            });
            describe("userA offers redundant permissions to administrator", () => __awaiter(this, void 0, void 0, function* () {
                beforeEach(() => __awaiter(this, void 0, void 0, function* () {
                    const [subscribedBB, updatedBB] = assertInsertionInUserPermissions(userB, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: true,
                        mayManage: true,
                        path: `/${userA.identity}/products`
                    });
                    yield index_1.timeout(subscribedBB, 10000);
                    const applied = applyAndAssertPermission(userA, {
                        userId: userB.identity
                    }, "/~/products", 'admin', {
                        mayRead: true,
                        mayWrite: true,
                        mayManage: true,
                        userId: userB.identity,
                        path: "/~/products",
                    });
                    yield Promise.all([
                        index_1.timeout(updatedBB, 15000),
                        index_1.timeout(applied, 15000)
                    ]);
                }));
                it("should not remove admin status if offered a write permission", () => __awaiter(this, void 0, void 0, function* () {
                    const token = yield userA.offerPermissions(`/~/products`, 'write');
                    const offeredPath = yield chai_1.assert.isFulfilled(userB.acceptPermissionOffer(token));
                    yield assertUserPermissions(userB, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: true,
                        mayManage: true,
                        path: offeredPath
                    });
                }));
                it("should not remove admin status if offered a read permission", () => __awaiter(this, void 0, void 0, function* () {
                    const token = yield userA.offerPermissions(`/~/products`, 'read');
                    const offeredPath = yield chai_1.assert.isFulfilled(userB.acceptPermissionOffer(token));
                    yield assertUserPermissions(userB, {
                        userId: userB.identity,
                        mayRead: true,
                        mayWrite: true,
                        mayManage: true,
                        path: offeredPath
                    });
                }));
            }));
            describe("userA offers expired permissions to userB", () => __awaiter(this, void 0, void 0, function* () {
                it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () {
                    const expiresAt = new Date();
                    const error = yield chai_1.assert.isRejected(userA.offerPermissions(`/~/products`, 'write', expiresAt), "The permission offer is expired.");
                    chai_1.assert.equal(error.statusCode, 701);
                }));
            }));
            describe("userB accepts expired permission offer from userA", () => __awaiter(this, void 0, void 0, function* () {
                it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () {
                    const expiresAt = new Date();
                    expiresAt.setSeconds(expiresAt.getSeconds() + 1);
                    const token = yield userA.offerPermissions(`/~/products`, 'write', expiresAt);
                    yield new Promise((resolve) => setTimeout(resolve, 1000));
                    const error = yield chai_1.assert.isRejected(userB.acceptPermissionOffer(token), "The permission offer is expired.");
                    chai_1.assert.equal(error.statusCode, 701);
                }));
            }));
            describe("userB accepts expired permission offer with invalid token", () => __awaiter(this, void 0, void 0, function* () {
                it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () {
                    const token = "INVALID TOKEN";
                    const error = yield chai_1.assert.isRejected(userB.acceptPermissionOffer(token), "Your request parameters did not validate.");
                    chai_1.assert.equal(error.statusCode, 601);
                }));
            }));
            describe("userB accepts expired permission offer with invalid token", () => __awaiter(this, void 0, void 0, function* () {
                it("should reject with an error", () => __awaiter(this, void 0, void 0, function* () {
                    const userC = yield Realm.Sync.User.register(server.url, faker.internet.userName(), faker.internet.password());
                    const token = "INVALID TOKEN";
                    const error = yield chai_1.assert.isRejected(userB.acceptPermissionOffer(token), "Your request parameters did not validate.");
                    chai_1.assert.equal(error.statusCode, 601);
                }));
            }));
        });
    });
    describe("Partial sync with other user's Realm", () => {
        it("Opening the partial Realm should succeed", () => __awaiter(this, void 0, void 0, function* () {
            const username1 = faker.internet.userName();
            const password1 = faker.internet.password();
            const username2 = faker.internet.userName();
            const password2 = faker.internet.password();
            const user1 = yield Realm.Sync.User.register(server.url, username1, password1);
            const user2 = yield Realm.Sync.User.register(server.url, username2, password2);
            yield chai_1.assert.isFulfilled(openRealm({
                sync: {
                    url: `realm://${server.address}/${user1.identity}/product`,
                    user: user1,
                    partial: true
                },
                schema: [Product.ProductSchema]
            }));
            yield chai_1.assert.isFulfilled(openRealm({
                sync: {
                    url: `realm://${server.address}/${user1.identity}/product`,
                    user: user2,
                    partial: true
                },
                schema: [Product.ProductSchema]
            }));
        }));
        it("Opening the partial Realm with incorrect prefix should fail", () => __awaiter(this, void 0, void 0, function* () {
            const username = faker.internet.userName();
            const password = faker.internet.password();
            const user = yield Realm.Sync.User.register(server.url, username, password);
            const bad_prefix = `abc${user.identity}`;
            const error = yield chai_1.assert.isRejected(openRealm({
                sync: {
                    url: `realm://${server.address}/${bad_prefix}/product`,
                    user: user,
                    partial: true
                },
                schema: [Product.ProductSchema]
            }), "");
            chai_1.assert.equal(error.name, "AuthError");
        }));
    });
    describe("Default Realm", () => {
        it("admin user should be able to perform partial sync with the default Realm", () => __awaiter(this, void 0, void 0, function* () {
            const adminUser = yield Realm.Sync.User.login(server.url, "realm-admin", "");
            const realm = yield chai_1.assert.isFulfilled(openRealm({
                sync: {
                    url: `realm://${server.address}/default`,
                    user: adminUser,
                    partial: true
                },
                schema: [Product.ProductSchema]
            }));
        }));
        it("non-admin user should be able to perform partial sync with the default Realm", () => __awaiter(this, void 0, void 0, function* () {
            const username = faker.internet.userName();
            const password = faker.internet.password();
            const user = yield Realm.Sync.User.register(server.url, username, password);
            const realm = yield chai_1.assert.isFulfilled(openRealm({
                sync: {
                    url: `realm://${server.address}/default`,
                    user: user,
                    partial: true
                },
                schema: [Product.ProductSchema]
            }));
        }));
    });
    describe.skip("User deletion", () => {
        let userNameA;
        let passwordA;
        let userIdA;
        let adminUser;
        beforeEach(() => __awaiter(this, void 0, void 0, function* () {
            userNameA = uuid.v4();
            passwordA = faker.internet.password();
            const userA = yield Realm.Sync.User.register(server.url, userNameA, passwordA);
            userIdA = userA.identity;
            adminUser = yield Realm.Sync.User.login(server.url, "realm-admin", "");
            const realmA = yield openRealm({
                sync: {
                    user: userA,
                    url: `realm://${server.address}/~/products`
                },
                schema: [Product.ProductSchema]
            });
            realmA.write(() => {
                realmA.create('Product', {
                    productId: 0,
                    name: faker.commerce.productName(),
                    price: faker.random.number({ min: 12, max: 7000 })
                });
            });
            const uploadCompletion = new Promise((resolve, reject) => {
                realmA.syncSession.addProgressNotification('upload', 'forCurrentlyOutstandingWork', (uploaded, uploadable) => {
                    if (uploaded === uploadable) {
                        resolve();
                    }
                });
            });
            yield uploadCompletion;
            realmA.close();
        }));
        it("UserA can login", () => __awaiter(this, void 0, void 0, function* () {
            const user = yield Realm.Sync.User.login(server.url, userNameA, passwordA);
            chai_1.assert.strictEqual(user.identity, userIdA, "The user name must be the same");
        }));
        it.skip("UserA cannot login after being deleted", () => __awaiter(this, void 0, void 0, function* () {
            const response = yield superagent.delete(`${server.url}/auth/user/${userIdA}`).set({
                Authorization: adminUser.token,
            })
                .send();
            const userPromise = Realm.Sync.User.login(server.url, userNameA, passwordA);
            yield chai_1.assert.isRejected(userPromise);
        }));
        it("adminUser reads UserA's Realm without deleting UserA", () => __awaiter(this, void 0, void 0, function* () {
            const config = {
                sync: {
                    user: adminUser,
                    url: `realm://${server.address}/${userIdA}/products`
                },
                schema: [Product.ProductSchema]
            };
            const realm = yield openRealm(config);
            const products = realm.objects('Product');
            chai_1.assert.strictEqual(products.length, 1);
            realm.close();
        }));
        it("adminUser reads UserA's Realm after deleting UserA", () => __awaiter(this, void 0, void 0, function* () {
            const response = yield superagent.delete(`${server.url}/auth/user/${userIdA}`).set({
                Authorization: adminUser.token,
            })
                .send();
            const config = {
                sync: {
                    user: adminUser,
                    url: `realm://${server.address}/${userIdA}/products`
                },
                schema: [Product.ProductSchema]
            };
            const realm = yield openRealm(config);
            const products = realm.objects('Product');
            chai_1.assert.strictEqual(products.length, 0);
            realm.close();
        }));
    });
    describe.skip("Realm deletion", () => {
        let userIdA;
        let adminUser;
        beforeEach(() => __awaiter(this, void 0, void 0, function* () {
            const userNameA = uuid.v4();
            const passwordA = faker.internet.password();
            const userA = yield Realm.Sync.User.register(server.url, userNameA, passwordA);
            chai_1.assert.notStrictEqual(userIdA, userA.identity);
            userIdA = userA.identity;
            adminUser = yield Realm.Sync.User.login(server.url, "realm-admin", "");
            const realmA = yield openRealm({
                sync: {
                    user: userA,
                    url: `realm://${server.address}/~/products`
                },
                schema: [Product.ProductSchema]
            });
            realmA.write(() => {
                realmA.create('Product', {
                    productId: 0,
                    name: faker.commerce.productName(),
                    price: faker.random.number({ min: 12, max: 7000 })
                });
            });
            const uploadCompletion = new Promise((resolve, reject) => {
                realmA.syncSession.addProgressNotification('upload', 'forCurrentlyOutstandingWork', (uploaded, uploadable) => {
                    if (uploaded === uploadable) {
                        resolve();
                    }
                });
            });
            yield uploadCompletion;
            realmA.close();
        }));
        it("adminUser reads the product Realm with no Realm deletion", () => __awaiter(this, void 0, void 0, function* () {
            const config = {
                sync: {
                    user: adminUser,
                    url: `realm://${server.address}/${userIdA}/products`
                },
                schema: [Product.ProductSchema]
            };
            const realm = yield openRealm(config);
            const products = realm.objects('Product');
            chai_1.assert.strictEqual(products.length, 1);
            realm.close();
        }));
        it("adminUser reads UserA's Realm after deleting UserA", () => __awaiter(this, void 0, void 0, function* () {
            const deleteUrl = new URI(server.url).segment(['realms', 'files']).segmentCoded(`${userIdA}/products`).toString();
            const response = yield superagent.delete(deleteUrl).set({
                Authorization: adminUser.token,
            })
                .send();
            const config = {
                sync: {
                    user: adminUser,
                    url: `realm://${server.address}/${userIdA}/products`
                },
                schema: [Product.ProductSchema]
            };
            const realm = yield openRealm(config);
            const products = realm.objects('Product');
            chai_1.assert.strictEqual(products.length, 0);
            realm.close();
        }));
    });
});
//# sourceMappingURL=realmjs-integration-tests.spec.js.map