Skip to content

Commit 57e619b

Browse files
authored
[App Search] Migrate Create Engine view (#89816)
* New CreateEngine view component * Add CreateEngine to index router * Add Layout-level components for CreateEngine * Static create engine view * Add new POST route for engines API endpoint * Logic for Create Engine view WIP tests failing * Fix enterpriseSearchRequestHandler path * Use setQueuedSuccessMessage after engine has been created * Use exact path for CREATE_ENGINES_PATH (but EngineRouter logic is still firing??) * Add TODO note * Put CreateEngine inside the common App Search Layout * Fix CreateEngineLogic jest tests * Move create engine view to /create_engine from /engines/new * Add Create an Engine button to Engines Overview * Missing FlashMessages on EngineOverview * Fix test for CreateEngine route * Fix strong'd text in santized name note * Use local constant for Supported Languages * Disable submit button when name is empty * Bad conflict fix * Lint nits * Improve CreateEngineLogic tests * Improve EngineOverview tests * Disable EnginesOverview header responsiveness * Moving CreateEngine route * create_engine/CreateEngine -> engine_creation/EngineCreation * Use static values for tests * Fixing constants, better casing, better ID names, i18ning dropdown labels * Removing unused imports * Fix EngineCreation tests * Fix Engines EmptyState tests * Fix EnginesOverview tests * Lint fixes * Reset mocks after tests * Update MockRouter properties * Revert newline change * Lint fix
1 parent 16eb41b commit 57e619b

File tree

18 files changed

+839
-35
lines changed

18 files changed

+839
-35
lines changed
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
import { i18n } from '@kbn/i18n';
9+
10+
export const DEFAULT_LANGUAGE = 'Universal';
11+
12+
export const ENGINE_CREATION_TITLE = i18n.translate(
13+
'xpack.enterpriseSearch.appSearch.engineCreation.title',
14+
{
15+
defaultMessage: 'Create an engine',
16+
}
17+
);
18+
19+
export const ENGINE_CREATION_FORM_TITLE = i18n.translate(
20+
'xpack.enterpriseSearch.appSearch.engineCreation.form.title',
21+
{
22+
defaultMessage: 'Name your engine',
23+
}
24+
);
25+
26+
export const ENGINE_CREATION_FORM_ENGINE_NAME_LABEL = i18n.translate(
27+
'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.label',
28+
{
29+
defaultMessage: 'Engine name',
30+
}
31+
);
32+
33+
export const ALLOWED_CHARS_NOTE = i18n.translate(
34+
'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.allowedCharactersHelpText',
35+
{
36+
defaultMessage: 'Engine names can only contain lowercase letters, numbers, and hyphens',
37+
}
38+
);
39+
40+
export const SANITIZED_NAME_NOTE = i18n.translate(
41+
'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.sanitizedNameHelpText',
42+
{
43+
defaultMessage: 'Your engine will be named',
44+
}
45+
);
46+
47+
export const ENGINE_CREATION_FORM_ENGINE_NAME_PLACEHOLDER = i18n.translate(
48+
'xpack.enterpriseSearch.appSearch.engineCreation.form.engineName.placeholder',
49+
{
50+
defaultMessage: 'i.e., my-search-engine',
51+
}
52+
);
53+
54+
export const ENGINE_CREATION_FORM_ENGINE_LANGUAGE_LABEL = i18n.translate(
55+
'xpack.enterpriseSearch.appSearch.engineCreation.form.engineLanguage.label',
56+
{
57+
defaultMessage: 'Engine language',
58+
}
59+
);
60+
61+
export const ENGINE_CREATION_FORM_SUBMIT_BUTTON_LABEL = i18n.translate(
62+
'xpack.enterpriseSearch.appSearch.engineCreation.form.submitButton.buttonLabel',
63+
{
64+
defaultMessage: 'Create engine',
65+
}
66+
);
67+
68+
export const ENGINE_CREATION_SUCCESS_MESSAGE = i18n.translate(
69+
'xpack.enterpriseSearch.appSearch.engineCreation.successMessage',
70+
{
71+
defaultMessage: 'Successfully created engine.',
72+
}
73+
);
74+
75+
export const SUPPORTED_LANGUAGES = [
76+
{
77+
value: 'Universal',
78+
text: i18n.translate(
79+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.universalDropDownOptionLabel',
80+
{
81+
defaultMessage: 'Universal',
82+
}
83+
),
84+
},
85+
{
86+
text: '—',
87+
disabled: true,
88+
},
89+
{
90+
value: 'zh',
91+
text: i18n.translate(
92+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.chineseDropDownOptionLabel',
93+
{
94+
defaultMessage: 'Chinese',
95+
}
96+
),
97+
},
98+
{
99+
value: 'da',
100+
text: i18n.translate(
101+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.danishDropDownOptionLabel',
102+
{
103+
defaultMessage: 'Danish',
104+
}
105+
),
106+
},
107+
{
108+
value: 'nl',
109+
text: i18n.translate(
110+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.dutchDropDownOptionLabel',
111+
{
112+
defaultMessage: 'Dutch',
113+
}
114+
),
115+
},
116+
{
117+
value: 'en',
118+
text: i18n.translate(
119+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.englishDropDownOptionLabel',
120+
{
121+
defaultMessage: 'English',
122+
}
123+
),
124+
},
125+
{
126+
value: 'fr',
127+
text: i18n.translate(
128+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.frenchDropDownOptionLabel',
129+
{
130+
defaultMessage: 'French',
131+
}
132+
),
133+
},
134+
{
135+
value: 'de',
136+
text: i18n.translate(
137+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.germanDropDownOptionLabel',
138+
{
139+
defaultMessage: 'German',
140+
}
141+
),
142+
},
143+
{
144+
value: 'it',
145+
text: i18n.translate(
146+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.italianDropDownOptionLabel',
147+
{
148+
defaultMessage: 'Italian',
149+
}
150+
),
151+
},
152+
{
153+
value: 'ja',
154+
text: i18n.translate(
155+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.japaneseDropDownOptionLabel',
156+
{
157+
defaultMessage: 'Japanese',
158+
}
159+
),
160+
},
161+
{
162+
value: 'ko',
163+
text: i18n.translate(
164+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.koreanDropDownOptionLabel',
165+
{
166+
defaultMessage: 'Korean',
167+
}
168+
),
169+
},
170+
{
171+
value: 'pt',
172+
text: i18n.translate(
173+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.portugueseDropDownOptionLabel',
174+
{
175+
defaultMessage: 'Portuguese',
176+
}
177+
),
178+
},
179+
{
180+
value: 'pt-br',
181+
text: i18n.translate(
182+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.portugueseBrazilDropDownOptionLabel',
183+
{
184+
defaultMessage: 'Portuguese (Brazil)',
185+
}
186+
),
187+
},
188+
{
189+
value: 'ru',
190+
text: i18n.translate(
191+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.russianDropDownOptionLabel',
192+
{
193+
defaultMessage: 'Russian',
194+
}
195+
),
196+
},
197+
{
198+
value: 'es',
199+
text: i18n.translate(
200+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.spanishDropDownOptionLabel',
201+
{
202+
defaultMessage: 'Spanish',
203+
}
204+
),
205+
},
206+
{
207+
value: 'th',
208+
text: i18n.translate(
209+
'xpack.enterpriseSearch.appSearch.engineCreation.supportedLanguages.thaiDropDownOptionLabel',
210+
{
211+
defaultMessage: 'Thai',
212+
}
213+
),
214+
},
215+
];
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
import { setMockActions, setMockValues } from '../../../__mocks__';
9+
10+
import React from 'react';
11+
12+
import { shallow } from 'enzyme';
13+
14+
import { EngineCreation } from './';
15+
16+
describe('EngineCreation', () => {
17+
const DEFAULT_VALUES = {
18+
name: '',
19+
rawName: '',
20+
language: 'Universal',
21+
};
22+
23+
const MOCK_ACTIONS = {
24+
setRawName: jest.fn(),
25+
setLanguage: jest.fn(),
26+
submitEngine: jest.fn(),
27+
};
28+
29+
beforeEach(() => {
30+
jest.clearAllMocks();
31+
setMockValues(DEFAULT_VALUES);
32+
setMockActions(MOCK_ACTIONS);
33+
});
34+
35+
it('renders', () => {
36+
const wrapper = shallow(<EngineCreation />);
37+
expect(wrapper.find('[data-test-subj="EngineCreation"]')).toHaveLength(1);
38+
});
39+
40+
it('EngineCreationForm calls submitEngine on form submit', () => {
41+
const wrapper = shallow(<EngineCreation />);
42+
const simulatedEvent = {
43+
preventDefault: jest.fn(),
44+
};
45+
wrapper.find('[data-test-subj="EngineCreationForm"]').simulate('submit', simulatedEvent);
46+
47+
expect(MOCK_ACTIONS.submitEngine).toHaveBeenCalledTimes(1);
48+
});
49+
50+
it('EngineCreationNameInput calls setRawName on change', () => {
51+
const wrapper = shallow(<EngineCreation />);
52+
const simulatedEvent = {
53+
currentTarget: { value: 'new-raw-name' },
54+
};
55+
wrapper.find('[data-test-subj="EngineCreationNameInput"]').simulate('change', simulatedEvent);
56+
57+
expect(MOCK_ACTIONS.setRawName).toHaveBeenCalledWith('new-raw-name');
58+
});
59+
60+
it('EngineCreationLanguageInput calls setLanguage on change', () => {
61+
const wrapper = shallow(<EngineCreation />);
62+
const simulatedEvent = {
63+
currentTarget: { value: 'English' },
64+
};
65+
wrapper
66+
.find('[data-test-subj="EngineCreationLanguageInput"]')
67+
.simulate('change', simulatedEvent);
68+
69+
expect(MOCK_ACTIONS.setLanguage).toHaveBeenCalledWith('English');
70+
});
71+
72+
describe('NewEngineSubmitButton', () => {
73+
it('is disabled when name is empty', () => {
74+
setMockValues({ ...DEFAULT_VALUES, name: '', rawName: '' });
75+
const wrapper = shallow(<EngineCreation />);
76+
77+
expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]').prop('disabled')).toEqual(
78+
true
79+
);
80+
});
81+
82+
it('is enabled when name has a value', () => {
83+
setMockValues({ ...DEFAULT_VALUES, name: 'test', rawName: 'test' });
84+
const wrapper = shallow(<EngineCreation />);
85+
86+
expect(wrapper.find('[data-test-subj="NewEngineSubmitButton"]').prop('disabled')).toEqual(
87+
false
88+
);
89+
});
90+
});
91+
92+
describe('EngineCreationNameFormRow', () => {
93+
it('renders sanitized name helptext when the raw name is being sanitized', () => {
94+
setMockValues({
95+
...DEFAULT_VALUES,
96+
name: 'un-sanitized-name',
97+
rawName: 'un-----sanitized-------name',
98+
});
99+
const wrapper = shallow(<EngineCreation />);
100+
const formRow = wrapper.find('[data-test-subj="EngineCreationNameFormRow"]').dive();
101+
102+
expect(formRow.contains('Your engine will be named')).toBeTruthy();
103+
});
104+
105+
it('renders allowed character helptext when rawName and sanitizedName match', () => {
106+
setMockValues({
107+
...DEFAULT_VALUES,
108+
name: 'pre-sanitized-name',
109+
rawName: 'pre-sanitized-name',
110+
});
111+
const wrapper = shallow(<EngineCreation />);
112+
const formRow = wrapper.find('[data-test-subj="EngineCreationNameFormRow"]').dive();
113+
114+
expect(
115+
formRow.contains('Engine names can only contain lowercase letters, numbers, and hyphens')
116+
).toBeTruthy();
117+
});
118+
});
119+
});

0 commit comments

Comments
 (0)