// Copyright Earl Warren // Copyright Loïc Dachary // SPDX-License-Identifier: MIT package f3 import ( "context" "crypto/sha256" "fmt" "io" "strings" "time" "code.forgejo.org/f3/gof3/v3/f3" helpers_repository "code.forgejo.org/f3/gof3/v3/forges/helpers/repository" tests_repository "code.forgejo.org/f3/gof3/v3/forges/helpers/tests/repository" "code.forgejo.org/f3/gof3/v3/kind" "code.forgejo.org/f3/gof3/v3/logger" "code.forgejo.org/f3/gof3/v3/path" f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3" "code.forgejo.org/f3/gof3/v3/tree/generic" "github.com/stretchr/testify/require" ) var RootUser *f3.User = &f3.User{ UserName: "root", } type Creator struct { logger logger.Interface t TestingT d string name string serial int } func now() time.Time { return time.Now().Truncate(time.Second) } func tick(now *time.Time) time.Time { *now = now.Add(1 * time.Minute) return *now } func NewCreator(t TestingT, name string, logger logger.Interface) *Creator { return &Creator{ t: t, d: t.TempDir(), logger: logger, name: name, } } func (f *Creator) randomString(prefix string) string { f.serial++ return fmt.Sprintf("%s%s%015d", prefix, f.name, f.serial) } func (f *Creator) GetDirectory() string { return f.d } func (f *Creator) Generate(k kind.Kind, parent path.Path) f3.Interface { switch k { case f3_tree.KindForge: return f.GenerateForge() case f3_tree.KindUser: return f.GenerateUser() case f3_tree.KindOrganization: return f.GenerateOrganization() case f3_tree.KindProject: return f.GenerateProject() case f3_tree.KindIssue: return f.GenerateIssue(parent) case f3_tree.KindMilestone: return f.GenerateMilestone() case f3_tree.KindTopic: return f.GenerateTopic() case f3_tree.KindReaction: return f.GenerateReaction(parent) case f3_tree.KindLabel: return f.GenerateLabel() case f3_tree.KindComment: return f.GenerateComment(parent) case f3_tree.KindRepository: return f.GenerateRepository(f3.RepositoryNameDefault) case f3_tree.KindRelease: return f.GenerateRelease(parent) case f3_tree.KindAsset: return f.GenerateAsset(parent) case f3_tree.KindPullRequest: return f.GeneratePullRequest(parent) case f3_tree.KindReview: return f.GenerateReview(parent) case f3_tree.KindReviewComment: return f.GenerateReviewComment(parent) default: panic(fmt.Errorf("not implemented %s", k)) } } func (f *Creator) GenerateForge() *f3.Forge { return &f3.Forge{ Common: f3.NewCommon("forge"), } } func (f *Creator) GenerateUser() *f3.User { username := f.randomString("user") return &f3.User{ Name: username + " Doe", UserName: username, Email: username + "@example.com", Password: "Wrobyak4", } } func (f *Creator) GenerateOrganization() *f3.Organization { orgname := f.randomString("org") return &f3.Organization{ FullName: orgname + " Lambda", Name: orgname, } } func (f *Creator) GenerateProject() *f3.Project { projectname := f.randomString("project") return &f3.Project{ Name: projectname, IsPrivate: false, IsMirror: false, Description: "project description", DefaultBranch: "master", } } func (f *Creator) GenerateForkedProject(parent path.Path, forked string) *f3.Project { project := f.GenerateProject() project.Forked = f3.NewReference(forked) return project } func (f *Creator) GenerateRepository(name string) *f3.Repository { repository := &f3.Repository{ Name: name, } p := f.t.TempDir() helper := tests_repository.NewTestHelper(f.t, p, nil) helper.CreateRepositoryContent("").PushMirror() repository.FetchFunc = func(ctx context.Context, destination string, internalRefs []string) { f.logger.Debug("%s %s", p, destination) helpers_repository.GitMirror(context.Background(), nil, p, destination, internalRefs) } return repository } func (f *Creator) GenerateReaction(parent path.Path) *f3.Reaction { user := f3_tree.GetFirstFormat[*f3.User](parent.Last().(generic.NodeInterface)) return &f3.Reaction{ UserID: f3_tree.NewUserReference(user.GetID()), Content: "heart", } } func (f *Creator) GenerateMilestone() *f3.Milestone { now := now() created := tick(&now) updated := tick(&now) deadline := tick(&now) return &f3.Milestone{ Title: "milestone1", Description: "milestone1 description", Deadline: &deadline, Created: created, Updated: &updated, Closed: nil, State: f3.MilestoneStateOpen, } } func (f *Creator) GeneratePullRequest(parent path.Path) *f3.PullRequest { user := f3_tree.GetFirstFormat[*f3.User](parent.Last().(generic.NodeInterface)) projectNode := f3_tree.GetFirstNodeKind(parent.Last().(generic.NodeInterface), f3_tree.KindProject) repositoryNode := projectNode.Find(generic.NewPathFromString("repositories/vcs")) repositoryNode.Get(context.Background()) repositoryHelper := tests_repository.NewTestHelper(f.t, "", repositoryNode) mainRef := "master" mainSha := repositoryHelper.GetRepositorySha(mainRef) featureRef := "feature" repositoryHelper.InternalBranchRepositoryFeature(featureRef, "feature content") featureSha := repositoryHelper.GetRepositorySha(featureRef) f.logger.Debug("master %s at main %s feature %s", repositoryHelper.GetBare(), mainSha, featureSha) repositoryHelper.PushMirror() now := now() prCreated := tick(&now) prUpdated := tick(&now) return &f3.PullRequest{ PosterID: f3_tree.NewUserReference(user.GetID()), Title: "pr title", Content: "pr content", State: f3.PullRequestStateOpen, IsLocked: false, Created: prCreated, Updated: prUpdated, Closed: nil, Merged: false, MergedTime: nil, MergeCommitSHA: "", Head: f3.PullRequestBranch{ Ref: featureRef, SHA: featureSha, Repository: f3_tree.NewPullRequestSameRepositoryReference(), }, Base: f3.PullRequestBranch{ Ref: mainRef, SHA: mainSha, Repository: f3_tree.NewPullRequestSameRepositoryReference(), }, } } func (f *Creator) GenerateLabel() *f3.Label { name := f.randomString("label") return &f3.Label{ Name: name, Color: "ffffff", Description: name + " description", } } func (f *Creator) GenerateTopic() *f3.Topic { return &f3.Topic{ Name: "topic1", } } func (f *Creator) GenerateIssue(parent path.Path) *f3.Issue { user := f3_tree.GetFirstFormat[*f3.User](parent.Last().(generic.NodeInterface)) projectNode := f3_tree.GetFirstNodeKind(parent.Last().(generic.NodeInterface), f3_tree.KindProject) labelsNode := projectNode.Find(generic.NewPathFromString("labels")) require.NotEqualValues(f.t, generic.NilNode, labelsNode) labels := labelsNode.GetChildren() require.NotEmpty(f.t, labels) firstLabel := labels[0] milestonesNode := projectNode.Find(generic.NewPathFromString("milestones")) require.NotEqualValues(f.t, generic.NilNode, milestonesNode) milestones := milestonesNode.GetChildren() require.NotEmpty(f.t, milestones) firstMilestone := milestones[0] now := now() updated := tick(&now) closed := tick(&now) created := tick(&now) return &f3.Issue{ PosterID: f3_tree.NewUserReference(user.GetID()), Assignees: []*f3.Reference{f3_tree.NewUserReference(user.GetID())}, Labels: []*f3.Reference{f3_tree.NewIssueLabelReference(firstLabel.GetID())}, Milestone: f3_tree.NewIssueMilestoneReference(firstMilestone.GetID()), Title: "title", Content: "content", State: f3.IssueStateOpen, IsLocked: false, Created: created, Updated: updated, Closed: &closed, } } func (f *Creator) GenerateComment(parent path.Path) *f3.Comment { user := f3_tree.GetFirstFormat[*f3.User](parent.Last().(generic.NodeInterface)) now := now() commentCreated := tick(&now) commentUpdated := tick(&now) posterID := f3_tree.NewUserReference(user.GetID()) return &f3.Comment{ PosterID: posterID, Created: commentCreated, Updated: commentUpdated, Content: "comment content", } } func (f *Creator) GenerateRelease(parent path.Path) *f3.Release { user := f3_tree.GetFirstFormat[*f3.User](parent.Last().(generic.NodeInterface)) project := f3_tree.GetFirstNodeKind(parent.Last().(generic.NodeInterface), f3_tree.KindProject) repository := project.Find(generic.NewPathFromString("repositories/vcs")) repository.Get(context.Background()) repositoryHelper := tests_repository.NewTestHelper(f.t, "", repository) now := now() releaseCreated := tick(&now) tag := "releasetagv12" repositoryHelper.CreateRepositoryTag(tag, "master") sha := repositoryHelper.GetRepositorySha("master") repositoryHelper.PushMirror() return &f3.Release{ TagName: tag, TargetCommitish: sha, Name: "v12 name", Body: "v12 body", Draft: false, Prerelease: false, PublisherID: f3_tree.NewUserReference(user.GetID()), Created: releaseCreated, } } func (f *Creator) GenerateAsset(parent path.Path) *f3.ReleaseAsset { name := "assetname" content := "assetcontent" downloadURL := "downloadURL" now := now() assetCreated := tick(&now) size := len(content) downloadCount := int64(10) sha256 := fmt.Sprintf("%x", sha256.Sum256([]byte(content))) return &f3.ReleaseAsset{ Name: name, Size: int64(size), DownloadCount: downloadCount, Created: assetCreated, SHA256: sha256, DownloadURL: downloadURL, DownloadFunc: func() io.ReadCloser { rc := io.NopCloser(strings.NewReader(content)) return rc }, } } func (f *Creator) GenerateReview(parent path.Path) *f3.Review { user := f3_tree.GetFirstFormat[*f3.User](parent.Last().(generic.NodeInterface)) projectNode := f3_tree.GetFirstNodeKind(parent.Last().(generic.NodeInterface), f3_tree.KindProject) repositoryNode := projectNode.Find(generic.NewPathFromString("repositories/vcs")) repositoryNode.Get(context.Background()) repositoryHelper := tests_repository.NewTestHelper(f.t, "", repositoryNode) now := now() reviewCreated := tick(&now) featureSha := repositoryHelper.GetRepositorySha("feature") return &f3.Review{ ReviewerID: f3_tree.NewUserReference(user.GetID()), Official: true, CommitID: featureSha, Content: "the review content", CreatedAt: reviewCreated, State: f3.ReviewStateCommented, } } func (f *Creator) GenerateReviewComment(parent path.Path) *f3.ReviewComment { user := f3_tree.GetFirstFormat[*f3.User](parent.Last().(generic.NodeInterface)) projectNode := f3_tree.GetFirstNodeKind(parent.Last().(generic.NodeInterface), f3_tree.KindProject) repositoryNode := projectNode.Find(generic.NewPathFromString("repositories/vcs")) repositoryNode.Get(context.Background()) repositoryHelper := tests_repository.NewTestHelper(f.t, "", repositoryNode) now := now() commentCreated := tick(&now) commentUpdated := tick(&now) featureSha := repositoryHelper.GetRepositorySha("feature") return &f3.ReviewComment{ Content: "comment content", TreePath: "README.md", DiffHunk: "@@ -108,7 +108,6 @@", Line: 1, CommitID: featureSha, PosterID: f3_tree.NewUserReference(user.GetID()), CreatedAt: commentCreated, UpdatedAt: commentUpdated, } }