@@ -408,3 +408,88 @@ func TestDisplayVersions(t *testing.T) {
408408 t .Errorf ("expected projects with different name to be filtered out; got: %s" , out )
409409 }
410410}
411+
412+ func TestValidateVersionExists_Found (t * testing.T ) {
413+ app , _ , _ := newTestApp (t , func (w http.ResponseWriter , r * http.Request ) {})
414+ projects := []Project {
415+ {Name : "test-project" , Version : "v0.9.0" },
416+ {Name : "test-project" , Version : "v1.0.0" },
417+ }
418+ if err := app .validateVersionExists (projects , "v1.0.0" ); err != nil {
419+ t .Fatalf ("expected nil error, got %v" , err )
420+ }
421+ }
422+
423+ func TestValidateVersionExists_NotFound (t * testing.T ) {
424+ app , _ , _ := newTestApp (t , func (w http.ResponseWriter , r * http.Request ) {})
425+ projects := []Project {
426+ {Name : "test-project" , Version : "v1.5.7" },
427+ {Name : "test-project" , Version : "v1.5.8" },
428+ }
429+ err := app .validateVersionExists (projects , "1.5.8" )
430+ if err == nil {
431+ t .Fatal ("expected error for missing version" )
432+ }
433+ msg := err .Error ()
434+ if ! strings .Contains (msg , `"1.5.8"` ) {
435+ t .Errorf ("expected requested version %q in error, got: %s" , "1.5.8" , msg )
436+ }
437+ if ! strings .Contains (msg , "not found" ) {
438+ t .Errorf ("expected 'not found' in error, got: %s" , msg )
439+ }
440+ if ! strings .Contains (msg , "v1.5.8" ) {
441+ t .Errorf ("expected available version 'v1.5.8' in error to make typo obvious, got: %s" , msg )
442+ }
443+ }
444+
445+ func TestValidateVersionExists_IgnoresOtherProjects (t * testing.T ) {
446+ app , _ , _ := newTestApp (t , func (w http.ResponseWriter , r * http.Request ) {})
447+ projects := []Project {
448+ {Name : "other-project" , Version : "v1.0.0" },
449+ }
450+ err := app .validateVersionExists (projects , "v1.0.0" )
451+ if err == nil {
452+ t .Fatal ("expected error: matching version under a different project name should not satisfy validation" )
453+ }
454+ if ! strings .Contains (err .Error (), "test-project" ) {
455+ t .Errorf ("expected configured project name in error, got: %s" , err .Error ())
456+ }
457+ }
458+
459+ func TestUpdateLifecycle_VersionNotInList (t * testing.T ) {
460+ projects := []Project {
461+ {UUID : "u-1" , Name : "test-project" , Version : "v1.5.7" , Active : true , IsLatest : false },
462+ {UUID : "u-2" , Name : "test-project" , Version : "v1.5.8" , Active : true , IsLatest : true },
463+ }
464+
465+ {
466+ app , _ , _ := newTestApp (t , func (w http.ResponseWriter , r * http.Request ) {
467+ t .Fatalf ("validation phase must not send any HTTP requests; got %s %s" , r .Method , r .URL .Path )
468+ })
469+ app .Config .Version = "1.5.8"
470+ if err := app .validateVersionExists (projects , app .Config .Version ); err == nil {
471+ t .Fatal ("expected validateVersionExists to reject typo'd version" )
472+ }
473+ }
474+
475+ handler , records , mu := newPatchRecorder ()
476+ app , _ , _ := newTestApp (t , handler )
477+ app .Config .Version = "1.5.8"
478+
479+ app .updateLifecycle (projects , true , true )
480+
481+ mu .Lock ()
482+ defer mu .Unlock ()
483+ if len (* records ) != 2 {
484+ t .Fatalf ("expected 2 destructive PATCHes (one per project) when validation is bypassed; got %d: %+v" ,
485+ len (* records ), * records )
486+ }
487+ for _ , r := range * records {
488+ if r .payload ["active" ] != false {
489+ t .Errorf ("expected active=false in destructive PATCH for %s, got %+v" , r .uuid , r .payload )
490+ }
491+ if r .payload ["isLatest" ] != false && r .uuid == "u-2" {
492+ t .Errorf ("expected isLatest=false in destructive PATCH for %s, got %+v" , r .uuid , r .payload )
493+ }
494+ }
495+ }
0 commit comments