Java tutorial
/* * Copyright (c) 2012 Ngewi Fet <ngewif@gmail.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.gnucash.android.test.ui; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.preference.PreferenceManager; import android.support.v4.app.Fragment; import android.test.ActivityInstrumentationTestCase2; import android.view.View; import android.widget.Spinner; import android.widget.TextView; import android.widget.ToggleButton; import com.jayway.android.robotium.solo.Solo; import org.gnucash.android.R; import org.gnucash.android.model.Account; import org.gnucash.android.model.Money; import org.gnucash.android.model.Transaction; import org.gnucash.android.db.AccountsDbAdapter; import org.gnucash.android.db.TransactionsDbAdapter; import org.gnucash.android.ui.UxArgument; import org.gnucash.android.ui.transaction.TransactionFormFragment; import org.gnucash.android.ui.transaction.TransactionsActivity; import java.text.NumberFormat; import java.text.ParseException; import java.util.Currency; import java.util.Date; import java.util.List; import java.util.Locale; import static org.fest.assertions.api.ANDROID.assertThat; public class TransactionsActivityTest extends ActivityInstrumentationTestCase2<TransactionsActivity> { private static final String TRANSACTION_AMOUNT = "9.99"; private static final String TRANSACTION_NAME = "Pizza"; private static final String DUMMY_ACCOUNT_UID = "transactions-account"; private static final String DUMMY_ACCOUNT_NAME = "Transactions Account"; private Solo mSolo; private Transaction mTransaction; private long mTransactionTimeMillis; public TransactionsActivityTest() { super(TransactionsActivity.class); } @Override protected void setUp() throws Exception { mTransactionTimeMillis = System.currentTimeMillis(); Account account = new Account(DUMMY_ACCOUNT_NAME); account.setUID(DUMMY_ACCOUNT_UID); account.setCurrency(Currency.getInstance(Locale.getDefault())); mTransaction = new Transaction(TRANSACTION_AMOUNT, TRANSACTION_NAME); mTransaction.setAccountUID(DUMMY_ACCOUNT_UID); mTransaction.setDescription("What up?"); mTransaction.setTime(mTransactionTimeMillis); account.addTransaction(mTransaction); Context context = getInstrumentation().getTargetContext(); AccountsDbAdapter adapter = new AccountsDbAdapter(context); long id = adapter.addAccount(account); adapter.close(); assertTrue(id > 0); Intent intent = new Intent(Intent.ACTION_VIEW); intent.putExtra(UxArgument.SELECTED_ACCOUNT_ID, id); setActivityIntent(intent); mSolo = new Solo(getInstrumentation(), getActivity()); } /** * Finds a view in the action bar and clicks it, since the native methods are not supported by ActionBarSherlock * @param id */ private void clickSherlockActionBarItem(int id) { View view = mSolo.getView(id); mSolo.clickOnView(view); } private void validateTransactionListDisplayed() { Fragment fragment = getActivity().getSupportFragmentManager() .findFragmentByTag(TransactionsActivity.FRAGMENT_TRANSACTIONS_LIST); assertNotNull(fragment); } private int getTranscationCount() { TransactionsDbAdapter transactionsDb = new TransactionsDbAdapter(getActivity()); int count = transactionsDb.getAllTransactionsForAccount(DUMMY_ACCOUNT_UID).size(); transactionsDb.close(); return count; } private void validateNewTransactionFields() { String expectedValue = TransactionFormFragment.DATE_FORMATTER.format(new Date(mTransactionTimeMillis)); TextView dateView = (TextView) mSolo.getView(R.id.input_date); String actualValue = dateView.getText().toString(); assertEquals(expectedValue, actualValue); expectedValue = TransactionFormFragment.TIME_FORMATTER.format(new Date(mTransactionTimeMillis)); TextView timeView = (TextView) mSolo.getView(R.id.input_time); actualValue = timeView.getText().toString(); assertEquals(expectedValue, actualValue); } public void testAddTransactionShouldRequireAmount() { mSolo.waitForText(TRANSACTION_NAME); validateTransactionListDisplayed(); TransactionsDbAdapter adapter = new TransactionsDbAdapter(getActivity()); int beforeCount = adapter.getTransactionsCount(adapter.getAccountID(DUMMY_ACCOUNT_UID)); clickSherlockActionBarItem(R.id.menu_add_transaction); mSolo.waitForText("Description"); mSolo.enterText(0, "Lunch"); clickSherlockActionBarItem(R.id.menu_save); String toastAmountRequired = getActivity().getString(R.string.toast_transanction_amount_required); boolean toastFound = mSolo.waitForText(toastAmountRequired); assertTrue(toastFound); int afterCount = adapter.getTransactionsCount(adapter.getAccountID(DUMMY_ACCOUNT_UID)); assertEquals(beforeCount, afterCount); adapter.close(); mSolo.goBack(); } private void validateEditTransactionFields(Transaction transaction) { String name = mSolo.getEditText(0).getText().toString(); assertEquals(transaction.getName(), name); String amountString = mSolo.getEditText(1).getText().toString(); NumberFormat formatter = NumberFormat.getInstance(); try { amountString = formatter.parse(amountString).toString(); } catch (ParseException e) { e.printStackTrace(); } Money amount = new Money(amountString, Currency.getInstance(Locale.getDefault()).getCurrencyCode()); assertEquals(transaction.getAmount(), amount); String description = mSolo.getEditText(2).getText().toString(); assertEquals(transaction.getDescription(), description); String expectedValue = TransactionFormFragment.DATE_FORMATTER.format(transaction.getTimeMillis()); TextView dateView = (TextView) mSolo.getView(R.id.input_date); String actualValue = dateView.getText().toString(); //mSolo.getText(6).getText().toString(); assertEquals(expectedValue, actualValue); expectedValue = TransactionFormFragment.TIME_FORMATTER.format(transaction.getTimeMillis()); TextView timeView = (TextView) mSolo.getView(R.id.input_time); actualValue = timeView.getText().toString();// mSolo.getText(7).getText().toString(); assertEquals(expectedValue, actualValue); } public void testAddTransaction() { mSolo.waitForText(TRANSACTION_NAME); // mSolo.waitForFragmentByTag(TransactionsActivity.FRAGMENT_TRANSACTIONS_LIST); validateTransactionListDisplayed(); // mSolo.clickOnActionBarItem(R.id.menu_add_transaction); clickSherlockActionBarItem(R.id.menu_add_transaction); // mSolo.waitForView(EditText.class); mSolo.waitForText("New transaction"); // validateNewTransactionFields(); //validate creation of transaction mSolo.enterText(0, "Lunch"); mSolo.enterText(1, "899"); //check that the amount is correctly converted in the input field String value = mSolo.getEditText(1).getText().toString(); String expectedValue = NumberFormat.getInstance().format(-8.99); assertEquals(expectedValue, value); int transactionsCount = getTranscationCount(); //Android 2.2 cannot handle this for some reason // mSolo.clickOnActionBarItem(R.id.menu_save); // mSolo.clickOnImage(3); clickSherlockActionBarItem(R.id.menu_save); mSolo.waitForText(DUMMY_ACCOUNT_NAME); validateTransactionListDisplayed(); assertEquals(transactionsCount + 1, getTranscationCount()); } public void testEditTransaction() { //open transactions mSolo.waitForText(DUMMY_ACCOUNT_NAME); validateTransactionListDisplayed(); mSolo.clickOnText(TRANSACTION_NAME); mSolo.waitForText("Note"); validateEditTransactionFields(mTransaction); mSolo.enterText(0, "Pasta"); clickSherlockActionBarItem(R.id.menu_save); //if we see the text, then it was successfully created mSolo.waitForText("Pasta"); } public void testDefaultTransactionType() { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); Editor editor = prefs.edit(); editor.putString(getActivity().getString(R.string.key_default_transaction_type), "CREDIT"); editor.commit(); clickSherlockActionBarItem(R.id.menu_add_transaction); mSolo.waitForText(getActivity().getString(R.string.label_transaction_name)); ToggleButton transactionTypeButton = (ToggleButton) mSolo.getButton(0); assertThat(transactionTypeButton).isNotChecked(); clickSherlockActionBarItem(R.id.menu_cancel); //now validate the other case editor = prefs.edit(); editor.putString(getActivity().getString(R.string.key_default_transaction_type), "DEBIT"); editor.commit(); clickSherlockActionBarItem(R.id.menu_add_transaction); mSolo.waitForText(getActivity().getString(R.string.label_transaction_name)); transactionTypeButton = (ToggleButton) mSolo.getButton(0); assertThat(transactionTypeButton).isChecked(); clickSherlockActionBarItem(R.id.menu_cancel); mSolo.goBack(); } public void testToggleTransactionType() { mSolo.waitForText(DUMMY_ACCOUNT_NAME); validateTransactionListDisplayed(); mSolo.clickOnText(TRANSACTION_NAME); mSolo.waitForText("Note"); validateEditTransactionFields(mTransaction); mSolo.clickOnButton(getActivity().getString(R.string.label_credit)); String amountString = mSolo.getEditText(1).getText().toString(); NumberFormat formatter = NumberFormat.getInstance(); try { amountString = formatter.parse(amountString).toString(); } catch (ParseException e) { e.printStackTrace(); } Money amount = new Money(amountString, Currency.getInstance(Locale.getDefault()).getCurrencyCode()); assertEquals("-9.99", amount.toPlainString()); clickSherlockActionBarItem(R.id.menu_save); mSolo.waitForText(DUMMY_ACCOUNT_NAME); TransactionsDbAdapter adapter = new TransactionsDbAdapter(getActivity()); List<Transaction> transactions = adapter.getAllTransactionsForAccount(DUMMY_ACCOUNT_UID); assertEquals(1, transactions.size()); Transaction trx = transactions.get(0); assertTrue(trx.getAmount().isNegative()); mSolo.goBack(); } public void testOpenTransactionEditShouldNotModifyTransaction() { mSolo.waitForText(DUMMY_ACCOUNT_NAME); validateTransactionListDisplayed(); mSolo.clickOnText(TRANSACTION_NAME); mSolo.waitForText("Edit transaction"); validateNewTransactionFields(); clickSherlockActionBarItem(R.id.menu_save); mSolo.waitForText(DUMMY_ACCOUNT_NAME); TransactionsDbAdapter adapter = new TransactionsDbAdapter(getActivity()); List<Transaction> transactions = adapter.getAllTransactionsForAccount(DUMMY_ACCOUNT_UID); assertEquals(1, transactions.size()); Transaction trx = transactions.get(0); assertEquals(TRANSACTION_NAME, trx.getName()); assertEquals(trx.getAccountUID(), DUMMY_ACCOUNT_UID); Date expectedDate = new Date(mTransactionTimeMillis); Date trxDate = new Date(trx.getTimeMillis()); assertEquals(TransactionFormFragment.DATE_FORMATTER.format(expectedDate), TransactionFormFragment.DATE_FORMATTER.format(trxDate)); assertEquals(TransactionFormFragment.TIME_FORMATTER.format(expectedDate), TransactionFormFragment.TIME_FORMATTER.format(trxDate)); //FIXME: for some reason, the expected time is higher (in the future) than the actual time //this should not be the case since the transaction was created with the expected time //I guess it has to do with the time precision and the fact that the time is repeatedly //converted to Date objects and back. But just validating the printable date and time should be ok // assertEquals(mTransactionTimeMillis, trx.getTimeMillis()); } public void testDeleteTransaction() { mSolo.waitForText(DUMMY_ACCOUNT_NAME); mSolo.clickOnCheckBox(0); clickSherlockActionBarItem(R.id.context_menu_delete); AccountsDbAdapter accountsDbAdapter = new AccountsDbAdapter(getActivity()); long id = accountsDbAdapter.getId(DUMMY_ACCOUNT_UID); TransactionsDbAdapter adapter = new TransactionsDbAdapter(getActivity()); assertEquals(0, adapter.getTransactionsCount(id)); accountsDbAdapter.close(); adapter.close(); } public void testBulkMoveTransactions() { String targetAccountName = "Target"; Account account = new Account(targetAccountName); account.setCurrency(Currency.getInstance(Locale.getDefault())); AccountsDbAdapter accountsDbAdapter = new AccountsDbAdapter(getActivity()); accountsDbAdapter.addAccount(account); int beforeOriginCount = accountsDbAdapter.getAccount(DUMMY_ACCOUNT_UID).getTransactionCount(); mSolo.waitForText(DUMMY_ACCOUNT_NAME); validateTransactionListDisplayed(); mSolo.clickOnCheckBox(0); mSolo.waitForText(getActivity().getString(R.string.title_selected, 1)); //initiate bulk move clickSherlockActionBarItem(R.id.context_menu_move_transactions); mSolo.waitForDialogToClose(2000); Spinner spinner = mSolo.getCurrentViews(Spinner.class).get(0); mSolo.clickOnView(spinner); mSolo.sleep(500); mSolo.clickOnText(targetAccountName); mSolo.clickOnButton(1); // mSolo.clickOnText(getActivity().getString(R.string.btn_move)); mSolo.waitForDialogToClose(2000); int targetCount = accountsDbAdapter.getAccount(account.getUID()).getTransactionCount(); assertEquals(1, targetCount); int afterOriginCount = accountsDbAdapter.getAccount(DUMMY_ACCOUNT_UID).getTransactionCount(); assertEquals(beforeOriginCount - 1, afterOriginCount); accountsDbAdapter.close(); } public void testIntentTransactionRecording() { TransactionsDbAdapter trxnAdapter = new TransactionsDbAdapter(getActivity()); int beforeCount = trxnAdapter.getTransactionsCount(trxnAdapter.getAccountID(DUMMY_ACCOUNT_UID)); Intent transactionIntent = new Intent(Intent.ACTION_INSERT); transactionIntent.setType(Transaction.MIME_TYPE); transactionIntent.putExtra(Intent.EXTRA_TITLE, "Power intents"); transactionIntent.putExtra(Intent.EXTRA_TEXT, "Intents for sale"); transactionIntent.putExtra(Transaction.EXTRA_AMOUNT, 4.99); transactionIntent.putExtra(Transaction.EXTRA_ACCOUNT_UID, DUMMY_ACCOUNT_UID); getActivity().sendBroadcast(transactionIntent); mSolo.sleep(2000); int afterCount = trxnAdapter.getTransactionsCount(trxnAdapter.getAccountID(DUMMY_ACCOUNT_UID)); assertEquals(beforeCount + 1, afterCount); List<Transaction> transactions = trxnAdapter.getAllTransactionsForAccount(DUMMY_ACCOUNT_UID); for (Transaction transaction : transactions) { if (transaction.getName().equals("Power intents")) { assertEquals("Intents for sale", transaction.getDescription()); assertEquals(4.99, transaction.getAmount().asDouble()); } } trxnAdapter.close(); } @Override protected void tearDown() throws Exception { AccountsDbAdapter adapter = new AccountsDbAdapter(getActivity()); adapter.deleteAllRecords(); adapter.close(); mSolo.finishOpenedActivities(); super.tearDown(); } }