Skip to content

Conversation

@notJoon
Copy link
Contributor

@notJoon notJoon commented Jul 12, 2025

Description

fixes #243

This PR fixes the --no-tunnel option in the fedify inbox command was being ignored, causing the server to always create a public tunnel regardless of the flag.

Changes

  1. Fixed the option checking logic from !options.tunnel to options.tunnel === false || options.noTunnel === true
  2. Added an InboxOptions interface
  3. Added inbox related tests in inbox.test.ts file

Problem

The fedify inbox command spin up an ephemeral ActivityPub server that can either be exposed to the public internet via a tunnel (default behavior) or run locally without tunneling when the --no-tunnel (or -T) flag is provided. However, as described in original issue, even when using the --no-tunnel flag, the server would still create a public HTTPS tunnel and be accessible from the outside.

The problem was the option handling logic of inbox.tsx. This was checking !options.tunnel to determine whether to disable tunneling.

fedify/cli/inbox.tsx

Lines 69 to 71 in 62db879

const server = await spawnTemporaryServer(fetch, {
noTunnel: !options.tunnel,
});

However, due to how the Cliffy framework handles negated boolean options, this logic was incorrect. When no flag is provided, options.tunnel is undefined, and !undefined evaluates to true, which incorrectly disabled tunneling by default. This meant the server would never create a tunnel unless the logic was inverted.

After fix, We can see the fedify inbox creates local server as expected:

With --no-tunnel option

$ deno task cli inbox --no-tunnel (or -T)
스크린샷 2025-07-12 오후 10 57 12

Without --no-tunnel option
스크린샷 2025-07-12 오후 10 59 46

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @notJoon, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical bug in the fedify inbox command where the --no-tunnel option was not functioning as intended, leading to the command always creating a public tunnel. The changes involve refining the command-line option parsing logic to correctly interpret the --no-tunnel flag, introducing dedicated types for better clarity, and adding new unit tests to validate the corrected behavior.

Highlights

  • Fix for --no-tunnel option: The core issue where the --no-tunnel option in the fedify inbox command was being ignored has been resolved. The logic for determining whether to disable tunneling now correctly respects the flag, preventing unintended public tunnels.
  • Improved Option Handling and Type Safety: An InboxOptions interface has been introduced to explicitly define the command's options, enhancing type safety. Additionally, a TunnelConfig utility object with a shouldDisableTunnel helper function centralizes and clarifies the tunneling decision logic.
  • New Test Coverage: A new test file, inbox.test.ts, has been added. It includes comprehensive unit tests for the shouldDisableTunnel logic, covering various scenarios such as the --no-tunnel flag, its shorthand (-T), default behavior, and other option combinations, ensuring the fix is robust.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions github-actions bot added component/cli CLI tools related difficulty/beginner Beginner friendly good first issue Good for newcomers priority/medium Medium priority issues type/bug Something isn't working labels Jul 12, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully fixes a bug where the --no-tunnel flag was being ignored. The approach of introducing a dedicated InboxOptions interface and a TunnelConfig object to handle the logic is sound, and the addition of tests is a great improvement. My review focuses on enhancing the new tests for better robustness and clarity. The most critical point is to ensure the tests validate the actual production code instead of a mock implementation. I've also provided a few suggestions to improve code structure and comments for better long-term maintainability.

Comment on lines 5 to 7
function shouldDisableTunnel(options: InboxOptions): boolean {
return options.tunnel === false || options.noTunnel === true;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This test file re-implements the logic from inbox.tsx instead of testing the actual implementation. This is a critical issue because it can lead to the tests passing even if the production code is broken. Please replace this mocked function with the actual implementation from inbox.tsx. You'll need to add import { TunnelConfig } from './inbox.tsx'; at the top of the file.

Suggested change
function shouldDisableTunnel(options: InboxOptions): boolean {
return options.tunnel === false || options.noTunnel === true;
}
import { TunnelConfig } from './inbox.tsx';
const shouldDisableTunnel = TunnelConfig.shouldDisableTunnel;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +23 to +20
const optionsWithT: InboxOptions = {
tunnel: true,
noTunnel: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The name of this test case and the mock data are a bit confusing. The flag definition '-T, --no-tunnel' suggests that -T is an alias for --no-tunnel, and both should result in options.tunnel being false. However, the test data here is { tunnel: true, noTunnel: true }, which is different from the test data for --no-tunnel ({ tunnel: false }). If cliffy indeed behaves this way, it would be great to add a comment explaining this behavior. Otherwise, if -T and --no-tunnel are supposed to be identical, the test data and name should be adjusted for clarity.

Deno.test("handles -T alias for --no-tunnel correctly", () => {

Comment on lines 77 to 75
const result = shouldDisableTunnel(options);
assertEquals(
typeof result,
"boolean",
"shouldDisableTunnel must return boolean",
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test only verifies that shouldDisableTunnel returns a boolean value, but it doesn't check if the returned value is correct for each combination of options. This test could be made much stronger by converting it into a data-driven test that asserts the expected outcome for each input case. This would make the test suite more robust.

Deno.test("shouldDisableTunnel handles various option combinations", () => {
  const testCases: { name: string; options: InboxOptions; expected: boolean }[] = [
    { name: "should enable tunnel by default", options: { tunnel: true }, expected: false },
    { name: "should disable tunnel with --no-tunnel", options: { tunnel: false }, expected: true },
    { name: "should disable tunnel with -T", options: { tunnel: true, noTunnel: true }, expected: true },
    { name: "should disable tunnel if both flags are present", options: { tunnel: false, noTunnel: true }, expected: true },
  ];

  for (const { name, options, expected } of testCases) {
    assertEquals(shouldDisableTunnel(options), expected, name);
  }
});

follow?: string[];
acceptFollow?: string[];
tunnel: boolean;
noTunnel?: boolean; // for -T shorthand support
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This comment is helpful, but it hints at a potentially confusing behavior from the cliffy library where an alias (-T) for a negated flag (--no-tunnel) behaves differently. For future maintainability, it would be very beneficial to add a more detailed explanation here or in a comment above the shouldDisableTunnel function, clarifying why two separate properties (tunnel and noTunnel) are needed.

cli/inbox.tsx Outdated
Comment on lines 51 to 53
shouldDisableTunnel: (opts: InboxOptions): boolean => {
return opts.tunnel === false || opts.noTunnel === true;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using a TunnelConfig object to namespace a single function might be a slight over-complication. You could simplify this by exporting shouldDisableTunnel as a standalone function. This would also require updating the call site on line 86. If you plan to add more tunnel-related logic to TunnelConfig in the future, the current approach is fine.

/**
 * Determines whether to disable the tunnel based on command-line options.
 */
export function shouldDisableTunnel(opts: InboxOptions): boolean {
  return opts.tunnel === false || opts.noTunnel === true;
}

@github-actions github-actions bot added the component/inbox Inbox related label Jul 12, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Jul 12, 2025

The docs for this pull request have been published:

https://b20dd4bf.fedify.pages.dev

Copy link
Member

@dahlia dahlia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! Just left a review comment about the changelog.

@github-actions
Copy link
Contributor

The latest push to this pull request has been published to JSR and npm as a pre-release:

Package Version JSR npm
@fedify/fedify 1.8.0-pr.284.978+1496f54f JSR npm
@fedify/cli 1.8.0-pr.284.978+1496f54f JSR
@fedify/amqp 1.8.0-pr.284.978+1496f54f JSR npm
@fedify/express 1.8.0-pr.284.978+1496f54f JSR npm
@fedify/h3 1.8.0-pr.284.978+1496f54f JSR npm
@fedify/postgres 1.8.0-pr.284.978+1496f54f JSR npm
@fedify/redis 1.8.0-pr.284.978+1496f54f JSR npm

Copy link
Member

@dahlia dahlia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Great work, again!

Copy link
Member

@dahlia dahlia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I missed that it's a bug fix! Could you change the target branch of this pull request to 1.7-maintenance instead of main?

@notJoon notJoon changed the base branch from main to 1.7-maintenance July 13, 2025 04:00
Copy link
Member

@dahlia dahlia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now everything looks fine!

@dahlia dahlia merged commit c473538 into fedify-dev:1.7-maintenance Jul 13, 2025
15 of 16 checks passed
@notJoon notJoon deleted the fix-243 branch July 13, 2025 05:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/cli CLI tools related component/inbox Inbox related difficulty/beginner Beginner friendly good first issue Good for newcomers priority/medium Medium priority issues type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fedify inbox --no-tunnel option is ignored, server still exposed via tunnel

2 participants