Skip to content

Commit

Permalink
add unit test for status route and component
Browse files Browse the repository at this point in the history
  • Loading branch information
MayankBansal12 committed Jan 8, 2025
1 parent 10b3b16 commit 4d20127
Show file tree
Hide file tree
Showing 2 changed files with 223 additions and 0 deletions.
123 changes: 123 additions & 0 deletions tests/unit/controllers/status-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { module, test } from 'qunit';
import { setupTest } from 'website-www/tests/helpers';
import { USER_STATES } from 'website-www/constants/user-status';
import Service from '@ember/service';
import ENV from 'website-www/config/environment';
import sinon from 'sinon';

class MockToastService extends Service {
success() {}
error() {}
}

module('Unit | Controller | status', function (hooks) {
setupTest(hooks);

hooks.beforeEach(function () {
this.owner.register('service:toast', MockToastService);
this.fetchStub = sinon.stub(window, 'fetch');
});

hooks.afterEach(function () {
this.fetchStub.restore();
});

test('it initializes with default values', function (assert) {
const controller = this.owner.lookup('controller:status');
assert.false(
controller.isStatusUpdating,
'isStatusUpdating is false by default',
);
assert.false(
controller.showUserStateModal,
'showUserStateModal is false by default',
);
assert.strictEqual(
controller.newStatus,
undefined,
'newStatus is undefined by default',
);
});

test('updateStatus sends the correct request', async function (assert) {
const mockResponse = {
data: {
currentStatus: { state: USER_STATES.ACTIVE },
},
};

this.fetchStub.resolves(
new Response(JSON.stringify(mockResponse), {
status: 200,
headers: { 'Content-Type': 'application/json' },
}),
);

const controller = this.owner.lookup('controller:status');
const newStatus = { currentStatus: { state: 'ACTIVE' } };
await controller.updateStatus(newStatus);

assert.ok(this.fetchStub.calledOnce, 'Fetch was called once');
assert.ok(
this.fetchStub.calledWith(
`${ENV.BASE_API_URL}/users/status/self?userStatusFlag=true`,
),
'Fetch was called with the correct URL',
);
});

test('updateStatus correctly handles different user states', async function (assert) {
assert.expect(10);
const controller = this.owner.lookup('controller:status');
const toastService = this.owner.lookup('service:toast');
toastService.success = sinon.spy();
toastService.error = sinon.spy();

const mockResponses = {
ACTIVE: { data: { currentStatus: { state: USER_STATES.ACTIVE } } },
OOO: { data: { currentStatus: { state: USER_STATES.OOO } } },
ONBOARDING: {
data: { currentStatus: { state: USER_STATES.ONBOARDING } },
},
IDLE: { data: { currentStatus: { state: USER_STATES.IDLE } } },
DNE: { data: { currentStatus: { state: USER_STATES.DNE } } },
};

const setupFetchResponse = (status) => {
this.fetchStub.resolves(
new Response(JSON.stringify(mockResponses[status]), {
status: 200,
headers: { 'Content-Type': 'application/json' },
}),
);
};

for (const state of Object.keys(mockResponses)) {
setupFetchResponse(state);

const newStatus = { currentStatus: { state: USER_STATES[state] } };
await controller.updateStatus(newStatus);
assert.ok(
toastService.success.calledOnce,
`Success toast is shown for ${state}`,
);
assert.strictEqual(
controller.status,
USER_STATES[state],
`Status is updated to ${state}`,
);
toastService.success.resetHistory();
this.fetchStub.resetHistory();
}
});

test('toggleUserStateModal works with OOO status', function (assert) {
let controller = this.owner.lookup('controller:status');
controller.status = USER_STATES.OOO;
controller.toggleUserStateModal();
assert.ok(
controller.showUserStateModal,
'User state modal is shown for OOO status',
);
});
});
100 changes: 100 additions & 0 deletions tests/unit/routes/status-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { module, test } from 'qunit';
import { setupTest } from 'website-www/tests/helpers';
import sinon from 'sinon';
import ENV from 'website-www/config/environment';
import { USER_STATES } from 'website-www/constants/user-status';
const API_BASE_URL = ENV.BASE_API_URL;

module('Unit | Route | status', function (hooks) {
setupTest(hooks);

hooks.beforeEach(function () {
this.fetchStub = sinon.stub(window, 'fetch');
this.route = this.owner.lookup('route:status');
sinon.stub(this.route.router, 'transitionTo');
});

hooks.afterEach(function () {
this.fetchStub.restore();
sinon.restore();
});

test('redirects to 404 page if dev flag is not present', function (assert) {
const transition = { to: { queryParams: { dev: 'false' } } };

this.route.beforeModel(transition);

assert.ok(
this.route.router.transitionTo.calledOnceWith('/page-not-found'),
'Redirected to /page-not-found when dev is not true',
);
});

test('allows access when dev flag is true', function (assert) {
const transition = { to: { queryParams: { dev: 'true' } } };

this.route.beforeModel(transition);

assert.ok(
this.route.router.transitionTo.notCalled,
'No redirection occurs when dev query param is true',
);
});

test('it fetches user status and returns it if API responds with 200', async function (assert) {
const userStatus = USER_STATES.ACTIVE;

this.fetchStub.resolves(
new Response(
JSON.stringify({ data: { currentStatus: { state: userStatus } } }),
{ status: 200 },
),
);

const result = await this.route.model();

assert.ok(
this.fetchStub.calledOnceWith(`${API_BASE_URL}/users/status/self`),
'Fetch called with correct URL',
);
assert.strictEqual(result, userStatus, 'Returns the user status from API');
});

test('displays error toast and redirects in case of 401 response', async function (assert) {
this.fetchStub.resolves(new Response(JSON.stringify({}), { status: 401 }));
const toastStub = sinon.stub(this.route.toast, 'error');

const result = await this.route.model();

assert.ok(
toastStub.calledWith(
'You are not logged in. Please login to continue.',
'',
sinon.match.object,
),
'Displays error toast when API responds with 401',
);
assert.strictEqual(result, undefined, 'No result returned for 401');
});

test('returns user status DNE on 404 error and displays toast', async function (assert) {
this.fetchStub.resolves(new Response(JSON.stringify({}), { status: 404 }));
const toastStub = sinon.stub(this.route.toast, 'error');

const result = await this.route.model();

assert.ok(
toastStub.calledWith(
"Your Status data doesn't exist yet. Please choose your status from the options below.",
'',
sinon.match.object,
),
'Displays error toast for 404 response',
);
assert.strictEqual(
result,
USER_STATES.DNE,
'Returns USER_STATES.DNE on 404',
);
});
});

0 comments on commit 4d20127

Please sign in to comment.