DEV: Support for running theme test with Ember CLI (second attempt)

This PR includes support for running theme tests in legacy ember
production envrionments.
This commit is contained in:
Robin Ward 2022-01-12 13:15:35 -05:00
parent 584c6a2e8b
commit 2c7906999a
30 changed files with 273 additions and 152 deletions

@ -12,7 +12,7 @@ lib/highlight_js/
plugins/**/lib/javascripts/locale plugins/**/lib/javascripts/locale
public/ public/
vendor/ vendor/
app/assets/javascripts/discourse/tests/test_helper.js app/assets/javascripts/discourse/tests/test-boot-rails.js
app/assets/javascripts/discourse/tests/fixtures app/assets/javascripts/discourse/tests/fixtures
node_modules/ node_modules/
dist/ dist/

@ -20,7 +20,7 @@ lib/highlight_js/
plugins/**/lib/javascripts/locale plugins/**/lib/javascripts/locale
public/ public/
vendor/ vendor/
app/assets/javascripts/discourse/tests/test_helper.js app/assets/javascripts/discourse/tests/test-boot-rails.js
app/assets/javascripts/discourse/tests/fixtures app/assets/javascripts/discourse/tests/fixtures
node_modules/ node_modules/
dist/ dist/

@ -11,7 +11,9 @@ let testingFunc = isLegacyEmber() ? run : next;
export default function () { export default function () {
if (isTesting()) { 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 { } else {
return debounce(...arguments); return debounce(...arguments);
} }

@ -37,8 +37,66 @@ module.exports = function (defaults) {
// We don't use SRI in Rails. Disable here to match: // We don't use SRI in Rails. Disable here to match:
enabled: false, 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. // WARNING: We should only import scripts here if they are not in NPM.
// For example: our very specific version of bootstrap-modal. // For example: our very specific version of bootstrap-modal.
app.import(vendorJs + "bootbox.js"); app.import(vendorJs + "bootbox.js");

@ -34,7 +34,7 @@
"discourse-common": "^1.0.0", "discourse-common": "^1.0.0",
"discourse-hbr": "^1.0.0", "discourse-hbr": "^1.0.0",
"discourse-widget-hbs": "^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-buffered-proxy": "^2.0.0-beta.0",
"ember-cli": "~3.25.3", "ember-cli": "~3.25.3",
"ember-cli-app-version": "^4.0.0", "ember-cli-app-version": "^4.0.0",

@ -0,0 +1,4 @@
document.write(
"<style>#ember-testing-container { position: fixed; background: white; bottom: 0; right: 0; width: 640px; height: 384px; overflow: auto; z-index: 9999; border: 1px solid #ccc; transform: translateZ(0)} #ember-testing { width: 200%; height: 200%; transform: scale(0.5); transform-origin: top left; }</style>"
);
require('discourse/tests/test-boot-ember-cli');

@ -8,13 +8,4 @@
require_asset(f) require_asset(f)
end end
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
%> %>

@ -1,4 +1,3 @@
//= require_tree ./acceptance //= require_tree ./acceptance
//= require_tree ./integration //= require_tree ./integration
//= require_tree ./unit //= require_tree ./unit
//= require ./plugin_tests

@ -50,9 +50,14 @@
<script src="{{rootURL}}assets/test-support.js"></script> <script src="{{rootURL}}assets/test-support.js"></script>
<script src="{{rootURL}}assets/discourse.js"></script> <script src="{{rootURL}}assets/discourse.js"></script>
<script src="{{rootURL}}assets/discourse-markdown.js"></script> <script src="{{rootURL}}assets/discourse-markdown.js"></script>
<script src="{{rootURL}}assets/discourse/tests/core_plugins_tests.js"></script> <script src="{{rootURL}}assets/discourse/tests/active-plugins.js"></script>
<script src="{{rootURL}}assets/admin.js"></script> <script src="{{rootURL}}assets/admin.js"></script>
<script src="{{rootURL}}assets/tests.js"></script> <script src="{{rootURL}}assets/test-helpers.js"></script>
<script src="{{rootURL}}assets/core-tests.js"></script>
<script src="{{rootURL}}assets/discourse/tests/plugin-tests.js"></script>
<script>
require('discourse/tests/test-boot-ember-cli');
</script>
<script src="{{rootURL}}assets/scripts/discourse-boot.js"></script> <script src="{{rootURL}}assets/scripts/discourse-boot.js"></script>
{{content-for "body-footer"}} {{content-for "body-footer"}}

@ -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
%>

@ -34,3 +34,4 @@ document.addEventListener("discourse-booted", () => {
setupEmberOnerrorValidation: !skippingCore, setupEmberOnerrorValidation: !skippingCore,
}); });
}); });
window.EmberENV.TESTS_FILE_LOADED = true;

@ -3,4 +3,3 @@
//= require_tree ./helpers //= require_tree ./helpers
//= require_tree ./fixtures //= require_tree ./fixtures
//= require ./setup-tests //= require ./setup-tests
//= require test-shims

@ -5,11 +5,10 @@
//= require fake_xml_http_request //= require fake_xml_http_request
//= require route-recognizer //= require route-recognizer
//= require pretender //= 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 sinon
//= require break_string //= require break_string
//= require test-shims
//= require jquery.magnific-popup.min.js
//= require handlebars
//= require ember-template-compiler
//= require markdown-it-bundle

@ -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

@ -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

@ -1,5 +1,5 @@
<% <%
if Rails.env.development? || Rails.env.test? if @force_ember_debug || Rails.env.development? || Rails.env.test?
require_asset ("ember.debug.js") require_asset ("ember.debug.js")
else else
require_asset ("ember.prod.js") require_asset ("ember.prod.js")

@ -0,0 +1,21 @@
//= 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

@ -0,0 +1,6 @@
//= require set-prototype-polyfill
//= require env
//= require jquery
//= require ember.debug.js
//= require discourse-loader
//= require vendor-common

@ -1,23 +1,2 @@
//= require ember_jquery //= require ember_jquery
//= require vendor-common
//= 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

@ -4810,6 +4810,41 @@ ember-auto-import@^1.10.1, ember-auto-import@^1.5.3:
walk-sync "^0.3.3" walk-sync "^0.3.3"
webpack "^4.43.0" 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: ember-buffered-proxy@^2.0.0-beta.0:
version "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" resolved "https://registry.yarnpkg.com/ember-buffered-proxy/-/ember-buffered-proxy-2.0.0-beta.0.tgz#65be4e2d0dcf40a5a2dab548c84a21aa332555a2"

@ -69,7 +69,7 @@ class BootstrapController < ApplicationController
locale_script: locale, locale_script: locale,
stylesheets: @stylesheets, stylesheets: @stylesheets,
plugin_js: plugin_js, 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, setup_data: client_side_setup_data,
preloaded: @preloaded, preloaded: @preloaded,
html: create_html, html: create_html,

@ -8,15 +8,32 @@ class QunitController < ApplicationController
} }
layout false layout false
def is_ember_cli_proxy?
request.headers["HTTP_X_DISCOURSE_EMBER_CLI"] == "true"
end
# only used in test / dev # only used in test / dev
def index 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? raise Discourse::InvalidAccess.new if Rails.env.production?
end end
def theme def theme
raise Discourse::NotFound.new if !can_see_theme_qunit? raise Discourse::NotFound.new if !can_see_theme_qunit?
@is_proxied = is_ember_cli_proxy?
@legacy_ember = if Rails.env.production?
ENV['EMBER_CLI_PROD_ASSETS'] != "1"
else
!@is_proxied
end
# In production mode all bundles use `application`
@app_bundle = "application"
if Rails.env.development? && @is_proxied
@app_bundle = "discourse"
end
param_key = nil param_key = nil
@suggested_themes = nil @suggested_themes = nil
if (id = get_param(:id)).present? if (id = get_param(:id)).present?

@ -13,9 +13,11 @@ module ApplicationHelper
@extra_body_classes ||= Set.new @extra_body_classes ||= Set.new
end end
def discourse_config_environment def discourse_config_environment(testing: false)
# TODO: Can this come from Ember CLI somehow? # TODO: Can this come from Ember CLI somehow?
{ modulePrefix: "discourse", config = {
modulePrefix: "discourse",
environment: Rails.env, environment: Rails.env,
rootURL: Discourse.base_path, rootURL: Discourse.base_path,
locationType: "auto", locationType: "auto",
@ -32,7 +34,16 @@ module ApplicationHelper
version: "#{Discourse::VERSION::STRING} #{Discourse.git_version}", version: "#{Discourse::VERSION::STRING} #{Discourse.git_version}",
exportApplicationGlobal: true 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 end
def google_universal_analytics_json(ua_domain_name = nil) def google_universal_analytics_json(ua_domain_name = nil)

@ -1,6 +1,38 @@
# frozen_string_literal: true # frozen_string_literal: true
module QunitHelper module QunitHelper
def vendor_theme_tests
return preload_script("vendor-theme-tests") if @legacy_ember
preload_script("vendor")
end
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 def theme_tests
theme = Theme.find_by(id: request.env[:resolved_theme_id]) theme = Theme.find_by(id: request.env[:resolved_theme_id])
return "" if theme.blank? return "" if theme.blank?

@ -5,8 +5,15 @@
<%= discourse_color_scheme_stylesheets %> <%= discourse_color_scheme_stylesheets %>
<%= discourse_stylesheet_link_tag(:desktop, theme_id: nil) %> <%= discourse_stylesheet_link_tag(:desktop, theme_id: nil) %>
<%= discourse_stylesheet_link_tag(:test_helper, theme_id: nil) %> <%= discourse_stylesheet_link_tag(:test_helper, theme_id: nil) %>
<%= preload_script "discourse/tests/test_helper" %> <%= preload_script "locales/#{I18n.locale}" %>
<%= preload_script "discourse/tests/core_plugins_tests" %> <%= 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" %> <%= preload_script "discourse/tests/test_starter" %>
<%= csrf_meta_tags %> <%= csrf_meta_tags %>
<meta property="og:title" content=""> <meta property="og:title" content="">

@ -6,17 +6,12 @@
<%- if !@suggested_themes %> <%- if !@suggested_themes %>
<%= discourse_stylesheet_link_tag(:desktop, theme_id: nil) %> <%= discourse_stylesheet_link_tag(:desktop, theme_id: nil) %>
<%= discourse_stylesheet_link_tag(:test_helper, theme_id: nil) %> <%= discourse_stylesheet_link_tag(:test_helper, theme_id: nil) %>
<%= preload_script "locales/en" %> <%= preload_script "locales/#{I18n.locale}" %>
<%= preload_script "discourse/tests/theme_qunit_ember_jquery" %> <%= vendor_theme_tests %>
<%= preload_script "discourse/tests/theme_qunit_vendor" %> <%= preload_script @app_bundle %>
<%= 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 "admin" %> <%= preload_script "admin" %>
<%= preload_script "discourse/tests/theme_qunit_helper" %> <%= preload_script "discourse/tests/active-plugins" %>
<%= support_bundles %>
<%= theme_translations_lookup %> <%= theme_translations_lookup %>
<%= theme_js_lookup %> <%= theme_js_lookup %>
<%= theme_lookup("head_tag") %> <%= theme_lookup("head_tag") %>
@ -24,7 +19,7 @@
<%= tag.meta id: 'data-discourse-setup', data: client_side_setup_data %> <%= tag.meta id: 'data-discourse-setup', data: client_side_setup_data %>
<meta property="og:title" content=""> <meta property="og:title" content="">
<meta property="og:url" content=""> <meta property="og:url" content="">
<%= preload_script "discourse/tests/test_starter" %> <meta name="discourse/config/environment" content="<%=u discourse_config_environment(testing: true) %>" />
<%- else %> <%- else %>
<style> <style>
html { html {
@ -35,8 +30,10 @@
</head> </head>
<body> <body>
<%- if !@suggested_themes %> <%- if !@suggested_themes %>
<div id="qunit"></div> <%- if @legacy_ember %>
<div id="qunit-fixture"></div> <div id="qunit"></div>
<div id="qunit-fixture"></div>
<%- end %>
<%- else %> <%- else %>
<h2>Theme QUnit Test Runner</h2> <h2>Theme QUnit Test Runner</h2>
<%- if @suggested_themes.size == 0 %> <%- if @suggested_themes.size == 0 %>
@ -49,4 +46,7 @@
<%- end %> <%- end %>
<%- end %> <%- end %>
</body> </body>
<%- if !@suggested_themes %>
<%= boot_bundles %>
<%- end %>
</html> </html>

@ -176,13 +176,18 @@ module Discourse
confirm-new-email/bootstrap.js confirm-new-email/bootstrap.js
onpopstate-handler.js onpopstate-handler.js
embed-application.js embed-application.js
discourse/tests/theme_qunit_ember_jquery.js discourse/tests/active-plugins.js
discourse/tests/theme_qunit_vendor.js
discourse/tests/theme_qunit_tests_vendor.js
discourse/tests/theme_qunit_helper.js
discourse/tests/test_starter.js discourse/tests/test_starter.js
} }
if ENV['EMBER_CLI_PROD_ASSETS'] != "1"
config.assets.precompile += %w{
discourse/tests/test-support-rails.js
discourse/tests/test-helpers-rails.js
vendor-theme-tests.js
}
end
# Precompile all available locales # Precompile all available locales
unless GlobalSetting.try(:omit_base_locales) unless GlobalSetting.try(:omit_base_locales)
Dir.glob("#{config.root}/app/assets/javascripts/locales/*.js.erb").each do |file| Dir.glob("#{config.root}/app/assets/javascripts/locales/*.js.erb").each do |file|
@ -370,7 +375,7 @@ module Discourse
%w{qunit.js %w{qunit.js
qunit.css qunit.css
test_helper.css test_helper.css
discourse/tests/test_helper.js discourse/tests/test-boot-rails.js
wizard/test/test_helper.js wizard/test/test_helper.js
}.include?(logical_path) || }.include?(logical_path) ||
logical_path =~ /\/node_modules/ || logical_path =~ /\/node_modules/ ||

@ -32,7 +32,7 @@ module Autospec
# Discourse specific # Discourse specific
reload(%r{^discourse/tests/javascripts/fixtures/.+_fixtures\.js(\.es6)?$}) reload(%r{^discourse/tests/javascripts/fixtures/.+_fixtures\.js(\.es6)?$})
reload(%r{^discourse/tests/javascripts/(helpers|mixins)/.+\.js(\.es6)?$}) reload(%r{^discourse/tests/javascripts/(helpers|mixins)/.+\.js(\.es6)?$})
reload("app/assets/javascripts/discoruse/tests/javascripts/test_helper.js") reload("app/assets/javascripts/discoruse/tests/javascripts/test-boot-rails.js")
watch(%r{^plugins/.*/test/.+\.js(\.es6)?$}) watch(%r{^plugins/.*/test/.+\.js(\.es6)?$})

@ -39,8 +39,7 @@ task 'assets:precompile:before' do
# Remove the assets that Ember CLI will handle for us # Remove the assets that Ember CLI will handle for us
Rails.configuration.assets.precompile.reject! do |asset| Rails.configuration.assets.precompile.reject! do |asset|
asset.is_a?(String) && asset.is_a?(String) &&
(%w(application.js admin.js ember_jquery.js pretty-text-bundle.js start-discourse.js vendor.js).include?(asset) || (%w(application.js admin.js ember_jquery.js pretty-text-bundle.js start-discourse.js vendor.js).include?(asset))
asset.start_with?("discourse/tests"))
end end
end end
end end
@ -250,9 +249,14 @@ def copy_ember_cli_assets
# Copy assets and generate manifest data # Copy assets and generate manifest data
log_task_duration('Copy assets and generate manifest data') { log_task_duration('Copy assets and generate manifest data') {
Dir["#{ember_cli_assets}**/*"].each do |f| Dir["#{ember_cli_assets}**/*"].each do |f|
if f !~ /test/ && File.file?(f) if File.file?(f)
rel_file = f.sub(ember_cli_assets, "") rel_file = f.sub(ember_cli_assets, "")
digest = f.scan(/\-([a-f0-9]+)\./)[0][0] file_digest = Digest::SHA384.digest(File.read(f))
digest = if f =~ /\-([a-f0-9]+)\./
Regexp.last_match[1]
else
Digest.hexencode(file_digest)[0...32]
end
dest = "public/assets" dest = "public/assets"
dest_sub = dest dest_sub = dest
@ -263,10 +267,17 @@ def copy_ember_cli_assets
FileUtils.mkdir_p(dest_sub) unless Dir.exist?(dest_sub) FileUtils.mkdir_p(dest_sub) unless Dir.exist?(dest_sub)
log_file = File.basename(rel_file).sub("-#{digest}", "") log_file = File.basename(rel_file).sub("-#{digest}", "")
# It's simpler to serve the file as `application.js` # We need a few hacks here to move what Ember uses to what Rails wants
if log_file == "discourse.js" case log_file
when "discourse.js"
log_file = "application.js" log_file = "application.js"
rel_file.sub!(/^discourse/, "application") rel_file.sub!(/^discourse/, "application")
when "test-support.js"
log_file = "discourse/tests/test-support-rails.js"
rel_file = "discourse/tests/test-support-rails-#{digest}.js"
when "test-helpers.js"
log_file = "discourse/tests/test-helpers-rails.js"
rel_file = "discourse/tests/test-helpers-rails-#{digest}.js"
end end
res = FileUtils.cp(f, "#{dest}/#{rel_file}") res = FileUtils.cp(f, "#{dest}/#{rel_file}")
@ -277,7 +288,7 @@ def copy_ember_cli_assets
"mtime" => File.mtime(f).iso8601(9), "mtime" => File.mtime(f).iso8601(9),
"size" => File.size(f), "size" => File.size(f),
"digest" => digest, "digest" => digest,
"integrity" => "sha384-#{Base64.encode64(Digest::SHA384.digest(File.read(f))).chomp}" "integrity" => "sha384-#{Base64.encode64(file_digest).chomp}"
} }
end end
end end

@ -98,16 +98,13 @@ describe QunitController do
expect(response.body).to include("/stylesheets/desktop_") expect(response.body).to include("/stylesheets/desktop_")
expect(response.body).to include("/stylesheets/test_helper_") expect(response.body).to include("/stylesheets/test_helper_")
expect(response.body).to include("/assets/locales/en.js") expect(response.body).to include("/assets/locales/en.js")
expect(response.body).to include("/assets/discourse/tests/theme_qunit_ember_jquery.js") expect(response.body).to include("/test-support")
expect(response.body).to include("/assets/discourse/tests/theme_qunit_vendor.js") expect(response.body).to include("/test-helpers")
expect(response.body).to include("/assets/discourse/tests/theme_qunit_tests_vendor.js")
expect(response.body).to include("/assets/markdown-it-bundle.js") expect(response.body).to include("/assets/markdown-it-bundle.js")
expect(response.body).to include("/assets/application.js") expect(response.body).to include("/assets/application.js")
expect(response.body).to include("/assets/admin.js") expect(response.body).to include("/assets/admin.js")
expect(response.body).to include("/assets/discourse/tests/theme_qunit_helper.js")
expect(response.body).to match(/\/theme-javascripts\/\h{40}\.js/) expect(response.body).to match(/\/theme-javascripts\/\h{40}\.js/)
expect(response.body).to include("/theme-javascripts/tests/#{theme.id}-") expect(response.body).to include("/theme-javascripts/tests/#{theme.id}-")
expect(response.body).to include("/assets/discourse/tests/test_starter.js")
end end
end end
end end