LCOV - code coverage report
Current view: top level - tests/functional/pty - test_config_wizard_pty.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 48 48
Test Date: 2026-04-20 19:54:22 Functions: 100.0 % 4 4

            Line data    Source code
       1              : /* SPDX-License-Identifier: GPL-3.0-or-later */
       2              : /* Copyright 2026 Peter Csaszar */
       3              : 
       4              : /**
       5              :  * @file test_config_wizard_pty.c
       6              :  * @brief PTY functional test for the interactive config wizard (FEAT-37).
       7              :  *
       8              :  * Launches `tg-cli login` under a PTY and verifies:
       9              :  *   1. The welcome text appears.
      10              :  *   2. The api_hash prompt is present.
      11              :  *   3. Characters typed at the api_hash prompt do NOT echo back to the master.
      12              :  *   4. After submitting valid values the binary prints "Saved to …/config.ini"
      13              :  *      and exits with code 0.
      14              :  *   5. The generated config.ini has mode 0600.
      15              :  */
      16              : 
      17              : #include "ptytest.h"
      18              : #include "pty_assert.h"
      19              : 
      20              : #include <stdio.h>
      21              : #include <stdlib.h>
      22              : #include <string.h>
      23              : #include <sys/stat.h>
      24              : #include <unistd.h>
      25              : 
      26              : /* Defined by CMake: path to the tg-cli binary under test. */
      27              : #ifndef TG_CLI_BINARY
      28              : #  error "TG_CLI_BINARY must be defined by CMake"
      29              : #endif
      30              : 
      31              : /* ---- helpers ---- */
      32              : 
      33              : /** Unique temp dir per process for XDG_CONFIG_HOME. */
      34              : static char g_tmp_dir[256];
      35              : 
      36            2 : static void setup_tmp_dir(void) {
      37            2 :     const char *base = getenv("TMPDIR");
      38            2 :     if (!base) base = "/tmp";
      39            2 :     snprintf(g_tmp_dir, sizeof(g_tmp_dir),
      40            2 :              "%s/tg-cli-pty-wiz-%d", base, (int)getpid());
      41              :     /* mkdir -p */
      42              :     char cmd[512];
      43            2 :     snprintf(cmd, sizeof(cmd), "mkdir -p %s", g_tmp_dir);
      44            2 :     int rc = system(cmd); (void)rc;
      45            2 : }
      46              : 
      47            1 : static void cleanup_tmp_dir(void) {
      48              :     char cmd[512];
      49            1 :     snprintf(cmd, sizeof(cmd), "rm -rf %s", g_tmp_dir);
      50            1 :     int rc = system(cmd); (void)rc;
      51            1 : }
      52              : 
      53              : static int g_tests_run    = 0;
      54              : static int g_tests_failed = 0;
      55              : 
      56              : /* ── Tests ─────────────────────────────────────────────────────────── */
      57              : 
      58              : /**
      59              :  * @brief Happy-path PTY test.
      60              :  *
      61              :  * Launches `tg-cli login` with XDG_CONFIG_HOME pointed at a temp dir,
      62              :  * feeds valid api_id (without echo suppression) then api_hash (with echo
      63              :  * suppression), and checks:
      64              :  *   - Welcome text visible.
      65              :  *   - api_hash typed chars NOT echoed (the hash string must NOT appear
      66              :  *     anywhere on screen after typing it).
      67              :  *   - "Saved to" line appears.
      68              :  *   - Exit code 0.
      69              :  *   - config.ini has mode 0600.
      70              :  */
      71            2 : static void test_wizard_pty_happy(void) {
      72            2 :     setup_tmp_dir();
      73              : 
      74              :     /* Point XDG_CONFIG_HOME to our temp dir so we don't touch the real one. */
      75            2 :     setenv("XDG_CONFIG_HOME", g_tmp_dir, 1);
      76              : 
      77            2 :     PtySession *s = pty_open(100, 30);
      78            2 :     ASSERT(s != NULL, "pty_open must succeed");
      79              : 
      80            2 :     const char *argv[] = { TG_CLI_BINARY, "login", NULL };
      81            2 :     int rc = pty_run(s, argv);
      82            1 :     ASSERT(rc == 0, "pty_run(tg-cli login) must succeed");
      83              : 
      84              :     /* Wait for welcome text. */
      85            1 :     int found = pty_wait_for(s, "Welcome to tg-cli", 5000);
      86            1 :     ASSERT(found == 0, "welcome text must appear on screen");
      87              : 
      88              :     /* Wait for the api_id prompt. */
      89            1 :     found = pty_wait_for(s, "Enter your api_id", 5000);
      90            1 :     ASSERT(found == 0, "api_id prompt must appear");
      91              : 
      92              :     /* Type a valid api_id followed by Enter. */
      93            1 :     pty_send(s, "99999\r", 6);
      94              : 
      95              :     /* Wait for the api_hash prompt. */
      96            1 :     found = pty_wait_for(s, "Enter your api_hash", 5000);
      97            1 :     ASSERT(found == 0, "api_hash prompt must appear");
      98              : 
      99              :     /* Type a valid api_hash (32 lowercase hex chars). */
     100            1 :     const char *hash = "abcdef0123456789abcdef0123456789";
     101            1 :     pty_send(s, hash, 32);
     102              :     /* Give the terminal a moment to process then check no echo. */
     103            1 :     pty_wait_for(s, "Saved to", 200); /* short timeout — probably not there yet */
     104              : 
     105              :     /* The hash should NOT appear in the screen buffer. */
     106            1 :     int hash_visible = pty_screen_contains(s, hash);
     107            1 :     ASSERT(hash_visible == 0,
     108              :            "api_hash must NOT echo: secret string must not appear on screen");
     109              : 
     110              :     /* Send Enter to submit. */
     111            1 :     pty_send(s, "\r", 1);
     112              : 
     113              :     /* Wait for "Saved to" confirmation. */
     114            1 :     found = pty_wait_for(s, "Saved to", 5000);
     115            1 :     ASSERT(found == 0, "\"Saved to\" must appear after valid input");
     116              : 
     117              :     /* Wait for the process to exit. */
     118            1 :     int exit_code = pty_wait_exit(s, 5000);
     119            1 :     ASSERT(exit_code == 0, "tg-cli login must exit with code 0");
     120              : 
     121              :     /* Verify config.ini mode 0600. */
     122              :     char cfg_path[512];
     123            1 :     snprintf(cfg_path, sizeof(cfg_path), "%s/tg-cli/config.ini", g_tmp_dir);
     124              :     struct stat st;
     125            1 :     ASSERT(stat(cfg_path, &st) == 0, "config.ini must exist after wizard");
     126            1 :     ASSERT((st.st_mode & 0777) == 0600, "config.ini must have mode 0600");
     127              : 
     128            1 :     pty_close(s);
     129            1 :     cleanup_tmp_dir();
     130            1 :     unsetenv("XDG_CONFIG_HOME");
     131              : }
     132              : 
     133              : /* ── Entry point ─────────────────────────────────────────────────────── */
     134              : 
     135            2 : int main(void) {
     136            2 :     printf("PTY config wizard tests (%s)\n", TG_CLI_BINARY);
     137              : 
     138            2 :     test_wizard_pty_happy();
     139              : 
     140            1 :     printf("\n%d tests run, %d failed\n", g_tests_run, g_tests_failed);
     141            1 :     return g_tests_failed > 0 ? 1 : 0;
     142              : }
        

Generated by: LCOV version 2.0-1