|
| 1 | +import { expect } from 'chai' |
| 2 | +import { describe, it } from 'mocha' |
| 3 | +import { contentstackClient } from '../../sanity-check/utility/ContentstackClient' |
| 4 | +import axios from 'axios' |
| 5 | +import dotenv from 'dotenv' |
| 6 | + |
| 7 | +dotenv.config() |
| 8 | +let accessToken = '' |
| 9 | +let loggedinUserID = '' |
| 10 | +let authUrl = '' |
| 11 | +let codeChallenge = '' |
| 12 | +let codeChallengeMethod = '' |
| 13 | +let authCode |
| 14 | +let authtoken = '' |
| 15 | +let redirectUrl = '' |
| 16 | +let refreshToken = '' |
| 17 | +const client = contentstackClient() |
| 18 | +const oauthClient = client.oauth({ |
| 19 | + clientId: process.env.CLIENT_ID, |
| 20 | + appId: process.env.APP_ID, |
| 21 | + redirectUri: process.env.REDIRECT_URI |
| 22 | +}) |
| 23 | + |
| 24 | +describe('OAuth Authentication API Test', () => { |
| 25 | + it('should login with credentials', done => { |
| 26 | + client.login({ email: process.env.EMAIL, password: process.env.PASSWORD }, { include_orgs: true, include_orgs_roles: true, include_stack_roles: true, include_user_settings: true }).then((response) => { |
| 27 | + expect(response.notice).to.be.equal('Login Successful.', 'Login success messsage does not match.') |
| 28 | + done() |
| 29 | + }) |
| 30 | + .catch(done) |
| 31 | + }) |
| 32 | + |
| 33 | + it('should get Current user info test', done => { |
| 34 | + client.getUser().then((user) => { |
| 35 | + authtoken = user.authtoken |
| 36 | + done() |
| 37 | + }) |
| 38 | + .catch(done) |
| 39 | + }) |
| 40 | + |
| 41 | + it('should fail when trying to login with invalid app credentials', () => { |
| 42 | + try { |
| 43 | + client.oauth({ |
| 44 | + clientId: 'clientId', |
| 45 | + appId: 'appId', |
| 46 | + redirectUri: 'redirectUri' |
| 47 | + }) |
| 48 | + } catch (error) { |
| 49 | + const jsonMessage = JSON.parse(error.message) |
| 50 | + expect(jsonMessage.status).to.be.equal(401, 'Status code does not match for invalid credentials') |
| 51 | + expect(jsonMessage.errorMessage).to.not.equal(null, 'Error message not proper') |
| 52 | + expect(jsonMessage.errorCode).to.be.equal(104, 'Error code does not match') |
| 53 | + } |
| 54 | + }) |
| 55 | + |
| 56 | + it('should generate OAuth authorization URL', async () => { |
| 57 | + authUrl = await oauthClient.authorize() |
| 58 | + const url = new URL(authUrl) |
| 59 | + |
| 60 | + codeChallenge = url.searchParams.get('code_challenge') |
| 61 | + codeChallengeMethod = url.searchParams.get('code_challenge_method') |
| 62 | + |
| 63 | + // Ensure they are not empty strings |
| 64 | + expect(codeChallenge).to.not.equal('') |
| 65 | + expect(codeChallengeMethod).to.not.equal('') |
| 66 | + expect(authUrl).to.include(process.env.CLIENT_ID, 'Client ID mismatch') |
| 67 | + }) |
| 68 | + |
| 69 | + it('should simulate calling the authorization URL and receive authorization code', async () => { |
| 70 | + try { |
| 71 | + const authorizationEndpoint = oauthClient.axiosInstance.defaults.developerHubBaseUrl |
| 72 | + axios.defaults.headers.common.authtoken = authtoken |
| 73 | + axios.defaults.headers.common.organization_uid = process.env.ORGANIZATION |
| 74 | + const response = await axios |
| 75 | + .post(`${authorizationEndpoint}/manifests/${process.env.APP_ID}/authorize`, { |
| 76 | + client_id: process.env.CLIENT_ID, |
| 77 | + redirect_uri: process.env.REDIRECT_URI, |
| 78 | + code_challenge: codeChallenge, |
| 79 | + code_challenge_method: codeChallengeMethod, |
| 80 | + response_type: 'code' |
| 81 | + }) |
| 82 | + const data = response.data |
| 83 | + redirectUrl = data.data.redirect_url |
| 84 | + const url = new URL(redirectUrl) |
| 85 | + authCode = url.searchParams.get('code') |
| 86 | + oauthClient.axiosInstance.oauth.appId = process.env.APP_ID |
| 87 | + oauthClient.axiosInstance.oauth.clientId = process.env.CLIENT_ID |
| 88 | + oauthClient.axiosInstance.oauth.redirectUri = process.env.REDIRECT_URI |
| 89 | + // Ensure they are not empty strings |
| 90 | + expect(redirectUrl).to.not.equal('') |
| 91 | + expect(url).to.not.equal('') |
| 92 | + } catch (error) { |
| 93 | + console.log(error) |
| 94 | + } |
| 95 | + }) |
| 96 | + |
| 97 | + it('should exchange authorization code for access token', async () => { |
| 98 | + const response = await oauthClient.exchangeCodeForToken(authCode) |
| 99 | + accessToken = response.access_token |
| 100 | + loggedinUserID = response.user_uid |
| 101 | + refreshToken = response.refresh_token |
| 102 | + |
| 103 | + expect(response.organization_uid).to.be.equal(process.env.ORGANIZATION, 'Organization mismatch') |
| 104 | + // eslint-disable-next-line no-unused-expressions |
| 105 | + expect(response.access_token).to.not.be.null |
| 106 | + // eslint-disable-next-line no-unused-expressions |
| 107 | + expect(response.refresh_token).to.not.be.null |
| 108 | + }) |
| 109 | + |
| 110 | + it('should get the logged-in user info using the access token', async () => { |
| 111 | + const user = await client.getUser({ |
| 112 | + authorization: `Bearer ${accessToken}` |
| 113 | + }) |
| 114 | + expect(user.uid).to.be.equal(loggedinUserID) |
| 115 | + expect(user.email).to.be.equal(process.env.EMAIL, 'Email mismatch') |
| 116 | + }) |
| 117 | + |
| 118 | + it('should refresh the access token using refresh token', async () => { |
| 119 | + const response = await oauthClient.refreshAccessToken(refreshToken) |
| 120 | + |
| 121 | + accessToken = response.access_token |
| 122 | + refreshToken = response.refresh_token |
| 123 | + // eslint-disable-next-line no-unused-expressions |
| 124 | + expect(response.access_token).to.not.be.null |
| 125 | + // eslint-disable-next-line no-unused-expressions |
| 126 | + expect(response.refresh_token).to.not.be.null |
| 127 | + }) |
| 128 | + |
| 129 | + it('should logout successfully after OAuth authentication', async () => { |
| 130 | + const response = await oauthClient.logout() |
| 131 | + expect(response).to.be.equal('Logged out successfully') |
| 132 | + }) |
| 133 | + |
| 134 | + it('should fail to make an API request with an expired token', async () => { |
| 135 | + try { |
| 136 | + await client.getUser({ |
| 137 | + authorization: `Bearer ${accessToken}` |
| 138 | + }) |
| 139 | + } catch (error) { |
| 140 | + expect(error.status).to.be.equal(401, 'API request should fail with status 401') |
| 141 | + expect(error.errorMessage).to.be.equal('The provided access token is invalid or expired or revoked', 'Error message mismatch') |
| 142 | + } |
| 143 | + }) |
| 144 | +}) |
0 commit comments