/**
* Copyright (C) 2011 JTalks.org Team
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.jtalks.jcommune.web.controller;
import org.jtalks.common.model.entity.Component;
import org.jtalks.common.service.exceptions.NotFoundException;
import org.jtalks.jcommune.model.entity.PluginConfiguration;
import org.jtalks.jcommune.model.entity.PluginProperty;
import org.jtalks.jcommune.plugin.api.core.Plugin;
import org.jtalks.jcommune.plugin.api.exceptions.UnexpectedErrorException;
import org.jtalks.jcommune.service.ComponentService;
import org.jtalks.jcommune.service.PluginService;
import org.jtalks.jcommune.service.UserService;
import org.jtalks.jcommune.plugin.api.web.dto.json.JsonResponse;
import org.jtalks.jcommune.plugin.api.web.dto.json.JsonResponseStatus;
import org.jtalks.jcommune.plugin.api.dto.PluginActivatingDto;
import org.jtalks.jcommune.plugin.api.filters.NameFilter;
import org.jtalks.jcommune.plugin.api.PluginLoader;
import org.mockito.Mock;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model;
import org.springframework.web.servlet.ModelAndView;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.*;
import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.springframework.test.web.ModelAndViewAssert.assertModelAttributeAvailable;
import static org.springframework.test.web.ModelAndViewAssert.assertViewName;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
/**
* @author Anuar Nurmakanov
*/
public class PluginControllerTest {
@Mock
private PluginService pluginService;
@Mock
private ComponentService componentService;
@Mock
private PluginLoader pluginLoader;
@Mock
private UserService userService;
private PluginController pluginController;
@BeforeMethod
public void init() {
initMocks(this);
this.pluginController = new PluginController(pluginService, componentService, pluginLoader, userService);
}
@Test
public void getPluginsShouldReturnAllPlugins() {
long componentId = 25L;
Component component = new Component();
component.setId(componentId);
when(componentService.getComponentOfForum()).thenReturn(component);
List<Plugin> expectedPlugins = Arrays.asList((Plugin) new DummyPlugin(), new DummyPlugin());
when(pluginService.getPlugins(componentId)).thenReturn(expectedPlugins);
ModelAndView pluginsModelAndView = pluginController.getPlugins();
assertViewName(pluginsModelAndView, "plugin/pluginList");
assertModelAttributeAvailable(pluginsModelAndView, "plugins");
assertModelAttributeAvailable(pluginsModelAndView, "pluginsActivatingListDto");
List<Plugin> actualPlugins = (List<Plugin>) pluginsModelAndView.getModel().get("plugins");
assertEquals(actualPlugins, expectedPlugins, "Plugins should be returned from services.");
}
@Test
public void startConfiguringPluginShouldMoveToPluginConfigurationPage() throws NotFoundException {
String configuredPluginName = "plugin";
PluginConfiguration expectedConfiguration = new PluginConfiguration();
long componentId = 25L;
Component component = new Component();
component.setId(componentId);
List<Plugin> pluginList = Arrays.asList((Plugin) new DummyPlugin());
when(componentService.getComponentOfForum()).thenReturn(component);
when(pluginService.getPluginConfiguration(configuredPluginName, componentId)).thenReturn(expectedConfiguration);
when(pluginLoader.getPlugins(new NameFilter(configuredPluginName))).thenReturn(pluginList);
ModelAndView pluginConfigModelAndView = pluginController.startConfiguringPlugin(configuredPluginName);
assertViewName(pluginConfigModelAndView, "plugin/pluginConfiguration");
assertModelAttributeAvailable(pluginConfigModelAndView, "pluginConfiguration");
assertModelAttributeAvailable(pluginConfigModelAndView, "labelsTranslation");
PluginConfiguration actualPluginConfiguration = (PluginConfiguration) pluginConfigModelAndView.getModel().get("pluginConfiguration");
assertEquals(actualPluginConfiguration, expectedConfiguration, "Plugin should be returned from services.");
}
@Test(expectedExceptions = NotFoundException.class)
public void startConfiguringPluginWhenPluginWasNotFoundShouldShowNotFoundError() throws NotFoundException {
long componentId = 25L;
Component component = new Component();
component.setId(componentId);
when(componentService.getComponentOfForum()).thenReturn(component);
String nonExistPluginName = "non-exist";
when(pluginService.getPluginConfiguration(nonExistPluginName, componentId)).thenThrow(new NotFoundException());
pluginController.startConfiguringPlugin(nonExistPluginName);
}
@Test
public void updateConfigurationShouldUpdateItByCallingServiceLayer()
throws NotFoundException, UnexpectedErrorException {
long componentId = 25L;
Component component = new Component();
component.setId(componentId);
when(componentService.getComponentOfForum()).thenReturn(component);
String pluginName = "plugin";
PluginConfiguration newConfiguration = new PluginConfiguration();
newConfiguration.setName(pluginName);
Model model = new ExtendedModelMap();
ModelAndView mav = pluginController.updateConfiguration(model, newConfiguration);
assertViewName(mav, "redirect:/plugins/configure/" + pluginName);
verify(pluginService).updateConfiguration(newConfiguration, componentId);
}
@Test
public void updateConfigurationShouldReturnConfigurationPageWithErrorWhenConfigurationWasFailed()
throws NotFoundException, UnexpectedErrorException {
PluginConfiguration newConfiguration = createFailingConfiguration();
Model model = new ExtendedModelMap();
ModelAndView mav = pluginController.updateConfiguration(model, newConfiguration);
assertViewName(mav, "plugin/pluginConfiguration");
assertTrue(model.containsAttribute("pluginConfiguration"));
}
private PluginConfiguration createFailingConfiguration() throws NotFoundException, UnexpectedErrorException {
long componentId = 25L;
Component component = new Component();
component.setId(componentId);
when(componentService.getComponentOfForum()).thenReturn(component);
String pluginName = "plugin";
PluginConfiguration newConfiguration = new PluginConfiguration();
newConfiguration.setName(pluginName);
doThrow(new UnexpectedErrorException(new IllegalArgumentException("Testing exception!")))
.when(pluginService).updateConfiguration(newConfiguration, componentId);
return newConfiguration;
}
@Test
public void updateEnablingShouldUpdatePassedPlugin() throws NotFoundException {
long componentId = 25L;
Component component = new Component();
component.setId(componentId);
when(componentService.getComponentOfForum()).thenReturn(component);
PluginActivatingDto pluginActivatingDto = new PluginActivatingDto("Dummy plugin", true);
String expectedStatus = new JsonResponse(JsonResponseStatus.SUCCESS).getStatus().name();
String actualStatus = pluginController.activatePlugin(pluginActivatingDto).getStatus().name();
assertEquals(actualStatus, expectedStatus);
}
/**
* Created for tests plugin.
*/
private static final class DummyPlugin implements Plugin {
@Override
public boolean supportsJCommuneVersion(String version) {
return false;
}
@Override
public String getName() {
return null;
}
@Override
public List getConfiguration() {
return null;
}
@Override
public List<PluginProperty> getDefaultConfiguration() {
return null;
}
@Override
public void configure(PluginConfiguration configuration) {
}
@Override
public State getState() {
return null;
}
@Override
public boolean isEnabled() {
return false;
}
@Override
public String translateLabel(String code, Locale locale) {
return "translation";
}
}
}