Gigantic Update
* Migrated manual tests to jest and started working on better coverage * Added a bookmarklet and push key generation tool allowing URL pushing from bookmarklets * Updated web scraping with tons of bug fixes * Updated attachments page to handle new push links * Aggressive note change checking, if patches get out of sync, server overwrites bad updates.
This commit is contained in:
100
server/tests/models/Attachment.test.js
Normal file
100
server/tests/models/Attachment.test.js
Normal file
@@ -0,0 +1,100 @@
|
||||
const Attachment = require('../../models/Attachment')
|
||||
const User = require('../../models/User')
|
||||
|
||||
const testUserName = 'jestTestUserAttachment'
|
||||
const password = 'Beans19934!!!'
|
||||
|
||||
let newUserId = null
|
||||
let masterKey = null
|
||||
let newPushKey = null
|
||||
|
||||
beforeAll(() => {
|
||||
|
||||
// Find and Delete Previous Test user, log in, get key
|
||||
return User.getByUserName(testUserName)
|
||||
.then((user) => {
|
||||
return User.deleteUser(user?.id, password)
|
||||
})
|
||||
.then((results) => {
|
||||
|
||||
return User.register(testUserName, password)
|
||||
})
|
||||
.then(({ token, userId }) => {
|
||||
newUserId = userId
|
||||
|
||||
return User.getMasterKey(userId, password)
|
||||
})
|
||||
.then((newMasterKey) => {
|
||||
masterKey = newMasterKey
|
||||
|
||||
return true
|
||||
})
|
||||
.catch(((error) => {
|
||||
console.log(error)
|
||||
}))
|
||||
|
||||
})
|
||||
|
||||
|
||||
test('Test Generate Push Key', () => {
|
||||
|
||||
return Attachment.generatePushKey(newUserId)
|
||||
.then( (pushKey) => {
|
||||
newPushKey = pushKey
|
||||
return Attachment.generatePushKey(newUserId)
|
||||
})
|
||||
.then( (pushKey) => {
|
||||
// expect a long, defined pushkey
|
||||
expect(pushKey).toBeDefined()
|
||||
expect(pushKey?.length).toBeGreaterThan(20)
|
||||
expect(pushKey).toMatch(newPushKey)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
test('Test get Push Key Bookmarklet', () => {
|
||||
|
||||
return Attachment.getPushkeyBookmarklet(newUserId)
|
||||
.then(( bookmarklet => {
|
||||
// Expect a bookmarklet containting URL encoded pushkey from above
|
||||
const keyCheck = bookmarklet.includes(encodeURIComponent(newPushKey))
|
||||
|
||||
expect(bookmarklet).toBeDefined()
|
||||
expect(keyCheck).toBe(true)
|
||||
|
||||
}))
|
||||
})
|
||||
|
||||
|
||||
test('Test Push URL', () => {
|
||||
|
||||
let url = 'https://www.solidscribe.com'
|
||||
|
||||
return Attachment.pushUrl(newPushKey, url)
|
||||
.then(( results => {
|
||||
|
||||
return Attachment.textSearch(newUserId, 'scribe')
|
||||
|
||||
}))
|
||||
.then((results) => {
|
||||
|
||||
expect(results.length == 1).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
test('Test Delete Push Key', () => {
|
||||
|
||||
return Attachment.deletePushKey(newUserId)
|
||||
.then(( results => {
|
||||
// Expect a true bool
|
||||
expect(results).toBe(true)
|
||||
}))
|
||||
})
|
||||
|
||||
afterAll(done => {
|
||||
// Close Database
|
||||
const db = require('../../config/database')
|
||||
db.end()
|
||||
done()
|
||||
})
|
117
server/tests/models/Note.test.js
Normal file
117
server/tests/models/Note.test.js
Normal file
@@ -0,0 +1,117 @@
|
||||
const Note = require('../../models/Note')
|
||||
const User = require('../../models/User')
|
||||
|
||||
const testUserName = 'jestTestUserNote'
|
||||
const password = 'Beans1234!!!'
|
||||
const secondPassword = 'Rice1234!!!'
|
||||
|
||||
let newUserId = null
|
||||
let masterKey = null
|
||||
|
||||
let testNoteId = 0
|
||||
let testNoteId2 = 0
|
||||
|
||||
|
||||
const searchWord1 = 'beans'
|
||||
const searchWord2 = 'RICE'
|
||||
const updatedNoteText = 'Some Note Text for Testing more '+searchWord2+' is nice'
|
||||
|
||||
|
||||
beforeAll(() => {
|
||||
|
||||
// Find and Delete Previous Test user, log in, get key
|
||||
return User.getByUserName(testUserName)
|
||||
.then((user) => {
|
||||
return User.deleteUser(user?.id, password)
|
||||
})
|
||||
.then((results) => {
|
||||
|
||||
return User.register(testUserName, password)
|
||||
})
|
||||
.then(({ token, userId }) => {
|
||||
newUserId = userId
|
||||
|
||||
return User.getMasterKey(userId, password)
|
||||
})
|
||||
.then((newMasterKey) => {
|
||||
masterKey = newMasterKey
|
||||
|
||||
return true
|
||||
})
|
||||
.catch(((error) => {
|
||||
console.log(error)
|
||||
}))
|
||||
|
||||
})
|
||||
|
||||
test('Create Note', () => {
|
||||
const noteTitle = 'Test Note'
|
||||
const noteText = 'Some Note Text for Testing'
|
||||
|
||||
return Note.create(newUserId, noteTitle, noteText, masterKey)
|
||||
.then((noteId) => {
|
||||
testNoteId = noteId
|
||||
expect(noteId).toBeGreaterThan(0)
|
||||
})
|
||||
})
|
||||
|
||||
test('Create Another Note', () => {
|
||||
const noteTitle = 'Test Note2'
|
||||
const noteText = 'Some Note Text for Testing more '+searchWord1
|
||||
|
||||
return Note.create(newUserId, noteTitle, noteText, masterKey)
|
||||
.then((noteId) => {
|
||||
testNoteId2 = noteId
|
||||
expect(noteId).toBeGreaterThan(0)
|
||||
})
|
||||
})
|
||||
|
||||
test('Update a note', () => {
|
||||
|
||||
return Note.update(newUserId, testNoteId, updatedNoteText, 'title', 0, 0, 0, 'hash', masterKey)
|
||||
.then((results) => {
|
||||
expect(results.changedRows).toEqual(1)
|
||||
})
|
||||
})
|
||||
|
||||
test('Decrypt a note', () => {
|
||||
|
||||
return Note.get(newUserId, testNoteId, masterKey)
|
||||
.then((noteData) => {
|
||||
expect(noteData.text).toMatch(updatedNoteText)
|
||||
})
|
||||
})
|
||||
|
||||
test('Update note search index', () => {
|
||||
return Note.reindex(newUserId, masterKey)
|
||||
.then((results) => {
|
||||
expect(results).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
test('Search Encrypted Index', () => {
|
||||
const searchString = `${searchWord1} ${searchWord2}`
|
||||
|
||||
return Note.encryptedIndexSearch(newUserId, searchString, null, masterKey)
|
||||
.then(({ids}) => {
|
||||
// Make sure beans is in one note and rice is in updated text
|
||||
expect(ids.length).toEqual(2)
|
||||
})
|
||||
})
|
||||
|
||||
test('Search Encrypted Index no results', () => {
|
||||
|
||||
return Note.encryptedIndexSearch(newUserId, 'zzz', null, masterKey)
|
||||
.then(({ids}) => {
|
||||
// Make sure beans is in one note and rice is in updated text
|
||||
expect(ids.length).toEqual(0)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
afterAll(done => {
|
||||
// Close Database
|
||||
const db = require('../../config/database')
|
||||
db.end()
|
||||
done()
|
||||
})
|
67
server/tests/models/ShareNote.js
Normal file
67
server/tests/models/ShareNote.js
Normal file
@@ -0,0 +1,67 @@
|
||||
const Note = require('../../models/Note')
|
||||
const User = require('../../models/User')
|
||||
const ShareNote = require('../../models/ShareNote')
|
||||
|
||||
const testUserName = 'jestTestUserNote'
|
||||
const password = 'Beans1234!!!'
|
||||
let newUserId = null
|
||||
let masterKey = null
|
||||
|
||||
const testUserName2 = 'jestTestUserDude'
|
||||
const password2 = 'Rice1234!!!'
|
||||
let newUserId2 = null
|
||||
let masterKey2 = null
|
||||
|
||||
|
||||
let testNoteId = 0
|
||||
let testNoteId2 = 0
|
||||
// let sharedNoteId = 0 //ID of note shared with user
|
||||
const shareUserId = 61
|
||||
const searchWord1 = 'beans'
|
||||
const searchWord2 = 'RICE'
|
||||
const updatedNoteText = 'Some Note Text for Testing more '+searchWord2+' is nice'
|
||||
|
||||
|
||||
|
||||
beforeAll(() => {
|
||||
|
||||
// Find and Delete Previous Test user, log in, get key
|
||||
return
|
||||
User.getByUserName(testUserName)
|
||||
.then(user => {
|
||||
User.deleteUser(user?.id, password)
|
||||
})
|
||||
.then(user => {
|
||||
User.getByUserName(testUserName2)
|
||||
})
|
||||
.then(user => {
|
||||
User.deleteUser(user?.id, password)
|
||||
})
|
||||
.then((results) => {
|
||||
|
||||
return User.register(testUserName, password)
|
||||
})
|
||||
.then(({ token, userId }) => {
|
||||
newUserId = userId
|
||||
|
||||
return User.getMasterKey(userId, password)
|
||||
})
|
||||
.then((newMasterKey) => {
|
||||
masterKey = newMasterKey
|
||||
|
||||
return true
|
||||
})
|
||||
.catch(((error) => {
|
||||
console.log(error)
|
||||
}))
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
afterAll(done => {
|
||||
// Close Database
|
||||
const db = require('../../config/database')
|
||||
db.end()
|
||||
done()
|
||||
})
|
112
server/tests/models/User.test.js
Normal file
112
server/tests/models/User.test.js
Normal file
@@ -0,0 +1,112 @@
|
||||
const User = require('../../models/User')
|
||||
const crypto = require('crypto')
|
||||
|
||||
const testUserName = 'jestTestUser'
|
||||
const password = 'Beans1234!!!'
|
||||
const secondPassword = 'Rice1234!!!'
|
||||
|
||||
let testUserId = null
|
||||
let masterKey = null
|
||||
|
||||
beforeAll(() => {
|
||||
|
||||
// Find and Delete Previous Test user
|
||||
return User.getByUserName(testUserName)
|
||||
.then((user) => {
|
||||
return User.deleteUser(user?.id, password)
|
||||
})
|
||||
.then((results) => {
|
||||
|
||||
return results
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
test('Test User Registration', () => {
|
||||
|
||||
return User.register(testUserName, password)
|
||||
.then((({ token, userId }) => {
|
||||
|
||||
testUserId = userId
|
||||
|
||||
expect(token).toBeDefined()
|
||||
expect(userId).toBeGreaterThan(0)
|
||||
}))
|
||||
})
|
||||
|
||||
test('Test decrypting user masterKey', () => {
|
||||
|
||||
return User.getMasterKey(testUserId, password)
|
||||
.then((newMasterKey) => {
|
||||
masterKey = newMasterKey
|
||||
|
||||
expect(masterKey).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
test('Test generating public and private key pair', () => {
|
||||
|
||||
return User.generateKeypair(testUserId, masterKey)
|
||||
.then(({publicKey, privateKey}) => {
|
||||
|
||||
const publicKeyMessage = 'Test: Public key decrypt - Pass'
|
||||
const privateKeyMessage = 'Test: Private key decrypt - Pass'
|
||||
|
||||
//Encrypt Message with private Key
|
||||
const privateKeyEncrypted = crypto.privateEncrypt(privateKey, Buffer.from(privateKeyMessage, 'utf8')).toString('base64')
|
||||
const decryptedPrivate = crypto.publicDecrypt(publicKey, Buffer.from(privateKeyEncrypted, 'base64'))
|
||||
//Conver back to a string
|
||||
expect(decryptedPrivate.toString('utf8')).toMatch(privateKeyMessage)
|
||||
|
||||
//Encrypt with public key
|
||||
const pubEncrMsc = crypto.publicEncrypt(publicKey, Buffer.from(publicKeyMessage, 'utf8')).toString('base64')
|
||||
const publicDeccryptMessage = crypto.privateDecrypt(privateKey, Buffer.from(pubEncrMsc, 'base64') )
|
||||
//Convert it back to string
|
||||
expect(publicDeccryptMessage.toString('utf8')).toMatch(publicKeyMessage)
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
test('Test Logging in User', () => {
|
||||
|
||||
return User.login(testUserName, password)
|
||||
.then(({token, userId}) => {
|
||||
expect(token).toBeDefined()
|
||||
expect(userId).toBeGreaterThan(0)
|
||||
})
|
||||
})
|
||||
|
||||
test('Test Changing Password', () => {
|
||||
return User.changePassword(testUserId, password, secondPassword)
|
||||
.then((passwordChangeResults) => {
|
||||
|
||||
expect(passwordChangeResults).toBe(true)
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
test('Test Login with wrong password', () => {
|
||||
|
||||
return User.login(testUserName, password)
|
||||
.then(({token, userId}) => {
|
||||
|
||||
expect(token).toBeNull()
|
||||
expect(userId).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
test('Test decrypting masterKey with new Password', () => {
|
||||
return User.getMasterKey(testUserId, secondPassword)
|
||||
.then((newMasterKey) => {
|
||||
|
||||
expect(newMasterKey).toBeDefined()
|
||||
expect(newMasterKey.length).toBe(28)
|
||||
})
|
||||
})
|
||||
|
||||
afterAll(done => {
|
||||
// Close Database
|
||||
const db = require('../../config/database')
|
||||
db.end()
|
||||
done()
|
||||
})
|
Reference in New Issue
Block a user