diff --git a/webapp/boards/src/properties/number/__snapshots__/number.test.tsx.snap b/webapp/boards/src/properties/number/__snapshots__/number.test.tsx.snap
new file mode 100644
index 0000000000..8e914cd2c6
--- /dev/null
+++ b/webapp/boards/src/properties/number/__snapshots__/number.test.tsx.snap
@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`properties/number should match snapshot for number with empty value 1`] = `
+
+
+
+`;
diff --git a/webapp/boards/src/properties/number/number.test.tsx b/webapp/boards/src/properties/number/number.test.tsx
new file mode 100644
index 0000000000..789439c73a
--- /dev/null
+++ b/webapp/boards/src/properties/number/number.test.tsx
@@ -0,0 +1,70 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React, {ComponentProps} from 'react'
+import {screen} from '@testing-library/react'
+import {mocked} from 'jest-mock'
+
+import {setup, wrapIntl} from 'src/testUtils'
+import {TestBlockFactory} from 'src/test/testBlockFactory'
+import mutator from 'src/mutator'
+
+import {Board, IPropertyTemplate} from 'src/blocks/board'
+import {Card} from 'src/blocks/card'
+
+import NumberProperty from './property'
+import NumberEditor from './number'
+
+jest.mock('src/components/flashMessages')
+jest.mock('src/mutator')
+
+const mockedMutator = mocked(mutator)
+
+describe('properties/number', () => {
+ let board: Board
+ let card: Card
+ let propertyTemplate: IPropertyTemplate
+ let baseProps: ComponentProps
+
+ beforeEach(() => {
+ board = TestBlockFactory.createBoard()
+ card = TestBlockFactory.createCard()
+ propertyTemplate = board.cardProperties[0]
+
+ baseProps = {
+ property: new NumberProperty(),
+ card,
+ board,
+ propertyTemplate,
+ propertyValue: '',
+ readOnly: false,
+ showEmptyPlaceholder: false,
+ }
+ })
+
+ it('should match snapshot for number with empty value', () => {
+ const {container} = setup(
+ wrapIntl((
+
+ ))
+ )
+ expect(container).toMatchSnapshot()
+ })
+
+ it('should fire change event when valid number value is entered', async () => {
+ const {user} = setup(
+ wrapIntl(
+
+ )
+ )
+ const value = '42'
+ const input = screen.getByRole('textbox')
+ await user.type(input, `${value}{Enter}`)
+
+ expect(mockedMutator.changePropertyValue).toHaveBeenCalledWith(board.id, card, propertyTemplate.id, `${value}`)
+ })
+})
diff --git a/webapp/boards/src/properties/number/number.tsx b/webapp/boards/src/properties/number/number.tsx
index cfcf50bcf1..4dc175009d 100644
--- a/webapp/boards/src/properties/number/number.tsx
+++ b/webapp/boards/src/properties/number/number.tsx
@@ -10,7 +10,7 @@ const Number = (props: PropertyProps): JSX.Element => {
return (
!isNaN(parseInt(props.propertyValue as string, 10))}
+ validator={() => props.propertyValue === '' || !isNaN(parseInt(props.propertyValue as string, 10))}
/>
)
}