initial commits
parent
26e17cae3d
commit
c2f05438b2
|
@ -0,0 +1,70 @@
|
|||
package frameproto
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
const skeleFrameTop =
|
||||
`<!DOCTYPE html>`+"\n"+
|
||||
`<html xmlns="http://www.w3.org/1999/xhtml">`+"\n"+
|
||||
`<head>`+"\n"+
|
||||
`<meta charset="utf-8" />`+"\n"
|
||||
|
||||
const skeleFrameBotton =
|
||||
`</head>`+"\n"+
|
||||
`<body>`+"\n"+
|
||||
`</body>`+"\n"+
|
||||
`</html>`+"\n"
|
||||
|
||||
// WriteSkeleFrame takes care of creating a skeleton-HTML-page that the Frame-Protocol's (i.e., Farcaster Frame's) tags are included in.
|
||||
//
|
||||
// For example, this:
|
||||
//
|
||||
// frameproto.WriteSkeleFrame(w, func(writer io.Writer){
|
||||
//
|
||||
// // This will write:
|
||||
// // <meta property="fc:frame" content="vNext" />
|
||||
// frameproto.WriteFrame(writer, frameproto.VersionVNext)
|
||||
//
|
||||
// // This will write:
|
||||
// <meta property="fc:frame:image" content="https://example.com/path/to/img.png" />
|
||||
// var imgURL string = "https://example.com/path/to/img.png"
|
||||
// frameproto.WriteFrameImage(writer, imgURL)
|
||||
// })
|
||||
//
|
||||
// Would write this:
|
||||
//
|
||||
// <!DOCTYPE html>
|
||||
// <html xmlns="http://www.w3.org/1999/xhtml">
|
||||
// <head>
|
||||
// <meta charset="utf-8" /
|
||||
// <meta property="fc:frame" content="vNext" />
|
||||
// <meta property="fc:frame:image" content="https://example.com/path/to/img.png" />
|
||||
// </head>
|
||||
// <body>
|
||||
// </body>
|
||||
// </html>
|
||||
//
|
||||
// Note that http.ResponseWriter is an io.Writer. So this function can be used to write to http.ResponseWriter.
|
||||
func WriteSkeleFrame(writer io.Writer, frameWriterFunc func(io.Writer)error) error {
|
||||
|
||||
var err error
|
||||
|
||||
_, err = io.WriteString(writer, skeleFrameTop)
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
|
||||
err = frameWriterFunc(writer)
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.WriteString(writer, skeleFrameBotton)
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
|
||||
package frameproto
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func TestWriteSkeleFrame(t *testing.T) {
|
||||
|
||||
tests := []struct{
|
||||
Head string
|
||||
Expected string
|
||||
}{
|
||||
{
|
||||
Head: "",
|
||||
Expected:
|
||||
`<!DOCTYPE html>`+"\n"+
|
||||
`<html xmlns="http://www.w3.org/1999/xhtml" lang="en">`+"\n"+
|
||||
`<head>`+"\n"+
|
||||
`<meta charset="utf-8" />`+"\n"+
|
||||
`</head>`+"\n"+
|
||||
`<body>`+"\n"+
|
||||
`</body>`+"\n"+
|
||||
`</html>`+"\n",
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
Head: `<!-- Hello world! -->`+"\n",
|
||||
Expected:
|
||||
`<!DOCTYPE html>`+"\n"+
|
||||
`<html xmlns="http://www.w3.org/1999/xhtml" lang="en">`+"\n"+
|
||||
`<head>`+"\n"+
|
||||
`<meta charset="utf-8" />`+"\n"+
|
||||
|
||||
`<!-- Hello world! -->`+"\n"+
|
||||
|
||||
`</head>`+"\n"+
|
||||
`<body>`+"\n"+
|
||||
`</body>`+"\n"+
|
||||
`</html>`+"\n",
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
Head: `<meta property="hello" content="world" />`+"\n",
|
||||
Expected:
|
||||
`<!DOCTYPE html>`+"\n"+
|
||||
`<html xmlns="http://www.w3.org/1999/xhtml" lang="en">`+"\n"+
|
||||
`<head>`+"\n"+
|
||||
`<meta charset="utf-8" />`+"\n"+
|
||||
|
||||
`<meta property="hello" content="world" />`+"\n"+
|
||||
|
||||
`</head>`+"\n"+
|
||||
`<body>`+"\n"+
|
||||
`</body>`+"\n"+
|
||||
`</html>`+"\n",
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
Head:
|
||||
`<meta property="fc:frame" content="vNext" />`+"\n"+
|
||||
`<meta property="fc:frame:image" content="https://example.com/path/to/img.png" />`+"\n"+
|
||||
`<meta property="og:image" content="https://example.com/path/to/img.png" />`+"\n",
|
||||
Expected:
|
||||
`<!DOCTYPE html>`+"\n"+
|
||||
`<html xmlns="http://www.w3.org/1999/xhtml" lang="en">`+"\n"+
|
||||
`<head>`+"\n"+
|
||||
`<meta charset="utf-8" />`+"\n"+
|
||||
|
||||
`<meta property="fc:frame" content="vNext" />`+"\n"+
|
||||
`<meta property="fc:frame:image" content="https://example.com/path/to/img.png" />`+"\n"+
|
||||
`<meta property="og:image" content="https://example.com/path/to/img.png" />`+"\n"+
|
||||
|
||||
`</head>`+"\n"+
|
||||
`<body>`+"\n"+
|
||||
`</body>`+"\n"+
|
||||
`</html>`+"\n",
|
||||
},
|
||||
}
|
||||
|
||||
for testNumber, test := range tests {
|
||||
|
||||
var buffer strings.Builder
|
||||
|
||||
WriteSkeleFrame(&buffer, func(writer io.Writer)error {
|
||||
io.WriteString(writer, test.Head)
|
||||
return nil
|
||||
})
|
||||
|
||||
expected := test.Expected
|
||||
actual := buffer.String()
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("For test #%d, ", testNumber)
|
||||
t.Logf("EXPECTED:\n%s", expected)
|
||||
t.Logf("ACTUAL:\n%s", actual)
|
||||
t.Logf("EXPECTED: %q", expected)
|
||||
t.Logf("ACTUAL: %q", actual)
|
||||
t.Logf("HEAD:\n%s", test.Head)
|
||||
t.Logf("HEAD: %q", test.Head)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue