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