diff --git a/web/src/App.test.js b/web/src/App.test.js
deleted file mode 100644
index e5a5b7d..0000000
--- a/web/src/App.test.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import React from 'react';
-import { shallow } from 'enzyme';
-import App from './App';
-
-it('renders without crashing', () => {
- shallow();
-});
\ No newline at end of file
diff --git a/web/src/components/IntentDetails.js b/web/src/components/IntentDetails.js
index ff5827f..6be2bf3 100644
--- a/web/src/components/IntentDetails.js
+++ b/web/src/components/IntentDetails.js
@@ -157,14 +157,14 @@ class IntentDetails extends Component {
}
handleQuestionEdit (e, index) {
- if (e.length === QUESTION_MAX_LENGTH || !/^[a-z,.' ]*$/i.test (e)) return;
+ if (e.length >= QUESTION_MAX_LENGTH || !/^[a-z,.' ]*$/i.test (e)) return;
let newIntent = this.state.intent;
newIntent.questions[index] = e;
this.setState ({intent: newIntent});
}
handleIntentExplanationEdit (e, index) {
- if (e.length === INTENT_EXPLANATION_MAX_LENGTH || !/^[a-z,.' ]*$/i.test (e))
+ if (e.length >= INTENT_EXPLANATION_MAX_LENGTH || !/^[a-z,.' ]*$/i.test (e))
return;
let newIntent = this.state.intent;
newIntent.intentExplanation = e;
@@ -172,21 +172,21 @@ class IntentDetails extends Component {
}
handleAnswerEdit (e) {
- if (e.length === ANSWER_MAX_LENGTH || !/^[a-z,.' ]*$/i.test (e)) return;
+ if (e.length >= ANSWER_MAX_LENGTH || !/^[a-z,.' ]*$/i.test (e)) return;
let newIntent = this.state.intent;
newIntent.answer = e;
this.setState ({intent: newIntent});
}
handleAnswerSourceEdit (e) {
- if (e.length === ANSWER_MAX_LENGTH) return;
+ if (e.length >= ANSWER_MAX_LENGTH) return;
let newIntent = this.state.intent;
newIntent.externalAnswerSource = e;
this.setState ({intent: newIntent});
}
handleIntentNameEdit (e) {
- if (e.length === INTENT_NAME_MAX_LENGTH || !/^[a-z]*$/i.test (e)) return;
+ if (e.length >= INTENT_NAME_MAX_LENGTH || !/^[a-z]*$/i.test (e)) return;
let newIntent = this.state.intent;
newIntent.intentName = e;
this.setState ({intent: newIntent});
diff --git a/web/src/components/__tests__/IntentDetails.test.js b/web/src/components/__tests__/IntentDetails.test.js
index 977fc97..09c79c4 100644
--- a/web/src/components/__tests__/IntentDetails.test.js
+++ b/web/src/components/__tests__/IntentDetails.test.js
@@ -1,10 +1,290 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import {shallow, mount} from 'enzyme';
import IntentDetails from '../IntentDetails';
+import {
+ QUESTION_MAX_LENGTH,
+ ANSWER_MAX_LENGTH,
+ INTENT_NAME_MAX_LENGTH,
+ INTENT_EXPLANATION_MAX_LENGTH,
+ ANSWER_TYPE,
+} from '../../config/constants';
-it('renders without crashing', () => {
- let dummyIntent = {
- questions:['q1','q2']
- }
- shallow();
+it ('renders without crashing', () => {
+ const dummyIntent = {
+ questions: ['q1', 'q2'],
+ };
+ shallow ();
+});
+
+describe('complete testing', () => {
+
+ let wrapper;
+ let newIntent;
+ beforeEach(()=>{
+ newIntent = {
+ intentName: '',
+ intentExplanation: '',
+ questions: [''],
+ answer: '',
+ answerType: ANSWER_TYPE.PREDEFINED,
+ externalAnswerSource: '',
+ };
+
+ wrapper = mount();
+ expect(wrapper.state('intent')).toEqual(newIntent);
+ });
+
+ it ('snapshot', () =>{
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it ('renders correctly for new intent input when empty intent is sent', () => {
+ expect(wrapper.find('TextField').length).toBe(4);
+ expect(wrapper.find('Button').length).toBe(4);
+
+ expect(wrapper.find('TextField').at(0).props().id).toEqual('intent explanation');
+ expect(wrapper.find('TextField').at(1).props().id).toEqual('intent name');
+ expect(wrapper.find('TextField').at(2).props().id).toEqual('intent question');
+ expect(wrapper.find('TextField').at(3).props().id).toEqual('intent answer');
+
+ expect(wrapper.find('Button').at(0).props().children).toEqual('add');
+ expect(wrapper.find('Button').at(1).props().children).toEqual('Answer type');
+ expect(wrapper.find('Button').at(2).props().children).toEqual('Save');
+ expect(wrapper.find('Button').at(3).props().children).toEqual('Delete');
+ });
+
+ it ('receives correct props for non empty intent with predefined answer', () => {
+ newIntent = {
+ intentName: 'Dummy intent',
+ intentExplanation: 'Dummy explanation',
+ questions: ['Dummy question'],
+ answer: 'dummy answer',
+ answerType: ANSWER_TYPE.PREDEFINED,
+ externalAnswerSource: '',
+ };
+
+ wrapper = mount();
+ expect(wrapper.state('intent')).toEqual(newIntent);
+ });
+
+ it ('receives correct props for non empty intent with external source for answer', () => {
+ newIntent = {
+ intentName: 'Dummy intent',
+ intentExplanation: 'Dummy explanation',
+ questions: ['Dummy question'],
+ answer: '',
+ answerType: ANSWER_TYPE.EXTERNAL_SOURCE_WP_NEWS,
+ externalAnswerSource: 'http://sarajevotimes.com',
+ };
+
+ wrapper = mount();
+ expect(wrapper.state('intent')).toEqual(newIntent);
+ });
+
+ it ('adds text field when add button is clicked', () => {
+ const addButton = wrapper.find('button').at(0);
+ addButton.simulate('click');
+ expect(wrapper.find('TextField').length).toBe(5);
+ addButton.simulate('click');
+ expect(wrapper.find('TextField').length).toBe(6);
+
+ expect(wrapper.find('TextField').at(0).props().id).toEqual('intent explanation');
+ expect(wrapper.find('TextField').at(1).props().id).toEqual('intent name');
+ expect(wrapper.find('TextField').at(2).props().id).toEqual('intent question');
+ expect(wrapper.find('TextField').at(3).props().id).toEqual('intent question');
+ expect(wrapper.find('TextField').at(4).props().id).toEqual('intent question');
+ expect(wrapper.find('TextField').at(5).props().id).toEqual('intent answer');
+
+ expect(wrapper.state('intent').questions.length).toBe(3);
+
+ });
+
+ xit ('removes correct text field when delete button on text field is clicked', () => {
+ const addButton = wrapper.find('button').at(0);
+ addButton.simulate('click');
+ addButton.simulate('click');
+ const firstQuestionTextField = wrapper.find('TextField').at(2);
+ const secondQuestionTextField = wrapper.find('TextField').at(3);
+ const thirdQuestionTextField = wrapper.find('TextField').at(4);
+ expect(firstQuestionTextField.props().id).toEqual('intent question');
+ expect(secondQuestionTextField.props().id).toEqual('intent question');
+ expect(thirdQuestionTextField.props().id).toEqual('intent question');
+ //TODO: simulate click on delete icon inside text field and check if text field is removed
+ });
+
+ it ('accepts text without special characters for intent explanation', () => {
+ let explanationTextField = wrapper.find('TextField').at(0);
+ let validExplanationText = 'to get latest news, say ';
+ explanationTextField.instance().props.onChange(validExplanationText);
+ expect(wrapper.state('intent').intentExplanation).toEqual(validExplanationText);
+ expect(explanationTextField.instance().value).toEqual(validExplanationText);
+ });
+
+ it ('does not accept text with special characters for intent explanation', () => {
+ let explanationTextField = wrapper.find('TextField').at(0);
+ let invalidExplanationText = '554to get latest news, say #$ ';
+ explanationTextField.instance().props.onChange(invalidExplanationText);
+ expect(wrapper.state('intent').intentExplanation).toEqual('');
+ expect(explanationTextField.instance().value).toEqual('');
+ });
+
+ it ('does not accept too long text for intent explanation', () => {
+ let explanationTextField = wrapper.find('TextField').at(0);
+ let invalidExplanationText = new Array(INTENT_EXPLANATION_MAX_LENGTH + 10).join('A');
+ explanationTextField.instance().props.onChange(invalidExplanationText);
+ expect(wrapper.state('intent').intentExplanation).toEqual('');
+ expect(explanationTextField.instance().value).toEqual('');
+ });
+
+ it ('accepts text without special characters for intent name', () => {
+ let intentNameTextField = wrapper.find('TextField').at(1);
+ let validIntentNameText = 'intentName';
+ intentNameTextField.instance().props.onChange(validIntentNameText);
+ expect(wrapper.state('intent').intentName).toEqual(validIntentNameText);
+ expect(intentNameTextField.instance().value).toEqual(validIntentNameText);
+ });
+
+ it ('does not accept text with speces characters for intent name', () => {
+ let intentNameTextField = wrapper.find('TextField').at(1);
+ let invalidIntentNameText = 'intentName with space';
+ intentNameTextField.instance().props.onChange(invalidIntentNameText);
+ expect(wrapper.state('intent').intentName).toEqual('');
+ expect(intentNameTextField.instance().value).toEqual('');
+ });
+
+ it ('does not accept text with special characters for intent name', () => {
+ let intentNameTextField = wrapper.find('TextField').at(1);
+ let invalidIntentNameText = 'intentName23!';
+ intentNameTextField.instance().props.onChange(invalidIntentNameText);
+ expect(wrapper.state('intent').intentName).toEqual('');
+ expect(intentNameTextField.instance().value).toEqual('');
+ });
+
+ it ('does not accept too long text for intent name', () => {
+ let intentNameTextField = wrapper.find('TextField').at(1);
+ let invalidIntentNameText = new Array(INTENT_NAME_MAX_LENGTH + 10).join('A');
+ intentNameTextField.instance().props.onChange(invalidIntentNameText);
+ expect(wrapper.state('intent').intentName).toEqual('');
+ expect(intentNameTextField.instance().value).toEqual('');
+ });
+
+ it ('accepts text without special characters for question text', () => {
+ let questionTextField = wrapper.find('TextField').at(2);
+ let validQuestionText = 'read me latest news'
+ questionTextField.instance().props.onChange(validQuestionText);
+ expect(wrapper.state('intent').questions).toEqual([validQuestionText]);
+ expect(questionTextField.instance().value).toEqual(validQuestionText);
+ });
+
+ it ('does not accept text with special characters for question text', () => {
+ let questionTextField = wrapper.find('TextField').at(2);
+ let invalidQuestionText = 'read m3 1at35t news #'
+ questionTextField.instance().props.onChange(invalidQuestionText);
+ expect(wrapper.state('intent').questions).toEqual(['']);
+ expect(questionTextField.instance().value).toEqual('');
+ });
+
+ it ('does not accept too long text for question text', () => {
+ let questionTextField = wrapper.find('TextField').at(2);
+ let invalidQuestionText = new Array(QUESTION_MAX_LENGTH + 10).join('A');
+ questionTextField.instance().props.onChange(invalidQuestionText);
+ expect(wrapper.state('intent').questions).toEqual(['']);
+ expect(questionTextField.instance().value).toEqual('');
+ });
+
+ it ('accepts text without special characters for answer text', () => {
+ let answerTextField = wrapper.find('TextField').at(3);
+ let validAnswerText = 'this is valid answer.'
+ answerTextField.instance().props.onChange(validAnswerText);
+ expect(wrapper.state('intent').answer).toEqual(validAnswerText);
+ expect(answerTextField.instance().value).toEqual(validAnswerText);
+ });
+
+ it ('does not accept text with special characters for answer text', () => {
+ let answerTextField = wrapper.find('TextField').at(3);
+ let invalidAnswerText = 'this is invalid answer.0123'
+ answerTextField.instance().props.onChange(invalidAnswerText);
+ expect(wrapper.state('intent').answer).toEqual('');
+ expect(answerTextField.instance().value).toEqual('');
+ });
+
+ it ('does not accept too long text for answer text', () => {
+ let answerTextField = wrapper.find('TextField').at(3);
+ let invalidAnswerText = new Array(ANSWER_MAX_LENGTH + 10).join('A');
+ answerTextField.instance().props.onChange(invalidAnswerText);
+ expect(wrapper.state('intent').answer).toEqual('');
+ expect(answerTextField.instance().value).toEqual('');
+ });
+
+ it ('accepts text for external source as answer', () => {
+ newIntent = {
+ intentName: '',
+ intentExplanation: '',
+ questions: [''],
+ answer: '',
+ answerType: ANSWER_TYPE.EXTERNAL_SOURCE_WP_NEWS,
+ externalAnswerSource: '',
+ };
+
+ wrapper = mount();
+
+ let answerTextField = wrapper.find('TextField').at(3);
+ let validAnswerText = 'http://sarajevotimes.com'
+ answerTextField.instance().props.onChange(validAnswerText);
+ expect(wrapper.state('intent').externalAnswerSource).toEqual(validAnswerText);
+ expect(answerTextField.instance().value).toEqual(validAnswerText);
+ });
+
+ it ('does not accept too long text for external source as answer', () => {
+ newIntent = {
+ intentName: '',
+ intentExplanation: '',
+ questions: [''],
+ answer: '',
+ answerType: ANSWER_TYPE.EXTERNAL_SOURCE_WP_NEWS,
+ externalAnswerSource: '',
+ };
+
+ wrapper = mount();
+
+ let answerTextField = wrapper.find('TextField').at(3);
+ let invalidAnswerText = new Array(ANSWER_MAX_LENGTH + 10).join('A');
+ answerTextField.instance().props.onChange(invalidAnswerText);
+ expect(wrapper.state('intent').answer).toEqual('');
+ expect(answerTextField.instance().value).toEqual('');
+ });
+
+ it ('calls function with correct data on save button click', () => {
+ newIntent = {
+ intentName: 'Dummy intent',
+ intentExplanation: 'Dummy explanation',
+ questions: ['Dummy question'],
+ answer: 'Dummy answer',
+ answerType: ANSWER_TYPE.PREDEFINED,
+ externalAnswerSource: '',
+ };
+ const onSaveFunction = jest.fn();
+
+ wrapper = mount();
+ wrapper.find('Button').at(2).simulate('click');
+ expect(onSaveFunction).toBeCalledWith(newIntent);
+ });
+
+ it ('calls function with correct data on delete button click', () => {
+ newIntent = {
+ intentName: 'Dummy intent',
+ intentExplanation: 'Dummy explanation',
+ questions: ['Dummy question'],
+ answer: 'Dummy answer',
+ answerType: ANSWER_TYPE.PREDEFINED,
+ externalAnswerSource: '',
+ };
+ const onSaveFunction = jest.fn();
+
+ wrapper = mount();
+ wrapper.find('Button').at(3).simulate('click');
+ expect(onSaveFunction).toBeCalledWith(newIntent);
+ });
+
+
});
diff --git a/web/src/components/__tests__/__snapshots__/IntentDetails.test.js.snap b/web/src/components/__tests__/__snapshots__/IntentDetails.test.js.snap
new file mode 100644
index 0000000..03a966c
--- /dev/null
+++ b/web/src/components/__tests__/__snapshots__/IntentDetails.test.js.snap
@@ -0,0 +1,898 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`complete testing snapshot 1`] = `
+
+
+
+
+
+ In introduction, Alexa will help users to ask her the right questions about your business. For Example, she will say : "To ask us about our services, say : What do you do ? ". What do you do ? is defined in question field. Alexa will use first variation of question in intro.
+
+
+ remove_red_eye
+
+ }
+ placeholder="To ask us about our services, say "
+ rightIconStateful={true}
+ type="text"
+ value=""
+ >
+