Tests are green now.

Recognise localhost equivalents in the parser.
Add rel=ugc to the bbcode parser too.
More shortening and boilerplate eliminating.
Fix a potential lock bug.
This commit is contained in:
Azareal 2019-10-06 11:49:31 +10:00
parent 11d1286b56
commit 8d40139ae5
6 changed files with 151 additions and 152 deletions

View File

@ -862,8 +862,7 @@ func parseMediaString(data string) (media MediaEmbed, ok bool) {
port := url.Port() port := url.Port()
query := url.Query() query := url.Query()
// TODO: Treat 127.0.0.1 and [::1] as localhost too samesite := hostname == "localhost" || hostname == "127.0.0.1" || hostname == "::1" || hostname == Site.URL
samesite := hostname == "localhost" || hostname == Site.URL
if samesite { if samesite {
hostname = strings.Split(Site.URL, ":")[0] hostname = strings.Split(Site.URL, ":")[0]
// ?- Test this as I'm not sure it'll do what it should. If someone's running SSL on port 80 or non-SSL on port 443 then... Well... They're in far worse trouble than this... // ?- Test this as I'm not sure it'll do what it should. If someone's running SSL on port 80 or non-SSL on port 443 then... Well... They're in far worse trouble than this...

View File

@ -5,7 +5,7 @@ import (
//"log" //"log"
"net/http/httptest" "net/http/httptest"
"github.com/Azareal/Gosora/common/phrases" p "github.com/Azareal/Gosora/common/phrases"
min "github.com/Azareal/Gosora/common/templates" min "github.com/Azareal/Gosora/common/templates"
) )
@ -16,8 +16,8 @@ type wolUsers struct {
UserCount int UserCount int
} }
func wolInit(widget *Widget, schedule *WidgetScheduler) error { func wolInit(w *Widget, schedule *WidgetScheduler) error {
schedule.Add(widget) schedule.Add(w)
return nil return nil
} }
@ -34,22 +34,22 @@ func wolGetUsers() ([]*User, int) {
return users, ucount return users, ucount
} }
func wolBuild(widget *Widget, hvars interface{}) (string, error) { func wolBuild(w *Widget, hvars interface{}) (string, error) {
users, ucount := wolGetUsers() users, ucount := wolGetUsers()
wol := &wolUsers{hvars.(*Header), phrases.GetTmplPhrase("widget.online_name"), users, ucount} wol := &wolUsers{hvars.(*Header), p.GetTmplPhrase("widget.online_name"), users, ucount}
err := wol.Header.Theme.RunTmpl("widget_online", wol, wol.Header.Writer) err := wol.Header.Theme.RunTmpl("widget_online", wol, wol.Header.Writer)
return "", err return "", err
} }
func wolRender(widget *Widget, hvars interface{}) (string, error) { func wolRender(w *Widget, hvars interface{}) (string, error) {
iTickMask := widget.TickMask.Load() iTickMask := w.TickMask.Load()
if iTickMask != nil { if iTickMask != nil {
tickMask := iTickMask.(*Widget) tickMask := iTickMask.(*Widget)
if tickMask != nil { if tickMask != nil {
return tickMask.Body, nil return tickMask.Body, nil
} }
} }
return wolBuild(widget, hvars) return wolBuild(w, hvars)
} }
var wolLastUsers []*User var wolLastUsers []*User
@ -88,7 +88,7 @@ func wolTick(widget *Widget) error {
//log.Printf("users: %+v\n", users) //log.Printf("users: %+v\n", users)
//log.Printf("wolLastUsers: %+v\n", wolLastUsers) //log.Printf("wolLastUsers: %+v\n", wolLastUsers)
wol := &wolUsers{SimpleDefaultHeader(w), phrases.GetTmplPhrase("widget.online_name"), users, ucount} wol := &wolUsers{SimpleDefaultHeader(w), p.GetTmplPhrase("widget.online_name"), users, ucount}
err := wol.Header.Theme.RunTmpl("widget_online", wol, wol.Header.Writer) err := wol.Header.Theme.RunTmpl("widget_online", wol, wol.Header.Writer)
if err != nil { if err != nil {
return err return err

View File

@ -48,7 +48,7 @@ type NameTextPair struct {
Text template.HTML Text template.HTML
} }
func preparseWidget(widget *Widget, wdata string) (err error) { func preparseWidget(w *Widget, wdata string) (err error) {
prebuildWidget := func(name string, data interface{}) (string, error) { prebuildWidget := func(name string, data interface{}) (string, error) {
var b bytes.Buffer var b bytes.Buffer
err := DefaultTemplates.ExecuteTemplate(&b, name+".html", data) err := DefaultTemplates.ExecuteTemplate(&b, name+".html", data)
@ -60,48 +60,48 @@ func preparseWidget(widget *Widget, wdata string) (err error) {
} }
sbytes := []byte(wdata) sbytes := []byte(wdata)
widget.Literal = true w.Literal = true
// TODO: Split these hard-coded items out of this file and into the files for the individual widget types // TODO: Split these hard-coded items out of this file and into the files for the individual widget types
switch widget.Type { switch w.Type {
case "simple", "about": case "simple", "about":
var tmp NameTextPair var tmp NameTextPair
err = json.Unmarshal(sbytes, &tmp) err = json.Unmarshal(sbytes, &tmp)
if err != nil { if err != nil {
return err return err
} }
widget.Body, err = prebuildWidget("widget_"+widget.Type, tmp) w.Body, err = prebuildWidget("widget_"+w.Type, tmp)
case "search_and_filter": case "search_and_filter":
widget.Literal = false w.Literal = false
widget.BuildFunc = widgetSearchAndFilter w.BuildFunc = widgetSearchAndFilter
case "wol": case "wol":
widget.Literal = false w.Literal = false
widget.InitFunc = wolInit w.InitFunc = wolInit
widget.BuildFunc = wolRender w.BuildFunc = wolRender
widget.TickFunc = wolTick w.TickFunc = wolTick
case "wol_context": case "wol_context":
widget.Literal = false w.Literal = false
widget.BuildFunc = wolContextRender w.BuildFunc = wolContextRender
default: default:
widget.Body = wdata w.Body = wdata
} }
// TODO: Test this // TODO: Test this
// TODO: Should we toss this through a proper parser rather than crudely replacing it? // TODO: Should we toss this through a proper parser rather than crudely replacing it?
widget.Location = strings.Replace(widget.Location, " ", "", -1) w.Location = strings.Replace(w.Location, " ", "", -1)
widget.Location = strings.Replace(widget.Location, "frontend", "!panel", -1) w.Location = strings.Replace(w.Location, "frontend", "!panel", -1)
widget.Location = strings.Replace(widget.Location, "!!", "", -1) w.Location = strings.Replace(w.Location, "!!", "", -1)
// Skip blank zones // Skip blank zones
var locs = strings.Split(widget.Location, "|") locs := strings.Split(w.Location, "|")
if len(locs) > 0 { if len(locs) > 0 {
widget.Location = "" w.Location = ""
for _, loc := range locs { for _, loc := range locs {
if loc == "" { if loc == "" {
continue continue
} }
widget.Location += loc + "|" w.Location += loc + "|"
} }
widget.Location = widget.Location[:len(widget.Location)-1] w.Location = w.Location[:len(w.Location)-1]
} }
return err return err
@ -139,13 +139,13 @@ func HasDock(dock string) bool {
} }
// TODO: Find a more optimimal way of doing this... // TODO: Find a more optimimal way of doing this...
func HasWidgets(dock string, header *Header) bool { func HasWidgets(dock string, h *Header) bool {
if !header.Theme.HasDock(dock) { if !h.Theme.HasDock(dock) {
return false return false
} }
// Let themes forcibly override this slot // Let themes forcibly override this slot
sbody := header.Theme.BuildDock(dock) sbody := h.Theme.BuildDock(dock)
if sbody != "" { if sbody != "" {
return true return true
} }
@ -167,25 +167,24 @@ func HasWidgets(dock string, header *Header) bool {
if !widget.Enabled { if !widget.Enabled {
continue continue
} }
if widget.Allowed(header.Zone,header.ZoneID) { if widget.Allowed(h.Zone, h.ZoneID) {
wcount++ wcount++
} }
} }
return wcount > 0 return wcount > 0
} }
func BuildWidget(dock string, header *Header) (sbody string) { func BuildWidget(dock string, h *Header) (sbody string) {
var widgets []*Widget if !h.Theme.HasDock(dock) {
if !header.Theme.HasDock(dock) {
return "" return ""
} }
// Let themes forcibly override this slot // Let themes forcibly override this slot
sbody = header.Theme.BuildDock(dock) sbody = h.Theme.BuildDock(dock)
if sbody != "" { if sbody != "" {
return sbody return sbody
} }
var widgets []*Widget
switch dock { switch dock {
case "leftOfNav": case "leftOfNav":
widgets = Docks.LeftOfNav widgets = Docks.LeftOfNav
@ -195,7 +194,7 @@ func BuildWidget(dock string, header *Header) (sbody string) {
// 1 = id for the default menu // 1 = id for the default menu
mhold, err := Menus.Get(1) mhold, err := Menus.Get(1)
if err == nil { if err == nil {
err := mhold.Build(header.Writer, &header.CurrentUser, header.Path) err := mhold.Build(h.Writer, &h.CurrentUser, h.Path)
if err != nil { if err != nil {
LogError(err) LogError(err)
} }
@ -211,8 +210,8 @@ func BuildWidget(dock string, header *Header) (sbody string) {
if !widget.Enabled { if !widget.Enabled {
continue continue
} }
if widget.Allowed(header.Zone,header.ZoneID) { if widget.Allowed(h.Zone, h.ZoneID) {
item, err := widget.Build(header) item, err := widget.Build(h)
if err != nil { if err != nil {
LogError(err) LogError(err)
} }
@ -230,52 +229,46 @@ func getDockWidgets(dock string) (widgets []*Widget, err error) {
defer rows.Close() defer rows.Close()
for rows.Next() { for rows.Next() {
var widget = &Widget{Position: 0, Side: dock} w := &Widget{Position: 0, Side: dock}
err = rows.Scan(&widget.ID, &widget.Position, &widget.Type, &widget.Enabled, &widget.Location, &widget.RawBody) err = rows.Scan(&w.ID, &w.Position, &w.Type, &w.Enabled, &w.Location, &w.RawBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = preparseWidget(widget, widget.RawBody) err = preparseWidget(w, w.RawBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
Widgets.set(widget) Widgets.set(w)
widgets = append(widgets, widget) widgets = append(widgets, w)
} }
return widgets, rows.Err() return widgets, rows.Err()
} }
// TODO: Make a store for this? // TODO: Make a store for this?
func InitWidgets() error { func InitWidgets() (fi error) {
leftOfNavWidgets, err := getDockWidgets("leftOfNav")
if err != nil {
return err
}
rightOfNavWidgets, err := getDockWidgets("rightOfNav")
if err != nil {
return err
}
leftSidebarWidgets, err := getDockWidgets("leftSidebar")
if err != nil {
return err
}
rightSidebarWidgets, err := getDockWidgets("rightSidebar")
if err != nil {
return err
}
footerWidgets, err := getDockWidgets("footer")
if err != nil {
return err
}
// TODO: Let themes set default values for widget docks, and let them lock in particular places with their stuff, e.g. leftOfNav and rightOfNav // TODO: Let themes set default values for widget docks, and let them lock in particular places with their stuff, e.g. leftOfNav and rightOfNav
f := func(name string) {
if fi != nil {
return
}
dock, err := getDockWidgets(name)
if err != nil {
fi = err
return
}
setDock(name, dock)
}
f("leftOfNav")
f("rightOfNav")
f("leftSidebar")
f("rightSidebar")
f("footer")
if fi != nil {
return fi
}
setDock("leftOfNav", leftOfNavWidgets)
setDock("rightOfNav", rightOfNavWidgets)
setDock("leftSidebar", leftSidebarWidgets)
setDock("rightSidebar", rightSidebarWidgets)
setDock("footer", footerWidgets)
AddScheduledSecondTask(Docks.LeftSidebar.Scheduler.Tick) AddScheduledSecondTask(Docks.LeftSidebar.Scheduler.Tick)
AddScheduledSecondTask(Docks.RightSidebar.Scheduler.Tick) AddScheduledSecondTask(Docks.RightSidebar.Scheduler.Tick)
AddScheduledSecondTask(Docks.Footer.Scheduler.Tick) AddScheduledSecondTask(Docks.Footer.Scheduler.Tick)
@ -294,7 +287,6 @@ func releaseWidgets(widgets []*Widget) {
// TODO: Use atomics // TODO: Use atomics
func setDock(dock string, widgets []*Widget) { func setDock(dock string, widgets []*Widget) {
dockHandle := func(dockWidgets []*Widget) { dockHandle := func(dockWidgets []*Widget) {
widgetUpdateMutex.Lock()
DebugLog(dock, widgets) DebugLog(dock, widgets)
releaseWidgets(dockWidgets) releaseWidgets(dockWidgets)
} }
@ -311,6 +303,8 @@ func setDock(dock string, widgets []*Widget) {
dockWidgets.Scheduler.Store() dockWidgets.Scheduler.Store()
return WidgetDock{widgets, dockWidgets.Scheduler} return WidgetDock{widgets, dockWidgets.Scheduler}
} }
widgetUpdateMutex.Lock()
defer widgetUpdateMutex.Unlock()
switch dock { switch dock {
case "leftOfNav": case "leftOfNav":
dockHandle(Docks.LeftOfNav) dockHandle(Docks.LeftOfNav)
@ -328,7 +322,6 @@ func setDock(dock string, widgets []*Widget) {
fmt.Printf("bad dock '%s'\n", dock) fmt.Printf("bad dock '%s'\n", dock)
return return
} }
widgetUpdateMutex.Unlock()
} }
type WidgetScheduler struct { type WidgetScheduler struct {
@ -336,8 +329,8 @@ type WidgetScheduler struct {
store atomic.Value store atomic.Value
} }
func (s *WidgetScheduler) Add(widget *Widget) { func (s *WidgetScheduler) Add(w *Widget) {
s.widgets = append(s.widgets, widget) s.widgets = append(s.widgets, w)
} }
func (s *WidgetScheduler) Store() { func (s *WidgetScheduler) Store() {

View File

@ -2,13 +2,13 @@ package main
import ( import (
"bytes" "bytes"
"database/sql"
"fmt" "fmt"
"net/http/httptest" "net/http/httptest"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
"testing" "testing"
"time" "time"
"database/sql"
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/common/phrases"
@ -183,7 +183,7 @@ func userStoreTest(t *testing.T, newUserID int) {
expect(t, user.ID == newUserID, fmt.Sprintf("user.ID does not match the requested UID. Got '%d' instead.", user.ID)) expect(t, user.ID == newUserID, fmt.Sprintf("user.ID does not match the requested UID. Got '%d' instead.", user.ID))
} }
userList, _ = c.Users.BulkGetMap([]int{1,uid}) userList, _ = c.Users.BulkGetMap([]int{1, uid})
expect(t, len(userList) == 2, fmt.Sprintf("Returned map should have two results, not %d", len(userList))) expect(t, len(userList) == 2, fmt.Sprintf("Returned map should have two results, not %d", len(userList)))
if ucache != nil { if ucache != nil {
@ -597,16 +597,16 @@ func TestForumStore(t *testing.T) {
// Forum reload test, kind of hacky but gets the job done // Forum reload test, kind of hacky but gets the job done
/* /*
CacheGet(id int) (*Forum, error) CacheGet(id int) (*Forum, error)
CacheSet(forum *Forum) error CacheSet(forum *Forum) error
*/ */
expect(t,ok,"ForumCache should be available") expect(t, ok, "ForumCache should be available")
forum.Name = "nanana" forum.Name = "nanana"
fcache.CacheSet(forum) fcache.CacheSet(forum)
forum, err = c.Forums.Get(2) forum, err = c.Forums.Get(2)
recordMustExist(t, err, "Couldn't find FID #2") recordMustExist(t, err, "Couldn't find FID #2")
expect(t, forum.Name == "nanana", fmt.Sprintf("The faux name should be nanana not %s", forum.Name)) expect(t, forum.Name == "nanana", fmt.Sprintf("The faux name should be nanana not %s", forum.Name))
expectNilErr(t,c.Forums.Reload(2)) expectNilErr(t, c.Forums.Reload(2))
forum, err = c.Forums.Get(2) forum, err = c.Forums.Get(2)
recordMustExist(t, err, "Couldn't find FID #2") recordMustExist(t, err, "Couldn't find FID #2")
expect(t, forum.Name == "General", fmt.Sprintf("The proper name should be 2 not %s", forum.Name)) expect(t, forum.Name == "General", fmt.Sprintf("The proper name should be 2 not %s", forum.Name))
@ -731,23 +731,23 @@ func TestForumPermsStore(t *testing.T) {
} }
f := func(fid int, gid int, msg string, inv ...bool) { f := func(fid int, gid int, msg string, inv ...bool) {
fp, err := c.FPStore.Get(fid,gid) fp, err := c.FPStore.Get(fid, gid)
expectNilErr(t,err) expectNilErr(t, err)
vt := fp.ViewTopic vt := fp.ViewTopic
if len(inv) > 0 && inv[0] == true { if len(inv) > 0 && inv[0] == true {
vt = !vt vt = !vt
} }
expect(t,vt,msg) expect(t, vt, msg)
} }
initialState := func() { initialState := func() {
f(1,1,"admins should be able to see reports") f(1, 1, "admins should be able to see reports")
f(1,2,"mods should be able to see reports") f(1, 2, "mods should be able to see reports")
f(1,3,"members should not be able to see reports",true) f(1, 3, "members should not be able to see reports", true)
f(1,4,"banned users should not be able to see reports",true) f(1, 4, "banned users should not be able to see reports", true)
f(2,1,"admins should be able to see general") f(2, 1, "admins should be able to see general")
f(2,3,"members should be able to see general") f(2, 3, "members should be able to see general")
f(2,6,"guests should be able to see general") f(2, 6, "guests should be able to see general")
} }
initialState() initialState()
@ -778,7 +778,7 @@ func TestGroupStore(t *testing.T) {
group, err = c.Groups.Get(1) group, err = c.Groups.Get(1)
recordMustExist(t, err, "Couldn't find GID #1") recordMustExist(t, err, "Couldn't find GID #1")
expect(t, group.ID == 1, fmt.Sprintf("group.ID doesn't not match the requested GID. Got '%d' instead.'", group.ID)) expect(t, group.ID == 1, fmt.Sprintf("group.ID doesn't not match the requested GID. Got '%d' instead.'", group.ID))
expect(t,len(group.CanSee) > 0,"group.CanSee should not be zero") expect(t, len(group.CanSee) > 0, "group.CanSee should not be zero")
expect(t, !c.Groups.Exists(-1), "GID #-1 shouldn't exist") expect(t, !c.Groups.Exists(-1), "GID #-1 shouldn't exist")
// 0 aka Unknown, for system posts and other oddities // 0 aka Unknown, for system posts and other oddities
@ -889,7 +889,7 @@ func TestGroupStore(t *testing.T) {
return true return true
} }
expect(t, canSeeTest(group.CanSee,canSee), "group.CanSee is not being reused") expect(t, canSeeTest(group.CanSee, canSee), "group.CanSee is not being reused")
// TODO: Test group deletion // TODO: Test group deletion
// TODO: Test group reload // TODO: Test group reload
@ -1030,7 +1030,7 @@ func TestProfileReplyStore(t *testing.T) {
func TestActivityStream(t *testing.T) { func TestActivityStream(t *testing.T) {
miscinit(t) miscinit(t)
expect(t,c.Activity.Count()==0,"activity stream count should be 0") expect(t, c.Activity.Count() == 0, "activity stream count should be 0")
_, err := c.Activity.Get(-1) _, err := c.Activity.Get(-1)
recordMustNotExist(t, err, "activity item -1 shouldn't exist") recordMustNotExist(t, err, "activity item -1 shouldn't exist")
@ -1041,17 +1041,17 @@ func TestActivityStream(t *testing.T) {
a := c.Alert{ActorID: 1, TargetUserID: 1, Event: "like", ElementType: "topic", ElementID: 1} a := c.Alert{ActorID: 1, TargetUserID: 1, Event: "like", ElementType: "topic", ElementID: 1}
id, err := c.Activity.Add(a) id, err := c.Activity.Add(a)
expectNilErr(t,err) expectNilErr(t, err)
expect(t,id==1,"new activity item id should be 1") expect(t, id == 1, "new activity item id should be 1")
expect(t,c.Activity.Count()==1,"activity stream count should be 1") expect(t, c.Activity.Count() == 1, "activity stream count should be 1")
alert, err := c.Activity.Get(1) alert, err := c.Activity.Get(1)
expectNilErr(t,err) expectNilErr(t, err)
expect(t,alert.ActorID==1,"alert actorid should be 1") expect(t, alert.ActorID == 1, "alert actorid should be 1")
expect(t,alert.TargetUserID==1,"alert targetuserid should be 1") expect(t, alert.TargetUserID == 1, "alert targetuserid should be 1")
expect(t,alert.Event=="like","alert event type should be like") expect(t, alert.Event == "like", "alert event type should be like")
expect(t,alert.ElementType=="topic","alert element type should be topic") expect(t, alert.ElementType == "topic", "alert element type should be topic")
expect(t,alert.ElementID==1,"alert element id should be 1") expect(t, alert.ElementID == 1, "alert element id should be 1")
} }
func TestLogs(t *testing.T) { func TestLogs(t *testing.T) {
@ -1217,35 +1217,41 @@ func TestPluginManager(t *testing.T) {
expectNilErr(t, plugin.SetActive(false)) expectNilErr(t, plugin.SetActive(false))
// Hook tests // Hook tests
expect(t, c.GetHookTable().Sshook("haha", "ho") == "ho", "Sshook shouldn't have anything bound to it yet") ht := func() *c.HookTable {
return c.GetHookTable()
}
expect(t, ht().Sshook("haha", "ho") == "ho", "Sshook shouldn't have anything bound to it yet")
handle := func(in string) (out string) { handle := func(in string) (out string) {
return in + "hi" return in + "hi"
} }
plugin.AddHook("haha", handle) plugin.AddHook("haha", handle)
expect(t, c.GetHookTable().Sshook("haha", "ho") == "hohi", "Sshook didn't give hohi") expect(t, ht().Sshook("haha", "ho") == "hohi", "Sshook didn't give hohi")
plugin.RemoveHook("haha", handle) plugin.RemoveHook("haha", handle)
expect(t, c.GetHookTable().Sshook("haha", "ho") == "ho", "Sshook shouldn't have anything bound to it anymore") expect(t, ht().Sshook("haha", "ho") == "ho", "Sshook shouldn't have anything bound to it anymore")
expect(t, c.GetHookTable().Hook("haha", "ho") == "ho", "Hook shouldn't have anything bound to it yet") expect(t, ht().Hook("haha", "ho") == "ho", "Hook shouldn't have anything bound to it yet")
handle2 := func(inI interface{}) (out interface{}) { handle2 := func(inI interface{}) (out interface{}) {
return inI.(string) + "hi" return inI.(string) + "hi"
} }
plugin.AddHook("hehe", handle2) plugin.AddHook("hehe", handle2)
expect(t, c.GetHookTable().Hook("hehe", "ho").(string) == "hohi", "Hook didn't give hohi") expect(t, ht().Hook("hehe", "ho").(string) == "hohi", "Hook didn't give hohi")
plugin.RemoveHook("hehe", handle2) plugin.RemoveHook("hehe", handle2)
expect(t, c.GetHookTable().Hook("hehe", "ho").(string) == "ho", "Hook shouldn't have anything bound to it anymore") expect(t, ht().Hook("hehe", "ho").(string) == "ho", "Hook shouldn't have anything bound to it anymore")
// TODO: Add tests for more hook types // TODO: Add tests for more hook types
} }
func TestPhrases(t *testing.T) { func TestPhrases(t *testing.T) {
getPhrase := phrases.GetGlobalPermPhrase
tp := func(name string, expects string) { tp := func(name string, expects string) {
expect(t, phrases.GetGlobalPermPhrase(name) == expects, "Not the expected phrase") res := getPhrase(name)
expect(t, res == expects, "Not the expected phrase, got '"+res+"' instead")
} }
tp("BanUsers","Can ban users") tp("BanUsers", "Can ban users")
tp("NoSuchPerm","{lang.perms[NoSuchPerm]}") tp("NoSuchPerm", "{lang.perms[NoSuchPerm]}")
tp("ViewTopic","Can view topics") getPhrase = phrases.GetLocalPermPhrase
tp("NoSuchPerm","{lang.perms[NoSuchPerm]}") tp("ViewTopic", "Can view topics")
tp("NoSuchPerm", "{lang.perms[NoSuchPerm]}")
// TODO: Cover the other phrase types, also try switching between languages to see if anything strange happens // TODO: Cover the other phrase types, also try switching between languages to see if anything strange happens
} }

View File

@ -143,6 +143,7 @@ func TestParser(t *testing.T) {
l := &METriList{nil} l := &METriList{nil}
url := "github.com/Azareal/Gosora" url := "github.com/Azareal/Gosora"
eurl := "<a rel='ugc' href='//" + url + "'>//" + url + "</a>"
l.Add("", "") l.Add("", "")
l.Add("haha", "haha") l.Add("haha", "haha")
l.Add("<b>t</b>", "<b>t</b>") l.Add("<b>t</b>", "<b>t</b>")
@ -183,7 +184,7 @@ func TestParser(t *testing.T) {
l.Add("gi", "gi") l.Add("gi", "gi")
l.Add("ss", "ss") l.Add("ss", "ss")
l.Add("haha\nhaha\nhaha", "haha<br>haha<br>haha") l.Add("haha\nhaha\nhaha", "haha<br>haha<br>haha")
l.Add("//"+url, "<a rel='ugc' href='//"+url+"'>//"+url+"</a>") l.Add("//"+url, eurl)
l.Add("//a", "<a rel='ugc' href='//a'>//a</a>") l.Add("//a", "<a rel='ugc' href='//a'>//a</a>")
l.Add(" //a", " <a rel='ugc' href='//a'>//a</a>") l.Add(" //a", " <a rel='ugc' href='//a'>//a</a>")
l.Add("//a ", "<a rel='ugc' href='//a'>//a</a> ") l.Add("//a ", "<a rel='ugc' href='//a'>//a</a> ")
@ -191,16 +192,16 @@ func TestParser(t *testing.T) {
l.Add("d //a ", "d <a rel='ugc' href='//a'>//a</a> ") l.Add("d //a ", "d <a rel='ugc' href='//a'>//a</a> ")
l.Add("ddd ddd //a ", "ddd ddd <a rel='ugc' href='//a'>//a</a> ") l.Add("ddd ddd //a ", "ddd ddd <a rel='ugc' href='//a'>//a</a> ")
l.Add("https://"+url, "<a rel='ugc' href='https://"+url+"'>https://"+url+"</a>") l.Add("https://"+url, "<a rel='ugc' href='https://"+url+"'>https://"+url+"</a>")
l.Add("https://t", "<a href='https://t'>https://t</a>") l.Add("https://t", "<a rel='ugc' href='https://t'>https://t</a>")
l.Add("http://"+url, "<a href='http://"+url+"'>http://"+url+"</a>") l.Add("http://"+url, "<a rel='ugc' href='http://"+url+"'>http://"+url+"</a>")
l.Add("#http://"+url, "#http://"+url) l.Add("#http://"+url, "#http://"+url)
l.Add("@http://"+url, "<red>[Invalid Profile]</red>ttp://"+url) l.Add("@http://"+url, "<red>[Invalid Profile]</red>ttp://"+url)
l.Add("//"+url+"\n", "<a href='//"+url+"'>//"+url+"</a><br>") l.Add("//"+url+"\n", "<a rel='ugc' href='//"+url+"'>//"+url+"</a><br>")
l.Add("\n//"+url, "<br><a href='//"+url+"'>//"+url+"</a>") l.Add("\n//"+url, "<br>"+eurl)
l.Add("\n//"+url+"\n", "<br><a href='//"+url+"'>//"+url+"</a><br>") l.Add("\n//"+url+"\n", "<br>"+eurl+"<br>")
l.Add("\n//"+url+"\n\n", "<br><a href='//"+url+"'>//"+url+"</a><br><br>") l.Add("\n//"+url+"\n\n", "<br>"+eurl+"<br><br>")
l.Add("//"+url+"\n//"+url, "<a href='//"+url+"'>//"+url+"</a><br><a href='//"+url+"'>//"+url+"</a>") l.Add("//"+url+"\n//"+url, eurl+"<br>"+eurl)
l.Add("//"+url+"\n\n//"+url, "<a href='//"+url+"'>//"+url+"</a><br><br><a href='//"+url+"'>//"+url+"</a>") l.Add("//"+url+"\n\n//"+url, eurl+"<br><br>"+eurl)
l.Add("//"+c.Site.URL, "<a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a>") l.Add("//"+c.Site.URL, "<a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a>")
l.Add("//"+c.Site.URL+"\n", "<a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a><br>") l.Add("//"+c.Site.URL+"\n", "<a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a><br>")
l.Add("//"+c.Site.URL+"\n//"+c.Site.URL, "<a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a><br><a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a>") l.Add("//"+c.Site.URL+"\n//"+c.Site.URL, "<a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a><br><a href='//"+c.Site.URL+"'>//"+c.Site.URL+"</a>")
@ -214,24 +215,24 @@ func TestParser(t *testing.T) {
local("127.0.0.1") local("127.0.0.1")
local("[::1]") local("[::1]")
l.Add("https://www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>") l.Add("https://www.youtube.com/watch?v=lalalalala", "<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
//l.Add("https://www.youtube.com/watch?v=;","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/;' frameborder=0 allowfullscreen></iframe>") //l.Add("https://www.youtube.com/watch?v=;","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/;' frameborder=0 allowfullscreen></iframe>")
l.Add("https://www.youtube.com/watch?v=d;","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/d' frameborder=0 allowfullscreen></iframe>") l.Add("https://www.youtube.com/watch?v=d;", "<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/d' frameborder=0 allowfullscreen></iframe>")
l.Add("https://www.youtube.com/watch?v=d;d","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/d' frameborder=0 allowfullscreen></iframe>") l.Add("https://www.youtube.com/watch?v=d;d", "<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/d' frameborder=0 allowfullscreen></iframe>")
l.Add("https://www.youtube.com/watch?v=alert()","<red>[Invalid URL]</red>()") l.Add("https://www.youtube.com/watch?v=alert()", "<red>[Invalid URL]</red>()")
l.Add("https://www.youtube.com/watch?v=alert()()","<red>[Invalid URL]</red>()()") l.Add("https://www.youtube.com/watch?v=alert()()", "<red>[Invalid URL]</red>()()")
l.Add("https://www.youtube.com/watch?v=js:alert()","<red>[Invalid URL]</red>()") l.Add("https://www.youtube.com/watch?v=js:alert()", "<red>[Invalid URL]</red>()")
l.Add("https://www.youtube.com/watch?v='+><script>alert(\"\")</script><+'","<red>[Invalid URL]</red>'+><script>alert(\"\")</script><+'") l.Add("https://www.youtube.com/watch?v='+><script>alert(\"\")</script><+'", "<red>[Invalid URL]</red>'+><script>alert(\"\")</script><+'")
l.Add("https://www.youtube.com/watch?v='+onready='alert(\"\")'+'","<red>[Invalid URL]</red>'+onready='alert(\"\")'+'") l.Add("https://www.youtube.com/watch?v='+onready='alert(\"\")'+'", "<red>[Invalid URL]</red>'+onready='alert(\"\")'+'")
l.Add(" https://www.youtube.com/watch?v=lalalalala"," <iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>") l.Add(" https://www.youtube.com/watch?v=lalalalala", " <iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("https://www.youtube.com/watch?v=lalalalala tt","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe> tt") l.Add("https://www.youtube.com/watch?v=lalalalala tt", "<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe> tt")
l.Add("https://www.youtube.com/watch?v=lalalalala&d=haha","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>") l.Add("https://www.youtube.com/watch?v=lalalalala&d=haha", "<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("https://gaming.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>") l.Add("https://gaming.youtube.com/watch?v=lalalalala", "<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("https://gaming.youtube.com/watch?v=lalalalala&d=haha","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>") l.Add("https://gaming.youtube.com/watch?v=lalalalala&d=haha", "<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("https://m.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>") l.Add("https://m.youtube.com/watch?v=lalalalala", "<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("https://m.youtube.com/watch?v=lalalalala&d=haha","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>") l.Add("https://m.youtube.com/watch?v=lalalalala&d=haha", "<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("http://www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>") l.Add("http://www.youtube.com/watch?v=lalalalala", "<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("//www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>") l.Add("//www.youtube.com/watch?v=lalalalala", "<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
//l.Add("www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>") //l.Add("www.youtube.com/watch?v=lalalalala","<iframe class='postIframe' src='https://www.youtube-nocookie.com/embed/lalalalala' frameborder=0 allowfullscreen></iframe>")
l.Add("#tid-1", "<a href='/topic/1'>#tid-1</a>") l.Add("#tid-1", "<a href='/topic/1'>#tid-1</a>")
@ -242,8 +243,8 @@ func TestParser(t *testing.T) {
l.Add("@ #tid-@", "<red>[Invalid Profile]</red>#tid-@") l.Add("@ #tid-@", "<red>[Invalid Profile]</red>#tid-@")
l.Add("#tid-1 #tid-1", "<a href='/topic/1'>#tid-1</a> <a href='/topic/1'>#tid-1</a>") l.Add("#tid-1 #tid-1", "<a href='/topic/1'>#tid-1</a> <a href='/topic/1'>#tid-1</a>")
l.Add("#tid-0", "<red>[Invalid Topic]</red>") l.Add("#tid-0", "<red>[Invalid Topic]</red>")
l.Add("https://"+url+"/#tid-1", "<a href='https://"+url+"/#tid-1'>https://"+url+"/#tid-1</a>") l.Add("https://"+url+"/#tid-1", "<a rel='ugc' href='https://"+url+"/#tid-1'>https://"+url+"/#tid-1</a>")
l.Add("https://"+url+"/?hi=2", "<a href='https://"+url+"/?hi=2'>https://"+url+"/?hi=2</a>") l.Add("https://"+url+"/?hi=2", "<a rel='ugc' href='https://"+url+"/?hi=2'>https://"+url+"/?hi=2</a>")
l.Add("#fid-1", "<a href='/forum/1'>#fid-1</a>") l.Add("#fid-1", "<a href='/forum/1'>#fid-1</a>")
l.Add(" #fid-1", " <a href='/forum/1'>#fid-1</a>") l.Add(" #fid-1", " <a href='/forum/1'>#fid-1</a>")
l.Add("#fid-0", "<red>[Invalid Forum]</red>") l.Add("#fid-0", "<red>[Invalid Forum]</red>")

View File

@ -60,8 +60,8 @@ func bbcodeRegexParse(msg string) string {
msg = bbcodeItalic.ReplaceAllString(msg, "<i>$1</i>") msg = bbcodeItalic.ReplaceAllString(msg, "<i>$1</i>")
msg = bbcodeUnderline.ReplaceAllString(msg, "<u>$1</u>") msg = bbcodeUnderline.ReplaceAllString(msg, "<u>$1</u>")
msg = bbcodeStrike.ReplaceAllString(msg, "<s>$1</s>") msg = bbcodeStrike.ReplaceAllString(msg, "<s>$1</s>")
msg = bbcodeURL.ReplaceAllString(msg, "<a href=''$1$2//$3' rel='nofollow'>$1$2//$3</i>") msg = bbcodeURL.ReplaceAllString(msg, "<a href=''$1$2//$3' rel='ugc'>$1$2//$3</i>")
msg = bbcodeURLLabel.ReplaceAllString(msg, "<a href=''$1$2//$3' rel='nofollow'>$4</i>") msg = bbcodeURLLabel.ReplaceAllString(msg, "<a href=''$1$2//$3' rel='ugc'>$4</i>")
msg = bbcodeQuotes.ReplaceAllString(msg, "<blockquote>$1</blockquote>") msg = bbcodeQuotes.ReplaceAllString(msg, "<blockquote>$1</blockquote>")
msg = bbcodeH1.ReplaceAllString(msg, "<h2>$1</h2>") msg = bbcodeH1.ReplaceAllString(msg, "<h2>$1</h2>")
//msg = bbcodeCode.ReplaceAllString(msg,"<span class='codequotes'>$1</span>") //msg = bbcodeCode.ReplaceAllString(msg,"<span class='codequotes'>$1</span>")
@ -198,8 +198,8 @@ func bbcodeParseWithoutCode(msg string) string {
// Copy the new complex parser over once the rough edges have been smoothed over // Copy the new complex parser over once the rough edges have been smoothed over
if complexBbc { if complexBbc {
msg = string(msgbytes) msg = string(msgbytes)
msg = bbcodeURL.ReplaceAllString(msg, "<a href='$1$2//$3' rel='nofollow'>$1$2//$3</i>") msg = bbcodeURL.ReplaceAllString(msg, "<a href='$1$2//$3' rel='ugc'>$1$2//$3</i>")
msg = bbcodeURLLabel.ReplaceAllString(msg, "<a href='$1$2//$3' rel='nofollow'>$4</i>") msg = bbcodeURLLabel.ReplaceAllString(msg, "<a href='$1$2//$3' rel='ugc'>$4</i>")
msg = bbcodeQuotes.ReplaceAllString(msg, "<blockquote>$1</blockquote>") msg = bbcodeQuotes.ReplaceAllString(msg, "<blockquote>$1</blockquote>")
return bbcodeCode.ReplaceAllString(msg, "<span class='codequotes'>$1</span>") return bbcodeCode.ReplaceAllString(msg, "<span class='codequotes'>$1</span>")
} }
@ -325,8 +325,8 @@ func bbcodeFullParse(msg string) string {
} }
// TODO: Optimise these // TODO: Optimise these
//msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>") //msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"ugc\">$1$2//$3</i>")
msg = bbcodeURLLabel.ReplaceAllString(msg, "<a href='$1$2//$3' rel='nofollow'>$4</i>") msg = bbcodeURLLabel.ReplaceAllString(msg, "<a href='$1$2//$3' rel='ugc'>$4</i>")
msg = bbcodeQuotes.ReplaceAllString(msg, "<blockquote>$1</blockquote>") msg = bbcodeQuotes.ReplaceAllString(msg, "<blockquote>$1</blockquote>")
msg = bbcodeCode.ReplaceAllString(msg, "<span class='codequotes'>$1</span>") msg = bbcodeCode.ReplaceAllString(msg, "<span class='codequotes'>$1</span>")
msg = bbcodeH1.ReplaceAllString(msg, "<h2>$1</h2>") msg = bbcodeH1.ReplaceAllString(msg, "<h2>$1</h2>")