@@ -3,22 +3,28 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
33import { UiPath } from '../../../src/core/uipath' ;
44import { UiPathConfig } from '../../../src/core/config/config' ;
55import { ExecutionContext } from '../../../src/core/context/execution' ;
6+ import { AuthenticationError , ValidationError } from '../../../src/core/errors' ;
67import { getConfig , getContext , getTokenManager , getPrivateSDK } from '../../utils/setup' ;
78import { TEST_CONSTANTS } from '../../utils/constants/common' ;
89
910// ===== MOCKING =====
11+ const mockAuthState = {
12+ token : 'mock-access-token' as string | undefined ,
13+ hasValidToken : true
14+ } ;
15+
1016const mockTokenManager = {
11- getToken : ( ) => 'mock-access- token' ,
12- hasValidToken : ( ) => true
17+ getToken : ( ) => mockAuthState . token ,
18+ hasValidToken : ( ) => mockAuthState . hasValidToken
1319} ;
1420
1521const mockLogout = vi . fn ( ) ;
1622
1723vi . mock ( '../../../src/core/auth/service' , ( ) => {
1824 const AuthService : any = vi . fn ( ) . mockImplementation ( ( ) => ( {
1925 getTokenManager : ( ) => mockTokenManager ,
20- hasValidToken : ( ) => true ,
21- getToken : ( ) => 'mock-access- token' ,
26+ hasValidToken : ( ) => mockAuthState . hasValidToken ,
27+ getToken : ( ) => mockAuthState . token ,
2228 authenticateWithSecret : vi . fn ( ) ,
2329 authenticate : vi . fn ( ) . mockResolvedValue ( true ) ,
2430 logout : mockLogout
@@ -34,6 +40,13 @@ vi.mock('../../../src/core/auth/service', () => {
3440
3541vi . mock ( '../../../src/core/http/api-client' ) ;
3642
43+ // ===== TEST HELPERS =====
44+ const createJwt = ( payload : Record < string , unknown > ) : string => {
45+ const header = Buffer . from ( JSON . stringify ( { alg : 'none' , typ : 'JWT' } ) ) . toString ( 'base64url' ) ;
46+ const body = Buffer . from ( JSON . stringify ( payload ) ) . toString ( 'base64url' ) ;
47+ return `${ header } .${ body } .signature` ;
48+ } ;
49+
3750// ===== TEST SUITE =====
3851describe ( 'UiPath Core' , ( ) => {
3952 describe ( 'Constructor' , ( ) => {
@@ -352,6 +365,100 @@ describe('UiPath Core', () => {
352365 } ) ;
353366 } ) ;
354367
368+ describe ( 'getTokenIdentity' , ( ) => {
369+ beforeEach ( ( ) => {
370+ mockAuthState . hasValidToken = true ;
371+ mockAuthState . token = 'mock-access-token' ;
372+ } ) ;
373+
374+ it ( 'should return all 5 mapped identity fields from JWT claims' , ( ) => {
375+ mockAuthState . token = createJwt ( {
376+ email : 'jane.doe@example.com' ,
377+ first_name : 'Jane' ,
378+ last_name : 'Doe' ,
379+ preferred_username : 'jane.doe' ,
380+ name : 'Jane Doe'
381+ } ) ;
382+
383+ const sdk = new UiPath ( {
384+ baseUrl : TEST_CONSTANTS . BASE_URL ,
385+ orgName : TEST_CONSTANTS . ORGANIZATION_ID ,
386+ tenantName : TEST_CONSTANTS . TENANT_ID ,
387+ secret : TEST_CONSTANTS . CLIENT_SECRET
388+ } ) ;
389+
390+ const identity = sdk . getTokenIdentity ( ) ;
391+
392+ expect ( identity ) . toEqual ( {
393+ email : 'jane.doe@example.com' ,
394+ firstName : 'Jane' ,
395+ lastName : 'Doe' ,
396+ preferredUsername : 'jane.doe' ,
397+ name : 'Jane Doe'
398+ } ) ;
399+ } ) ;
400+
401+ it ( 'should return undefined for missing claims' , ( ) => {
402+ mockAuthState . token = createJwt ( { email : 'only.email@example.com' } ) ;
403+
404+ const sdk = new UiPath ( {
405+ baseUrl : TEST_CONSTANTS . BASE_URL ,
406+ orgName : TEST_CONSTANTS . ORGANIZATION_ID ,
407+ tenantName : TEST_CONSTANTS . TENANT_ID ,
408+ secret : TEST_CONSTANTS . CLIENT_SECRET
409+ } ) ;
410+
411+ const identity = sdk . getTokenIdentity ( ) ;
412+
413+ expect ( identity . email ) . toBe ( 'only.email@example.com' ) ;
414+ expect ( identity . firstName ) . toBeUndefined ( ) ;
415+ expect ( identity . lastName ) . toBeUndefined ( ) ;
416+ expect ( identity . preferredUsername ) . toBeUndefined ( ) ;
417+ expect ( identity . name ) . toBeUndefined ( ) ;
418+ } ) ;
419+
420+ it ( 'should throw AuthenticationError when user is not authenticated' , ( ) => {
421+ mockAuthState . hasValidToken = false ;
422+
423+ const sdk = new UiPath ( {
424+ baseUrl : TEST_CONSTANTS . BASE_URL ,
425+ orgName : TEST_CONSTANTS . ORGANIZATION_ID ,
426+ tenantName : TEST_CONSTANTS . TENANT_ID ,
427+ secret : TEST_CONSTANTS . CLIENT_SECRET
428+ } ) ;
429+
430+ expect ( ( ) => sdk . getTokenIdentity ( ) ) . toThrow ( AuthenticationError ) ;
431+ } ) ;
432+
433+ it ( 'should throw ValidationError when token has fewer than 3 segments' , ( ) => {
434+ mockAuthState . token = 'not-a-jwt' ;
435+
436+ const sdk = new UiPath ( {
437+ baseUrl : TEST_CONSTANTS . BASE_URL ,
438+ orgName : TEST_CONSTANTS . ORGANIZATION_ID ,
439+ tenantName : TEST_CONSTANTS . TENANT_ID ,
440+ secret : TEST_CONSTANTS . CLIENT_SECRET
441+ } ) ;
442+
443+ expect ( ( ) => sdk . getTokenIdentity ( ) ) . toThrow ( ValidationError ) ;
444+ } ) ;
445+
446+ it ( 'should throw ValidationError when payload is not valid JSON' , ( ) => {
447+ const header = Buffer . from ( JSON . stringify ( { alg : 'none' } ) ) . toString ( 'base64url' ) ;
448+ const invalidPayload = Buffer . from ( 'not-json-content' ) . toString ( 'base64url' ) ;
449+ mockAuthState . token = `${ header } .${ invalidPayload } .signature` ;
450+
451+ const sdk = new UiPath ( {
452+ baseUrl : TEST_CONSTANTS . BASE_URL ,
453+ orgName : TEST_CONSTANTS . ORGANIZATION_ID ,
454+ tenantName : TEST_CONSTANTS . TENANT_ID ,
455+ secret : TEST_CONSTANTS . CLIENT_SECRET
456+ } ) ;
457+
458+ expect ( ( ) => sdk . getTokenIdentity ( ) ) . toThrow ( ValidationError ) ;
459+ } ) ;
460+ } ) ;
461+
355462 describe ( 'Multiple Instance Support' , ( ) => {
356463 it ( 'should support creating multiple independent instances' , ( ) => {
357464 const sdk1 = new UiPath ( {
0 commit comments