/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2017 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.trans.steps.salesforceinput;
import com.sforce.soap.partner.sobject.SObject;
import com.sforce.ws.bind.XmlObject;
import com.sforce.ws.wsdl.Constants;
import org.apache.commons.lang.reflect.FieldUtils;
import org.eclipse.swt.widgets.Shell;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.Props;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.steps.salesforceinput.SalesforceInputMeta;
import org.pentaho.di.ui.core.PropsUI;
import javax.xml.namespace.QName;
import java.lang.reflect.Field;
import java.util.LinkedHashSet;
import java.util.Set;
import static org.junit.Assert.assertArrayEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.doNothing;
public class SalesforceInputDialogTest {
public static final String VALUE = "value";
private static boolean changedPropsUi;
private SalesforceInputDialog dialog;
@BeforeClass
public static void initKettle() throws Exception {
KettleEnvironment.init();
}
@BeforeClass
public static void hackPropsUi() throws Exception {
Field props = getPropsField();
if ( props == null ) {
throw new IllegalStateException( "Cannot find 'props' field in " + Props.class.getName() );
}
Object value = FieldUtils.readStaticField( props, true );
if ( value == null ) {
PropsUI mock = mock( PropsUI.class );
FieldUtils.writeStaticField( props, mock, true );
changedPropsUi = true;
} else {
changedPropsUi = false;
}
}
@AfterClass
public static void restoreNullInPropsUi() throws Exception {
if ( changedPropsUi ) {
Field props = getPropsField();
FieldUtils.writeStaticField( props, null, true );
}
}
private static Field getPropsField() {
return FieldUtils.getDeclaredField( Props.class, "props", true );
}
@Before
public void setUp() {
dialog = spy( new SalesforceInputDialog( mock( Shell.class ), new SalesforceInputMeta(), mock( TransMeta.class ), "SalesforceInputDialogTest" ) );
doNothing().when( dialog ).addFieldToTable( any(), any(), anyBoolean(), any(), any(), any() );
}
@Test
public void testAddFieldsFromSOQLQuery() throws Exception {
final Set<String> fields = new LinkedHashSet<>();
XmlObject testObject = createObject( "Field1", VALUE, ObjectType.XMLOBJECT );
dialog.addFields( "", fields, testObject );
dialog.addFields( "", fields, testObject );
assertArrayEquals( "No duplicates", new String[]{"Field1"}, fields.toArray() );
testObject = createObject( "Field2", VALUE, ObjectType.XMLOBJECT );
dialog.addFields( "", fields, testObject );
assertArrayEquals( "Two fields", new String[]{"Field1", "Field2"}, fields.toArray() );
}
@Test
public void testAddFields_nullIdNotAdded() throws Exception {
final Set<String> fields = new LinkedHashSet<>();
XmlObject testObject = createObject( "Id", null, ObjectType.XMLOBJECT );
dialog.addFields( "", fields, testObject );
assertArrayEquals( "Null Id field not added", new String[]{}, fields.toArray() );
}
@Test
public void testAddFields_IdAdded() throws Exception {
final Set<String> fields = new LinkedHashSet<>();
XmlObject testObject = createObject( "Id", VALUE, ObjectType.XMLOBJECT );
dialog.addFields( "", fields, testObject );
assertArrayEquals( "Id field added", new String[]{"Id"}, fields.toArray() );
}
@Test
public void testAddFields_nullRelationalIdNotAdded() throws Exception {
final Set<String> fields = new LinkedHashSet<>();
XmlObject complexObject = createObject( "Module2", null, ObjectType.SOBJECT );
complexObject.addField( "Id", createObject( "Id", null, ObjectType.XMLOBJECT ) );
dialog.addFields( "", fields, complexObject );
assertArrayEquals( "Relational null Id not added", new String[]{}, fields.toArray() );
}
@Test
public void testAddFields_relationalIdAdded() throws Exception {
final Set<String> fields = new LinkedHashSet<>();
XmlObject complexObject = createObject( "Module2", null, ObjectType.SOBJECT );
complexObject.addField( "Id", createObject( "Id", VALUE, ObjectType.XMLOBJECT ) );
complexObject.addField( "Name", createObject( "Name", VALUE, ObjectType.XMLOBJECT ) );
dialog.addFields( "", fields, complexObject );
assertArrayEquals( "Relational fields added", new String[]{"Module2.Id", "Module2.Name"}, fields.toArray() );
}
private XmlObject createObject( String fieldName, String value, ObjectType type ) {
XmlObject result;
switch ( type ) {
case SOBJECT:
result = new SObject();
break;
case XMLOBJECT:
result = new XmlObject();
break;
default:
throw new IllegalArgumentException();
}
result.setName( new QName( Constants.PARTNER_SOBJECT_NS, fieldName ) );
result.setValue( value );
return result;
}
private enum ObjectType {
SOBJECT,
XMLOBJECT
}
}