package factories import ( "fmt" "os" "strings" "sync/atomic" "time" "github.com/icrowley/fake" "rocketgit.ru/rsmon/worker/app/models" "rocketgit.ru/rsmon/worker/app/models/authidentity" ) var userCounter uint64 // processPrefix is unique per OS process so that parallel test binaries // (e.g. notifier and sender running at the same time with go test ./...) // do not generate duplicate email addresses when given the same base email. var processPrefix = fmt.Sprintf("%d%d", os.Getpid(), time.Now().UnixNano()%1000000) // UserFactory creates a new User with a random email. func UserFactory() models.User { email := fake.EmailAddress() user := models.User{ Email: &email, } return user } // AuthIdentity creates an AuthIdentity for the given user. func AuthIdentity(user *models.User, _ string) authidentity.AuthIdentity { t := time.Now() ai := authidentity.AuthIdentity{ Basic: authidentity.Basic{ UserID: &user.ID, Provider: "password", UID: *user.Email, ConfirmedAt: &t, }, } return ai } // PersistedUser creates and persists a user with the given email and password. func PersistedUser(email, password string) models.User { user := UserFactory() if email == "" { email = fake.EmailAddress() } else { id := atomic.AddUint64(&userCounter, 1) atIdx := len(email) - len(email[strings.Index(email, "@"):]) //nolint:gocritic // offBy1: strings.Index is always valid for emails // Embed both the process prefix and counter so emails are unique across // parallel test binaries AND across sequential calls within a binary. email = email[:atIdx] + "+" + processPrefix + fmt.Sprintf("%d", id) + email[atIdx:] } user.Email = &email err := models.DB().Save(&user).Error if err != nil { panic(err) } ai := AuthIdentity(&user, password) err = models.DB().Save(&ai).Error if err != nil { panic(err) } return user }