From f055d1bda4eb3701ed8293a022a58e7e3a37c0af Mon Sep 17 00:00:00 2001
From: Giles Thompson <giles@papaiti.com>
Date: Sat, 7 Oct 2023 14:45:19 +1300
Subject: [PATCH 1/5] feat(test helper): replace tests helper blueprint with
 test support helper functions

---
 .../files/tests/helpers/flash-message.js      |  3 --
 .../blueprints/ember-cli-flash/index.js       | 17 -------
 ember-cli-flash/src/test-support.js           | 12 +++++
 test-app/tests/unit/flash/object-test.js      | 46 +++++++++++++++++++
 4 files changed, 58 insertions(+), 20 deletions(-)
 delete mode 100644 ember-cli-flash/blueprints/ember-cli-flash/files/tests/helpers/flash-message.js
 delete mode 100644 ember-cli-flash/blueprints/ember-cli-flash/index.js
 create mode 100644 ember-cli-flash/src/test-support.js

diff --git a/ember-cli-flash/blueprints/ember-cli-flash/files/tests/helpers/flash-message.js b/ember-cli-flash/blueprints/ember-cli-flash/files/tests/helpers/flash-message.js
deleted file mode 100644
index 56646e87..00000000
--- a/ember-cli-flash/blueprints/ember-cli-flash/files/tests/helpers/flash-message.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import FlashObject from 'ember-cli-flash/flash/object';
-
-FlashObject.reopen({ init() {} });
diff --git a/ember-cli-flash/blueprints/ember-cli-flash/index.js b/ember-cli-flash/blueprints/ember-cli-flash/index.js
deleted file mode 100644
index c7014594..00000000
--- a/ember-cli-flash/blueprints/ember-cli-flash/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-var EOL = require('os').EOL;
-
-module.exports = {
-  description: 'Generates ember-cli-flash test helper',
-
-  afterInstall() {
-    const TEST_HELPER_PATH = 'tests/test-helper.js';
-    const IMPORT_STATEMENT = EOL + "import './helpers/flash-message';";
-    const INSERT_AFTER = "import { start } from 'ember-qunit';";
-
-    return this.insertIntoFile(TEST_HELPER_PATH, IMPORT_STATEMENT, {
-      after: INSERT_AFTER,
-    });
-  },
-
-  normalizeEntityName() {},
-};
diff --git a/ember-cli-flash/src/test-support.js b/ember-cli-flash/src/test-support.js
new file mode 100644
index 00000000..0f61d012
--- /dev/null
+++ b/ember-cli-flash/src/test-support.js
@@ -0,0 +1,12 @@
+import FlashObject from './flash/object';
+
+const originalInit = FlashObject.prototype.init;
+const noopInit = () => {};
+
+export function disableTimers() {
+  FlashObject.reopen({ init: noopInit });
+}
+
+export function enableTimers() {
+  FlashObject.reopen({ init: originalInit });
+}
diff --git a/test-app/tests/unit/flash/object-test.js b/test-app/tests/unit/flash/object-test.js
index e2711150..b87ae72b 100644
--- a/test-app/tests/unit/flash/object-test.js
+++ b/test-app/tests/unit/flash/object-test.js
@@ -2,10 +2,56 @@ import { run, later } from '@ember/runloop';
 import { isPresent } from '@ember/utils';
 import { module, test } from 'qunit';
 import FlashMessage from 'ember-cli-flash/flash/object';
+import { disableTimers, enableTimers } from 'ember-cli-flash/test-support';
 
 const testTimerDuration = 50;
 let flash = null;
 
+module('FlashMessageObject disableTimers', function (hooks) {
+  hooks.beforeEach(function () {
+    disableTimers();
+    flash = FlashMessage.create({
+      type: 'test',
+      message: 'Cool story brah',
+      timeout: testTimerDuration,
+      service: {},
+    });
+  });
+
+  hooks.afterEach(function () {
+    flash = null;
+    enableTimers();
+  });
+
+  test('it does not create a timer', function (assert) {
+    assert.notOk(flash.get('timerTaskInstance'), 'it does not create a timer');
+  });
+});
+
+module('FlashMessageObject enableTimers', function (hooks) {
+  hooks.beforeEach(function () {
+    disableTimers();
+    enableTimers();
+    flash = FlashMessage.create({
+      type: 'test',
+      message: 'Cool story brah',
+      timeout: testTimerDuration,
+      service: {},
+    });
+  });
+
+  hooks.afterEach(function () {
+    flash = null;
+  });
+
+  test('it sets a timer after init', function (assert) {
+    assert.ok(
+      isPresent(flash.get('timerTaskInstance')),
+      'it does create a timer'
+    );
+  });
+});
+
 module('FlashMessageObject', function (hooks) {
   hooks.beforeEach(function () {
     flash = FlashMessage.create({

From 9f5a24d1996b8b0364924870847247c435134df2 Mon Sep 17 00:00:00 2001
From: Giles Thompson <giles@papaiti.com>
Date: Mon, 23 Oct 2023 14:14:29 +1300
Subject: [PATCH 2/5] doc(upgrading): add instructions for upgrading to static
 test helpers

---
 UPGRADING.md | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 UPGRADING.md

diff --git a/UPGRADING.md b/UPGRADING.md
new file mode 100644
index 00000000..8a7828ef
--- /dev/null
+++ b/UPGRADING.md
@@ -0,0 +1,40 @@
+# Upgrading ember-cli-flash
+
+## Upgrading to v5
+
+### Test helpers
+
+In previous versions an install-time blueprint would add an import to consuming apps' `tests/test-helper.js` file.
+
+This was used to disable the async timer functionality when displaying flash messages. For most apps this is a sensible default.
+
+Most apps with this addon installed will have the following import in their `tests/test-helper.js`:
+
+```js
+// tests/test-helper.js
+import './helpers/flash-message';
+```
+
+Remove this import and replace it with the `disableTimers` helper function. This helper function _should also be invoked_ within the same file.
+
+```diff
+// tests/test-helper.js
+import Application from 'example-app/app';
+import config from 'example-app/config/environment';
+import * as QUnit from 'qunit';
+import { setApplication } from '@ember/test-helpers';
+import { setup } from 'qunit-dom';
+import { start } from 'ember-qunit';
+- import './helpers/flash-message';
++ import { disableTimers } from 'ember-cli-flash/test-support';
+
++ disableTimers();
+
+setApplication(Application.create(config.APP));
+
+setup(QUnit.assert);
+
+start();
+```
+
+An `enableTimers` helper is also provided for fine-grained control at any time during test runs.

From d8d0a160187126180da80d338a92ab778ee26756 Mon Sep 17 00:00:00 2001
From: Giles Thompson <giles@papaiti.com>
Date: Mon, 23 Oct 2023 14:18:26 +1300
Subject: [PATCH 3/5] docs(installation): add disableTimers suggestion to the
 installation guide

---
 README.md | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/README.md b/README.md
index 82b3ac62..8cf96030 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,27 @@ This ember addon adds a flash message service and component to your app.
 ember install ember-cli-flash
 ```
 
+You may also want to disable flash message timers during test runs by adding the following to `tests/test-helper.js`:
+
+```diff
+// tests/test-helper.js
+import Application from 'example-app/app';
+import config from 'example-app/config/environment';
+import * as QUnit from 'qunit';
+import { setApplication } from '@ember/test-helpers';
+import { setup } from 'qunit-dom';
+import { start } from 'ember-qunit';
++ import { disableTimers } from 'ember-cli-flash/test-support';
+
++ disableTimers();
+
+setApplication(Application.create(config.APP));
+
+setup(QUnit.assert);
+
+start();
+```
+
 ## Compatibility
 This addon is tested against the Ember `release`, `beta` and `canary` channels, back to Ember `v3.28`.
 

From eff1425c48e3e367f8eec59bc7a1bebe6e423e4e Mon Sep 17 00:00:00 2001
From: Giles Thompson <giles@papaiti.com>
Date: Mon, 23 Oct 2023 14:36:23 +1300
Subject: [PATCH 4/5] docs(test helpers): add docs and examples

---
 README.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 62 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md
index 8cf96030..5c4e428b 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ This ember addon adds a flash message service and component to your app.
 ember install ember-cli-flash
 ```
 
-You may also want to disable flash message timers during test runs by adding the following to `tests/test-helper.js`:
+It's also recommended to disable flash message timers during test runs by adding the following to `tests/test-helper.js`:
 
 ```diff
 // tests/test-helper.js
@@ -63,6 +63,8 @@ setup(QUnit.assert);
 start();
 ```
 
+For more information about test helpers see: [Test helpers](#test-helpers)
+
 ## Compatibility
 This addon is tested against the Ember `release`, `beta` and `canary` channels, back to Ember `v3.28`.
 
@@ -426,14 +428,68 @@ If the provided component isn't to your liking, you can easily create your own.
 {{/each}}
 ```
 
-## Acceptance / Integration tests
-When you install the addon, it should automatically generate a helper located at `tests/helpers/flash-message.js`. You can do this manually as well:
+## Test helpers
+
+This addon provides helper functions which enable disabling and enabling flash message timers at any time during test runs.
+
+- `disableTimers: () => void`
+
+  ```js
+  import { disableTimers } from 'ember-cli-flash/test-support';
+  ```
+
+  Globally prevents flash messages from being removed after `timeout`.
+
+- `enableTimers: () => void`
+
+  ```js
+  import { enableTimers } from 'ember-cli-flash/test-support';
+  ```
+
+  Globally enables flash messages to be removed after `timeout`.
+
+The recommended approach is to disable timers for your entire test suite as described in [Installation](#installation).
+
+You may also use these helpers to enable or disable timers granularly.
+
+```javascript
+// tests/acceptance/foo-page-test.js
+
+import { module, test } from 'qunit';
+import { setupApplicationTest } from 'ember-qunit';
+import { click, visit } from '@ember/test-helpers';
+import { enableTimers, disableTimers } from 'ember-cli-flash/test-support';
+
+module('Application | Component | foo-page', function (hooks) {
+  setupApplicationTest(hooks);
+
+  module('with flash timers' function (hooks) {
+    hooks.before(function () {
+      // Enable timers for tests within this module
+      enableTimers();
+    });
+
+    hooks.after(function () {
+      // Clean up by disabling timers again
+      disableTimers();
+    })
+
+    test('flash message is removed after 5 seconds', async function (assert) {
+      assert.expect(1);
+
+      await visit('/');
+
+      await click('.button-that-opens-alert');
 
-```shell
-$ ember generate ember-cli-flash
+      assert.dom('.alert.alert-success').doesNotExist(
+        'Timer was removed due to `timeout: 5_000`'
+      );
+    });
+  });
+});
 ```
 
-This also adds the helper to `tests/test-helper.js`. You won't actually need to import this into your tests, but it's good to know what the blueprint does. Basically, the helper overrides a method used to initialise the flash-message's class, so that it behaves intuitively in a testing environment.
+## Acceptance / Integration tests
 
 Some example tests below, based on qunit.
 

From b639f47f48d013009166d773050a9bc60a2ba8f7 Mon Sep 17 00:00:00 2001
From: Giles Thompson <giles@papaiti.com>
Date: Mon, 23 Oct 2023 14:50:24 +1300
Subject: [PATCH 5/5] refactor(test helpers): rename to disableTimeout and
 enableTimeout

---
 README.md                                | 34 ++++++++++++------------
 UPGRADING.md                             | 10 +++----
 ember-cli-flash/src/flash/object.js      |  4 ++-
 ember-cli-flash/src/test-support.js      | 11 +++-----
 test-app/tests/unit/flash/object-test.js | 14 +++++-----
 5 files changed, 36 insertions(+), 37 deletions(-)

diff --git a/README.md b/README.md
index 5c4e428b..5a50a8b5 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ This ember addon adds a flash message service and component to your app.
 ember install ember-cli-flash
 ```
 
-It's also recommended to disable flash message timers during test runs by adding the following to `tests/test-helper.js`:
+It's also recommended to disable flash message timeout during test runs by adding the following to `tests/test-helper.js`:
 
 ```diff
 // tests/test-helper.js
@@ -52,9 +52,9 @@ import * as QUnit from 'qunit';
 import { setApplication } from '@ember/test-helpers';
 import { setup } from 'qunit-dom';
 import { start } from 'ember-qunit';
-+ import { disableTimers } from 'ember-cli-flash/test-support';
++ import { disableTimeout } from 'ember-cli-flash/test-support';
 
-+ disableTimers();
++ disableTimeout();
 
 setApplication(Application.create(config.APP));
 
@@ -430,27 +430,27 @@ If the provided component isn't to your liking, you can easily create your own.
 
 ## Test helpers
 
-This addon provides helper functions which enable disabling and enabling flash message timers at any time during test runs.
+This addon provides helper functions which enable disabling and enabling flash message timeout at any time during test runs.
 
-- `disableTimers: () => void`
+- `disableTimeout: () => void`
 
   ```js
-  import { disableTimers } from 'ember-cli-flash/test-support';
+  import { disableTimeout } from 'ember-cli-flash/test-support';
   ```
 
   Globally prevents flash messages from being removed after `timeout`.
 
-- `enableTimers: () => void`
+- `enableTimeout: () => void`
 
   ```js
-  import { enableTimers } from 'ember-cli-flash/test-support';
+  import { enableTimeout } from 'ember-cli-flash/test-support';
   ```
 
-  Globally enables flash messages to be removed after `timeout`.
+  Globally enables flash messages removal after `timeout`.
 
-The recommended approach is to disable timers for your entire test suite as described in [Installation](#installation).
+The recommended approach is to disable timeout for your entire test suite as described in [Installation](#installation).
 
-You may also use these helpers to enable or disable timers granularly.
+You may also use these helpers to enable or disable timeout granularly.
 
 ```javascript
 // tests/acceptance/foo-page-test.js
@@ -458,20 +458,20 @@ You may also use these helpers to enable or disable timers granularly.
 import { module, test } from 'qunit';
 import { setupApplicationTest } from 'ember-qunit';
 import { click, visit } from '@ember/test-helpers';
-import { enableTimers, disableTimers } from 'ember-cli-flash/test-support';
+import { enableTimeout, disableTimeout } from 'ember-cli-flash/test-support';
 
 module('Application | Component | foo-page', function (hooks) {
   setupApplicationTest(hooks);
 
-  module('with flash timers' function (hooks) {
+  module('with flash message timeout' function (hooks) {
     hooks.before(function () {
-      // Enable timers for tests within this module
-      enableTimers();
+      // Enable timeout for tests within this module
+      enableTimeout();
     });
 
     hooks.after(function () {
-      // Clean up by disabling timers again
-      disableTimers();
+      // Clean up by disabling timeout again
+      disableTimeout();
     })
 
     test('flash message is removed after 5 seconds', async function (assert) {
diff --git a/UPGRADING.md b/UPGRADING.md
index 8a7828ef..68f08ab1 100644
--- a/UPGRADING.md
+++ b/UPGRADING.md
@@ -6,7 +6,7 @@
 
 In previous versions an install-time blueprint would add an import to consuming apps' `tests/test-helper.js` file.
 
-This was used to disable the async timer functionality when displaying flash messages. For most apps this is a sensible default.
+This was used to disable the timeout functionality where a flash message is removed after a delay. For most apps this is a sensible default.
 
 Most apps with this addon installed will have the following import in their `tests/test-helper.js`:
 
@@ -15,7 +15,7 @@ Most apps with this addon installed will have the following import in their `tes
 import './helpers/flash-message';
 ```
 
-Remove this import and replace it with the `disableTimers` helper function. This helper function _should also be invoked_ within the same file.
+Remove this import and replace it with the `disableTimeout` helper function. This helper function _should also be invoked_ within the same file.
 
 ```diff
 // tests/test-helper.js
@@ -26,9 +26,9 @@ import { setApplication } from '@ember/test-helpers';
 import { setup } from 'qunit-dom';
 import { start } from 'ember-qunit';
 - import './helpers/flash-message';
-+ import { disableTimers } from 'ember-cli-flash/test-support';
++ import { disableTimeout } from 'ember-cli-flash/test-support';
 
-+ disableTimers();
++ disableTimeout();
 
 setApplication(Application.create(config.APP));
 
@@ -37,4 +37,4 @@ setup(QUnit.assert);
 start();
 ```
 
-An `enableTimers` helper is also provided for fine-grained control at any time during test runs.
+An `enableTimeout` helper is also provided for fine-grained control at any time during test runs.
diff --git a/ember-cli-flash/src/flash/object.js b/ember-cli-flash/src/flash/object.js
index 6a2bf26c..13af5241 100644
--- a/ember-cli-flash/src/flash/object.js
+++ b/ember-cli-flash/src/flash/object.js
@@ -11,6 +11,8 @@ export default class FlashObject extends EmberObject.extend(Evented) {
   isExitable = true;
   initializedTime = null;
 
+  // disableTimeout – Set by `disableTimeout` and `enableTimeout` in test-support.js
+
   @(guidFor('message').readOnly())
   _guid;
 
@@ -18,7 +20,7 @@ export default class FlashObject extends EmberObject.extend(Evented) {
   init() {
     super.init(...arguments);
 
-    if (this.sticky) {
+    if (this.disableTimeout || this.sticky) {
       return;
     }
     this.timerTask();
diff --git a/ember-cli-flash/src/test-support.js b/ember-cli-flash/src/test-support.js
index 0f61d012..ad46f983 100644
--- a/ember-cli-flash/src/test-support.js
+++ b/ember-cli-flash/src/test-support.js
@@ -1,12 +1,9 @@
 import FlashObject from './flash/object';
 
-const originalInit = FlashObject.prototype.init;
-const noopInit = () => {};
-
-export function disableTimers() {
-  FlashObject.reopen({ init: noopInit });
+export function disableTimeout() {
+  FlashObject.reopen({ disableTimeout: true });
 }
 
-export function enableTimers() {
-  FlashObject.reopen({ init: originalInit });
+export function enableTimeout() {
+  FlashObject.reopen({ disableTimeout: false });
 }
diff --git a/test-app/tests/unit/flash/object-test.js b/test-app/tests/unit/flash/object-test.js
index b87ae72b..87d0ff60 100644
--- a/test-app/tests/unit/flash/object-test.js
+++ b/test-app/tests/unit/flash/object-test.js
@@ -2,14 +2,14 @@ import { run, later } from '@ember/runloop';
 import { isPresent } from '@ember/utils';
 import { module, test } from 'qunit';
 import FlashMessage from 'ember-cli-flash/flash/object';
-import { disableTimers, enableTimers } from 'ember-cli-flash/test-support';
+import { disableTimeout, enableTimeout } from 'ember-cli-flash/test-support';
 
 const testTimerDuration = 50;
 let flash = null;
 
-module('FlashMessageObject disableTimers', function (hooks) {
+module('FlashMessageObject disableTimeout', function (hooks) {
   hooks.beforeEach(function () {
-    disableTimers();
+    disableTimeout();
     flash = FlashMessage.create({
       type: 'test',
       message: 'Cool story brah',
@@ -20,7 +20,7 @@ module('FlashMessageObject disableTimers', function (hooks) {
 
   hooks.afterEach(function () {
     flash = null;
-    enableTimers();
+    enableTimeout();
   });
 
   test('it does not create a timer', function (assert) {
@@ -28,10 +28,10 @@ module('FlashMessageObject disableTimers', function (hooks) {
   });
 });
 
-module('FlashMessageObject enableTimers', function (hooks) {
+module('FlashMessageObject enableTimeout', function (hooks) {
   hooks.beforeEach(function () {
-    disableTimers();
-    enableTimers();
+    disableTimeout();
+    enableTimeout();
     flash = FlashMessage.create({
       type: 'test',
       message: 'Cool story brah',