diff --git a/x-pack/legacy/plugins/spaces/server/lib/space_schema.test.ts b/x-pack/legacy/plugins/spaces/server/lib/space_schema.test.ts index 6ca37affb84871..719f9a0908a76f 100644 --- a/x-pack/legacy/plugins/spaces/server/lib/space_schema.test.ts +++ b/x-pack/legacy/plugins/spaces/server/lib/space_schema.test.ts @@ -62,3 +62,77 @@ describe('#id', () => { } ); }); + +describe('#color', () => { + test('is optional', () => { + const result = spaceSchema.validate({ + ...defaultProperties, + color: undefined, + }); + expect(result.error).toBeNull(); + }); + + test(`doesn't allow an empty string`, () => { + const result = spaceSchema.validate({ + ...defaultProperties, + color: '', + }); + expect(result.error).toMatchInlineSnapshot( + `[ValidationError: child "color" fails because ["color" is not allowed to be empty]]` + ); + }); + + test(`allows lower case hex color code`, () => { + const result = spaceSchema.validate({ + ...defaultProperties, + color: '#aabbcc', + }); + expect(result.error).toBeNull(); + }); + + test(`allows upper case hex color code`, () => { + const result = spaceSchema.validate({ + ...defaultProperties, + color: '#AABBCC', + }); + expect(result.error).toBeNull(); + }); + + test(`allows numeric hex color code`, () => { + const result = spaceSchema.validate({ + ...defaultProperties, + color: '#123456', + }); + expect(result.error).toBeNull(); + }); + + test(`must start with a hash`, () => { + const result = spaceSchema.validate({ + ...defaultProperties, + color: '123456', + }); + expect(result.error).toMatchInlineSnapshot( + `[ValidationError: child "color" fails because ["color" with value "123456" fails to match the 6 digit hex color, starting with a # pattern]]` + ); + }); + + test(`cannot exceed 6 digits following the hash`, () => { + const result = spaceSchema.validate({ + ...defaultProperties, + color: '1234567', + }); + expect(result.error).toMatchInlineSnapshot( + `[ValidationError: child "color" fails because ["color" with value "1234567" fails to match the 6 digit hex color, starting with a # pattern]]` + ); + }); + + test(`cannot be fewer than 6 digits following the hash`, () => { + const result = spaceSchema.validate({ + ...defaultProperties, + color: '12345', + }); + expect(result.error).toMatchInlineSnapshot( + `[ValidationError: child "color" fails because ["color" with value "12345" fails to match the 6 digit hex color, starting with a # pattern]]` + ); + }); +}); diff --git a/x-pack/legacy/plugins/spaces/server/lib/space_schema.ts b/x-pack/legacy/plugins/spaces/server/lib/space_schema.ts index c2dcd3b2b9ac06..824c5f27d5fdab 100644 --- a/x-pack/legacy/plugins/spaces/server/lib/space_schema.ts +++ b/x-pack/legacy/plugins/spaces/server/lib/space_schema.ts @@ -12,7 +12,7 @@ export const spaceSchema = Joi.object({ name: Joi.string().required(), description: Joi.string().allow(''), initials: Joi.string().max(MAX_SPACE_INITIALS), - color: Joi.string().regex(/^#[a-z0-9]{6}$/, `6 digit hex color, starting with a #`), + color: Joi.string().regex(/^#[a-zA-Z0-9]{6}$/, `6 digit hex color, starting with a #`), disabledFeatures: Joi.array() .items(Joi.string()) .default([]), diff --git a/x-pack/test/api_integration/apis/spaces/index.ts b/x-pack/test/api_integration/apis/spaces/index.ts index 5aa35a10159f01..adcf70d032e0f1 100644 --- a/x-pack/test/api_integration/apis/spaces/index.ts +++ b/x-pack/test/api_integration/apis/spaces/index.ts @@ -10,5 +10,6 @@ export default function({ loadTestFile }: FtrProviderContext) { this.tags('ciGroup6'); loadTestFile(require.resolve('./saved_objects')); + loadTestFile(require.resolve('./space_attributes')); }); } diff --git a/x-pack/test/api_integration/apis/spaces/space_attributes.ts b/x-pack/test/api_integration/apis/spaces/space_attributes.ts new file mode 100644 index 00000000000000..1f9c0315f0e145 --- /dev/null +++ b/x-pack/test/api_integration/apis/spaces/space_attributes.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + + describe('space attributes', () => { + it('should allow a space to be created with a mixed-case hex color code', async () => { + await supertest + .post('/api/spaces/space') + .set('kbn-xsrf', 'xxx') + .send({ + id: 'api-test-space', + name: 'api test space', + disabledFeatures: [], + color: '#aaBB78', + }) + .expect(200, { + id: 'api-test-space', + name: 'api test space', + disabledFeatures: [], + color: '#aaBB78', + }); + }); + }); +}