Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working version with deny list #41

Merged
merged 23 commits into from
Jun 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions __tests__/e2e/blocking_requests.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//TODO work in this file is paused/block.
// More details and follow up on: https://github.com/lfilho/ddg-test-project/issues/38

/*
import browserWrapper from 'playwright-firefox';

import child_process from 'child_process';
import webExt from 'web-ext';
import pptr from 'puppeteer-core';

import { LOCAL_TEST_PAGE_URL } from '../shared/__url_fixtures.js';
*/
let page;
/*
let browser;

beforeAll(async () => {
webExt.default.util.logger.consoleStream.makeVerbose();
const runningInfo = await webExt.default.cmd
.run(
{
sourceDir: `${process.cwd()}/src`,
firefox: 'nightly'
},
{ shouldExitProgram: false }
)
.then((runner) => runner.extensionRunners[0].runningInfo);

// Needed because `webExt.cmd.run` returns before the DevTools agent starts running.
// Alternative would be to wrap the call to pptr.connect() with some custom retry logic
child_process.execSync('sleep 5');

const browserURL = `ws://127.0.0.1:${runningInfo.debuggerPort}`;

browser = await browserWrapper.firefox.connect({
wsEndpoint: browserURL,
logger: {
isEnabled: () => true,
log: (name, severity, message, args) => {
console.log(`[${severity}] ${name} ${message}. Args: ${args}`);
},
},
});
const context = await browser.newContext();
page = await context.newPage();

await page.goto(LOCAL_TEST_PAGE_URL);
});

afterAll(async () => {
await browser.close();
});
*/

describe('request to known tracker urls should be blocked', () => {
it.skip('loads the test page', async () => {
const text = await page.evaluate(() => {
return document.querySelector('[data-testid="test-page-header"]');
});
expect(text).toBeTruthy();
});

it.skip('blocks a known bad url by not loading its iframe', async () => {
//TODO waiting on resolution for: https://github.com/mozilla/web-ext/issues/1927
// More details and follow up on: https://github.com/lfilho/ddg-test-project/issues/38
});
});
45 changes: 45 additions & 0 deletions __tests__/shared/test_page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>Test page</title>
<style type="text/css">
body {
padding: 2rem;
}

#bad-page-iframe,
#good-page-iframe {
display: block;
width: 100%;
height: 13rem;
border: 0.2rem solid transparent;
}

#bad-page-iframe {
border-color: red;
}

#good-page-iframe {
border-color: green;
}
</style>
</head>

<body>
<h1 data-testid="test-page-header">🦆 Test page</h1>

<h2>Bad page iframe (should be blank):</h2>
<iframe id="bad-page-iframe"
src="https://itty.bitty.site/#bad_page/data:text/html;charset=utf-8;bxze64,XQAAAAI1AgAAAAAAAAAeGInmWR9D5qtrM4PFJv4W1okR98bzFbE2QlIWuIKxrmOKcpOUCz+bgN13tm1YwI65ckLaaMk97I0eK4ZJmz5rEyi5AYIrCihWPyWsU8imdwCjsAu9mVY4Uz3NDJSwS2tBy4fpBWIzlJM+PEIF1Dz7uHdB5dd0JkIYoHoNI51/xPcOHjaLtkdq929hapYOYARvUkxhKCAYZqoeWl/azB+/iRrItZhXoN2Xhb7cEouQ4ySG85i7cH0nZAJxZezxYYPzjYOKj1QECrYU2ufsndUGql9zsUXyBzVv3UCYzraVIpXLzEWabESPgYK1HY3biPhAiXzCU1i3msUdqKm0jl/HwqnVgJjhKaCsQvuv8pyy+VVkaz/XPVibLpmrbELCVUdG/jgKW2ig1pqjIAIoFb7YROo5+5026HlBBKlBJSJtJPiB5wAAbZMivZGwt72qmdA5R4jjQVr+djo2"
frameborder="0"></iframe>

<h2>Good page iframe (should not be blank):</h2>
<iframe id="good-page-iframe"
src="https://itty.bitty.site/#good_page/data:text/html;charset=utf-8;bxze64,XQAAAALrAQAAAAAAAAAeGInmWR9D5qtrM4PFJv4W1okR98bzFbE2QlIiIqEKRNhWozLGaVxy2UBVi6vb5PjLiS+KmhnoBI2zbVEi38FFqGt0V2dZ/n48NtEOjSTkOFXBuNLAKC6rlcwmvnHnUnMAWA2l/QImsEbNvvf1bv40vbtBzNp9F3TGp/HpcdlmwUSp59tjbjdUlRkOVnMxBaTPI6tnqjg9UBREwBH6Y4c6xLg53hJodPJyK8AysLdOEqC5OPFdGrHq7n6ViwKq90juHDM+UhFD8ug4iSu0Yo74yBMAo7Rtj+Jd5h9AkkjDCs/m4RMIP7KQKT4AldOuVvxaNDd4LcfbH/7lFxzMpv2FPyYxeR5ZmDMwE6422v7jh2OnV4nTcu42kWkhVBP7U06PxG1bBjmd5+5p11z/jK399tAktg=="
frameborder="0"></iframe>
</body>

</html>
7 changes: 7 additions & 0 deletions __tests__/src/lib/__request_fixtures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { A_URL } from '../../../src/shared/__url_fixtures.js';

export const RANDOM_REQUEST_DETAILS = { url: A_URL };
export const BLOCKING_RESPONSE = {
CANCELLED: { cancel: true },
NOT_CANCELLED: { cancel: false },
};
62 changes: 62 additions & 0 deletions __tests__/src/lib/list.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import List from '../../../src/lib/model/list.js';
import {
A_URL,
ANOTHER_URL,
SOME_URLS,
} from '../../../src/shared/__url_fixtures.js';

let list;

beforeEach(() => {
const RANDOM_TYPE = List.types.DENY_LIST;
list = new List(RANDOM_TYPE);
});

describe('List', () => {
it('should add an url to the list', () => {
const originalListSize = list.size;
list.add(A_URL);
expect(list.size).toBe(originalListSize + 1);
});

it('should not add duplicate urls to the list', () => {
const originalListSize = list.size;
list.add(A_URL);
list.add(A_URL);
expect(list.size).toBe(originalListSize + 1);
});

it('should remove an url from the list', () => {
const originalListSize = list.size;
list.add(A_URL);
list.remove(A_URL);
expect(list.size).toBe(originalListSize);
});

it('should tell if an url is on the list', () => {
list.add(A_URL);
expect(list.has(A_URL)).toBe(true);
expect(list.has(ANOTHER_URL)).toBe(false);
});

it('should clear the list', () => {
list.add(A_URL);
list.add(ANOTHER_URL);
list.clear();
expect(list.size).toBe(0);
});

it('should return the size of the list', () => {
expect(list.size).toBe(0);
list.add(A_URL);
expect(list.size).toBe(1);
list.add(ANOTHER_URL);
expect(list.size).toBe(2);
});

it('should add several urls at once', () => {
expect(list.size).toBe(0);
list.bulkAdd(SOME_URLS);
expect(list.size).toBe(SOME_URLS.length);
});
});
25 changes: 25 additions & 0 deletions __tests__/src/lib/request_listener.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { jest } from '@jest/globals';

import requestListener from '../../../src/lib/request_listener.js';
import RequestMatcher from '../../../src/lib/request_matcher.js';

import {
RANDOM_REQUEST_DETAILS,
BLOCKING_RESPONSE,
} from './__request_fixtures.js';

jest.mock('../../../src/lib/request_matcher.js');

describe('Request Listener', () => {
it('should return a BlockingResponse with cancel: true for a tracker url', () => {
RequestMatcher.isDenied = jest.fn().mockReturnValue(true);
const result = requestListener(RANDOM_REQUEST_DETAILS);
expect(result).toEqual(BLOCKING_RESPONSE.CANCELLED);
});

it('should return a BlockingResponse with cancel: false for a non-tracker url', () => {
RequestMatcher.isDenied = jest.fn().mockReturnValue(false);
const result = requestListener(RANDOM_REQUEST_DETAILS);
expect(result).toEqual(BLOCKING_RESPONSE.NOT_CANCELLED);
});
});
17 changes: 17 additions & 0 deletions __tests__/src/lib/request_matcher.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import RequestMatcher from '../../../src/lib/request_matcher.js';
import { BAD_URL, GOOD_URL } from '../../../src/shared/__url_fixtures.js';

beforeAll(() => RequestMatcher.denyList.add(BAD_URL));
afterAll(() => RequestMatcher.denyList.clear());

describe('Request Matcher', () => {
it('should deny urls in the deny list', () => {
const result = RequestMatcher.isDenied(BAD_URL);
expect(result).toBe(true);
});

it('should not deny urls if they are not in the deny list', () => {
const result = RequestMatcher.isDenied(GOOD_URL);
expect(result).toBe(false);
});
});
2 changes: 2 additions & 0 deletions bin/change-ext-version.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/usr/bin/env node

import fs from 'fs';

const MANITFEST_FILE = 'src/manifest.json';
Expand Down
8 changes: 8 additions & 0 deletions docs/development/TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Testing

//TODO the below are just reminders for now

- Add explanation about test "trophy" and why i didn't unit test everything (e.g.: request_blocker --> little value added)
https://twitter.com/kentcdodds/status/960723172591992832
- Add explanation about unit testing the List being overkill -- just antecipating a change in DS in the future (and it was pretty trivial)
- Add explanation on playwright/puppeteer + web-ext problem: https://github.com/lfilho/ddg-test-project/issues/38
15 changes: 9 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
},
"homepage": "https://github.com/lfilho/ddg-test-project#readme",
"scripts": {
"develop": "npm run web-ext -- run",
"develop": "npm run web-ext -- run --bc --url $(pwd)/__tests__/shared/test_page.html",
"format": "prettier --write \"**/*.{js,json,css,md}\"",
"//eslint is configured with prettier, so it will check and fix js formatting too": "",
"lint": "npm run lint:js && npm run lint:ext",
Expand All @@ -25,18 +25,19 @@
"lint:js:fix": "npm run lint:js -- --fix",
"pretest": "npm run lint",
"start": "npm run develop",
"test": "NODE_ENV=test jest",
"test": "NODE_ENV=test node --experimental-vm-modules node_modules/jest/bin/jest.js",
"test:watch": "npm test -- --watch",
"web-ext": "web-ext",
"//Release related scripts:": "",
"release": "semantic-release",
"build": "npm run web-ext -- build",
"get-version": "echo $npm_package_version",
"change-ext-version": "node bin/change-ext-version.js"
"change-ext-version": "bin/change-ext-version.js"
},
"devDependencies": {
"@commitlint/cli": "8.3.5",
"@commitlint/config-conventional": "8.3.4",
"@jest/globals": "26.0.1",
"@semantic-release/commit-analyzer": "8.0.1",
"@semantic-release/exec": "5.0.0",
"@semantic-release/github": "7.0.7",
Expand All @@ -59,15 +60,16 @@
"jest": {
"displayName": "test",
"testRegex": "\\.spec\\.js$",
"testEnvironment": "jsdom",
"testEnvironment": "jest-environment-node",
"testURL": "http://localhost",
"watchPlugins": [
"jest-watch-typeahead/filename",
"jest-watch-typeahead/testname"
],
"coveragePathIgnorePatterns": [
"/node_modules/"
]
],
"transform": {}
},
"husky": {
"hooks": {
Expand Down Expand Up @@ -145,5 +147,6 @@
"webExt": {
"sourceDir": "src",
"artifactsDir": "dist"
}
},
"dependencies": {}
}
10 changes: 10 additions & 0 deletions src/background_script.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
</head>
<body>
<script type="module" src="./background_script.js"></script>
</body>
</html>
5 changes: 4 additions & 1 deletion src/background_script.js
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
console.log('This is coming from background script!');
import RequestBlocker from './lib/request_blocker.js';

console.log('Extension is ready to start blocking!');
RequestBlocker.startMonitoring();
2 changes: 1 addition & 1 deletion src/browserAction/script.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
window.alert('This is coming from the extension button!');
console.info('This is coming from the extension button!');
2 changes: 1 addition & 1 deletion src/content_script.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
window.alert('This is comming from content script!');
console.info('This is comming from content script!');
20 changes: 20 additions & 0 deletions src/lib/list_populator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import List from './model/list.js';
import { BAD_URLS } from '../shared/__url_fixtures.js';

// TODO for now, just populating it with the examples from fixtures
// TODO real deal: fetch from local files shipped with the extension, augment it with live sources...
// https://github.com/lfilho/ddg-test-project/issues/24
// https://github.com/lfilho/ddg-test-project/issues/18
// https://github.com/lfilho/ddg-test-project/issues/17

export default class ListPopulator {
static async populateList(list) {
const listTypeToUrlMapper = {
[List.types.DENY_LIST]: BAD_URLS,
};
const urls = listTypeToUrlMapper[list.type];
list.bulkAdd(urls);

//TODO https://github.com/lfilho/ddg-test-project/issues/8
}
}
7 changes: 7 additions & 0 deletions src/lib/model/deny_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import List from './list.js';

export default class DenyList extends List {
constructor() {
super(List.types.DENY_LIST);
}
}
Loading