@@ -21,6 +21,7 @@ type FakeProjectsService struct {
2121 ListFunc func (ctx context.Context , query kernel.ProjectListParams , opts ... option.RequestOption ) (* pagination.OffsetPagination [kernel.Project ], error )
2222 NewFunc func (ctx context.Context , body kernel.ProjectNewParams , opts ... option.RequestOption ) (* kernel.Project , error )
2323 GetFunc func (ctx context.Context , id string , opts ... option.RequestOption ) (* kernel.Project , error )
24+ UpdateFunc func (ctx context.Context , id string , body kernel.ProjectUpdateParams , opts ... option.RequestOption ) (* kernel.Project , error )
2425 DeleteFunc func (ctx context.Context , id string , opts ... option.RequestOption ) error
2526}
2627
@@ -45,6 +46,13 @@ func (f *FakeProjectsService) Get(ctx context.Context, id string, opts ...option
4546 return & kernel.Project {ID : id , Name : "default" }, nil
4647}
4748
49+ func (f * FakeProjectsService ) Update (ctx context.Context , id string , body kernel.ProjectUpdateParams , opts ... option.RequestOption ) (* kernel.Project , error ) {
50+ if f .UpdateFunc != nil {
51+ return f .UpdateFunc (ctx , id , body , opts ... )
52+ }
53+ return & kernel.Project {ID : id , Name : body .UpdateProjectRequest .Name .Value }, nil
54+ }
55+
4856func (f * FakeProjectsService ) Delete (ctx context.Context , id string , opts ... option.RequestOption ) error {
4957 if f .DeleteFunc != nil {
5058 return f .DeleteFunc (ctx , id , opts ... )
@@ -146,6 +154,121 @@ func TestProjectsGet_InvalidOutput(t *testing.T) {
146154 assert .Contains (t , err .Error (), "unsupported --output value" )
147155}
148156
157+ func TestProjectsUpdate_Success (t * testing.T ) {
158+ buf := capturePtermOutput (t )
159+ c := ProjectsCmd {
160+ projects : & FakeProjectsService {
161+ UpdateFunc : func (ctx context.Context , id string , body kernel.ProjectUpdateParams , opts ... option.RequestOption ) (* kernel.Project , error ) {
162+ assert .Equal (t , "a12345678901234567890123" , id )
163+ assert .True (t , body .UpdateProjectRequest .Name .Valid ())
164+ assert .Equal (t , "Renamed" , body .UpdateProjectRequest .Name .Value )
165+ return & kernel.Project {ID : id , Name : body .UpdateProjectRequest .Name .Value }, nil
166+ },
167+ },
168+ limits : & FakeProjectLimitsService {},
169+ }
170+
171+ err := c .Update (context .Background (), ProjectsUpdateInput {
172+ Identifier : "a12345678901234567890123" ,
173+ Name : "Renamed" ,
174+ })
175+
176+ require .NoError (t , err )
177+ out := buf .String ()
178+ assert .Contains (t , out , "Updated project: Renamed" )
179+ assert .Contains (t , out , "a12345678901234567890123" )
180+ }
181+
182+ func TestProjectsUpdate_JSONOutput (t * testing.T ) {
183+ project := mustProject (t , `{"id":"a12345678901234567890123","name":"Renamed","status":"active","created_at":"2026-05-29T12:00:00Z","updated_at":"2026-05-29T12:30:00Z"}` )
184+ c := ProjectsCmd {
185+ projects : & FakeProjectsService {
186+ UpdateFunc : func (ctx context.Context , id string , body kernel.ProjectUpdateParams , opts ... option.RequestOption ) (* kernel.Project , error ) {
187+ assert .Equal (t , "a12345678901234567890123" , id )
188+ assert .True (t , body .UpdateProjectRequest .Name .Valid ())
189+ assert .Equal (t , "Renamed" , body .UpdateProjectRequest .Name .Value )
190+ return & project , nil
191+ },
192+ },
193+ limits : & FakeProjectLimitsService {},
194+ }
195+
196+ var err error
197+ out := captureStdout (t , func () {
198+ err = c .Update (context .Background (), ProjectsUpdateInput {
199+ Identifier : "a12345678901234567890123" ,
200+ Name : "Renamed" ,
201+ Output : "json" ,
202+ })
203+ })
204+
205+ require .NoError (t , err )
206+ assert .JSONEq (t , `{"id":"a12345678901234567890123","name":"Renamed","status":"active","created_at":"2026-05-29T12:00:00Z","updated_at":"2026-05-29T12:30:00Z"}` , out )
207+ }
208+
209+ func TestProjectsUpdate_ResolvesName (t * testing.T ) {
210+ c := ProjectsCmd {
211+ projects : & FakeProjectsService {
212+ ListFunc : func (ctx context.Context , query kernel.ProjectListParams , opts ... option.RequestOption ) (* pagination.OffsetPagination [kernel.Project ], error ) {
213+ return & pagination.OffsetPagination [kernel.Project ]{
214+ Items : []kernel.Project {{ID : "a12345678901234567890123" , Name : "Default" }},
215+ }, nil
216+ },
217+ UpdateFunc : func (ctx context.Context , id string , body kernel.ProjectUpdateParams , opts ... option.RequestOption ) (* kernel.Project , error ) {
218+ assert .Equal (t , "a12345678901234567890123" , id )
219+ return & kernel.Project {ID : id , Name : body .UpdateProjectRequest .Name .Value }, nil
220+ },
221+ },
222+ limits : & FakeProjectLimitsService {},
223+ }
224+
225+ err := c .Update (context .Background (), ProjectsUpdateInput {
226+ Identifier : "default" ,
227+ Name : "Renamed" ,
228+ })
229+
230+ require .NoError (t , err )
231+ }
232+
233+ func TestProjectsUpdate_RequiresName (t * testing.T ) {
234+ c := ProjectsCmd {
235+ projects : & FakeProjectsService {
236+ UpdateFunc : func (ctx context.Context , id string , body kernel.ProjectUpdateParams , opts ... option.RequestOption ) (* kernel.Project , error ) {
237+ t .Fatal ("Update should not be called" )
238+ return nil , nil
239+ },
240+ },
241+ limits : & FakeProjectLimitsService {},
242+ }
243+
244+ err := c .Update (context .Background (), ProjectsUpdateInput {Identifier : "a12345678901234567890123" })
245+
246+ require .Error (t , err )
247+ assert .Contains (t , err .Error (), "--name is required" )
248+ assert .Contains (t , err .Error (), "add --name <name>" )
249+ }
250+
251+ func TestProjectsUpdate_InvalidOutput (t * testing.T ) {
252+ c := ProjectsCmd {
253+ projects : & FakeProjectsService {
254+ UpdateFunc : func (ctx context.Context , id string , body kernel.ProjectUpdateParams , opts ... option.RequestOption ) (* kernel.Project , error ) {
255+ t .Fatal ("Update should not be called" )
256+ return nil , nil
257+ },
258+ },
259+ limits : & FakeProjectLimitsService {},
260+ }
261+
262+ err := c .Update (context .Background (), ProjectsUpdateInput {
263+ Identifier : "a12345678901234567890123" ,
264+ Name : "Renamed" ,
265+ Output : "yaml" ,
266+ })
267+
268+ require .Error (t , err )
269+ assert .Contains (t , err .Error (), "unsupported --output value" )
270+ }
271+
149272func TestProjectsLimitsGet_DefaultOutput (t * testing.T ) {
150273 buf := capturePtermOutput (t )
151274 limits := & kernel.ProjectLimits {
0 commit comments