11import { describe , it , expect } from 'vitest' ;
22import { MANAGED_BY_BUCKETS } from '@object-ui/types' ;
33import {
4- resolveCrudAffordances ,
4+ resolveEffectiveCrudAffordances ,
55 isWriteOptedIn ,
66 isSystemWritable ,
77 isObjectInlineEditable ,
88 normalizeUserAction ,
99 userActionPredicates ,
1010} from './managedBy' ;
1111
12- describe ( 'resolveCrudAffordances (shared source of truth) ' , ( ) => {
12+ describe ( 'resolveEffectiveCrudAffordances — bucket half, delegated to the spec ' , ( ) => {
1313 it ( 'defaults to the platform bucket (full CRUD) when managedBy is unset' , ( ) => {
14- expect ( resolveCrudAffordances ( { } ) ) . toEqual ( {
14+ expect ( resolveEffectiveCrudAffordances ( { } ) ) . toEqual ( {
1515 create : true , import : true , edit : true , delete : true , exportCsv : true ,
1616 } ) ;
17- expect ( resolveCrudAffordances ( null ) ) . toEqual ( resolveCrudAffordances ( { managedBy : 'platform' } ) ) ;
17+ expect ( resolveEffectiveCrudAffordances ( null ) ) . toEqual ( resolveEffectiveCrudAffordances ( { managedBy : 'platform' } ) ) ;
1818 } ) ;
1919
2020 it ( 'config: New/Edit/Delete + export, no import' , ( ) => {
21- expect ( resolveCrudAffordances ( { managedBy : 'config' } ) ) . toEqual ( {
21+ expect ( resolveEffectiveCrudAffordances ( { managedBy : 'config' } ) ) . toEqual ( {
2222 create : true , import : false , edit : true , delete : true , exportCsv : true ,
2323 } ) ;
2424 } ) ;
2525
2626 it ( 'system / engine-owned / append-only / better-auth: export-only by default' , ( ) => {
2727 for ( const managedBy of [ 'system' , 'engine-owned' , 'append-only' , 'better-auth' ] ) {
28- expect ( resolveCrudAffordances ( { managedBy } ) ) . toEqual ( {
28+ expect ( resolveEffectiveCrudAffordances ( { managedBy } ) ) . toEqual ( {
2929 create : false , import : false , edit : false , delete : false , exportCsv : true ,
3030 } ) ;
3131 }
3232 } ) ;
3333
3434 it ( 'userActions overrides the bucket default (ADR-0103 writable system)' , ( ) => {
35- const aff = resolveCrudAffordances ( { managedBy : 'system' , userActions : { create : true , edit : true , delete : true } } ) ;
35+ const aff = resolveEffectiveCrudAffordances ( { managedBy : 'system' , userActions : { create : true , edit : true , delete : true } } ) ;
3636 expect ( aff ) . toMatchObject ( { create : true , edit : true , delete : true , import : false } ) ;
3737 } ) ;
3838
3939 it ( 'unknown bucket falls back to platform (defensive)' , ( ) => {
40- expect ( resolveCrudAffordances ( { managedBy : 'totally-unknown' } ) . edit ) . toBe ( true ) ;
40+ expect ( resolveEffectiveCrudAffordances ( { managedBy : 'totally-unknown' } ) . edit ) . toBe ( true ) ;
4141 } ) ;
4242
4343 it ( '#2614 object form: carries predicates, keys off enabled, boolean path unchanged' , ( ) => {
44- const withPreds = resolveCrudAffordances ( {
44+ const withPreds = resolveEffectiveCrudAffordances ( {
4545 managedBy : 'platform' ,
4646 userActions : { edit : { enabled : true , disabledWhen : 'record.locked == true' } } ,
4747 } ) ;
4848 expect ( withPreds . edit ) . toBe ( true ) ;
4949 expect ( withPreds . editPredicates ) . toEqual ( { disabledWhen : 'record.locked == true' } ) ;
5050 // enabled omitted → falls back to the bucket default (platform edit = true)
51- expect ( resolveCrudAffordances ( { managedBy : 'platform' , userActions : { edit : { disabledWhen : 'x' } } } ) . edit ) . toBe ( true ) ;
51+ expect ( resolveEffectiveCrudAffordances ( { managedBy : 'platform' , userActions : { edit : { disabledWhen : 'x' } } } ) . edit ) . toBe ( true ) ;
5252 // boolean form leaves predicates absent
53- expect ( resolveCrudAffordances ( { managedBy : 'system' , userActions : { edit : true } } ) . editPredicates ) . toBeUndefined ( ) ;
53+ expect ( resolveEffectiveCrudAffordances ( { managedBy : 'system' , userActions : { edit : true } } ) . editPredicates ) . toBeUndefined ( ) ;
5454 } ) ;
5555} ) ;
5656
@@ -144,26 +144,26 @@ describe('MANAGED_BY_BUCKETS', () => {
144144 } ) ;
145145} ) ;
146146
147- describe ( 'resolveCrudAffordances — effective API operations (#3391)' , ( ) => {
147+ describe ( 'resolveEffectiveCrudAffordances — effective API operations (#3391)' , ( ) => {
148148 it ( 'undefined effective set → affordances unchanged (backward-compatible)' , ( ) => {
149149 const platform = { managedBy : 'platform' } ;
150- expect ( resolveCrudAffordances ( platform ) ) . toEqual ( resolveCrudAffordances ( platform , undefined ) ) ;
151- expect ( resolveCrudAffordances ( platform , undefined ) ) . toEqual ( {
150+ expect ( resolveEffectiveCrudAffordances ( platform ) ) . toEqual ( resolveEffectiveCrudAffordances ( platform , undefined ) ) ;
151+ expect ( resolveEffectiveCrudAffordances ( platform , undefined ) ) . toEqual ( {
152152 create : true , import : true , edit : true , delete : true , exportCsv : true ,
153153 } ) ;
154154 } ) ;
155155
156156 it ( 'ANDs each affordance bit with its API operation (create/import→create/import, edit→update, delete→delete, exportCsv→export)' , ( ) => {
157157 // A full-CRUD platform object whose server effective set is read-only + list-derived.
158- const aff = resolveCrudAffordances ( { managedBy : 'platform' } , [ 'get' , 'list' , 'export' ] ) ;
158+ const aff = resolveEffectiveCrudAffordances ( { managedBy : 'platform' } , [ 'get' , 'list' , 'export' ] ) ;
159159 expect ( aff ) . toMatchObject ( {
160160 create : false , import : false , edit : false , delete : false , exportCsv : true ,
161161 } ) ;
162162 } ) ;
163163
164164 it ( 'keeps a bit only when BOTH the affordance and the effective op allow it' , ( ) => {
165165 // create+update present → create/import/edit survive; no delete/list → delete/export drop.
166- const aff = resolveCrudAffordances ( { managedBy : 'platform' } , [ 'create' , 'update' , 'import' ] ) ;
166+ const aff = resolveEffectiveCrudAffordances ( { managedBy : 'platform' } , [ 'create' , 'update' , 'import' ] ) ;
167167 expect ( aff . create ) . toBe ( true ) ;
168168 expect ( aff . edit ) . toBe ( true ) ;
169169 expect ( aff . import ) . toBe ( true ) ;
@@ -172,15 +172,15 @@ describe('resolveCrudAffordances — effective API operations (#3391)', () => {
172172 } ) ;
173173
174174 it ( 'empty effective set → all bits off (deny-all)' , ( ) => {
175- expect ( resolveCrudAffordances ( { managedBy : 'platform' } , [ ] ) ) . toMatchObject ( {
175+ expect ( resolveEffectiveCrudAffordances ( { managedBy : 'platform' } , [ ] ) ) . toMatchObject ( {
176176 create : false , import : false , edit : false , delete : false , exportCsv : false ,
177177 } ) ;
178178 } ) ;
179179
180180 it ( 'never re-enables a bit the bucket/userActions already denied' , ( ) => {
181181 // config bucket has no import; even if the server would allow import, the
182182 // UI-intent axis keeps it off (intersection, never union).
183- const aff = resolveCrudAffordances ( { managedBy : 'config' } , [ 'create' , 'update' , 'delete' , 'import' , 'export' ] ) ;
183+ const aff = resolveEffectiveCrudAffordances ( { managedBy : 'config' } , [ 'create' , 'update' , 'delete' , 'import' , 'export' ] ) ;
184184 expect ( aff . import ) . toBe ( false ) ; // config never imports
185185 expect ( aff . create ) . toBe ( true ) ;
186186 expect ( aff . exportCsv ) . toBe ( true ) ;
0 commit comments