From 3d7c26c15e6a4c834129addef752548208944a40 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Tue, 11 Jun 2019 12:41:27 -0400 Subject: [PATCH] FIX: Memory Leaks w/ Container (#7750) Gives instance initializers the ability to add a `teardown` method that will be called between tests to clean up after themselves. --- .../discourse/initializers/csrf-token.js.es6 | 25 ++++++++++++------- test/javascripts/test_helper.js | 9 +++++++ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/discourse/initializers/csrf-token.js.es6 b/app/assets/javascripts/discourse/initializers/csrf-token.js.es6 index 0ddd5dda5d5..3edee0161e2 100644 --- a/app/assets/javascripts/discourse/initializers/csrf-token.js.es6 +++ b/app/assets/javascripts/discourse/initializers/csrf-token.js.es6 @@ -1,21 +1,28 @@ // Append our CSRF token to AJAX requests when necessary. -let installedFilter = false; +let installed = false; +let callbacks = $.Callbacks(); export default { name: "csrf-token", - initialize: function(container) { + initialize(container) { // Add a CSRF token to all AJAX requests let session = container.lookup("session:main"); session.set("csrfToken", $("meta[name=csrf-token]").attr("content")); - if (!installedFilter) { - $.ajaxPrefilter(function(options, originalOptions, xhr) { - if (!options.crossDomain) { - xhr.setRequestHeader("X-CSRF-Token", session.get("csrfToken")); - } - }); - installedFilter = true; + if (!installed) { + $.ajaxPrefilter(callbacks.fire); + installed = true; } + + callbacks.add(function(options, originalOptions, xhr) { + if (!options.crossDomain) { + xhr.setRequestHeader("X-CSRF-Token", session.get("csrfToken")); + } + }); + }, + + teardown() { + callbacks.empty(); } }; diff --git a/test/javascripts/test_helper.js b/test/javascripts/test_helper.js index ee3ee129d89..9d9d859da1a 100644 --- a/test/javascripts/test_helper.js +++ b/test/javascripts/test_helper.js @@ -169,6 +169,15 @@ QUnit.testDone(function() { }); }); + Discourse._runInitializer("instanceInitializers", function( + name, + initializer + ) { + if (initializer && initializer.teardown) { + initializer.teardown(); + } + }); + // attempts to remove any subscribed message bus callback window.MessageBus.callbacks.forEach(function(callback) { window.MessageBus.unsubscribe(callback.channel, callback.func);