@@ -379,6 +379,186 @@ describe("wrangler", () => {
379379 expect ( requests . count ) . toEqual ( 1 ) ;
380380 } ) ;
381381 } ) ;
382+
383+ describe ( "rename" , ( ) => {
384+ function mockUpdateRequest (
385+ expectedNamespaceId : string ,
386+ expectedTitle : string
387+ ) {
388+ const requests = { count : 0 } ;
389+ msw . use (
390+ http . put (
391+ "*/accounts/:accountId/storage/kv/namespaces/:namespaceId" ,
392+ async ( { request, params } ) => {
393+ requests . count ++ ;
394+ expect ( params . accountId ) . toEqual ( "some-account-id" ) ;
395+ expect ( params . namespaceId ) . toEqual ( expectedNamespaceId ) ;
396+ const body = ( await request . json ( ) ) as Record < string , string > ;
397+ expect ( body . title ) . toEqual ( expectedTitle ) ;
398+ return HttpResponse . json (
399+ createFetchResult ( {
400+ id : expectedNamespaceId ,
401+ title : expectedTitle ,
402+ } ) ,
403+ { status : 200 }
404+ ) ;
405+ } ,
406+ { once : true }
407+ )
408+ ) ;
409+ return requests ;
410+ }
411+
412+ function mockListRequestForRename ( namespaces : KVNamespaceInfo [ ] ) {
413+ const requests = { count : 0 } ;
414+ msw . use (
415+ http . get (
416+ "*/accounts/:accountId/storage/kv/namespaces" ,
417+ async ( { request, params } ) => {
418+ const url = new URL ( request . url ) ;
419+ requests . count ++ ;
420+ expect ( params . accountId ) . toEqual ( "some-account-id" ) ;
421+ expect ( url . searchParams . get ( "per_page" ) ) . toEqual ( "100" ) ;
422+ expect ( url . searchParams . get ( "order" ) ) . toEqual ( "title" ) ;
423+ expect ( url . searchParams . get ( "direction" ) ) . toEqual ( "asc" ) ;
424+ expect ( url . searchParams . get ( "page" ) ) . toEqual ( `${ requests . count } ` ) ;
425+
426+ const pageSize = Number ( url . searchParams . get ( "per_page" ) ) ;
427+ const page = Number ( url . searchParams . get ( "page" ) ) ;
428+ return HttpResponse . json (
429+ createFetchResult (
430+ namespaces . slice ( ( page - 1 ) * pageSize , page * pageSize )
431+ )
432+ ) ;
433+ }
434+ )
435+ ) ;
436+ return requests ;
437+ }
438+
439+ it ( "should display help for rename command" , async ( ) => {
440+ await expect (
441+ runWrangler ( "kv namespace rename --help" )
442+ ) . resolves . toBeUndefined ( ) ;
443+
444+ expect ( std . out ) . toMatchInlineSnapshot ( `
445+ "wrangler kv namespace rename [old-name]
446+
447+ Rename a KV namespace
448+
449+ POSITIONALS
450+ old-name The current name (title) of the namespace to rename [string]
451+
452+ GLOBAL FLAGS
453+ -c, --config Path to Wrangler configuration file [string]
454+ --cwd Run as if Wrangler was started in the specified directory instead of the current working directory [string]
455+ -e, --env Environment to use for operations, and for selecting .env and .dev.vars files [string]
456+ -h, --help Show help [boolean]
457+ -v, --version Show version number [boolean]
458+
459+ OPTIONS
460+ --namespace-id The id of the namespace to rename [string]
461+ --new-name The new name for the namespace [string] [required]"
462+ ` ) ;
463+ } ) ;
464+
465+ it ( "should error if neither name nor namespace-id is provided" , async ( ) => {
466+ await expect (
467+ runWrangler ( "kv namespace rename --new-name new-name" )
468+ ) . rejects . toThrowErrorMatchingInlineSnapshot (
469+ `[Error: Either old-name (as first argument) or --namespace-id must be specified]`
470+ ) ;
471+ } ) ;
472+
473+ it ( "should error if new-name is not provided" , async ( ) => {
474+ await expect (
475+ runWrangler ( "kv namespace rename" )
476+ ) . rejects . toThrowErrorMatchingInlineSnapshot (
477+ `[Error: Missing required argument: new-name]`
478+ ) ;
479+ } ) ;
480+
481+ it ( "should rename namespace by ID" , async ( ) => {
482+ const requests = mockUpdateRequest (
483+ "some-namespace-id" ,
484+ "new-namespace-name"
485+ ) ;
486+ await runWrangler (
487+ "kv namespace rename --namespace-id some-namespace-id --new-name new-namespace-name"
488+ ) ;
489+ expect ( requests . count ) . toEqual ( 1 ) ;
490+ expect ( std . out ) . toMatchInlineSnapshot ( `
491+ "Resource location: remote
492+ Renaming KV namespace some-namespace-id to \\"new-namespace-name\\".
493+ ✨ Successfully renamed namespace to \\"new-namespace-name\\""
494+ ` ) ;
495+ } ) ;
496+
497+ it ( "should rename namespace by old name" , async ( ) => {
498+ const listRequests = mockListRequestForRename ( [
499+ { id : "some-namespace-id" , title : "old-namespace-name" } ,
500+ { id : "other-namespace-id" , title : "other-namespace" } ,
501+ ] ) ;
502+ const updateRequests = mockUpdateRequest (
503+ "some-namespace-id" ,
504+ "new-namespace-name"
505+ ) ;
506+
507+ await runWrangler (
508+ "kv namespace rename old-namespace-name --new-name new-namespace-name"
509+ ) ;
510+
511+ expect ( listRequests . count ) . toEqual ( 1 ) ;
512+ expect ( updateRequests . count ) . toEqual ( 1 ) ;
513+ expect ( std . out ) . toMatchInlineSnapshot ( `
514+ "Resource location: remote
515+ Renaming KV namespace some-namespace-id to \\"new-namespace-name\\".
516+ ✨ Successfully renamed namespace to \\"new-namespace-name\\""
517+ ` ) ;
518+ } ) ;
519+
520+ it ( "should error if namespace with old name is not found" , async ( ) => {
521+ mockListRequestForRename ( [
522+ { id : "other-namespace-id" , title : "other-namespace" } ,
523+ ] ) ;
524+
525+ await expect (
526+ runWrangler (
527+ "kv namespace rename nonexistent-name --new-name new-name"
528+ )
529+ ) . rejects . toThrowErrorMatchingInlineSnapshot (
530+ `[Error: No namespace found with the name "nonexistent-name". Use --namespace-id instead or check available namespaces with "wrangler kv namespace list".]`
531+ ) ;
532+ } ) ;
533+
534+ it ( "should error if namespace ID does not exist" , async ( ) => {
535+ // Mock a 404 response for the namespace ID
536+ msw . use (
537+ http . put (
538+ "*/accounts/:accountId/storage/kv/namespaces/:namespaceId" ,
539+ ( { params } ) => {
540+ expect ( params . accountId ) . toEqual ( "some-account-id" ) ;
541+ expect ( params . namespaceId ) . toEqual ( "nonexistent-id" ) ;
542+ return HttpResponse . json (
543+ createFetchResult ( null , false , [
544+ { code : 10009 , message : "Unknown namespace." } ,
545+ ] ) ,
546+ { status : 404 }
547+ ) ;
548+ } ,
549+ { once : true }
550+ )
551+ ) ;
552+
553+ await expect (
554+ runWrangler (
555+ "kv namespace rename --namespace-id nonexistent-id --new-name new-name"
556+ )
557+ ) . rejects . toThrowErrorMatchingInlineSnapshot (
558+ `[APIError: A request to the Cloudflare API (/accounts/some-account-id/storage/kv/namespaces/nonexistent-id) failed.]`
559+ ) ;
560+ } ) ;
561+ } ) ;
382562 } ) ;
383563
384564 describe ( "kv key" , ( ) => {
0 commit comments