/*
* Copyright (c) 2005-2011 Grameen Foundation USA
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* See also http://www.apache.org/licenses/LICENSE-2.0.html for an
* explanation of the license and how it is applied.
*/
package org.mifos.platform.questionnaire.ui.controller;
import org.hamcrest.CoreMatchers;
import org.hamcrest.core.Is;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mifos.framework.exceptions.SystemException;
import org.mifos.platform.validations.ValidationException;
import org.mifos.platform.matchers.MessageMatcher;
import org.mifos.platform.questionnaire.QuestionnaireConstants;
import org.mifos.platform.questionnaire.exceptions.BadNumericResponseException;
import org.mifos.platform.questionnaire.exceptions.MandatoryAnswerNotFoundException;
import org.mifos.platform.questionnaire.matchers.QuestionGroupDetailFormMatcher;
import org.mifos.platform.questionnaire.matchers.QuestionGroupDetailMatcher;
import org.mifos.platform.questionnaire.matchers.QuestionGroupDetailsMatcher;
import org.mifos.platform.questionnaire.matchers.QuestionGroupsGroupByEventSourceMatcher;
import org.mifos.platform.questionnaire.service.QuestionDetail;
import org.mifos.platform.questionnaire.service.QuestionGroupDetail;
import org.mifos.platform.questionnaire.service.QuestionGroupDetails;
import org.mifos.platform.questionnaire.service.QuestionType;
import org.mifos.platform.questionnaire.service.QuestionnaireServiceFacade;
import org.mifos.platform.questionnaire.service.SectionDetail;
import org.mifos.platform.questionnaire.service.SectionQuestionDetail;
import org.mifos.platform.questionnaire.service.dtos.EventSourceDto;
import org.mifos.platform.questionnaire.ui.model.QuestionGroupForm;
import org.mifos.platform.questionnaire.ui.model.SectionDetailForm;
import org.mifos.platform.validation.MifosBeanValidator;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.binding.message.MessageContext;
import org.springframework.ui.ModelMap;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.webflow.execution.RequestContext;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.mifos.platform.questionnaire.QuestionnaireConstants.GENERIC_VALIDATION;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
@SuppressWarnings("PMD")
public class QuestionGroupControllerTest {
private static final String TITLE = "Title";
@Mock
private QuestionnaireServiceFacade questionnaireServiceFacade;
private QuestionGroupController questionGroupController;
@Mock
private RequestContext requestContext;
@Mock
private MessageContext messageContext;
@Mock
private ModelMap model;
@Mock
private HttpServletRequest httpServletRequest;
MifosBeanValidator validator = new MifosBeanValidator();
LocalValidatorFactoryBean targetValidator = new LocalValidatorFactoryBean();
@Before
public void setUp() {
questionGroupController = new QuestionGroupController(questionnaireServiceFacade);
targetValidator.afterPropertiesSet();
validator.setTargetValidator(targetValidator);
}
@Test
public void testDeleteSection() {
QuestionGroupForm questionGroup = new QuestionGroupForm();
String sectionName = "sectionName";
questionGroup.setSectionName(sectionName);
questionGroup.addCurrentSection();
assertThat(questionGroup.getSections().size(), Is.is(1));
questionGroupController.deleteSection(questionGroup, sectionName);
assertThat(questionGroup.getSections().size(), Is.is(0));
}
@Test
public void testAddSectionForSuccess() throws Exception {
QuestionGroupForm questionGroup = new QuestionGroupForm();
questionGroup.setQuestionPool(new ArrayList<SectionQuestionDetail>(asList(getSectionQuestionDetail(1, "Q1"), getSectionQuestionDetail(2, "Q2"))));
questionGroup.setSelectedQuestionIds(asList("1"));
questionGroup.setTitle("title");
questionGroup.setSectionName("sectionName");
String result = questionGroupController.addSection(questionGroup, requestContext);
assertThat(questionGroup.getSections().size(), Is.is(1));
assertThat(questionGroup.getSections().get(0).getName(), Is.is("sectionName"));
assertThat(questionGroup.getSections().get(0).getSectionQuestions().size(), Is.is(1));
assertThat(questionGroup.getSections().get(0).getSectionQuestions().get(0).getText(), Is.is("Q1"));
assertThat(result, Is.is("success"));
}
@Test
public void testAddSectionsSuccessWhenSectionNameIsNotProvided() {
QuestionGroupForm questionGroup = new QuestionGroupForm();
questionGroup.setQuestionPool(new ArrayList<SectionQuestionDetail>(asList(getSectionQuestionDetail(1, "Q1"), getSectionQuestionDetail(2, "Q2"))));
questionGroup.setSelectedQuestionIds(asList("2"));
String result = questionGroupController.addSection(questionGroup, requestContext);
assertThat(questionGroup.getSections().size(), Is.is(1));
assertThat(questionGroup.getSections().get(0).getName(), Is.is("Misc"));
assertThat(questionGroup.getSections().get(0).getSectionQuestions().size(), Is.is(1));
assertThat(questionGroup.getSections().get(0).getSectionQuestions().get(0).getText(), Is.is("Q2"));
assertThat(result, Is.is("success"));
}
@Test
public void testAddSectionForSuccessWhenQuestionTitleProvidedWithAllBlanks() throws Exception {
QuestionGroupForm questionGroup = new QuestionGroupForm();
questionGroup.setQuestionPool(new ArrayList<SectionQuestionDetail>(asList(getSectionQuestionDetail(1, "Q1"), getSectionQuestionDetail(2, "Q2"))));
questionGroup.setSelectedQuestionIds(asList("1", "2"));
questionGroup.setSectionName(" ");
String result = questionGroupController.addSection(questionGroup, requestContext);
assertThat(questionGroup.getSections().size(), Is.is(1));
assertThat(questionGroup.getSections().get(0).getName(), Is.is("Misc"));
assertThat(questionGroup.getSections().get(0).getSectionQuestions().size(), Is.is(2));
assertThat(questionGroup.getSections().get(0).getSectionQuestions().get(0).getText(), Is.is("Q1"));
assertThat(questionGroup.getSections().get(0).getSectionQuestions().get(1).getText(), Is.is("Q2"));
assertThat(result, Is.is("success"));
}
@Test
public void testAddSectionWithoutQuestions() throws Exception {
when(requestContext.getMessageContext()).thenReturn(messageContext);
QuestionGroupForm questionGroup = new QuestionGroupForm();
questionGroup.setTitle("title");
questionGroup.setSectionName("sectionName");
String result = questionGroupController.addSection(questionGroup, requestContext);
verify(requestContext).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("questionnaire.error.no.question.in.section")));
assertThat(result, Is.is("failure"));
}
@Test
public void testRemoveQuestionFromSection() {
QuestionGroupForm questionGroup = new QuestionGroupForm();
List<SectionDetailForm> sections = new ArrayList<SectionDetailForm>();
sections.add(getSectionSectionDetailForm("sectionName", new ArrayList<SectionQuestionDetail>(asList(getSectionQuestionDetail(1, "Q1"), getSectionQuestionDetail(2, "Q2")))));
questionGroup.setSections(sections);
assertThat(questionGroup.getSections().size(), CoreMatchers.is(1));
assertThat(questionGroup.getSections().get(0).getSectionQuestions().size(), CoreMatchers.is(2));
assertThat(questionGroup.getSections().get(0).getSectionQuestions().get(0).getText(), CoreMatchers.is("Q1"));
assertThat(questionGroup.getSections().get(0).getSectionQuestions().get(1).getText(), CoreMatchers.is("Q2"));
questionGroupController.deleteQuestion(questionGroup, "sectionName", "1");
assertThat(questionGroup.getSections().size(), CoreMatchers.is(1));
assertThat(questionGroup.getSections().get(0).getSectionQuestions().size(), CoreMatchers.is(1));
assertThat(questionGroup.getSections().get(0).getSectionQuestions().get(0).getText(), CoreMatchers.is("Q2"));
questionGroupController.deleteQuestion(questionGroup, "sectionName", "2");
assertThat(questionGroup.getSections().size(), CoreMatchers.is(0));
}
@Test
public void testCreateQuestionGroupSuccess() throws Exception {
QuestionGroupForm questionGroup = getQuestionGroupForm(" " + TITLE + " ", "Create.Client", "S1", "S2");
String result = questionGroupController.defineQuestionGroup(questionGroup, requestContext, true);
assertThat(result, Is.is("success"));
QuestionGroupDetail questionGroupDetail = getQuestionGroupDetail(TITLE, "Create", "Client", "S1", "S2");
questionGroupDetail.setActive(true);
verify(questionnaireServiceFacade).createActiveQuestionGroup(argThat(new QuestionGroupDetailMatcher(questionGroupDetail)));
}
@Test
public void testEditQuestionGroupSuccess() throws Exception {
QuestionGroupForm questionGroup = getQuestionGroupForm(" " + TITLE + " ", "Create.Client", "S1", "S2");
String result = questionGroupController.defineQuestionGroup(questionGroup, requestContext, false);
assertThat(result, Is.is("success"));
QuestionGroupDetail questionGroupDetail = getQuestionGroupDetail(TITLE, "Create", "Client", "S1", "S2");
questionGroupDetail.setActive(false);
verify(questionnaireServiceFacade).createQuestionGroup(argThat(new QuestionGroupDetailMatcher(questionGroupDetail)));
}
private QuestionGroupDetail getQuestionGroupDetail(String title, String event, String source, String... sectionNames) {
QuestionGroupDetail questionGroupDetail = new QuestionGroupDetail();
questionGroupDetail.setTitle(title);
questionGroupDetail.setEventSources(Arrays.asList(new EventSourceDto(event, source, null)));
List<SectionDetail> sectionDetails = new ArrayList<SectionDetail>();
for (String sectionName : sectionNames) {
SectionDetail sectionDetail = new SectionDetail();
sectionDetail.setName(sectionName);
sectionDetails.add(sectionDetail);
}
questionGroupDetail.setSectionDetails(sectionDetails);
return questionGroupDetail;
}
@Test
public void testCreateQuestionGroupForFailureWhenQuestionGroupTitleNotProvided() throws Exception {
QuestionGroupForm questionGroupForm = getQuestionGroupForm(null, "Create.Client", "Section");
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.defineQuestionGroup(questionGroupForm, requestContext, true);
assertThat(result, Is.is(notNullValue()));
assertThat(result, Is.is("failure"));
verify(requestContext).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("questionnaire.error.questionGroup.title.empty")));
}
@SuppressWarnings({"ThrowableInstanceNeverThrown"})
@Test
public void testCreateQuestionGroupFailureWhenSectionsNotPresent() throws Exception {
when(requestContext.getMessageContext()).thenReturn(messageContext);
QuestionGroupForm questionGroupForm = getQuestionGroupForm(TITLE, "Create.Client");
String result = questionGroupController.defineQuestionGroup(questionGroupForm, requestContext, true);
assertThat(result, Is.is("failure"));
verify(requestContext).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("questionnaire.error.section.atLeastOne")));
}
@Test
public void testCreateQuestionGroupForFailureWhenQuestionGroupAppliesToNotProvided() throws Exception {
QuestionGroupForm questionGroupForm = getQuestionGroupForm(TITLE, QuestionnaireConstants.DEFAULT_APPLIES_TO_OPTION, "Section");
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.defineQuestionGroup(questionGroupForm, requestContext, true);
assertThat(result, Is.is(notNullValue()));
assertThat(result, Is.is("failure"));
verify(requestContext).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("questionnaire.error.appliesTo.mandatory")));
}
@SuppressWarnings({"ThrowableInstanceNeverThrown"})
@Test
public void testCreateQuestionGroupFailure() throws Exception {
QuestionGroupForm questionGroupForm = getQuestionGroupForm(TITLE, "Create.Client", "S1", "S2");
when(requestContext.getMessageContext()).thenReturn(messageContext);
doThrow(new SystemException("questionnaire.error.duplicate.question.found.in.section")).when(questionnaireServiceFacade).createActiveQuestionGroup(Matchers.<QuestionGroupDetail>anyObject());
String result = questionGroupController.defineQuestionGroup(questionGroupForm, requestContext, true);
assertThat(result, Is.is("failure"));
verify(questionnaireServiceFacade).createActiveQuestionGroup(Matchers.<QuestionGroupDetail>anyObject());
verify(requestContext).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("questionnaire.error.duplicate.question.found.in.section")));
}
//TODO Question Groups added to testing data should have different titles, otherwise QuestionGroupSectionMatcher will throw exceptions. Matchers shouldn't throw exception when matching fail but return 'false'
@Test
public void shouldGetAllQuestionGroups() {
QuestionGroupDetail questionGroupDetail1 = getQuestionGroupDetail(1, TITLE + "1", "View", "Loan", true, true, "title1", "sectionName1");
QuestionGroupDetail questionGroupDetail2 = getQuestionGroupDetail(2, TITLE + "2", "View", "Loan", true, true, "title2", "sectionName2");
QuestionGroupDetail questionGroupDetail3 = getQuestionGroupDetail(3, TITLE + "3", "Create", "Loan", true, true, "title3", "sectionName3");
List<QuestionGroupDetail> questionGroupDetails = asList(questionGroupDetail1, questionGroupDetail2, questionGroupDetail3);
Map <String,List <QuestionGroupDetail>> questionGroupsCategoriesSplit = new HashMap<String, List<QuestionGroupDetail>>();
questionGroupsCategoriesSplit.put("View Loan", asList(questionGroupDetail1, questionGroupDetail2));
questionGroupsCategoriesSplit.put("Create Loan", asList(questionGroupDetail3));
when(questionnaireServiceFacade.getAllQuestionGroups()).thenReturn(questionGroupDetails);
when(questionnaireServiceFacade.getAllEventSources()).thenReturn(asList(questionGroupDetail2.getEventSources().get(0), questionGroupDetail3.getEventSources().get(0)));
String view = questionGroupController.getAllQuestionGroups(model, httpServletRequest);
assertThat(view, Is.is("viewQuestionGroups"));
verify(questionnaireServiceFacade).getAllQuestionGroups();
verify(questionnaireServiceFacade).getAllEventSources();
verify(model).addAttribute(Matchers.eq("questionGroups"), argThat(new QuestionGroupsGroupByEventSourceMatcher(questionGroupsCategoriesSplit)));
}
@Test
public void shouldGetQuestionGroupById() throws SystemException {
int questionGroupId = 1;
QuestionGroupDetail questionGroupDetail = getQuestionGroupDetail(questionGroupId, TITLE, "S1", "S2", "S3");
when(questionnaireServiceFacade.getQuestionGroupDetail(questionGroupId)).thenReturn(questionGroupDetail);
when(httpServletRequest.getParameter("questionGroupId")).thenReturn(Integer.toString(questionGroupId));
String view = questionGroupController.getQuestionGroup(model, httpServletRequest);
assertThat(view, Is.is("viewQuestionGroupDetail"));
verify(questionnaireServiceFacade).getQuestionGroupDetail(questionGroupId);
verify(questionnaireServiceFacade, times(1)).getAllEventSources();
verify(httpServletRequest, times(1)).getParameter("questionGroupId");
verify(model).addAttribute(Matchers.eq("questionGroupDetail"), argThat(new QuestionGroupDetailFormMatcher(new QuestionGroupForm(questionGroupDetail))));
}
@SuppressWarnings({"ThrowableInstanceNeverThrown"})
@Test
public void testGetQuestionGroupWhenNotPresentInDb() throws SystemException {
int questionGroupId = 1;
when(questionnaireServiceFacade.getQuestionGroupDetail(questionGroupId)).thenThrow(new SystemException(QuestionnaireConstants.QUESTION_GROUP_NOT_FOUND));
when(httpServletRequest.getParameter("questionGroupId")).thenReturn("1");
String view = questionGroupController.getQuestionGroup(model, httpServletRequest);
assertThat(view, Is.is("viewQuestionGroupDetail"));
verify(questionnaireServiceFacade).getQuestionGroupDetail(questionGroupId);
verify(httpServletRequest, times(1)).getParameter("questionGroupId");
verify(model).addAttribute("error_message_code", QuestionnaireConstants.QUESTION_GROUP_NOT_FOUND);
}
@Test
public void testGetQuestionGroupWhenIdIsNull() throws SystemException {
when(httpServletRequest.getParameter("questionGroupId")).thenReturn(null);
String view = questionGroupController.getQuestionGroup(model, httpServletRequest);
assertThat(view, Is.is("viewQuestionGroupDetail"));
verify(httpServletRequest, times(1)).getParameter("questionGroupId");
verify(questionnaireServiceFacade, times(0)).getQuestionGroupDetail(Matchers.anyInt());
verify(model).addAttribute("error_message_code", QuestionnaireConstants.INVALID_QUESTION_GROUP_ID);
}
@Test
public void testGetQuestionGroupWhenIdIsNotInteger() throws SystemException {
when(httpServletRequest.getParameter("questionGroupId")).thenReturn("1A");
String view = questionGroupController.getQuestionGroup(model, httpServletRequest);
assertThat(view, Is.is("viewQuestionGroupDetail"));
verify(httpServletRequest, times(1)).getParameter("questionGroupId");
verify(questionnaireServiceFacade, times(0)).getQuestionGroupDetail(Matchers.anyInt());
verify(model).addAttribute("error_message_code", QuestionnaireConstants.INVALID_QUESTION_GROUP_ID);
}
@Test
public void shouldGetAllQgEventSources() {
when(questionnaireServiceFacade.getAllEventSources()).thenReturn(asList(new EventSourceDto("Create", "Client", "Create Client"), new EventSourceDto("View", "Client", "View Client")));
Map<String, String> eventSources = questionGroupController.getAllQgEventSources();
verify(questionnaireServiceFacade).getAllEventSources();
assertThat(eventSources.get("Create.Client"), Is.is("Create Client"));
assertThat(eventSources.get("View.Client"), Is.is("View Client"));
}
@Test
public void shouldGetAllSectionQuestions() {
when(questionnaireServiceFacade.getAllActiveQuestions()).thenReturn(asList(getQuestionDetail(1, "Q1", QuestionType.NUMERIC), getQuestionDetail(2, "Q2", QuestionType.DATE)));
List<SectionQuestionDetail> sectionQuestions = questionGroupController.getAllSectionQuestions();
assertThat(sectionQuestions, Is.is(notNullValue()));
assertThat(sectionQuestions.size(), Is.is(2));
assertThat(sectionQuestions.get(0).getQuestionId(), Is.is(1));
assertThat(sectionQuestions.get(0).getText(), Is.is("Q1"));
assertThat(sectionQuestions.get(1).getQuestionId(), Is.is(2));
assertThat(sectionQuestions.get(1).getText(), Is.is("Q2"));
verify(questionnaireServiceFacade).getAllActiveQuestions();
}
@Test
public void shouldGetAllSectionQuestionsWithoutExcludedQuestions() {
List<Integer> excludedQuestions = asList(3);
List<QuestionDetail> questionDetails = asList(getQuestionDetail(1, "Q1", QuestionType.NUMERIC), getQuestionDetail(2, "Q2", QuestionType.DATE));
when(questionnaireServiceFacade.getAllActiveQuestions(excludedQuestions)).thenReturn(questionDetails);
QuestionGroupForm questionGroupForm = getQuestionGroupFormWithOneSectionQuestion("QG1", 3);
List<SectionQuestionDetail> sectionQuestions = questionGroupController.getAllSectionQuestions(questionGroupForm);
assertThat(sectionQuestions, Is.is(notNullValue()));
assertThat(sectionQuestions.size(), Is.is(2));
assertThat(sectionQuestions.get(0).getQuestionId(), Is.is(1));
assertThat(sectionQuestions.get(0).getText(), Is.is("Q1"));
assertThat(sectionQuestions.get(1).getQuestionId(), Is.is(2));
assertThat(sectionQuestions.get(1).getText(), Is.is("Q2"));
verify(questionnaireServiceFacade).getAllActiveQuestions(excludedQuestions);
}
private QuestionGroupForm getQuestionGroupFormWithOneSectionQuestion(String qgTitle, int questionId) {
QuestionGroupForm questionGroupForm = getQuestionGroupForm(qgTitle, "Create.Client");
SectionDetail sectionDetail = new SectionDetail();
sectionDetail.setName("Sec1");
sectionDetail.setQuestionDetails(asList(new SectionQuestionDetail(getQuestionDetail(questionId, "Q3", QuestionType.FREETEXT), true)));
questionGroupForm.getQuestionGroupDetail().getSectionDetails().add(sectionDetail);
return questionGroupForm;
}
@Test
public void shouldGetAllSectionQuestionsEmpty() {
when(questionnaireServiceFacade.getAllActiveQuestions()).thenReturn(null);
List<SectionQuestionDetail> sectionQuestions = questionGroupController.getAllSectionQuestions();
assertThat(sectionQuestions, Is.is(notNullValue()));
assertThat(sectionQuestions.size(), Is.is(0));
verify(questionnaireServiceFacade).getAllActiveQuestions();
}
@Test
public void testSaveQuestionnaireSuccess() {
String result = questionGroupController.saveQuestionnaire(
getQuestionGroupDetails(), 1, requestContext);
verify(questionnaireServiceFacade, times(1)).saveResponses(argThat(new QuestionGroupDetailsMatcher(
new QuestionGroupDetails(1, 2, 3, asList(
getQuestionGroupDetail(TITLE, "View", "Client", "S1", "S3"))))));
assertThat(result, is("success"));
}
@Test
public void testSaveQuestionnaireFailure() {
ValidationException validationException = new ValidationException(GENERIC_VALIDATION);
validationException.addChildException(new MandatoryAnswerNotFoundException("q1"));
doThrow(validationException).when(questionnaireServiceFacade).saveResponses(Mockito.<QuestionGroupDetails>any());
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.saveQuestionnaire(getQuestionGroupDetails(), 1, requestContext);
assertThat(result, is("failure"));
verify(requestContext, times(1)).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("questionnaire.noresponse")));
}
@SuppressWarnings({"ThrowableInstanceNeverThrown"})
@Test
public void testSaveQuestionnaireFailureForNumericResponseWithoutBounds() {
ValidationException validationException = new ValidationException(GENERIC_VALIDATION);
validationException.addChildException(new BadNumericResponseException("q1", null, null));
doThrow(validationException).when(questionnaireServiceFacade).saveResponses(Mockito.<QuestionGroupDetails>any());
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.saveQuestionnaire(getQuestionGroupDetails(), 1, requestContext);
assertThat(result, is("failure"));
verify(requestContext, times(1)).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("questionnaire.invalid.numeric.response")));
}
@SuppressWarnings({"ThrowableInstanceNeverThrown"})
@Test
public void testSaveQuestionnaireFailureForNumericResponseNotWithinBounds() {
ValidationException validationException = new ValidationException(GENERIC_VALIDATION);
validationException.addChildException(new BadNumericResponseException("q1", 10, 100));
doThrow(validationException).when(questionnaireServiceFacade).saveResponses(Mockito.<QuestionGroupDetails>any());
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.saveQuestionnaire(getQuestionGroupDetails(), 1, requestContext);
assertThat(result, is("failure"));
verify(requestContext, times(1)).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("questionnaire.invalid.numeric.range.response")));
}
@SuppressWarnings({"ThrowableInstanceNeverThrown"})
@Test
public void testSaveQuestionnaireFailureForNumericResponseLessThanMinBound() {
ValidationException validationException = new ValidationException(GENERIC_VALIDATION);
validationException.addChildException(new BadNumericResponseException("q1", 10, null));
doThrow(validationException).when(questionnaireServiceFacade).saveResponses(Mockito.<QuestionGroupDetails>any());
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.saveQuestionnaire(getQuestionGroupDetails(), 1, requestContext);
assertThat(result, is("failure"));
verify(requestContext, times(1)).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("questionnaire.invalid.numeric.min.response")));
}
@SuppressWarnings({"ThrowableInstanceNeverThrown"})
@Test
public void testSaveQuestionnaireFailureForNumericResponseGreaterThanMaxBound() {
ValidationException validationException = new ValidationException(GENERIC_VALIDATION);
validationException.addChildException(new BadNumericResponseException("q1", null, 100));
doThrow(validationException).when(questionnaireServiceFacade).saveResponses(Mockito.<QuestionGroupDetails>any());
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.saveQuestionnaire(getQuestionGroupDetails(), 1, requestContext);
assertThat(result, is("failure"));
verify(requestContext, times(1)).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("questionnaire.invalid.numeric.max.response")));
}
@Test
public void testAddQuestion() {
QuestionGroupForm questionGroupForm = getQuestionGroupForm(TITLE, "Create.Client", "Default");
questionGroupForm.getCurrentQuestion().setText("Question1");
questionGroupForm.getCurrentQuestion().setType("freeText");
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.addQuestion(questionGroupForm, requestContext);
assertThat(result, is("success"));
verify(requestContext, times(1)).getMessageContext();
}
@Test
public void testAddQuestionForEmptyTitle() {
QuestionGroupForm questionGroupForm = getQuestionGroupForm(TITLE, "Create.Client", "Default");
questionGroupForm.setValidator(validator);
questionGroupForm.getCurrentQuestion().setText(null);
questionGroupForm.getCurrentQuestion().setType("freeText");
when(messageContext.hasErrorMessages()).thenReturn(true);
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.addQuestion(questionGroupForm, requestContext);
assertThat(result, is("failure"));
verify(requestContext, times(1)).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("NotNull.QuestionGroupForm.currentQuestion.text")));
}
@Test
public void testAddQuestionForEmptyType() {
QuestionGroupForm questionGroupForm = getQuestionGroupForm(TITLE, "Create.Client", "Default");
questionGroupForm.setValidator(validator);
questionGroupForm.getCurrentQuestion().setText(TITLE);
questionGroupForm.getCurrentQuestion().setType(null);
when(messageContext.hasErrorMessages()).thenReturn(true);
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.addQuestion(questionGroupForm, requestContext);
assertThat(result, is("failure"));
verify(requestContext, times(1)).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("NotNull.QuestionGroupForm.currentQuestion.type")));
}
@Test
public void testAddQuestionForDuplicateTitle() {
QuestionGroupForm questionGroupForm = getQuestionGroupForm(TITLE, "Create.Client", "Default");
questionGroupForm.setValidator(validator);
questionGroupForm.getCurrentQuestion().setText(TITLE);
questionGroupForm.getCurrentQuestion().setType("freeText");
when(questionnaireServiceFacade.isDuplicateQuestion(TITLE)).thenReturn(true);
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.addQuestion(questionGroupForm, requestContext);
assertThat(result, is("failure"));
verify(requestContext, times(1)).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("questionnaire.error.question.duplicate")));
}
@Test
public void testAddQuestionForInvalidAnswerChoices() {
QuestionGroupForm questionGroupForm = getQuestionGroupForm(TITLE, "Create.Client", "Default");
questionGroupForm.setValidator(validator);
questionGroupForm.getCurrentQuestion().setText(TITLE);
questionGroupForm.getCurrentQuestion().setType("singleSelect");
questionGroupForm.getCurrentQuestion().setCurrentChoice("Choice1");
questionGroupForm.getCurrentQuestion().addAnswerChoice();
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.addQuestion(questionGroupForm, requestContext);
assertThat(result, is("failure"));
verify(requestContext, times(1)).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher("questionnaire.error.question.choices")));
}
@Test
public void testAddQuestionForInvalidNumericBounds() {
QuestionGroupForm questionGroupForm = getQuestionGroupForm(TITLE, "Create.Client", "Default");
questionGroupForm.setValidator(validator);
questionGroupForm.getCurrentQuestion().setText(TITLE);
questionGroupForm.getCurrentQuestion().setType("number");
questionGroupForm.getCurrentQuestion().setNumericMin(100);
questionGroupForm.getCurrentQuestion().setNumericMax(10);
when(requestContext.getMessageContext()).thenReturn(messageContext);
String result = questionGroupController.addQuestion(questionGroupForm, requestContext);
assertThat(result, is("failure"));
verify(requestContext, times(1)).getMessageContext();
verify(messageContext).addMessage(argThat(new MessageMatcher(QuestionnaireConstants.INVALID_NUMERIC_BOUNDS)));
}
private QuestionGroupDetails getQuestionGroupDetails() {
QuestionGroupDetails questionGroupDetails = new QuestionGroupDetails(1, 2, 3, asList(
getQuestionGroupDetail(TITLE, "View", "Client", "S1", "S2"),
getQuestionGroupDetail(TITLE, "View", "Client", "S1", "S3")
));
return questionGroupDetails;
}
private QuestionGroupDetail getQuestionGroupDetail(int questionGroupId, String title, String... sectionNames) {
List<SectionDetail> sectionDetails = new ArrayList<SectionDetail>();
for (String sectionName : sectionNames) {
SectionDetail sectionDetail = new SectionDetail();
sectionDetail.setName(sectionName);
sectionDetails.add(sectionDetail);
}
return new QuestionGroupDetail(questionGroupId, title, sectionDetails);
}
private QuestionGroupDetail getQuestionGroupDetail(int questionGroupId, String title,String event, String source, boolean active, boolean editable, String... sectionNames) {
List<SectionDetail> sectionDetails = new ArrayList<SectionDetail>();
for (String sectionName : sectionNames) {
SectionDetail sectionDetail = new SectionDetail();
sectionDetail.setName(sectionName);
sectionDetails.add(sectionDetail);
}
return new QuestionGroupDetail(questionGroupId, title, Arrays.asList(new EventSourceDto(event, source, null)), sectionDetails,editable,active);
}
private QuestionGroupForm getQuestionGroupForm(String title, String eventSourceId, String... sectionNames) {
QuestionGroupForm questionGroup = new QuestionGroupForm();
questionGroup.setTitle(title);
questionGroup.setEventSourceIds(Arrays.asList(eventSourceId));
for (String sectionName : sectionNames) {
questionGroup.setSectionName(sectionName);
questionGroup.addCurrentSection();
}
return questionGroup;
}
private SectionDetailForm getSectionSectionDetailForm(String sectionName, List<SectionQuestionDetail> questions) {
SectionDetailForm section = new SectionDetailForm();
section.setName(sectionName);
section.setQuestionDetails(questions);
return section;
}
private SectionQuestionDetail getSectionQuestionDetail(int id, String title) {
return new SectionQuestionDetail(new QuestionDetail(id, title, QuestionType.FREETEXT, true, true), true);
}
private QuestionDetail getQuestionDetail(int id, String title, QuestionType type) {
return new QuestionDetail(id, title, type, true, true);
}
}