0

I'm new to ember and trying to figure out how to unit test, using sinon, the sessionStorage based on url parameters when that page is visited. I've tried a few things but still can't get the desired result. It passes even if I change the 'sessionValue' without editing the query param. Thank you in advance.

ember component

beforeModel(transition) {

    //transition will contain an object containing a query parameter. '?userid=1234' and is set in the sessionStorage.

    if(transition.queryparam.hasOwnProperty('userid')){
        sessionStorage.setItem('user:id', transition.queryparam)
    }
}

Ember test

test('Session Storage contains query param value', async assert => {
let sessionKey = "user:id";
let sessionValue = "1234"

let store = {};
  const mockLocalStorage = {
    getItem: (key) => {
      return key in store ? store[key] : null;
    },
    setItem: (key, value) => {
      store[key] = `${value}`;
    },
    clear: () => {
      store = {};
    }
  };

  asserts.expect(1);
  
  let spy = sinon.spy(sessionStorage, "setItem");
  spy.calledWith(mockLocalStorage.setItem);

  let stub = sinon.stub(sessionStorage, "getItem");
  stub.calledWith(mockLocalStorage.getItem);
  stub.returns(sessionValue);

  await visit('/page?userid=1234');
     
  mockLocalStorage.setItem(sessionKey, sessionValue);
  assert.equal(mockLocalStorage.getItem(sessionKey), sessionValue, 'storage contains value');
})
dar
  • 43
  • 1
  • 6

1 Answers1

0

Welcome to Ember!

There are many ways to test, and the below suggestion is one way (how I would approach interacting with the SessionStorage).

Instead of re-creating the SessionStorage API in your test, how do you feel about using a pre-made proxy around the Session Storage? (ie: "Don't mock what you don't own")

Using: https://github.com/CrowdStrike/ember-browser-services/#sessionstorage

Your app code would look like:

@service('browser/session-storage') sessionStorage;

beforeModel(transition) {
  // ... details omitted ...
  // note the addition of `this` -- the apis are entirely the same
  //     as SessionStorage
  this.sessionStorage.setItem('user:id', ...)
}

then in your test:

module('Scenario Name', function (hooks) {
  setupApplicationTest(hooks);
  setupBrowserFakes(hooks, { sessionStorage: true });

  test('Session Storage contains query param value', async assert => {
    let sessionKey = "user:id";
    let sessionValue = "1234"

    let sessionStorage = this.owner.lookup('browser/session-storage');

    await visit('/page?userid=1234');
     
    assert.equal(sessionStorage.getItem(sessionKey), '1234', 'storage contains value');
  });

})

With this approach, sinon isn't even needed :)

NullVoxPopuli
  • 61,906
  • 73
  • 206
  • 352