aboutsummaryrefslogtreecommitdiff
path: root/tests/test_core.c
diff options
context:
space:
mode:
authorAnders Betts <anders.betts@gmail.com>2026-09-18 22:16:32 +0200
committerAnders Betts <anders.betts@gmail.com>2026-09-18 22:16:32 +0200
commite9fc91dbc8314a25a0d71b7ee4344d3fc4ccfd5e (patch)
treed5c14087df9db17c63b5be5cada4f11592c493b3 /tests/test_core.c
parent251eb8c54c77029f0b43aa987ea50c44016147f3 (diff)
downloadbokf-0.1.29.tar.gz
bokf-0.1.29.zip
attachments: link/unlink from the TUI, multi-voucher linksv0.1.29
The voucher detail can attach a file to an existing voucher (^F) and the underlag picker (f) can remove a link (d, confirmed). The Underlag inbox links a highlighted item to a voucher picked from a list (k). attachment.link and attachment.unlink are new write commands (dry-run, audited); unlinked files return to the inbox. The same content may now link to several vouchers — only the same voucher/attachment pair is a CONFLICT, matching the table's primary key.
Diffstat (limited to 'tests/test_core.c')
-rw-r--r--tests/test_core.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/tests/test_core.c b/tests/test_core.c
index aa2bd4a..6f114b9 100644
--- a/tests/test_core.c
+++ b/tests/test_core.c
@@ -928,6 +928,74 @@ int main(void)
CHECK(yyjson_arr_size(jget(d, "result.items")) == 0);
yyjson_doc_free(d);
+ /* the same content may link to several vouchers, but not twice to one */
+ d = call(reqf("{\"v\":1,\"id\":\"61a\",\"cmd\":\"attachment.put\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"filename\":"
+ "\"kvitto.txt\",\"mime\":\"text/plain\","
+ "\"content_base64\":\"aGVsbG8gd29ybGQ=\",\"voucher_id\":%lld}}",
+ g_session, (int)org_id, (long long)sale_id));
+ CHECK_OK(d);
+ CHECK(jint(d, "result.id") == att_id);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"61b\",\"cmd\":\"attachment.put\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"filename\":"
+ "\"kvitto.txt\",\"mime\":\"text/plain\","
+ "\"content_base64\":\"aGVsbG8gd29ybGQ=\",\"voucher_id\":%lld}}",
+ g_session, (int)org_id, (long long)sale_id));
+ CHECK_STR(d, "error.code", "CONFLICT");
+ yyjson_doc_free(d);
+
+ /* link/unlink an existing attachment */
+ d = call(reqf("{\"v\":1,\"id\":\"61c\",\"cmd\":\"attachment.put\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"filename\":"
+ "\"extra.txt\",\"content_base64\":\"ZXh0cmE=\"}}",
+ g_session, (int)org_id));
+ CHECK_OK(d);
+ int64_t orphan = jint(d, "result.id");
+ CHECK(orphan > 0);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"61d\",\"cmd\":\"attachment.link\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%lld,"
+ "\"voucher_id\":%lld}}",
+ g_session, (int)org_id, (long long)orphan,
+ (long long)sale_id));
+ CHECK_OK(d);
+ CHECK(jint(d, "result.voucher_id") == sale_id);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"61e\",\"cmd\":\"attachment.link\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%lld,"
+ "\"voucher_id\":%lld}}",
+ g_session, (int)org_id, (long long)orphan,
+ (long long)sale_id));
+ CHECK_STR(d, "error.code", "CONFLICT");
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"61f\",\"cmd\":\"attachment.unlink\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%lld,"
+ "\"voucher_id\":%lld}}",
+ g_session, (int)org_id, (long long)orphan,
+ (long long)sale_id));
+ CHECK_OK(d);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"61g\",\"cmd\":\"attachment.unlink\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%lld,"
+ "\"voucher_id\":%lld}}",
+ g_session, (int)org_id, (long long)orphan,
+ (long long)sale_id));
+ CHECK_STR(d, "error.code", "NOT_FOUND");
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"61h\",\"cmd\":\"attachment.link\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%lld,"
+ "\"voucher_id\":999999}}",
+ g_session, (int)org_id, (long long)orphan));
+ CHECK_STR(d, "error.code", "NOT_FOUND");
+ yyjson_doc_free(d);
+
/* correction */
d = call(reqf("{\"v\":1,\"id\":\"62\",\"cmd\":\"voucher.correct\","
"\"session\":\"%s\",\"org\":%d,\"args\":{\"voucher\":%lld,"