tester.test.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. import { MatchTest, resetBlacklist, testScript, testBlacklist } from '@/background/utils/tester';
  2. import cache from '@/background/utils/cache';
  3. afterEach(cache.destroy);
  4. function buildScript(props) {
  5. return Object.assign({
  6. custom: {
  7. origInclude: true,
  8. origExclude: true,
  9. origMatch: true,
  10. origExcludeMatch: true,
  11. },
  12. meta: {},
  13. }, props);
  14. }
  15. describe('scheme', () => {
  16. test('should match all', () => {
  17. {
  18. const script = buildScript({
  19. meta: {
  20. match: [
  21. '*://*/*',
  22. ],
  23. },
  24. });
  25. expect(testScript('http://www.google.com/', script)).toBeTruthy();
  26. expect(testScript('https://www.google.com/', script)).toBeTruthy();
  27. expect(testScript('file:///Users/Gerald/file', script)).toBeFalsy();
  28. }
  29. {
  30. const script = buildScript({
  31. meta: {
  32. match: [
  33. 'http*://*/*',
  34. ],
  35. },
  36. });
  37. expect(testScript('http://www.google.com/', script)).toBeTruthy();
  38. expect(testScript('https://www.google.com/', script)).toBeTruthy();
  39. expect(testScript('file:///Users/Gerald/file', script)).toBeFalsy();
  40. }
  41. });
  42. test('should match exact', () => {
  43. const script = buildScript({
  44. meta: {
  45. match: [
  46. 'http://*/*',
  47. 'ftp://*/*',
  48. 'file:///*',
  49. ],
  50. },
  51. });
  52. expect(testScript('http://www.google.com/', script)).toBeTruthy();
  53. expect(testScript('https://www.google.com/', script)).toBeFalsy();
  54. expect(testScript('file:///Users/Gerald/file', script)).toBeTruthy();
  55. expect(testScript('ftp://example.com/file', script)).toBeTruthy();
  56. });
  57. });
  58. describe('host', () => {
  59. test('should match domain', () => {
  60. const script = buildScript({
  61. meta: {
  62. match: [
  63. '*://docs.google.com/',
  64. ],
  65. },
  66. });
  67. expect(testScript('https://docs.google.com/', script)).toBeTruthy();
  68. expect(testScript('https://sub.docs.google.com/', script)).toBeFalsy();
  69. expect(testScript('https://docs.google.com.cn/', script)).toBeFalsy();
  70. });
  71. test('should match wildcard', () => {
  72. const script = buildScript({
  73. meta: {
  74. match: [
  75. '*://*.google.com/',
  76. '*://www.example.*/',
  77. ],
  78. },
  79. });
  80. [
  81. 'https://www.google.com/',
  82. 'https://a.b.google.com/',
  83. 'https://google.com/',
  84. 'https://www.example.com/',
  85. 'https://www.example.com.cn/',
  86. 'https://www.example.g.com/',
  87. ].forEach(url => {
  88. expect(testScript(url, script)).toBeTruthy();
  89. });
  90. expect(testScript('https://www.google.com.hk/', script)).toBeFalsy();
  91. });
  92. test('should match tld', () => {
  93. const script = buildScript({
  94. meta: {
  95. match: [
  96. '*://www.google.tld/',
  97. '*://www.dummy.TLD/', // testing for a mistake: `.tld` should be lowercase
  98. ],
  99. },
  100. });
  101. [
  102. 'https://www.google.com/', // should match subdomains
  103. 'https://www.google.com.cn/', // should match subdomains
  104. 'https://www.google.jp/', // should match tld
  105. 'https://www.google.no-ip.org/', // should match a hyphened `no-ip.org` from Public Suffix List
  106. ].forEach(url => {
  107. expect(testScript(url, script)).toBeTruthy();
  108. });
  109. [
  110. 'https://www.google.example.com/',
  111. 'https://www.dummy.com/', // `.tld` should be lowercase
  112. ].forEach(url => {
  113. expect(testScript(url, script)).toBeFalsy();
  114. });
  115. });
  116. test('should ignore case', () => {
  117. const script = buildScript({
  118. meta: {
  119. match: [
  120. '*://GOOGLE.com/',
  121. ],
  122. },
  123. });
  124. expect(testScript('https://google.COM/', script)).toBeTruthy();
  125. });
  126. });
  127. describe('path', () => {
  128. test('should match any', () => {
  129. const script = buildScript({
  130. meta: {
  131. match: [
  132. 'https://www.google.com/*',
  133. ],
  134. },
  135. });
  136. [
  137. 'https://www.google.com/',
  138. 'https://www.google.com/hello/world',
  139. ].forEach(url => {
  140. expect(testScript(url, script)).toBeTruthy();
  141. });
  142. });
  143. test('should match exact', () => {
  144. const script = buildScript({
  145. meta: {
  146. match: [
  147. 'https://www.google.com/a/b/c',
  148. ],
  149. },
  150. });
  151. expect(testScript('https://www.google.com/a/b/c', script)).toBeTruthy();
  152. expect(testScript('https://www.google.com/a/b/c/d', script)).toBeFalsy();
  153. });
  154. test('should ignore query string and hash', () => {
  155. const script = buildScript({
  156. meta: {
  157. match: [
  158. 'https://www.google.com/a',
  159. ],
  160. },
  161. });
  162. [
  163. 'https://www.google.com/a', // should match without query and hash
  164. 'https://www.google.com/a#hash', // should match with hash
  165. 'https://www.google.com/a?query', // should match with query
  166. 'https://www.google.com/a?query#hash', // should match with query and hash
  167. ].forEach(url => {
  168. expect(testScript(url, script)).toBeTruthy();
  169. });
  170. });
  171. test('should match query string and hash if existed in rules', () => {
  172. const script = buildScript({
  173. meta: {
  174. match: [
  175. 'https://www.google.com/a?query',
  176. 'https://www.google.com/b#hash',
  177. 'https://www.google.com/c?query#hash',
  178. ],
  179. },
  180. });
  181. [
  182. 'https://www.google.com/a?query',
  183. 'https://www.google.com/a?query#hash',
  184. 'https://www.google.com/b#hash',
  185. 'https://www.google.com/c?query#hash',
  186. ].forEach(url => {
  187. expect(testScript(url, script)).toBeTruthy();
  188. });
  189. [
  190. 'https://www.google.com/a',
  191. 'https://www.google.com/b',
  192. 'https://www.google.com/b?query#hash',
  193. ].forEach(url => {
  194. expect(testScript(url, script)).toBeFalsy();
  195. });
  196. });
  197. test('should be case-sensitive', () => {
  198. const script = buildScript({
  199. meta: {
  200. match: [
  201. 'https://www.google.com/a?Query',
  202. 'https://www.google.com/b#Hash',
  203. ],
  204. },
  205. });
  206. [
  207. 'https://www.google.com/a?Query',
  208. 'https://www.google.com/b#Hash',
  209. ].forEach(url => {
  210. expect(testScript(url, script)).toBeTruthy();
  211. });
  212. [
  213. 'https://www.google.com/a?query',
  214. 'https://www.google.com/b#hash',
  215. ].forEach(url => {
  216. expect(testScript(url, script)).toBeFalsy();
  217. });
  218. });
  219. });
  220. describe('include', () => {
  221. test('should include any', () => {
  222. const script = buildScript({
  223. meta: {
  224. include: [
  225. '*',
  226. ],
  227. },
  228. });
  229. [
  230. 'https://www.google.com/',
  231. 'file:///Users/Gerald/file'
  232. ].forEach(url => {
  233. expect(testScript(url, script)).toBeTruthy();
  234. });
  235. });
  236. test('should include by glob', () => {
  237. const script = buildScript({
  238. meta: {
  239. include: [
  240. 'https://www.google.com/*',
  241. 'https://twitter.com/*',
  242. ],
  243. },
  244. });
  245. [
  246. 'https://www.google.com/',
  247. 'https://www.google.com/hello/world',
  248. ].forEach(url => {
  249. expect(testScript(url, script)).toBeTruthy();
  250. });
  251. expect(testScript('https://www.hello.com/', script)).toBeFalsy();
  252. });
  253. test('should include by regexp', () => {
  254. const script = buildScript({
  255. meta: {
  256. include: [
  257. '/invalid-regexp(/',
  258. '/https://www\\.google\\.com/.*/',
  259. ],
  260. },
  261. });
  262. expect(testScript('https://www.google.com/', script)).toBeTruthy();
  263. expect(testScript('https://www.hello.com/', script)).toBeFalsy();
  264. });
  265. test('should support magic TLD', () => {
  266. const script = buildScript({
  267. meta: {
  268. include: [
  269. 'https://www.google.tld/*',
  270. ],
  271. },
  272. });
  273. [
  274. 'https://www.google.com/',
  275. 'https://www.google.com.hk/',
  276. 'https://www.google.no-ip.org/',
  277. ].forEach(url => {
  278. expect(testScript(url, script)).toBeTruthy();
  279. });
  280. expect(testScript('https://www.google.example.com/', script)).toBeFalsy();
  281. });
  282. test('should ignore case', () => {
  283. const script = buildScript({
  284. meta: {
  285. include: [
  286. 'https://www.google.*',
  287. '/regexp/',
  288. ],
  289. },
  290. });
  291. [
  292. 'https://www.GOOGLE.com/',
  293. 'https://www.REGEXP.com/',
  294. ].forEach(url => {
  295. expect(testScript(url, script)).toBeTruthy();
  296. });
  297. });
  298. });
  299. describe('exclude', () => {
  300. test('should exclude any', () => {
  301. const script = buildScript({
  302. meta: {
  303. match: [
  304. '*://*/*',
  305. ],
  306. exclude: [
  307. '*',
  308. ],
  309. },
  310. });
  311. expect(testScript('https://www.google.com/', script)).toBeFalsy();
  312. });
  313. test('should include by glob', () => {
  314. const script = buildScript({
  315. meta: {
  316. match: [
  317. '*://*/*',
  318. ],
  319. excludeMatch: [
  320. 'https://www.google.com/*',
  321. 'https://twitter.com/*',
  322. ],
  323. },
  324. });
  325. [
  326. 'https://www.google.com/',
  327. 'https://www.google.com/hello/world',
  328. ].forEach(url => {
  329. expect(testScript(url, script)).toBeFalsy();
  330. });
  331. expect(testScript('https://www.hello.com/', script)).toBeTruthy();
  332. });
  333. test('should support magic TLD', () => {
  334. const script = buildScript({
  335. meta: {
  336. exclude: [
  337. 'https://www.google.tld/*',
  338. ],
  339. },
  340. });
  341. [
  342. 'https://www.google.com/',
  343. 'https://www.google.com.hk/',
  344. 'https://www.google.no-ip.org/',
  345. ].forEach(url => {
  346. expect(testScript(url, script)).toBeFalsy();
  347. });
  348. expect(testScript('https://www.google.example.com/', script)).toBeTruthy();
  349. });
  350. });
  351. describe('exclude-match', () => {
  352. test('should exclude any', () => {
  353. const script = buildScript({
  354. meta: {
  355. match: [
  356. '*://*/*',
  357. ],
  358. excludeMatch: [
  359. '*://*/*',
  360. ],
  361. },
  362. });
  363. expect(testScript('https://www.google.com/', script)).toBeFalsy();
  364. });
  365. test('should include by glob', () => {
  366. const script = buildScript({
  367. meta: {
  368. match: [
  369. '*://*/*',
  370. ],
  371. excludeMatch: [
  372. 'https://www.google.com/*',
  373. 'https://twitter.com/*',
  374. ],
  375. },
  376. });
  377. [
  378. 'https://www.google.com/',
  379. 'https://www.google.com/hello/world',
  380. ].forEach(url => {
  381. expect(testScript(url, script)).toBeFalsy();
  382. });
  383. expect(testScript('https://www.hello.com/', script)).toBeTruthy();
  384. });
  385. test('should ignore case only in host', () => {
  386. const script = buildScript({
  387. meta: {
  388. match: [
  389. '*://GOOGLE.com/FOO?BAR#HASH',
  390. ],
  391. },
  392. });
  393. expect(testScript('https://google.COM/FOO?BAR#HASH', script)).toBeTruthy();
  394. expect(testScript('https://google.com/foo?bar#hash', script)).toBeFalsy();
  395. });
  396. });
  397. describe('@match error reporting', () => {
  398. test('should throw', () => {
  399. for (const [rule, err] of [
  400. ['://*/*', 'missing scheme'],
  401. ['foo://*/*', 'unknown scheme'],
  402. ['*//*/*', 'missing "://"'],
  403. ['http:/*/', 'missing "://"'],
  404. ['htp:*', 'unknown scheme, missing "://"'],
  405. ['https://foo*', 'missing "/" for path'],
  406. ]) {
  407. expect(() => MatchTest.try(rule)).toThrow(`Bad pattern: ${err} in ${rule}`);
  408. }
  409. });
  410. });
  411. describe('custom', () => {
  412. test('should ignore original rules', () => {
  413. const script = buildScript({
  414. custom: {
  415. match: [
  416. 'https://twitter.com/*',
  417. ],
  418. },
  419. meta: {
  420. match: [
  421. 'https://www.google.com/*',
  422. ],
  423. },
  424. });
  425. expect(testScript('https://twitter.com/', script)).toBeTruthy();
  426. expect(testScript('https://www.google.com/', script)).toBeFalsy();
  427. });
  428. });
  429. describe('blacklist', () => {
  430. test('should exclude match rules', () => {
  431. resetBlacklist(`\
  432. # match rules
  433. *://www.google.com/*
  434. `);
  435. [
  436. 'http://www.google.com/',
  437. 'https://www.google.com/',
  438. ].forEach(url => {
  439. expect(testBlacklist(url)).toBeTruthy();
  440. });
  441. expect(testBlacklist('https://twitter.com/')).toBeFalsy();
  442. });
  443. test('should exclude domains', () => {
  444. resetBlacklist(`\
  445. # domains
  446. www.google.com
  447. `);
  448. [
  449. 'http://www.google.com/',
  450. 'https://www.google.com/',
  451. ].forEach(url => {
  452. expect(testBlacklist(url)).toBeTruthy();
  453. });
  454. expect(testBlacklist('https://twitter.com/')).toBeFalsy();
  455. });
  456. test('should support @exclude rules', () => {
  457. resetBlacklist(`\
  458. # @exclude rules
  459. @exclude https://www.google.com/*
  460. `);
  461. [
  462. 'https://www.google.com/',
  463. 'https://www.google.com/whatever',
  464. ].forEach(url => {
  465. expect(testBlacklist(url)).toBeTruthy();
  466. });
  467. expect(testBlacklist('http://www.google.com/')).toBeFalsy();
  468. });
  469. });