Skip to content

Commit

Permalink
🔄 Sync from monorepo
Browse files Browse the repository at this point in the history
  • Loading branch information
mojo-machine[bot] committed Mar 20, 2024
1 parent 25b41a8 commit 17e8524
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 11 deletions.
7 changes: 4 additions & 3 deletions lib/discourse/discourse.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package discourse

import (
"net/http"
"net/url"
"time"

"github.com/wearemojo/mojo-public-go/lib/httpclient"
Expand All @@ -12,12 +13,12 @@ import (
const ErrEmptyParam = merr.Code("empty_param")

type Client struct {
BaseURL string
BaseURL *url.URL

apiKey string
}

func NewClient(baseURL, apiKey string) *Client {
func NewClient(baseURL *url.URL, apiKey string) *Client {
return &Client{
BaseURL: baseURL,

Expand All @@ -32,7 +33,7 @@ type IdentifiedClient struct {
func (c *Client) identifiedClient(header http.Header) *IdentifiedClient {
return &IdentifiedClient{
client: jsonclient.NewClient(
c.BaseURL,
c.BaseURL.String(),
httpclient.NewClient(10*time.Second, roundTripper{header}),
),
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package discourseemoji

import (
"net/url"
"slices"
"strings"

"github.com/wearemojo/mojo-public-go/lib/slicefn"
"golang.org/x/net/html"
)

func ReplaceHTMLImagesWithEmojis(src string) (string, error) {
func UnmungeCookedHTML(src string, baseURL *url.URL) (string, error) {
doc, err := html.Parse(strings.NewReader(src))
if err != nil {
return "", err
Expand All @@ -17,9 +18,17 @@ func ReplaceHTMLImagesWithEmojis(src string) (string, error) {
var body *html.Node
var fn func(*html.Node) *html.Node
fn = func(node *html.Node) *html.Node {
if node.Type == html.ElementNode && node.Data == "body" {
switch {
case node.Type == html.ElementNode && node.Data == "body":
body = node
} else if node.Type == html.ElementNode && node.Data == "img" {
case node.Type == html.ElementNode && node.Data == "a" && baseURL != nil:
if idx := slicefn.FindIndex(node.Attr, func(a html.Attribute) bool { return a.Key == "href" }); idx != -1 {
if url, _ := url.Parse(node.Attr[idx].Val); url != nil {
url = baseURL.ResolveReference(url)
node.Attr[idx].Val = url.String()
}
}
case node.Type == html.ElementNode && node.Data == "img":
class, ok1 := slicefn.Find(node.Attr, func(a html.Attribute) bool { return a.Key == "class" })
alt, ok2 := slicefn.Find(node.Attr, func(a html.Attribute) bool { return a.Key == "alt" })
shortcode, ok3 := strings.CutPrefix(alt.Val, ":")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,55 @@
package discourseemoji

import (
"net/url"
"strings"
"testing"

"github.com/matryer/is"
)

func TestReplaceHTMLImagesWithEmojis(t *testing.T) {
func urlMustParse(s string) *url.URL {
u, err := url.Parse(s)
if err != nil {
panic(err)
}
return u
}

func TestUnmungeCookedHTML(t *testing.T) {
tests := []struct {
name string
input string
expected string
name string
inputBaseURL *url.URL
inputSource string
expected string
}{
{
"upside_down_face",
nil,
`<img src="https://emoji.discourse-cdn.com/twitter/upside_down_face.png?v=12" title=":upside_down_face:" class="emoji" alt=":upside_down_face:" loading="lazy" width="20" height="20">`,
"🙃",
},
{
"only-emoji end",
nil,
`<img src="https://emoji.discourse-cdn.com/twitter/upside_down_face.png?v=12" title=":upside_down_face:" class="emoji only-emoji" alt=":upside_down_face:" loading="lazy" width="20" height="20">`,
"🙃",
},
{
"only-emoji start",
nil,
`<img src="https://emoji.discourse-cdn.com/twitter/upside_down_face.png?v=12" title=":upside_down_face:" class="only-emoji emoji" alt=":upside_down_face:" loading="lazy" width="20" height="20">`,
"🙃",
},
{
"only-only-emoji",
nil,
`<img src="https://emoji.discourse-cdn.com/twitter/upside_down_face.png?v=12" title=":upside_down_face:" class="only-emoji" alt=":upside_down_face:" loading="lazy" width="20" height="20">`,
`<img src="https://emoji.discourse-cdn.com/twitter/upside_down_face.png?v=12" title=":upside_down_face:" class="only-emoji" alt=":upside_down_face:" loading="lazy" width="20" height="20"/>`,
},
{
"two paragraphs",
nil,
strings.TrimSpace(`
<p>
<img src="https://emoji.discourse-cdn.com/twitter/upside_down_face.png?v=12" title=":upside_down_face:" class="emoji" alt=":upside_down_face:" loading="lazy" width="20" height="20">
Expand Down Expand Up @@ -76,6 +91,7 @@ func TestReplaceHTMLImagesWithEmojis(t *testing.T) {
},
{
"unrecognized",
nil,
strings.TrimSpace(`
<p>
<img src="https://emoji.discourse-cdn.com/twitter/upside_down_face.png?v=12" title=":upside_down_face:" class="emoji" alt=":upside_down_face:" loading="lazy" width="20" height="20">
Expand All @@ -91,13 +107,71 @@ func TestReplaceHTMLImagesWithEmojis(t *testing.T) {
</p>
`),
},
{
"urls",
nil,
strings.TrimSpace(`
<p>
<img src="https://emoji.discourse-cdn.com/twitter/upside_down_face.png?v=12" title=":upside_down_face:" class="emoji" alt=":upside_down_face:" loading="lazy" width="20" height="20">
<img src="https://emoji.discourse-cdn.com/blah/raised_back_of_hand/2.png?v=12" title=":blah:t2:" class="emoji" alt=":blah:t2:" loading="lazy" width="20" height="20">
<img src="https://emoji.discourse-cdn.com/apple/cold_face.png?v=12" title=":cold_face:" class="emoji" alt=":cold_face:" loading="lazy" width="20" height="20">
</p>
`),
strings.TrimSpace(`
<p>
🙃
<img src="https://emoji.discourse-cdn.com/blah/raised_back_of_hand/2.png?v=12" title=":blah:t2:" class="emoji" alt=":blah:t2:" loading="lazy" width="20" height="20"/>
🥶
</p>
`),
},
{
"preserves links without a base URL",
nil,
strings.TrimSpace(`
<a href="https://example.com">example</a>
<a href="/relative">relative</a>
<a href="anchor">anchor</a>
<a href="mailto:[email protected]">email</a>
<a href="?query">query</a>
<a href="#fragment">fragment</a>
`),
strings.TrimSpace(`
<a href="https://example.com">example</a>
<a href="/relative">relative</a>
<a href="anchor">anchor</a>
<a href="mailto:[email protected]">email</a>
<a href="?query">query</a>
<a href="#fragment">fragment</a>
`),
},
{
"updates links correctly with a base URL",
urlMustParse("https://example.invalid/testing/foo"),
strings.TrimSpace(`
<a href="https://example.com">example</a>
<a href="/relative">relative</a>
<a href="anchor">anchor</a>
<a href="mailto:[email protected]">email</a>
<a href="?query">query</a>
<a href="#fragment">fragment</a>
`),
strings.TrimSpace(`
<a href="https://example.com">example</a>
<a href="https://example.invalid/relative">relative</a>
<a href="https://example.invalid/testing/anchor">anchor</a>
<a href="mailto:[email protected]">email</a>
<a href="https://example.invalid/testing/foo?query">query</a>
<a href="https://example.invalid/testing/foo#fragment">fragment</a>
`),
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
is := is.New(t)

res, err := ReplaceHTMLImagesWithEmojis(test.input)
res, err := UnmungeCookedHTML(test.inputSource, test.inputBaseURL)

is.NoErr(err)
is.Equal(res, test.expected)
Expand Down

0 comments on commit 17e8524

Please sign in to comment.