44 * you may not use this file except in compliance with the Elastic License.
55 */
66import { savedObjectsClientMock } from 'src/core/server/mocks' ;
7- import { createAgentActionFromPolicyAction } from './state_new_actions' ;
8- import { OutputType , Agent , AgentPolicyAction } from '../../../types' ;
7+ import { take } from 'rxjs/operators' ;
8+ import {
9+ createAgentActionFromPolicyAction ,
10+ createNewActionsSharedObservable ,
11+ } from './state_new_actions' ;
12+ import { getNewActionsSince } from '../actions' ;
13+ import { OutputType , Agent , AgentAction , AgentPolicyAction } from '../../../types' ;
914
1015jest . mock ( '../../app_context' , ( ) => ( {
1116 appContextService : {
17+ getInternalUserSOClient : ( ) => {
18+ return { } ;
19+ } ,
1220 getEncryptedSavedObjects : ( ) => ( {
1321 getDecryptedAsInternalUser : ( ) => ( {
1422 attributes : {
@@ -19,7 +27,83 @@ jest.mock('../../app_context', () => ({
1927 } ,
2028} ) ) ;
2129
30+ jest . mock ( '../actions' ) ;
31+
32+ jest . useFakeTimers ( ) ;
33+
34+ function waitForPromiseResolved ( ) {
35+ return new Promise ( ( resolve ) => setImmediate ( resolve ) ) ;
36+ }
37+
38+ function getMockedNewActionSince ( ) {
39+ return getNewActionsSince as jest . MockedFunction < typeof getNewActionsSince > ;
40+ }
41+
2242describe ( 'test agent checkin new action services' , ( ) => {
43+ describe ( 'newAgetActionObservable' , ( ) => {
44+ beforeEach ( ( ) => {
45+ ( getNewActionsSince as jest . MockedFunction < typeof getNewActionsSince > ) . mockReset ( ) ;
46+ } ) ;
47+ it ( 'should work, call get actions until there is new action' , async ( ) => {
48+ const observable = createNewActionsSharedObservable ( ) ;
49+
50+ getMockedNewActionSince ( )
51+ . mockResolvedValueOnce ( [ ] )
52+ . mockResolvedValueOnce ( [
53+ ( { id : 'action1' , created_at : new Date ( ) . toISOString ( ) } as unknown ) as AgentAction ,
54+ ] )
55+ . mockResolvedValueOnce ( [
56+ ( { id : 'action2' , created_at : new Date ( ) . toISOString ( ) } as unknown ) as AgentAction ,
57+ ] ) ;
58+ // First call
59+ const promise = observable . pipe ( take ( 1 ) ) . toPromise ( ) ;
60+
61+ jest . advanceTimersByTime ( 5000 ) ;
62+ await waitForPromiseResolved ( ) ;
63+ jest . advanceTimersByTime ( 5000 ) ;
64+ await waitForPromiseResolved ( ) ;
65+
66+ const res = await promise ;
67+ expect ( getNewActionsSince ) . toBeCalledTimes ( 2 ) ;
68+ expect ( res ) . toHaveLength ( 1 ) ;
69+ expect ( res [ 0 ] . id ) . toBe ( 'action1' ) ;
70+ // Second call
71+ const secondSubscription = observable . pipe ( take ( 1 ) ) . toPromise ( ) ;
72+
73+ jest . advanceTimersByTime ( 5000 ) ;
74+ await waitForPromiseResolved ( ) ;
75+
76+ const secondRes = await secondSubscription ;
77+ expect ( secondRes ) . toHaveLength ( 1 ) ;
78+ expect ( secondRes [ 0 ] . id ) . toBe ( 'action2' ) ;
79+ expect ( getNewActionsSince ) . toBeCalledTimes ( 3 ) ;
80+ // It should call getNewActionsSince with the last action returned
81+ expect ( getMockedNewActionSince ( ) . mock . calls [ 2 ] [ 1 ] ) . toBe ( res [ 0 ] . created_at ) ;
82+ } ) ;
83+
84+ it ( 'should not fetch actions concurrently' , async ( ) => {
85+ const observable = createNewActionsSharedObservable ( ) ;
86+
87+ const resolves : Array < ( ) => void > = [ ] ;
88+ getMockedNewActionSince ( ) . mockImplementation ( ( ) => {
89+ return new Promise ( ( resolve ) => {
90+ resolves . push ( resolve ) ;
91+ } ) ;
92+ } ) ;
93+
94+ observable . pipe ( take ( 1 ) ) . toPromise ( ) ;
95+
96+ jest . advanceTimersByTime ( 5000 ) ;
97+ await waitForPromiseResolved ( ) ;
98+ jest . advanceTimersByTime ( 5000 ) ;
99+ await waitForPromiseResolved ( ) ;
100+ jest . advanceTimersByTime ( 5000 ) ;
101+ await waitForPromiseResolved ( ) ;
102+
103+ expect ( getNewActionsSince ) . toBeCalledTimes ( 1 ) ;
104+ } ) ;
105+ } ) ;
106+
23107 describe ( 'createAgentActionFromPolicyAction()' , ( ) => {
24108 const mockSavedObjectsClient = savedObjectsClientMock . create ( ) ;
25109 const mockAgent : Agent = {
0 commit comments