diff options
author | Oliver Bolte <obo@openoffice.org> | 2003-10-21 07:53:03 +0000 |
---|---|---|
committer | Oliver Bolte <obo@openoffice.org> | 2003-10-21 07:53:03 +0000 |
commit | bd5c37216466fb5f329a394e204287feecf88c29 (patch) | |
tree | 050d289a9484112d819745162f8834b727c1edb5 /forms/qa | |
parent | a13eb8444ad775db0aae947e24ebec3d3f89b9ce (diff) |
INTEGRATION: CWS formcelllinkage (1.1.4); FILE ADDED
2003/10/02 13:44:27 fs 1.1.4.2: some extensions while writing a integration test for #18683#
2003/10/02 07:59:50 fs 1.1.4.1: #i18994# merging the changes from the CWS fs002
Diffstat (limited to 'forms/qa')
-rw-r--r-- | forms/qa/integration/forms/FormControlTest.java | 1017 |
1 files changed, 1017 insertions, 0 deletions
diff --git a/forms/qa/integration/forms/FormControlTest.java b/forms/qa/integration/forms/FormControlTest.java new file mode 100644 index 000000000000..5468e3c66b23 --- /dev/null +++ b/forms/qa/integration/forms/FormControlTest.java @@ -0,0 +1,1017 @@ +/************************************************************************* + * + * $RCSfile: FormControlTest.java,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: obo $ $Date: 2003-10-21 08:53:03 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +package integration.forms; + +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.Any; + +import com.sun.star.container.XNameAccess; +import com.sun.star.container.XIndexContainer; +import com.sun.star.container.XIndexAccess; + +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XComponent; + +import com.sun.star.util.XCloseable; +import com.sun.star.util.URL; + +import com.sun.star.sdb.CommandType; +import com.sun.star.sdbc.XDataSource; +import com.sun.star.sdbc.XConnection; +import com.sun.star.sdbc.XResultSet; +import com.sun.star.sdbc.XResultSetUpdate; +import com.sun.star.sdbc.XStatement; +import com.sun.star.sdbcx.XTablesSupplier; + +import com.sun.star.form.XImageProducerSupplier; + +import com.sun.star.beans.XPropertySet; +import com.sun.star.beans.PropertyValue; + +import com.sun.star.frame.XComponentLoader; +import com.sun.star.frame.XDispatch; + +import com.sun.star.awt.XImageProducer; + +import com.sun.star.accessibility.XAccessible; +import com.sun.star.accessibility.XAccessibleEditableText; + +import complexlib.ComplexTestCase; +import integration.forms.dbfTools; +import integration.forms.DocumentHelper; +import integration.forms.FormLayer; + +import util.utils; +import java.util.*; +import java.io.*; +import java.lang.*; + +public class FormControlTest extends ComplexTestCase +{ + private static String s_tableName = "CTC_form_controls"; + + private XDataSource m_dataSource; + private XPropertySet m_dataSourceProps; + private XMultiServiceFactory m_orb; + private DocumentHelper m_document; + private FormLayer m_formLayer; + private XPropertySet m_masterForm; + private String m_sImageURL; + + /* ------------------------------------------------------------------ */ + public String[] getTestMethodNames() + { + return new String[] { + "checkFirstRow", + "checkInsertRow", + "checkImageControl", + "checkCrossUpdates_checkBox", + "checkCrossUpdates_radioButton", + "checkRowUpdates" + }; + } + + /* ------------------------------------------------------------------ */ + public String getTestObjectName() + { + return "Database Form Controls Test"; + } + + /* ------------------------------------------------------------------ */ + /// pre-test initialization + public void before() throws com.sun.star.uno.Exception, java.lang.Exception + { + // ensure that we have a data source to work with, and the required tables + if ( !ensureDataSource() || !ensureTables() ) + { + failed( "could not access the required data source or table therein." ); + return; + } + + // create the document which we work on + createSampleDocument(); + + createImageFile(); + } + + /* ------------------------------------------------------------------ */ + public void checkFirstRow() throws com.sun.star.uno.Exception, java.lang.Exception + { + moveToFirst(); + + // and check the content of the various controls + if ( !checkRadios( (short)1, (short)0, (short)0 ) + || !checkDoubleValue( 1, "ID", "Value" ) + || !checkDoubleValue( 42, "f_integer", "EffectiveValue" ) + || !checkStringValue( "the answer", "f_text", "Text" ) + || !checkDoubleValue( 0.12, "f_decimal", "Value" ) + || !checkIntValue ( 20030922, "f_date", "Date" ) + || !checkIntValue ( 15000000, "f_time", "Time" ) + || !checkIntValue ( 20030923, "f_timestamp_date", "Date" ) + || !checkIntValue ( 17152300, "f_timestamp_time", "Time" ) + || !checkShortValue ( (short)1, "f_tinyint", "State" ) + ) + { + failed( "checking the content of one or more controls on the first row failed (see the log for details)" ); + return; + } + } + + /* ------------------------------------------------------------------ */ + public void checkInsertRow() throws com.sun.star.uno.Exception, java.lang.Exception + { + // move the cursor to the insert row + moveToInsertRow(); + + // and check the content of the various controls + if ( !verifyCleanInsertRow() ) + { + failed( "checking the content of one or more controls on the insert row failed (see the log for details)" ); + return; + } + } + + /* ------------------------------------------------------------------ */ + /// some tests with the image control + public void checkImageControl() throws com.sun.star.uno.Exception, java.lang.Exception + { + // since we did not yet insert any image, the control should not display one ... + moveToFirst(); + if ( !verifyReferenceImage( new byte[0] ) ) + { + failed( "image control failed to display empty image" ); + return; + } + + // check if the image control is able to insert our sample image into the database + // insert an + XPropertySet xImageModel = getControlModel( "f_blob" ); + xImageModel.setPropertyValue( "ImageURL", m_sImageURL ); + + if ( !verifyReferenceImage( getSamplePictureBytes() ) ) + { + failed( "image control does not display the sample image as required" ); + return; + } + + // save the record + saveRecordByUI(); + + // still needs to be the sample image + if ( !verifyReferenceImage( getSamplePictureBytes() ) ) + { + failed( "image control does not, after saving the record, display the sample image as required" ); + return; + } + + // on the next record, the image should be empty + moveToNext(); + if ( !verifyReferenceImage( new byte[0] ) ) + { + failed( "image control failed to display empty image, after coming from a non-empty image" ); + return; + } + + // back to the record where we just inserted the image, it should be our sample image + moveToFirst(); + if ( !verifyReferenceImage( getSamplePictureBytes() ) ) + { + failed( "image control does not, after coming back to the record, display the sample image as required" ); + return; + } + + // okay, now remove the image + xImageModel.setPropertyValue( "ImageURL", new String() ); + if ( !verifyReferenceImage( new byte[0] ) ) + { + failed( "image control failed to remove the image" ); + return; + } + nextRecordByUI(); + previousRecordByUI(); + if ( !verifyReferenceImage( new byte[0] ) ) + { + failed( "image still there after coming back, though we just removed it" ); + return; + } + } + + /* ------------------------------------------------------------------ */ + /** This is both a test for controls which are bound to the same column (they must reflect + * each others updates), and for the immediate updates which need to happen for both check + * boxes and radio buttons: They must commit their content to the underlying column as soon + * as the change is made, *not* only upon explicit commit + */ + public void checkCrossUpdates_checkBox() throws com.sun.star.uno.Exception, java.lang.Exception + { + // move to the first record + moveToFirst(); + if ( !checkShortValue ( (short)1, "f_tinyint", "State" ) + || !checkDoubleValue( 1, "f_tinyint_format", "EffectiveValue" ) + ) + { + failed( "huh? inconsistence in the test!" ); + // we created the sample data in a way that the f_tinyint field should contain a "1" at the first + // record. We already asserted the proper function of the check box in checkFirstRow, so if this + // fails here, the script became inconsistent + return; + } + + XPropertySet checkModel = getControlModel( "f_tinyint" ); + checkModel.setPropertyValue( "State", new Short( (short)0 ) ); + + // setting the state of the check box needs to be reflected in the formatted field immediately + if ( !checkDoubleValue( 0, "f_tinyint_format", "EffectiveValue" ) ) + { + failed( "cross-update failed: updating the check box should result in updating the same-bound formatted field (1)!" ); + return; + } + + // same for the "indetermined" state of the check box + checkModel.setPropertyValue( "State", new Short( (short)2 ) ); + if ( !checkNullValue( "f_tinyint_format", "EffectiveValue" ) ) + { + failed( "cross-update failed: updating the check box should result in updating the same-bound formatted field (2)!" ); + return; + } + + // undo the changes done so far + undoRecordByUI(); + // and see if this is properly reflected in the controls + if ( !checkShortValue ( (short)1, "f_tinyint", "State" ) + || !checkDoubleValue( 1, "f_tinyint_format", "EffectiveValue" ) + ) + { + failed( "either the check box or the formatted field failed to recognize the UNDO!" ); + return; + } + + // the other way round - when changing the formatted field - the change should *not* + // be reflected to the check box, since the formatted field needs an explicit commit + XPropertySet tinyFormattedModel = getControlModel( "f_tinyint_format" ); + m_document.getCurrentView().grabControlFocus( tinyFormattedModel ); + userTextInput( tinyFormattedModel, "0", false ); + if ( !checkShortValue ( (short)1, "f_tinyint", "State" ) + ) + { + failed( "the check box should not be updated here! (did the formatted model commit immediately?)" ); + return; + } + + // set the focus to *any* other control (since we just have it at hand, we use the check box control) + // this should result in the formatted control being committed, and thus in the check box updating + m_document.getCurrentView().grabControlFocus( checkModel ); + if ( !checkShortValue ( (short)0, "f_tinyint", "State" ) + ) + { + failed( "formatted field did not commit (or check box did not update)" ); + return; + } + + // undo the changes done so far, so we leave the document in a clean state for the next test + undoRecordByUI(); + } + + /* ------------------------------------------------------------------ */ + /** very similar to checkCrossUpdates_checkBox - does nearly the same for the radio buttons. See there for more + * explanations. + */ + public void checkCrossUpdates_radioButton() throws com.sun.star.uno.Exception, java.lang.Exception + { + // move to the first record + moveToFirst(); + if ( !checkRadios( (short)1, (short)0, (short)0 ) + || !checkStringValue( "none", "f_text_enum_text", "Text" ) + ) + { + failed( "huh? inconsistence in the test!" ); + return; + } + + XPropertySet radioModel = getRadioModel( "radio_group", "normal" ); + radioModel.setPropertyValue( "State", new Short( (short)1 ) ); + + // setting the state of the radio button needs to be reflected in the formatted field immediately + if ( !checkStringValue( "normal", "f_text_enum_text", "Text" ) ) + { + failed( "cross-update failed: updating the radio button should result in updating the same-bound text field (1)!" ); + return; + } + + // same for the "indetermined" state of the check box + getRadioModel( "radio_group", "important" ).setPropertyValue( "State", new Short( (short)1 ) ); + if ( !checkStringValue( "important", "f_text_enum_text", "Text" ) ) + { + failed( "cross-update failed: updating the radio button should result in updating the same-bound text field (2)!" ); + return; + } + + // undo the changes done so far + undoRecordByUI(); + // and see if this is properly reflected in the controls + if ( !checkRadios( (short)1, (short)0, (short)0 ) + || !checkStringValue( "none", "f_text_enum_text", "Text" ) + ) + { + failed( "either the radio button or the text field failed to recognize the UNDO!" ); + return; + } + + // the other way round - when changing the formatted field - the change should *not* + // be reflected to the check box, since the formatted field needs an explicit commit + XPropertySet textModel = getControlModel( "f_text_enum_text" ); + m_document.getCurrentView().grabControlFocus( textModel ); + userTextInput( textModel, "normal", false ); + if ( !checkRadios( (short)1, (short)0, (short)0 ) + ) + { + failed( "the radio buttons should not be updated here! (did the formatted model commit immediately?)" ); + return; + } + + // set the focus to *any* other control (since we just have it at hand, we use the check box control) + // this should result in the formatted control being committed, and thus in the check box updating + m_document.getCurrentView().grabControlFocus( radioModel ); + if ( !checkRadios( (short)0, (short)1, (short)0 ) + ) + { + failed( "text field did not commit (or radio button did not update)" ); + return; + } + + // undo the changes done so far, so we leave the document in a clean state for the next test + undoRecordByUI(); + } + + /* ------------------------------------------------------------------ */ + /** some tests with updating the table via our controls + */ + public void checkRowUpdates() throws com.sun.star.uno.Exception, java.lang.Exception + { + // start with inserting a new record + moveToInsertRow(); + if ( !verifyCleanInsertRow() ) + { + failed( "insert row not in expected clean state" ); + return; + } + + userTextInput( "ID", "3", true ); + userTextInput( "f_integer", "729", true ); + userTextInput( "f_text", "test", true ); + userTextInput( "f_decimal", "152343", true ); + userTextInput( "f_date", "31.12.1999", true ); + userTextInput( "f_time", "23:59:59", true ); + + // move to the next row, this should automatically commit the changes we made + nextRecordByUI(); + // and back to the row we just inserted + previousRecordByUI(); + + if ( !checkDoubleValue( 3, "ID", "Value" ) + || !checkDoubleValue( 729, "f_integer", "EffectiveValue" ) + || !checkStringValue( "test", "f_text", "Text" ) + || !checkDoubleValue( 152343, "f_decimal", "Value" ) + || !checkIntValue ( 19991231, "f_date", "Date" ) + || !checkIntValue ( 23595900, "f_time", "Time" ) + ) + { + failed( "the changes we made on the insert row have not been committed" ); + return; + } + + // now change the data, to see if regular updates work, too + userTextInput( "ID", "4", true ); + userTextInput( "f_integer", "618", true ); + userTextInput( "f_text", "yet another stupid, meaningless text", true ); + userTextInput( "f_decimal", "4562", true ); + userTextInput( "f_date", "26.03.2004", true ); + userTextInput( "f_time", "17:05:00", true ); + + // move to the next row, this should automatically commit the changes we made + nextRecordByUI(); + // and back to the row we just inserted + previousRecordByUI(); + + if ( !checkDoubleValue( 4, "ID", "Value" ) + || !checkDoubleValue( 618, "f_integer", "EffectiveValue" ) + || !checkStringValue( "yet another stupid, meaningless text", "f_text", "Text" ) + || !checkDoubleValue( 4562, "f_decimal", "Value" ) + || !checkIntValue ( 20040326, "f_date", "Date" ) + || !checkIntValue ( 17050000, "f_time", "Time" ) + ) + { + failed( "the changes we made on the insert row have not been committed" ); + return; + } + + m_document.getCurrentView().grabControlFocus( getControlModel( "ID" ) ); + } + + /* ------------------------------------------------------------------ */ + private boolean verifyCleanInsertRow( ) throws com.sun.star.uno.Exception, java.lang.Exception + { + // and check the content of the various controls + return ( checkRadios( (short)0, (short)0, (short)0 ) + && checkShortValue( (short)2, "f_tinyint", "State" ) + && checkStringValue( "", "f_text", "Text" ) + && checkNullValue( "ID", "Value" ) + && checkNullValue( "f_integer", "EffectiveValue" ) + && checkNullValue( "f_decimal", "Value" ) + ); + } + + /* ------------------------------------------------------------------ */ + /// post-test cleanup + public void after() throws com.sun.star.uno.Exception, java.lang.Exception + { + // close our document + if ( m_document != null ) + { + XCloseable closeDoc = (XCloseable)UnoRuntime.queryInterface( XCloseable.class, + m_document.getDocument() ); + closeDoc.close( true ); + } + } + + //========================================================================= + /* ------------------------------------------------------------------ */ + private boolean ensureDataSource() throws com.sun.star.uno.Exception + { + m_orb = (XMultiServiceFactory)param.getMSF(); + + XNameAccess aDSContext = (XNameAccess)UnoRuntime.queryInterface( XNameAccess.class, + m_orb.createInstance( "com.sun.star.sdb.DatabaseContext" ) ); + + String sDataSourceName = (String)param.get( "datasource" ); + if ( null == sDataSourceName ) + sDataSourceName = "FormControlTest"; + if ( !aDSContext.hasByName( sDataSourceName ) ) + { + log.println( "\n" ); + log.println( "There is no data source named '" + sDataSourceName + "'\n" ); + log.println( "You need to create a data source in your office installation, pointing" ); + log.println( "to a database (preferably MySQL, other types not tested so far)" ); + log.println( "which this test should work with.\n" ); + log.println( "The test will automatically create and populate a sample table in this" ); + log.println( "data source.\n" ); + log.println( "Unless specified otherwise in the FormControlTest.props, the expected" ); + log.println( "name of the data source is \"FormControlTest\".\n\n" ); + return false; + } + log.println( "using data source " + sDataSourceName ); + + m_dataSource = (XDataSource)UnoRuntime.queryInterface( XDataSource.class, + aDSContext.getByName( sDataSourceName ) ); + m_dataSourceProps = dbfTools.queryXPropertySet( m_dataSource ); + return m_dataSource != null; + } + + /* ------------------------------------------------------------------ */ + /** retrives the control model with the given name + */ + private XPropertySet getControlModel( String name ) throws com.sun.star.uno.Exception, java.lang.Exception + { + XNameAccess nameAccess = (XNameAccess)UnoRuntime.queryInterface( XNameAccess.class, + m_masterForm ); + return (XPropertySet)UnoRuntime.queryInterface( XPropertySet.class, + nameAccess.getByName( name ) ); + } + + /* ------------------------------------------------------------------ */ + private void createSampleDocument() throws com.sun.star.uno.Exception, java.lang.Exception + { + // °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° + m_document = DocumentHelper.blankTextDocument( m_orb ); + m_formLayer = new FormLayer( m_document ); + + // insert some controls + XPropertySet xIDField = m_formLayer.insertControlLine( "DatabaseNumericField", "ID", "", 3 ); + m_formLayer.insertControlLine( "DatabaseFormattedField","f_integer", "", 11 ); + m_formLayer.insertControlLine( "DatabaseTextField", "f_text", "", 19 ); + XPropertySet xDecField = m_formLayer.insertControlLine( "DatabaseNumericField", "f_decimal", "", 27 ); + m_formLayer.insertControlLine( "DatabaseDateField", "f_date", "", 35 ); + XPropertySet xTimeField = m_formLayer.insertControlLine( "DatabaseTimeField", "f_time", "", 43 ); + m_formLayer.insertControlLine( "DatabaseDateField", "f_timestamp", "_date", 51 ); + m_formLayer.insertControlLine( "DatabaseTimeField", "f_timestamp", "_time", 59 ); + XPropertySet xImageField = m_formLayer.insertControlLine( "DatabaseImageControl", "f_blob", "", 2, 67, 40 ); + m_formLayer.insertControlLine( "DatabaseTextField", "f_text_enum", "_text", 80, 25, 6 ); + XPropertySet xCheckBox = m_formLayer.insertControlLine( "DatabaseCheckBox", "f_tinyint", "", 80, 33, 6 ); + m_formLayer.insertControlLine( "DatabaseFormattedField","f_tinyint", "_format",80, 41, 6 ); + m_formLayer.insertControlLine( "DatabaseTextField", "dummy", "", 150 ); + + xIDField.setPropertyValue( "DecimalAccuracy", new Short( (short)0 ) ); + xImageField.setPropertyValue( "ScaleImage", new Boolean( (boolean)true) ); + xImageField.setPropertyValue( "Tabstop", new Boolean( true) ); + xCheckBox.setPropertyValue( "TriState", new Boolean( true ) ); + xCheckBox.setPropertyValue( "DefaultState", new Short( (short)2 ) ); + xTimeField.setPropertyValue( "TimeFormat", new Short( (short)1 ) ); + xTimeField.setPropertyValue( "TimeMax", new Integer( 23595999 ) ); + + // the logical form + m_masterForm = (XPropertySet)dbfTools.getParent( xIDField, XPropertySet.class ); + m_masterForm.setPropertyValue( "DataSourceName", m_dataSourceProps.getPropertyValue( "Name" ) ); + m_masterForm.setPropertyValue( "CommandType", new Integer( CommandType.TABLE ) ); + m_masterForm.setPropertyValue( "Command", s_tableName ); + + insertRadio( 3, "none", "none" ); + insertRadio( 10, "normal", "normal" ); + insertRadio( 17, "important", "important" ); + + // switch the forms into data entry mode + m_document.getCurrentView( ).toggleFormDesignMode( ); + + // set the focus to the ID control + m_document.getCurrentView().grabControlFocus( xIDField ); + } + + /* ------------------------------------------------------------------ */ + private void insertRadio( int nYPos, String label, String refValue ) throws com.sun.star.uno.Exception, java.lang.Exception + { + XPropertySet xRadio = m_formLayer.createControlAndShape( "DatabaseRadioButton", 106, nYPos, 25, 6 ); + xRadio.setPropertyValue( "Label", label ); + xRadio.setPropertyValue( "RefValue", refValue ); + xRadio.setPropertyValue( "Name", new String( "radio_group" ) ); + xRadio.setPropertyValue( "DataField", new String( "f_text_enum" ) ); + } + + /* ------------------------------------------------------------------ */ + private String getCreateTableStatement( ) + { + String sCreateTableStatement = "CREATE TABLE CTC_form_controls ("; + sCreateTableStatement += "ID int(11) NOT NULL default '0',"; + sCreateTableStatement += "f_integer int(11) default NULL,"; + sCreateTableStatement += "f_text varchar(50) default NULL,"; + sCreateTableStatement += "f_decimal decimal(10,2) default NULL,"; + sCreateTableStatement += "f_date date default NULL,"; + sCreateTableStatement += "f_time time default NULL,"; + sCreateTableStatement += "f_timestamp datetime default NULL,"; + sCreateTableStatement += "f_blob blob,"; + sCreateTableStatement += "f_text_enum varchar(50) default NULL,"; + sCreateTableStatement += "f_tinyint tinyint(4) default NULL,"; + sCreateTableStatement += "PRIMARY KEY (ID)"; + sCreateTableStatement += ") TYPE=MyISAM;"; + return sCreateTableStatement; + } + + /* ------------------------------------------------------------------ */ + private String[] getSampleDataValueString( ) throws java.lang.Exception + { + String[] aValues = new String[] { + "1,42,'the answer',0.12,'2003-09-22','15:00:00','2003-09-23 17:15:23',NULL,'none',1", + "2,13,'the question',12.43,'2003-09-24','16:18:00','2003-09-24 08:45:12',NULL,'none',0" + }; + return aValues; + } + + /* ------------------------------------------------------------------ */ + private boolean ensureTables() throws com.sun.star.uno.Exception, java.lang.Exception + { + // conenct to the data source + String user = (String)param.get( "user" ); + if ( ( user == null ) || ( user.length() == 0 ) ) + { + user = (String)m_dataSourceProps.getPropertyValue( "User" ); + if ( user.length() == 0 ) + user = "testtool"; + } + + String password = (String)param.get( "password" ); + boolean needPasswordOverride = true; + + if ( ( password == null ) || ( password.length() == 0 ) ) + { + password = (String)m_dataSourceProps.getPropertyValue( "Password" ); + if ( password.length() == 0 ) + password = "testtool"; + else + needPasswordOverride = false; + } + + XConnection xConn = m_dataSource.getConnection( user, password ); + if ( xConn == null ) + { + failed( "could not connect to the data source, authenticating with '" + user + "'/'**********'" ); + return false; + } + if ( ( user.length() == 0 ) && ( password.length() == 0 ) ) + log.println( "connected to the data source" ); + else + log.println( "connected to the data source, authenticated with '" + user + "'/'**********'" ); + + // if we successfully connected, remember the password. Later on, when the form document is switched + // to alive mode, this is needed, since we unfortunately have no chance to pass the password to the + // form to use when connecting + if ( needPasswordOverride ) + { + m_dataSourceProps.setPropertyValue( "User", user ); + m_dataSourceProps.setPropertyValue( "Password", password ); + } + + // drop the table, if it already exists + if ( !implExecuteStatement( xConn, "DROP TABLE IF EXISTS CTC_form_controls" ) + || !implExecuteStatement( xConn, getCreateTableStatement() ) + ) + { + failed( "could not create the required sample table!" ); + return false; + } + + String sInsertionPrefix = "INSERT INTO CTC_form_controls VALUES ("; + String[] aValues = getSampleDataValueString(); + for ( int i=0; i<aValues.length; ++i ) + if ( !implExecuteStatement( xConn, sInsertionPrefix + aValues[ i ] + ")" ) ) + { + failed( "could not create the required sample data" ); + return false; + } + + XTablesSupplier xSuppTables = (XTablesSupplier)UnoRuntime.queryInterface( XTablesSupplier.class, + xConn ); + XNameAccess xTables = xSuppTables.getTables(); + + if ( !xTables.hasByName( s_tableName ) ) + { + String sNewTableName = (String)param.get( "TablePrefix" ); + sNewTableName += '.' + s_tableName; + if ( !xTables.hasByName( sNewTableName ) ) + { + failed( "could not find the table " + s_tableName ); + return false; + } + s_tableName = sNewTableName; + } + + // do not need the connection anymore + dbfTools.disposeComponent( xConn ); + + return true; + } + + /* ------------------------------------------------------------------ */ + /// checks the 3 radio buttons for the given states + private boolean checkRadios( short stateNone, short stateNormal, short stateImportant ) throws com.sun.star.uno.Exception, java.lang.Exception + { + if ( ((Short)getRadioModel( "radio_group", "none" ).getPropertyValue( "State" )).shortValue() != stateNone ) + { + failed( "wrong value of the 'none' radio button!" ); + } + else if ( ((Short)getRadioModel( "radio_group", "normal" ).getPropertyValue( "State" )).shortValue() != stateNormal ) + { + failed( "wrong value of the 'normal' radio button!" ); + } + else if ( ((Short)getRadioModel( "radio_group", "important" ).getPropertyValue( "State" )).shortValue() != stateImportant ) + { + failed( "wrong value of the 'important' radio button!" ); + } + else + return true; + + return false; + } + + /* ------------------------------------------------------------------ */ + private boolean checkNullValue( String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception + { + Object value = getControlModel( fieldName ).getPropertyValue( propertyName ); + if ( !util.utils.isVoid( value ) ) + { + log.println( "wrong value of the " + fieldName + " field!" ); + log.println( " expected: <null/>" ); + log.println( " found : " + value.toString() ); + } + else + return true; + + return false; + } + + /* ------------------------------------------------------------------ */ + private boolean checkIntValue( int requiredValue, String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception + { + try + { + int currentValue = ((Integer)getControlModel( fieldName ).getPropertyValue( propertyName )).intValue(); + if ( currentValue != requiredValue ) + { + log.println( "wrong value of the " + fieldName + " field!" ); + log.println( " expected: " + String.valueOf( requiredValue ) ); + log.println( " found : " + String.valueOf( currentValue ) ); + } + else + return true; + } + catch( com.sun.star.uno.Exception e ) + { + log.println( "caught an exception while retrieving property value '" + propertyName + "' of control model '" + fieldName + "'" ); + throw e; + } + + return false; + } + + /* ------------------------------------------------------------------ */ + private boolean checkShortValue( short requiredValue, String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception + { + try + { + short currentValue = ((Short)getControlModel( fieldName ).getPropertyValue( propertyName )).shortValue(); + if ( currentValue != requiredValue ) + { + log.println( "wrong value of the " + fieldName + " field!" ); + log.println( " expected: " + String.valueOf( requiredValue ) ); + log.println( " found : " + String.valueOf( currentValue ) ); + } + else + return true; + } + catch( com.sun.star.uno.Exception e ) + { + log.println( "caught an exception while retrieving property value '" + propertyName + "' of control model '" + fieldName + "'" ); + throw e; + } + + return false; + } + + /* ------------------------------------------------------------------ */ + private boolean checkDoubleValue( double requiredValue, String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception + { + double currentValue = ((Double)getControlModel( fieldName ).getPropertyValue( propertyName )).doubleValue(); + if ( currentValue != requiredValue ) + { + log.println( "wrong value of the " + fieldName + " field!" ); + log.println( " expected: " + String.valueOf( requiredValue ) ); + log.println( " found : " + String.valueOf( currentValue ) ); + } + else + return true; + + return false; + } + + /* ------------------------------------------------------------------ */ + private boolean checkStringValue( String requiredValue, String fieldName, String propertyName ) throws com.sun.star.uno.Exception, java.lang.Exception + { + String currentValue = (String)getControlModel( fieldName ).getPropertyValue( propertyName ); + if ( !currentValue.equals( requiredValue ) ) + { + log.println( "wrong value of the " + fieldName + " field!" ); + log.println( " expected: " + requiredValue ); + log.println( " found : " + currentValue ); + } + else + return true; + + return false; + } + + /* ------------------------------------------------------------------ */ + private XPropertySet getRadioModel( String name, String refValue ) throws com.sun.star.uno.Exception, java.lang.Exception + { + return m_formLayer.getRadioModel( m_masterForm, name, refValue ); + } + + /* ------------------------------------------------------------------ */ + /** executes the given statement on the given connection + */ + protected boolean implExecuteStatement( XConnection xConn, String sStatement ) throws java.lang.Exception + { + try + { + XStatement xStatement = xConn.createStatement( ); + xStatement.execute( sStatement ); + } + catch(com.sun.star.sdbc.SQLException e) + { + System.err.println( e ); + return false; + } + + return true; + } + + /* ------------------------------------------------------------------ */ + /** simulates a user's text input into a control given by model name + */ + private void userTextInput( String modelName, String text, boolean withCommit ) throws com.sun.star.uno.Exception, java.lang.Exception + { + userTextInput( getControlModel( modelName ), text, withCommit ); + } + + /* ------------------------------------------------------------------ */ + /** simulates a user's text input into a control given by control model + */ + private void userTextInput( XPropertySet controlModel, String text, boolean withCommit ) throws com.sun.star.uno.Exception, java.lang.Exception + { + // the form runtime environment (namely the form controller) rely on focus events for recognizing + // control content changes ... + if ( withCommit ) + m_document.getCurrentView().grabControlFocus( controlModel ); + + // we will *not* simply set the value property at the model. This is not the same as + // doing a user input, as the latter will trigger a lot of notifications, which the forms runtime environment + // (namely the FormController) relies on to notice that the control changed. + // Instead, we use the Accessibility interfaces of the control to simulate text input + XAccessible formattedAccessible = (XAccessible)UnoRuntime.queryInterface( XAccessible.class, + m_document.getCurrentView().getControl( controlModel ) + ); + XAccessibleEditableText textAccess = (XAccessibleEditableText)UnoRuntime.queryInterface( XAccessibleEditableText.class, + formattedAccessible.getAccessibleContext() ); + textAccess.setText( text ); + + // focus back to a dummy control model so the content of the model we just changed will + // be committed to the underlying database column + if ( withCommit ) + m_document.getCurrentView().grabControlFocus( getControlModel( "dummy" ) ); + } + + /* ------------------------------------------------------------------ */ + private void moveToInsertRow() throws com.sun.star.uno.Exception, java.lang.Exception + { + XResultSetUpdate xResultSet = (XResultSetUpdate)UnoRuntime.queryInterface( XResultSetUpdate.class, m_masterForm ); + xResultSet.moveToInsertRow( ); + } + + /* ------------------------------------------------------------------ */ + private void moveToFirst() throws com.sun.star.uno.Exception, java.lang.Exception + { + XResultSet xResultSet = (XResultSet)UnoRuntime.queryInterface( XResultSet.class, m_masterForm ); + xResultSet.first( ); + } + + /* ------------------------------------------------------------------ */ + private void moveToNext() throws com.sun.star.uno.Exception, java.lang.Exception + { + XResultSet xResultSet = (XResultSet)UnoRuntime.queryInterface( XResultSet.class, m_masterForm ); + xResultSet.next( ); + } + + /* ------------------------------------------------------------------ */ + /** simulates pressing a toolbox button with the given URL + */ + private void executeSlot( String slotURL ) throws java.lang.Exception + { + XDispatch xDispatch = (XDispatch)m_document.getCurrentView().getDispatcher( slotURL ); + PropertyValue[] aArgs = new PropertyValue[0]; + URL url = new URL(); + url.Complete = slotURL; + xDispatch.dispatch( url, aArgs ); + } + + /* ------------------------------------------------------------------ */ + /** undos the changes on the current record, by simulating pressing of the respective toolbox button + */ + private void undoRecordByUI() throws java.lang.Exception + { + executeSlot( ".uno:RecUndo" ); + } + + /* ------------------------------------------------------------------ */ + /** saves the current record, by simulating pressing of the respective toolbox button + */ + private void saveRecordByUI() throws java.lang.Exception + { + executeSlot( ".uno:RecSave" ); + } + + /* ------------------------------------------------------------------ */ + /** moves to the next record, by simulating pressing of the respective toolbox button + */ + private void nextRecordByUI() throws java.lang.Exception + { + executeSlot( ".uno:NextRecord" ); + } + /* ------------------------------------------------------------------ */ + /** moves to the previous record, by simulating pressing of the respective toolbox button + */ + private void previousRecordByUI() throws java.lang.Exception + { + executeSlot( ".uno:PrevRecord" ); + } + + /* ------------------------------------------------------------------ */ + private void createImageFile() throws java.io.IOException + { + m_sImageURL = util.utils.getOfficeTempDir( m_orb ) + "image.gif"; + + FileOutputStream aFile = new FileOutputStream( m_sImageURL ); + aFile.write( getSamplePicture() ); + aFile.close(); + log.println( "created temporary image file: " + m_sImageURL ); + + // for later setting the url at the imaghe control, we need a real URL, no system path + m_sImageURL = util.utils.getOfficeTemp( m_orb ) + "image.gif"; + } + + /* ------------------------------------------------------------------ */ + private byte[] getSamplePicture() + { + byte[] aBytes = new byte[] { + (byte)0x47, (byte)0x49, (byte)0x46, (byte)0x38, (byte)0x39, (byte)0x61, (byte)0x0A, (byte)0x00, (byte)0x0A, (byte)0x00, (byte)0xB3, (byte)0x00, (byte)0x00, (byte)0xFF, (byte)0x00, (byte)0x00, + (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0x00, (byte)0x00, (byte)0xFF, (byte)0xFF, (byte)0x00, (byte)0xFF, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xFF, (byte)0xFF, + (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, + (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0x2C, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x0A, (byte)0x00, (byte)0x0A, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x20, (byte)0x10, (byte)0xC8, (byte)0x49, (byte)0x41, (byte)0xB9, (byte)0xF8, (byte)0xCA, + (byte)0x12, (byte)0xBA, (byte)0x2F, (byte)0x5B, (byte)0x30, (byte)0x8C, (byte)0x43, (byte)0x00, (byte)0x5A, (byte)0x22, (byte)0x41, (byte)0x94, (byte)0x27, (byte)0x37, (byte)0xA8, (byte)0x6C, + (byte)0x48, (byte)0xC6, (byte)0xA8, (byte)0xD7, (byte)0xB5, (byte)0x19, (byte)0x56, (byte)0xED, (byte)0x11, (byte)0x00, (byte)0x3B + }; + + return aBytes; + } + + private byte[] getSamplePictureBytes() + { + byte[] aBytes = new byte[] { + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x05, (byte)0x05, (byte)0x05, (byte)0x05, + (byte)0x05, (byte)0x05, (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x05, + (byte)0x01, (byte)0x03, (byte)0x03, (byte)0x03, (byte)0x03, (byte)0x01, (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x01, (byte)0x03, (byte)0x04, (byte)0x04, (byte)0x03, (byte)0x01, + (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x01, (byte)0x03, (byte)0x04, (byte)0x04, (byte)0x03, (byte)0x01, (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x01, (byte)0x03, + (byte)0x03, (byte)0x03, (byte)0x03, (byte)0x01, (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x05, (byte)0x00, + (byte)0x00, (byte)0x05, (byte)0x05, (byte)0x05, (byte)0x05, (byte)0x05, (byte)0x05, (byte)0x05, (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 + }; + return aBytes; + } + + /* ------------------------------------------------------------------ */ + private boolean verifyReferenceImage( byte[] referenceBytes ) throws com.sun.star.uno.Exception, java.lang.Exception + { + XPropertySet xImageModel = getControlModel( "f_blob" ); + + // check if the image control properly says that there currently is no image on the first record + XImageProducerSupplier xSuppProducer = (XImageProducerSupplier)UnoRuntime.queryInterface( XImageProducerSupplier.class, + xImageModel ); + XImageProducer xProducer = xSuppProducer.getImageProducer(); + + ImageComparison compareImages = new ImageComparison( referenceBytes, this ); + synchronized( this ) + { + xProducer.addConsumer( compareImages ); + xProducer.startProduction(); + wait(); + } + xProducer.removeConsumer( compareImages ); + + return compareImages.imagesEqual( ); + } + +} |