@@ -10,7 +10,7 @@ import { describe, expect, it, vi } from 'vitest'
1010 */
1111vi . unmock ( '@/tools/registry' )
1212
13- import { GitHubBlock , GitHubV2Block } from '@/blocks/blocks/github'
13+ import { GITHUB_PARAM_ALIASES , GitHubBlock , GitHubV2Block } from '@/blocks/blocks/github'
1414import { getTool } from '@/tools/utils'
1515
1616function map ( params : Record < string , unknown > ) : Record < string , unknown > {
@@ -20,23 +20,66 @@ function map(params: Record<string, unknown>): Record<string, unknown> {
2020}
2121
2222/**
23- * Each pair is (block subBlock id, tool param name, tool id). The serializer
24- * keys values by subBlock id, so without the mapper the tool param stays
25- * undefined and the field is inert.
23+ * Derived from the alias table itself rather than mirrored by hand, so a new
24+ * alias cannot be added without these assertions covering it.
2625 */
27- const RENAMES = [
28- [ 'reaction_content' , 'content' , 'github_create_issue_reaction' ] ,
29- [ 'reaction_content' , 'content' , 'github_create_comment_reaction' ] ,
30- [ 'milestone_title' , 'title' , 'github_create_milestone' ] ,
31- [ 'milestone_title' , 'title' , 'github_update_milestone' ] ,
32- [ 'milestone_description' , 'description' , 'github_create_milestone' ] ,
33- [ 'milestone_description' , 'description' , 'github_update_milestone' ] ,
34- [ 'milestone_state' , 'state' , 'github_list_milestones' ] ,
35- [ 'milestone_sort' , 'sort' , 'github_list_milestones' ] ,
36- [ 'fork_name' , 'name' , 'github_fork_repo' ] ,
37- [ 'fork_sort' , 'sort' , 'github_list_forks' ] ,
38- [ 'gist_public' , 'public' , 'github_create_gist' ] ,
39- ] as const
26+ const RENAMES = GITHUB_PARAM_ALIASES . flatMap ( ( alias ) =>
27+ alias . operations . map ( ( operation ) => [ alias . from , alias . to , operation ] as const )
28+ )
29+
30+ describe ( 'the alias table is internally coherent' , ( ) => {
31+ /**
32+ * A floor, not a mirror: the derived assertions above scale to new aliases on
33+ * their own, but nothing would notice an alias being DELETED — the tests for
34+ * it would simply stop existing. These eight are the defects this suite was
35+ * written for, so their removal has to fail loudly.
36+ */
37+ it ( 'still covers every field this suite was written to fix' , ( ) => {
38+ expect ( GITHUB_PARAM_ALIASES . map ( ( a ) => a . from ) . sort ( ) ) . toEqual ( [
39+ 'fork_name' ,
40+ 'fork_sort' ,
41+ 'gist_public' ,
42+ 'milestone_description' ,
43+ 'milestone_sort' ,
44+ 'milestone_state' ,
45+ 'milestone_title' ,
46+ 'reaction_content' ,
47+ ] )
48+ } )
49+
50+ it ( 'covers every alias with at least one operation' , ( ) => {
51+ expect ( GITHUB_PARAM_ALIASES . length ) . toBeGreaterThan ( 0 )
52+ for ( const alias of GITHUB_PARAM_ALIASES ) {
53+ expect ( alias . operations . length , `${ alias . from } is scoped to no operation` ) . toBeGreaterThan ( 0 )
54+ }
55+ } )
56+
57+ /** A typo'd operation id would silently disable the alias — the exact class of bug this PR fixes. */
58+ it . each ( GITHUB_PARAM_ALIASES . flatMap ( ( a ) => a . operations . map ( ( op ) => [ a . from , op ] as const ) ) ) (
59+ '%s is scoped to %s, which the block can actually select' ,
60+ ( _from , operation ) => {
61+ expect ( GitHubBlock . tools . access ) . toContain ( operation )
62+ }
63+ )
64+
65+ /** An alias pointing at an operation where its field never renders can never fire. */
66+ it . each ( GITHUB_PARAM_ALIASES . map ( ( a ) => [ a . from , a ] as const ) ) (
67+ '%s renders on every operation it is scoped to' ,
68+ ( from , alias ) => {
69+ const rendered = new Set < string > ( )
70+ for ( const sub of GitHubBlock . subBlocks . filter ( ( s ) => s . id === from ) ) {
71+ const value = ( sub . condition as { value ?: unknown } ) ?. value
72+ for ( const op of Array . isArray ( value ) ? ( value as string [ ] ) : [ value as string ] ) {
73+ rendered . add ( op )
74+ }
75+ }
76+ expect ( rendered . size , `${ from } has no subBlock` ) . toBeGreaterThan ( 0 )
77+ for ( const op of alias . operations ) {
78+ expect ( [ ...rendered ] ) . toContain ( op )
79+ }
80+ }
81+ )
82+ } )
4083
4184describe ( 'every renamed subBlock reaches its tool param' , ( ) => {
4285 it . each ( RENAMES ) ( '%s -> %s' , ( subBlockId , paramName , toolId ) => {
0 commit comments