// @ts-nocheck import { expect } from 'chai'; import * as sinon from 'sinon'; const sandbox = sinon.createSandbox(); import { RedeemableTokenService } from '../../src/redeemable-token'; import { TestConfiguration } from '../../src/configuration'; import { RedeemableToken } from '../../src/models/redeemable-token'; import { PersonalisedToken } from '../../src/models/personalised-token'; describe('RedeemableTokenService', () => { const userId = 'id'; const REDEEMABLE_TOKEN_DATA = { id: 'tokenId', creationDateTime: '2019-05-30T11:10:55.132Z', accessDuration: null, accessLicenceId: 'accessLicenceId', type: 'LICENCE', status: 'AVAILABLE', validUntil: '2020-01-01T01:02:03.000Z', redeemability: 'UNLIMITED', }; const PERSONALISED_TOKEN_DATA = { id: 'tokenId', creationDateTime: '2019-05-30T11:10:55.132Z', emailAddress: 'example@ft.com', accessLicenceId: 'accessLicenceId', externalUserId: 'ext.user.id', }; const MOCK_REDEEM_TOKEN_RESPONSE = { id: 'userId', creationDateTime: '2019-05-30T11:10:55.132Z', redeemableFor: { accessLicenceId: 'accessLicenceId', accessDuration: 'accessDuration', type: 'LICENCE', }, validUntil: '2020-01-01T01:02:03.000Z', status: 'AVAILABLE', redeemability: 'UNLIMITED', }; let tokenService; let config; beforeEach(() => { config = new TestConfiguration({ redeemableTokenApiKey: 'secret', redeemableEmailTokenApiKey: 'secret', originSystemId: 'n-membership-sdk test', }); tokenService = new RedeemableTokenService(config); sandbox.stub(tokenService, 'requestPost').resolves(MOCK_REDEEM_TOKEN_RESPONSE); }); afterEach(() => { sandbox.restore(); }); it('throws an error when host and key configuration properties do not exist', () => { try { new RedeemableTokenService({}); expect.fail('It should throw'); } catch (error) { } }); describe('redeem', () => { context('given a RedeemableToken', () => { it('should make a request with the correct parameters', async () => { const token = new RedeemableToken(REDEEMABLE_TOKEN_DATA); const expectedPostOptions = { url: `${tokenService.membershipApi}/redeemable-tokens/${token.id}/redeem`, body: { userId }, key: tokenService.redeemableTokenApiKey, }; await tokenService.redeem(token, userId); expect(tokenService.requestPost.calledWith(expectedPostOptions)).to.be.true; }); it('should return a new RedeemableToken', async () => { const token = new RedeemableToken(REDEEMABLE_TOKEN_DATA); const result = await tokenService.redeem(token, userId); expect(result).to.be.instanceOf(RedeemableToken); expect(result !== token).to.be.true; }); it('should throw if a userId wasn’t provided', async () => { const token = new RedeemableToken(REDEEMABLE_TOKEN_DATA); try { await tokenService.redeem(token); expect.fail('Should have thrown the error!'); } catch (error) { expect(error.message).to.equal('No userId provided'); } }); it('should throw if the redemption request failed', async () => { const token = new RedeemableToken(REDEEMABLE_TOKEN_DATA); const errorResponse = new Error('Test failure'); tokenService.requestPost.rejects(errorResponse); try { await tokenService.redeem(token, userId); expect.fail('Should have thrown the error!'); } catch (error) { expect(error).to.deep.equal(errorResponse); } }); }); context('given a PersonalisedToken', () => { it('should make a request with the correct parameters', async () => { const token = new PersonalisedToken(PERSONALISED_TOKEN_DATA); const expectedPostOptions = { url: `${tokenService.membershipApi}/redeemable-email-tokens/v1/${token.id}/redeem`, key: tokenService.redeemableEmailTokenApiKey, }; await tokenService.redeem(token, userId); expect(tokenService.requestPost.calledWith(expectedPostOptions)).to.be.true; }); it('should return the token', async () => { const token = new PersonalisedToken(PERSONALISED_TOKEN_DATA); const result = await tokenService.redeem(token, userId); expect(result).to.be.instanceOf(PersonalisedToken); expect(result === token).to.be.true; }); it('should throw if the redemption request failed', async () => { const token = new PersonalisedToken(PERSONALISED_TOKEN_DATA); const errorResponse = new Error('Test failure'); tokenService.requestPost.rejects(errorResponse); try { await tokenService.redeem(token, userId); expect.fail('Should have thrown the error!'); } catch (error) { expect(error).to.deep.equal(errorResponse); } }); }); context('given an unknown token', () => { it('should throw', async () => { const errorResponse = new Error('Test failure'); tokenService.requestPost.rejects(errorResponse); try { await tokenService.redeem({}, userId); expect.fail('Should have thrown the error!'); } catch (error) { expect(error.message).to.equal('Unknown token type'); } }); }); }); describe('mapRedeemableTokenResponse', () => { const tokenData = { id: '00000000-0000-0000-0000-000000000000', status: 'AVAILABLE', redeemability: 'UNLIMITED', redeemableFor: { licenceId: 'mockLicenceId', accessDuration: null, type: 'LICENCE', }, }; it('should return RedeemableToken object when called with raw token data', async () => { const redeemableToken = tokenService.mapRedeemableTokenResponse(tokenData); expect(redeemableToken instanceof RedeemableToken).to.be.true; expect(redeemableToken.id).equals(tokenData.id); expect(redeemableToken.accessLicenceId).equals(tokenData.redeemableFor.licenceId); expect(redeemableToken.status).equals(tokenData.status); }); }); });