[engine] Add first-class online_id accessors for Split and Account

Promote the OFX/HBCI online_id to named engine accessors:
  xaccSplitGetOnlineID / SetOnlineID / HasOnlineID
  xaccAccountGetOnlineID / SetOnlineID
The getters return an instance-owned const char* (mirroring
xaccTransGetDocLink / xaccTransGetNotes), so the existing
add_methods_with_prefix auto-wrapper exposes them in the Python bindings
with no .i changes and no %newobject.  They write to the same engine KVP
slot ("online_id") the desktop importer uses, so there is no data or
behavior change.

With the accessors in place the gnc_import_*_online_id wrappers in
import-utilities are redundant, so replace every call site (OFX,
AqBanking, and the generic matcher/backend) with them, delete
import-utilities.cpp, and drop the online_id declarations from
import-utilities.h (its importer preference-key macros are retained).

- The engine getters return an instance-owned const char* instead of a
  g_strdup'd copy, so callers no longer free the result; the affected
  locals are retyped const and their g_free()s dropped.
  hash_account_online_ids() g_strdups before inserting, since its hash
  table owns its keys (g_free key-destructor).
- xaccAccountSetOnlineID(acc, "") clears the slot, matching the OFX
  "delete the online_id" intent (the old wrapper stored an empty string).
- Drop the two unused wrappers: gnc_import_set_trans_online_id (marked
  "Not actually used") and gnc_import_trans_has_online_id (no callers).
- Add xaccSplitGet/SetOnlineID to the Split gmock so test-import-backend
  links without import-utilities.
This commit is contained in:
Noah R committed 2026-06-21 16:43:03 -07:00
1 parent 222714d764
commit 3e98c5d8c8
19 files changed
+191 -201

No files matched your search

+9
View File
@@ -17,6 +17,15 @@ class TestAccount(AccountSession):
self.account.SetName(NAME)
self.assertEqual( NAME, self.account.GetName() )
def test_online_id(self):
ONLINE_ID = "061000104:0123456789:CHECKING"
self.assertEqual( None, self.account.GetOnlineID() )
self.account.SetOnlineID(ONLINE_ID)
self.assertEqual( ONLINE_ID, self.account.GetOnlineID() )
# Passing None (or "") clears it.
self.account.SetOnlineID(None)
self.assertEqual( None, self.account.GetOnlineID() )
def test_split(self):
SPLIT = Split(self.book)
self.assertTrue(self.account.insert_split(SPLIT))
+13
View File
@@ -21,6 +21,19 @@ class TestSplit(SplitSession):
self.split.SetMemo(MEMO)
self.assertEqual( MEMO, self.split.GetMemo() )
def test_online_id(self):
FITID = "20240131-0001-1234567890"
# Unset online_id reads back as None (no KVP slot present).
self.assertEqual( None, self.split.GetOnlineID() )
self.assertFalse( self.split.HasOnlineID() )
self.split.SetOnlineID(FITID)
self.assertEqual( FITID, self.split.GetOnlineID() )
self.assertTrue( self.split.HasOnlineID() )
# Passing "" (or None) clears it.
self.split.SetOnlineID("")
self.assertEqual( None, self.split.GetOnlineID() )
self.assertFalse( self.split.HasOnlineID() )
def test_account(self):
ACCT = Account(self.book)
ACCT.SetCommodity(self.currency)
-1
View File
@@ -20,7 +20,6 @@ set (generic_import_SOURCES
import-format-dialog.cpp
import-match-picker.cpp
import-parse.cpp
import-utilities.cpp
import-settings.cpp
import-main-matcher.cpp
import-pending-matches.cpp
@@ -63,7 +63,6 @@
#include "gnc-ui-util.h"
#include "gnc-session.h"
#include "import-account-matcher.h"
#include "import-utilities.h"
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = GNC_MOD_ASSISTANT;
@@ -684,7 +683,7 @@ save_kvp_acc_cb(gpointer key, gpointer value, gpointer user_data)
const gchar *ab_accountid, *gnc_accountid;
const gchar *ab_bankcode, *gnc_bankcode;
gchar *ab_online_id;
gchar *gnc_online_id;
const gchar *gnc_online_id;
g_return_if_fail(ab_acc && gnc_acc);
@@ -707,11 +706,10 @@ save_kvp_acc_cb(gpointer key, gpointer value, gpointer user_data)
gnc_ab_set_account_bankcode(gnc_acc, ab_bankcode);
ab_online_id = gnc_ab_create_online_id(ab_bankcode, ab_accountid);
gnc_online_id = gnc_import_get_acc_online_id(gnc_acc);
gnc_online_id = xaccAccountGetOnlineID(gnc_acc);
if (ab_online_id && (!gnc_online_id || (strcmp(ab_online_id, gnc_online_id) != 0)))
gnc_import_set_acc_online_id(gnc_acc, ab_online_id);
xaccAccountSetOnlineID(gnc_acc, ab_online_id);
g_free(ab_online_id);
g_free (gnc_online_id);
}
static void
+1 -2
View File
@@ -49,7 +49,6 @@
#include "gnc-ui.h"
#include "import-account-matcher.h"
#include "import-main-matcher.h"
#include "import-utilities.h"
#include "qof.h"
#include "engine-helpers.h"
#include <aqbanking/gui/abgui.h>
@@ -569,7 +568,7 @@ gnc_ab_trans_to_gnc (const AB_TRANSACTION *ab_trans, Account *gnc_acc)
/* Set OFX unique transaction ID */
if (fitid && *fitid)
gnc_import_set_split_online_id (split, fitid);
xaccSplitSetOnlineID (split, fitid);
/* FIXME: Extract function */
{
@@ -34,7 +34,6 @@
#include <glib/gi18n.h>
#include "import-account-matcher.h"
#include "import-utilities.h"
#include "dialog-account.h"
#include "dialog-utils.h"
@@ -70,15 +69,11 @@ typedef struct
static gpointer test_acct_online_id_match(Account *acct, gpointer data)
{
AccountOnlineMatch *match = (AccountOnlineMatch*)data;
char *acct_online_id = gnc_import_get_acc_online_id(acct);
const char *acct_online_id = xaccAccountGetOnlineID(acct);
int acct_len, match_len;
if (acct_online_id == NULL || match->online_id == NULL)
{
if (acct_online_id)
g_free (acct_online_id);
return NULL;
}
acct_len = strlen(acct_online_id);
match_len = strlen(match->online_id);
@@ -91,10 +86,7 @@ static gpointer test_acct_online_id_match(Account *acct, gpointer data)
if (strncmp (acct_online_id, match->online_id, acct_len) == 0)
{
if (strncmp(acct_online_id, match->online_id, match_len) == 0)
{
g_free (acct_online_id);
return (gpointer *) acct;
}
if (match->partial_match == NULL)
{
match->partial_match = acct;
@@ -102,8 +94,8 @@ static gpointer test_acct_online_id_match(Account *acct, gpointer data)
}
else
{
char *partial_online_id =
gnc_import_get_acc_online_id(match->partial_match);
const char *partial_online_id =
xaccAccountGetOnlineID(match->partial_match);
int partial_len = strlen(partial_online_id);
if (partial_online_id[partial_len - 1] == ' ')
--partial_len;
@@ -133,11 +125,9 @@ static gpointer test_acct_online_id_match(Account *acct, gpointer data)
g_free (name1);
g_free (name2);
}
g_free (partial_online_id);
}
}
g_free (acct_online_id);
return NULL;
}
@@ -469,7 +459,7 @@ Account * gnc_import_select_account(GtkWidget *parent,
if (account_online_id_value)
{
gnc_import_set_acc_online_id(retval, account_online_id_value);
xaccAccountSetOnlineID(retval, account_online_id_value);
}
ok_pressed_retval = TRUE;
break;
+5 -8
View File
@@ -861,11 +861,9 @@ process_reconcile(Account *base_acc,
/* Copy the online id to the reconciled transaction, so
* the match will be remembered */
auto online_id = gnc_import_get_split_online_id(trans_info->first_split);
auto online_id = xaccSplitGetOnlineID(trans_info->first_split);
if (online_id && *online_id)
gnc_import_set_split_online_id(selected_match->split, online_id);
g_free (online_id);
xaccSplitSetOnlineID(selected_match->split, online_id);
/* Done editing. */
/*DEBUG("CommitEdit selected_match")*/
@@ -1040,9 +1038,9 @@ hash_account_online_ids (Account *account)
(g_str_hash, g_str_equal, g_free, nullptr);
for (auto split : xaccAccountGetSplits (account))
{
auto id = gnc_import_get_split_online_id (split);
auto id = xaccSplitGetOnlineID (split);
if (id && *id)
g_hash_table_insert (acct_hash, (void*) id, GINT_TO_POINTER (1));
g_hash_table_insert (acct_hash, (void*) g_strdup (id), GINT_TO_POINTER (1));
}
return acct_hash;
}
@@ -1056,7 +1054,7 @@ gboolean gnc_import_exists_online_id (Transaction *trans, GHashTable* acct_id_ha
auto source_split = xaccTransGetSplit(trans, 0);
g_assert(source_split);
auto source_online_id = gnc_import_get_split_online_id (source_split);
auto source_online_id = xaccSplitGetOnlineID (source_split);
// No online id, no point in continuing. We'd crash if we tried.
if (!source_online_id)
@@ -1081,7 +1079,6 @@ gboolean gnc_import_exists_online_id (Transaction *trans, GHashTable* acct_id_ha
DEBUG("Transaction with online ID %s already exists, date: %s", source_online_id, date_str);
g_free (date_str);
}
g_free (source_online_id);
return online_id_exists;
}
@@ -2360,7 +2360,7 @@ create_hash_of_potential_matches (GList *candidate_splits,
candidate = g_list_next (candidate))
{
auto split = static_cast<Split*>(candidate->data);
if (gnc_import_split_has_online_id (split))
if (xaccSplitHasOnlineID (split))
continue;
/* In this context an open transaction represents a freshly
* downloaded one. That can't possibly be a match yet */
-116
View File
@@ -1,116 +0,0 @@
/********************************************************************\
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License*
* along with this program; if not, contact: *
* *
* Free Software Foundation Voice: +1-617-542-5942 *
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
* Boston, MA 02110-1301, USA gnu@gnu.org *
\********************************************************************/
/** @addtogroup Import_Export
@{ */
/** @internal
@file import-utilities.c
@brief Utility functions for writing import modules.
@author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
*/
#include <config.h>
#include <glib.h>
#include <stdlib.h>
#include "import-utilities.h"
#include "qof.h"
#include "Account.h"
#include "Transaction.h"
/********************************************************************\
* Setter and getter functions for the online_id kvp frame in
* Account, Transaction and Split
\********************************************************************/
gchar *
gnc_import_get_acc_online_id (Account * account)
{
gchar *id = NULL;
qof_instance_get (QOF_INSTANCE (account), "online-id", &id, NULL);
return id;
}
/* Used in the midst of editing a transaction; make it save the
* account data. */
void
gnc_import_set_acc_online_id (Account *account, const gchar *id)
{
g_return_if_fail (account != NULL);
xaccAccountBeginEdit (account);
qof_instance_set (QOF_INSTANCE (account), "online-id", id, NULL);
xaccAccountCommitEdit (account);
}
gchar *
gnc_import_get_trans_online_id (Transaction * transaction)
{
gchar *id = NULL;
qof_instance_get (QOF_INSTANCE (transaction), "online-id", &id, NULL);
return id;
}
/* Not actually used */
void
gnc_import_set_trans_online_id (Transaction *transaction, const gchar *id)
{
g_return_if_fail (transaction != NULL);
xaccTransBeginEdit (transaction);
qof_instance_set (QOF_INSTANCE (transaction), "online-id", id, NULL);
xaccTransCommitEdit (transaction);
}
gboolean
gnc_import_trans_has_online_id (Transaction * transaction)
{
gchar *online_id = gnc_import_get_trans_online_id(transaction);
gboolean retval = (online_id && *online_id);
g_free (online_id);
return retval;
}
gchar *
gnc_import_get_split_online_id (Split * split)
{
gchar *id = NULL;
qof_instance_get (QOF_INSTANCE (split), "online-id", &id, NULL);
return id;
}
/* Used several places in a transaction edit where many other
* parameters are also being set, so individual commits wouldn't be
* appropriate. Besides, there isn't a function for one.*/
void
gnc_import_set_split_online_id (Split *split, const gchar *id)
{
g_return_if_fail (split != NULL);
qof_instance_set (QOF_INSTANCE (split), "online-id", id, NULL);
}
gboolean
gnc_import_split_has_online_id (Split * split)
{
gchar *online_id = gnc_import_get_split_online_id(split);
gboolean retval = (online_id && *online_id);
g_free (online_id);
return retval;
}
/* @} */
+1 -46
View File
@@ -19,7 +19,7 @@
/** @addtogroup Import_Export
@{ */
/** @file import-utilities.h
@brief Utility functions for writing import modules.
@brief Preference keys for the generic importer.
@author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
*/
#ifndef IMPORT_UTILITIES_H
@@ -40,50 +40,5 @@
#include "Account.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** @name Setter-getters
Setter and getter functions for the online_id field for
Accounts.
@{
*/
gchar * gnc_import_get_acc_online_id(Account * account);
void gnc_import_set_acc_online_id(Account * account,
const gchar * string_value);
/** @} */
/** @name Setter-getters
Setter and getter functions for the online_id field for
Transactions.
@{
*/
gchar * gnc_import_get_trans_online_id(Transaction * transaction);
void gnc_import_set_trans_online_id(Transaction * transaction,
const gchar * string_value);
/** @} */
gboolean gnc_import_trans_has_online_id(Transaction * transaction);
/** @name Setter-getters
Setter and getter functions for the online_id field for
Splits.
@{
*/
gchar * gnc_import_get_split_online_id(Split * split);
void gnc_import_set_split_online_id(Split * split,
const gchar * string_value);
/** @} */
gboolean gnc_import_split_has_online_id(Split * split);
#ifdef __cplusplus
}
#endif
#endif
/** @} */
+5 -7
View File
@@ -592,8 +592,7 @@ process_bank_transaction(Transaction *transaction, Account *import_account,
}
if (data->fi_id_valid)
{
gnc_import_set_split_online_id(split,
sanitize_string (data->fi_id));
xaccSplitSetOnlineID(split, sanitize_string (data->fi_id));
}
}
@@ -618,7 +617,7 @@ create_investment_subaccount(GtkWindow *parent, Account* parent_acct,
ACCT_TYPE_STOCK);
if (investment_account)
{
gnc_import_set_acc_online_id(investment_account, inv_data->online_id);
xaccAccountSetOnlineID(investment_account, inv_data->online_id);
inv_data->choosing = FALSE;
ofx_parent_account = parent_acct;
}
@@ -644,7 +643,7 @@ continue_account_selection(GtkWidget* parent, Account* account,
gnc_commodity_get_fullname(commodity),
gnc_commodity_get_fullname(xaccAccountGetCommodity(account)));
// We must also delete the online_id that was set in gnc_import_select_account()
gnc_import_set_acc_online_id(account, "");
xaccAccountSetOnlineID(account, "");
return keep_going;
}
@@ -815,8 +814,7 @@ add_investment_split(Transaction* transaction, Account* account,
xaccAccountTypesCompatible(xaccAccountGetType(account),
ACCT_TYPE_ASSET))
{
gnc_import_set_split_online_id(split,
sanitize_string (data->fi_id));
xaccSplitSetOnlineID(split, sanitize_string (data->fi_id));
}
}
@@ -837,7 +835,7 @@ add_currency_split(Transaction *transaction, Account* account,
// Set split memo from ofx transaction name or memo
gnc_ofx_set_split_memo(data, split);
if (data->fi_id_valid)
gnc_import_set_split_online_id (split, sanitize_string (data->fi_id));
xaccSplitSetOnlineID (split, sanitize_string (data->fi_id));
}
/* ******** Process an investment transaction **********/
@@ -59,7 +59,6 @@ set(gtest_import_backend_SOURCES
gtest-import-backend.cpp
${CMAKE_SOURCE_DIR}/gnucash/import-export/import-backend.cpp
${CMAKE_SOURCE_DIR}/gnucash/import-export/import-settings.cpp
${CMAKE_SOURCE_DIR}/gnucash/import-export/import-utilities.cpp
${CMAKE_SOURCE_DIR}/libgnucash/engine/mocks/gmock-qofinstance.cpp
${CMAKE_SOURCE_DIR}/libgnucash/app-utils/mocks/gmock-gnc-prefs.cpp
${CMAKE_SOURCE_DIR}/libgnucash/engine/mocks/gmock-qofbook.cpp
+14
View File
@@ -2638,6 +2638,13 @@ xaccAccountSetNotes (Account *acc, const char *str)
set_kvp_string_path (acc, {"notes"}, str);
}
void
xaccAccountSetOnlineID (Account *acc, const char *id)
{
g_return_if_fail (GNC_IS_ACCOUNT(acc));
set_kvp_string_path (acc, {KEY_ONLINE_ID}, id);
}
void
xaccAccountSetAssociatedAccount (Account *acc, const char *tag, const Account* assoc_acct)
@@ -3350,6 +3357,13 @@ xaccAccountGetNotes (const Account *acc)
return get_kvp_string_path (acc, {"notes"});
}
const char *
xaccAccountGetOnlineID (const Account *acc)
{
g_return_val_if_fail (GNC_IS_ACCOUNT(acc), nullptr);
return get_kvp_string_path (acc, {KEY_ONLINE_ID});
}
Account*
xaccAccountGetAssociatedAccount (const Account *acc, const char *tag)
{
+13
View File
@@ -317,6 +317,14 @@ typedef enum
/** Set the account's notes */
void xaccAccountSetNotes (Account *account, const char *notes);
/** Set the account's online_id, the identifier (e.g. an OFX/HBCI
* BANKID+ACCTID composite) of the online account this GnuCash account
* is mapped to for bank imports. This is the same value (engine KVP
* slot "online_id") that the desktop OFX/HBCI importer uses to match a
* downloaded statement to its GnuCash account. Passing NULL or ""
* clears it. Wraps its own begin/commit edit. */
void xaccAccountSetOnlineID (Account *account, const char *id);
/** Set the account's associated account e.g. stock account -> dividend account */
void xaccAccountSetAssociatedAccount (Account *acc, const char *tag,
const Account *assoc_acct);
@@ -426,6 +434,11 @@ typedef enum
/** Get the account's notes */
const char * xaccAccountGetNotes (const Account *account);
/** Get the account's online_id (see xaccAccountSetOnlineID). The
* returned string is owned by the account and must NOT be freed;
* returns NULL if no online_id is set. */
const char * xaccAccountGetOnlineID (const Account *account);
/** Get the account's associated account e.g. stock account -> dividend account */
Account* xaccAccountGetAssociatedAccount (const Account *acc, const char *tag);
/** Get the last num field of an Account */
+30
View File
@@ -101,6 +101,7 @@ enum
static const char * split_type_normal = "normal";
static const char * split_type_stock_split = "stock-split";
static const char * split_online_id = "online_id";
/* GObject Initialization */
G_DEFINE_TYPE(Split, gnc_split, QOF_TYPE_INSTANCE)
@@ -1901,6 +1902,35 @@ xaccSplitGetMemo (const Split *split)
return split ? split->memo : nullptr;
}
void
xaccSplitSetOnlineID (Split *split, const char *id)
{
if (!split) return;
/* No xaccTransBeginEdit/CommitEdit here: the online_id is normally set
* while many other parameters of a transaction are being changed, so
* the caller wraps this in the parent transaction's edit. */
std::optional<const char*> val;
if (id && *id)
val = g_strdup (id);
qof_instance_set_path_kvp<const char*> (QOF_INSTANCE(split), val, {split_online_id});
qof_instance_set_dirty (QOF_INSTANCE(split));
}
const char *
xaccSplitGetOnlineID (const Split *split)
{
if (!split) return nullptr;
auto rv{qof_instance_get_path_kvp<const char*> (QOF_INSTANCE(split), {split_online_id})};
return rv ? *rv : nullptr;
}
gboolean
xaccSplitHasOnlineID (const Split *split)
{
auto id = xaccSplitGetOnlineID (split);
return (id && *id);
}
const char *
xaccSplitGetAction (const Split *split)
{
+19
View File
@@ -160,6 +160,25 @@ void xaccSplitSetMemo (Split *split, const char *memo);
/** Returns the memo string. */
const char * xaccSplitGetMemo (const Split *split);
/** The online_id is the OFX/HBCI "FITID" recorded on a split when it is
* imported. It is used to recognise the split on re-import so that
* overlapping or re-downloaded statements don't create duplicates. This
* is the same value (engine KVP slot "online_id") that the desktop
* OFX/HBCI importer reads and writes.
*
* The setter only changes engine data: call it inside the parent
* transaction's edit (xaccTransBeginEdit()/xaccTransCommitEdit()), and a
* session save persists it. Passing NULL or "" clears the online_id. */
void xaccSplitSetOnlineID (Split *split, const char *id);
/** Returns the split's online_id. The returned string is owned by the
* split and must NOT be freed; it is valid until the online_id is changed
* or the split is destroyed. Returns NULL if no online_id is set. */
const char * xaccSplitGetOnlineID (const Split *split);
/** Returns TRUE if the split has a non-empty online_id. */
gboolean xaccSplitHasOnlineID (const Split *split);
/** The Action is an arbitrary user-assigned string.
* The action field is an arbitrary user-assigned value.
* It is meant to be a very short (one to ten character) string that
+15
View File
@@ -110,6 +110,21 @@ xaccSplitSetMemo (Split *split, const char *memo)
gnc_mocksplit(split)->set_memo(memo);
}
const char *
xaccSplitGetOnlineID (const Split *split)
{
SCOPED_TRACE("");
auto mocksplit = gnc_mocksplit(split);
return mocksplit ? mocksplit->get_online_id() : nullptr;
}
void
xaccSplitSetOnlineID (Split *split, const char *id)
{
ASSERT_TRUE(GNC_IS_MOCKSPLIT(split));
gnc_mocksplit(split)->set_online_id(id);
}
char
xaccSplitGetReconcile (const Split *split)
{
+2
View File
@@ -73,6 +73,8 @@ public:
MOCK_METHOD1(set_value, void(gnc_numeric));
MOCK_CONST_METHOD0(get_memo, const char *());
MOCK_METHOD1(set_memo, void(const char *));
MOCK_CONST_METHOD0(get_online_id, const char *());
MOCK_METHOD1(set_online_id, void(const char *));
MOCK_CONST_METHOD0(get_reconcile, char());
MOCK_METHOD1(set_reconcile, void(char));
MOCK_METHOD1(set_date_reconciled_secs, void(time64));
@@ -442,11 +442,67 @@ test_vendor_kvp_properties (Fixture *fixture, gconstpointer pData)
}
static void
test_split_online_id_accessors (Fixture *fixture, gconstpointer pData)
{
Split *split = fixture->split;
const char *fitid = "20240131-0001-1234567890";
gchar *raw = NULL;
/* Initially unset. */
g_assert_true (xaccSplitGetOnlineID (split) == NULL);
g_assert_true (!xaccSplitHasOnlineID (split));
/* Round-trip via the new accessors. */
xaccSplitSetOnlineID (split, fitid);
g_assert_cmpstr (xaccSplitGetOnlineID (split), ==, fitid);
g_assert_true (xaccSplitHasOnlineID (split));
/* GUI parity: the value is stored in the engine KVP slot "online_id",
* readable via the "online-id" GObject property used by the importer. */
qof_instance_get (QOF_INSTANCE (split), "online-id", &raw, NULL);
g_assert_cmpstr (raw, ==, fitid);
g_free (raw);
/* "" clears it. */
xaccSplitSetOnlineID (split, "");
g_assert_true (xaccSplitGetOnlineID (split) == NULL);
g_assert_true (!xaccSplitHasOnlineID (split));
/* NULL clears it too. */
xaccSplitSetOnlineID (split, fitid);
xaccSplitSetOnlineID (split, NULL);
g_assert_true (xaccSplitGetOnlineID (split) == NULL);
}
static void
test_account_online_id_accessors (Fixture *fixture, gconstpointer pData)
{
Account *acct = fixture->acct;
const char *acct_online_id = "061000104:0123456789:CHECKING";
gchar *raw = NULL;
g_assert_true (xaccAccountGetOnlineID (acct) == NULL);
xaccAccountSetOnlineID (acct, acct_online_id);
g_assert_cmpstr (xaccAccountGetOnlineID (acct), ==, acct_online_id);
/* GUI parity: stored in the "online_id" KVP slot. */
qof_instance_get (QOF_INSTANCE (acct), "online-id", &raw, NULL);
g_assert_cmpstr (raw, ==, acct_online_id);
g_free (raw);
xaccAccountSetOnlineID (acct, NULL);
g_assert_true (xaccAccountGetOnlineID (acct) == NULL);
}
void test_suite_engine_kvp_properties (void)
{
GNC_TEST_ADD (suitename, "Account", Fixture, NULL, setup_account, test_account_kvp_properties, teardown);
GNC_TEST_ADD (suitename, "Transaction", Fixture, NULL, setup_trans, test_trans_kvp_properties, teardown);
GNC_TEST_ADD (suitename, "Split", Fixture, NULL, setup_split, test_split_kvp_properties, teardown);
GNC_TEST_ADD (suitename, "Split online_id accessors", Fixture, NULL, setup_split, test_split_online_id_accessors, teardown);
GNC_TEST_ADD (suitename, "Account online_id accessors", Fixture, NULL, setup_account, test_account_online_id_accessors, teardown);
GNC_TEST_ADD (suitename, "Lot", Fixture, NULL, setup_lot, test_lot_kvp_properties, teardown);
GNC_TEST_ADD (suitename, "Customer", Fixture, NULL, setup_customer, test_customer_kvp_properties, teardown);
GNC_TEST_ADD (suitename, "Employee", Fixture, NULL, setup_employee, test_employee_kvp_properties, teardown);