api tests added
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
dump.rdb
|
||||
bin/
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
database.sqlite-journal
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"plugins": {
|
||||
"node": {}
|
||||
},
|
||||
"libs": [
|
||||
"ecma5",
|
||||
"ecma6"
|
||||
],
|
||||
"ecmaVersion": 6
|
||||
}
|
||||
Generated
+1
-1
@@ -76,6 +76,6 @@
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "82edf4a4585c9ad3318ead49e58d8bca7efed18e2f727be8e8fc6498972fc039"
|
||||
inputs-digest = "441429b4f331d40009b166378491cbd1b7e797135151d16d79394725cfbe16a2"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
var frisby = require('frisby');
|
||||
|
||||
frisby.create('Landing page')
|
||||
.get('http://localhost:3000/')
|
||||
.expectStatus(200)
|
||||
.expectHeaderContains('content-type', 'text/html; charset=utf-8')
|
||||
.expectBodyContains('Markdown Publishing')
|
||||
.toss();
|
||||
|
||||
frisby.create('Open note page')
|
||||
.get('http://localhost:3000/new')
|
||||
.expectStatus(200)
|
||||
.expectHeaderContains('content-type', 'text/html; charset=utf-8')
|
||||
.expectBodyContains('Terms of Service')
|
||||
.toss();
|
||||
|
||||
frisby.create('Open TOS')
|
||||
.get('http://localhost:3000/TOS.md')
|
||||
.expectStatus(200)
|
||||
.expectHeaderContains('content-type', 'text/html; charset=utf-8')
|
||||
.expectBodyContains('Site Terms of Use Modifications')
|
||||
.toss();
|
||||
|
||||
frisby.create('Incurrect URL')
|
||||
.get('http://localhost:3000/abcdef')
|
||||
.expectStatus(404)
|
||||
.expectBodyContains('Not found')
|
||||
.toss();
|
||||
|
||||
frisby.create('Invalid posting 1')
|
||||
.post('http://localhost:3000/note')
|
||||
.expectStatus(412)
|
||||
.expectHeaderContains('content-type', 'text/html; charset=utf-8')
|
||||
.expectBodyContains('Precondition failed')
|
||||
.toss();
|
||||
|
||||
frisby.create('Invalid posting 2')
|
||||
.post('http://localhost:3000/note', { tos: "on" })
|
||||
.expectStatus(400)
|
||||
.expectHeaderContains('content-type', 'text/html; charset=utf-8')
|
||||
.expectBodyContains('Bad request')
|
||||
.toss();
|
||||
|
||||
frisby.create('Invalid posting 3')
|
||||
.post('http://localhost:3000/note', {
|
||||
text: "too short",
|
||||
password: '',
|
||||
tos: 'on',
|
||||
})
|
||||
.expectStatus(400)
|
||||
.expectHeaderContains('content-type', 'text/html; charset=utf-8')
|
||||
.expectBodyContains('length not accepted')
|
||||
.toss();
|
||||
|
||||
let testNote = 'This is a test note';
|
||||
|
||||
frisby.create('Invalid posting 4')
|
||||
.post('http://localhost:3000/note', {
|
||||
note: testNote
|
||||
})
|
||||
.expectStatus(412)
|
||||
.expectHeaderContains('content-type', 'text/html; charset=utf-8')
|
||||
.expectBodyContains('Precondition failed')
|
||||
.toss();
|
||||
|
||||
frisby.create('Valid posting')
|
||||
.post('http://localhost:3000/note', {
|
||||
password: '',
|
||||
tos: 'on',
|
||||
text: testNote
|
||||
})
|
||||
.expectStatus(301)
|
||||
.expectHeaderContains('content-type', 'text/plain; charset=utf-8')
|
||||
.expectHeaderContains('Location', '/')
|
||||
.after(function(err, res, body) {
|
||||
let noteId = res.headers.location.replace('/', '');
|
||||
frisby.create('Read posted note')
|
||||
.get('http://localhost:3000/' + noteId)
|
||||
.expectStatus(200)
|
||||
.expectBodyContains(testNote)
|
||||
.after((err, res, body) => {
|
||||
frisby.create('Illegal note editing attempt with empty password')
|
||||
.post('http://localhost:3000/note', {
|
||||
id: noteId,
|
||||
tos: 'on',
|
||||
action: 'UPDATE',
|
||||
text: testNote + '!!!',
|
||||
password: ''
|
||||
})
|
||||
.expectStatus(400)
|
||||
.expectBodyContains('password is empty')
|
||||
.toss();
|
||||
})
|
||||
.after((err, res, body) => {
|
||||
frisby.create('Illegal note editing attempt')
|
||||
.post('http://localhost:3000/note', {
|
||||
id: noteId,
|
||||
tos: 'on',
|
||||
action: 'UPDATE',
|
||||
text: testNote + '!!!',
|
||||
password: 'aaabbb'
|
||||
})
|
||||
.expectStatus(401)
|
||||
.expectBodyContains('id or password is wrong')
|
||||
.toss();
|
||||
|
||||
})
|
||||
.toss();
|
||||
})
|
||||
.toss();
|
||||
|
||||
frisby.create('Valid posting, editing and more')
|
||||
.post('http://localhost:3000/note', {
|
||||
password: 'aabbcc',
|
||||
tos: 'on',
|
||||
text: testNote
|
||||
})
|
||||
.expectStatus(301)
|
||||
.expectHeaderContains('Location', '/')
|
||||
.expectHeaderContains('content-type', 'text/plain; charset=utf-8')
|
||||
.after(function(err, res, body) {
|
||||
let noteId = res.headers.location.replace('/', '');
|
||||
frisby.create('Export posted note')
|
||||
.get('http://localhost:3000/' + noteId + '/export')
|
||||
.expectStatus(200)
|
||||
.expectHeaderContains('content-type', 'text/plain; charset=utf-8')
|
||||
.expectBodyContains(testNote)
|
||||
.toss();
|
||||
frisby.create('Read posted note')
|
||||
.get('http://localhost:3000/' + noteId)
|
||||
.expectStatus(200)
|
||||
.expectBodyContains(testNote)
|
||||
.expectHeaderContains('content-type', 'text/html; charset=utf-8')
|
||||
.after((err, res, body) => {
|
||||
frisby.create('Unauthorized note editing attempt')
|
||||
.post('http://localhost:3000/note', {
|
||||
id: noteId,
|
||||
tos: 'on',
|
||||
text: testNote + '!!!',
|
||||
password: 'abbcc'
|
||||
})
|
||||
.expectStatus(401)
|
||||
.expectBodyContains('password is wrong')
|
||||
.toss();
|
||||
})
|
||||
.after((err, res, body) => {
|
||||
frisby.create('Valid note editing attempt')
|
||||
.post('http://localhost:3000/note', {
|
||||
id: noteId,
|
||||
tos: 'on',
|
||||
text: 'Changed text!',
|
||||
password: 'aabbcc'
|
||||
})
|
||||
.expectStatus(301)
|
||||
.after((err, res, body) => {
|
||||
frisby.create('Read changed note')
|
||||
.get('http://localhost:3000/' + noteId)
|
||||
.expectStatus(200)
|
||||
.expectBodyContains('Changed text!')
|
||||
.toss();
|
||||
})
|
||||
.toss();
|
||||
})
|
||||
.toss();
|
||||
frisby.create('Read export of posted note')
|
||||
.expectStatus(200)
|
||||
.get('http://localhost:3000/' + noteId + '/export')
|
||||
.expectHeaderContains('content-type', 'text/plain; charset=utf-8')
|
||||
.expectBodyContains(testNote)
|
||||
.toss();
|
||||
frisby.create('Open /edit on posted note')
|
||||
.expectStatus(200)
|
||||
.expectBodyContains('<textarea autofocus name="text">' + testNote + '</textarea>')
|
||||
.get('http://localhost:3000/' + noteId + '/edit')
|
||||
.toss();
|
||||
frisby.create('Read stats of posted note')
|
||||
.get('http://localhost:3000/' + noteId + '/stats')
|
||||
.expectHeaderContains('content-type', 'text/html; charset=utf-8')
|
||||
.expectStatus(200)
|
||||
.expectBodyContains('Statistics')
|
||||
.expectBodyContains('<tr><td>Views</td><td>0</td></tr>')
|
||||
.toss();
|
||||
})
|
||||
.toss();
|
||||
|
||||
var tooLongNote = 'ABCD';
|
||||
|
||||
while (tooLongNote.length < 1024*200) tooLongNote += tooLongNote;
|
||||
|
||||
frisby.create('Invalid posting of too long note')
|
||||
.post('http://localhost:3000/note', {
|
||||
action: 'POST',
|
||||
tos: 'on',
|
||||
password: 'aabbcc',
|
||||
text: tooLongNote
|
||||
})
|
||||
.expectStatus(400)
|
||||
.expectHeaderContains('content-type', 'text/html; charset=utf-8')
|
||||
.expectBodyContains('length not accepted')
|
||||
.toss();
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "NoteHub",
|
||||
"version": "3.0.0",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "jasmine-node ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"frisby": "^0.8.5"
|
||||
}
|
||||
}
|
||||
@@ -142,7 +142,7 @@ func main() {
|
||||
code = http.StatusBadRequest
|
||||
}
|
||||
c.Logger().Errorf("POST /note error: %d", code)
|
||||
return c.Render(code, "Note", errPage(code))
|
||||
return c.Render(code, "Note", errPage(code, err.Error()))
|
||||
}
|
||||
c.Logger().Debugf("note %q saved", n.ID)
|
||||
return c.Redirect(http.StatusMovedPermanently, "/"+n.ID)
|
||||
@@ -160,7 +160,7 @@ func get(vals url.Values, key string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func md2html(c echo.Context, name string) (Note, int) {
|
||||
func md2html(c echo.Context, name string) (*Note, int) {
|
||||
path := "assets/markdown/" + name + ".md"
|
||||
mdContent, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
@@ -169,5 +169,5 @@ func md2html(c echo.Context, name string) (Note, int) {
|
||||
return errPage(code), code
|
||||
}
|
||||
c.Logger().Debugf("rendering markdown page %q", name)
|
||||
return Note{Title: name, Content: mdTmplHTML(mdContent)}, http.StatusOK
|
||||
return &Note{Title: name, Content: mdTmplHTML(mdContent)}, http.StatusOK
|
||||
}
|
||||
|
||||
+12
-11
@@ -54,15 +54,18 @@ type Note struct {
|
||||
Content, Ads template.HTML
|
||||
}
|
||||
|
||||
func errPage(code int, details ...string) Note {
|
||||
func errPage(code int, details ...string) *Note {
|
||||
text := errorCodes[code]
|
||||
body := text
|
||||
if len(details) > 0 {
|
||||
text += ": " + strings.Join(details, ";")
|
||||
body += ": " + strings.Join(details, ";")
|
||||
}
|
||||
return Note{
|
||||
Title: text,
|
||||
Content: mdTmplHTML([]byte(fmt.Sprintf("# %d %s", code, text))),
|
||||
n := &Note{
|
||||
Title: text,
|
||||
Text: fmt.Sprintf("# %d %s", code, body),
|
||||
}
|
||||
n.prepare()
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *Note) prepare() {
|
||||
@@ -88,13 +91,11 @@ func persistStats(logger echo.Logger, db *sql.DB, stats *sync.Map) {
|
||||
stats.Range(func(id, views interface{}) bool {
|
||||
stmt, _ := tx.Prepare("update notes set views = ? where id = ?")
|
||||
_, err := stmt.Exec(views, id)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return false
|
||||
if err == nil {
|
||||
c++
|
||||
}
|
||||
stmt.Close()
|
||||
defer stats.Delete(id)
|
||||
c++
|
||||
return true
|
||||
})
|
||||
tx.Commit()
|
||||
@@ -174,7 +175,7 @@ func randId() string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func load(c echo.Context, db *sql.DB) (Note, int) {
|
||||
func load(c echo.Context, db *sql.DB) (*Note, int) {
|
||||
q := c.Param("id")
|
||||
c.Logger().Debugf("loading note %q", q)
|
||||
stmt, _ := db.Prepare("select * from notes where id = ?")
|
||||
@@ -198,7 +199,7 @@ func load(c echo.Context, db *sql.DB) (Note, int) {
|
||||
if editedVal != nil {
|
||||
n.Edited = editedVal.(time.Time)
|
||||
}
|
||||
return *n, http.StatusOK
|
||||
return n, http.StatusOK
|
||||
}
|
||||
|
||||
var mdRenderer = markdown.New(markdown.HTML(true))
|
||||
|
||||
Reference in New Issue
Block a user