From 117c375f98aadb17f1fe0079203f1e926b00966c Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 3 Apr 2026 16:55:50 +0000 Subject: [PATCH 1/2] Add tests for skipProxy with Inertia-style asset scenarios (JS, CSS, SCSS, images) Validates that skip_proxy: true correctly generates absolute URLs pointing directly to the Vite dev server for all asset types. Covers manifest lookups, tag helpers (client, JS, CSS, SCSS, images, React refresh), and documents known caveats (CORS, Rails 6 .scss.css, cookies, SSL, Docker networking). https://claude.ai/code/session_01Dfaxd2gi78PhPtXVqcfkcq --- test/helper_test.rb | 81 +++++++++++++++++++++++++++++++++++++++++++ test/manifest_test.rb | 67 +++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) diff --git a/test/helper_test.rb b/test/helper_test.rb index 27686bc8..40131045 100644 --- a/test/helper_test.rb +++ b/test/helper_test.rb @@ -42,6 +42,11 @@ def with_dev_server_running(&block) refresh_config(mode: "development") super end + + def with_skip_proxy_dev_server_running(&block) + refresh_config(mode: "development", skip_proxy: true) + ViteRuby.instance.stub(:dev_server_running?, true, &block) + end end class LegacyHelperTest < HelperTestCase @@ -190,6 +195,82 @@ def test_vite_image_tag } end + # skipProxy tests: validate that all tag helpers emit absolute URLs pointing + # directly to the Vite dev server when skipProxy is enabled. + + def test_vite_client_tag_with_skip_proxy + assert_nil vite_client_tag + with_skip_proxy_dev_server_running { + origin = ViteRuby.config.origin + assert_equal %(), vite_client_tag + } + end + + def test_vite_asset_path_with_skip_proxy + with_skip_proxy_dev_server_running { + origin = ViteRuby.config.origin + assert_equal "#{origin}/vite-dev/entrypoints/main.ts", vite_asset_path("main.ts") + assert_equal "#{origin}/vite-dev/entrypoints/app.css", vite_asset_path("app.css") + assert_equal "#{origin}/vite-dev/images/logo.png", vite_asset_path("images/logo.png") + } + end + + def test_vite_javascript_tag_with_skip_proxy + with_skip_proxy_dev_server_running { + origin = ViteRuby.config.origin + assert_equal %(), + vite_typescript_tag("main") + + assert_equal %(), + vite_javascript_tag("entrypoints/frameworks/vue") + } + end + + def test_vite_stylesheet_tag_with_skip_proxy + with_skip_proxy_dev_server_running { + origin = ViteRuby.config.origin + assert_similar link(href: "#{origin}/vite-dev/entrypoints/app.css"), vite_stylesheet_tag("app") + assert_equal vite_stylesheet_tag("app"), vite_stylesheet_tag("app.css") + + if Rails::VERSION::MAJOR >= 7 + assert_similar link(href: "#{origin}/vite-dev/entrypoints/sassy.scss"), vite_stylesheet_tag("sassy.scss") + else + # Rails 6 appends .css to non-.css extensions. Without the proxy to + # normalize .scss.css → .scss, Vite cannot serve this URL. + assert_similar link(href: "#{origin}/vite-dev/entrypoints/sassy.scss.css"), vite_stylesheet_tag("sassy.scss") + end + } + end + + def test_vite_image_tag_with_skip_proxy + with_skip_proxy_dev_server_running { + origin = ViteRuby.config.origin + assert_equal %(Logo), + vite_image_tag("images/logo.png", alt: "Logo") + + assert_equal %(Logo), + vite_image_tag("images/logo.png", srcset: {"images/logo-2x.png" => "2x"}, alt: "Logo") + } + end + + def test_vite_react_refresh_tag_with_skip_proxy + with_skip_proxy_dev_server_running { + origin = ViteRuby.config.origin + assert_equal <<~HTML.chomp, vite_react_refresh_tag(nonce: nil) + + HTML + } + end + def test_vite_picture_tag if Rails.gem_version >= Gem::Version.new("7.1.0") assert_equal <<~HTML.gsub(/\n\s*/, ""), vite_picture_tag("images/logo.svg", "images/logo.png", class: "test", image: {alt: "Logo"}) diff --git a/test/manifest_test.rb b/test/manifest_test.rb index b777c750..1c2a8870 100644 --- a/test/manifest_test.rb +++ b/test/manifest_test.rb @@ -193,6 +193,73 @@ def test_vite_client_src } end + # NOTE: skipProxy (experimental since v3.2.12) causes asset URLs to point + # directly to the Vite dev server. Known caveats: + # + # 1. CORS: Browser makes cross-origin requests to Vite. Vite sets permissive + # CORS headers by default, but custom middleware may interfere. + # 2. Rails 6 .scss.css: Without the proxy to normalize .scss.css → .scss, + # Rails 6's stylesheet_link_tag produces URLs Vite can't serve. + # 3. Cookies: Asset requests to a different origin won't carry same-origin + # cookies. Usually not an issue since assets don't require auth. + # 4. SSL: Both Rails and Vite need valid certs when using HTTPS. + # 5. Docker/VM: "localhost:3036" from the browser may not reach Vite inside + # a container. Must configure host to a reachable address. + # 6. vite_asset_url may produce double-origin URLs since path_for already + # returns an absolute URL when skipProxy is enabled. + + def test_lookup_success_with_skip_proxy_and_dev_server_running + refresh_config(mode: "development", skip_proxy: true) + with_dev_server_running { + origin = ViteRuby.config.origin # "https://localhost:3535" + + entry = {"file" => "#{origin}/vite-dev/entrypoints/application.js"} + assert_equal entry, lookup!("application.js", type: :javascript) + assert_equal entry, lookup!("entrypoints/application.js") + + assert_equal "#{origin}/vite-dev/entrypoints/application.ts", + path_for("application", type: :typescript) + + assert_equal "#{origin}/vite-dev/entrypoints/styles.css", + path_for("styles", type: :stylesheet) + + assert_equal "#{origin}/vite-dev/image/logo.png", + path_for("image/logo.png") + + assert_equal "#{origin}/vite-dev/logo.png", + path_for("~/logo.png") + + assert_equal "#{origin}/vite-dev/@fs#{ViteRuby.config.root}/app/assets/theme.css", + path_for("/app/assets/theme", type: :stylesheet) + } + end + + def test_vite_client_src_with_skip_proxy + refresh_config(mode: "development", skip_proxy: true) + + assert_nil vite_client_src + + with_dev_server_running { + assert_equal "#{ViteRuby.config.origin}/vite-dev/@vite/client", vite_client_src + } + + # Origin from skip_proxy takes precedence over asset_host + refresh_config(asset_host: "http://example.com", mode: "development", skip_proxy: true) + + with_dev_server_running { + assert_equal "#{ViteRuby.config.origin}/vite-dev/@vite/client", vite_client_src + } + end + + def test_skip_proxy_has_no_effect_without_dev_server + refresh_config(skip_proxy: true) + + # Production paths are unchanged — skipProxy only matters when dev server runs + assert_equal prefixed("main.9dcad042.js"), path_for("main", type: :typescript) + assert_equal prefixed("app.517bf154.css"), path_for("app", type: :stylesheet) + assert_equal prefixed("logo.f42fb7ea.png"), path_for("images/logo.png") + end + def test_lookup_nil assert_nil lookup("foo.js") end From 32ada2abbfb52b230f3a5dff2d44727328d64a49 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 12:21:15 +0000 Subject: [PATCH 2/2] Remove packageManager field from package.json to fix CI test failures Agent-Logs-Url: https://github.com/ElMassimo/vite_ruby/sessions/9c28094b-6fe9-4ce2-bd67-d75b32e8fab9 Co-authored-by: ElMassimo <1158253+ElMassimo@users.noreply.github.com> --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 3d86088f..9f53874f 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,5 @@ "type": "git", "url": "https://github.com/ElMassimo/vite_ruby" }, - "homepage": "https://github.com/ElMassimo/vite_ruby", - "packageManager": "pnpm@10.32.1" + "homepage": "https://github.com/ElMassimo/vite_ruby" } \ No newline at end of file