package posting import ( "regexp" "testing" "github.com/gochan-org/gochan/pkg/config" "github.com/gochan-org/gochan/pkg/gcsql" "github.com/stretchr/testify/assert" lua "github.com/yuin/gopher-lua" ) const ( versionStr = "4.0.0" bbcodeMsgPreRender = `[b]Bold[/b] [i]Italics[/i] [u]Underline[/u] [url=https://gochan.org]URL[/url] [?]Spoiler[/?] [code]Code[/code] [hide]Hidden[/hide]` bbcodeMsgExpected = `Bold Italics Underline URL Spoiler
` + `
Code

` + `` linkTestPreRender = `gochan.org: https://gochan.org gochan.org with path: https://gochan.org/a gochan.org with bad link: https://gochan.org/a">:)` linkTestExpected = `gochan.org: https://gochan.org
` + `gochan.org with path: https://gochan.org/a
` + `gochan.org with bad link: https://gochan.org/a">:)</a>` doubleTagPreRender = `[url=https://gochan.org]Gochan[/url] [url]https://gochan.org[/url]` doubleTagExpected = `Gochan https://gochan.org` luaBBCodeTest = `local bbcode = require("bbcode") local msg = "[lua]Lua test[/lua]" bbcode.set_tag("lua", function(node) return {name="span", attrs={class="lua"}} end)` luaBBCodeTestExpected = `Lua test` ) var ( diceTestCases = []diceRollerTestCase{ { desc: "[2d6]", post: gcsql.Post{ MessageRaw: "[2d6]", }, matcher: regexp.MustCompile(`2d6 = \d{1,2}`), expectMin: 2, expectMax: 12, }, { desc: "[2d6+1]", post: gcsql.Post{ MessageRaw: "[2d6+1]", }, matcher: regexp.MustCompile(`2d6\+1 = \d{1,2}`), expectMin: 3, expectMax: 13, }, { desc: "[2d6-1]", post: gcsql.Post{ MessageRaw: "[2d6-1]", }, matcher: regexp.MustCompile(`2d6-1 = \d{1,2}`), expectMin: 1, expectMax: 11, }, { desc: "[d8]", post: gcsql.Post{ MessageRaw: "[d8]", }, matcher: regexp.MustCompile(`1d8 = \d`), expectMin: 1, expectMax: 8, }, { desc: "before[1d6]after, no space", post: gcsql.Post{ MessageRaw: "before[1d6]after", }, matcher: regexp.MustCompile(`before1d6 = \dafter`), expectMin: 1, expectMax: 6, }, { desc: "before [1d6] after, no space (test for injection)", post: gcsql.Post{ MessageRaw: `[1d6]`, }, matcher: regexp.MustCompile(`<script>alert\("lol"\)</script>1d6 = \d<script>alert\("lmao"\)</script>`), expectMin: 1, expectMax: 6, }, { desc: "two dice rolls, no space", post: gcsql.Post{ MessageRaw: "[d6][2d6]", }, matcher: regexp.MustCompile(`1d6 = \d2d6 = \d{1,2}`), expectMin: 0, expectMax: 7, }, { desc: "multiple dice rolls, no space", post: gcsql.Post{ MessageRaw: "[d6][2d20-2][3d8+1]", }, matcher: regexp.MustCompile(`1d6 = \d2d20-2 = \d{1,2}3d8\+1 = \d{1,2}`), expectMin: 0, expectMax: 38, }, { desc: "invalid number of dice", post: gcsql.Post{ MessageRaw: "[0d6]", }, expectError: true, }, { desc: "invalid die size", post: gcsql.Post{ MessageRaw: "[1d0]", }, expectError: true, }, { desc: "invalid modifier", post: gcsql.Post{ MessageRaw: "[1d6+]", }, matcher: regexp.MustCompile(`\[1d6\+\]`), }, } ) type diceRollerTestCase struct { desc string post gcsql.Post expectError bool matcher *regexp.Regexp expectMin int expectMax int } func TestBBCode(t *testing.T) { config.SetVersion(versionStr) var testFmtr MessageFormatter testFmtr.Init() rendered := testFmtr.Compile(bbcodeMsgPreRender, "") assert.Equal(t, bbcodeMsgExpected, rendered, "Testing BBcode rendering") } func TestLinks(t *testing.T) { config.SetVersion(versionStr) var testFmtr MessageFormatter testFmtr.Init() rendered := urlRE.ReplaceAllStringFunc(linkTestPreRender, wrapLinksInURL) rendered = testFmtr.Compile(rendered, "") assert.Equal(t, linkTestExpected, rendered) } func TestNoDoubleTags(t *testing.T) { config.SetVersion(versionStr) msgfmtr.Init() rendered, err := FormatMessage(doubleTagPreRender, "") assert.NoError(t, err) assert.EqualValues(t, doubleTagExpected, rendered) } func TestLuaBBCode(t *testing.T) { config.SetVersion(versionStr) msgfmtr.Init() l := lua.NewState() defer l.Close() l.PreloadModule("bbcode", PreloadBBCodeModule) assert.NoError(t, l.DoString(luaBBCodeTest)) compiled := msgfmtr.bbCompiler.Compile("[lua]Lua test[/lua]") assert.Equal(t, luaBBCodeTestExpected, compiled) assert.NoError(t, l.DoString(`require("bbcode").set_tag("b", nil)`)) assert.Equal(t, "[b]Lua test[/b]", msgfmtr.bbCompiler.Compile("[b]Lua test[/b]")) assert.Error(t, l.DoString(`bbcode.set_tag("lua", 1)`)) } func diceRollRunner(t *testing.T, tC *diceRollerTestCase) { var err error tC.post.Message, err = FormatMessage(tC.post.MessageRaw, "") assert.NoError(t, err) err = ApplyDiceRoll(&tC.post) if tC.expectError { assert.Error(t, err) } else { assert.NoError(t, err) assert.Regexp(t, tC.matcher, tC.post.Message) } if t.Failed() { t.FailNow() } } func TestDiceRoll(t *testing.T) { config.SetVersion(versionStr) msgfmtr.Init() for _, tC := range diceTestCases { t.Run(tC.desc, func(t *testing.T) { for i := 0; i < 100; i++ { // Run the test case multiple times to account for randomness diceRollRunner(t, &tC) } }) } }