From de1cec8693e1d9572cce8459ef4beb8fbdf0a3ef Mon Sep 17 00:00:00 2001 From: Jeremy Rose Date: Wed, 27 Jul 2022 09:18:33 -0700 Subject: [PATCH] test: migrate shell specs to main process (#35058) --- shell/common/api/electron_api_shell.cc | 8 +++ spec-main/api-shell-spec.ts | 72 ++++++++++++++++++++- spec/api-shell-spec.js | 87 -------------------------- 3 files changed, 79 insertions(+), 88 deletions(-) delete mode 100644 spec/api-shell-spec.js diff --git a/shell/common/api/electron_api_shell.cc b/shell/common/api/electron_api_shell.cc index 20fd7929ee5..e279f3a73fe 100644 --- a/shell/common/api/electron_api_shell.cc +++ b/shell/common/api/electron_api_shell.cc @@ -15,6 +15,7 @@ #include "shell/common/platform_util.h" #if BUILDFLAG(IS_WIN) +#include "base/threading/thread_restrictions.h" #include "base/win/scoped_com_initializer.h" #include "base/win/shortcut.h" @@ -105,6 +106,11 @@ v8::Local TrashItem(v8::Isolate* isolate, } #if BUILDFLAG(IS_WIN) +// The use of the ForTesting flavors is a hack workaround to avoid having to +// patch these as friends into the associated guard classes. +class ShortcutAccessScopedAllowBlocking + : public base::ScopedAllowBlockingForTesting {}; + bool WriteShortcutLink(const base::FilePath& shortcut_path, gin_helper::Arguments* args) { base::win::ShortcutOperation operation = @@ -136,6 +142,7 @@ bool WriteShortcutLink(const base::FilePath& shortcut_path, if (options.Get("toastActivatorClsid", &toastActivatorClsid)) properties.set_toast_activator_clsid(toastActivatorClsid); + ShortcutAccessScopedAllowBlocking allow_blocking; base::win::ScopedCOMInitializer com_initializer; return base::win::CreateOrUpdateShortcutLink(shortcut_path, properties, operation); @@ -145,6 +152,7 @@ v8::Local ReadShortcutLink(gin_helper::ErrorThrower thrower, const base::FilePath& path) { using base::win::ShortcutProperties; gin::Dictionary options = gin::Dictionary::CreateEmpty(thrower.isolate()); + ShortcutAccessScopedAllowBlocking allow_blocking; base::win::ScopedCOMInitializer com_initializer; base::win::ShortcutProperties properties; if (!base::win::ResolveShortcutProperties( diff --git a/spec-main/api-shell-spec.ts b/spec-main/api-shell-spec.ts index 33bc29791fa..f2cd1cdf8f7 100644 --- a/spec-main/api-shell-spec.ts +++ b/spec-main/api-shell-spec.ts @@ -2,9 +2,10 @@ import { BrowserWindow, app } from 'electron/main'; import { shell } from 'electron/common'; import { closeAllWindows } from './window-helpers'; import { emittedOnce } from './events-helpers'; -import { ifit } from './spec-helpers'; +import { ifdescribe, ifit } from './spec-helpers'; import * as http from 'http'; import * as fs from 'fs-extra'; +import * as os from 'os'; import * as path from 'path'; import { AddressInfo } from 'net'; import { expect } from 'chai'; @@ -84,4 +85,73 @@ describe('shell module', () => { await expect(w.webContents.executeJavaScript('require(\'electron\').shell.trashItem(\'does-not-exist\')')).to.be.rejectedWith(/does-not-exist|Failed to move item|Failed to create FileOperation/); }); }); + + const shortcutOptions = { + target: 'C:\\target', + description: 'description', + cwd: 'cwd', + args: 'args', + appUserModelId: 'appUserModelId', + icon: 'icon', + iconIndex: 1, + toastActivatorClsid: '{0E3CFA27-6FEA-410B-824F-A174B6E865E5}' + }; + ifdescribe(process.platform === 'win32')('shell.readShortcutLink(shortcutPath)', () => { + it('throws when failed', () => { + expect(() => { + shell.readShortcutLink('not-exist'); + }).to.throw('Failed to read shortcut link'); + }); + + const fixtures = path.resolve(__dirname, '..', 'spec', 'fixtures'); + it('reads all properties of a shortcut', () => { + const shortcut = shell.readShortcutLink(path.join(fixtures, 'assets', 'shortcut.lnk')); + expect(shortcut).to.deep.equal(shortcutOptions); + }); + }); + + ifdescribe(process.platform === 'win32')('shell.writeShortcutLink(shortcutPath[, operation], options)', () => { + const tmpShortcut = path.join(os.tmpdir(), `${Date.now()}.lnk`); + + afterEach(() => { + fs.unlinkSync(tmpShortcut); + }); + + it('writes the shortcut', () => { + expect(shell.writeShortcutLink(tmpShortcut, { target: 'C:\\' })).to.be.true(); + expect(fs.existsSync(tmpShortcut)).to.be.true(); + }); + + it('correctly sets the fields', () => { + expect(shell.writeShortcutLink(tmpShortcut, shortcutOptions)).to.be.true(); + expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(shortcutOptions); + }); + + it('updates the shortcut', () => { + expect(shell.writeShortcutLink(tmpShortcut, 'update', shortcutOptions)).to.be.false(); + expect(shell.writeShortcutLink(tmpShortcut, 'create', shortcutOptions)).to.be.true(); + expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(shortcutOptions); + const change = { target: 'D:\\' }; + expect(shell.writeShortcutLink(tmpShortcut, 'update', change)).to.be.true(); + expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal({ ...shortcutOptions, ...change }); + }); + + it('replaces the shortcut', () => { + expect(shell.writeShortcutLink(tmpShortcut, 'replace', shortcutOptions)).to.be.false(); + expect(shell.writeShortcutLink(tmpShortcut, 'create', shortcutOptions)).to.be.true(); + expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(shortcutOptions); + const change = { + target: 'D:\\', + description: 'description2', + cwd: 'cwd2', + args: 'args2', + appUserModelId: 'appUserModelId2', + icon: 'icon2', + iconIndex: 2, + toastActivatorClsid: '{C51A3996-CAD9-4934-848B-16285D4A1496}' + }; + expect(shell.writeShortcutLink(tmpShortcut, 'replace', change)).to.be.true(); + expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(change); + }); + }); }); diff --git a/spec/api-shell-spec.js b/spec/api-shell-spec.js deleted file mode 100644 index 6eacf513639..00000000000 --- a/spec/api-shell-spec.js +++ /dev/null @@ -1,87 +0,0 @@ -const { expect } = require('chai'); - -const fs = require('fs'); -const path = require('path'); -const os = require('os'); -const http = require('http'); -const { shell } = require('electron'); - -describe('shell module', () => { - const fixtures = path.resolve(__dirname, 'fixtures'); - const shortcutOptions = { - target: 'C:\\target', - description: 'description', - cwd: 'cwd', - args: 'args', - appUserModelId: 'appUserModelId', - icon: 'icon', - iconIndex: 1, - toastActivatorClsid: '{0E3CFA27-6FEA-410B-824F-A174B6E865E5}' - }; - - describe('shell.readShortcutLink(shortcutPath)', () => { - beforeEach(function () { - if (process.platform !== 'win32') this.skip(); - }); - - it('throws when failed', () => { - expect(() => { - shell.readShortcutLink('not-exist'); - }).to.throw('Failed to read shortcut link'); - }); - - it('reads all properties of a shortcut', () => { - const shortcut = shell.readShortcutLink(path.join(fixtures, 'assets', 'shortcut.lnk')); - expect(shortcut).to.deep.equal(shortcutOptions); - }); - }); - - describe('shell.writeShortcutLink(shortcutPath[, operation], options)', () => { - beforeEach(function () { - if (process.platform !== 'win32') this.skip(); - }); - - const tmpShortcut = path.join(os.tmpdir(), `${Date.now()}.lnk`); - - afterEach(() => { - fs.unlinkSync(tmpShortcut); - }); - - it('writes the shortcut', () => { - expect(shell.writeShortcutLink(tmpShortcut, { target: 'C:\\' })).to.be.true(); - expect(fs.existsSync(tmpShortcut)).to.be.true(); - }); - - it('correctly sets the fields', () => { - expect(shell.writeShortcutLink(tmpShortcut, shortcutOptions)).to.be.true(); - expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(shortcutOptions); - }); - - it('updates the shortcut', () => { - expect(shell.writeShortcutLink(tmpShortcut, 'update', shortcutOptions)).to.be.false(); - expect(shell.writeShortcutLink(tmpShortcut, 'create', shortcutOptions)).to.be.true(); - expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(shortcutOptions); - const change = { target: 'D:\\' }; - expect(shell.writeShortcutLink(tmpShortcut, 'update', change)).to.be.true(); - expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal({ ...shortcutOptions, ...change }); - }); - - it('replaces the shortcut', () => { - expect(shell.writeShortcutLink(tmpShortcut, 'replace', shortcutOptions)).to.be.false(); - expect(shell.writeShortcutLink(tmpShortcut, 'create', shortcutOptions)).to.be.true(); - expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(shortcutOptions); - const change = { - target: 'D:\\', - description: 'description2', - cwd: 'cwd2', - args: 'args2', - appUserModelId: 'appUserModelId2', - icon: 'icon2', - iconIndex: 2, - toastActivatorClsid: '{C51A3996-CAD9-4934-848B-16285D4A1496}' - }; - expect(shell.writeShortcutLink(tmpShortcut, 'replace', change)).to.be.true(); - expect(shell.readShortcutLink(tmpShortcut)).to.deep.equal(change); - }); - }); -});