/*! ****************************************************************************** * * 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.trans.steps.salesforce; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Random; import com.sforce.soap.partner.sobject.SObject; import com.sforce.ws.wsdl.Constants; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.Mockito; import org.pentaho.di.core.Const; import org.pentaho.di.core.encryption.Encr; import org.pentaho.di.core.encryption.TwoWayPasswordEncoderPluginType; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.logging.LogChannel; import org.pentaho.di.core.logging.LogChannelInterface; import org.pentaho.di.core.plugins.PluginRegistry; import org.pentaho.di.core.util.EnvUtil; import com.sforce.soap.partner.Connector; import com.sforce.soap.partner.PartnerConnection; import com.sforce.ws.ConnectionException; import com.sforce.ws.ConnectorConfig; import com.sforce.ws.bind.XmlObject; import javax.xml.namespace.QName; public class SalesforceConnectionTest { private LogChannelInterface logInterface = mock( LogChannelInterface.class ); private String url = "url"; private String username = "username"; private String password = "password"; private int recordsFilter = 0; @BeforeClass public static void setUpClass() throws KettleException { PluginRegistry.addPluginType( TwoWayPasswordEncoderPluginType.getInstance() ); PluginRegistry.init(); String passwordEncoderPluginID = Const.NVL( EnvUtil.getSystemProperty( Const.KETTLE_PASSWORD_ENCODER_PLUGIN ), "Kettle" ); Encr.init( passwordEncoderPluginID ); } @Test public void testConstructor_emptyUrl() throws KettleException { try { new SalesforceConnection( logInterface, null, username, password ); fail(); } catch ( KettleException expected ) { // OK } } @Test public void testConstructor_emptyUserName() throws KettleException { try { new SalesforceConnection( logInterface, url, null, password ); fail(); } catch ( KettleException expected ) { // OK } } @Test public void testSetCalendarStartNull() throws KettleException { SalesforceConnection connection = new SalesforceConnection( logInterface, url, username, password ); GregorianCalendar endDate = new GregorianCalendar( 2000, 2, 10 ); try { connection.setCalendar( recordsFilter, null, endDate ); fail(); } catch ( KettleException expected ) { // OK } } @Test public void testSetCalendarEndNull() throws KettleException { SalesforceConnection connection = new SalesforceConnection( logInterface, url, username, password ); GregorianCalendar startDate = new GregorianCalendar( 2000, 2, 10 ); try { connection.setCalendar( recordsFilter, startDate, null ); fail(); } catch ( KettleException expected ) { // OK } } @Test public void testSetCalendarStartDateTooOlder() throws KettleException { SalesforceConnection connection = new SalesforceConnection( logInterface, url, username, password ); GregorianCalendar startDate = new GregorianCalendar( 2000, 3, 20 ); GregorianCalendar endDate = new GregorianCalendar( 2000, 2, 10 ); try { connection.setCalendar( recordsFilter, startDate, endDate ); fail(); } catch ( KettleException expected ) { // OK } } @Test public void testSetCalendarDatesTooFarApart() throws KettleException { SalesforceConnection connection = new SalesforceConnection( logInterface, url, username, password ); GregorianCalendar startDate = new GregorianCalendar( 2000, 1, 1 ); GregorianCalendar endDate = new GregorianCalendar( 2000, 2, 11 ); try { connection.setCalendar( recordsFilter, startDate, endDate ); fail(); } catch ( KettleException expected ) { // OK } } @Test public void testConstructor() { SalesforceConnection conn; // Test all-invalid parameters try { conn = null; conn = new SalesforceConnection( null, null, null, null ); fail(); } catch ( KettleException expected ) { // Ignore, expected result } // Test null Log Interface try { conn = null; conn = new SalesforceConnection( null, "http://localhost:1234", "anonymous", "mypwd" ); assertTrue( conn.getURL().length() > 0 ); assertTrue( conn.getUsername().length() > 0 ); assertTrue( conn.getPassword().length() > 0 ); } catch ( KettleException e ) { fail(); } // Test valid Log Interface try { conn = null; conn = new SalesforceConnection( new LogChannel( this ), "http://localhost:1234", "anonymous", "mypwd" ); assertTrue( conn.getURL().length() > 0 ); assertTrue( conn.getUsername().length() > 0 ); assertTrue( conn.getPassword().length() > 0 ); } catch ( KettleException e ) { fail(); } // Test missing target URL (should fail) try { conn = null; conn = new SalesforceConnection( null, null, "anonymous", "mypwd" ); fail(); } catch ( KettleException expected ) { // Ignore, expected result } // Test missing username (should fail) try { conn = null; conn = new SalesforceConnection( null, "http://localhost:1234", null, "mypwd" ); fail(); } catch ( KettleException expected ) { // Ignore, expected result } // Test missing password (should fail) try { conn = null; conn = new SalesforceConnection( null, "http://localhost:1234", "anonymous", null ); assertTrue( conn.getURL().length() > 0 ); assertEquals( "anonymous", conn.getUsername() ); } catch ( KettleException e ) { fail(); } } @Test public void testSetCalendar() { SalesforceConnection conn = mock( SalesforceConnection.class, Mockito.CALLS_REAL_METHODS ); // Test valid data try { conn.setCalendar( new Random().nextInt( SalesforceConnectionUtils.recordsFilterDesc.length ), new GregorianCalendar( 2016, Calendar.JANUARY, 1 ), new GregorianCalendar( 2016, Calendar.JANUARY, 31 ) ); // No errors detected } catch ( KettleException e ) { fail(); } // Test reversed dates (should fail) try { conn.setCalendar( new Random().nextInt( SalesforceConnectionUtils.recordsFilterDesc.length ), new GregorianCalendar( 2016, Calendar.JANUARY, 31 ), new GregorianCalendar( 2016, Calendar.JANUARY, 1 ) ); fail(); } catch ( KettleException expected ) { // Ignore, expected result } // Test null start date (should fail) try { conn.setCalendar( new Random().nextInt( SalesforceConnectionUtils.recordsFilterDesc.length ), null, new GregorianCalendar( 2016, Calendar.JANUARY, 31 ) ); fail(); } catch ( KettleException expected ) { // Ignore, expected result } // Test null end date (should fail) try { conn.setCalendar( new Random().nextInt( SalesforceConnectionUtils.recordsFilterDesc.length ), new GregorianCalendar( 2016, Calendar.JANUARY, 1 ), null ); fail(); } catch ( KettleException expected ) { // Ignore, expected result } } @Test public void testMessageElements() throws Exception { XmlObject me = SalesforceConnection.fromTemplateElement( "myName", 123, false ); assertNotNull( me ); assertEquals( "myName", me.getName().getLocalPart() ); assertNull( me.getValue() ); me = null; me = SalesforceConnection.fromTemplateElement( "myName", 123, true ); assertNotNull( me ); assertEquals( "myName", me.getName().getLocalPart() ); assertEquals( 123, me.getValue() ); me = null; me = SalesforceConnection.createMessageElement( "myName", 123, false ); assertNotNull( me ); assertEquals( "myName", me.getName().getLocalPart() ); assertEquals( 123, me.getValue() ); me = null; try { me = SalesforceConnection.createMessageElement( "myName", 123, true ); fail(); } catch ( Exception expected ) { // Ignore, name was expected to have a colon ':' } me = null; try { me = SalesforceConnection.createMessageElement( "myType:Name", "123", true ); assertNotNull( me ); assertEquals( "Name", me.getName().getLocalPart() ); assertEquals( "myType", me.getField( "type" ) ); assertEquals( "123", me.getField( "Name" ) ); } catch ( Exception expected ) { fail(); } me = null; try { me = SalesforceConnection.createMessageElement( "myType:Name/MyLookupField", 123, true ); assertNotNull( me ); assertEquals( "MyLookupField", me.getName().getLocalPart() ); //assertEquals( "myType", me.getField( "type" ) ); assertEquals( 123, me.getField( "Name" ) ); } catch ( Exception expected ) { fail(); } } @Test public void testCreateBinding() throws KettleException, ConnectionException { SalesforceConnection conn = new SalesforceConnection( null, "http://localhost:1234", "aUser", "aPass" ); ConnectorConfig config = new ConnectorConfig(); config.setAuthEndpoint( Connector.END_POINT ); config.setManualLogin( true ); // Required to prevent connection attempt during test assertNull( conn.getBinding() ); conn.createBinding( config ); PartnerConnection binding1 = conn.getBinding(); conn.createBinding( config ); PartnerConnection binding2 = conn.getBinding(); assertSame( binding1, binding2 ); } @Test //PDI-15973 public void testGetRecordValue() throws Exception { //PDI-15973 SalesforceConnection conn = mock( SalesforceConnection.class, Mockito.CALLS_REAL_METHODS ); SObject sObject = new SObject(); sObject.setName( new QName( Constants.PARTNER_SOBJECT_NS, "sObject" ) ); SObject testObject = createObject( "field", "value" ); sObject.addField( "field", testObject ); assertEquals( "Get value of simple record", "value", conn.getRecordValue( sObject, "field" ) ); SObject parentObject = createObject( "parentField", null ); sObject.addField( "parentField", parentObject ); SObject childObject = createObject( "subField", "subValue" ); parentObject.addField( "subField", childObject ); assertEquals( "Get value of record with hierarchy", "subValue", conn.getRecordValue( sObject, "parentField.subField" ) ); XmlObject nullObject = new XmlObject( new QName( "nullField" ) ); sObject.addField( "nullField", nullObject ); assertEquals( "Get null value when relational query id is null", null, conn.getRecordValue( sObject, "nullField.childField" ) ); } private SObject createObject( String fieldName, String value ) { SObject result = new SObject(); result.setName( new QName( Constants.PARTNER_SOBJECT_NS, fieldName ) ); result.setValue( value ); return result; } }