package moves import ( "crypto/rand" "regexp" "strings" "testing" "github.com/carlosframework/platform/internal/provision" ) func TestOpIDsAreShapedBySpec(t *testing.T) { // ยง3: mv_ or rb_ plus 26 lowercase base32 characters. shape := regexp.MustCompile(`^(mv|rb)_[a-z2-7]{26}$`) mv, err := NewMoveID(rand.Reader) if err != nil || !shape.MatchString(mv) { t.Fatalf("move id %q, err %v", mv, err) } rb, err := NewRollbackID(rand.Reader) if err != nil || !shape.MatchString(rb) { t.Fatalf("rollback id %q, err %v", rb, err) } if !ValidOpID(mv) || !ValidOpID(rb) || OpIDKind(mv) != "move" || OpIDKind(rb) != "rollback" { t.Fatal("valid ids refused or misclassified") } for _, bad := range []string{"", "mv_", "MV_abcdefghijklmnopqrstuvwxyz", "mv_abcdefghijklmnopqrstuvwxy1", "mv_abcdefghijklmnopqrstuvwxyz/", "xx_abcdefghijklmnopqrstuvwxyz"} { if ValidOpID(bad) || OpIDKind(bad) != "" { t.Fatalf("%q accepted", bad) } } if a, _ := NewMoveID(rand.Reader); a == mv { t.Fatal("two ids equal") } } func TestOpIDMintFailsOnShortRandomSource(t *testing.T) { if id, err := NewMoveID(strings.NewReader("short")); err == nil || id != "" { t.Fatalf("short reader gave %q, %v", id, err) } if id, err := NewRollbackID(strings.NewReader("")); err == nil || id != "" { t.Fatalf("empty reader gave %q, %v", id, err) } } // opIDShape and provision's two shapes are twins (moves imports provision, // so the copy is forced): every id minted here passes provision's check for // its kind and fails the other's, and ValidOpID agrees with the pair. func TestOpIDShapeTwinsProvision(t *testing.T) { for i := 0; i < 64; i++ { mv, err := NewMoveID(rand.Reader) if err != nil { t.Fatal(err) } rb, err := NewRollbackID(rand.Reader) if err != nil { t.Fatal(err) } if !provision.ValidMoveID(mv) || provision.ValidRollbackID(mv) || !provision.ValidRollbackID(rb) || provision.ValidMoveID(rb) { t.Fatalf("minted %q and %q disagree with provision", mv, rb) } } for _, id := range []string{"mv_abcdefghijklmnopqrstuvwxyz", "rb_abcdefghijklmnopqrstuvwxyz", "rb_short", "xx_abcdefghijklmnopqrstuvwxyz", "rb_ABCDEFGHIJKLMNOPQRSTUVWXYZ", ""} { if ValidOpID(id) != (provision.ValidMoveID(id) || provision.ValidRollbackID(id)) { t.Fatalf("ValidOpID(%q) disagrees with provision", id) } } }