/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2015 by Pentaho : http://www.pentaho.com * ******************************************************************************* * * 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. * ******************************************************************************/ package org.pentaho.di.ui.repository.repositoryexplorer.controllers; import org.apache.commons.lang.reflect.FieldUtils; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.pentaho.di.core.KettleEnvironment; import org.pentaho.di.core.ProgressMonitorListener; import org.pentaho.di.core.database.DatabaseMeta; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.repository.Repository; import org.pentaho.di.repository.StringObjectId; import org.pentaho.di.ui.core.database.dialog.DatabaseDialog; import org.pentaho.di.ui.repository.repositoryexplorer.model.UIDatabaseConnection; import org.pentaho.ui.xul.containers.XulTree; import java.util.List; import static java.util.Collections.singletonList; import static org.mockito.Mockito.*; /** * @author Andrey Khayrutdinov */ public class ConnectionsControllerTest { @BeforeClass public static void initKettle() throws Exception { KettleEnvironment.init(); } private ConnectionsController controller; private DatabaseDialog databaseDialog; private Repository repository; private XulTree connectionsTable; @Before public void setUp() throws Exception { // a tricky initialisation - first inject private fields controller = new ConnectionsController(); connectionsTable = mock( XulTree.class ); FieldUtils.writeDeclaredField( controller, "connectionsTable", connectionsTable, true ); // and then spy the controller controller = spy( controller ); databaseDialog = mock( DatabaseDialog.class ); doReturn( databaseDialog ).when( controller ).getDatabaseDialog(); doNothing().when( controller ).refreshConnectionList(); doNothing().when( controller ).showAlreadyExistsMessage(); repository = mock( Repository.class ); controller.init( repository ); } @Test public void createConnection_NullName() throws Exception { testEditConnectionGetsWrongName( null ); } @Test public void createConnection_EmptyName() throws Exception { testEditConnectionGetsWrongName( "" ); } @Test public void createConnection_BlankName() throws Exception { testCreateConnectionGetsWrongName( " " ); } private void testCreateConnectionGetsWrongName( String wrongName ) throws Exception { when( databaseDialog.open() ).thenReturn( wrongName ); controller.createConnection(); assertRepositoryWasNotAccessed(); } private void assertRepositoryWasNotAccessed() throws KettleException { verify( repository, never() ).getDatabaseID( anyString() ); assertSaveWasNotInvoked(); } @Test public void createConnection_NameExists() throws Exception { final String dbName = "name"; when( databaseDialog.open() ).thenReturn( dbName ); when( repository.getDatabaseID( dbName ) ).thenReturn( new StringObjectId( "existing" ) ); controller.createConnection(); assertShowedAlreadyExistsMessage(); } @Test public void createConnection_NewName() throws Exception { final String dbName = "name"; when( databaseDialog.open() ).thenReturn( dbName ); when( databaseDialog.getDatabaseMeta() ).thenReturn( new DatabaseMeta() ); when( repository.getDatabaseID( dbName ) ).thenReturn( null ); controller.createConnection(); assertRepositorySavedDb(); } @Test public void editConnection_NullName() throws Exception { testEditConnectionGetsWrongName( null ); } @Test public void editConnection_EmptyName() throws Exception { testEditConnectionGetsWrongName( "" ); } @Test public void editConnection_BlankName() throws Exception { testEditConnectionGetsWrongName( " " ); } private void testEditConnectionGetsWrongName( String wrongName ) throws Exception { final String dbName = "name"; List<UIDatabaseConnection> selectedConnection = createSelectedConnectionList( dbName ); when( connectionsTable.<UIDatabaseConnection>getSelectedItems() ).thenReturn( selectedConnection ); when( repository.getDatabaseID( dbName ) ).thenReturn( new StringObjectId( "existing" ) ); when( databaseDialog.open() ).thenReturn( wrongName ); controller.editConnection(); assertSaveWasNotInvoked(); } @Test public void editConnection_NameExists_Same() throws Exception { final String dbName = "name"; List<UIDatabaseConnection> selectedConnection = createSelectedConnectionList( dbName ); when( connectionsTable.<UIDatabaseConnection>getSelectedItems() ).thenReturn( selectedConnection ); when( repository.getDatabaseID( dbName ) ).thenReturn( new StringObjectId( "existing" ) ); when( databaseDialog.open() ).thenReturn( dbName ); controller.editConnection(); assertRepositorySavedDb(); } @Test public void editConnection_NameDoesNotExist() throws Exception { final String dbName = "name"; List<UIDatabaseConnection> selectedConnection = createSelectedConnectionList( dbName ); when( connectionsTable.<UIDatabaseConnection>getSelectedItems() ).thenReturn( selectedConnection ); when( repository.getDatabaseID( dbName ) ).thenReturn( new StringObjectId( "existing" ) ); when( databaseDialog.open() ).thenReturn( "non-existing-name" ); controller.editConnection(); assertRepositorySavedDb(); } @Test public void editConnection_NameExists_Different() throws Exception { final String dbName = "name"; List<UIDatabaseConnection> selectedConnection = createSelectedConnectionList( dbName ); when( connectionsTable.<UIDatabaseConnection>getSelectedItems() ).thenReturn( selectedConnection ); final String anotherName = "anotherName"; when( repository.getDatabaseID( dbName ) ).thenReturn( new StringObjectId( "existing" ) ); when( repository.getDatabaseID( anotherName ) ).thenReturn( new StringObjectId( "another-existing" ) ); when( databaseDialog.open() ).thenReturn( anotherName ); controller.editConnection(); assertShowedAlreadyExistsMessage(); } private List<UIDatabaseConnection> createSelectedConnectionList( String selectedDbName ) { DatabaseMeta meta = new DatabaseMeta(); meta.setName( selectedDbName ); return singletonList( new UIDatabaseConnection( meta, repository ) ); } private void assertSaveWasNotInvoked() throws KettleException { verify( repository, never() ).save( any( DatabaseMeta.class ), anyString(), any( ProgressMonitorListener.class ) ); } private void assertShowedAlreadyExistsMessage() throws KettleException { assertSaveWasNotInvoked(); // instead the error dialog was shown verify( controller ).showAlreadyExistsMessage(); } private void assertRepositorySavedDb() throws KettleException { // repository.save() was invoked verify( repository ).save( any( DatabaseMeta.class ), anyString(), any( ProgressMonitorListener.class ) ); } }