diff --git a/.eslintignore b/.eslintignore
index 68b8560b4a8..3956d17380d 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -12,7 +12,7 @@ lib/highlight_js/
plugins/**/lib/javascripts/locale
public/
vendor/
-app/assets/javascripts/discourse/tests/test_helper.js
+app/assets/javascripts/discourse/tests/test-boot-rails.js
app/assets/javascripts/discourse/tests/fixtures
node_modules/
dist/
diff --git a/.prettierignore b/.prettierignore
index 3884169675c..217c164e17c 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -20,7 +20,7 @@ lib/highlight_js/
plugins/**/lib/javascripts/locale
public/
vendor/
-app/assets/javascripts/discourse/tests/test_helper.js
+app/assets/javascripts/discourse/tests/test-boot-rails.js
app/assets/javascripts/discourse/tests/fixtures
node_modules/
dist/
diff --git a/app/assets/javascripts/discourse-common/addon/lib/debounce.js b/app/assets/javascripts/discourse-common/addon/lib/debounce.js
index 5e30864574f..dcd2693b78c 100644
--- a/app/assets/javascripts/discourse-common/addon/lib/debounce.js
+++ b/app/assets/javascripts/discourse-common/addon/lib/debounce.js
@@ -11,7 +11,9 @@ let testingFunc = isLegacyEmber() ? run : next;
export default function () {
if (isTesting()) {
- return testingFunc(...arguments);
+ // Don't include the time argument (in ms)
+ let args = [].slice.call(arguments, 0, -1);
+ return testingFunc.apply(void 0, args);
} else {
return debounce(...arguments);
}
diff --git a/app/assets/javascripts/discourse/ember-cli-build.js b/app/assets/javascripts/discourse/ember-cli-build.js
index 5125e7e08e5..602f51f189b 100644
--- a/app/assets/javascripts/discourse/ember-cli-build.js
+++ b/app/assets/javascripts/discourse/ember-cli-build.js
@@ -37,8 +37,66 @@ module.exports = function (defaults) {
// We don't use SRI in Rails. Disable here to match:
enabled: false,
},
+
+ "ember-cli-terser": {
+ enabled: true,
+ exclude: [
+ "**/test-*.js",
+ "**/core-tests*.js",
+ "**/highlightjs/*",
+ "**/javascripts/*",
+ ],
+ },
+
+ // We need to build tests in prod for theme tests
+ tests: true,
});
+ // Patching a private method is not great, but there's no other way for us to tell
+ // Ember CLI that we want the tests alone in a package without helpers/fixtures, since
+ // we re-use those in the theme tests.
+ app._defaultPackager.packageApplicationTests = function (tree) {
+ let appTestTrees = []
+ .concat(
+ this.packageEmberCliInternalFiles(),
+ this.packageTestApplicationConfig(),
+ tree
+ )
+ .filter(Boolean);
+
+ appTestTrees = mergeTrees(appTestTrees, {
+ overwrite: true,
+ annotation: "TreeMerger (appTestTrees)",
+ });
+
+ let tests = concat(appTestTrees, {
+ inputFiles: [
+ "**/tests/acceptance/*.js",
+ "**/tests/integration/*.js",
+ "**tests/unit/*.js",
+ ],
+ headerFiles: ["vendor/ember-cli/tests-prefix.js"],
+ footerFiles: ["vendor/ember-cli/app-config.js"],
+ outputFile: "/assets/core-tests.js",
+ annotation: "Concat: Core Tests",
+ sourceMapConfig: false,
+ });
+
+ let testHelpers = concat(appTestTrees, {
+ inputFiles: [
+ "**/tests/test-boot-ember-cli.js",
+ "**/tests/helpers/**/*.js",
+ "**/tests/fixtures/**/*.js",
+ "**/tests/setup-tests.js",
+ ],
+ outputFile: "/assets/test-helpers.js",
+ annotation: "Concat: Test Helpers",
+ sourceMapConfig: false,
+ });
+
+ return mergeTrees([tests, testHelpers]);
+ };
+
// WARNING: We should only import scripts here if they are not in NPM.
// For example: our very specific version of bootstrap-modal.
app.import(vendorJs + "bootbox.js");
diff --git a/app/assets/javascripts/discourse/package.json b/app/assets/javascripts/discourse/package.json
index 32b109253a9..056a33e0880 100644
--- a/app/assets/javascripts/discourse/package.json
+++ b/app/assets/javascripts/discourse/package.json
@@ -34,7 +34,7 @@
"discourse-common": "^1.0.0",
"discourse-hbr": "^1.0.0",
"discourse-widget-hbs": "^1.0.0",
- "ember-auto-import": "^1.10.1",
+ "ember-auto-import": "^1.12.0",
"ember-buffered-proxy": "^2.0.0-beta.0",
"ember-cli": "~3.25.3",
"ember-cli-app-version": "^4.0.0",
diff --git a/app/assets/javascripts/discourse/public/assets/scripts/discourse-test-listen-boot.js b/app/assets/javascripts/discourse/public/assets/scripts/discourse-test-listen-boot.js
new file mode 100644
index 00000000000..8f46890eb42
--- /dev/null
+++ b/app/assets/javascripts/discourse/public/assets/scripts/discourse-test-listen-boot.js
@@ -0,0 +1,4 @@
+document.write(
+ ""
+);
+require('discourse/tests/test-boot-ember-cli');
diff --git a/app/assets/javascripts/discourse/tests/plugin_tests.js.erb b/app/assets/javascripts/discourse/tests/active-plugins.js.erb
similarity index 53%
rename from app/assets/javascripts/discourse/tests/plugin_tests.js.erb
rename to app/assets/javascripts/discourse/tests/active-plugins.js.erb
index 0bb267961df..6b2958541e9 100644
--- a/app/assets/javascripts/discourse/tests/plugin_tests.js.erb
+++ b/app/assets/javascripts/discourse/tests/active-plugins.js.erb
@@ -8,13 +8,4 @@
require_asset(f)
end
end
-
- Discourse.plugins.each do |p|
- root_path = "#{File.dirname(p.path)}/test/javascripts"
-
- to_glob = [root_path + '/**/**.es6']
- to_glob << (root_path + '/**/**.js') if p.transpile_js
-
- Dir.glob(to_glob) { |f| require_asset(f) }
- end
%>
diff --git a/app/assets/javascripts/discourse/tests/core_plugins_tests.js b/app/assets/javascripts/discourse/tests/core-tests.js
similarity index 75%
rename from app/assets/javascripts/discourse/tests/core_plugins_tests.js
rename to app/assets/javascripts/discourse/tests/core-tests.js
index f9c99ce034e..1890b65888e 100644
--- a/app/assets/javascripts/discourse/tests/core_plugins_tests.js
+++ b/app/assets/javascripts/discourse/tests/core-tests.js
@@ -1,4 +1,3 @@
//= require_tree ./acceptance
//= require_tree ./integration
//= require_tree ./unit
-//= require ./plugin_tests
diff --git a/app/assets/javascripts/discourse/tests/index.html b/app/assets/javascripts/discourse/tests/index.html
index 34c33c48e40..1c9ac2bb559 100644
--- a/app/assets/javascripts/discourse/tests/index.html
+++ b/app/assets/javascripts/discourse/tests/index.html
@@ -50,9 +50,14 @@
-
+
-
+
+
+
+
{{content-for "body-footer"}}
diff --git a/app/assets/javascripts/discourse/tests/plugin-tests.js.erb b/app/assets/javascripts/discourse/tests/plugin-tests.js.erb
new file mode 100644
index 00000000000..f2b38319a4a
--- /dev/null
+++ b/app/assets/javascripts/discourse/tests/plugin-tests.js.erb
@@ -0,0 +1,10 @@
+<%
+ Discourse.plugins.each do |p|
+ root_path = "#{File.dirname(p.path)}/test/javascripts"
+
+ to_glob = [root_path + '/**/**.es6']
+ to_glob << (root_path + '/**/**.js') if p.transpile_js
+
+ Dir.glob(to_glob) { |f| require_asset(f) }
+ end
+%>
diff --git a/app/assets/javascripts/discourse/tests/test-helper.js b/app/assets/javascripts/discourse/tests/test-boot-ember-cli.js
similarity index 96%
rename from app/assets/javascripts/discourse/tests/test-helper.js
rename to app/assets/javascripts/discourse/tests/test-boot-ember-cli.js
index ffb266b9724..cfbc0b9ff8c 100644
--- a/app/assets/javascripts/discourse/tests/test-helper.js
+++ b/app/assets/javascripts/discourse/tests/test-boot-ember-cli.js
@@ -34,3 +34,4 @@ document.addEventListener("discourse-booted", () => {
setupEmberOnerrorValidation: !skippingCore,
});
});
+window.EmberENV.TESTS_FILE_LOADED = true;
diff --git a/app/assets/javascripts/discourse/tests/theme_qunit_helper.js b/app/assets/javascripts/discourse/tests/test-helpers-rails.js
similarity index 82%
rename from app/assets/javascripts/discourse/tests/theme_qunit_helper.js
rename to app/assets/javascripts/discourse/tests/test-helpers-rails.js
index a9c60c90f9e..71bb2c44530 100644
--- a/app/assets/javascripts/discourse/tests/theme_qunit_helper.js
+++ b/app/assets/javascripts/discourse/tests/test-helpers-rails.js
@@ -3,4 +3,3 @@
//= require_tree ./helpers
//= require_tree ./fixtures
//= require ./setup-tests
-//= require test-shims
diff --git a/app/assets/javascripts/discourse/tests/theme_qunit_tests_vendor.js b/app/assets/javascripts/discourse/tests/test-support-rails.js
similarity index 69%
rename from app/assets/javascripts/discourse/tests/theme_qunit_tests_vendor.js
rename to app/assets/javascripts/discourse/tests/test-support-rails.js
index 3c6865b1e04..4f916572efc 100644
--- a/app/assets/javascripts/discourse/tests/theme_qunit_tests_vendor.js
+++ b/app/assets/javascripts/discourse/tests/test-support-rails.js
@@ -5,11 +5,10 @@
//= require fake_xml_http_request
//= require route-recognizer
//= require pretender
-
-// These are not loaded in prod or development
-// But we need them for testing handlebars templates in qunit
-//= require handlebars
-//= require ember-template-compiler
-
//= require sinon
//= require break_string
+//= require test-shims
+//= require jquery.magnific-popup.min.js
+//= require handlebars
+//= require ember-template-compiler
+//= require markdown-it-bundle
diff --git a/app/assets/javascripts/discourse/tests/test_helper.js b/app/assets/javascripts/discourse/tests/test_helper.js
deleted file mode 100644
index 028f3a5167f..00000000000
--- a/app/assets/javascripts/discourse/tests/test_helper.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// discourse-skip-module
-
-//= require env
-//= require jquery.debug
-//= require jquery.ui.widget
-//= require ember.debug
-//= require message-bus
-//= require qunit
-//= require ember-qunit
-//= require fake_xml_http_request
-//= require route-recognizer
-//= require pretender
-//= require locales/i18n
-//= require locales/en
-//= require discourse-loader
-
-// Our base application
-//= require vendor
-//= require discourse-shims
-//= require markdown-it-bundle
-//= require application
-//= require admin
-
-// These are not loaded in prod or development
-// But we need them for testing handlebars templates in qunit
-//= require handlebars
-//= require ember-template-compiler
-
-// Test helpers
-//= require sinon
-//= require_tree ./helpers
-//= require break_string
-
-//= require_tree ./fixtures
-
-//= require ./setup-tests
-//= require test-shims
-//= require jquery.magnific-popup.min.js
diff --git a/app/assets/javascripts/discourse/tests/theme_qunit_vendor.js b/app/assets/javascripts/discourse/tests/theme_qunit_vendor.js
deleted file mode 100644
index 9eb492b917d..00000000000
--- a/app/assets/javascripts/discourse/tests/theme_qunit_vendor.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// This bundle contains the same dependencies as app/assets/javascripts/vendor.js
-// minus ember_jquery.
-// ember_jquery doesn't work with theme tests in production because it
-// contains production builds of Ember and jQuery, so we have a separate bundle
-// caled theme_qunit_ember_jquery which contains a debug build for Ember and jQuery.
-// We don't put theme_qunit_ember_jquery in this bundle because it would make the
-// bundle too big and cause OOM exceptions during rebuilds for self-hosters on
-// low-end machines.
-
-//= require logster
-
-//= require template_include.js
-
-//= require message-bus
-//= require jquery.ui.widget.js
-//= require Markdown.Converter.js
-//= require bootbox.js
-//= require popper.js
-//= require bootstrap-modal.js
-//= require caret_position
-//= require jquery.sortable.js
-//= require lodash.js
-//= require itsatrap.js
-//= require rsvp.js
-//= require uppy.js
-//= require buffered-proxy
-//= require virtual-dom
-//= require virtual-dom-amd
-//= require discourse-shims
-//= require pretty-text-bundle
diff --git a/app/assets/javascripts/yarn.lock b/app/assets/javascripts/yarn.lock
index 691b5eea85e..80a80588c24 100644
--- a/app/assets/javascripts/yarn.lock
+++ b/app/assets/javascripts/yarn.lock
@@ -4810,6 +4810,41 @@ ember-auto-import@^1.10.1, ember-auto-import@^1.5.3:
walk-sync "^0.3.3"
webpack "^4.43.0"
+ember-auto-import@^1.12.0:
+ version "1.12.0"
+ resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-1.12.0.tgz#52246b04891090e2608244e65c4c6af7710df12b"
+ integrity sha512-fzMGnyHGfUNFHchpLbJ98Vs/c5H2wZBMR9r/XwW+WOWPisZDGLUPPyhJQsSREPoUQ+o8GvyLaD/rkrKqW8bmgw==
+ dependencies:
+ "@babel/core" "^7.1.6"
+ "@babel/preset-env" "^7.10.2"
+ "@babel/traverse" "^7.1.6"
+ "@babel/types" "^7.1.6"
+ "@embroider/core" "^0.33.0"
+ babel-core "^6.26.3"
+ babel-loader "^8.0.6"
+ babel-plugin-syntax-dynamic-import "^6.18.0"
+ babylon "^6.18.0"
+ broccoli-debug "^0.6.4"
+ broccoli-node-api "^1.7.0"
+ broccoli-plugin "^4.0.0"
+ broccoli-source "^3.0.0"
+ debug "^3.1.0"
+ ember-cli-babel "^7.0.0"
+ enhanced-resolve "^4.0.0"
+ fs-extra "^6.0.1"
+ fs-tree-diff "^2.0.0"
+ handlebars "^4.3.1"
+ js-string-escape "^1.0.1"
+ lodash "^4.17.19"
+ mkdirp "^0.5.1"
+ resolve-package-path "^3.1.0"
+ rimraf "^2.6.2"
+ semver "^7.3.4"
+ symlink-or-copy "^1.2.0"
+ typescript-memoize "^1.0.0-alpha.3"
+ walk-sync "^0.3.3"
+ webpack "^4.43.0"
+
ember-buffered-proxy@^2.0.0-beta.0:
version "2.0.0-beta.0"
resolved "https://registry.yarnpkg.com/ember-buffered-proxy/-/ember-buffered-proxy-2.0.0-beta.0.tgz#65be4e2d0dcf40a5a2dab548c84a21aa332555a2"
diff --git a/app/controllers/bootstrap_controller.rb b/app/controllers/bootstrap_controller.rb
index 811058d7526..af3919e8285 100644
--- a/app/controllers/bootstrap_controller.rb
+++ b/app/controllers/bootstrap_controller.rb
@@ -69,7 +69,7 @@ class BootstrapController < ApplicationController
locale_script: locale,
stylesheets: @stylesheets,
plugin_js: plugin_js,
- plugin_test_js: [script_asset_path("plugin_tests")],
+ plugin_test_js: [script_asset_path("plugin-tests")],
setup_data: client_side_setup_data,
preloaded: @preloaded,
html: create_html,
diff --git a/app/controllers/qunit_controller.rb b/app/controllers/qunit_controller.rb
index 309d2af8b20..7e196d72369 100644
--- a/app/controllers/qunit_controller.rb
+++ b/app/controllers/qunit_controller.rb
@@ -8,15 +8,28 @@ class QunitController < ApplicationController
}
layout false
+ def is_ember_cli_proxy?
+ request.headers["HTTP_X_DISCOURSE_EMBER_CLI"] == "true"
+ end
+
# only used in test / dev
def index
- raise Discourse::NotFound.new if request.headers["HTTP_X_DISCOURSE_EMBER_CLI"] == "true"
+ raise Discourse::NotFound.new if is_ember_cli_proxy?
raise Discourse::InvalidAccess.new if Rails.env.production?
end
def theme
raise Discourse::NotFound.new if !can_see_theme_qunit?
+ @is_proxied = is_ember_cli_proxy?
+ @legacy_ember = Rails.env.development? && !@is_proxied
+
+ # In production mode all bundles use `application`
+ @app_bundle = "application"
+ if Rails.env.development? && @is_proxied
+ @app_bundle = "discourse"
+ end
+
param_key = nil
@suggested_themes = nil
if (id = get_param(:id)).present?
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index c5a96271231..f232bd5b7e5 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -13,9 +13,11 @@ module ApplicationHelper
@extra_body_classes ||= Set.new
end
- def discourse_config_environment
+ def discourse_config_environment(testing: false)
+
# TODO: Can this come from Ember CLI somehow?
- { modulePrefix: "discourse",
+ config = {
+ modulePrefix: "discourse",
environment: Rails.env,
rootURL: Discourse.base_path,
locationType: "auto",
@@ -32,7 +34,16 @@ module ApplicationHelper
version: "#{Discourse::VERSION::STRING} #{Discourse.git_version}",
exportApplicationGlobal: true
}
- }.to_json
+ }
+
+ if testing
+ config[:environment] = "test"
+ config[:locationType] = "none"
+ config[:APP][:autoboot] = false
+ config[:APP][:rootElement] = '#ember-testing'
+ end
+
+ config.to_json
end
def google_universal_analytics_json(ua_domain_name = nil)
diff --git a/app/helpers/qunit_helper.rb b/app/helpers/qunit_helper.rb
index e0376a1ad26..029c4d04c97 100644
--- a/app/helpers/qunit_helper.rb
+++ b/app/helpers/qunit_helper.rb
@@ -1,6 +1,33 @@
# frozen_string_literal: true
module QunitHelper
+
+ def support_bundles
+ result = []
+ if Rails.env.production? || @legacy_ember
+ result << preload_script("discourse/tests/test-support-rails")
+ result << preload_script("discourse/tests/test-helpers-rails")
+ else
+ result << preload_script("test-support")
+ result << preload_script("test-helpers")
+ end
+ result.join("\n").html_safe
+ end
+
+ def boot_bundles
+ result = []
+ if @legacy_ember
+ result << preload_script("discourse/tests/test_starter")
+ elsif @is_proxied
+ result << preload_script("scripts/discourse-test-listen-boot")
+ result << preload_script("scripts/discourse-boot")
+ else
+ result << preload_script("discourse-test-listen-boot")
+ result << preload_script("discourse-boot")
+ end
+ result.join("\n").html_safe
+ end
+
def theme_tests
theme = Theme.find_by(id: request.env[:resolved_theme_id])
return "" if theme.blank?
diff --git a/app/views/qunit/index.html.erb b/app/views/qunit/index.html.erb
index 830e3d8bb50..9912387a2d7 100644
--- a/app/views/qunit/index.html.erb
+++ b/app/views/qunit/index.html.erb
@@ -5,8 +5,15 @@
<%= discourse_color_scheme_stylesheets %>
<%= discourse_stylesheet_link_tag(:desktop, theme_id: nil) %>
<%= discourse_stylesheet_link_tag(:test_helper, theme_id: nil) %>
- <%= preload_script "discourse/tests/test_helper" %>
- <%= preload_script "discourse/tests/core_plugins_tests" %>
+ <%= preload_script "locales/#{I18n.locale}" %>
+ <%= preload_script "vendor" %>
+ <%= preload_script "application" %>
+ <%= preload_script "admin" %>
+ <%= preload_script "discourse/tests/test-support-rails" %>
+ <%= preload_script "discourse/tests/test-helpers-rails" %>
+ <%= preload_script "discourse/tests/active-plugins" %>
+ <%= preload_script "discourse/tests/core-tests" %>
+ <%= preload_script "discourse/tests/plugin-tests" %>
<%= preload_script "discourse/tests/test_starter" %>
<%= csrf_meta_tags %>
diff --git a/app/views/qunit/theme.html.erb b/app/views/qunit/theme.html.erb
index 53752cc9a29..23db6bf4513 100644
--- a/app/views/qunit/theme.html.erb
+++ b/app/views/qunit/theme.html.erb
@@ -6,17 +6,12 @@
<%- if !@suggested_themes %>
<%= discourse_stylesheet_link_tag(:desktop, theme_id: nil) %>
<%= discourse_stylesheet_link_tag(:test_helper, theme_id: nil) %>
- <%= preload_script "locales/en" %>
- <%= preload_script "discourse/tests/theme_qunit_ember_jquery" %>
- <%= preload_script "discourse/tests/theme_qunit_vendor" %>
- <%= preload_script "discourse/tests/theme_qunit_tests_vendor" %>
- <%= preload_script "markdown-it-bundle" %>
- <%= preload_script "application" %>
- <%- Discourse.find_plugin_js_assets(include_official: allow_plugins?, include_unofficial: allow_third_party_plugins?, request: request).each do |file| %>
- <%= preload_script file %>
- <%- end %>
+ <%= preload_script "locales/#{I18n.locale}" %>
+ <%= preload_script "vendor" %>
+ <%= preload_script @app_bundle %>
<%= preload_script "admin" %>
- <%= preload_script "discourse/tests/theme_qunit_helper" %>
+ <%= preload_script "discourse/tests/active-plugins" %>
+ <%= support_bundles %>
<%= theme_translations_lookup %>
<%= theme_js_lookup %>
<%= theme_lookup("head_tag") %>
@@ -24,7 +19,7 @@
<%= tag.meta id: 'data-discourse-setup', data: client_side_setup_data %>
- <%= preload_script "discourse/tests/test_starter" %>
+
<%- else %>