summaryrefslogtreecommitdiff
path: root/tests/test_core.c
diff options
context:
space:
mode:
authorAnders Betts <anders.betts@gmail.com>2026-09-20 09:56:56 +0200
committerAnders Betts <anders.betts@gmail.com>2026-09-20 09:57:20 +0200
commit59ef95d3c1f590a05c3bea79834d424200d28250 (patch)
tree6fd26b77e3ffb10658c3e3ef029704704118dd0d /tests/test_core.c
parentb5349b52e757399d8ddb6325120a58e7d9e6e1f6 (diff)
downloadbokf-59ef95d3c1f590a05c3bea79834d424200d28250.tar.gz
bokf-59ef95d3c1f590a05c3bea79834d424200d28250.zip
report: per-org moms rule editor commands
Diffstat (limited to 'tests/test_core.c')
-rw-r--r--tests/test_core.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/tests/test_core.c b/tests/test_core.c
index ee0d3b9..56c70dd 100644
--- a/tests/test_core.c
+++ b/tests/test_core.c
@@ -960,6 +960,16 @@ int main(void)
CHECK(arg_field_is(find_arg(d, "number"), "type", "string"));
yyjson_doc_free(d);
+ d = call(reqf("{\"v\":1,\"id\":\"30f\",\"cmd\":\"describe\","
+ "\"session\":\"%s\",\"args\":{\"cmd\":\"report.rule_create\"}}",
+ g_session));
+ CHECK_OK(d);
+ CHECK_STR(d, "result.command.name", "report.rule_create");
+ CHECK(arg_required(find_arg(d, "report")));
+ CHECK(arg_field_is(find_arg(d, "match_type"), "type", "enum"));
+ CHECK(!arg_required(find_arg(d, "sign")));
+ yyjson_doc_free(d);
+
d = call(reqf("{\"v\":1,\"id\":\"30c\",\"cmd\":\"voucher.post\","
"\"session\":\"%s\",\"org\":%d,\"args\":"
"{\"description\":\"Saknar datum\",\"rows\":["
@@ -1996,6 +2006,198 @@ int main(void)
CHECK(n05 == 1);
yyjson_doc_free(d);
+ /* ---------------- moms rules: per-org editor -------------------- */
+ d = call(reqf("{\"v\":1,\"id\":\"116a\",\"cmd\":\"report.rule_list\","
+ "\"session\":\"%s\",\"org\":%d}",
+ g_session, (int)vat_org));
+ CHECK_OK(d);
+ int nrules = (int)yyjson_arr_size(jget(d, "result.items"));
+ CHECK(nrules >= 15);
+ {
+ yyjson_val *items = jget(d, "result.items");
+ for (size_t i = 0; i < yyjson_arr_size(items); i++) {
+ yyjson_val *rv = yyjson_obj_get(yyjson_arr_get(items, i), "report");
+ CHECK(rv && yyjson_is_str(rv) &&
+ strcmp(yyjson_get_str(rv), "vat") == 0);
+ }
+ }
+ CHECK_STR(d, "result.items.0.box", "05");
+ CHECK(jint(d, "result.items.0.sort_order") == 10);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116b\",\"cmd\":\"report.rule_list\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"report\":\"vat\"}}",
+ g_session, (int)vat_org));
+ CHECK_OK(d);
+ CHECK(yyjson_arr_size(jget(d, "result.items")) == (size_t)nrules);
+ yyjson_doc_free(d);
+
+ /* dry run validates but must not create a rule */
+ d = call(reqf("{\"v\":1,\"id\":\"116c\",\"cmd\":\"report.rule_create\","
+ "\"session\":\"%s\",\"org\":%d,\"dry_run\":true,\"args\":"
+ "{\"report\":\"vat\",\"box\":\"05\",\"match_type\":\"type\","
+ "\"pattern\":\"revenue\",\"sign\":-1,\"sort_order\":1}}",
+ g_session, (int)vat_org));
+ CHECK_OK(d);
+ CHECK(jbool(d, "result.dry_run"));
+ CHECK(jint(d, "result.id") == 0);
+ CHECK_STR(d, "result.match_type", "type");
+ CHECK_STR(d, "result.pattern", "revenue");
+ CHECK(jint(d, "result.sign") == -1);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116d\",\"cmd\":\"report.rule_list\","
+ "\"session\":\"%s\",\"org\":%d}",
+ g_session, (int)vat_org));
+ CHECK_OK(d);
+ CHECK(yyjson_arr_size(jget(d, "result.items")) == (size_t)nrules);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116e\",\"cmd\":\"report.rule_create\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":"
+ "{\"report\":\"vat\",\"box\":\"05\",\"match_type\":\"type\","
+ "\"pattern\":\"revenue\",\"sign\":-1,\"sort_order\":1}}",
+ g_session, (int)vat_org));
+ CHECK_OK(d);
+ int64_t rule_id = jint(d, "result.id");
+ CHECK(rule_id > 0);
+ CHECK_STR(d, "result.report", "vat");
+ CHECK_STR(d, "result.box", "05");
+ CHECK(jint(d, "result.sign") == -1);
+ CHECK(jint(d, "result.sort_order") == 1);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116f\",\"cmd\":\"report.rule_list\","
+ "\"session\":\"%s\",\"org\":%d}",
+ g_session, (int)vat_org));
+ CHECK_OK(d);
+ CHECK(yyjson_arr_size(jget(d, "result.items")) == (size_t)nrules + 1);
+ {
+ int found = 0;
+ yyjson_val *items = jget(d, "result.items");
+ for (size_t i = 0; i < yyjson_arr_size(items); i++) {
+ yyjson_val *iv = yyjson_obj_get(yyjson_arr_get(items, i), "id");
+ if (iv && yyjson_is_int(iv) && yyjson_get_int(iv) == rule_id)
+ found = 1;
+ }
+ CHECK(found);
+ }
+ yyjson_doc_free(d);
+
+ /* the rule adds the revenue type on top of the seeded ranges */
+ d = call(reqf("{\"v\":1,\"id\":\"116g\",\"cmd\":\"report.vat\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":"
+ "{\"from\":\"2026-02-01\",\"to\":\"2026-02-28\"}}",
+ g_session, (int)vat_org));
+ CHECK_OK(d);
+ CHECK(vat_box(d, "05") == 300000);
+ CHECK(vat_box(d, "49") == 35500);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116h\",\"cmd\":\"report.rule_update\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":"
+ "{\"id\":%lld,\"sign\":1,\"sort_order\":2}}",
+ g_session, (int)vat_org, (long long)rule_id));
+ CHECK_OK(d);
+ CHECK_STR(d, "result.match_type", "type");
+ CHECK_STR(d, "result.pattern", "revenue");
+ CHECK(jint(d, "result.sign") == 1);
+ CHECK(jint(d, "result.sort_order") == 2);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116i\",\"cmd\":\"report.vat\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":"
+ "{\"from\":\"2026-02-01\",\"to\":\"2026-02-28\"}}",
+ g_session, (int)vat_org));
+ CHECK_OK(d);
+ CHECK(vat_box(d, "05") == 0);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116j\",\"cmd\":\"report.rule_update\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%lld,"
+ "\"match_type\":\"range\",\"pattern\":\"3100-3000\"}}",
+ g_session, (int)vat_org, (long long)rule_id));
+ CHECK_STR(d, "error.code", "INVALID_ARGS");
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116k\",\"cmd\":\"report.rule_update\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%d}}",
+ g_session, (int)vat_org, 999999));
+ CHECK_STR(d, "error.code", "NOT_FOUND");
+ yyjson_doc_free(d);
+
+ /* dry-run delete keeps the rule */
+ d = call(reqf("{\"v\":1,\"id\":\"116l\",\"cmd\":\"report.rule_delete\","
+ "\"session\":\"%s\",\"org\":%d,\"dry_run\":true,"
+ "\"args\":{\"id\":%lld}}",
+ g_session, (int)vat_org, (long long)rule_id));
+ CHECK_OK(d);
+ CHECK(jbool(d, "result.deleted"));
+ CHECK(jbool(d, "result.dry_run"));
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116m\",\"cmd\":\"report.rule_delete\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%lld}}",
+ g_session, (int)vat_org, (long long)rule_id));
+ CHECK_OK(d);
+ CHECK(jint(d, "result.id") == rule_id);
+ CHECK(jbool(d, "result.deleted"));
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116n\",\"cmd\":\"report.rule_list\","
+ "\"session\":\"%s\",\"org\":%d}",
+ g_session, (int)vat_org));
+ CHECK_OK(d);
+ CHECK(yyjson_arr_size(jget(d, "result.items")) == (size_t)nrules);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116o\",\"cmd\":\"report.vat\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":"
+ "{\"from\":\"2026-02-01\",\"to\":\"2026-02-28\"}}",
+ g_session, (int)vat_org));
+ CHECK_OK(d);
+ CHECK(vat_box(d, "05") == 150000);
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116p\",\"cmd\":\"report.rule_delete\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":{\"id\":%lld}}",
+ g_session, (int)vat_org, (long long)rule_id));
+ CHECK_STR(d, "error.code", "NOT_FOUND");
+ yyjson_doc_free(d);
+
+ /* invalid rules are rejected before any write */
+ d = call(reqf("{\"v\":1,\"id\":\"116q\",\"cmd\":\"report.rule_create\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":"
+ "{\"report\":\"vat\",\"box\":\"05\","
+ "\"match_type\":\"bogus\",\"pattern\":\"3001\"}}",
+ g_session, (int)vat_org));
+ CHECK_STR(d, "error.code", "INVALID_ARGS");
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116r\",\"cmd\":\"report.rule_create\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":"
+ "{\"report\":\"vat\",\"box\":\"05\","
+ "\"match_type\":\"range\",\"pattern\":\"3100-3000\"}}",
+ g_session, (int)vat_org));
+ CHECK_STR(d, "error.code", "INVALID_ARGS");
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116s\",\"cmd\":\"report.rule_create\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":"
+ "{\"report\":\"vat\",\"box\":\"05\","
+ "\"match_type\":\"account\",\"pattern\":\"30a1\"}}",
+ g_session, (int)vat_org));
+ CHECK_STR(d, "error.code", "INVALID_ARGS");
+ yyjson_doc_free(d);
+
+ d = call(reqf("{\"v\":1,\"id\":\"116t\",\"cmd\":\"report.rule_create\","
+ "\"session\":\"%s\",\"org\":%d,\"args\":"
+ "{\"report\":\"vat\",\"box\":\"05\","
+ "\"match_type\":\"type\",\"pattern\":\"revenue\",\"sign\":0}}",
+ g_session, (int)vat_org));
+ CHECK_STR(d, "error.code", "INVALID_ARGS");
+ yyjson_doc_free(d);
+
/* ---------------- bokslut: dispositions, tax, transfer ---------- */
d = call(reqf("{\"v\":1,\"id\":\"120\",\"cmd\":\"bokslut.post\","
"\"session\":\"%s\",\"org\":%d,\"dry_run\":true,\"args\":"