diff --git a/app/assets/javascripts/discourse/ember-cli-build.js b/app/assets/javascripts/discourse/ember-cli-build.js
index 07836c3efbc..e43030aec48 100644
--- a/app/assets/javascripts/discourse/ember-cli-build.js
+++ b/app/assets/javascripts/discourse/ember-cli-build.js
@@ -103,12 +103,9 @@ module.exports = function (defaults) {
"ember-cli-terser": {
enabled: isProduction,
- exclude: [
- "**/test-*.js",
- "**/core-tests*.js",
- "**/highlightjs/*",
- "**/javascripts/*",
- ],
+ exclude:
+ ["**/highlightjs/*", "**/javascripts/*"] +
+ (isEmbroider ? [] : ["**/test-*.js", "**/core-tests*.js"]),
},
"ember-cli-babel": {
@@ -119,8 +116,9 @@ module.exports = function (defaults) {
plugins: [require.resolve("deprecation-silencer")],
},
- // We need to build tests in prod for theme tests
- tests: true,
+ // Was previously true so that we could run theme tests in production
+ // but we're moving away from that as part of the Embroider migration
+ tests: isEmbroider ? !isProduction : true,
vendorFiles: {
// Freedom patch - includes bug fix and async stack support
diff --git a/app/controllers/qunit_controller.rb b/app/controllers/qunit_controller.rb
index 31c411688d8..0911a9434b4 100644
--- a/app/controllers/qunit_controller.rb
+++ b/app/controllers/qunit_controller.rb
@@ -7,6 +7,8 @@ class QunitController < ApplicationController
def theme
raise Discourse::NotFound.new if !can_see_theme_qunit?
+ @has_test_bundle = EmberCli.has_tests?
+
param_key = nil
@suggested_themes = nil
if (id = get_param(:id)).present?
diff --git a/app/views/qunit/theme.html.erb b/app/views/qunit/theme.html.erb
index 726c3eb7539..b100db08017 100644
--- a/app/views/qunit/theme.html.erb
+++ b/app/views/qunit/theme.html.erb
@@ -5,7 +5,7 @@
<%= discourse_color_scheme_stylesheets %>
- <%- if !@suggested_themes %>
+ <%- if @has_test_bundle && !@suggested_themes %>
<%= preload_script "locales/#{I18n.locale}" %>
<%= preload_script "vendor" %>
<%= preload_script "test-support" %>
@@ -44,7 +44,10 @@
<%- end %>
- <%- if @suggested_themes %>
+ <%- if !@has_test_bundle %>
+ This is a production installation of Discourse, and cannot be used for theme testing.
+ For more information, see this guide.
+ <% elsif @suggested_themes %>
Theme QUnit Test Runner
<%- if @suggested_themes.size == 0 %>
@@ -55,9 +58,7 @@
<%= link_to name, theme_qunit_path(id: id) %>
<%- end %>
<%- end %>
- <%- end %>
-
- <%- if !@suggested_themes %>
+ <% else %>
<%= preload_script "scripts/discourse-test-listen-boot" %>
<%= preload_script "scripts/discourse-boot" %>
<%- end %>
diff --git a/lib/ember_cli.rb b/lib/ember_cli.rb
index 4e241fb7b94..d8b8d677260 100644
--- a/lib/ember_cli.rb
+++ b/lib/ember_cli.rb
@@ -103,4 +103,8 @@ module EmberCli
chunk_infos
end
+
+ def self.has_tests?
+ File.exist?("#{dist_dir}/tests/index.html")
+ end
end
diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake
index 27e7398cf84..9a37c584c47 100644
--- a/lib/tasks/assets.rake
+++ b/lib/tasks/assets.rake
@@ -9,13 +9,15 @@ task "assets:precompile:before": "environment" do
end
if ENV["EMBER_CLI_COMPILE_DONE"] != "1"
- compile_command = "yarn --cwd app/assets/javascripts/discourse run ember build -prod"
+ compile_command = "yarn --cwd app/assets/javascripts/discourse run ember build"
if check_node_heap_size_limit < 1024
STDERR.puts "Detected low Node.js heap_size_limit. Using --max-old-space-size=1024."
compile_command = "NODE_OPTIONS='--max-old-space-size=1024' #{compile_command}"
end
+ compile_command = "EMBER_ENV=production #{compile_command}" if ENV["EMBER_ENV"].nil?
+
only_assets_precompile_remaining = (ARGV.last == "assets:precompile")
if only_assets_precompile_remaining
diff --git a/spec/requests/qunit_controller_spec.rb b/spec/requests/qunit_controller_spec.rb
index 17e4250df6a..99f0073a274 100644
--- a/spec/requests/qunit_controller_spec.rb
+++ b/spec/requests/qunit_controller_spec.rb
@@ -1,108 +1,30 @@
# frozen_string_literal: true
RSpec.describe QunitController do
- describe "#theme" do
- let(:theme) { Fabricate(:theme, name: "main-theme") }
- let(:component) { Fabricate(:theme, component: true, name: "enabled-component") }
- let(:disabled_component) do
- Fabricate(:theme, component: true, enabled: false, name: "disabled-component")
- end
- let(:theme_without_tests) { Fabricate(:theme, name: "no-tests-guy") }
+ def production_sign_in(user)
+ # We need to call sign_in before stubbing the method because SessionController#become
+ # checks for the current env when the file is loaded.
+ # We need to make sure become is called once before stubbing, or the method
+ # wont'be available for future tests if this one runs first.
+ sign_in(user) if user
+ Rails.env.stubs(:production?).returns(true)
+ end
- before do
- Theme.destroy_all
- theme.set_default!
- component.add_relative_theme!(:parent, theme)
- disabled_component.add_relative_theme!(:parent, theme)
- [theme, component, disabled_component].each do |t|
- t.set_field(
- target: :extra_js,
- type: :js,
- name: "discourse/initializers/my-#{t.id}-initializer.js",
- value: "console.log(#{t.id});",
- )
- t.set_field(
- target: :tests_js,
- type: :js,
- name: "acceptance/some-test-#{t.id}.js",
- value: "assert.ok(#{t.id});",
- )
- t.save!
- end
- end
+ it "hides page for regular users in production" do
+ production_sign_in(Fabricate(:user))
+ get "/theme-qunit"
+ expect(response.status).to eq(404)
+ end
- context "with non-admin users on production" do
- before do
- # We need to call sign_in before stubbing the method because SessionController#become
- # checks for the current env when the file is loaded.
- # We need to make sure become is called once before stubbing, or the method
- # wont'be available for future tests if this one runs first.
- sign_in(Fabricate(:user))
- Rails.env.stubs(:production?).returns(true)
- end
+ it "hides page for anon in production" do
+ production_sign_in(nil)
+ get "/theme-qunit"
+ expect(response.status).to eq(404)
+ end
- it "regular users cannot see the page" do
- get "/theme-qunit"
- expect(response.status).to eq(404)
- end
-
- it "anons cannot see the page" do
- sign_out
- get "/theme-qunit"
- expect(response.status).to eq(404)
- end
- end
-
- context "with admin users" do
- before { sign_in(Fabricate(:admin)) }
-
- context "when no theme is specified" do
- it "renders a list of themes and components that have tests" do
- get "/theme-qunit"
- expect(response.status).to eq(200)
- [theme, component, disabled_component].each do |t|
- expect(response.body).to include(t.name)
- expect(response.body).to include("/theme-qunit?id=#{t.id}")
- end
- expect(response.body).not_to include(theme_without_tests.name)
- expect(response.body).not_to include("/theme-qunit?id=#{theme_without_tests.id}")
- end
- end
-
- it "can specify theme by id" do
- get "/theme-qunit?id=#{theme.id}"
- expect(response.status).to eq(200)
- expect(response.body).to include("/theme-javascripts/tests/#{theme.id}-")
- end
-
- it "can specify theme by name" do
- get "/theme-qunit?name=#{theme.name}"
- expect(response.status).to eq(200)
- expect(response.body).to include("/theme-javascripts/tests/#{theme.id}-")
- end
-
- it "can specify theme by url" do
- theme.build_remote_theme(remote_url: "git@github.com:discourse/discourse.git").save!
- theme.save!
- get "/theme-qunit?url=#{theme.remote_theme.remote_url}"
- expect(response.status).to eq(200)
- expect(response.body).to include("/theme-javascripts/tests/#{theme.id}-")
- end
-
- it "themes qunit page includes all the JS/CSS it needs" do
- get "/theme-qunit?id=#{theme.id}"
- expect(response.status).to eq(200)
- expect(response.body).to include("/stylesheets/color_definitions_base_")
- expect(response.body).to include("/stylesheets/desktop_")
- expect(response.body).to include("* https://qunitjs.com/") # inlined QUnit CSS
- expect(response.body).to include("/assets/locales/en.js")
- expect(response.body).to include("/test-support.js")
- expect(response.body).to include("/test-site-settings.js")
- expect(response.body).to include("/assets/markdown-it-bundle.js")
- expect(response.body).to include("/assets/admin.js")
- expect(response.body).to match(/\/theme-javascripts\/\h{40}\.js/)
- expect(response.body).to include("/theme-javascripts/tests/#{theme.id}-")
- end
- end
+ it "shows page for admin in production" do
+ production_sign_in(Fabricate(:admin))
+ get "/theme-qunit"
+ expect(response.status).to eq(200)
end
end
diff --git a/spec/system/theme_qunit_spec.rb b/spec/system/theme_qunit_spec.rb
index e6c0affa57d..fed80e73a0f 100644
--- a/spec/system/theme_qunit_spec.rb
+++ b/spec/system/theme_qunit_spec.rb
@@ -1,8 +1,9 @@
# frozen_string_literal: true
describe "Theme qunit testing", type: :system do
+ let!(:theme_without_tests) { Fabricate(:theme, name: "no-tests-guy") }
let!(:theme_with_test) do
- t = Fabricate(:theme, name: "My Theme")
+ t = Fabricate(:theme, name: "Theme With Tests")
t.set_field(target: :tests_js, type: :js, name: "acceptance/some-test.js", value: <<~JS)
import { module, test } from "qunit";
@@ -12,16 +13,27 @@ describe "Theme qunit testing", type: :system do
});
});
JS
+ t.build_remote_theme(remote_url: "https://example.com/mytheme")
t.save!
t
end
- it "can run theme tests correctly" do
+ it "lists themes and can run tests by id, name and url" do
visit "/theme-qunit"
+ expect(page).to have_css("a[href^='/theme-qunit?id=']", count: 1)
+
find("a[href=\"/theme-qunit?id=#{theme_with_test.id}\"]").click
success_count = find("#qunit-testresult-display .passed").text
expect(success_count).to eq("1")
+
+ visit "/theme-qunit?name=#{theme_with_test.name}"
+ success_count = find("#qunit-testresult-display .passed").text
+ expect(success_count).to eq("1")
+
+ visit "/theme-qunit?url=#{theme_with_test.remote_theme.remote_url}"
+ success_count = find("#qunit-testresult-display .passed").text
+ expect(success_count).to eq("1")
end
end