From 3bdb4150a27752c0e5a9c2c5e2ed3d106de0f18b Mon Sep 17 00:00:00 2001 From: Purexo <5005154+Purexo@users.noreply.github.com> Date: Mon, 13 May 2024 17:13:25 +0200 Subject: [PATCH] fix: format-checkers regex need to support `:emoji:` format * add some unit tests * change `FunctionChecker` type use string instead Message for testing, all checks use `cleanContent` from `Message` --- src/format-checkers/Job.ts | 2 +- src/format-checkers/Link.ts | 2 +- src/format-checkers/Project.ts | 4 +- src/framework/FormatChecker.ts | 11 +++-- tests/format-checkers/Link.test.ts | 75 ++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 8 deletions(-) create mode 100644 tests/format-checkers/Link.test.ts diff --git a/src/format-checkers/Job.ts b/src/format-checkers/Job.ts index 4df702a..0d656de 100644 --- a/src/format-checkers/Job.ts +++ b/src/format-checkers/Job.ts @@ -5,7 +5,7 @@ export default new FormatChecker({ name: 'Job', description: 'Force le formatage du canal #jobs.', channelName: 'jobs', - checker({ cleanContent }, logger) { + checker(cleanContent, logger) { const lines = cleanContent.split('\n'); const headerParts = lines[0].split(' - '); diff --git a/src/format-checkers/Link.ts b/src/format-checkers/Link.ts index 2c6e4db..2a4a1e3 100644 --- a/src/format-checkers/Link.ts +++ b/src/format-checkers/Link.ts @@ -4,7 +4,7 @@ import createRegExp from 'emoji-regex'; const unicodeEmojiRegexp = createRegExp().source; const urlRegexp = '?'; -const titleRegexp = `(?:[\\w- ]|(?:)|${unicodeEmojiRegexp})+`; +const titleRegexp = `(?:[a-zA-Z0-9_\\- ]|(?:)|(?::\\w{2,32}:)|${unicodeEmojiRegexp})+`; const linkRegexp = `^\\[( )?(\\*\\*)?${titleRegexp}\\2\\1\\](?:[^\\n])+ - ${urlRegexp}$`; export default new FormatChecker({ diff --git a/src/format-checkers/Project.ts b/src/format-checkers/Project.ts index f34eb91..e4f0fb5 100644 --- a/src/format-checkers/Project.ts +++ b/src/format-checkers/Project.ts @@ -4,7 +4,7 @@ import { FormatChecker } from '../framework/index.js'; const unicodeEmojiRegexp = createRegExp().source; const urlRegexp = '?'; -const headerRegexp = `(?:[\\w- ]|(?:)|${unicodeEmojiRegexp})`; +const headerRegexp = `(?:[a-zA-Z0-9_\\- ]|(?:)|(?::\\w{2,32}:)|${unicodeEmojiRegexp})+`; const projectRegexp = new RegExp( `^\\*\\*${headerRegexp}+\\*\\*\\n\\n(?:.*\\n)+\n(?:(?:${headerRegexp}* )?${urlRegexp}\n)+$`, ); @@ -14,7 +14,7 @@ export default new FormatChecker({ name: 'Project', description: 'Force le formatage du canal #projets.', channelName: 'projets', - checker: ({ cleanContent }) => projectRegexp.test(cleanContent + '\n'), + checker: (cleanContent) => projectRegexp.test(cleanContent + '\n'), examples: [ `**Nom du projet**\n\nDescription du projet\n\nhttps://github.com`, ], diff --git a/src/framework/FormatChecker.ts b/src/framework/FormatChecker.ts index 7f3b386..2526007 100644 --- a/src/framework/FormatChecker.ts +++ b/src/framework/FormatChecker.ts @@ -7,7 +7,7 @@ import { Base, BaseConfig } from './Base.js'; import { Bot } from './Bot.js'; import { findTextChannelByName, isTextChannel } from './helpers.js'; -type FunctionChecker = (message: Message, logger: Logger) => boolean; +type FunctionChecker = (cleanContent: string, logger: Logger) => boolean; export interface FormatCheckerConfig extends BaseConfig { channelName: string; @@ -38,6 +38,11 @@ export class FormatChecker extends Base { this._messageUpdateHandler = this._messageUpdateHandler.bind(this); } + isMessageValid(cleanContent: string, logger: Logger) { + if (this.checker instanceof RegExp) return this.checker.test(cleanContent); + return this.checker(cleanContent, logger); + } + async _messageHandler(message: Message): Promise { if (this.bot === undefined) return; if ( @@ -53,9 +58,7 @@ export class FormatChecker extends Base { checkerName: this.name, }); - if (this.checker instanceof RegExp) { - if (this.checker.test(message.cleanContent)) return; - } else if (this.checker(message, logger)) return; + if (this.isMessageValid(message.cleanContent, logger)) return; const { cleanContent, author } = message; diff --git a/tests/format-checkers/Link.test.ts b/tests/format-checkers/Link.test.ts new file mode 100644 index 0000000..444fe1c --- /dev/null +++ b/tests/format-checkers/Link.test.ts @@ -0,0 +1,75 @@ +import { describe, test, expect } from 'vitest'; +import Link from '../../src/format-checkers/Link.js'; +import { pino, transport } from 'pino'; +import { randomUUID } from 'node:crypto'; + +describe('Link', () => { + const logger = pino(transport({ target: 'pino-pretty' })).child({ + id: randomUUID(), + type: 'FormatChecker', + checkerName: 'Link', + }); + + test('valid without emoji', () => { + const message = `[**SUJET**] Votre description ici - https://github.com/es-community`; + const isValid = Link.isMessageValid(message, logger); + + expect(isValid).toBe(true); + }); + + test('valid with unicode emoji', () => { + const message = `[👍] Votre description ici - https://github.com/es-community`; + const isValid = Link.isMessageValid(message, logger); + + expect(isValid).toBe(true); + }); + + test('valid with multiple unicode emojis', () => { + const message = `[👍👌] Votre description ici - https://github.com/es-community`; + const isValid = Link.isMessageValid(message, logger); + + expect(isValid).toBe(true); + }); + + test('valid with discord emoji', () => { + const message = `[<:adonis:793993785712312361>] Breadcrumbs automatiques pour les routes sur Adonis V6 - https://adonis-breadcrumbs.pages.dev`; + const isValid = Link.isMessageValid(message, logger); + + expect(isValid).toBe(true); + }); + + test('valid with multiple discord emojis', () => { + const message = `[<:adonis:793993785712312361><:firefox:793993785712312369>] Breadcrumbs automatiques pour les routes sur Adonis V6 - https://adonis-breadcrumbs.pages.dev`; + const isValid = Link.isMessageValid(message, logger); + + expect(isValid).toBe(true); + }); + + test('valid with multiple discord emojis mixed with unicode emojis', () => { + const message = `[<:adonis:793993785712312361>🌈<:firefox:793993785712312369>👍👌] Breadcrumbs automatiques pour les routes sur Adonis V6 - https://adonis-breadcrumbs.pages.dev`; + const isValid = Link.isMessageValid(message, logger); + + expect(isValid).toBe(true); + }); + + test.skip('valid with discord dismissed emoji', () => { + const message = `[:adonis:] Breadcrumbs automatiques pour les routes sur Adonis V6 - https://adonis-breadcrumbs.pages.dev`; + const isValid = Link.isMessageValid(message, logger); + + expect(isValid).toBe(true); + }); + + test('invalid, link is missing', () => { + const message = `[**SUJET**] Votre description ici`; + const isValid = Link.isMessageValid(message, logger); + + expect(isValid).toBe(false); + }); + + test('invalid, separator is missing', () => { + const message = `[**SUJET**] Votre description ici https://github.com/es-community`; + const isValid = Link.isMessageValid(message, logger); + + expect(isValid).toBe(false); + }); +});