@@ -3576,6 +3576,8 @@ describe( 'state', () => {
3576
3576
blocks,
3577
3577
settings,
3578
3578
zoomLevel,
3579
+ blockListSettings,
3580
+ blockEditingModes,
3579
3581
} )
3580
3582
) ;
3581
3583
@@ -3957,6 +3959,210 @@ describe( 'state', () => {
3957
3959
} ) ;
3958
3960
} ) ;
3959
3961
3962
+ describe ( 'contentOnly template locking' , ( ) => {
3963
+ let initialState ;
3964
+ beforeAll ( ( ) => {
3965
+ select . mockImplementation ( ( storeName ) => {
3966
+ if ( storeName === preferencesStore ) {
3967
+ return {
3968
+ get : jest . fn ( ( ) => 'edit' ) ,
3969
+ } ;
3970
+ }
3971
+ return select ( storeName ) ;
3972
+ } ) ;
3973
+
3974
+ // Simulates how the editor typically inserts controlled blocks,
3975
+ // - first the pattern is inserted with no inner blocks.
3976
+ // - next the pattern is marked as a controlled block.
3977
+ // - finally, once the inner blocks of the pattern are received, they're inserted.
3978
+ // This process is repeated for the two patterns in this test.
3979
+ initialState = dispatchActions (
3980
+ [
3981
+ {
3982
+ type : 'UPDATE_SETTINGS' ,
3983
+ settings : {
3984
+ [ sectionRootClientIdKey ] : '' ,
3985
+ } ,
3986
+ } ,
3987
+ {
3988
+ type : 'RESET_BLOCKS' ,
3989
+ blocks : [
3990
+ {
3991
+ name : 'core/group' ,
3992
+ clientId : 'group-1' ,
3993
+ attributes : { } ,
3994
+ innerBlocks : [
3995
+ {
3996
+ name : 'core/paragraph' ,
3997
+ clientId : 'paragraph-1' ,
3998
+ attributes : { } ,
3999
+ innerBlocks : [ ] ,
4000
+ } ,
4001
+ {
4002
+ name : 'core/group' ,
4003
+ clientId : 'group-2' ,
4004
+ attributes : { } ,
4005
+ innerBlocks : [
4006
+ {
4007
+ name : 'core/paragraph' ,
4008
+ clientId : 'paragraph-2' ,
4009
+ attributes : { } ,
4010
+ innerBlocks : [ ] ,
4011
+ } ,
4012
+ ] ,
4013
+ } ,
4014
+ ] ,
4015
+ } ,
4016
+ ] ,
4017
+ } ,
4018
+ {
4019
+ type : 'UPDATE_BLOCK_LIST_SETTINGS' ,
4020
+ clientId : 'group-1' ,
4021
+ settings : {
4022
+ templateLock : 'contentOnly' ,
4023
+ } ,
4024
+ } ,
4025
+ ] ,
4026
+ testReducer ,
4027
+ initialState
4028
+ ) ;
4029
+ } ) ;
4030
+
4031
+ afterAll ( ( ) => {
4032
+ select . mockRestore ( ) ;
4033
+ } ) ;
4034
+
4035
+ it ( 'returns the expected block editing modes for a parent block with contentOnly template locking' , ( ) => {
4036
+ // Only the parent pattern and its own children that have bindings
4037
+ // are in contentOnly mode. All other blocks are disabled.
4038
+ expect ( initialState . derivedBlockEditingModes ) . toEqual (
4039
+ new Map (
4040
+ Object . entries ( {
4041
+ 'paragraph-1' : 'contentOnly' ,
4042
+ 'group-2' : 'disabled' ,
4043
+ 'paragraph-2' : 'contentOnly' ,
4044
+ } )
4045
+ )
4046
+ ) ;
4047
+ } ) ;
4048
+
4049
+ it ( 'removes block editing modes when template locking is removed' , ( ) => {
4050
+ const { derivedBlockEditingModes } = dispatchActions (
4051
+ [
4052
+ {
4053
+ type : 'UPDATE_BLOCK_LIST_SETTINGS' ,
4054
+ clientId : 'group-1' ,
4055
+ settings : {
4056
+ templateLock : false ,
4057
+ } ,
4058
+ } ,
4059
+ ] ,
4060
+ testReducer ,
4061
+ initialState
4062
+ ) ;
4063
+
4064
+ expect ( derivedBlockEditingModes ) . toEqual ( new Map ( ) ) ;
4065
+ } ) ;
4066
+
4067
+ it ( 'allows explicitly set blockEditingModes to override the contentOnly template locking' , ( ) => {
4068
+ const { derivedBlockEditingModes } = dispatchActions (
4069
+ [
4070
+ {
4071
+ type : 'SET_BLOCK_EDITING_MODE' ,
4072
+ clientId : 'group-1' ,
4073
+ mode : 'disabled' ,
4074
+ } ,
4075
+ {
4076
+ type : 'SET_BLOCK_EDITING_MODE' ,
4077
+ clientId : 'paragraph-2' ,
4078
+ mode : 'disabled' ,
4079
+ } ,
4080
+ ] ,
4081
+ testReducer ,
4082
+ initialState
4083
+ ) ;
4084
+
4085
+ expect ( derivedBlockEditingModes ) . toEqual (
4086
+ new Map (
4087
+ Object . entries ( {
4088
+ 'paragraph-1' : 'contentOnly' ,
4089
+ 'group-2' : 'disabled' ,
4090
+ 'paragraph-2' : 'contentOnly' ,
4091
+ } )
4092
+ )
4093
+ ) ;
4094
+ } ) ;
4095
+
4096
+ it ( 'returns the expected block editing modes for synced patterns when switching to navigation mode' , ( ) => {
4097
+ select . mockImplementation ( ( storeName ) => {
4098
+ if ( storeName === preferencesStore ) {
4099
+ return {
4100
+ get : jest . fn ( ( ) => 'navigation' ) ,
4101
+ } ;
4102
+ }
4103
+ return select ( storeName ) ;
4104
+ } ) ;
4105
+
4106
+ const { derivedNavModeBlockEditingModes } = dispatchActions (
4107
+ [
4108
+ {
4109
+ type : 'SET_EDITOR_MODE' ,
4110
+ mode : 'navigation' ,
4111
+ } ,
4112
+ ] ,
4113
+ testReducer ,
4114
+ initialState
4115
+ ) ;
4116
+
4117
+ expect ( derivedNavModeBlockEditingModes ) . toEqual (
4118
+ new Map (
4119
+ Object . entries ( {
4120
+ '' : 'contentOnly' , // Section root.
4121
+ // Group 1 is now a section, so is set to contentOnly.
4122
+ 'group-1' : 'contentOnly' ,
4123
+ 'group-2' : 'disabled' ,
4124
+ 'paragraph-1' : 'contentOnly' ,
4125
+ 'paragraph-2' : 'contentOnly' ,
4126
+ } )
4127
+ )
4128
+ ) ;
4129
+
4130
+ select . mockImplementation ( ( storeName ) => {
4131
+ if ( storeName === preferencesStore ) {
4132
+ return {
4133
+ get : jest . fn ( ( ) => 'edit' ) ,
4134
+ } ;
4135
+ }
4136
+ return select ( storeName ) ;
4137
+ } ) ;
4138
+ } ) ;
4139
+
4140
+ it ( 'returns the expected block editing modes for synced patterns when switching to zoomed out mode' , ( ) => {
4141
+ const { derivedBlockEditingModes } = dispatchActions (
4142
+ [
4143
+ {
4144
+ type : 'SET_ZOOM_LEVEL' ,
4145
+ zoom : 'auto-scaled' ,
4146
+ } ,
4147
+ ] ,
4148
+ testReducer ,
4149
+ initialState
4150
+ ) ;
4151
+
4152
+ expect ( derivedBlockEditingModes ) . toEqual (
4153
+ new Map (
4154
+ Object . entries ( {
4155
+ '' : 'contentOnly' , // Section root.
4156
+ 'group-1' : 'contentOnly' , // Section.
4157
+ 'group-2' : 'disabled' ,
4158
+ 'paragraph-1' : 'disabled' ,
4159
+ 'paragraph-2' : 'disabled' ,
4160
+ } )
4161
+ )
4162
+ ) ;
4163
+ } ) ;
4164
+ } ) ;
4165
+
3960
4166
describe ( 'navigation mode' , ( ) => {
3961
4167
let initialState ;
3962
4168
0 commit comments