@ -3,10 +3,9 @@ import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators' ;
import { AppEvents } from '@grafana/data' ;
import { BackendSrv , getBackendSrv } from '../services/backend_srv' ;
import { BackendSrv } from '../services/backend_srv' ;
import { Emitter } from '../utils/emitter' ;
import { ContextSrv , User } from '../services/context_srv' ;
import { CoreEvents } from '../../types' ;
import { describe , expect } from '../../../test/lib/common' ;
const getTestContext = ( overides? : object ) = > {
@ -47,7 +46,6 @@ const getTestContext = (overides?: object) => {
} as any ) as ContextSrv ;
const logoutMock = jest . fn ( ) ;
const parseRequestOptionsMock = jest . fn ( ) . mockImplementation ( options = > options ) ;
const parseDataSourceRequestOptionsMock = jest . fn ( ) . mockImplementation ( options = > options ) ;
const backendSrv = new BackendSrv ( {
fromFetch : fromFetchMock ,
@ -57,7 +55,6 @@ const getTestContext = (overides?: object) => {
} ) ;
backendSrv [ 'parseRequestOptions' ] = parseRequestOptionsMock ;
backendSrv [ 'parseDataSourceRequestOptions' ] = parseDataSourceRequestOptionsMock ;
const expectCallChain = ( options : any ) = > {
expect ( fromFetchMock ) . toHaveBeenCalledTimes ( 1 ) ;
@ -65,13 +62,7 @@ const getTestContext = (overides?: object) => {
const expectRequestCallChain = ( options : any ) = > {
expect ( parseRequestOptionsMock ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( parseRequestOptionsMock ) . toHaveBeenCalledWith ( options , 1337 ) ;
expectCallChain ( options ) ;
} ;
const expectDataSourceRequestCallChain = ( options : any ) = > {
expect ( parseDataSourceRequestOptionsMock ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( parseDataSourceRequestOptionsMock ) . toHaveBeenCalledWith ( options , 1337 , undefined ) ;
expect ( parseRequestOptionsMock ) . toHaveBeenCalledWith ( options ) ;
expectCallChain ( options ) ;
} ;
@ -83,33 +74,12 @@ const getTestContext = (overides?: object) => {
textMock ,
logoutMock ,
parseRequestOptionsMock ,
parseDataSourceRequestOptionsMock ,
expectRequestCallChain ,
expectDataSourceRequestCallChain ,
} ;
} ;
describe ( 'backendSrv' , ( ) = > {
describe ( 'parseRequestOptions' , ( ) = > {
it . each `
retry | url | orgId | expected
$ { undefined } | $ { 'http://localhost:3000/api/dashboard' } | $ { undefined } | $ { { retry : 0 , url : 'http://localhost:3000/api/dashboard' } }
$ { 1 } | $ { 'http://localhost:3000/api/dashboard' } | $ { 1 } | $ { { retry : 1 , url : 'http://localhost:3000/api/dashboard' } }
$ { undefined } | $ { 'api/dashboard' } | $ { undefined } | $ { { retry : 0 , url : 'api/dashboard' } }
$ { undefined } | $ { '/api/dashboard' } | $ { undefined } | $ { { retry : 0 , url : 'api/dashboard' } }
$ { undefined } | $ { '/api/dashboard/' } | $ { undefined } | $ { { retry : 0 , url : 'api/dashboard' } }
$ { 1 } | $ { '/api/dashboard/' } | $ { undefined } | $ { { retry : 1 , url : 'api/dashboard' } }
$ { undefined } | $ { '/api/dashboard/' } | $ { 1 } | $ { { retry : 0 , url : 'api/dashboard' , headers : { 'X-Grafana-Org-Id' : 1 } } }
$ { 1 } | $ { '/api/dashboard/' } | $ { 1 } | $ { { retry : 1 , url : 'api/dashboard' , headers : { 'X-Grafana-Org-Id' : 1 } } }
` (
"when called with retry: '$retry', url: '$url' and orgId: '$orgId' then result should be '$expected'" ,
( { retry , url , orgId , expected } ) = > {
expect ( getBackendSrv ( ) [ 'parseRequestOptions' ] ( { retry , url } , orgId ) ) . toEqual ( expected ) ;
}
) ;
} ) ;
describe ( 'parseDataSourceRequestOptions' , ( ) = > {
it . each `
retry | url | headers | orgId | noBackendCache | expected
$ { undefined } | $ { 'http://localhost:3000/api/dashboard' } | $ { undefined } | $ { undefined } | $ { undefined } | $ { { retry : 0 , url : 'http://localhost:3000/api/dashboard' } }
@ -125,11 +95,23 @@ describe('backendSrv', () => {
$ { 1 } | $ { '/api/dashboard/' } | $ { { Authorization : 'Some Auth' } } | $ { 1 } | $ { undefined } | $ { { retry : 1 , url : 'api/dashboard/' , headers : { 'X-DS-Authorization' : 'Some Auth' , 'X-Grafana-Org-Id' : 1 } } }
$ { 1 } | $ { '/api/dashboard/' } | $ { { Authorization : 'Some Auth' } } | $ { 1 } | $ { true } | $ { { retry : 1 , url : 'api/dashboard/' , headers : { 'X-DS-Authorization' : 'Some Auth' , 'X-Grafana-Org-Id' : 1 , 'X-Grafana-NoCache' : 'true' } } }
` (
"when called with retry: '$retry', url: '$url', he aders: '$headers', orgId: '$orgId' and noBackendCache: '$noBackendCache ' then result should be '$expected'" ,
"when called with retry: '$retry', url: '$url' an d orgId: '$orgId' then result should be '$expected'" ,
( { retry , url , headers , orgId , noBackendCache , expected } ) = > {
expect (
getBackendSrv ( ) [ 'parseDataSourceRequestOptions' ] ( { retry , url , headers } , orgId , noBackendCache )
) . toEqual ( expected ) ;
const srv = new BackendSrv ( {
contextSrv : {
user : {
orgId : orgId ,
} ,
} ,
} as any ) ;
if ( noBackendCache ) {
srv . withNoBackendCache ( async ( ) = > {
expect ( srv [ 'parseRequestOptions' ] ( { retry , url , headers } ) ) . toEqual ( expected ) ;
} ) ;
} else {
expect ( srv [ 'parseRequestOptions' ] ( { retry , url , headers } ) ) . toEqual ( expected ) ;
}
}
) ;
} ) ;
@ -142,6 +124,7 @@ describe('backendSrv', () => {
} ) ;
const url = '/api/dashboard/' ;
const result = await backendSrv . request ( { url , method : 'DELETE' , showSuccessAlert : false } ) ;
expect ( result ) . toEqual ( { message : 'A message' } ) ;
expect ( appEventsMock . emit ) . not . toHaveBeenCalled ( ) ;
expectRequestCallChain ( { url , method : 'DELETE' , showSuccessAlert : false } ) ;
@ -155,6 +138,7 @@ describe('backendSrv', () => {
} ) ;
const url = '/api/dashboard/' ;
const result = await backendSrv . request ( { url , method : 'DELETE' , showSuccessAlert : true } ) ;
expect ( result ) . toEqual ( { message : 'A message' } ) ;
expect ( appEventsMock . emit ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( appEventsMock . emit ) . toHaveBeenCalledWith ( AppEvents . alertSuccess , [ 'A message' ] ) ;
@ -162,61 +146,6 @@ describe('backendSrv', () => {
} ) ;
} ) ;
describe ( 'when called with the same requestId twice' , ( ) = > {
it ( 'then it should cancel the first call and the first call should be unsubscribed' , async ( ) = > {
const url = '/api/dashboard/' ;
const { backendSrv , fromFetchMock } = getTestContext ( { url } ) ;
const unsubscribe = jest . fn ( ) ;
const slowData = { message : 'Slow Request' } ;
const slowFetch = new Observable ( subscriber = > {
subscriber . next ( {
ok : true ,
status : 200 ,
statusText : 'Ok' ,
text : ( ) = > Promise . resolve ( JSON . stringify ( slowData ) ) ,
headers : {
map : {
'content-type' : 'application/json' ,
} ,
} ,
redirected : false ,
type : 'basic' ,
url ,
} ) ;
return unsubscribe ;
} ) . pipe ( delay ( 10000 ) ) ;
const fastData = { message : 'Fast Request' } ;
const fastFetch = of ( {
ok : true ,
status : 200 ,
statusText : 'Ok' ,
text : ( ) = > Promise . resolve ( JSON . stringify ( fastData ) ) ,
headers : {
map : {
'content-type' : 'application/json' ,
} ,
} ,
redirected : false ,
type : 'basic' ,
url ,
} ) ;
fromFetchMock . mockImplementationOnce ( ( ) = > slowFetch ) ;
fromFetchMock . mockImplementation ( ( ) = > fastFetch ) ;
const options = {
url ,
method : 'GET' ,
requestId : 'A' ,
} ;
const slowRequest = backendSrv . request ( options ) ;
const fastResponse = await backendSrv . request ( options ) ;
expect ( fastResponse ) . toEqual ( { message : 'Fast Request' } ) ;
const result = await slowRequest ;
expect ( result ) . toEqual ( [ ] ) ;
expect ( unsubscribe ) . toHaveBeenCalledTimes ( 1 ) ;
} ) ;
} ) ;
describe ( 'when making an unsuccessful call and conditions for retry are favorable and loginPing does not throw' , ( ) = > {
it ( 'then it should retry' , async ( ) = > {
jest . useFakeTimers ( ) ;
@ -228,9 +157,11 @@ describe('backendSrv', () => {
data : { message : 'UnAuthorized' } ,
url ,
} ) ;
backendSrv . loginPing = jest
. fn ( )
. mockResolvedValue ( { ok : true , status : 200 , statusText : 'OK' , data : { message : 'Ok' } } ) ;
await backendSrv
. request ( { url , method : 'GET' , retry : 0 } )
. catch ( error = > {
@ -260,10 +191,12 @@ describe('backendSrv', () => {
statusText : 'UnAuthorized' ,
data : { message : 'UnAuthorized' } ,
} ) ;
backendSrv . loginPing = jest
. fn ( )
. mockRejectedValue ( { status : 403 , statusText : 'Forbidden' , data : { message : 'Forbidden' } } ) ;
const url = '/api/dashboard/' ;
await backendSrv
. request ( { url , method : 'GET' , retry : 0 } )
. catch ( error = > {
@ -294,6 +227,7 @@ describe('backendSrv', () => {
data : { message : 'Unprocessable Entity' } ,
} ) ;
const url = '/api/dashboard/' ;
await backendSrv
. request ( { url , method : 'GET' } )
. catch ( error = > {
@ -326,6 +260,7 @@ describe('backendSrv', () => {
data : { message : 'Not found' } ,
} ) ;
const url = '/api/dashboard/' ;
await backendSrv . request ( { url , method : 'GET' } ) . catch ( error = > {
expect ( error . status ) . toBe ( 404 ) ;
expect ( error . statusText ) . toBe ( 'Not found' ) ;
@ -345,9 +280,10 @@ describe('backendSrv', () => {
describe ( 'when making a successful call and silent is true' , ( ) = > {
it ( 'then it should not emit message' , async ( ) = > {
const url = 'http://localhost:3000/api/some-mock' ;
const { backendSrv , appEventsMock , expectDataSource RequestCallChain } = getTestContext ( { url } ) ;
const { backendSrv , appEventsMock , expectRequestCallChain } = getTestContext ( { url } ) ;
const options = { url , method : 'GET' , silent : true } ;
const result = await backendSrv . datasourceRequest ( options ) ;
expect ( result ) . toEqual ( {
data : { test : 'hello world' } ,
ok : true ,
@ -358,16 +294,23 @@ describe('backendSrv', () => {
url ,
config : options ,
} ) ;
expect ( appEventsMock . emit ) . not . toHaveBeenCalled ( ) ;
expectDataSource RequestCallChain ( { url , method : 'GET' , silent : true } ) ;
expectRequestCallChain ( { url , method : 'GET' , silent : true } ) ;
} ) ;
} ) ;
describe ( 'when making a successful call and silent is not defined' , ( ) = > {
it ( 'then it should not emit message' , async ( ) = > {
const url = 'http://localhost:3000/api/some-mock' ;
const { backendSrv , appEventsMock , expectDataSource RequestCallChain } = getTestContext ( { url } ) ;
const { backendSrv , expectRequestCallChain } = getTestContext ( { url } ) ;
const options = { url , method : 'GET' } ;
let inspectorPacket : any = null ;
backendSrv . getInspectorStream ( ) . subscribe ( {
next : rsp = > ( inspectorPacket = rsp ) ,
} ) ;
const result = await backendSrv . datasourceRequest ( options ) ;
const expectedResult = {
data : { test : 'hello world' } ,
@ -381,9 +324,8 @@ describe('backendSrv', () => {
} ;
expect ( result ) . toEqual ( expectedResult ) ;
expect ( appEventsMock . emit ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( appEventsMock . emit ) . toHaveBeenCalledWith ( CoreEvents . dsRequestResponse , expectedResult ) ;
expectDataSourceRequestCallChain ( { url , method : 'GET' } ) ;
expect ( inspectorPacket ) . toEqual ( expectedResult ) ;
expectRequestCallChain ( { url , method : 'GET' } ) ;
} ) ;
} ) ;
@ -405,6 +347,7 @@ describe('backendSrv', () => {
} ) ;
return unsubscribe ;
} ) . pipe ( delay ( 10000 ) ) ;
const fastData = { message : 'Fast Request' } ;
const fastFetch = of ( {
ok : true ,
@ -415,118 +358,119 @@ describe('backendSrv', () => {
type : 'basic' ,
url ,
} ) ;
fromFetchMock . mockImplementationOnce ( ( ) = > slowFetch ) ;
fromFetchMock . mockImplementation ( ( ) = > fastFetch ) ;
const options = {
url ,
method : 'GET' ,
requestId : 'A' ,
} ;
const slowRequest = backendSrv . datasourceRequest ( options ) ;
const fastResponse = await backendSrv . datasourceRequest ( options ) ;
let slowError : any = null ;
backendSrv . request ( options ) . catch ( err = > {
slowError = err ;
} ) ;
const fastResponse = await backendSrv . request ( options ) ;
expect ( fastResponse ) . toEqual ( {
data : { message : 'Fast Request' } ,
ok : true ,
redirected : false ,
status : 200 ,
statusText : 'Ok' ,
type : 'basic' ,
url : '/api/dashboard/' ,
config : options ,
message : 'Fast Request' ,
} ) ;
const result = await slowRequest ;
expect ( result ) . toEqual ( {
data : [ ] ,
expect ( unsubscribe ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( slowError ) . toEqual ( {
cancelled : true ,
data : null ,
status : - 1 ,
statusText : 'Request was aborted' ,
config : options ,
} ) ;
expect ( unsubscribe ) . toHaveBeenCalledTimes ( 1 ) ;
} ) ;
} ) ;
describe ( 'when making an unsuccessful call and conditions for retry are favorable and loginPing does not throw' , ( ) = > {
it ( 'then it should retry' , async ( ) = > {
const { backendSrv , appEventsMock , logoutMock , expectDataSource RequestCallChain } = getTestContext ( {
const { backendSrv , logoutMock , expectRequestCallChain } = getTestContext ( {
ok : false ,
status : 401 ,
statusText : 'UnAuthorized' ,
data : { message : 'UnAuthorized' } ,
} ) ;
backendSrv . loginPing = jest
. fn ( )
. mockResolvedValue ( { ok : true , status : 200 , statusText : 'OK' , data : { message : 'Ok' } } ) ;
const url = '/api/dashboard/' ;
let inspectorPacket : any = null ;
backendSrv . getInspectorStream ( ) . subscribe ( {
next : rsp = > ( inspectorPacket = rsp ) ,
} ) ;
await backendSrv . datasourceRequest ( { url , method : 'GET' , retry : 0 } ) . catch ( error = > {
expect ( error . status ) . toBe ( 401 ) ;
expect ( error . statusText ) . toBe ( 'UnAuthorized' ) ;
expect ( error . data ) . toEqual ( { message : 'UnAuthorized' } ) ;
expect ( appEventsMock . emit ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( appEventsMock . emit ) . toHaveBeenCalledWith ( CoreEvents . dsRequestError , {
data : { message : 'UnAuthorized' } ,
status : 401 ,
statusText : 'UnAuthorized' ,
} ) ;
expect ( inspectorPacket ) . toBe ( error ) ;
expect ( backendSrv . loginPing ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( logoutMock ) . not . toHaveBeenCalled ( ) ;
expectDataSource RequestCallChain ( { url , method : 'GET' , retry : 0 } ) ;
expectRequestCallChain ( { url , method : 'GET' , retry : 0 } ) ;
} ) ;
} ) ;
} ) ;
describe ( 'when making an unsuccessful call and conditions for retry are favorable and retry throws' , ( ) = > {
it ( 'then it throw error' , async ( ) = > {
const { backendSrv , appEventsMock , logoutMock , expectDataSource RequestCallChain } = getTestContext ( {
const { backendSrv , logoutMock , expectRequestCallChain } = getTestContext ( {
ok : false ,
status : 401 ,
statusText : 'UnAuthorized' ,
data : { message : 'UnAuthorized' } ,
} ) ;
const options = {
url : '/api/dashboard/' ,
method : 'GET' ,
retry : 0 ,
} ;
backendSrv . loginPing = jest
. fn ( )
. mockRejectedValue ( { status : 403 , statusText : 'Forbidden' , data : { message : 'Forbidden' } } ) ;
const url = '/api/dashboard/' ;
await backendSrv . datasourceRequest ( { url , method : 'GET' , retry : 0 } ) . catch ( error = > {
await backendSrv . datasourceRequest ( options ) . catch ( error = > {
expect ( error . status ) . toBe ( 403 ) ;
expect ( error . statusText ) . toBe ( 'Forbidden' ) ;
expect ( error . data ) . toEqual ( { message : 'Forbidden' } ) ;
expect ( appEventsMock . emit ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( appEventsMock . emit ) . toHaveBeenCalledWith ( CoreEvents . dsRequestError , {
data : { message : 'Forbidden' } ,
status : 403 ,
statusText : 'Forbidden' ,
} ) ;
expect ( backendSrv . loginPing ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( logoutMock ) . not . toHaveBeenCalled ( ) ;
expectDataSource RequestCallChain ( { url , method : 'GET' , retry : 0 } ) ;
expectRequestCallChain ( options ) ;
} ) ;
} ) ;
} ) ;
describe ( 'when making an Internal Error call' , ( ) = > {
it ( 'then it should throw cancelled error' , async ( ) = > {
const { backendSrv , appEventsMock , logoutMock , expectDataSource RequestCallChain } = getTestContext ( {
const { backendSrv , logoutMock , expectRequestCallChain } = getTestContext ( {
ok : false ,
status : 500 ,
statusText : 'Internal Server Error' ,
data : 'Internal Server Error' ,
} ) ;
const url = '/api/dashboard/' ;
await backendSrv . datasourceRequest ( { url , method : 'GET' } ) . catch ( error = > {
const options = {
url : '/api/dashboard/' ,
method : 'GET' ,
} ;
await backendSrv . datasourceRequest ( options ) . catch ( error = > {
expect ( error ) . toEqual ( {
status : 500 ,
statusText : 'Internal Server Error' ,
data : {
error : 'Internal Server Error' ,
response : 'Internal Server Error' ,
message : 'Internal Server Error' ,
} ,
} ) ;
expect ( appEventsMock . emit ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( appEventsMock . emit ) . toHaveBeenCalledWith ( CoreEvents . dsRequestError , {
status : 500 ,
statusText : 'Internal Server Error' ,
config : options ,
data : {
error : 'Internal Server Error' ,
response : 'Internal Server Error' ,
@ -534,40 +478,42 @@ describe('backendSrv', () => {
} ,
} ) ;
expect ( logoutMock ) . not . toHaveBeenCalled ( ) ;
expectDataSource RequestCallChain ( { url , method : 'GET' } ) ;
expectRequestCallChain ( options ) ;
} ) ;
} ) ;
} ) ;
describe ( 'when formatting prometheus error' , ( ) = > {
it ( 'then it should throw cancelled error' , async ( ) = > {
const { backendSrv , appEventsMock , logoutMock , expectDataSource RequestCallChain } = getTestContext ( {
const { backendSrv , logoutMock , expectRequestCallChain } = getTestContext ( {
ok : false ,
status : 403 ,
statusText : 'Forbidden' ,
data : { error : 'Forbidden' } ,
} ) ;
const url = '/api/dashboard/' ;
await backendSrv . datasourceRequest ( { url , method : 'GET' } ) . catch ( error = > {
const options = {
url : '/api/dashboard/' ,
method : 'GET' ,
} ;
let inspectorPacket : any = null ;
backendSrv . getInspectorStream ( ) . subscribe ( {
next : rsp = > ( inspectorPacket = rsp ) ,
} ) ;
await backendSrv . datasourceRequest ( options ) . catch ( error = > {
expect ( error ) . toEqual ( {
status : 403 ,
statusText : 'Forbidden' ,
config : options ,
data : {
error : 'Forbidden' ,
message : 'Forbidden' ,
} ,
} ) ;
expect ( appEventsMock . emit ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( appEventsMock . emit ) . toHaveBeenCalledWith ( CoreEvents . dsRequestError , {
status : 403 ,
statusText : 'Forbidden' ,
data : {
error : 'Forbidden' ,
message : 'Forbidden' ,
} ,
} ) ;
expect ( inspectorPacket ) . toEqual ( error ) ;
expect ( logoutMock ) . not . toHaveBeenCalled ( ) ;
expectDataSource RequestCallChain ( { url , method : 'GET' } ) ;
expectRequestCallChain ( options ) ;
} ) ;
} ) ;
} ) ;
@ -575,23 +521,7 @@ describe('backendSrv', () => {
describe ( 'cancelAllInFlightRequests' , ( ) = > {
describe ( 'when called with 2 separate requests and then cancelAllInFlightRequests is called' , ( ) = > {
enum RequestType {
request ,
dataSourceRequest ,
}
const url = '/api/dashboard/' ;
const options = {
url ,
method : 'GET' ,
} ;
const dataSourceRequestResult = {
data : ( [ ] as unknown [ ] ) as any [ ] ,
status : - 1 ,
statusText : 'Request was aborted' ,
config : options ,
} ;
const getRequestObservable = ( message : string , unsubscribe : any ) = >
new Observable ( subscriber = > {
@ -612,47 +542,37 @@ describe('backendSrv', () => {
return unsubscribe ;
} ) . pipe ( delay ( 10000 ) ) ;
it . each `
firstRequestType | secondRequestType | firstRequestResult | secondRequestResult
$ { RequestType . request } | $ { RequestType . request } | $ { [ ] } | $ { [ ] }
$ { RequestType . dataSourceRequest } | $ { RequestType . dataSourceRequest } | $ { dataSourceRequestResult } | $ { dataSourceRequestResult }
$ { RequestType . request } | $ { RequestType . dataSourceRequest } | $ { [ ] } | $ { dataSourceRequestResult }
$ { RequestType . dataSourceRequest } | $ { RequestType . request } | $ { dataSourceRequestResult } | $ { [ ] }
` (
'then it both requests should be cancelled and unsubscribed' ,
async ( { firstRequestType , secondRequestType , firstRequestResult , secondRequestResult } ) = > {
const unsubscribe = jest . fn ( ) ;
const { backendSrv , fromFetchMock } = getTestContext ( { url } ) ;
const firstObservable = getRequestObservable ( 'First' , unsubscribe ) ;
const secondObservable = getRequestObservable ( 'Second' , unsubscribe ) ;
fromFetchMock . mockImplementationOnce ( ( ) = > firstObservable ) ;
fromFetchMock . mockImplementation ( ( ) = > secondObservable ) ;
const options = {
url ,
method : 'GET' ,
} ;
it ( 'then it both requests should be cancelled and unsubscribed' , async ( ) = > {
const unsubscribe = jest . fn ( ) ;
const { backendSrv , fromFetchMock } = getTestContext ( { url } ) ;
const firstObservable = getRequestObservable ( 'First' , unsubscribe ) ;
const secondObservable = getRequestObservable ( 'Second' , unsubscribe ) ;
const firstRequest =
firstRequestType === RequestType . request
? backendSrv . request ( options )
: backendSrv . datasourceRequest ( options ) ;
fromFetchMock . mockImplementationOnce ( ( ) = > firstObservable ) ;
fromFetchMock . mockImplementation ( ( ) = > secondObservable ) ;
const secondRequest =
secondRequestType === RequestType . request
? backendSrv . request ( options )
: backendSrv . datasourceRequest ( options ) ;
const options = {
url ,
method : 'GET' ,
} ;
const firstRequest = backendSrv . request ( options ) ;
const secondRequest = backendSrv . request ( options ) ;
backendSrv . cancelAllInFlightRequests ( ) ;
backendSrv . cancelAllInFlightRequests ( ) ;
const result = await Promise . all ( [ firstRequest , secondRequest ] ) ;
let catchedError : any = null ;
expect ( result [ 0 ] ) . toEqual ( firstRequestResult ) ;
expect ( result [ 1 ] ) . toEqual ( secondRequestResult ) ;
expect ( unsubscribe ) . toHaveBeenCalledTimes ( 2 ) ;
try {
await Promise . all ( [ firstRequest , secondRequest ] ) ;
} catch ( err ) {
catchedError = err ;
}
) ;
expect ( catchedError . cancelled ) . toEqual ( true ) ;
expect ( catchedError . statusText ) . toEqual ( 'Request was aborted' ) ;
expect ( unsubscribe ) . toHaveBeenCalledTimes ( 2 ) ;
} ) ;
} ) ;
} ) ;
} ) ;