1 /********************************************************************
2  * test-engine-kvp-properties.c: GLib g_test test suite for         *
3  * KVP-based properties in several engine classes.                  *
4  * Copyright 2013 John Ralls <jralls@ceridwen.us>		    *
5  *                                                                  *
6  * This program is free software; you can redistribute it and/or    *
7  * modify it under the terms of the GNU General Public License as   *
8  * published by the Free Software Foundation; either version 2 of   *
9  * the License, or (at your option) any later version.              *
10  *                                                                  *
11  * This program is distributed in the hope that it will be useful,  *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
14  * GNU General Public License for more details.                     *
15  *                                                                  *
16  * You should have received a copy of the GNU General Public License*
17  * along with this program; if not, contact:                        *
18  *                                                                  *
19  * Free Software Foundation           Voice:  +1-617-542-5942       *
20  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
21  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
22 \********************************************************************/
23 
24 /**
25  * Test Engine KVP Properties Acceptance testing for KVP Properties
26  * added to various engine classes to make private the internals of
27  * KVP storage used for a variety of parameters on several engine
28  * classes.
29  */
30 
31 #include <config.h>
32 #include <glib.h>
33 #include <qof.h>
34 #include <unittest-support.h>
35 #include "../Transaction.h"
36 #include "../Split.h"
37 #include "../Account.h"
38 #include "../SchedXaction.h"
39 #include "../gncCustomer.h"
40 #include "../gncEmployee.h"
41 #include "../gncJob.h"
42 #include "../gncVendor.h"
43 
44 typedef struct
45 {
46     union
47     {
48 	Account      *acct;
49 	Transaction  *trans;
50 	Split        *split;
51 	GNCLot       *lot;
52 	GncCustomer  *cust;
53 	GncEmployee  *emp;
54 	GncJob       *job;
55 	GncVendor    *vend;
56     };
57     GSList *hdlrs;
58 } Fixture;
59 
60 /* Prototype to shut clang up */
61 void test_suite_engine_kvp_properties (void);
62 
63 /* Private QofInstance functions needed for testing */
64 extern void qof_instance_mark_clean (QofInstance*);
65 
66 const gchar *suitename = "/engine/kvp-properties";
67 
68 static void
setup_account(Fixture * fixture,gconstpointer pData)69 setup_account (Fixture *fixture, gconstpointer pData)
70 {
71     QofBook *book = qof_book_new ();
72     fixture->acct = xaccMallocAccount (book);
73 }
74 
75 static void
setup_trans(Fixture * fixture,gconstpointer pData)76 setup_trans (Fixture *fixture, gconstpointer pData)
77 {
78     QofBook *book = qof_book_new ();
79     fixture->trans = xaccMallocTransaction (book);
80 }
81 
82 static void
setup_split(Fixture * fixture,gconstpointer pData)83 setup_split (Fixture *fixture, gconstpointer pData)
84 {
85     QofBook *book = qof_book_new ();
86     fixture->split = xaccMallocSplit (book);
87 }
88 
89 static void
setup_lot(Fixture * fixture,gconstpointer pData)90 setup_lot (Fixture *fixture, gconstpointer pData)
91 {
92     QofBook *book = qof_book_new ();
93     fixture->lot = gnc_lot_new (book);
94 }
95 
96 static void
setup_customer(Fixture * fixture,gconstpointer pData)97 setup_customer (Fixture *fixture, gconstpointer pData)
98 {
99     QofBook *book = qof_book_new ();
100     fixture->cust = gncCustomerCreate (book);
101 }
102 
103 static void
setup_employee(Fixture * fixture,gconstpointer pData)104 setup_employee (Fixture *fixture, gconstpointer pData)
105 {
106     QofBook *book = qof_book_new ();
107     fixture->emp = gncEmployeeCreate (book);
108 }
109 
110 static void
setup_job(Fixture * fixture,gconstpointer pData)111 setup_job (Fixture *fixture, gconstpointer pData)
112 {
113     QofBook *book = qof_book_new ();
114     fixture->job = gncJobCreate (book);
115 }
116 
117 static void
setup_vendor(Fixture * fixture,gconstpointer pData)118 setup_vendor (Fixture *fixture, gconstpointer pData)
119 {
120     QofBook *book = qof_book_new ();
121     fixture->vend = gncVendorCreate (book);
122 }
123 
124 static void
teardown(Fixture * fixture,gconstpointer pData)125 teardown (Fixture *fixture, gconstpointer pData)
126 {
127 /* It doesn't actually matter which union member we use here, they're
128  * all QofInstances, so this will work for any of them.
129  */
130     QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->acct));
131     test_destroy (fixture->acct);
132     qof_book_destroy (book);
133 }
134 
135 static void
test_account_kvp_properties(Fixture * fixture,gconstpointer pData)136 test_account_kvp_properties (Fixture *fixture, gconstpointer pData)
137 {
138     gint64 next_id = 12345678909876;
139     gint64 ab_acct_uid = 67890987654321;
140     gint64 next_id_r, ab_acct_uid_r;
141     gchar *online_id = "my online id";
142     gchar *ab_acct_id = "1234-5678-9087";
143     gchar *ab_bank_code = "0032340";
144     gchar *online_id_r, *ab_acct_id_r, *ab_bank_code_r;
145     GncGUID *ofx_income_acct = guid_malloc ();
146     GncGUID *ofx_income_acct_r;
147     Time64 trans_retr = {gnc_time(NULL)};
148     Time64 *trans_retr_r;
149 
150     xaccAccountBeginEdit (fixture->acct);
151     qof_instance_set (QOF_INSTANCE (fixture->acct),
152 		      "lot-next-id", next_id,
153 		      "online-id", online_id,
154 		      "ofx-income-account", ofx_income_acct,
155 		      "ab-account-id", ab_acct_id,
156 		      "ab-bank-code", ab_bank_code,
157 		      "ab-account-uid", ab_acct_uid,
158 		      "ab-trans-retrieval", &trans_retr,
159 		      NULL);
160 
161     g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->acct)));
162     qof_instance_mark_clean (QOF_INSTANCE (fixture->acct));
163 
164     qof_instance_get (QOF_INSTANCE (fixture->acct),
165 		      "lot-next-id", &next_id_r,
166 		      "online-id", &online_id_r,
167 		      "ofx-income-account", &ofx_income_acct_r,
168 		      "ab-account-id", &ab_acct_id_r,
169 		      "ab-bank-code", &ab_bank_code_r,
170 		      "ab-account-uid", &ab_acct_uid_r,
171 		      "ab-trans-retrieval", &trans_retr_r,
172 		      NULL);
173     g_assert_cmpint (next_id, ==, next_id_r);
174     g_assert_cmpstr (online_id, ==, online_id_r);
175     g_assert (guid_equal (ofx_income_acct, ofx_income_acct_r));
176     g_assert_cmpstr (ab_acct_id, ==, ab_acct_id_r);
177     g_assert_cmpstr (ab_bank_code, ==, ab_bank_code_r);
178     g_assert_cmpint (ab_acct_uid, ==, ab_acct_uid_r);
179     g_assert_cmpint (trans_retr.t, ==, trans_retr_r->t);
180     g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->acct)));
181 
182     guid_free (ofx_income_acct);
183     guid_free (ofx_income_acct_r);
184 }
185 
186 static void
test_trans_kvp_properties(Fixture * fixture,gconstpointer pData)187 test_trans_kvp_properties (Fixture *fixture, gconstpointer pData)
188 {
189     GncGUID *invoice = guid_malloc ();
190     GncGUID *from_sx = guid_malloc ();
191     GncGUID *invoice_r, *from_sx_r;
192     gchar *online_id = "my online id";
193     gchar *online_id_r;
194 
195     xaccTransBeginEdit (fixture->trans);
196     qof_instance_set (QOF_INSTANCE (fixture->trans),
197 		      "invoice", invoice,
198 		      "from-sched-xaction", from_sx,
199 		      "online-id", online_id,
200 		      NULL);
201 
202     g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->trans)));
203     qof_instance_mark_clean (QOF_INSTANCE (fixture->trans));
204 
205     qof_instance_get (QOF_INSTANCE (fixture->trans),
206 		      "invoice", &invoice_r,
207 		      "from-sched-xaction", &from_sx_r,
208 		      "online-id", &online_id_r,
209 		      NULL);
210     g_assert (guid_equal (invoice, invoice_r));
211     g_assert (guid_equal (from_sx, from_sx_r));
212     g_assert_cmpstr (online_id, ==, online_id_r);
213     g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->trans)));
214     guid_free (invoice);
215     guid_free (invoice_r);
216     guid_free (from_sx);
217     guid_free (from_sx_r);
218     g_free (online_id_r);
219 }
220 
221 static void
test_split_kvp_properties(Fixture * fixture,gconstpointer pData)222 test_split_kvp_properties (Fixture *fixture, gconstpointer pData)
223 {
224     gchar *debit_formula = "e^xdydx";
225     gchar *credit_formula = "seccostansin";
226     gchar *sx_shares = "43";
227     gchar *online_id = "my_online_id";
228     gchar *debit_formula_r, *credit_formula_r, *sx_shares_r;
229     gchar *online_id_r;
230     GncGUID *sx_account = guid_malloc ();
231     GncGUID *sx_account_r;
232     gnc_numeric debit_numeric = gnc_numeric_create (123, 456);
233     gnc_numeric credit_numeric = gnc_numeric_create (789, 456);
234     gnc_numeric *debit_numeric_r, *credit_numeric_r;
235 
236     qof_begin_edit (QOF_INSTANCE (fixture->split));
237     qof_instance_set (QOF_INSTANCE (fixture->split),
238 		      "sx-debit-formula", debit_formula,
239 		      "sx-debit-numeric", &debit_numeric,
240 		      "sx-credit-formula", credit_formula,
241 		      "sx-credit-numeric", &credit_numeric,
242 		      "sx-account", sx_account,
243 		      "sx-shares", sx_shares,
244 		      "online-id", online_id,
245 		      NULL);
246 
247     g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->split)));
248     qof_instance_mark_clean (QOF_INSTANCE (fixture->split));
249 
250     qof_instance_get (QOF_INSTANCE (fixture->split),
251 		      "sx-debit-formula", &debit_formula_r,
252 		      "sx-debit-numeric", &debit_numeric_r,
253 		      "sx-credit-formula", &credit_formula_r,
254 		      "sx-credit-numeric", &credit_numeric_r,
255 		      "sx-account", &sx_account_r,
256 		      "sx-shares", &sx_shares_r,
257 		      "online-id", &online_id_r,
258 		      NULL);
259     g_assert_cmpstr (debit_formula, ==, debit_formula_r);
260     g_assert (gnc_numeric_equal (debit_numeric, *debit_numeric_r));
261     g_assert_cmpstr (credit_formula, ==, credit_formula_r);
262     g_assert (gnc_numeric_equal (credit_numeric, *credit_numeric_r));
263     g_assert (guid_equal (sx_account, sx_account_r));
264     g_assert_cmpstr (sx_shares, ==, sx_shares_r);
265     g_assert_cmpstr (online_id, ==, online_id_r);
266     g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->split)));
267     g_free (debit_formula_r);
268     g_free (debit_numeric_r);
269     g_free (credit_formula_r);
270     g_free (credit_numeric_r);
271     qof_begin_edit (QOF_INSTANCE (fixture->split));
272     qof_instance_set (QOF_INSTANCE (fixture->split),
273 		      "sx-credit-formula", NULL,
274 		      NULL);
275     qof_instance_get (QOF_INSTANCE (fixture->split),
276 		      "sx-credit-formula", &credit_numeric_r,
277 		      NULL);
278     g_assert (credit_numeric_r == NULL);
279     g_free (sx_shares_r);
280     g_free (online_id_r);
281     guid_free (sx_account);
282     guid_free (sx_account_r);
283 }
284 
285 static void
test_lot_kvp_properties(Fixture * fixture,gconstpointer pData)286 test_lot_kvp_properties (Fixture *fixture, gconstpointer pData)
287 {
288     GncGUID *invoice = guid_malloc ();
289     GncGUID *invoice_r;
290     gint64 owner_type = 47;
291     gint64 owner_type_r;
292     GncGUID *owner = guid_malloc ();
293     GncGUID *owner_r;
294 
295     qof_begin_edit (QOF_INSTANCE (fixture->lot));
296     qof_instance_set (QOF_INSTANCE (fixture->lot),
297 		      "invoice", invoice,
298 		      GNC_OWNER_TYPE, owner_type,
299 		      GNC_OWNER_GUID, owner,
300 		      NULL);
301 
302     g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->lot)));
303     qof_instance_mark_clean (QOF_INSTANCE (fixture->lot));
304 
305     qof_instance_get (QOF_INSTANCE (fixture->lot),
306 		      "invoice", &invoice_r,
307 		      GNC_OWNER_TYPE, &owner_type_r,
308 		      GNC_OWNER_GUID, &owner_r,
309 		      NULL);
310     g_assert (guid_equal (invoice, invoice_r));
311     g_assert_cmpint (owner_type, ==, owner_type_r);
312     g_assert (guid_equal (owner, owner_r));
313     g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->lot)));
314     guid_free (invoice);
315     guid_free (invoice_r);
316     guid_free (owner);
317     guid_free (owner_r);
318 }
319 
320 static void
test_customer_kvp_properties(Fixture * fixture,gconstpointer pData)321 test_customer_kvp_properties (Fixture *fixture, gconstpointer pData)
322 {
323     gchar *pdf_dir = "/foo/bar/baz";
324     gchar *pdf_dir_r;
325     GncGUID *inv_acct = guid_malloc ();
326     GncGUID *pmt_acct = guid_malloc ();
327     GncGUID *inv_acct_r, *pmt_acct_r;
328 
329     qof_begin_edit (QOF_INSTANCE (fixture->cust));
330     qof_instance_set (QOF_INSTANCE (fixture->cust),
331 		      "export-pdf-dir", pdf_dir,
332 		      "invoice-last-posted-account", inv_acct,
333 		      "payment-last-account", pmt_acct,
334 		      NULL);
335 
336     g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->cust)));
337     qof_instance_mark_clean (QOF_INSTANCE (fixture->cust));
338 
339     qof_instance_get (QOF_INSTANCE (fixture->cust),
340 		      "export-pdf-dir", &pdf_dir_r,
341 		      "invoice-last-posted-account", &inv_acct_r,
342 		      "payment-last-account", &pmt_acct_r,
343 		      NULL);
344 
345     g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
346     g_assert (guid_equal (inv_acct, inv_acct_r));
347     g_assert (guid_equal (pmt_acct, pmt_acct_r));
348     guid_free (inv_acct);
349     guid_free (inv_acct_r);
350     guid_free (pmt_acct);
351     guid_free (pmt_acct_r);
352     g_free (pdf_dir_r);
353 
354 }
355 
356 static void
test_employee_kvp_properties(Fixture * fixture,gconstpointer pData)357 test_employee_kvp_properties (Fixture *fixture, gconstpointer pData)
358 {
359     gchar *pdf_dir = "/foo/bar/baz";
360     gchar *pdf_dir_r;
361     GncGUID *inv_acct = guid_malloc ();
362     GncGUID *pmt_acct = guid_malloc ();
363     GncGUID *inv_acct_r, *pmt_acct_r;
364 
365     qof_begin_edit (QOF_INSTANCE (fixture->emp));
366     qof_instance_set (QOF_INSTANCE (fixture->emp),
367 		      "export-pdf-dir", pdf_dir,
368 		      "invoice-last-posted-account", inv_acct,
369 		      "payment-last-account", pmt_acct,
370 		      NULL);
371 
372     g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->emp)));
373     qof_instance_mark_clean (QOF_INSTANCE (fixture->emp));
374 
375     qof_instance_get (QOF_INSTANCE (fixture->emp),
376 		      "export-pdf-dir", &pdf_dir_r,
377 		      "invoice-last-posted-account", &inv_acct_r,
378 		      "payment-last-account", &pmt_acct_r,
379 		      NULL);
380 
381     g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
382     g_assert (guid_equal (inv_acct, inv_acct_r));
383     g_assert (guid_equal (pmt_acct, pmt_acct_r));
384     guid_free (inv_acct);
385     guid_free (inv_acct_r);
386     guid_free (pmt_acct);
387     guid_free (pmt_acct_r);
388     g_free (pdf_dir_r);
389 
390 }
391 
392 static void
test_job_kvp_properties(Fixture * fixture,gconstpointer pData)393 test_job_kvp_properties (Fixture *fixture, gconstpointer pData)
394 {
395     gchar *pdf_dir = "/foo/bar/baz";
396     gchar *pdf_dir_r;
397 
398     qof_begin_edit (QOF_INSTANCE (fixture->job));
399     qof_instance_set (QOF_INSTANCE (fixture->job),
400 		      "export-pdf-dir", pdf_dir,
401 		      NULL);
402 
403     g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->job)));
404     qof_instance_mark_clean (QOF_INSTANCE (fixture->job));
405 
406     qof_instance_get (QOF_INSTANCE (fixture->job),
407 		      "export-pdf-dir", &pdf_dir_r,
408 		      NULL);
409 
410     g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
411     g_free (pdf_dir_r);
412 
413 }
414 
415 static void
test_vendor_kvp_properties(Fixture * fixture,gconstpointer pData)416 test_vendor_kvp_properties (Fixture *fixture, gconstpointer pData)
417 {
418     gchar *pdf_dir = "/foo/bar/baz";
419     gchar *pdf_dir_r;
420     GncGUID *inv_acct = guid_malloc ();
421     GncGUID *pmt_acct = guid_malloc ();
422     GncGUID *inv_acct_r, *pmt_acct_r;
423 
424     qof_begin_edit (QOF_INSTANCE (fixture->vend));
425     qof_instance_set (QOF_INSTANCE (fixture->vend),
426 		      "export-pdf-dir", pdf_dir,
427 		      "invoice-last-posted-account", inv_acct,
428 		      "payment-last-account", pmt_acct,
429 		      NULL);
430 
431     g_assert (qof_instance_is_dirty (QOF_INSTANCE (fixture->vend)));
432     qof_instance_mark_clean (QOF_INSTANCE (fixture->vend));
433 
434     qof_instance_get (QOF_INSTANCE (fixture->vend),
435 		      "export-pdf-dir", &pdf_dir_r,
436 		      "invoice-last-posted-account", &inv_acct_r,
437 		      "payment-last-account", &pmt_acct_r,
438 		      NULL);
439 
440     g_assert_cmpstr (pdf_dir, ==, pdf_dir_r);
441     g_assert (guid_equal (inv_acct, inv_acct_r));
442     g_assert (guid_equal (pmt_acct, pmt_acct_r));
443     guid_free (inv_acct);
444     guid_free (inv_acct_r);
445     guid_free (pmt_acct);
446     guid_free (pmt_acct_r);
447     g_free (pdf_dir_r);
448 
449 }
450 
test_suite_engine_kvp_properties(void)451 void test_suite_engine_kvp_properties (void)
452 {
453     GNC_TEST_ADD (suitename, "Account", Fixture, NULL, setup_account, test_account_kvp_properties, teardown);
454     GNC_TEST_ADD (suitename, "Transaction", Fixture, NULL, setup_trans, test_trans_kvp_properties, teardown);
455     GNC_TEST_ADD (suitename, "Split", Fixture, NULL, setup_split, test_split_kvp_properties, teardown);
456     GNC_TEST_ADD (suitename, "Lot", Fixture, NULL, setup_lot, test_lot_kvp_properties, teardown);
457     GNC_TEST_ADD (suitename, "Customer", Fixture, NULL, setup_customer, test_customer_kvp_properties, teardown);
458     GNC_TEST_ADD (suitename, "Employee", Fixture, NULL, setup_employee, test_employee_kvp_properties, teardown);
459     GNC_TEST_ADD (suitename, "Job", Fixture, NULL, setup_job, test_job_kvp_properties, teardown);
460     GNC_TEST_ADD (suitename, "Vendor", Fixture, NULL, setup_vendor, test_vendor_kvp_properties, teardown);
461 }
462