@@ -10,10 +10,16 @@ import {
10
10
ScheduleHandle ,
11
11
ScheduleSummary ,
12
12
ScheduleUpdateOptions ,
13
+ ScheduleDescription ,
13
14
} from '@temporalio/client' ;
14
15
import { msToNumber } from '@temporalio/common/lib/time' ;
15
- import { SearchAttributes , TypedSearchAttributes } from '@temporalio/common' ;
16
- import { registerDefaultCustomSearchAttributes , RUN_INTEGRATION_TESTS } from './helpers' ;
16
+ import {
17
+ SearchAttributeType ,
18
+ SearchAttributes ,
19
+ TypedSearchAttributes ,
20
+ defineSearchAttributeKey ,
21
+ } from '@temporalio/common' ;
22
+ import { registerDefaultCustomSearchAttributes , RUN_INTEGRATION_TESTS , waitUntil } from './helpers' ;
17
23
import { defaultSAKeys } from './helpers-integration' ;
18
24
19
25
export interface Context {
@@ -751,4 +757,128 @@ if (RUN_INTEGRATION_TESTS) {
751
757
await handle . delete ( ) ;
752
758
}
753
759
} ) ;
760
+
761
+ test . serial ( 'Can update search attributes of a schedule' , async ( t ) => {
762
+ const { client } = t . context ;
763
+ const scheduleId = `can-update-search-attributes-of-schedule-${ randomUUID ( ) } ` ;
764
+
765
+ // Helper to wait for search attribute changes to propagate.
766
+ const waitForAttributeChange = async (
767
+ handle : ScheduleHandle ,
768
+ attributeName : string ,
769
+ shouldExist : boolean
770
+ ) : Promise < ScheduleDescription > => {
771
+ await waitUntil ( async ( ) => {
772
+ const desc = await handle . describe ( ) ;
773
+ const exists =
774
+ desc . typedSearchAttributes . getAll ( ) . find ( ( pair ) => pair . key . name === attributeName ) !== undefined ;
775
+ return exists === shouldExist ;
776
+ } , 300 ) ;
777
+ return await handle . describe ( ) ;
778
+ } ;
779
+
780
+ // Create a schedule with search attributes.
781
+ const handle = await client . schedule . create ( {
782
+ scheduleId,
783
+ spec : {
784
+ calendars : [ { hour : { start : 2 , end : 7 , step : 1 } } ] ,
785
+ } ,
786
+ action : {
787
+ type : 'startWorkflow' ,
788
+ workflowType : dummyWorkflow ,
789
+ taskQueue,
790
+ } ,
791
+ searchAttributes : {
792
+ CustomKeywordField : [ 'keyword-one' ] ,
793
+ } ,
794
+ typedSearchAttributes : [ { key : defineSearchAttributeKey ( 'CustomIntField' , SearchAttributeType . INT ) , value : 1 } ] ,
795
+ } ) ;
796
+
797
+ // Check the search attributes are part of the schedule description.
798
+ const desc = await handle . describe ( ) ;
799
+ // eslint-disable-next-line deprecation/deprecation
800
+ t . deepEqual ( desc . searchAttributes , {
801
+ CustomKeywordField : [ 'keyword-one' ] ,
802
+ CustomIntField : [ 1 ] ,
803
+ } ) ;
804
+ t . deepEqual (
805
+ desc . typedSearchAttributes ,
806
+ new TypedSearchAttributes ( [
807
+ { key : defineSearchAttributeKey ( 'CustomIntField' , SearchAttributeType . INT ) , value : 1 } ,
808
+ { key : defineSearchAttributeKey ( 'CustomKeywordField' , SearchAttributeType . KEYWORD ) , value : 'keyword-one' } ,
809
+ ] )
810
+ ) ;
811
+
812
+ // Perform a series of updates to schedule's search attributes.
813
+ try {
814
+ // Update existing search attributes, add new ones.
815
+ await handle . update ( ( desc ) => ( {
816
+ ...desc ,
817
+ searchAttributes : {
818
+ CustomKeywordField : [ 'keyword-two' ] ,
819
+ // Add a new search attribute.
820
+ CustomDoubleField : [ 1.5 ] ,
821
+ } ,
822
+ typedSearchAttributes : [
823
+ { key : defineSearchAttributeKey ( 'CustomIntField' , SearchAttributeType . INT ) , value : 2 } ,
824
+ // Add a new typed search attribute.
825
+ { key : defineSearchAttributeKey ( 'CustomTextField' , SearchAttributeType . TEXT ) , value : 'new-text' } ,
826
+ ] ,
827
+ } ) ) ;
828
+
829
+ let desc = await waitForAttributeChange ( handle , 'CustomTextField' , true ) ;
830
+ // eslint-disable-next-line deprecation/deprecation
831
+ t . deepEqual ( desc . searchAttributes , {
832
+ CustomKeywordField : [ 'keyword-two' ] ,
833
+ CustomIntField : [ 2 ] ,
834
+ CustomDoubleField : [ 1.5 ] ,
835
+ CustomTextField : [ 'new-text' ] ,
836
+ } ) ;
837
+ t . deepEqual (
838
+ desc . typedSearchAttributes ,
839
+ new TypedSearchAttributes ( [
840
+ { key : defineSearchAttributeKey ( 'CustomIntField' , SearchAttributeType . INT ) , value : 2 } ,
841
+ { key : defineSearchAttributeKey ( 'CustomKeywordField' , SearchAttributeType . KEYWORD ) , value : 'keyword-two' } ,
842
+ { key : defineSearchAttributeKey ( 'CustomTextField' , SearchAttributeType . TEXT ) , value : 'new-text' } ,
843
+ { key : defineSearchAttributeKey ( 'CustomDoubleField' , SearchAttributeType . DOUBLE ) , value : 1.5 } ,
844
+ ] )
845
+ ) ;
846
+
847
+ // Update and remove some search attributes. We remove a search attribute by omitting an existing key from the update.
848
+ await handle . update ( ( desc ) => ( {
849
+ ...desc ,
850
+ searchAttributes : {
851
+ CustomKeywordField : [ 'keyword-three' ] ,
852
+ } ,
853
+ typedSearchAttributes : [ { key : defineSearchAttributeKey ( 'CustomIntField' , SearchAttributeType . INT ) , value : 3 } ] ,
854
+ } ) ) ;
855
+
856
+ desc = await waitForAttributeChange ( handle , 'CustomTextField' , false ) ;
857
+ // eslint-disable-next-line deprecation/deprecation
858
+ t . deepEqual ( desc . searchAttributes , {
859
+ CustomKeywordField : [ 'keyword-three' ] ,
860
+ CustomIntField : [ 3 ] ,
861
+ } ) ;
862
+ t . deepEqual (
863
+ desc . typedSearchAttributes ,
864
+ new TypedSearchAttributes ( [
865
+ { key : defineSearchAttributeKey ( 'CustomIntField' , SearchAttributeType . INT ) , value : 3 } ,
866
+ { key : defineSearchAttributeKey ( 'CustomKeywordField' , SearchAttributeType . KEYWORD ) , value : 'keyword-three' } ,
867
+ ] )
868
+ ) ;
869
+
870
+ // Remove all search attributes.
871
+ await handle . update ( ( desc ) => ( {
872
+ ...desc ,
873
+ searchAttributes : { } ,
874
+ typedSearchAttributes : [ ] ,
875
+ } ) ) ;
876
+
877
+ desc = await waitForAttributeChange ( handle , 'CustomIntField' , false ) ;
878
+ t . deepEqual ( desc . searchAttributes , { } ) ; // eslint-disable-line deprecation/deprecation
879
+ t . deepEqual ( desc . typedSearchAttributes , new TypedSearchAttributes ( [ ] ) ) ;
880
+ } finally {
881
+ await handle . delete ( ) ;
882
+ }
883
+ } ) ;
754
884
}
0 commit comments