Skip to content

Commit

Permalink
feat(validation): add slack channel name validation (#488)
Browse files Browse the repository at this point in the history
  • Loading branch information
NozomuIkuta committed Mar 6, 2024
1 parent 1079e3b commit a74e820
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/validation/rules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export { requiredHms } from './requiredHms'
export { requiredIf } from './requiredIf'
export { requiredYmd } from './requiredYmd'
export { rule } from './rule'
export { slackChannelName } from './slackChannelName'
export { url } from './url'
export { ymd } from './ymd'
export { zeroOrNegativeInteger } from './zeroOrNegativeInteger'
Expand Down
15 changes: 15 additions & 0 deletions lib/validation/rules/slackChannelName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createRule } from '../Rule'
import { type SlackChannelNameOptions, slackChannelName as baseSlackChannelName } from '../validators'

export const message = {
en: 'The slack channel name is invalid.',
ja: 'Slackチャンネル名の形式が正しくありません。'
}

export function slackChannelName(options?: SlackChannelNameOptions, msg?: string) {
return createRule({
message: ({ lang }) => msg ?? message[lang],
optional: true,
validation: (value) => baseSlackChannelName(value, options)
})
}
1 change: 1 addition & 0 deletions lib/validation/validators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export * from './required'
export * from './requiredHms'
export * from './requiredIf'
export * from './requiredYmd'
export * from './slackChannelName'
export * from './url'
export * from './ymd'
export * from './zero'
16 changes: 16 additions & 0 deletions lib/validation/validators/slackChannelName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { isString } from '../../support/Utils'

export interface SlackChannelNameOptions {
offset?: number
}

export function slackChannelName(value: unknown, options: SlackChannelNameOptions = {}): boolean {
if (!isString(value)) {
return false
}

const { offset = 0 } = options
const maxLength = /* Slack channel name max length */ 80 - offset

return new RegExp(`^[\\p{L}\\p{M}\\p{N}_-]{1,${maxLength}}$`, 'u').test(value)
}
78 changes: 78 additions & 0 deletions tests/validation/rules/slackChannelName.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { slackChannelName } from 'sefirot/validation/rules'

describe('validation/rules/slackChannelName', () => {
test('it validates whether the value is valid', () => {
const rule = slackChannelName()

expect(rule.$validator('1'.repeat(80), null, null)).toBe(true)
expect(rule.$validator(undefined, null, null)).toBe(true)
expect(rule.$validator(null, null, null)).toBe(true)
expect(rule.$validator('', null, null)).toBe(true)
expect(rule.$validator([], null, null)).toBe(true)

expect(rule.$validator('1'.repeat(81), null, null)).toBe(false)
expect(rule.$validator(' ', null, null)).toBe(false)
expect(rule.$validator(',', null, null)).toBe(false)
expect(rule.$validator('.', null, null)).toBe(false)
expect(rule.$validator('!', null, null)).toBe(false)
expect(rule.$validator('@', null, null)).toBe(false)
expect(rule.$validator('#', null, null)).toBe(false)
expect(rule.$validator('$', null, null)).toBe(false)
expect(rule.$validator('%', null, null)).toBe(false)
expect(rule.$validator('^', null, null)).toBe(false)
expect(rule.$validator('&', null, null)).toBe(false)
expect(rule.$validator('*', null, null)).toBe(false)
expect(rule.$validator('?', null, null)).toBe(false)
expect(rule.$validator('(', null, null)).toBe(false)
expect(rule.$validator(')', null, null)).toBe(false)
expect(rule.$validator('{', null, null)).toBe(false)
expect(rule.$validator('}', null, null)).toBe(false)
expect(rule.$validator('<', null, null)).toBe(false)
expect(rule.$validator('>', null, null)).toBe(false)
expect(rule.$validator('=', null, null)).toBe(false)
expect(rule.$validator('+', null, null)).toBe(false)
expect(rule.$validator('|', null, null)).toBe(false)
expect(rule.$validator('・', null, null)).toBe(false)
// eslint-disable-next-line @typescript-eslint/quotes
expect(rule.$validator("'", null, null)).toBe(false)
expect(rule.$validator('`', null, null)).toBe(false)
expect(rule.$validator('~', null, null)).toBe(false)
expect(rule.$validator('/', null, null)).toBe(false)
expect(rule.$validator('\\', null, null)).toBe(false)
expect(rule.$validator('[', null, null)).toBe(false)
expect(rule.$validator(']', null, null)).toBe(false)
expect(rule.$validator('"', null, null)).toBe(false)
expect(rule.$validator(true, null, null)).toBe(false)
expect(rule.$validator(false, null, null)).toBe(false)
expect(rule.$validator(1, null, null)).toBe(false)
expect(rule.$validator({}, null, null)).toBe(false)
})

test('it validates whether the value is valid with offset', () => {
const rule = slackChannelName({
offset: 10
})

expect(rule.$validator('1'.repeat(70), null, null)).toBe(true)
expect(rule.$validator(undefined, null, null)).toBe(true)
expect(rule.$validator(null, null, null)).toBe(true)
expect(rule.$validator('', null, null)).toBe(true)
expect(rule.$validator([], null, null)).toBe(true)

expect(rule.$validator('1'.repeat(71), null, null)).toBe(false)
expect(rule.$validator(true, null, null)).toBe(false)
expect(rule.$validator(false, null, null)).toBe(false)
expect(rule.$validator(1, null, null)).toBe(false)
expect(rule.$validator({}, null, null)).toBe(false)
})

test('default error message', () => {
const rule = slackChannelName()
expect(rule.$message({ $params: {} })).toBe('The slack channel name is invalid.')
})

test('it can set custom error message', () => {
const rule = slackChannelName({}, 'Custom message.')
expect(rule.$message({ $params: {} })).toBe('Custom message.')
})
})
66 changes: 66 additions & 0 deletions tests/validation/validators/slackChannelName.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { slackChannelName } from 'sefirot/validation/validators'

describe('validation/validators/slackChannelName', () => {
test('it validates whether the value is valid', () => {
expect(slackChannelName('1'.repeat(80))).toBe(true)

expect(slackChannelName('')).toBe(false)
expect(slackChannelName('1'.repeat(81))).toBe(false)
expect(slackChannelName(' ')).toBe(false)
expect(slackChannelName(',')).toBe(false)
expect(slackChannelName('.')).toBe(false)
expect(slackChannelName('!')).toBe(false)
expect(slackChannelName('@')).toBe(false)
expect(slackChannelName('#')).toBe(false)
expect(slackChannelName('$')).toBe(false)
expect(slackChannelName('%')).toBe(false)
expect(slackChannelName('^')).toBe(false)
expect(slackChannelName('&')).toBe(false)
expect(slackChannelName('*')).toBe(false)
expect(slackChannelName('?')).toBe(false)
expect(slackChannelName('(')).toBe(false)
expect(slackChannelName(')')).toBe(false)
expect(slackChannelName('{')).toBe(false)
expect(slackChannelName('}')).toBe(false)
expect(slackChannelName('<')).toBe(false)
expect(slackChannelName('>')).toBe(false)
expect(slackChannelName('=')).toBe(false)
expect(slackChannelName('+')).toBe(false)
expect(slackChannelName('|')).toBe(false)
expect(slackChannelName('・')).toBe(false)
// eslint-disable-next-line @typescript-eslint/quotes
expect(slackChannelName("'")).toBe(false)
expect(slackChannelName('`')).toBe(false)
expect(slackChannelName('~')).toBe(false)
expect(slackChannelName('/')).toBe(false)
expect(slackChannelName('\\')).toBe(false)
expect(slackChannelName('[')).toBe(false)
expect(slackChannelName(']')).toBe(false)
expect(slackChannelName('"')).toBe(false)
expect(slackChannelName(undefined)).toBe(false)
expect(slackChannelName(null)).toBe(false)
expect(slackChannelName(true)).toBe(false)
expect(slackChannelName(false)).toBe(false)
expect(slackChannelName(1)).toBe(false)
expect(slackChannelName([])).toBe(false)
expect(slackChannelName({})).toBe(false)
})

test('it validates whether the value is valid with offset', () => {
const options = {
offset: 10
}

expect(slackChannelName('1'.repeat(70), options)).toBe(true)

expect(slackChannelName('', options)).toBe(false)
expect(slackChannelName('1'.repeat(71), options)).toBe(false)
expect(slackChannelName(undefined, options)).toBe(false)
expect(slackChannelName(null, options)).toBe(false)
expect(slackChannelName(true, options)).toBe(false)
expect(slackChannelName(false, options)).toBe(false)
expect(slackChannelName(1, options)).toBe(false)
expect(slackChannelName([], options)).toBe(false)
expect(slackChannelName({}, options)).toBe(false)
})
})

0 comments on commit a74e820

Please sign in to comment.