LCOV - code coverage report
Current view: top level - tests/unit - test_smtp_adapter.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 80 80
Test Date: 2026-05-07 15:53:07 Functions: 100.0 % 14 14

            Line data    Source code
       1              : #include "test_helpers.h"
       2              : #include "smtp_adapter.h"
       3              : #include "config.h"
       4              : #include <stdlib.h>
       5              : #include <string.h>
       6              : 
       7              : /* ── smtp_send error paths ───────────────────────────────────────────── */
       8              : 
       9            1 : static void test_send_null_cfg(void) {
      10            1 :     ASSERT(smtp_send(NULL, "a@b.com", "c@d.com", "msg", 3) == -1,
      11              :            "send: NULL cfg → -1");
      12              : }
      13              : 
      14            1 : static void test_send_null_from(void) {
      15            1 :     Config cfg = {0};
      16            1 :     ASSERT(smtp_send(&cfg, NULL, "c@d.com", "msg", 3) == -1,
      17              :            "send: NULL from → -1");
      18              : }
      19              : 
      20            1 : static void test_send_null_to(void) {
      21            1 :     Config cfg = {0};
      22            1 :     ASSERT(smtp_send(&cfg, "a@b.com", NULL, "msg", 3) == -1,
      23              :            "send: NULL to → -1");
      24              : }
      25              : 
      26            1 : static void test_send_null_message(void) {
      27            1 :     Config cfg = {0};
      28            1 :     ASSERT(smtp_send(&cfg, "a@b.com", "c@d.com", NULL, 0) == -1,
      29              :            "send: NULL message → -1");
      30              : }
      31              : 
      32            1 : static void test_send_rejects_insecure_url(void) {
      33              :     /* smtp:// without ssl_no_verify should be rejected */
      34            1 :     Config cfg = {0};
      35            1 :     cfg.smtp_host = "smtp://insecure.example.com";
      36            1 :     cfg.ssl_no_verify = 0;
      37            1 :     int rc = smtp_send(&cfg, "a@b.com", "c@d.com",
      38              :                         "From: a\r\n\r\nbody\r\n", 20);
      39            1 :     ASSERT(rc == -1, "send: insecure smtp:// rejected");
      40              : }
      41              : 
      42            1 : static void test_send_rejects_derived_insecure(void) {
      43              :     /* Derived from imap:// (not imaps://) → smtp:// → rejected */
      44            1 :     Config cfg = {0};
      45            1 :     cfg.host = "imap://imap.example.com";
      46            1 :     cfg.ssl_no_verify = 0;
      47            1 :     int rc = smtp_send(&cfg, "a@b.com", "c@d.com",
      48              :                         "From: a\r\n\r\nbody\r\n", 20);
      49            1 :     ASSERT(rc == -1, "send: derived smtp:// rejected");
      50              : }
      51              : 
      52            1 : static void test_send_url_from_host_no_scheme(void) {
      53              :     /* cfg->host without scheme → url = strdup(cfg->host) path in build_smtp_url;
      54              :      * then ssl check fails (not smtps://) → -1 */
      55            1 :     Config cfg = {0};
      56            1 :     cfg.host = "mail.example.com";   /* no :// — hits the else/strdup branch */
      57            1 :     cfg.ssl_no_verify = 0;
      58            1 :     int rc = smtp_send(&cfg, "a@b.com", "c@d.com",
      59              :                         "From: a\r\n\r\nbody\r\n", 20);
      60            1 :     ASSERT(rc == -1, "send: bare host URL rejected (not smtps://)");
      61              : }
      62              : 
      63            1 : static void test_send_url_fallback_localhost(void) {
      64              :     /* No smtp_host, no host → url = "smtp://localhost";
      65              :      * ssl_no_verify=0 → rejected (not smtps://) */
      66            1 :     Config cfg = {0};
      67            1 :     cfg.ssl_no_verify = 0;
      68            1 :     int rc = smtp_send(&cfg, "a@b.com", "c@d.com",
      69              :                         "From: a\r\n\r\nbody\r\n", 20);
      70            1 :     ASSERT(rc == -1, "send: fallback smtp://localhost rejected");
      71              : }
      72              : 
      73            1 : static void test_send_url_fallback_localhost_ssl_skip(void) {
      74              :     /* No smtp_host, no host → url = "smtp://localhost";
      75              :      * ssl_no_verify=1 → passes TLS check, reaches curl, curl fails to connect → -1 */
      76            1 :     Config cfg = {0};
      77            1 :     cfg.ssl_no_verify = 1;
      78            1 :     int rc = smtp_send(&cfg, "a@b.com", "c@d.com",
      79              :                         "From: a\r\n\r\nbody\r\n", 20);
      80            1 :     ASSERT(rc == -1, "send: smtp://localhost + ssl_no_verify reaches curl (connection refused)");
      81              : }
      82              : 
      83            1 : static void test_send_smtp_host_with_embedded_port(void) {
      84              :     /* smtp_host already contains a port → build_smtp_url uses strdup branch */
      85            1 :     Config cfg = {0};
      86            1 :     cfg.smtp_host = "smtps://smtp.example.com:465";
      87            1 :     cfg.smtp_port = 587;  /* ignored because port already in URL */
      88            1 :     cfg.ssl_no_verify = 1;
      89              :     /* smtps:// passes TLS check; curl will fail to connect → -1 */
      90            1 :     int rc = smtp_send(&cfg, "a@b.com", "c@d.com",
      91              :                         "From: a\r\n\r\nbody\r\n", 20);
      92            1 :     ASSERT(rc == -1, "send: smtp_host with embedded port (strdup path), curl fails");
      93              : }
      94              : 
      95            1 : static void test_send_smtp_host_port_appended(void) {
      96              :     /* smtp_port set, no port in smtp_host → asprintf path */
      97            1 :     Config cfg = {0};
      98            1 :     cfg.smtp_host = "smtps://smtp.example.com";
      99            1 :     cfg.smtp_port = 465;
     100            1 :     cfg.ssl_no_verify = 1;
     101              :     /* smtps:// passes TLS check; curl will fail to connect → -1 */
     102            1 :     int rc = smtp_send(&cfg, "a@b.com", "c@d.com",
     103              :                         "From: a\r\n\r\nbody\r\n", 20);
     104            1 :     ASSERT(rc == -1, "send: smtp_port appended to smtp_host URL, curl fails");
     105              : }
     106              : 
     107            1 : static void test_send_display_name_stripping(void) {
     108              :     /* from/to with display names → angle-bracket stripping in envelope */
     109            1 :     Config cfg = {0};
     110            1 :     cfg.smtp_host = "smtps://smtp.example.com";
     111            1 :     cfg.ssl_no_verify = 1;
     112              :     /* The display name parsing runs before curl; curl fails → -1 */
     113            1 :     int rc = smtp_send(&cfg,
     114              :                        "Alice Smith <alice@example.com>",
     115              :                        "Bob Jones <bob@example.com>",
     116              :                        "From: Alice Smith <alice@example.com>\r\nTo: Bob Jones <bob@example.com>\r\n\r\nHello\r\n",
     117              :                        80);
     118            1 :     ASSERT(rc == -1, "send: display name stripping reaches curl (connection refused)");
     119              : }
     120              : 
     121            1 : static void test_send_smtps_derived_from_imaps(void) {
     122              :     /* Derive from imaps:// → smtps:// passes TLS check; curl fails → -1 */
     123            1 :     Config cfg = {0};
     124            1 :     cfg.host = "imaps://imap.example.com";
     125            1 :     cfg.ssl_no_verify = 1;
     126            1 :     int rc = smtp_send(&cfg, "a@b.com", "c@d.com",
     127              :                         "From: a\r\n\r\nbody\r\n", 20);
     128            1 :     ASSERT(rc == -1, "send: smtps derived from imaps + ssl_no_verify reaches curl");
     129              : }
     130              : 
     131              : /* ── Registration ────────────────────────────────────────────────────── */
     132              : 
     133            1 : void test_smtp_adapter(void) {
     134            1 :     RUN_TEST(test_send_null_cfg);
     135            1 :     RUN_TEST(test_send_null_from);
     136            1 :     RUN_TEST(test_send_null_to);
     137            1 :     RUN_TEST(test_send_null_message);
     138            1 :     RUN_TEST(test_send_rejects_insecure_url);
     139            1 :     RUN_TEST(test_send_rejects_derived_insecure);
     140            1 :     RUN_TEST(test_send_url_from_host_no_scheme);
     141            1 :     RUN_TEST(test_send_url_fallback_localhost);
     142            1 :     RUN_TEST(test_send_url_fallback_localhost_ssl_skip);
     143            1 :     RUN_TEST(test_send_smtp_host_with_embedded_port);
     144            1 :     RUN_TEST(test_send_smtp_host_port_appended);
     145            1 :     RUN_TEST(test_send_display_name_stripping);
     146            1 :     RUN_TEST(test_send_smtps_derived_from_imaps);
     147            1 : }
        

Generated by: LCOV version 2.0-1