Skip to content

Commit

Permalink
Refactor and test oidc enrollment saga
Browse files Browse the repository at this point in the history
  • Loading branch information
arbulu89 committed Aug 7, 2024
1 parent d859d6d commit 3f0bb54
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 20 deletions.
18 changes: 6 additions & 12 deletions assets/js/state/sagas/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ import {
import { networkClient } from '@lib/network';
import { isSingleSignOnEnabled } from '@lib/auth/config';

export function* performOIDCEnrollment({ payload: { code, state } }) {
export function* performLogin({ payload: { username, password, totpCode } }) {
yield put(setAuthInProgress());
try {
const {
data: { access_token: accessToken, refresh_token: refreshToken },
} = yield call(oidcEnrollment, { code, session_state: state });
} = yield call(login, { username, password, totp_code: totpCode });
yield call(storeAccessToken, accessToken);
yield call(storeRefreshToken, refreshToken);

// Get logged user information
const {
id,
username: profileUsername,
Expand Down Expand Up @@ -64,35 +64,29 @@ export function* performOIDCEnrollment({ payload: { code, state } }) {
}
}

export function* performLogin({ payload: { username, password, totpCode } }) {
export function* performOIDCEnrollment({ payload: { code, state } }) {
yield put(setAuthInProgress());
try {
const {
data: { access_token: accessToken, refresh_token: refreshToken },
} = yield call(login, { username, password, totp_code: totpCode });
} = yield call(oidcEnrollment, { code, session_state: state });
yield call(storeAccessToken, accessToken);
yield call(storeRefreshToken, refreshToken);
// Get logged user information

const {
id,
username: profileUsername,
created_at,
email,
fullname,
updated_at,
abilities,
password_change_requested,
} = yield call(profile, networkClient);
yield put(
setUser({
username: profileUsername,
id,
created_at,
email,
fullname,
updated_at,
abilities,
password_change_requested,
})
);
yield put(setUserAsLogged());
Expand Down
99 changes: 91 additions & 8 deletions assets/js/state/sagas/user.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,20 @@ import {
performLogin,
clearUserAndLogout,
checkUserPasswordChangeRequested,
performOIDCEnrollment,
} from './user';

const axiosMock = new MockAdapter(authClient);
const networkClientAxiosMock = new MockAdapter(networkClient);

const credentialResponse = {
access_token:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0cmVudG8tcHJvamVjdCIsImV4cCI6MTY3MTY0MTE5NiwiaWF0IjoxNjcxNjQwNTk2LCJpc3MiOiJodHRwczovL2dpdGh1Yi5jb20vdHJlbnRvLXByb2plY3Qvd2ViIiwianRpIjoiMnNwZG9ndmxtOTJmdG1kdm1nMDAwbmExIiwibmJmIjoxNjcxNjQwNTk2LCJzdWIiOjEsInR5cCI6IkJlYXJlciJ9.ZuHORuLkK9e15NGGMRRpxFOUR1BO1_BLuT9EeOJfuLM',
expires_in: 600,
refresh_token:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0cmVudG8tcHJvamVjdCIsImV4cCI6MTY3MTY0MDY1NiwiaWF0IjoxNjcxNjQwNTk2LCJpc3MiOiJodHRwczovL2dpdGh1Yi5jb20vdHJlbnRvLXByb2plY3Qvd2ViIiwianRpIjoiMnNwZG9ndmxtZWhmbG1kdm1nMDAwbmMxIiwibmJmIjoxNjcxNjQwNTk2LCJzdWIiOjEsInR5cCI6IlJlZnJlc2gifQ.AW6-iV1XHWdzQKBVadhf7o7gUdidYg6mEyyuDke_zlA',
};

describe('user actions saga', () => {
beforeEach(() => {
axiosMock.reset();
Expand Down Expand Up @@ -85,14 +94,6 @@ describe('user login saga', () => {
});

it('should set the username in the store and set the user as logged when login is successful, persisting the information in the local storage', async () => {
const credentialResponse = {
access_token:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0cmVudG8tcHJvamVjdCIsImV4cCI6MTY3MTY0MTE5NiwiaWF0IjoxNjcxNjQwNTk2LCJpc3MiOiJodHRwczovL2dpdGh1Yi5jb20vdHJlbnRvLXByb2plY3Qvd2ViIiwianRpIjoiMnNwZG9ndmxtOTJmdG1kdm1nMDAwbmExIiwibmJmIjoxNjcxNjQwNTk2LCJzdWIiOjEsInR5cCI6IkJlYXJlciJ9.ZuHORuLkK9e15NGGMRRpxFOUR1BO1_BLuT9EeOJfuLM',
expires_in: 600,
refresh_token:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0cmVudG8tcHJvamVjdCIsImV4cCI6MTY3MTY0MDY1NiwiaWF0IjoxNjcxNjQwNTk2LCJpc3MiOiJodHRwczovL2dpdGh1Yi5jb20vdHJlbnRvLXByb2plY3Qvd2ViIiwianRpIjoiMnNwZG9ndmxtZWhmbG1kdm1nMDAwbmMxIiwibmJmIjoxNjcxNjQwNTk2LCJzdWIiOjEsInR5cCI6IlJlZnJlc2gifQ.AW6-iV1XHWdzQKBVadhf7o7gUdidYg6mEyyuDke_zlA',
};

const {
email,
username,
Expand Down Expand Up @@ -199,5 +200,87 @@ describe('user login saga', () => {

expect(dispatched).toEqual([]);
});

it('should permorm OIDC enrollment', async () => {
const { email, username, id, fullname, abilities } =
profileFactory.build();

axiosMock
.onPost('/api/session/oidc_local/callback', {
code: 'code',
session_state: 'state',
})
.reply(200, credentialResponse);

networkClientAxiosMock.onGet('/api/v1/profile').reply(200, {
username,
id,
email,
fullname,
abilities,
});

const dispatched = await recordSaga(
performOIDCEnrollment,
{
payload: {
code: 'code',
state: 'state',
},
},
{
user: {
password_change_requested: true,
},
}
);

expect(dispatched).toContainEqual(setAuthInProgress());
expect(dispatched).toContainEqual(
setUser({
username,
id,
email,
fullname,
abilities,
})
);
expect(dispatched).toContainEqual(setUserAsLogged());

expect(getAccessTokenFromStore()).toEqual(
credentialResponse.access_token
);
expect(getRefreshTokenFromStore()).toEqual(
credentialResponse.refresh_token
);
});

it('should set the error when the OIDC enrollment fails', async () => {
axiosMock
.onPost('/api/session/oidc_local/callback', {
code: 'bad',
session_state: 'bad',
})
.reply(401, {
error: 'unauthorized',
});

const dispatched = await recordSaga(performOIDCEnrollment, {
payload: {
code: 'bad',
state: 'bad',
},
});

expect(dispatched).toContainEqual(setAuthInProgress());
expect(dispatched).toContainEqual(
setAuthError({
message: 'Request failed with status code 401',
code: 401,
})
);
expect(getAccessTokenFromStore()).toEqual(null);
expect(getRefreshTokenFromStore()).toEqual(null);
});
});
});

0 comments on commit 3f0bb54

Please sign in to comment.