import { Test , TestingModule } from '@nestjs/testing' ; import { LoggerService } from '@fc/logger' ; import { OidcClientService } from '@fc/oidc-client' ; import { OidcProviderService } from '@fc/oidc-provider' ; import { SessionService } from '@fc/session' ; import { MockIdentityProviderService } from '../services' ; import { MockIdentityProviderController } from './mock-identity-provider.controller' ; describe ( 'MockIdentityProviderFcaController' , ( ) => { let controller ; const req = { fc : { interactionId : 'interactionIdMockValue' , } , } ; const res = { redirect : jest . fn ( ) , } ; const next = jest . fn ( ) ; const oidcClientServiceMock = { getAuthorizeUrl : jest . fn ( ) , getTokenSet : jest . fn ( ) , getUserInfo : jest . fn ( ) , wellKnownKeys : jest . fn ( ) , buildAuthorizeParameters : jest . fn ( ) , finishInteraction : jest . fn ( ) , } ; const loggerServiceMock = { setContext : jest . fn ( ) , trace : jest . fn ( ) , } as unknown as LoggerService ; const oidcClientSessionServiceMock = { set : jest . fn ( ) , get : jest . fn ( ) , getId : jest . fn ( ) , setAlias : jest . fn ( ) , } ; const oidcProviderServiceMock = { getInteraction : jest . fn ( ) , finishInteraction : jest . fn ( ) , } ; const mockIdentityProviderFcaServiceMock = { getIdentity : jest . fn ( ) , } ; const interactionIdMock = 'interactionIdMockValue' ; const acrMock = 'eidas2' ; const scopeMock = 'scopeMock' ; const providerUidMock = 'providerUidMock' ; const loginMockValue = 'loginMockValue' ; const randomStringMock = 'randomStringMockValue' ; const stateMock = randomStringMock ; const sessionIdMock = randomStringMock ; const interactionMock = { uid : 'uidMockValue' , params : 'paramsMockValue' , } ; const spNameMock = Symbol ( 'spNameMockValue' ) ; beforeEach ( async ( ) => { const module = await Test . createTestingModule ( { controllers : [ MockIdentityProviderController ] , providers : [ OidcClientService , LoggerService , SessionService , OidcProviderService , MockIdentityProviderService , ] , } ) . overrideProvider ( OidcClientService ) . useValue ( oidcClientServiceMock ) . overrideProvider ( LoggerService ) . useValue ( loggerServiceMock ) . overrideProvider ( SessionService ) . useValue ( oidcClientSessionServiceMock ) . overrideProvider ( OidcProviderService ) . useValue ( oidcProviderServiceMock ) . overrideProvider ( MockIdentityProviderService ) . useValue ( mockIdentityProviderFcaServiceMock ) . compile ( ) ; controller = module . get < MockIdentityProviderController > ( MockIdentityProviderController ) ; jest . resetAllMocks ( ) ; oidcClientServiceMock . buildAuthorizeParameters . mockReturnValue ( { state : stateMock , scope : scopeMock , providerUid : providerUidMock , acr_values : acrMock , } ) ; oidcProviderServiceMock . getInteraction . mockResolvedValue ( interactionMock ) ; oidcClientSessionServiceMock . get . mockResolvedValue ( spNameMock ) ; oidcClientSessionServiceMock . getId . mockReturnValue ( sessionIdMock ) ; } ) ; it ( 'should be defined' , ( ) => { expect ( controller ) . toBeDefined ( ) ; } ) ; describe ( 'index' , ( ) => { it ( 'Should return some status object' , async ( ) => { oidcClientSessionServiceMock . set . mockResolvedValueOnce ( undefined ) ; const result = await controller . index ( ) ; expect ( result ) . toEqual ( { status : 'ok' } ) ; } ) ; } ) ; describe ( 'getInteraction' , ( ) => { const appSessionServiceMock = { get : jest . fn ( ) , set : jest . fn ( ) , } ; const finalSpIdMock = 'abcdefghijklmnopqrstuvwxyz0123456789' ; beforeEach ( ( ) => { appSessionServiceMock . get . mockResolvedValueOnce ( finalSpIdMock ) ; } ) ; it ( 'should call oidcProvider.getInteraction' , async ( ) => { await controller . getInteraction ( req , res , oidcClientSessionServiceMock , appSessionServiceMock ) ; expect ( oidcProviderServiceMock . getInteraction ) . toBeCalledTimes ( 1 ) ; expect ( oidcProviderServiceMock . getInteraction ) . toBeCalledWith ( req , res ) ; } ) ; it ( 'should call oidcClientSessionServiceMock.get with spName' , async ( ) => { await controller . getInteraction ( req , res , oidcClientSessionServiceMock , appSessionServiceMock ) ; expect ( oidcClientSessionServiceMock . get ) . toBeCalledTimes ( 1 ) ; expect ( oidcClientSessionServiceMock . get ) . toBeCalledWith ( 'spName' ) ; } ) ; it ( 'should call appSessionServiceMock.get with finalspId' , async ( ) => { await controller . getInteraction ( req , res , oidcClientSessionServiceMock , appSessionServiceMock ) ; expect ( appSessionServiceMock . get ) . toBeCalledTimes ( 1 ) ; expect ( appSessionServiceMock . get ) . toBeCalledWith ( 'finalSpId' ) ; } ) ; it ( 'should return an object with data from session and oidcProvider interaction' , async ( ) => { const result = await controller . getInteraction ( req , res , oidcClientSessionServiceMock , appSessionServiceMock ) ; expect ( result ) . toEqual ( { uid : interactionMock . uid , params : interactionMock . params , spName : spNameMock , finalSpId : finalSpIdMock , } ) ; } ) ; } ) ; describe ( 'getLogin' , ( ) => { const interactionId = interactionIdMock ; const body = { login : loginMockValue , interactionId , acr : acrMock , } ; it ( 'should call service.getIdentity()' , async ( ) => { const identityMock = { } ; mockIdentityProviderFcaServiceMock . getIdentity . mockResolvedValue ( identityMock ) ; await controller . getLogin ( next , req , body , oidcClientSessionServiceMock ) ; expect ( mockIdentityProviderFcaServiceMock . getIdentity ) . toHaveBeenCalledTimes ( 1 ) ; expect ( mockIdentityProviderFcaServiceMock . getIdentity ) . toHaveBeenCalledWith ( body . login ) ; } ) ; it ( 'should store identity and acr in session' , async ( ) => { const identityMock = { } ; mockIdentityProviderFcaServiceMock . getIdentity . mockResolvedValue ( identityMock ) ; await controller . getLogin ( next , req , body , oidcClientSessionServiceMock ) ; expect ( oidcClientSessionServiceMock . set ) . toHaveBeenCalledTimes ( 1 ) ; expect ( oidcClientSessionServiceMock . set ) . toHaveBeenCalledWith ( { spIdentity : identityMock , spAcr : acrMock , } ) ; } ) ; it ( 'should call next if the identity is found' , async ( ) => { const accountMock = { } ; mockIdentityProviderFcaServiceMock . getIdentity . mockResolvedValue ( accountMock ) ; const interactionId = interactionIdMock ; const body = { interactionId , login : loginMockValue , acr : acrMock , } ; await controller . getLogin ( next , req , body , oidcClientSessionServiceMock ) ; expect ( next ) . toHaveBeenCalledTimes ( 1 ) ; } ) ; } ) ; it ( 'should throw an error and not call "next" if the identity is not found' , async ( ) => { mockIdentityProviderFcaServiceMock . getIdentity . mockResolvedValue ( undefined ) ; const interactionId = interactionIdMock ; const body = { interactionId , login : loginMockValue , acr : acrMock , } ; const expectedError = new Error ( 'Identity not found in database' ) ; await expect ( ( ) => controller . getLogin ( next , req , body , oidcClientSessionServiceMock ) ) . rejects . toThrow ( expectedError ) ; expect ( next ) . toHaveBeenCalledTimes ( 0 ) ; } ) ; } ) ;