how to test for options(fields) in settings API?

Before saving the options the first time get_option( 'rtwhc_settings' ) returns false as the option doesn’t exist.

Saving values, deleting them and then saving again causes the value of get_option( 'rtwhc_settings' ) to be an array with the field names as keys, which have empty values.

You can see this, if you var_dump() the option value.

array(3) {
  ["rtwhc_api_url"]=>
  string(0) ""
  ["rtwhc_community_id"]=>
  string(0) ""
  ["rtwhc_api_token"]=>
  string(0) ""
}

rtwhc_debug is missing from the array probably, because it’s a checkbox and when it’s not checked it doesn’t get sent with the $_POST data.

To fix the issue in the shortcode just replace isset() with !empty() checks. The isset() returns true, because the options array has the given key, but it doesn’t care, if there’s a value (as long as it’s not null) for that key or not. With !empty() you check that the key exists and it has some truthy value.

My personal preference is to wrap options calls like this in a helper function, which always returns the data in the expected format and with the necessary default values.

function my_option_values_with_defaults(): array {
    // get options or return empty array instead of false, if option doesn't exist
    $option = get_option('rtwhc_settings', []);

    // get defaults from constants or other source
    $defaults = [
        'rtwhc_api_url' => WHC_API_URL,
        'rtwhc_community_id' => WHC_COMMUNITY_ID,
        'rtwhc_api_token' => WHC_TOKEN,
        'rtwhc_debug' => WHC_ENABLE_DEBUG,
    ];

    // mash found options and defaults together
    $parsed = [];
    foreach ($defaults as $key => $default) {
        $parsed[$key] = ! empty($option[$key]) ? $option[$key] : $default;
    }

    return $parsed;
}