forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			371 lines
		
	
	
	
		
			9.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			371 lines
		
	
	
	
		
			9.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| const ORIGIN = "https://example.com";
 | |
| 
 | |
| async function tryPeerConnection(browser, expectedError = null) {
 | |
|   let errtype = await SpecialPowers.spawn(browser, [], async function() {
 | |
|     let pc = new content.RTCPeerConnection();
 | |
|     try {
 | |
|       await pc.createOffer({ offerToReceiveAudio: true });
 | |
|       return null;
 | |
|     } catch (err) {
 | |
|       return err.name;
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   let detail = expectedError
 | |
|     ? `createOffer() threw a ${expectedError}`
 | |
|     : "createOffer() succeeded";
 | |
|   is(errtype, expectedError, detail);
 | |
| }
 | |
| 
 | |
| // Helper for tests that use the peer-request-allowed and -blocked events.
 | |
| // A test that expects some of those events does the following:
 | |
| //  - call Events.on() before the test to setup event handlers
 | |
| //  - call Events.expect(name) after a specific event is expected to have
 | |
| //    occured.  This will fail if the event didn't occur, and will return
 | |
| //    the details passed to the handler for furhter checking.
 | |
| //  - call Events.off() at the end of the test to clean up.  At this point, if
 | |
| //    any events were triggered that the test did not expect, the test fails.
 | |
| const Events = {
 | |
|   events: ["peer-request-allowed", "peer-request-blocked"],
 | |
|   details: new Map(),
 | |
|   handlers: new Map(),
 | |
|   on() {
 | |
|     for (let event of this.events) {
 | |
|       let handler = data => {
 | |
|         if (this.details.has(event)) {
 | |
|           ok(false, `Got multiple ${event} events`);
 | |
|         }
 | |
|         this.details.set(event, data);
 | |
|       };
 | |
|       webrtcUI.on(event, handler);
 | |
|       this.handlers.set(event, handler);
 | |
|     }
 | |
|   },
 | |
|   expect(event) {
 | |
|     let result = this.details.get(event);
 | |
|     isnot(result, undefined, `${event} event was triggered`);
 | |
|     this.details.delete(event);
 | |
| 
 | |
|     // All events should have a good origin
 | |
|     is(result.origin, ORIGIN, `${event} event has correct origin`);
 | |
| 
 | |
|     return result;
 | |
|   },
 | |
|   off() {
 | |
|     for (let event of this.events) {
 | |
|       webrtcUI.off(event, this.handlers.get(event));
 | |
|       this.handlers.delete(event);
 | |
|     }
 | |
|     for (let [event] of this.details) {
 | |
|       ok(false, `Got unexpected event ${event}`);
 | |
|     }
 | |
|   },
 | |
| };
 | |
| 
 | |
| var gTests = [
 | |
|   {
 | |
|     desc: "Basic peer-request-allowed event",
 | |
|     run: async function testPeerRequestEvent(browser) {
 | |
|       Events.on();
 | |
| 
 | |
|       await tryPeerConnection(browser);
 | |
| 
 | |
|       let details = Events.expect("peer-request-allowed");
 | |
|       isnot(
 | |
|         details.callID,
 | |
|         undefined,
 | |
|         "peer-request-allowed event includes callID"
 | |
|       );
 | |
|       isnot(
 | |
|         details.windowID,
 | |
|         undefined,
 | |
|         "peer-request-allowed event includes windowID"
 | |
|       );
 | |
| 
 | |
|       Events.off();
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   {
 | |
|     desc: "Immediate peer connection blocker can allow",
 | |
|     run: async function testBlocker(browser) {
 | |
|       Events.on();
 | |
| 
 | |
|       let blockerCalled = false;
 | |
|       let blocker = params => {
 | |
|         is(
 | |
|           params.origin,
 | |
|           ORIGIN,
 | |
|           "Peer connection blocker origin parameter is correct"
 | |
|         );
 | |
|         blockerCalled = true;
 | |
|         return "allow";
 | |
|       };
 | |
| 
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker);
 | |
| 
 | |
|       await tryPeerConnection(browser);
 | |
|       is(blockerCalled, true, "Blocker was called");
 | |
|       Events.expect("peer-request-allowed");
 | |
| 
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker);
 | |
|       Events.off();
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   {
 | |
|     desc: "Deferred peer connection blocker can allow",
 | |
|     run: async function testDeferredBlocker(browser) {
 | |
|       Events.on();
 | |
| 
 | |
|       let blocker = params => Promise.resolve("allow");
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker);
 | |
| 
 | |
|       await tryPeerConnection(browser);
 | |
|       Events.expect("peer-request-allowed");
 | |
| 
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker);
 | |
|       Events.off();
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   {
 | |
|     desc: "Immediate peer connection blocker can deny",
 | |
|     run: async function testBlockerDeny(browser) {
 | |
|       Events.on();
 | |
| 
 | |
|       let blocker = params => "deny";
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker);
 | |
| 
 | |
|       await tryPeerConnection(browser, "NotAllowedError");
 | |
| 
 | |
|       Events.expect("peer-request-blocked");
 | |
| 
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker);
 | |
|       Events.off();
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   {
 | |
|     desc: "Multiple blockers work (both allow)",
 | |
|     run: async function testMultipleAllowBlockers(browser) {
 | |
|       Events.on();
 | |
| 
 | |
|       let blocker1Called = false,
 | |
|         blocker1 = params => {
 | |
|           blocker1Called = true;
 | |
|           return "allow";
 | |
|         };
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker1);
 | |
| 
 | |
|       let blocker2Called = false,
 | |
|         blocker2 = params => {
 | |
|           blocker2Called = true;
 | |
|           return "allow";
 | |
|         };
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker2);
 | |
| 
 | |
|       await tryPeerConnection(browser);
 | |
| 
 | |
|       Events.expect("peer-request-allowed");
 | |
|       ok(blocker1Called, "First blocker was called");
 | |
|       ok(blocker2Called, "Second blocker was called");
 | |
| 
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker1);
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker2);
 | |
|       Events.off();
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   {
 | |
|     desc: "Multiple blockers work (allow then deny)",
 | |
|     run: async function testAllowDenyBlockers(browser) {
 | |
|       Events.on();
 | |
| 
 | |
|       let blocker1Called = false,
 | |
|         blocker1 = params => {
 | |
|           blocker1Called = true;
 | |
|           return "allow";
 | |
|         };
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker1);
 | |
| 
 | |
|       let blocker2Called = false,
 | |
|         blocker2 = params => {
 | |
|           blocker2Called = true;
 | |
|           return "deny";
 | |
|         };
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker2);
 | |
| 
 | |
|       await tryPeerConnection(browser, "NotAllowedError");
 | |
| 
 | |
|       Events.expect("peer-request-blocked");
 | |
|       ok(blocker1Called, "First blocker was called");
 | |
|       ok(blocker2Called, "Second blocker was called");
 | |
| 
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker1);
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker2);
 | |
|       Events.off();
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   {
 | |
|     desc: "Multiple blockers work (deny first)",
 | |
|     run: async function testDenyAllowBlockers(browser) {
 | |
|       Events.on();
 | |
| 
 | |
|       let blocker1Called = false,
 | |
|         blocker1 = params => {
 | |
|           blocker1Called = true;
 | |
|           return "deny";
 | |
|         };
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker1);
 | |
| 
 | |
|       let blocker2Called = false,
 | |
|         blocker2 = params => {
 | |
|           blocker2Called = true;
 | |
|           return "allow";
 | |
|         };
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker2);
 | |
| 
 | |
|       await tryPeerConnection(browser, "NotAllowedError");
 | |
| 
 | |
|       Events.expect("peer-request-blocked");
 | |
|       ok(blocker1Called, "First blocker was called");
 | |
|       ok(
 | |
|         !blocker2Called,
 | |
|         "Peer connection blocker after a deny is not invoked"
 | |
|       );
 | |
| 
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker1);
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker2);
 | |
|       Events.off();
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   {
 | |
|     desc: "Blockers may be removed",
 | |
|     run: async function testRemoveBlocker(browser) {
 | |
|       Events.on();
 | |
| 
 | |
|       let blocker1Called = false,
 | |
|         blocker1 = params => {
 | |
|           blocker1Called = true;
 | |
|           return "allow";
 | |
|         };
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker1);
 | |
| 
 | |
|       let blocker2Called = false,
 | |
|         blocker2 = params => {
 | |
|           blocker2Called = true;
 | |
|           return "allow";
 | |
|         };
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker2);
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker1);
 | |
| 
 | |
|       await tryPeerConnection(browser);
 | |
| 
 | |
|       Events.expect("peer-request-allowed");
 | |
| 
 | |
|       ok(!blocker1Called, "Removed peer connection blocker is not invoked");
 | |
|       ok(blocker2Called, "Second peer connection blocker was invoked");
 | |
| 
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker2);
 | |
|       Events.off();
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   {
 | |
|     desc: "Blocker that throws is ignored",
 | |
|     run: async function testBlockerThrows(browser) {
 | |
|       Events.on();
 | |
|       let blocker1Called = false,
 | |
|         blocker1 = params => {
 | |
|           blocker1Called = true;
 | |
|           throw new Error("kaboom");
 | |
|         };
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker1);
 | |
| 
 | |
|       let blocker2Called = false,
 | |
|         blocker2 = params => {
 | |
|           blocker2Called = true;
 | |
|           return "allow";
 | |
|         };
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker2);
 | |
| 
 | |
|       await tryPeerConnection(browser);
 | |
| 
 | |
|       Events.expect("peer-request-allowed");
 | |
|       ok(blocker1Called, "First blocker was invoked");
 | |
|       ok(blocker2Called, "Second blocker was invoked");
 | |
| 
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker1);
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker2);
 | |
|       Events.off();
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   {
 | |
|     desc: "Cancel peer request",
 | |
|     run: async function testBlockerCancel(browser) {
 | |
|       let blocker,
 | |
|         blockerPromise = new Promise(resolve => {
 | |
|           blocker = params => {
 | |
|             resolve();
 | |
|             // defer indefinitely
 | |
|             return new Promise(innerResolve => {});
 | |
|           };
 | |
|         });
 | |
|       webrtcUI.addPeerConnectionBlocker(blocker);
 | |
| 
 | |
|       await SpecialPowers.spawn(browser, [], async function() {
 | |
|         new content.RTCPeerConnection().createOffer({
 | |
|           offerToReceiveAudio: true,
 | |
|         });
 | |
|       });
 | |
| 
 | |
|       await blockerPromise;
 | |
| 
 | |
|       let eventPromise = new Promise(resolve => {
 | |
|         webrtcUI.on("peer-request-cancel", function listener(details) {
 | |
|           resolve(details);
 | |
|           webrtcUI.off("peer-request-cancel", listener);
 | |
|         });
 | |
|       });
 | |
| 
 | |
|       await SpecialPowers.spawn(browser, [], async function() {
 | |
|         content.location.reload();
 | |
|       });
 | |
| 
 | |
|       let details = await eventPromise;
 | |
|       isnot(
 | |
|         details.callID,
 | |
|         undefined,
 | |
|         "peer-request-cancel event includes callID"
 | |
|       );
 | |
|       is(
 | |
|         details.origin,
 | |
|         ORIGIN,
 | |
|         "peer-request-cancel event has correct origin"
 | |
|       );
 | |
| 
 | |
|       webrtcUI.removePeerConnectionBlocker(blocker);
 | |
|     },
 | |
|   },
 | |
| ];
 | |
| 
 | |
| add_task(async function test() {
 | |
|   await runTests(gTests, {
 | |
|     skipObserverVerification: true,
 | |
|     cleanup() {
 | |
|       is(
 | |
|         webrtcUI.peerConnectionBlockers.size,
 | |
|         0,
 | |
|         "Peer connection blockers list is empty"
 | |
|       );
 | |
|     },
 | |
|   });
 | |
| });
 | 
