@@ -461,3 +461,159 @@ func TestMany2ManyDuplicateBelongsToAssociation(t *testing.T) {
461
461
tests .AssertEqual (t , nil , err )
462
462
tests .AssertEqual (t , user2 , findUser2 )
463
463
}
464
+
465
+ func TestMany2ManyEmptyAssociations (t * testing.T ) {
466
+ user := User {Name : "TestEmptyAssociations" }
467
+
468
+ // Create user with no associations
469
+ if err := DB .Create (& user ).Error ; err != nil {
470
+ t .Fatalf ("errors happened when create user: %v" , err )
471
+ }
472
+
473
+ var languages []Language
474
+ if err := DB .Model (& user ).Association ("Languages" ).Find (& languages ); err != nil {
475
+ t .Errorf ("Error finding empty associations: %v" , err )
476
+ }
477
+
478
+ if len (languages ) != 0 {
479
+ t .Errorf ("Expected 0 languages, got %d" , len (languages ))
480
+ }
481
+
482
+ count := DB .Model (& user ).Association ("Languages" ).Count ()
483
+ if count != 0 {
484
+ t .Errorf ("Expected count 0 for empty association, got %d" , count )
485
+ }
486
+
487
+ if err := DB .Model (& user ).Association ("Languages" ).Clear (); err != nil {
488
+ t .Errorf ("Error clearing empty association: %v" , err )
489
+ }
490
+
491
+ if err := DB .Model (& user ).Association ("Languages" ).Delete (& Language {}); err != nil {
492
+ t .Errorf ("Error deleting from empty association: %v" , err )
493
+ }
494
+ }
495
+
496
+ func TestMany2ManyAssociationCountValidation (t * testing.T ) {
497
+ user := * GetUser ("count-validation" , Config {Languages : 3 })
498
+
499
+ if err := DB .Create (& user ).Error ; err != nil {
500
+ t .Fatalf ("errors happened when create: %v" , err )
501
+ }
502
+
503
+ // Initial count check
504
+ initialCount := DB .Model (& user ).Association ("Languages" ).Count ()
505
+ if initialCount != 3 {
506
+ t .Fatalf ("Expected initial count 3, got %d" , initialCount )
507
+ }
508
+
509
+ newLanguages := []Language {
510
+ {Code : "count-test-1" , Name : "Count Test 1" },
511
+ {Code : "count-test-2" , Name : "Count Test 2" },
512
+ }
513
+ DB .Create (& newLanguages )
514
+
515
+ if err := DB .Model (& user ).Association ("Languages" ).Append (& newLanguages ); err != nil {
516
+ t .Fatalf ("Error appending languages: %v" , err )
517
+ }
518
+
519
+ // Check count after append
520
+ countAfterAppend := DB .Model (& user ).Association ("Languages" ).Count ()
521
+ if countAfterAppend != 5 {
522
+ t .Errorf ("Expected count 5 after append, got %d" , countAfterAppend )
523
+ }
524
+
525
+ replaceLanguage := Language {Code : "count-replace" , Name : "Count Replace" }
526
+ DB .Create (& replaceLanguage )
527
+
528
+ if err := DB .Model (& user ).Association ("Languages" ).Replace (& replaceLanguage ); err != nil {
529
+ t .Fatalf ("Error replacing languages: %v" , err )
530
+ }
531
+
532
+ // Check count after replace
533
+ countAfterReplace := DB .Model (& user ).Association ("Languages" ).Count ()
534
+ if countAfterReplace != 1 {
535
+ t .Errorf ("Expected count 1 after replace, got %d" , countAfterReplace )
536
+ }
537
+
538
+ // Verify actual data matches count
539
+ var actualLanguages []Language
540
+ DB .Model (& user ).Association ("Languages" ).Find (& actualLanguages )
541
+ if len (actualLanguages ) != int (countAfterReplace ) {
542
+ t .Errorf ("Count mismatch: Count() returned %d but Find() returned %d languages" ,
543
+ countAfterReplace , len (actualLanguages ))
544
+ }
545
+ }
546
+
547
+ func TestMany2ManyConstraintViolations (t * testing.T ) {
548
+ user := * GetUser ("constraint-test" , Config {Languages : 1 })
549
+
550
+ if err := DB .Create (& user ).Error ; err != nil {
551
+ t .Fatalf ("errors happened when create: %v" , err )
552
+ }
553
+
554
+ existingLanguage := user .Languages [0 ]
555
+
556
+ // append the same language again
557
+ if err := DB .Model (& user ).Association ("Languages" ).Append (& existingLanguage ); err != nil {
558
+ t .Logf ("Appending duplicate language resulted in: %v" , err )
559
+ }
560
+
561
+ // Verify count is still correct
562
+ count := DB .Model (& user ).Association ("Languages" ).Count ()
563
+ if count > 1 {
564
+ t .Errorf ("Expected count 1 after duplicate append, got %d" , count )
565
+ }
566
+
567
+ tempLanguage := Language {Code : "temp-invalid" , Name : "Temp Invalid" }
568
+ if err := DB .Create (& tempLanguage ).Error ; err != nil {
569
+ t .Logf ("Could not create temp language for FK test: %v" , err )
570
+ return
571
+ }
572
+
573
+ // append, then delete the language record to create inconsistency
574
+ if err := DB .Model (& user ).Association ("Languages" ).Append (& tempLanguage ); err != nil {
575
+ t .Logf ("Could not append temp language: %v" , err )
576
+ }
577
+
578
+ // Delete the language record directly
579
+ DB .Unscoped ().Delete (& tempLanguage )
580
+
581
+ // access associations after deleting referenced record
582
+ var languages []Language
583
+ if err := DB .Model (& user ).Association ("Languages" ).Find (& languages ); err != nil {
584
+ t .Logf ("Finding associations after FK deletion resulted in: %v" , err )
585
+ }
586
+
587
+ var manyLanguages []Language
588
+ for i := 0 ; i < 10 ; i ++ {
589
+ manyLanguages = append (manyLanguages , Language {
590
+ Code : fmt .Sprintf ("mass-test-%d" , i ),
591
+ Name : fmt .Sprintf ("Mass Test %d" , i ),
592
+ })
593
+ }
594
+
595
+ // Create the languages first
596
+ if err := DB .Create (& manyLanguages ).Error ; err != nil {
597
+ t .Logf ("Creating many languages failed: %v" , err )
598
+ return
599
+ }
600
+
601
+ // append all at once
602
+ if err := DB .Model (& user ).Association ("Languages" ).Append (& manyLanguages ); err != nil {
603
+ t .Logf ("Mass append operation resulted in: %v" , err )
604
+ }
605
+
606
+ // Verify the operation completed
607
+ finalCount := DB .Model (& user ).Association ("Languages" ).Count ()
608
+ t .Logf ("Final language count after mass operation: %d" , finalCount )
609
+
610
+ if err := DB .Model (& user ).Association ("Languages" ).Clear (); err != nil {
611
+ t .Errorf ("Error clearing associations after mass operation: %v" , err )
612
+ }
613
+
614
+ // Verify clear worked
615
+ countAfterClear := DB .Model (& user ).Association ("Languages" ).Count ()
616
+ if countAfterClear != 0 {
617
+ t .Errorf ("Expected count 0 after clear, got %d" , countAfterClear )
618
+ }
619
+ }
0 commit comments