mirror of
https://github.com/usatiuk/ustk-todolist.git
synced 2025-10-28 15:47:48 +01:00
require authentication for todos,
use in-memody db for tests
This commit is contained in:
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@@ -2,4 +2,5 @@
|
|||||||
"editor.tabSize": 2,
|
"editor.tabSize": 2,
|
||||||
"prettier.eslintIntegration": true,
|
"prettier.eslintIntegration": true,
|
||||||
"editor.insertSpaces": true,
|
"editor.insertSpaces": true,
|
||||||
|
"jest.pathToJest": "npm test --"
|
||||||
}
|
}
|
||||||
15
app.js
15
app.js
@@ -6,24 +6,27 @@ const cors = require('cors');
|
|||||||
const config = require('./config');
|
const config = require('./config');
|
||||||
const db = require('./config/db');
|
const db = require('./config/db');
|
||||||
|
|
||||||
|
require('./models/TodoList');
|
||||||
|
require('./models/User');
|
||||||
|
require('./models/Todo');
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(bodyParser.urlencoded({ extended: false }));
|
app.use(bodyParser.urlencoded({ extended: false }));
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
app.use(morgan('dev'));
|
app.use(morgan('dev'));
|
||||||
|
|
||||||
require('./models/User');
|
|
||||||
require('./models/TodoList');
|
|
||||||
require('./models/Todo');
|
|
||||||
|
|
||||||
const passport = require('./config/passport');
|
const passport = require('./config/passport');
|
||||||
|
|
||||||
app.use(passport.initialize());
|
app.use(passport.initialize());
|
||||||
|
|
||||||
app.use('/lists', require('./routes/lists'));
|
|
||||||
app.use('/todos', require('./routes/todos'));
|
|
||||||
app.use('/users', require('./routes/users'));
|
app.use('/users', require('./routes/users'));
|
||||||
|
|
||||||
|
const auth = require('./routes/auth');
|
||||||
|
|
||||||
|
app.use('/lists', auth.required, require('./routes/lists'));
|
||||||
|
app.use('/todos', auth.required, require('./routes/todos'));
|
||||||
|
|
||||||
// 404 route
|
// 404 route
|
||||||
app.use((req, res) => {
|
app.use((req, res) => {
|
||||||
res.status(404);
|
res.status(404);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const config = require('./');
|
const config = require('./');
|
||||||
|
|
||||||
const { host, port, name } = config.db;
|
|
||||||
const connectionString = `mongodb://${host}:${port}/${name}`;
|
|
||||||
|
|
||||||
async function connect() {
|
async function connect() {
|
||||||
|
const { host, port, name } = config.db;
|
||||||
|
const connectionString = `mongodb://${host}:${port}/${name}`;
|
||||||
|
|
||||||
await mongoose.connect(connectionString);
|
await mongoose.connect(connectionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,15 +11,8 @@ const dev = {
|
|||||||
},
|
},
|
||||||
secret: process.env.DEV_SECRET || 'devsecret',
|
secret: process.env.DEV_SECRET || 'devsecret',
|
||||||
};
|
};
|
||||||
|
|
||||||
const test = {
|
const test = {
|
||||||
app: {
|
|
||||||
port: process.env.TEST_APP_PORT || 4001,
|
|
||||||
},
|
|
||||||
db: {
|
|
||||||
host: process.env.TEST_DB_HOST || 'localhost',
|
|
||||||
port: process.env.TEST_DB_PORT || 27017,
|
|
||||||
name: process.env.TEST_DB_NAME || 'todolistTest',
|
|
||||||
},
|
|
||||||
secret: process.env.TEST_SECRET || 'testsecret',
|
secret: process.env.TEST_SECRET || 'testsecret',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
const TodoList = mongoose.model('TodoList');
|
|
||||||
const { Schema } = mongoose;
|
const { Schema } = mongoose;
|
||||||
|
|
||||||
const TodoSchema = Schema({
|
const TodoSchema = Schema({
|
||||||
@@ -9,17 +8,26 @@ const TodoSchema = Schema({
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
list: { type: Schema.Types.ObjectId, ref: 'TodoList', required: true },
|
list: { type: Schema.Types.ObjectId, ref: 'TodoList', required: true },
|
||||||
|
user: { type: Schema.Types.ObjectId, ref: 'User', required: true },
|
||||||
completed: { type: Boolean, default: false },
|
completed: { type: Boolean, default: false },
|
||||||
});
|
});
|
||||||
|
|
||||||
TodoSchema.pre('save', async function () {
|
TodoSchema.pre('save', async function () {
|
||||||
const list = await TodoList.findById(this.list);
|
const user = await this.model('User').findById(this.user);
|
||||||
|
user.todos.push(this._id);
|
||||||
|
await user.save();
|
||||||
|
|
||||||
|
const list = await this.model('TodoList').findById(this.list);
|
||||||
list.todos.push(this._id);
|
list.todos.push(this._id);
|
||||||
await list.save();
|
await list.save();
|
||||||
});
|
});
|
||||||
|
|
||||||
TodoSchema.pre('remove', async function () {
|
TodoSchema.pre('remove', async function () {
|
||||||
const list = await TodoList.findById(this.list);
|
const user = await this.model('User').findById(this.user);
|
||||||
|
user.todos.splice(user.todos.indexOf(this._id), 1);
|
||||||
|
await user.save();
|
||||||
|
|
||||||
|
const list = await this.model('TodoList').findById(this.list);
|
||||||
list.todos.splice(list.todos.indexOf(this._id), 1);
|
list.todos.splice(list.todos.indexOf(this._id), 1);
|
||||||
await list.save();
|
await list.save();
|
||||||
});
|
});
|
||||||
@@ -29,6 +37,7 @@ TodoSchema.methods.toJson = function () {
|
|||||||
id: this._id.toString(),
|
id: this._id.toString(),
|
||||||
text: this.text,
|
text: this.text,
|
||||||
list: this.list.toString(),
|
list: this.list.toString(),
|
||||||
|
user: this.user.toString(),
|
||||||
completed: this.completed,
|
completed: this.completed,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,18 +8,27 @@ const TodoListSchema = Schema({
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
todos: [{ type: Schema.Types.ObjectId, ref: 'Todo' }],
|
todos: [{ type: Schema.Types.ObjectId, ref: 'Todo' }],
|
||||||
|
user: { type: Schema.Types.ObjectId, ref: 'User', required: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
TodoListSchema.pre('save', async function () {
|
||||||
|
const user = await this.model('User').findById(this.user);
|
||||||
|
user.lists.push(this._id);
|
||||||
|
await user.save();
|
||||||
});
|
});
|
||||||
|
|
||||||
TodoListSchema.pre('remove', async function () {
|
TodoListSchema.pre('remove', async function () {
|
||||||
this.todos.forEach(async (todo) => {
|
const user = await this.model('User').findById(this.user);
|
||||||
await todo.remove();
|
user.lists.splice(user.todos.indexOf(this._id), 1);
|
||||||
});
|
await user.save();
|
||||||
|
await this.model('Todo').remove({ list: this._id });
|
||||||
});
|
});
|
||||||
|
|
||||||
TodoListSchema.methods.toJson = function () {
|
TodoListSchema.methods.toJson = function () {
|
||||||
const todos = this.populated('todos') ? this.todos.map(todo => todo.toJson()) : this.todos;
|
const todos = this.populated('todos') ? this.todos.map(todo => todo.toJson()) : this.todos;
|
||||||
return {
|
return {
|
||||||
id: this._id.toString(),
|
id: this._id.toString(),
|
||||||
|
user: this.user.toString(),
|
||||||
name: this.name,
|
name: this.name,
|
||||||
todos,
|
todos,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,17 +1,33 @@
|
|||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const passportLocalMongoose = require('passport-local-mongoose');
|
const passportLocalMongoose = require('passport-local-mongoose');
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
|
const uniqueValidator = require('mongoose-unique-validator');
|
||||||
|
|
||||||
const { secret } = require('../config');
|
const { secret } = require('../config');
|
||||||
|
|
||||||
const { Schema } = mongoose;
|
const { Schema } = mongoose;
|
||||||
|
|
||||||
const UserSchema = Schema({ username: { type: String, required: true } });
|
const UserSchema = Schema({
|
||||||
|
username: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
unique: true,
|
||||||
|
validate: /^\S*$/,
|
||||||
|
},
|
||||||
|
lists: [{ type: Schema.Types.ObjectId, ref: 'TodoList' }],
|
||||||
|
todos: [{ type: Schema.Types.ObjectId, ref: 'Todo' }],
|
||||||
|
});
|
||||||
|
|
||||||
UserSchema.plugin(passportLocalMongoose);
|
UserSchema.plugin(passportLocalMongoose);
|
||||||
|
UserSchema.plugin(uniqueValidator);
|
||||||
|
|
||||||
|
UserSchema.pre('remove', async function () {
|
||||||
|
await this.model('TodoList').remove({ user: this._id });
|
||||||
|
await this.model('Todo').remove({ user: this._id });
|
||||||
|
});
|
||||||
|
|
||||||
UserSchema.methods.generateJwt = function () {
|
UserSchema.methods.generateJwt = function () {
|
||||||
return jwt.sign({ id: this._id, username: this.username }, secret, { expiresIn: '1y' });
|
return jwt.sign({ id: this._id, username: this.username }, secret, { expiresIn: '6m' });
|
||||||
};
|
};
|
||||||
|
|
||||||
UserSchema.methods.toAuthJson = function () {
|
UserSchema.methods.toAuthJson = function () {
|
||||||
|
|||||||
394
package-lock.json
generated
394
package-lock.json
generated
@@ -1033,6 +1033,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"base64-js": {
|
||||||
|
"version": "0.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
|
||||||
|
"integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"basic-auth": {
|
"basic-auth": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
|
||||||
@@ -1057,6 +1063,16 @@
|
|||||||
"integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
|
"integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"bl": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"readable-stream": "^2.3.5",
|
||||||
|
"safe-buffer": "^5.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"bluebird": {
|
"bluebird": {
|
||||||
"version": "3.5.0",
|
"version": "3.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
|
||||||
@@ -1169,11 +1185,50 @@
|
|||||||
"resolved": "https://registry.npmjs.org/bson/-/bson-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/bson/-/bson-1.0.6.tgz",
|
||||||
"integrity": "sha512-D8zmlb46xfuK2gGvKmUjIklQEouN2nQ0LEHHeZ/NoHM2LDiMk2EYzZ5Ntw/Urk+bgMDosOZxaRzXxvhI5TcAVQ=="
|
"integrity": "sha512-D8zmlb46xfuK2gGvKmUjIklQEouN2nQ0LEHHeZ/NoHM2LDiMk2EYzZ5Ntw/Urk+bgMDosOZxaRzXxvhI5TcAVQ=="
|
||||||
},
|
},
|
||||||
|
"buffer": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz",
|
||||||
|
"integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"base64-js": "0.0.8",
|
||||||
|
"ieee754": "^1.1.4",
|
||||||
|
"isarray": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buffer-alloc": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"buffer-alloc-unsafe": "^1.1.0",
|
||||||
|
"buffer-fill": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buffer-alloc-unsafe": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"buffer-crc32": {
|
||||||
|
"version": "0.2.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||||
|
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"buffer-equal-constant-time": {
|
"buffer-equal-constant-time": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||||
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
|
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
|
||||||
},
|
},
|
||||||
|
"buffer-fill": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"buffer-from": {
|
"buffer-from": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz",
|
||||||
@@ -1554,6 +1609,15 @@
|
|||||||
"delayed-stream": "~1.0.0"
|
"delayed-stream": "~1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"commander": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
|
||||||
|
"integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"graceful-readlink": ">= 1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"compare-versions": {
|
"compare-versions": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.2.1.tgz",
|
||||||
@@ -1764,6 +1828,95 @@
|
|||||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
|
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"decompress": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz",
|
||||||
|
"integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"decompress-tar": "^4.0.0",
|
||||||
|
"decompress-tarbz2": "^4.0.0",
|
||||||
|
"decompress-targz": "^4.0.0",
|
||||||
|
"decompress-unzip": "^4.0.1",
|
||||||
|
"graceful-fs": "^4.1.10",
|
||||||
|
"make-dir": "^1.0.0",
|
||||||
|
"pify": "^2.3.0",
|
||||||
|
"strip-dirs": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"decompress-tar": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"file-type": "^5.2.0",
|
||||||
|
"is-stream": "^1.1.0",
|
||||||
|
"tar-stream": "^1.5.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"decompress-tarbz2": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"decompress-tar": "^4.1.0",
|
||||||
|
"file-type": "^6.1.0",
|
||||||
|
"is-stream": "^1.1.0",
|
||||||
|
"seek-bzip": "^1.0.5",
|
||||||
|
"unbzip2-stream": "^1.0.9"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"file-type": {
|
||||||
|
"version": "6.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
|
||||||
|
"integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"decompress-targz": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"decompress-tar": "^4.1.1",
|
||||||
|
"file-type": "^5.2.0",
|
||||||
|
"is-stream": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"decompress-unzip": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
|
||||||
|
"integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"file-type": "^3.8.0",
|
||||||
|
"get-stream": "^2.2.0",
|
||||||
|
"pify": "^2.3.0",
|
||||||
|
"yauzl": "^2.4.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"file-type": {
|
||||||
|
"version": "3.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
|
||||||
|
"integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"get-stream": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
|
||||||
|
"integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"object-assign": "^4.0.1",
|
||||||
|
"pinkie-promise": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"deep-extend": {
|
"deep-extend": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz",
|
||||||
@@ -1983,6 +2136,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||||
},
|
},
|
||||||
|
"end-of-stream": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"once": "^1.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"error-ex": {
|
"error-ex": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
|
||||||
@@ -2574,6 +2736,15 @@
|
|||||||
"bser": "^2.0.0"
|
"bser": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fd-slicer": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"pend": "~1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"figures": {
|
"figures": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
|
||||||
@@ -2593,6 +2764,12 @@
|
|||||||
"object-assign": "^4.0.1"
|
"object-assign": "^4.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"file-type": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
|
||||||
|
"integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"filename-regex": {
|
"filename-regex": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
|
||||||
@@ -2734,6 +2911,23 @@
|
|||||||
"integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
|
"integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"fs-constants": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"fs-extra": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "^4.1.2",
|
||||||
|
"jsonfile": "^4.0.0",
|
||||||
|
"universalify": "^0.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fs.realpath": {
|
"fs.realpath": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
@@ -3292,6 +3486,12 @@
|
|||||||
"integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
|
"integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"get-port": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz",
|
||||||
|
"integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"get-stream": {
|
"get-stream": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||||
@@ -3304,6 +3504,26 @@
|
|||||||
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
|
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"getos": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/getos/-/getos-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-i9vrxtDu5DlLVFcrbqUqGWYlZN/zZ4pGMICCAcZoYsX3JA54nYp8r5EThw5K+m2q3wszkx4Th746JstspB0H4Q==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"async": "2.4.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"async": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-2.4.0.tgz",
|
||||||
|
"integrity": "sha1-SZAgDxjqW4N8LMT4wDGmmFw4VhE=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4.14.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"getpass": {
|
"getpass": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||||
@@ -3400,6 +3620,12 @@
|
|||||||
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
|
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"graceful-readlink": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"growly": {
|
"growly": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
|
||||||
@@ -3608,6 +3834,12 @@
|
|||||||
"safer-buffer": ">= 2.1.2 < 3"
|
"safer-buffer": ">= 2.1.2 < 3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ieee754": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"ignore": {
|
"ignore": {
|
||||||
"version": "3.3.8",
|
"version": "3.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz",
|
||||||
@@ -3880,6 +4112,12 @@
|
|||||||
"is-path-inside": "^1.0.0"
|
"is-path-inside": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-natural-number": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
|
||||||
|
"integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"is-npm": {
|
"is-npm": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
|
||||||
@@ -4653,6 +4891,15 @@
|
|||||||
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
|
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"jsonfile": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||||
|
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "^4.1.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"jsonify": {
|
"jsonify": {
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
|
||||||
@@ -4800,11 +5047,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"lockfile": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"signal-exit": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.10",
|
"version": "4.17.10",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
|
||||||
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
|
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
|
||||||
},
|
},
|
||||||
|
"lodash.foreach": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
|
||||||
|
"integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM="
|
||||||
|
},
|
||||||
"lodash.get": {
|
"lodash.get": {
|
||||||
"version": "4.4.2",
|
"version": "4.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||||
@@ -4940,6 +5201,15 @@
|
|||||||
"integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=",
|
"integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"md5-file": {
|
||||||
|
"version": "3.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/md5-file/-/md5-file-3.2.3.tgz",
|
||||||
|
"integrity": "sha512-3Tkp1piAHaworfcCgH0jKbTvj1jWWFgbvh2cXaNCgHwyTCBxxvD1Y04rmfpvdPm1P4oXMOpm6+2H7sr7v9v8Fw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"buffer-alloc": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"media-typer": {
|
"media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
@@ -5086,6 +5356,38 @@
|
|||||||
"require_optional": "^1.0.1"
|
"require_optional": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mongodb-memory-server": {
|
||||||
|
"version": "1.7.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-1.7.4.tgz",
|
||||||
|
"integrity": "sha512-8CNbBV80cBradJEuyAl+Vw45Wf0MJYTplDphGE9z3qqaQVRYG25PhZ2Uk+kyVVF6HqF4obe+meCMpoOoeXwJ8w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-runtime": "^6.26.0",
|
||||||
|
"debug": "^3.1.0",
|
||||||
|
"decompress": "^4.2.0",
|
||||||
|
"fs-extra": "^5.0.0",
|
||||||
|
"get-port": "^3.2.0",
|
||||||
|
"getos": "^3.1.0",
|
||||||
|
"lockfile": "^1.0.4",
|
||||||
|
"md5-file": "^3.2.3",
|
||||||
|
"mkdirp": "^0.5.1",
|
||||||
|
"request": "^2.85.0",
|
||||||
|
"request-promise": "^4.2.2",
|
||||||
|
"tmp": "^0.0.33",
|
||||||
|
"uuid": "^3.2.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"mongoose": {
|
"mongoose": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.1.2.tgz",
|
||||||
@@ -5116,6 +5418,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz",
|
||||||
"integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
|
"integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
|
||||||
},
|
},
|
||||||
|
"mongoose-unique-validator": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mongoose-unique-validator/-/mongoose-unique-validator-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-Eqq7lZMy0nPSojG8UyDZvlBie1aBZJXk68GDMBXXQH0TAi0hZHf76nCrwuipReNK1jLkjyKzV7eIZotja5eEBw==",
|
||||||
|
"requires": {
|
||||||
|
"lodash.foreach": "^4.1.0",
|
||||||
|
"lodash.get": "^4.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"morgan": {
|
"morgan": {
|
||||||
"version": "1.9.0",
|
"version": "1.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
|
||||||
@@ -5697,6 +6008,12 @@
|
|||||||
"through": "~2.3"
|
"through": "~2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pend": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"performance-now": {
|
"performance-now": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||||
@@ -6098,6 +6415,18 @@
|
|||||||
"uuid": "^3.1.0"
|
"uuid": "^3.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request-promise": {
|
||||||
|
"version": "4.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.2.tgz",
|
||||||
|
"integrity": "sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"bluebird": "^3.5.0",
|
||||||
|
"request-promise-core": "1.1.1",
|
||||||
|
"stealthy-require": "^1.1.0",
|
||||||
|
"tough-cookie": ">=2.3.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"request-promise-core": {
|
"request-promise-core": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
|
||||||
@@ -6588,6 +6917,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/scmp/-/scmp-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/scmp/-/scmp-2.0.0.tgz",
|
||||||
"integrity": "sha1-JHEQ7yLM+JexOj8KvdtSeCOTzWo="
|
"integrity": "sha1-JHEQ7yLM+JexOj8KvdtSeCOTzWo="
|
||||||
},
|
},
|
||||||
|
"seek-bzip": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"commander": "~2.8.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.5.0",
|
"version": "5.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||||
@@ -7058,6 +7396,15 @@
|
|||||||
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"strip-dirs": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-natural-number": "^4.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"strip-eof": {
|
"strip-eof": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
|
||||||
@@ -7135,6 +7482,21 @@
|
|||||||
"string-width": "^2.1.1"
|
"string-width": "^2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tar-stream": {
|
||||||
|
"version": "1.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz",
|
||||||
|
"integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"bl": "^1.0.0",
|
||||||
|
"buffer-alloc": "^1.1.0",
|
||||||
|
"end-of-stream": "^1.0.0",
|
||||||
|
"fs-constants": "^1.0.0",
|
||||||
|
"readable-stream": "^2.3.0",
|
||||||
|
"to-buffer": "^1.1.0",
|
||||||
|
"xtend": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"term-size": {
|
"term-size": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
|
||||||
@@ -7526,6 +7888,12 @@
|
|||||||
"integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=",
|
"integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"to-buffer": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"to-fast-properties": {
|
"to-fast-properties": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||||
@@ -7689,6 +8057,16 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"unbzip2-stream": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"buffer": "^3.0.1",
|
||||||
|
"through": "^2.3.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"undefsafe": {
|
"undefsafe": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
|
||||||
@@ -7742,6 +8120,12 @@
|
|||||||
"crypto-random-string": "^1.0.0"
|
"crypto-random-string": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"universalify": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
|
||||||
|
"integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"unpipe": {
|
"unpipe": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
@@ -8185,6 +8569,16 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"yauzl": {
|
||||||
|
"version": "2.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz",
|
||||||
|
"integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"buffer-crc32": "~0.2.3",
|
||||||
|
"fd-slicer": "~1.0.1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"express-jwt": "^5.3.1",
|
"express-jwt": "^5.3.1",
|
||||||
"jsonwebtoken": "^8.2.1",
|
"jsonwebtoken": "^8.2.1",
|
||||||
"mongoose": "^5.1.1",
|
"mongoose": "^5.1.1",
|
||||||
|
"mongoose-unique-validator": "^2.0.1",
|
||||||
"morgan": "^1.9.0",
|
"morgan": "^1.9.0",
|
||||||
"passport": "^0.4.0",
|
"passport": "^0.4.0",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
"eslint-plugin-import": "^2.12.0",
|
"eslint-plugin-import": "^2.12.0",
|
||||||
"eslint-plugin-jest": "^21.15.2",
|
"eslint-plugin-jest": "^21.15.2",
|
||||||
"jest": "^22.4.4",
|
"jest": "^22.4.4",
|
||||||
|
"mongodb-memory-server": "^1.7.4",
|
||||||
"nodemon": "^1.17.5",
|
"nodemon": "^1.17.5",
|
||||||
"supertest": "^3.1.0"
|
"supertest": "^3.1.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,12 +6,14 @@ const router = express.Router();
|
|||||||
const TodoList = mongoose.model('TodoList');
|
const TodoList = mongoose.model('TodoList');
|
||||||
|
|
||||||
const asyncHelper = require('../asyncHelper');
|
const asyncHelper = require('../asyncHelper');
|
||||||
|
const auth = require('./auth');
|
||||||
|
const { NotFoundError } = require('../errors');
|
||||||
|
|
||||||
// index
|
// index
|
||||||
router.get(
|
router.get(
|
||||||
'/',
|
'/',
|
||||||
asyncHelper(async (req, res) => {
|
asyncHelper(async (req, res) => {
|
||||||
const lists = await TodoList.find({})
|
const lists = await TodoList.find({ user: req.user.id })
|
||||||
.populate('todos')
|
.populate('todos')
|
||||||
.exec();
|
.exec();
|
||||||
res.json({ success: true, data: lists.map(list => list.toJson()) });
|
res.json({ success: true, data: lists.map(list => list.toJson()) });
|
||||||
@@ -23,7 +25,7 @@ router.post(
|
|||||||
'/',
|
'/',
|
||||||
asyncHelper(async (req, res) => {
|
asyncHelper(async (req, res) => {
|
||||||
const { name } = req.body;
|
const { name } = req.body;
|
||||||
const newList = new TodoList({ name });
|
const newList = new TodoList({ name, user: req.user.id });
|
||||||
await newList.save();
|
await newList.save();
|
||||||
res.json({ success: true, data: newList.toJson() });
|
res.json({ success: true, data: newList.toJson() });
|
||||||
}),
|
}),
|
||||||
@@ -34,7 +36,7 @@ router.delete(
|
|||||||
'/:listId',
|
'/:listId',
|
||||||
asyncHelper(async (req, res) => {
|
asyncHelper(async (req, res) => {
|
||||||
const { listId } = req.params;
|
const { listId } = req.params;
|
||||||
const list = await TodoList.findById(listId)
|
const list = await TodoList.find({ _id: listId, user: req.user.id })
|
||||||
.populate('todos')
|
.populate('todos')
|
||||||
.exec();
|
.exec();
|
||||||
await list.remove();
|
await list.remove();
|
||||||
@@ -48,15 +50,13 @@ router.patch(
|
|||||||
asyncHelper(async (req, res) => {
|
asyncHelper(async (req, res) => {
|
||||||
const { listId } = req.params;
|
const { listId } = req.params;
|
||||||
const { name } = req.body;
|
const { name } = req.body;
|
||||||
const patch = {};
|
const list = await TodoList.find({ _id: listId, user: req.user.id });
|
||||||
if (name !== undefined) {
|
if (!list) {
|
||||||
patch.name = name;
|
throw new NotFoundError("can't find list");
|
||||||
|
}
|
||||||
|
if (name !== undefined) {
|
||||||
|
list.name = name;
|
||||||
}
|
}
|
||||||
const list = await TodoList.findByIdAndUpdate(
|
|
||||||
{ _id: listId },
|
|
||||||
{ $set: patch },
|
|
||||||
{ new: true },
|
|
||||||
).exec();
|
|
||||||
await list.save();
|
await list.save();
|
||||||
res.json({ success: true, data: list.toJson() });
|
res.json({ success: true, data: list.toJson() });
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ router.get(
|
|||||||
'/',
|
'/',
|
||||||
asyncHelper(async (req, res) => {
|
asyncHelper(async (req, res) => {
|
||||||
const { listId } = res.locals || req.body;
|
const { listId } = res.locals || req.body;
|
||||||
const todos = await Todo.find({ list: listId }).exec();
|
const todos = await Todo.find({ list: listId, user: req.user.id }).exec();
|
||||||
res.json({ success: true, data: todos.map(todo => todo.toJson()) });
|
res.json({ success: true, data: todos.map(todo => todo.toJson()) });
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -24,7 +24,7 @@ router.post(
|
|||||||
asyncHelper(async (req, res) => {
|
asyncHelper(async (req, res) => {
|
||||||
const { listId } = res.locals || req.body;
|
const { listId } = res.locals || req.body;
|
||||||
const { text } = req.body;
|
const { text } = req.body;
|
||||||
const todo = new Todo({ text, list: listId });
|
const todo = new Todo({ text, list: listId, user: req.user.id });
|
||||||
await todo.save();
|
await todo.save();
|
||||||
res.json({ success: true, data: todo.toJson() });
|
res.json({ success: true, data: todo.toJson() });
|
||||||
}),
|
}),
|
||||||
@@ -36,16 +36,15 @@ router.patch(
|
|||||||
asyncHelper(async (req, res) => {
|
asyncHelper(async (req, res) => {
|
||||||
const { todoId } = req.params;
|
const { todoId } = req.params;
|
||||||
const { text, completed } = req.body;
|
const { text, completed } = req.body;
|
||||||
const patch = {};
|
const todo = await Todo.find({ _id: todoId, user: req.user.id });
|
||||||
|
if (!todo) {
|
||||||
|
throw new NotFoundError("can't find todo");
|
||||||
|
}
|
||||||
if (text !== undefined) {
|
if (text !== undefined) {
|
||||||
patch.text = text;
|
todo.text = text;
|
||||||
}
|
}
|
||||||
if (completed !== undefined) {
|
if (completed !== undefined) {
|
||||||
patch.completed = completed;
|
todo.completed = completed;
|
||||||
}
|
|
||||||
const todo = await Todo.findByIdAndUpdate(todoId, { $set: patch }, { new: true }).exec();
|
|
||||||
if (!todo) {
|
|
||||||
throw new NotFoundError(`can't find todo with id ${todoId}`);
|
|
||||||
}
|
}
|
||||||
res.json({ success: true, data: todo.toJson() });
|
res.json({ success: true, data: todo.toJson() });
|
||||||
}),
|
}),
|
||||||
@@ -56,7 +55,7 @@ router.delete(
|
|||||||
'/:todoId',
|
'/:todoId',
|
||||||
asyncHelper(async (req, res) => {
|
asyncHelper(async (req, res) => {
|
||||||
const { todoId } = req.params;
|
const { todoId } = req.params;
|
||||||
const todo = await Todo.findById(todoId).exec();
|
const todo = await Todo.find({ _id: todoId, user: req.user.id }).exec();
|
||||||
if (!todo) {
|
if (!todo) {
|
||||||
throw new NotFoundError(`can't find todo with id ${todoId}`);
|
throw new NotFoundError(`can't find todo with id ${todoId}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,11 @@ router.patch(
|
|||||||
if (username !== undefined) {
|
if (username !== undefined) {
|
||||||
patch.username = username;
|
patch.username = username;
|
||||||
}
|
}
|
||||||
const user = await User.findByIdAndUpdate(req.user.id, { $set: patch }, { new: true }).exec();
|
const user = await User.findOneAndUpdate(
|
||||||
|
{ _id: req.user.id },
|
||||||
|
{ $set: patch },
|
||||||
|
{ runValidators: true, context: 'query', new: true },
|
||||||
|
).exec();
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new NotFoundError(`can't find user with username ${req.user.username}`);
|
throw new NotFoundError(`can't find user with username ${req.user.username}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,65 +3,57 @@ const server = require('../../app.js');
|
|||||||
const request = require('supertest');
|
const request = require('supertest');
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
const db = require('../../config/db');
|
|
||||||
|
|
||||||
const TodoList = mongoose.model('TodoList');
|
|
||||||
const Todo = mongoose.model('Todo');
|
const Todo = mongoose.model('Todo');
|
||||||
|
const TodoList = mongoose.model('TodoList');
|
||||||
|
const User = mongoose.model('User');
|
||||||
|
|
||||||
let lists;
|
jest.setTimeout(60000);
|
||||||
let listsPopulated;
|
const MongoDBMemoryServer = require('mongodb-memory-server').default;
|
||||||
let todos;
|
const { seed, clean } = require('./utils');
|
||||||
|
|
||||||
|
let user;
|
||||||
|
let token;
|
||||||
|
let list;
|
||||||
|
let todo;
|
||||||
|
let mongoServer;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
mongoServer = new MongoDBMemoryServer();
|
||||||
|
const mongoUri = await mongoServer.getConnectionString();
|
||||||
|
await mongoose.connect(mongoUri);
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await db.connect();
|
({
|
||||||
|
user, token, list, todo,
|
||||||
// seed lists and todos
|
} = await seed());
|
||||||
const list1 = new TodoList({ name: 'List1' });
|
|
||||||
const todo1 = new Todo({ text: 'Todo1', list: list1._id });
|
|
||||||
const todo2 = new Todo({ text: 'Todo2', list: list1._id });
|
|
||||||
|
|
||||||
await list1.save();
|
|
||||||
await todo1.save();
|
|
||||||
await todo2.save();
|
|
||||||
lists = await TodoList.find({}).exec();
|
|
||||||
listsPopulated = await TodoList.find({})
|
|
||||||
.populate('todos')
|
|
||||||
.exec();
|
|
||||||
todos = await Todo.find({}).exec();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
await TodoList.remove({}).exec();
|
await clean();
|
||||||
await Todo.remove({}).exec();
|
|
||||||
await db.disconnect();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
await mongoose.disconnect();
|
||||||
|
await mongoServer.stop();
|
||||||
await server.close();
|
await server.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('test lists', () => {
|
describe('test lists', () => {
|
||||||
test('should index lists', async () => {
|
test('should not index lists without authentication', async () => {
|
||||||
const response = await request(server)
|
await request(server)
|
||||||
.get('/lists')
|
.get('/lists')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect(200)
|
.expect(401);
|
||||||
.expect('Content-Type', 'application/json; charset=utf-8');
|
|
||||||
expect(response.body.success).toBe(true);
|
|
||||||
expect(response.body.data).toBeInstanceOf(Array);
|
|
||||||
expect(response.body.data).toEqual(listsPopulated.map(list => list.toJson()));
|
|
||||||
});
|
});
|
||||||
test('should create list', async () => {
|
test('should not create list without authentication', async () => {
|
||||||
const response = await request(server)
|
await request(server)
|
||||||
.post('/lists')
|
.post('/lists')
|
||||||
.send({
|
.send({
|
||||||
name: 'List2',
|
name: 'List2',
|
||||||
})
|
})
|
||||||
.set('Content-Type', 'application/json')
|
.set('Content-Type', 'application/json')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect(200)
|
.expect(401);
|
||||||
.expect('Content-Type', 'application/json; charset=utf-8');
|
|
||||||
expect(response.body.success).toBeTruthy();
|
|
||||||
expect(await TodoList.findOne({ name: 'List2' })).toBeTruthy();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,26 +3,43 @@ const server = require('../../app.js');
|
|||||||
const request = require('supertest');
|
const request = require('supertest');
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
const Todo = require('../../models/Todo');
|
const Todo = mongoose.model('Todo');
|
||||||
const TodoList = require('../../models/TodoList');
|
const TodoList = mongoose.model('TodoList');
|
||||||
|
const User = mongoose.model('User');
|
||||||
|
|
||||||
const db = require('../../config/db');
|
jest.setTimeout(60000);
|
||||||
|
const MongoDBMemoryServer = require('mongodb-memory-server').default;
|
||||||
|
const { seed, clean } = require('./utils');
|
||||||
|
|
||||||
|
let user;
|
||||||
|
let token;
|
||||||
|
let list;
|
||||||
|
let todo;
|
||||||
|
let mongoServer;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
mongoServer = new MongoDBMemoryServer();
|
||||||
|
const mongoUri = await mongoServer.getConnectionString();
|
||||||
|
await mongoose.connect(mongoUri);
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await db.connect();
|
({
|
||||||
|
user, token, list, todo,
|
||||||
|
} = await seed());
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
await db.disconnect();
|
await clean();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await TodoList.remove({}).exec();
|
await mongoose.disconnect();
|
||||||
await Todo.remove({}).exec();
|
await mongoServer.stop();
|
||||||
await server.close();
|
await server.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Test not found', () => {
|
describe('test not found', () => {
|
||||||
test('respond not found with json', async () => {
|
test('respond not found with json', async () => {
|
||||||
const response = await request(server)
|
const response = await request(server)
|
||||||
.get('/')
|
.get('/')
|
||||||
|
|||||||
@@ -4,29 +4,40 @@ const request = require('supertest');
|
|||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
|
|
||||||
const db = require('../../config/db');
|
const Todo = mongoose.model('Todo');
|
||||||
const { secret } = require('../../config');
|
const TodoList = mongoose.model('TodoList');
|
||||||
|
|
||||||
const User = mongoose.model('User');
|
const User = mongoose.model('User');
|
||||||
|
|
||||||
|
jest.setTimeout(60000);
|
||||||
|
const MongoDBMemoryServer = require('mongodb-memory-server').default;
|
||||||
|
const { seed, clean } = require('./utils');
|
||||||
|
const { secret } = require('../../config');
|
||||||
|
|
||||||
let user;
|
let user;
|
||||||
let token;
|
let token;
|
||||||
|
let list;
|
||||||
|
let todo;
|
||||||
|
let mongoServer;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
mongoServer = new MongoDBMemoryServer();
|
||||||
|
const mongoUri = await mongoServer.getConnectionString();
|
||||||
|
await mongoose.connect(mongoUri);
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await db.connect();
|
({
|
||||||
|
user, token, list, todo,
|
||||||
user = new User({ username: 'User' });
|
} = await seed());
|
||||||
await user.setPassword('password');
|
|
||||||
await user.save();
|
|
||||||
token = user.generateJwt();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
await User.remove({}).exec();
|
await clean();
|
||||||
await db.disconnect();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
await mongoose.disconnect();
|
||||||
|
await mongoServer.stop();
|
||||||
await server.close();
|
await server.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -35,8 +46,8 @@ describe('test users', () => {
|
|||||||
const response = await request(server)
|
const response = await request(server)
|
||||||
.post('/users')
|
.post('/users')
|
||||||
.send({
|
.send({
|
||||||
username: 'User 2',
|
username: 'User2',
|
||||||
password: 'password 2',
|
password: 'password2',
|
||||||
})
|
})
|
||||||
.set('Content-Type', 'application/json')
|
.set('Content-Type', 'application/json')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
@@ -44,8 +55,8 @@ describe('test users', () => {
|
|||||||
.expect('Content-Type', 'application/json; charset=utf-8');
|
.expect('Content-Type', 'application/json; charset=utf-8');
|
||||||
expect(response.body.success).toBeTruthy();
|
expect(response.body.success).toBeTruthy();
|
||||||
const tokenDecoded = jwt.verify(response.body.data.jwt, secret);
|
const tokenDecoded = jwt.verify(response.body.data.jwt, secret);
|
||||||
expect(tokenDecoded.username).toEqual('User 2');
|
expect(tokenDecoded.username).toEqual('User2');
|
||||||
const userAuth = await User.authenticate()('User 2', 'password 2');
|
const userAuth = await User.authenticate()('User2', 'password2');
|
||||||
expect(userAuth.user).toBeTruthy();
|
expect(userAuth.user).toBeTruthy();
|
||||||
});
|
});
|
||||||
test('should not create user with no username', async () => {
|
test('should not create user with no username', async () => {
|
||||||
@@ -53,7 +64,7 @@ describe('test users', () => {
|
|||||||
.post('/users')
|
.post('/users')
|
||||||
.send({
|
.send({
|
||||||
username: '',
|
username: '',
|
||||||
password: 'password 2',
|
password: 'password2',
|
||||||
})
|
})
|
||||||
.set('Content-Type', 'application/json')
|
.set('Content-Type', 'application/json')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
@@ -78,8 +89,8 @@ describe('test users', () => {
|
|||||||
const response = await request(server)
|
const response = await request(server)
|
||||||
.post('/users/login')
|
.post('/users/login')
|
||||||
.send({
|
.send({
|
||||||
username: 'User',
|
username: 'User1',
|
||||||
password: 'password',
|
password: 'password1',
|
||||||
})
|
})
|
||||||
.set('Content-Type', 'application/json')
|
.set('Content-Type', 'application/json')
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
@@ -87,7 +98,7 @@ describe('test users', () => {
|
|||||||
.expect('Content-Type', 'application/json; charset=utf-8');
|
.expect('Content-Type', 'application/json; charset=utf-8');
|
||||||
expect(response.body.success).toBeTruthy();
|
expect(response.body.success).toBeTruthy();
|
||||||
const tokenDecoded = jwt.verify(response.body.data.jwt, secret);
|
const tokenDecoded = jwt.verify(response.body.data.jwt, secret);
|
||||||
expect(tokenDecoded.username).toEqual('User');
|
expect(tokenDecoded.username).toEqual('User1');
|
||||||
});
|
});
|
||||||
test('should not login user with no name', async () => {
|
test('should not login user with no name', async () => {
|
||||||
await request(server)
|
await request(server)
|
||||||
@@ -115,7 +126,7 @@ describe('test users', () => {
|
|||||||
const response = await request(server)
|
const response = await request(server)
|
||||||
.patch('/users/user')
|
.patch('/users/user')
|
||||||
.send({
|
.send({
|
||||||
username: 'User 2',
|
username: 'User2',
|
||||||
password: 'password2',
|
password: 'password2',
|
||||||
})
|
})
|
||||||
.set('Authorization', `Bearer ${token}`)
|
.set('Authorization', `Bearer ${token}`)
|
||||||
@@ -125,15 +136,15 @@ describe('test users', () => {
|
|||||||
.expect('Content-Type', 'application/json; charset=utf-8');
|
.expect('Content-Type', 'application/json; charset=utf-8');
|
||||||
expect(response.body.success).toBeTruthy();
|
expect(response.body.success).toBeTruthy();
|
||||||
const tokenDecoded = jwt.verify(response.body.data.jwt, secret);
|
const tokenDecoded = jwt.verify(response.body.data.jwt, secret);
|
||||||
expect(tokenDecoded.username).toEqual('User 2');
|
expect(tokenDecoded.username).toEqual('User2');
|
||||||
const userAuth = await User.authenticate()('User 2', 'password2');
|
const userAuth = await User.authenticate()('User2', 'password2');
|
||||||
expect(userAuth.user).toBeTruthy();
|
expect(userAuth.user).toBeTruthy();
|
||||||
});
|
});
|
||||||
test('should not update user without authentication', async () => {
|
test('should not update user without authentication', async () => {
|
||||||
const response = await request(server)
|
const response = await request(server)
|
||||||
.patch('/users/user')
|
.patch('/users/user')
|
||||||
.send({
|
.send({
|
||||||
username: 'User 2',
|
username: 'User2',
|
||||||
password: 'password2',
|
password: 'password2',
|
||||||
})
|
})
|
||||||
.set('Content-Type', 'application/json')
|
.set('Content-Type', 'application/json')
|
||||||
@@ -148,7 +159,7 @@ describe('test users', () => {
|
|||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.expect(401);
|
.expect(401);
|
||||||
expect(response.body.success).toBeFalsy();
|
expect(response.body.success).toBeFalsy();
|
||||||
expect(await User.findOne({ username: 'User' }).exec()).toBeTruthy();
|
expect(await User.findOne({ username: 'User1' }).exec()).toBeTruthy();
|
||||||
});
|
});
|
||||||
test('should delete user', async () => {
|
test('should delete user', async () => {
|
||||||
const response = await request(server)
|
const response = await request(server)
|
||||||
@@ -159,6 +170,6 @@ describe('test users', () => {
|
|||||||
.expect(200)
|
.expect(200)
|
||||||
.expect('Content-Type', 'application/json; charset=utf-8');
|
.expect('Content-Type', 'application/json; charset=utf-8');
|
||||||
expect(response.body.success).toBeTruthy();
|
expect(response.body.success).toBeTruthy();
|
||||||
expect(await User.findOne({ username: 'User' }).exec()).toBeFalsy();
|
expect(await User.findOne({ username: 'User1' }).exec()).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
33
tests/integration/utils.js
Normal file
33
tests/integration/utils.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const User = mongoose.model('User');
|
||||||
|
const Todo = mongoose.model('Todo');
|
||||||
|
const TodoList = mongoose.model('TodoList');
|
||||||
|
|
||||||
|
async function seed() {
|
||||||
|
const user = new User({ username: 'User1' });
|
||||||
|
await user.setPassword('password1');
|
||||||
|
await user.save();
|
||||||
|
const token = user.generateJwt();
|
||||||
|
|
||||||
|
const list = new TodoList({ name: 'List1', user: user._id });
|
||||||
|
const todo = new Todo({ text: 'Todo1', list: list._id, user: user._id });
|
||||||
|
|
||||||
|
await list.save();
|
||||||
|
await todo.save();
|
||||||
|
|
||||||
|
return {
|
||||||
|
user,
|
||||||
|
token,
|
||||||
|
list,
|
||||||
|
todo,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function clean() {
|
||||||
|
await TodoList.remove({}).exec();
|
||||||
|
await Todo.remove({}).exec();
|
||||||
|
await User.remove({}).exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { seed, clean };
|
||||||
Reference in New Issue
Block a user