Skip to content

Commit

Permalink
fix: always blacklist the regex that was watched, if possible
Browse files Browse the repository at this point in the history
  • Loading branch information
double-beep authored Sep 13, 2024
1 parent f028748 commit eccfdb7
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 63 deletions.
4 changes: 2 additions & 2 deletions src/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ function updateKeywordLists(
try {
const newRegex = new RegExp(regex, 'is');

const compare = (regex: RegExp): boolean =>
regex.source !== newRegex.source && regex.source !== `\\b${newRegex.source}\\b`;
const compare = (regexp: RegExp): boolean =>
regexp.source !== newRegex.source && regexp.source !== `\\b${newRegex.source}\\b`;

switch (action) {
case 'watch': {
Expand Down
33 changes: 23 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,17 @@ export const helpers = {
&& Number(seHits) < 5; // not explicitly mentioned, but thought it's a good limit
},

// given a regexes array and a domain, find if the latter is matched by any items in the former
isCaught: (type: 'watch' | 'blacklist', domain: string): boolean => {
// find if given string exists in the watchlist/blacklist
// returns the last regex from that list which matches that string
isCaught: (type: 'watch' | 'blacklist', domain: string): RegExp | undefined => {
const regexes = Domains[`${type}ed`];

return regexes.some(regex => regex.test(domain));
return regexes.findLast(regex => regex.test(domain));
},

isWatched: (domain: string): boolean => helpers.isCaught('watch', domain),
isWatched: (domain: string): RegExp | undefined => helpers.isCaught('watch', domain),

isBlacklisted: (domain: string): boolean => helpers.isCaught('blacklist', domain),
isBlacklisted: (domain: string): boolean => Boolean(helpers.isCaught('blacklist', domain)),

// get the id the domain li has - dots are replaced with dash
getDomainId: (domainName: string): string => `fire-extra-${domainName.replace(/\./g, '-')}`,
Expand All @@ -131,7 +132,13 @@ export const helpers = {
},

// the tooltip text of !!/watch, !!/blacklist buttons
getButtonsText: (action: 'watch' | 'blacklist', term: string, done: boolean, domain?: string): string => {
getButtonsText: (
action: 'watch' | 'blacklist',
term: string,
done: boolean,
domain?: string,
regex?: RegExp
): string => {
const command = action === 'watch' ? '!!/watch-' : '!!/blacklist-website-';
const alreadyDone = 'action already taken';

Expand All @@ -142,9 +149,15 @@ export const helpers = {
.replace(/blogspot\.\w+(\.\w+)?$/, 'blogspot') // abc.blogspot.com => abc.blogspot
.replace(/\./g, '\\.'); // escape dots

const replacement = regex?.source.slice(2, -2)
// fire-tooltip content is parsed as HTML
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;');

return done
? alreadyDone
: `${command} ${watchValue}`;
: `${command} ${action === 'blacklist' && regex ? replacement : watchValue}`;
},

// (?-i:) - case sensitive
Expand Down Expand Up @@ -183,14 +196,14 @@ function updateEmojisInformation(term: string): void {
const qualifiesForBlacklist = helpers.qualifiesForBlacklist(metasmokeStats, seResultCount);

const watch = {
human: helpers.getActionDone('watched', isWatched),
tooltip: helpers.getButtonsText('watch', term, isWatched || isBlacklisted, domainName),
human: helpers.getActionDone('watched', Boolean(isWatched)),
tooltip: helpers.getButtonsText('watch', term, Boolean(isWatched) || isBlacklisted, domainName),
suggested: qualifiesForWatch && !isWatched && !isBlacklisted,
};

const blacklist = {
human: helpers.getActionDone('blacklisted', isBlacklisted),
tooltip: helpers.getButtonsText('blacklist', term, isBlacklisted, domainName),
tooltip: helpers.getButtonsText('blacklist', term, isBlacklisted, domainName, isWatched),
suggested: qualifiesForBlacklist && !isBlacklisted,
};

Expand Down
16 changes: 9 additions & 7 deletions test/chat.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ function getRandomMessage(
): string {
// linuxbuz\\.com is the (escaped domain) that's watched in the original message
return original
.replace("Auto watch", `Auto ${action}`)
.replace("linuxbuz\\.com", escapedDomain);
.replace('Auto watch', `Auto ${action}`)
.replace('linuxbuz\\.com', escapedDomain);
}

async function getMessage(id: number): Promise<string> {
Expand All @@ -36,7 +36,7 @@ describe('chat helpers', function() {

const messages = [
'watch random-domain\\.com',
'blacklist random-random-domain\\.com',
'blacklist random-random-domain\\.com',
'unwatch random-domain\\.com',
'unblacklist tenderpublish',
'watch domain\\.with\\.a\\.few\\.dots\\.com',
Expand All @@ -49,7 +49,7 @@ describe('chat helpers', function() {
const actionType = messageSplit[0] as ChatMessageActions;
const domain = messageSplit[1];

const fullMessage = getRandomMessage(chatMessage, actionType, domain)
const fullMessage = getRandomMessage(chatMessage, actionType, domain);

return new JSDOM(fullMessage).window.document;
})
Expand All @@ -64,7 +64,8 @@ describe('chat helpers', function() {
);
});

const { isWatched, isBlacklisted } = helpers;
const isWatched = (domain: string): boolean => Boolean(helpers.isWatched(domain));
const { isBlacklisted } = helpers;

// random-domain.com was first watched, then unwatched and shouldn't be in the watchlist
expect(isWatched('random-domain.com')).to.be.false;
Expand Down Expand Up @@ -104,7 +105,8 @@ describe('chat helpers', function() {
}
];

const { isWatched, isBlacklisted } = helpers;
const isWatched = (domain: string): boolean => Boolean(helpers.isWatched(domain));
const { isBlacklisted } = helpers;

// Merge pull request #12085
expect(isBlacklisted('spam.com')).to.be.false;
Expand All @@ -127,4 +129,4 @@ describe('chat helpers', function() {
expect(Domains.pullRequests.find(pr => pr.id === 12085)).to.be.undefined;
expect(Domains.pullRequests.find(pr => pr.id === 12080)).to.be.undefined;
});
});
});
4 changes: 2 additions & 2 deletions test/dom_utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('DOM utils', () => {
// MS part
expect(msPart.children[0].textContent).to.be.equal('MS');
expect(msPart.children[1].classList.contains('fire-extra-ms-stats')).to.be.true;
expect(msPart.children[1].children[0]?.classList.contains('fire-extra-wait')).to.be.true;
expect(msPart.children[1].children[0].classList.contains('fire-extra-wait')).to.be.true;

// SE part
expect(sePart.classList.contains('fire-extra-se-results'));
Expand Down Expand Up @@ -93,6 +93,6 @@ describe('DOM utils', () => {

expect(hitCountAnchor.innerHTML).to.be.equal('SE search');
// expect(hitCountAnchor.innerHTML).to.be.equal('SE: 10.5k');
//expect(hitCountAnchor.getAttribute('fire-tooltip')).to.be.equal('10.5k hits on SE');
// expect(hitCountAnchor.getAttribute('fire-tooltip')).to.be.equal('10.5k hits on SE');
});
});
2 changes: 1 addition & 1 deletion test/domain_stats.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,4 @@ describe('whitelisted domains and URL shorteners', () => {
expect(isWhitelisted).to.be.false;
});
});
});
});
12 changes: 5 additions & 7 deletions test/github.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,22 @@ import {
getUpdatedPrInfo,
parseApiResponse
} from '../src/github';
import jsdom from "jsdom";
import jsdom from 'jsdom';
import { Domains } from '../src/domain_stats';

const { JSDOM } = jsdom;

global.document = new JSDOM().window.document;

const watchSample = String.raw
`1494929269 tripleee thewellnesscorner\.com
const watchSample = String.raw`1494929269 tripleee thewellnesscorner\.com
1494929399 tripleee optisolbusiness\.com
1494997469 tripleee careinfo\.in
1494997580 tripleee carebaba\.com
1494999587 tripleee punjabimp3club\.com
1495002561 tripleee erozon
1495005325 tripleee onlinesupplementworld\.com
1495006487 tripleee ahealthadvisory\.com`;
const blacklistedSample = String.raw
`resolit\.us
const blacklistedSample = String.raw`resolit\.us
techinpost\.com
hackerscontent\.com
hrsoftwaresolution\.com
Expand Down Expand Up @@ -139,7 +137,7 @@ describe('github helpers', () => {
validChatMessages.forEach(async message => {
const content = new JSDOM(message).window.document;

const text = content.body?.innerHTML || '';
const text = content.body.innerHTML || '';
const functionReturnValue = await getUpdatedPrInfo(text);

expect(functionReturnValue).not.to.be.undefined;
Expand All @@ -148,4 +146,4 @@ describe('github helpers', () => {
const irrelevantMessage = 'This is an unrelated message about a pull request';
expect(await getUpdatedPrInfo(irrelevantMessage)).to.be.undefined;
});
});
});
71 changes: 47 additions & 24 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ describe('index helpers', () => {
before(async () => await Domains.fetchAllDomainInformation());

it('should find if a domain with specific stats qualifies for watch', () => {
expect(helpers.qualifiesForWatch([1, 0, 0], '0')).to.be.true;
expect(helpers.qualifiesForWatch([5, 0, 0], '10')).to.be.false;
expect(helpers.qualifiesForWatch([1, 0, 1], '2')).to.be.false;
const { qualifiesForWatch: shouldWatch } = helpers;

expect(shouldWatch([1, 0, 0], '0')).to.be.true;
expect(shouldWatch([5, 0, 0], '10')).to.be.false;
expect(shouldWatch([1, 0, 1], '2')).to.be.false;
});

it('should find if a domain with specific stats qualifies for blacklist', () => {
expect(helpers.qualifiesForBlacklist([5, 0, 0], '4')).to.be.true;
expect(helpers.qualifiesForBlacklist([10, 0, 0], '5')).to.be.false;
expect(helpers.qualifiesForBlacklist([10, 2, 0], '4')).to.be.false;
const { qualifiesForBlacklist: shouldBlacklist } = helpers;

expect(shouldBlacklist([5, 0, 0], '4')).to.be.true;
expect(shouldBlacklist([10, 0, 0], '5')).to.be.false;
expect(shouldBlacklist([10, 2, 0], '4')).to.be.false;
});

it('should get the correct li id given a domain', () => {
Expand Down Expand Up @@ -66,10 +70,11 @@ describe('index helpers', () => {
const body = url.searchParams.get('body');

expect(body).to.be.equal(`(?i)speakatoo\\.com`);
});
}).timeout(5000);

it('should figure out if a domain is caught or not', () => {
const { isWatched, isBlacklisted } = helpers;
const isWatched = (domain: string): boolean => Boolean(helpers.isWatched(domain));
const { isBlacklisted } = helpers;

const validWatches = ['essayssos.com', 'trimfire', 'erozon', 'saleleads.net', 'SaleLeads.net'];
const invalidWatches = ['non-existent-keyword', 'google.com'];
Expand Down Expand Up @@ -107,47 +112,65 @@ describe('index helpers', () => {
});

it('should correctly pluralise words', () => {
expect(helpers.pluralise('hit', 1)).to.be.equal('hit');
expect(helpers.pluralise('hit', 0)).to.be.equal('hits');
expect(helpers.pluralise('hit', 100)).to.be.equal('hits');
const { pluralise } = helpers;

expect(pluralise('hit', 1)).to.be.equal('hit');
expect(pluralise('hit', 0)).to.be.equal('hits');
expect(pluralise('hit', 100)).to.be.equal('hits');
});

it('should correctly fetch accurate tooltip texts for the emojis', () => {
expect(helpers.getActionDone('watched', true)).to.be.equal('watched: yes');
expect(helpers.getActionDone('watched', false)).to.be.equal('watched: no');
const { getActionDone } = helpers;

expect(helpers.getActionDone('blacklisted', true)).to.be.equal('blacklisted: yes');
expect(helpers.getActionDone('blacklisted', false)).to.be.equal('blacklisted: no');
expect(getActionDone('watched', true)).to.be.equal('watched: yes');
expect(getActionDone('watched', false)).to.be.equal('watched: no');

expect(getActionDone('blacklisted', true)).to.be.equal('blacklisted: yes');
expect(getActionDone('blacklisted', false)).to.be.equal('blacklisted: no');
});

it('should correctly fetch accurate tooltip texts for !!/watch and !!/blacklist', () => {
const watchedNoAction = helpers.getButtonsText('watch', 'example.com', true);
const blacklistedNoAction = helpers.getButtonsText('blacklist', 'example.com', true);
const { getButtonsText } = helpers;

const watchedNoAction = getButtonsText('watch', 'example.com', true);
const blacklistedNoAction = getButtonsText('blacklist', 'example.com', true);

const watchExampleCom = helpers.getButtonsText('watch', 'example.com', false);
const blacklistManyDots = helpers.getButtonsText('blacklist', 'many.dots..com', false);
const watchExampleCom = getButtonsText('watch', 'example.com', false);
const blacklistManyDots = getButtonsText('blacklist', 'many.dots..com', false);

expect(watchedNoAction).to.be.equal(blacklistedNoAction);
expect(watchExampleCom).to.be.equal('!!/watch- example\\.com');
expect(blacklistManyDots).to.be.equal('!!/blacklist-website- many\\.dots\\.\\.com');

const watchShortenerPath = helpers.getButtonsText('watch', 'FNEuyd', false, 'goo.gl');
const watchShortenerPath = getButtonsText('watch', 'FNEuyd', false, 'goo.gl');
expect(watchShortenerPath).to.be.equal('!!/watch- (?-i:FNEuyd)(?#goo.gl)');

const watchBlogspotCom = helpers.getButtonsText('watch', 'abc.blogspot.com', false);
const watchBlogspotDe = helpers.getButtonsText('watch', 'abc.blogspot.de', false);
const watchBlogspotCom = getButtonsText('watch', 'abc.blogspot.com', false);
const watchBlogspotDe = getButtonsText('watch', 'abc.blogspot.de', false);

expect(watchBlogspotCom)
.to.be.equal(watchBlogspotDe)
.to.be.equal('!!/watch- abc\\.blogspot');

expect(
getButtonsText(
'blacklist',
'test.example.com',
false,
'',
/\bexample\.com(?<!api\.example\.com)\b/
)
).to.be.equal(
String.raw`!!/blacklist-website- example\.com(?&lt;!api\.example\.com)`
);
});

it('should correctly fetch the correct regex for paths of shorteners', () => {
Object.entries(
{
'3vcWir3': ['bit.ly', '(?-i:3vcWir3)(?#bit.ly)'],
'FNEuyd': ['goo.gl', '(?-i:FNEuyd)(?#goo.gl)'],
'KdxEAt91D7k': ['youtu.be', '(?-i:KdxEAt91D7k)(?#youtu.be)'],
FNEuyd: ['goo.gl', '(?-i:FNEuyd)(?#goo.gl)'],
KdxEAt91D7k: ['youtu.be', '(?-i:KdxEAt91D7k)(?#youtu.be)'],
// escape +
'+jJyLwSpqLeAzNmFi': ['t.me', String.raw`(?-i:\+jJyLwSpqLeAzNmFi)(?#t.me)`],
// don't escape /
Expand Down
15 changes: 8 additions & 7 deletions test/metasmoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
getAllDomainsFromPost,
getMsSearchResults
} from '../src/metasmoke';
import jsdom from "jsdom";
import jsdom from 'jsdom';

const { JSDOM } = jsdom;

Expand All @@ -12,18 +12,18 @@ global.GM_xmlhttpRequest = ({
url,
onload,
onerror
}) => {
}): void => {
fetch(url)
.then(async response => {
// @ts-ignore
onload({
status: response.status,
responseText: await response.text()
})
});
})
// @ts-ignore
// @ts-expect-error
.catch(error => onerror(error));
}
};
global.DOMParser = new JSDOM().window.DOMParser;

describe('metasmoke helpers', () => {
Expand All @@ -42,12 +42,13 @@ describe('metasmoke helpers', () => {
this.timeout(10000); // due to calls to MS search

const termEntries = Object.entries({
'LcZ2pm9XtXA': [3, 0, 0],
'FNEuyd': [0, 1, 0],
LcZ2pm9XtXA: [3, 0, 0],
FNEuyd: [0, 1, 0],
'3vcWir3': [1, 0, 0]
});

for (const [term, expectedCounts] of termEntries) {
// eslint-disable-next-line no-await-in-loop
const actualCounts = await getMsSearchResults(term);

expect(actualCounts).deep.equal(expectedCounts);
Expand Down
4 changes: 2 additions & 2 deletions test/stackexchange.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
getSeResultCount,
getShortenedResultCount
} from '../src/stackexchange';
import jsdom from "jsdom";
import jsdom from 'jsdom';

const { JSDOM } = jsdom;

Expand All @@ -14,7 +14,7 @@ describe('stackexchange helpers', () => {
it('should correctly get the correct Stack Exchange search URL', () => {
const data = {
'example.com': 'https://stackexchange.com/search?q=url%3Aexample.com',
'KdxEAt91D7k': 'https://stackexchange.com/search?q=KdxEAt91D7k'
KdxEAt91D7k: 'https://stackexchange.com/search?q=KdxEAt91D7k'
};

Object
Expand Down
Loading

0 comments on commit eccfdb7

Please sign in to comment.