chore: clean up context bridge scopes and add specs for internal bridge (#23334)

* chore: clean up context bridge context scopes

* spec: add specs for internalContextBridge
This commit is contained in:
Samuel Attard 2020-05-11 13:41:42 -07:00 committed by GitHub
parent cf635c5fac
commit 7f9b7b2e95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 269 additions and 121 deletions

View file

@ -341,7 +341,7 @@ describe('contextBridge', () => {
if (!useSandbox) {
it('should release the global hold on methods sent across contexts', async () => {
await makeBindingWindow(() => {
require('electron').ipcRenderer.on('get-gc-info', e => e.sender.send('gc-info', (contextBridge as any).debugGC()));
require('electron').ipcRenderer.on('get-gc-info', e => e.sender.send('gc-info', contextBridge.debugGC()));
contextBridge.exposeInMainWorld('example', {
getFunction: () => () => 123
});
@ -365,7 +365,7 @@ describe('contextBridge', () => {
if (useSandbox) {
it('should not leak the global hold on methods sent across contexts when reloading a sandboxed renderer', async () => {
await makeBindingWindow(() => {
require('electron').ipcRenderer.on('get-gc-info', e => e.sender.send('gc-info', (contextBridge as any).debugGC()));
require('electron').ipcRenderer.on('get-gc-info', e => e.sender.send('gc-info', contextBridge.debugGC()));
contextBridge.exposeInMainWorld('example', {
getFunction: () => () => 123
});
@ -553,6 +553,148 @@ describe('contextBridge', () => {
// Every protomatch should be true
expect(result.protoMatches).to.deep.equal(result.protoMatches.map(() => true));
});
describe('internalContextBridge', () => {
describe('overrideGlobalValueFromIsolatedWorld', () => {
it('should override top level properties', async () => {
await makeBindingWindow(() => {
contextBridge.internalContextBridge.overrideGlobalValueFromIsolatedWorld(['open'], () => ({ you: 'are a wizard' }));
});
const result = await callWithBindings(async (root: any) => {
return root.open();
});
expect(result).to.deep.equal({ you: 'are a wizard' });
});
it('should override deep properties', async () => {
await makeBindingWindow(() => {
contextBridge.internalContextBridge.overrideGlobalValueFromIsolatedWorld(['document', 'foo'], () => 'I am foo');
});
const result = await callWithBindings(async (root: any) => {
return root.document.foo();
});
expect(result).to.equal('I am foo');
});
});
describe('overrideGlobalPropertyFromIsolatedWorld', () => {
it('should call the getter correctly', async () => {
await makeBindingWindow(() => {
let callCount = 0;
const getter = () => {
callCount++;
return true;
};
contextBridge.internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['isFun'], getter);
contextBridge.exposeInMainWorld('foo', {
callCount: () => callCount
});
});
const result = await callWithBindings(async (root: any) => {
return [root.isFun, root.foo.callCount()];
});
expect(result[0]).to.equal(true);
expect(result[1]).to.equal(1);
});
it('should not make a setter if none is provided', async () => {
await makeBindingWindow(() => {
contextBridge.internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['isFun'], () => true);
});
const result = await callWithBindings(async (root: any) => {
root.isFun = 123;
return root.isFun;
});
expect(result).to.equal(true);
});
it('should call the setter correctly', async () => {
await makeBindingWindow(() => {
const callArgs: any[] = [];
const setter = (...args: any[]) => {
callArgs.push(args);
return true;
};
contextBridge.internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['isFun'], () => true, setter);
contextBridge.exposeInMainWorld('foo', {
callArgs: () => callArgs
});
});
const result = await callWithBindings(async (root: any) => {
root.isFun = 123;
return root.foo.callArgs();
});
expect(result).to.have.lengthOf(1);
expect(result[0]).to.have.lengthOf(1);
expect(result[0][0]).to.equal(123);
});
});
describe('overrideGlobalValueWithDynamicPropsFromIsolatedWorld', () => {
it('should not affect normal values', async () => {
await makeBindingWindow(() => {
contextBridge.internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['thing'], {
a: 123,
b: () => 2,
c: () => ({ d: 3 })
});
});
const result = await callWithBindings(async (root: any) => {
return [root.thing.a, root.thing.b(), root.thing.c()];
});
expect(result).to.deep.equal([123, 2, { d: 3 }]);
});
it('should work with getters', async () => {
await makeBindingWindow(() => {
contextBridge.internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['thing'], {
get foo () {
return 'hi there';
}
});
});
const result = await callWithBindings(async (root: any) => {
return root.thing.foo;
});
expect(result).to.equal('hi there');
});
it('should work with setters', async () => {
await makeBindingWindow(() => {
let a: any = null;
contextBridge.internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['thing'], {
get foo () {
return a;
},
set foo (arg: any) {
a = arg + 1;
}
});
});
const result = await callWithBindings(async (root: any) => {
root.thing.foo = 123;
return root.thing.foo;
});
expect(result).to.equal(124);
});
it('should work with deep properties', async () => {
await makeBindingWindow(() => {
contextBridge.internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['thing'], {
a: () => ({
get foo () {
return 'still here';
}
})
});
});
const result = await callWithBindings(async (root: any) => {
return root.thing.a().foo;
});
expect(result).to.equal('still here');
});
});
});
});
};