564 lines · 15.2 KB · Go
RawDownload
// Copyright 2019 The Gitea Authors. All rights reserved.// SPDX-License-Identifier: MIT package references import (	"regexp"	"testing" 	"forgejo.org/modules/setting" 	"github.com/stretchr/testify/assert") type testFixture struct {	input    string	expected []testResult} type testResult struct {	Index          int64	Owner          string	Name           string	Issue          string	IsPull         bool	Action         XRefAction	RefLocation    *RefSpan	ActionLocation *RefSpan	TimeLog        string} func TestConvertFullHTMLReferencesToShortRefs(t *testing.T) {	re := regexp.MustCompile(`(\s|^|\(|\[)` +		regexp.QuoteMeta("https://ourgitea.com/git/") +		`([0-9a-zA-Z-_\.]+/[0-9a-zA-Z-_\.]+)/` +		`((?:issues)|(?:pulls))/([0-9]+)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)	test := `this is a https://ourgitea.com/git/owner/repo/issues/123456789, foohttps://ourgitea.com/git/owner/repo/pulls/123456789  And https://ourgitea.com/git/owner/repo/pulls/123`	expect := `this is a owner/repo#123456789, fooowner/repo!123456789  And owner/repo!123` 	contentBytes := []byte(test)	convertFullHTMLReferencesToShortRefs(re, &contentBytes)	result := string(contentBytes)	assert.Equal(t, expect, result)} func TestFindAllIssueReferences(t *testing.T) {	fixtures := []testFixture{		{			"Simply closes: #29 yes",			[]testResult{				{29, "", "", "29", false, XRefActionCloses, &RefSpan{Start: 15, End: 18}, &RefSpan{Start: 7, End: 13}, ""},			},		},		{			"Simply closes: !29 yes",			[]testResult{				{29, "", "", "29", true, XRefActionCloses, &RefSpan{Start: 15, End: 18}, &RefSpan{Start: 7, End: 13}, ""},			},		},		{			" #124 yes, this is a reference.",			[]testResult{				{124, "", "", "124", false, XRefActionNone, &RefSpan{Start: 0, End: 4}, nil, ""},			},		},		{			"```\nThis is a code block.\n#723 no, it's a code block.```",			[]testResult{},		},		{			"This `#724` no, it's inline code.",			[]testResult{},		},		{			"This org3/repo4#200 yes.",			[]testResult{				{200, "org3", "repo4", "200", false, XRefActionNone, &RefSpan{Start: 5, End: 19}, nil, ""},			},		},		{			"This org3/repo4!200 yes.",			[]testResult{				{200, "org3", "repo4", "200", true, XRefActionNone, &RefSpan{Start: 5, End: 19}, nil, ""},			},		},		{			"This [one](#919) no, this is a URL fragment.",			[]testResult{},		},		{			"This [two](/user2/repo1/issues/921) yes.",			[]testResult{				{921, "user2", "repo1", "921", false, XRefActionNone, nil, nil, ""},			},		},		{			"This [three](/user2/repo1/pulls/922) yes.",			[]testResult{				{922, "user2", "repo1", "922", true, XRefActionNone, nil, nil, ""},			},		},		{			"This [four](http://gitea.com:3000/org3/repo4/issues/203) yes.",			[]testResult{				{203, "org3", "repo4", "203", false, XRefActionNone, nil, nil, ""},			},		},		{			"This [five](http://github.com/org3/repo4/issues/204) no.",			[]testResult{},		},		{			"This http://gitea.com:3000/user4/repo5/201 no, bad URL.",			[]testResult{},		},		{			"This http://gitea.com:3000/user4/repo5/pulls/202 yes.",			[]testResult{				{202, "user4", "repo5", "202", true, XRefActionNone, nil, nil, ""},			},		},		{			"This http://gitea.com:3000/user4/repo5/pulls/202 yes. http://gitea.com:3000/user4/repo5/pulls/203 no",			[]testResult{				{202, "user4", "repo5", "202", true, XRefActionNone, nil, nil, ""},				{203, "user4", "repo5", "203", true, XRefActionNone, nil, nil, ""},			},		},		{			"This http://GiTeA.COM:3000/user4/repo6/pulls/205 yes.",			[]testResult{				{205, "user4", "repo6", "205", true, XRefActionNone, nil, nil, ""},			},		},		{			"Reopens #15 yes",			[]testResult{				{15, "", "", "15", false, XRefActionReopens, &RefSpan{Start: 8, End: 11}, &RefSpan{Start: 0, End: 7}, ""},			},		},		{			"This closes #20 for you yes",			[]testResult{				{20, "", "", "20", false, XRefActionCloses, &RefSpan{Start: 12, End: 15}, &RefSpan{Start: 5, End: 11}, ""},			},		},		{			"Do you fix org6/repo6#300 ? yes",			[]testResult{				{300, "org6", "repo6", "300", false, XRefActionCloses, &RefSpan{Start: 11, End: 25}, &RefSpan{Start: 7, End: 10}, ""},			},		},		{			"For 999 #1235 no keyword, but yes",			[]testResult{				{1235, "", "", "1235", false, XRefActionNone, &RefSpan{Start: 8, End: 13}, nil, ""},			},		},		{			"For [!123] yes",			[]testResult{				{123, "", "", "123", true, XRefActionNone, &RefSpan{Start: 5, End: 9}, nil, ""},			},		},		{			"For (#345) yes",			[]testResult{				{345, "", "", "345", false, XRefActionNone, &RefSpan{Start: 5, End: 9}, nil, ""},			},		},		{			"For #22,#23 no, neither #28:#29 or !30!31#32;33 should",			[]testResult{},		},		{			"For #24, and #25. yes; also #26; #27? #28! and #29: should",			[]testResult{				{24, "", "", "24", false, XRefActionNone, &RefSpan{Start: 4, End: 7}, nil, ""},				{25, "", "", "25", false, XRefActionNone, &RefSpan{Start: 13, End: 16}, nil, ""},				{26, "", "", "26", false, XRefActionNone, &RefSpan{Start: 28, End: 31}, nil, ""},				{27, "", "", "27", false, XRefActionNone, &RefSpan{Start: 33, End: 36}, nil, ""},				{28, "", "", "28", false, XRefActionNone, &RefSpan{Start: 38, End: 41}, nil, ""},				{29, "", "", "29", false, XRefActionNone, &RefSpan{Start: 47, End: 50}, nil, ""},			},		},		{			"This org3/repo4#200, yes.",			[]testResult{				{200, "org3", "repo4", "200", false, XRefActionNone, &RefSpan{Start: 5, End: 19}, nil, ""},			},		},		{			"Merge pull request '#12345 My fix for a bug' (!1337) from feature-branch into main",			[]testResult{				{12345, "", "", "12345", false, XRefActionNone, &RefSpan{Start: 20, End: 26}, nil, ""},				{1337, "", "", "1337", true, XRefActionNone, &RefSpan{Start: 46, End: 51}, nil, ""},			},		},		{			"Which abc. #9434 same as above",			[]testResult{				{9434, "", "", "9434", false, XRefActionNone, &RefSpan{Start: 11, End: 16}, nil, ""},			},		},		{			"This closes #600 and reopens #599",			[]testResult{				{600, "", "", "600", false, XRefActionCloses, &RefSpan{Start: 12, End: 16}, &RefSpan{Start: 5, End: 11}, ""},				{599, "", "", "599", false, XRefActionReopens, &RefSpan{Start: 29, End: 33}, &RefSpan{Start: 21, End: 28}, ""},			},		},		{			"This fixes #100 spent @40m and reopens #101, also fixes #102 spent @4h15m",			[]testResult{				{100, "", "", "100", false, XRefActionCloses, &RefSpan{Start: 11, End: 15}, &RefSpan{Start: 5, End: 10}, "40m"},				{101, "", "", "101", false, XRefActionReopens, &RefSpan{Start: 39, End: 43}, &RefSpan{Start: 31, End: 38}, ""},				{102, "", "", "102", false, XRefActionCloses, &RefSpan{Start: 56, End: 60}, &RefSpan{Start: 50, End: 55}, "4h15m"},			},		},	} 	testFixtures(t, fixtures, "default") 	type alnumFixture struct {		input          string		issue          string		refLocation    *RefSpan		action         XRefAction		actionLocation *RefSpan	} 	alnumFixtures := []alnumFixture{		{			"This ref ABC-123 is alphanumeric",			"ABC-123", &RefSpan{Start: 9, End: 16},			XRefActionNone, nil,		},		{			"This closes ABCD-1234 alphanumeric",			"ABCD-1234", &RefSpan{Start: 12, End: 21},			XRefActionCloses, &RefSpan{Start: 5, End: 11},		},	} 	for _, fixture := range alnumFixtures {		found, ref := FindRenderizableReferenceAlphanumeric(fixture.input)		if fixture.issue == "" {			assert.False(t, found, "Failed to parse: {%s}", fixture.input)		} else {			assert.True(t, found, "Failed to parse: {%s}", fixture.input)			assert.Equal(t, fixture.issue, ref.Issue, "Failed to parse: {%s}", fixture.input)			assert.Equal(t, fixture.refLocation, ref.RefLocation, "Failed to parse: {%s}", fixture.input)			assert.Equal(t, fixture.action, ref.Action, "Failed to parse: {%s}", fixture.input)			assert.Equal(t, fixture.actionLocation, ref.ActionLocation, "Failed to parse: {%s}", fixture.input)		}	}} func testFixtures(t *testing.T, fixtures []testFixture, context string) {	// Save original value for other tests that may rely on it	prevURL := setting.AppURL	setting.AppURL = "https://gitea.com:3000/" 	for _, fixture := range fixtures {		expraw := make([]*rawReference, len(fixture.expected))		for i, e := range fixture.expected {			expraw[i] = &rawReference{				index:          e.Index,				owner:          e.Owner,				name:           e.Name,				isPull:         e.IsPull,				action:         e.Action,				issue:          e.Issue,				refLocation:    e.RefLocation,				actionLocation: e.ActionLocation,				timeLog:        e.TimeLog,			}		}		expref := rawToIssueReferenceList(expraw)		refs := FindAllIssueReferencesMarkdown(fixture.input)		assert.Equal(t, expref, refs, "[%s] Failed to parse: {%s}", context, fixture.input)		rawrefs := findAllIssueReferencesMarkdown(fixture.input)		assert.Equal(t, expraw, rawrefs, "[%s] Failed to parse: {%s}", context, fixture.input)	} 	// Restore for other tests that may rely on the original value	setting.AppURL = prevURL} func TestFindAllMentions(t *testing.T) {	res := FindAllMentionsBytes([]byte("@tasha, @mike; @lucy: @john"))	assert.Equal(t, []RefSpan{		{Start: 0, End: 6},		{Start: 8, End: 13},		{Start: 15, End: 20},		{Start: 22, End: 27},	}, res)} func TestFindRenderizableCommitCrossReference(t *testing.T) {	cases := []struct {		Input    string		Expected *RenderizableReference	}{		{			Input:    "",			Expected: nil,		},		{			Input:    "test",			Expected: nil,		},		{			Input:    "go-gitea/gitea@test",			Expected: nil,		},		{			Input:    "go-gitea/gitea@ab1234",			Expected: nil,		},		{			Input: "go-gitea/gitea@abcd1234",			Expected: &RenderizableReference{				Owner:       "go-gitea",				Name:        "gitea",				CommitSha:   "abcd1234",				RefLocation: &RefSpan{Start: 0, End: 23},			},		},		{			Input: "go-gitea/gitea@abcd1234abcd1234abcd1234abcd1234abcd1234",			Expected: &RenderizableReference{				Owner:       "go-gitea",				Name:        "gitea",				CommitSha:   "abcd1234abcd1234abcd1234abcd1234abcd1234",				RefLocation: &RefSpan{Start: 0, End: 55},			},		},		{			Input:    "go-gitea/gitea@abcd1234abcd1234abcd1234abcd1234abcd12341234512345123451234512345", // longer than 64 characters			Expected: nil,		},		{			Input: "test go-gitea/gitea@abcd1234 test",			Expected: &RenderizableReference{				Owner:       "go-gitea",				Name:        "gitea",				CommitSha:   "abcd1234",				RefLocation: &RefSpan{Start: 5, End: 28},			},		},	} 	for _, c := range cases {		found, ref := FindRenderizableCommitCrossReference(c.Input)		assert.Equal(t, ref != nil, found)		assert.Equal(t, c.Expected, ref)	}} func TestRegExp_mentionPattern(t *testing.T) {	trueTestCases := []struct {		pat string		exp string	}{		{"@User", "@User"},		{"@ANT_123", "@ANT_123"},		{"@xxx-DiN0-z-A..uru..s-xxx", "@xxx-DiN0-z-A..uru..s-xxx"},		{"   @lol   ", "@lol"},		{" @Te-st", "@Te-st"},		{"(@gitea)", "@gitea"},		{"[@gitea]", "@gitea"},		{"@gitea! this", "@gitea"},		{"@gitea? this", "@gitea"},		{"@gitea. this", "@gitea"},		{"@gitea, this", "@gitea"},		{"@gitea; this", "@gitea"},		{"@gitea!\nthis", "@gitea"},		{"\n@gitea?\nthis", "@gitea"},		{"\t@gitea.\nthis", "@gitea"},		{"@gitea,\nthis", "@gitea"},		{"@gitea;\nthis", "@gitea"},		{"@gitea!", "@gitea"},		{"@gitea?", "@gitea"},		{"@gitea.", "@gitea"},		{"@gitea,", "@gitea"},		{"@gitea;", "@gitea"},		{"@gitea/team1;", "@gitea/team1"},		{"@jess'", "@jess"},		{"@forgejo's", "@forgejo"},		{"Оно сломалось из-за коммитов от @jopik'а", "@jopik"},	}	falseTestCases := []string{		"@ 0",		"@ ",		"@",		"",		"ABC",		"@.ABC",		"/home/gitea/@gitea",		"\"@gitea\"",		"@@gitea",		"@gitea!this",		"@gitea?this",		"@gitea,this",		"@gitea;this",		"@gitea/team1/more",	} 	for _, testCase := range trueTestCases {		found := mentionPattern.FindStringSubmatch(testCase.pat)		assert.Len(t, found, 2)		assert.Equal(t, testCase.exp, found[1])	}	for _, testCase := range falseTestCases {		res := mentionPattern.MatchString(testCase)		assert.False(t, res, "[%s] should be false", testCase)	}} func TestRegExp_issueNumericPattern(t *testing.T) {	trueTestCases := []string{		"#1234",		"#0",		"#1234567890987654321",		"  #12",		"#12:",		"ref: #12: msg",		"\"#1234\"",		"'#1234'",	}	falseTestCases := []string{		"# 1234",		"# 0",		"# ",		"#",		"#ABC",		"#1A2B",		"",		"ABC",	} 	for _, testCase := range trueTestCases {		assert.True(t, issueNumericPattern.MatchString(testCase))	}	for _, testCase := range falseTestCases {		assert.False(t, issueNumericPattern.MatchString(testCase))	}} func TestRegExp_issueAlphanumericPattern(t *testing.T) {	trueTestCases := []string{		"ABC-1234",		"A-1",		"RC-80",		"ABCDEFGHIJ-1234567890987654321234567890",		"ABC-123.",		"(ABC-123)",		"[ABC-123]",		"ABC-123:",		"\"ABC-123\"",		"'ABC-123'",		"ABC-123, unknown PR",	}	falseTestCases := []string{		"RC-08",		"PR-0",		"ABCDEFGHIJK-1",		"PR_1",		"",		"#ABC",		"",		"ABC",		"GG-",		"rm-1",		"/home/gitea/ABC-1234",		"MY-STRING-ABC-123",	} 	for _, testCase := range trueTestCases {		assert.True(t, issueAlphanumericPattern.MatchString(testCase))	}	for _, testCase := range falseTestCases {		assert.False(t, issueAlphanumericPattern.MatchString(testCase))	}} func TestCustomizeCloseKeywords(t *testing.T) {	fixtures := []testFixture{		{			"Simplemente cierra: #29 yes",			[]testResult{				{29, "", "", "29", false, XRefActionCloses, &RefSpan{Start: 20, End: 23}, &RefSpan{Start: 12, End: 18}, ""},			},

Lines 1–500 of 564.