// Copyright Earl Warren // Copyright Loïc Dachary // SPDX-License-Identifier: MIT package f3 import ( "context" "crypto/sha256" "fmt" "io" "strings" "testing" "time" "code.forgejo.org/f3/gof3/v3/f3" tests_repository "code.forgejo.org/f3/gof3/v3/forges/helpers/tests/repository" "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" ) func GeneratorSetRandomID(id string, f f3.Interface, parent path.Path) f3.Interface { if parent.First().(generic.NodeInterface).GetTree().AllocateID() { return f } return GeneratorSetID(f, id) } func GeneratorSetID(f f3.Interface, id string) f3.Interface { f.SetID(id) return f } type ModificatorFunc func(t *testing.T, f f3.Interface, parent path.Path) []f3.Interface func GeneratorModify(t *testing.T, f f3.Interface, parent path.Path) []f3.Interface { switch v := f.(type) { case *f3.User: return GeneratorModifyUser(v) case *f3.Organization: return GeneratorModifyOrganization(v) case *f3.Project: return GeneratorModifyProject(v, parent) case *f3.Issue: return GeneratorModifyIssue(v, parent) case *f3.Milestone: return GeneratorModifyMilestone(v, parent) case *f3.Topic: return GeneratorModifyTopic(v, parent) case *f3.Reaction: // a reaction cannot be modified, it can only be created and deleted return []f3.Interface{} case *f3.Label: return GeneratorModifyLabel(v, parent) case *f3.Comment: return GeneratorModifyComment(v, parent) case *f3.Release: return GeneratorModifyRelease(t, v, parent) case *f3.ReleaseAsset: return GeneratorModifyReleaseAsset(v, parent) case *f3.PullRequest: return GeneratorModifyPullRequest(t, v, parent) case *f3.Review: // a review cannot be modified, it can only be created and deleted return []f3.Interface{} case *f3.ReviewComment: return GeneratorModifyReviewComment(t, v, parent) default: panic(fmt.Errorf("not implemented %T", f)) } } type GeneratorFunc func(t *testing.T, name string, f f3.Interface, parent path.Path) f3.Interface func GeneratorSetRandom(t *testing.T, name string, f f3.Interface, parent path.Path) f3.Interface { GeneratorSetRandomID(name, f, parent) switch v := f.(type) { case *f3.User: return GeneratorSetRandomUser(v) case *f3.Organization: return GeneratorSetRandomOrganization(v) case *f3.Project: return GeneratorSetRandomProject(v, parent) case *f3.Issue: return GeneratorSetRandomIssue(v, parent) case *f3.Milestone: return GeneratorSetRandomMilestone(v, parent) case *f3.Topic: return GeneratorSetRandomTopic(v, parent) case *f3.Reaction: return GeneratorSetRandomReaction(v, parent) case *f3.Label: return GeneratorSetRandomLabel(v, parent) case *f3.Comment: return GeneratorSetRandomComment(v, parent) case *f3.Release: return GeneratorSetRandomRelease(t, v, parent) case *f3.ReleaseAsset: return GeneratorSetRandomReleaseAsset(v, parent) case *f3.PullRequest: return GeneratorSetRandomPullRequest(t, v, parent) case *f3.Review: return GeneratorSetReview(t, v, parent) case *f3.ReviewComment: return GeneratorSetReviewComment(t, v, parent) default: panic(fmt.Errorf("not implemented %T", f)) } } func GeneratorSetRandomUser(user *f3.User) *f3.User { username := fmt.Sprintf("generateduser%s", user.GetID()) user.Name = username + " Doe" user.UserName = username user.Email = username + "@example.com" user.Password = "Wrobyak4" return user } func GeneratorModifyUser(user *f3.User) []f3.Interface { return []f3.Interface{user.Clone()} } func GeneratorSetRandomOrganization(organization *f3.Organization) *f3.Organization { organizationname := fmt.Sprintf("generatedorg%s", organization.GetID()) organization.FullName = organizationname + " Lambda" organization.Name = organizationname return organization } func GeneratorModifyOrganization(organization *f3.Organization) []f3.Interface { organization0 := organization.Clone().(*f3.Organization) organization0.FullName = "modified " + organization.FullName return []f3.Interface{organization0} } func GeneratorSetRandomProject(project *f3.Project, parent path.Path) *f3.Project { projectname := fmt.Sprintf("project%s", project.GetID()) project.Name = projectname project.IsPrivate = false project.IsMirror = false project.Description = "project description" project.DefaultBranch = "main" return project } func GeneratorModifyProject(project *f3.Project, parent path.Path) []f3.Interface { project0 := project.Clone().(*f3.Project) project0.Description = "modified " + project.Description return []f3.Interface{project0} } func GeneratorSetRandomIssue(issue *f3.Issue, 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")) labels := labelsNode.GetChildren() firstLabel := labels[0] now := now() updated := tick(&now) closed := tick(&now) created := tick(&now) userRef := f3_tree.NewUserReference(user.GetID()) labelRef := f3_tree.NewIssueLabelReference(firstLabel.GetID()) milestonesNode := projectNode.Find(generic.NewPathFromString("milestones")) milestones := milestonesNode.GetChildren() firstMilestone := milestones[0] issue.PosterID = userRef issue.Assignees = []*f3.Reference{userRef} issue.Labels = []*f3.Reference{labelRef} issue.Milestone = f3_tree.NewIssueMilestoneReference(firstMilestone.GetID()) issue.Title = "title" issue.Content = "content" issue.State = f3.IssueStateOpen issue.IsLocked = false issue.Created = created issue.Updated = updated issue.Closed = &closed return issue } func GeneratorModifyIssue(issue *f3.Issue, parent path.Path) []f3.Interface { assignees := issue.Assignees milestone := issue.Milestone labels := issue.Labels issue0 := issue.Clone().(*f3.Issue) issue0.Title = "modified " + issue.Title issue0.Content = "modified " + issue.Content issueClosed := issue0.Clone().(*f3.Issue) issueClosed.Assignees = []*f3.Reference{} issueClosed.Milestone = &f3.Reference{} issueClosed.Labels = []*f3.Reference{} issueClosed.State = f3.IssueStateClosed issueClosed.IsLocked = true issueOpen := issue0.Clone().(*f3.Issue) issueOpen.Assignees = assignees issueOpen.Milestone = milestone issueOpen.Labels = labels issueOpen.State = f3.IssueStateOpen issueClosed.IsLocked = false return []f3.Interface{ issue0, issueClosed, issueOpen, } } func GeneratorSetRandomMilestone(milestone *f3.Milestone, parent path.Path) *f3.Milestone { now := now() created := tick(&now) updated := tick(&now) deadline := tick(&now) title := fmt.Sprintf("milestone%s", milestone.GetID()) milestone.Title = title milestone.Description = title + " description" milestone.Deadline = &deadline milestone.Created = created milestone.Updated = &updated milestone.Closed = nil milestone.State = f3.MilestoneStateOpen return milestone } func GeneratorModifyMilestone(milestone *f3.Milestone, parent path.Path) []f3.Interface { milestone0 := milestone.Clone().(*f3.Milestone) milestone0.Title = "modified " + milestone.Title milestoneClosed := milestone0.Clone().(*f3.Milestone) milestoneClosed.State = f3.MilestoneStateClosed deadline := time.Now().Truncate(time.Second).Add(5 * time.Minute) milestoneClosed.Deadline = &deadline milestoneOpen := milestone0.Clone().(*f3.Milestone) milestoneOpen.State = f3.MilestoneStateOpen return []f3.Interface{ milestone0, milestoneClosed, milestoneOpen, } } func GeneratorSetRandomTopic(topic *f3.Topic, parent path.Path) *f3.Topic { topic.Name = fmt.Sprintf("topic%s", topic.GetID()) return topic } func GeneratorModifyTopic(topic *f3.Topic, parent path.Path) []f3.Interface { topic0 := topic.Clone().(*f3.Topic) return []f3.Interface{topic0} } func GeneratorSetRandomReaction(reaction *f3.Reaction, parent path.Path) *f3.Reaction { user := f3_tree.GetFirstFormat[*f3.User](parent.Last().(generic.NodeInterface)) reaction.UserID = f3_tree.NewUserReference(user.GetID()) reaction.Content = "laugh" return reaction } func GeneratorSetRandomLabel(label *f3.Label, parent path.Path) *f3.Label { name := fmt.Sprintf("label%s", label.GetID()) label.Name = name label.Description = name + " description" label.Color = "ffffff" return label } func GeneratorModifyLabel(label *f3.Label, parent path.Path) []f3.Interface { label0 := label.Clone().(*f3.Label) label0.Name = "modified" + label.Name label0.Color = "f0f0f0" label0.Description = "modified " + label.Description return []f3.Interface{label0} } func GeneratorSetRandomComment(comment *f3.Comment, parent path.Path) *f3.Comment { user := f3_tree.GetFirstFormat[*f3.User](parent.Last().(generic.NodeInterface)) now := now() commentCreated := tick(&now) commentUpdated := tick(&now) comment.PosterID = f3_tree.NewUserReference(user.GetID()) comment.Created = commentCreated comment.Updated = commentUpdated comment.Content = "comment content" return comment } func GeneratorModifyComment(comment *f3.Comment, parent path.Path) []f3.Interface { comment0 := comment.Clone().(*f3.Comment) comment0.Content = "modified" + comment.Content return []f3.Interface{comment0} } func GeneratorSetRandomRelease(t *testing.T, release *f3.Release, 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(t, "", repository) now := now() releaseCreated := tick(&now) tag := fmt.Sprintf("release%s", release.GetID()) repositoryHelper.CreateRepositoryTag(tag, "master") sha := repositoryHelper.GetRepositorySha("master") fmt.Printf("GeneratorSetRandomRelease %s %s\n", repository.GetCurrentPath(), repository.GetID()) repositoryHelper.PushMirror() release.TagName = tag release.TargetCommitish = sha release.Name = tag + " name" release.Body = tag + " body" release.Draft = false release.Prerelease = false release.PublisherID = f3_tree.NewUserReference(user.GetID()) release.Created = releaseCreated return release } func GeneratorModifyRelease(t *testing.T, release *f3.Release, parent path.Path) []f3.Interface { release0 := release.Clone().(*f3.Release) release0.Body = "modified " + release.Body return []f3.Interface{release0} } func GeneratorSetRandomReleaseAsset(asset *f3.ReleaseAsset, parent path.Path) *f3.ReleaseAsset { name := fmt.Sprintf("assetname%s", asset.GetID()) content := fmt.Sprintf("assetcontent%s", asset.GetID()) downloadURL := "downloadURL" now := now() assetCreated := tick(&now) size := len(content) downloadCount := int64(10) sha256 := fmt.Sprintf("%x", sha256.Sum256([]byte(content))) asset.Name = name asset.Size = int64(size) asset.DownloadCount = downloadCount asset.Created = assetCreated asset.SHA256 = sha256 asset.DownloadURL = downloadURL asset.DownloadFunc = func() io.ReadCloser { rc := io.NopCloser(strings.NewReader(content)) return rc } return asset } func GeneratorModifyReleaseAsset(asset *f3.ReleaseAsset, parent path.Path) []f3.Interface { asset0 := asset.Clone().(*f3.ReleaseAsset) asset0.Name = "modified" + asset.Name return []f3.Interface{asset0} } func GeneratorSetRandomPullRequest(t *testing.T, pullRequest *f3.PullRequest, 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(t, "", repositoryNode) mainRef := "master" mainSha := repositoryHelper.GetRepositorySha(mainRef) featureRef := "generatedfeature" repositoryHelper.InternalBranchRepositoryFeature(featureRef, featureRef+" content") featureSha := repositoryHelper.GetRepositorySha(featureRef) fmt.Printf("createPullRequest: master %s at main %s feature %s\n", repositoryHelper.GetBare(), mainSha, featureSha) repositoryHelper.PushMirror() now := now() prCreated := tick(&now) prUpdated := tick(&now) pullRequest.PosterID = f3_tree.NewUserReference(user.GetID()) pullRequest.Title = featureRef + " pr title" pullRequest.Content = featureRef + " pr content" pullRequest.State = f3.PullRequestStateOpen pullRequest.IsLocked = false pullRequest.Created = prCreated pullRequest.Updated = prUpdated pullRequest.Closed = nil pullRequest.Merged = false pullRequest.MergedTime = nil pullRequest.MergeCommitSHA = "" pullRequest.Head = f3.PullRequestBranch{ Ref: featureRef, SHA: featureSha, Repository: f3.NewReference("../../repository/vcs"), } pullRequest.Base = f3.PullRequestBranch{ Ref: mainRef, SHA: mainSha, Repository: f3.NewReference("../../repository/vcs"), } return pullRequest } func GeneratorModifyPullRequest(t *testing.T, pullRequest *f3.PullRequest, parent path.Path) []f3.Interface { pullRequest0 := pullRequest.Clone().(*f3.PullRequest) pullRequest0.Title = "modified " + pullRequest.Title return []f3.Interface{pullRequest0} } func GeneratorSetReview(t *testing.T, review *f3.Review, 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(t, "", repositoryNode) now := now() reviewCreated := tick(&now) featureSha := repositoryHelper.GetRepositorySha("feature") review.ReviewerID = f3_tree.NewUserReference(user.GetID()) review.Official = true review.CommitID = featureSha review.Content = "the review content" review.CreatedAt = reviewCreated review.State = f3.ReviewStateCommented return review } func GeneratorSetReviewComment(t *testing.T, comment *f3.ReviewComment, 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(t, "", repositoryNode) now := now() commentCreated := tick(&now) commentUpdated := tick(&now) featureSha := repositoryHelper.GetRepositorySha("feature") comment.Content = "comment content" comment.TreePath = "README.md" comment.DiffHunk = "@@ -108,7 +108,6 @@" comment.Line = 1 comment.CommitID = featureSha comment.PosterID = f3_tree.NewUserReference(user.GetID()) comment.CreatedAt = commentCreated comment.UpdatedAt = commentUpdated return comment } func GeneratorModifyReviewComment(t *testing.T, comment *f3.ReviewComment, parent path.Path) []f3.Interface { comment0 := comment.Clone().(*f3.ReviewComment) comment0.Content = "modified " + comment.Content return []f3.Interface{comment0} }