[
  {
    "path": ".gitignore",
    "content": "node_modules\n*.log\nyarn-error.log\ndist\nDS_Store\n"
  },
  {
    "path": "README.md",
    "content": "# Intro to MongoDB\n> Scott Moss & Frontend Masters\n\n- [Resources](#resources)\n- [Course](#course)\n- [Excercises](#excercises)\n  - [Installing MongoDB](#installing-mongodb)\n  - [Models](#models)\n  - [Queries](#queries)\n  - [Hooks](#hooks)\n  - [App](#app)\n\n## Resources\n* [MongoDB Docs](https://docs.mongodb.com/)\n* [MongoDB Installation](https://www.mongodb.com/download-center#community)\n* [Mongoose](https://mongoosejs.com/docs/guide.html)\n* [mLab](https://mlab.com/)\n\n## Course\nThanks for taking the [Introduction to MongoDB course](https://frontendmasters.com/courses/mongodb/), created by Scott Moss & Frontend Masters. This course aims to cover a wide intro into using MongoDb with Nodejs. Topics refrain from going deep, but instead, focus on a wide view.\n\n## Exercises\n\n### Installing MongoDB\nThere are many ways to install MongoDB. [The offical website](https://www.mongodb.com/download-center#community) has you covered either way. After installation, you might have to add a `dbPath`, a location where mongodb saves your data. You can do so like this.\n```bash\nmkdir -p /data/db\n```\nNote: If you have an error like \"data directory not found\" or \"permission denied\" while installing MongoDB:\n```bash\nsudo mkdir -p /data/db\nsudo chown -R $USER /data/db\n```\n\n### Models\n* location - `exercises/models`\n* commands\n  * test - `yarn test exercises/models/__test__/` or `npm test exercises/models/__test__/`\n\nThis exercise will have you create connection logic and mongoose schemas. Using the schema, you must create some CRUD functionality.\n\n- [ ] check out to the `start` branch\n- [ ] install node modules with npm or yarn\n- [ ] check the README on how to run test\n- [ ] create connection logic on `connect.js`\n- [ ] finish the user schema so that the the user model tests pass\n- [ ] complete the crud functions with the user model and get all the crud test to pass \n\n### Queries\n* location - `exercises/queries`\n* commands\n  * test - `yarn test exercises/queries/__test__/` or `npm test exercises/queries/__test__/`\n\nThis exercise will have you add relationships between models. You'll then use those models to create slightly more advanced queries than the last exercise\n\n- [ ] check out to the `start` branch\n- [ ] check the README on how to run your test\n- [ ] the post model should have have a one-to-one author field that points to the author collection\n- [ ] the post model should have a one-to-many similarPost field that points to posts\n- [ ] get all the post model tests to pass\n- [ ] get all the query tests to pass\n\n### Hooks\n* location - `exercises/hooks`\n* commands\n  * test - `yarn test exercises/hooks/__test__/` or `npm test exercises/hooks/__test__/`\n\nIn this exercise, you'll learn how to use schema middleware and virtuals. Also, you'll dig into indexes in more detail and create compound indexes.\n\n- [ ] check out to the `start` branch\n- [ ] check the README on how to run your test\n- [ ] add a compound index to the project schema so that project names are unique per org\n- [ ] add a virtual getter to the project schema called `budgetLeft` that calculates how much budget is left vs how much is spent so far\n- [ ] add a post remove hook to the org schema that removes all projects associated with the org\n- [ ] add a virtual getter to the org schema called `avatar` that creates the fill url to the org avatar by concatinating the cdnUrl with the org id\n- [ ] get all org tests to pass\n- [ ] get all project tests to pass\n\n### App\n* location - `exercises/app`\n* commands\n  * start the server - `node exercises/app/index.js`\n\nIn this exercise, you'll have to create queries in Expressjs controllers to satisfy the request. You'll learn how to use mongodb in an API environment. You'll also have the couse to use a hosted MongoDB.\n\n- [ ] check out to the `start` branch\n- [ ] check the README on how to run your server\n- [ ] create db query for `GET /todo/:id`\n- [ ] create db query for `GET /todo`\n- [ ] create db mutation for `POST /todo/`\n- [ ] **optional** create a mLab sandbox and use your hosted DB\n\n## Debugging\nNote: To handle the error `MongoError: E11000 duplicate key error collection` drop the database.\n\n```bash\nmongo\nuse dbName;\ndb.dropDatabase();\nexit\n```\n\n(dbName is the name of the database)\n"
  },
  {
    "path": "exercises/app/index.js",
    "content": "const express = require('express')\nconst morgan = require('morgan')\nconst connect = require('../connect')\nconst {json, urlencoded} = require('body-parser')\nconst app = express()\nconst Todo = require('./todo')\n\napp.use(morgan('dev'))\napp.use(urlencoded({extended: true}))\napp.use(json())\n\napp.get('/todo/:id', async (req, res) => {\n  const todoId = req.params.id\n  const todo = await Todo.findById(id).exec()\n  res.status(200).json(todo)\n})\n\napp.get('/todos', async (req, res) => {\n  const todos = await Todo.find({}).lean().exec()\n  res.status(200).json(todos)\n})\n\napp.post('/todo', async () => {\n  const todoToCreate = req.body.todo\n  const todo = await Todo.create(todoToCreate)\n  res.status(201).json(todo.toJSON())\n})\n\nconnect('mongodb://localhost:27017/intro-to-mongodb')\n  .then(() => app.listen(4000, () => {\n    console.log('server on http://localhost:4000')\n  }))\n  .catch(e => console.error(e))\n"
  },
  {
    "path": "exercises/app/todo.js",
    "content": "const mongoose = require('mongoose')\n\nconst todoSchema = new mongoose.Schema({\n  message: {\n    type: String,\n    required: true,\n    unique: true\n  },\n  complete: {\n    type: Boolean,\n    default: false,\n    required: true\n  },\n  dueOn: Date\n}, {timestamps: true})\n\n\nmodule.exports = mongoose.model('todo', todoSchema)\n"
  },
  {
    "path": "exercises/connect.js",
    "content": "const mongoose = require('mongoose')\nmongoose.Promise = global.Promise\n\nconst connect = (url) => mongoose.connect(url, {\n  useNewUrlParser: true\n})\n\nmodule.exports = connect\n"
  },
  {
    "path": "exercises/hooks/__test__/org.spec.js",
    "content": "const Project = require('../project')\nconst Org = require('../org')\nconst mongoose = require('mongoose')\n\ndescribe('Org model', () => {\n  test('removes projects when org is remove', async () => {\n    const org = await Org.create({name: 'org'})\n    await Project.create([\n      {name: 'project1', org: org.id},\n      {name: 'project', org: org.id}\n    ])\n    \n    await org.remove()\n    const matchedProjects = await Project.find({org: org._id}).exec()\n    expect(matchedProjects).toHaveLength(0)\n  })\n})\n"
  },
  {
    "path": "exercises/hooks/__test__/project.spec.js",
    "content": "const Project = require('../project')\nconst mongoose = require('mongoose')\n\ndescribe('Project model', () => {\n  test('project names are unique per org', async () => {\n    expect.assertions(1)\n\n    const org = mongoose.Types.ObjectId()\n    const name = 'name'\n    try {\n      await Project.init()\n      await Project.create([\n        {org, name},\n        {org, name}\n      ])\n    } catch (e) {\n      expect(e).toBeTruthy()\n    }\n  })\n  test('budgetLeft virtual should calculate budget left', async () => {\n    const project = await Project.create({\n      name: 'p1',\n      org: mongoose.Types.ObjectId(),\n      budget: 4000,\n      spent: 1000\n    })\n\n    expect(project.budgetLeft).toBe(3000)\n  })\n})\n"
  },
  {
    "path": "exercises/hooks/org.js",
    "content": "const mongoose = require('mongoose')\nconst Project = require('./project')\nconst cdnUrl = 'https://cdn.adminapp.com'\n\nconst orgSchema = new mongoose.Schema({\n  name: {\n    type: String,\n    required: true,\n    unique: true\n  },\n  subscription: {\n    status: {\n      type: String,\n      required: true,\n      default: ['active'],\n      enum: ['active', 'trialing', 'overdue', 'canceled']\n    },\n    last4: {\n      type: Number,\n      min: 4,\n      max: 4\n    }\n  }\n})\n\n\norgSchema.post('remove', async (doc, next) => {\n  await Project.remove({org: doc._id}).exec()\n  next()\n})\n\norgSchema.virtual('avatar').get(function() {\n  return `${cdnUrl}/${this._id.toString()}`\n})\n\nmodule.exports = mongoose.model('org', orgSchema)\n"
  },
  {
    "path": "exercises/hooks/project.js",
    "content": "const mongoose = require('mongoose')\n\nconst projectSchema = new mongoose.Schema({\n  name: {\n    type: String,\n    required: true\n  },\n  org: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: 'org',\n    required: true\n  },\n  dueOn: Date,\n  budget: {\n    type: Number,\n    default: 0\n  },\n  spent: {\n    type: Number,\n    default: 0\n  },\n  onTrack: {\n    type: Boolean,\n    default: false\n  }\n})\n\nprojectSchema.index({\n  org: 1,\n  name: 1\n}, {unique: true})\n\n\nprojectSchema.virtual('budgetLeft').get(function() {\n  return this.budget - this.spent\n})\nmodule.exports = mongoose.model('project', projectSchema)\n"
  },
  {
    "path": "exercises/models/__test__/crud.spec.js",
    "content": "const User = require('../user')\nconst crud = require('../crud')\n\ndescribe('User crud', () => {\n  describe('getUserById', () => {\n    test('get user by object id', async () => {\n      const user = await User.create({\n        firstName: 'Nemo',\n        lastName: 'Nemo',\n        email: 'nemo@nemo.com'\n      })\n      const match = await crud.getUserById(user.id)\n\n      expect(match.id).toBe(user.id)\n    })\n  })\n  describe('getAllUsers', () => {\n    test('get all users in the DB', async () => {\n      const usersToCreate = [\n        {\n          firstName: 'Nemo',\n          lastName: 'Nemo',\n          email: 'nemo@nemo.com'\n        },\n        {\n          firstName: 'Nemo1',\n          lastName: 'Nemo1',\n          email: 'nemo1@nemo.com'\n        },\n        {\n          firstName: 'Nemo3',\n          lastName: 'Nemo3',\n          email: 'nemo3@nemo.com'\n        }\n      ]\n      const users = await User.create(usersToCreate)\n      const matchedUsers = await crud.getAllUsers()\n      \n      expect(matchedUsers).toHaveLength(users.length)\n    })\n  })\n  describe('createUser', () => {\n    test('create a user', async () => {\n      const userConfig = {\n        firstName: 'Nemo',\n        lastName: 'Nemo',\n        email: 'nemo@nemo.com'\n      }\n      const {id} = await crud.createUser(userConfig)\n      const match = await User.findById(id).exec()\n      expect(match.id).toBe(id)\n    })\n  })\n  describe('removeUserById', () => {\n    test('remove user by id', async () => {\n      const {id} = await User.create({\n        firstName: 'Nemo',\n        lastName: 'Nemo',\n        email: 'nemo@nemo.com'\n      })\n      await crud.removeUserById(id)\n      const match = await User.findById(id).exec()\n      expect(match).toBe(null)\n    })\n  })\n  describe('updateUserById', () => {\n    test('update user by id', async () => {\n      const {id} = await User.create({\n        firstName: 'Nemo',\n        lastName: 'Nemo',\n        email: 'nemo@nemo.com'\n      })\n      const user = await crud.updateUserById(id, {betaUser: true})\n      expect(user.id).toBe(id)\n      expect(user.betaUser).toBe(true)\n    })\n  })\n})\n"
  },
  {
    "path": "exercises/models/__test__/user.spec.js",
    "content": "const User = require('../user')\n\ndescribe('User model', () => {\n  test('first name must be required', async () => {\n    expect.assertions(1)\n\n    try {\n      await User.create({\n        lastName: 'Williams',\n        email: 'sasha@gmail.com'\n      })\n    } catch (e) {\n      expect(e).toBeTruthy()\n    }    \n  })\n  test('last name must be required', async () => {\n    expect.assertions(1)\n\n    try {\n      await User.create({\n        firstName: 'Williams',\n        email: 'sasha@gmail.com'\n      })\n    } catch (e) {\n      expect(e).toBeTruthy()\n    }    \n  })\n  test('email must be required', async () => {\n    expect.assertions(1)\n\n    try {\n      await User.create({\n        lastName: 'Williams',\n        firstName: 'Sasha'\n      })\n    } catch (e) {\n      expect(e).toBeTruthy()\n    }    \n  })\n\n  test('email must be unique', async () => {\n    expect.assertions(1)\n\n    try {\n      await User.init() // wait for index to build\n      await User.create([\n        {\n          lastName: 'Williams',\n          firstName: 'Sasha',\n          email: 'email@gmail.com'\n        },\n        {\n          lastName: 'Haas',\n          firstName: 'Mel',\n          email: 'email@gmail.com'\n        }\n      ])\n    } catch (e) {\n      expect(e).toBeTruthy()\n    }    \n  })\n\n  test('betaUser should default to false', async () => {\n    const user = await User.create({\n      firstName: 'Tilly',\n      lastName: 'Mills',\n      email: 'tg@gmail.com'\n    })\n\n    expect(user.betaUser).toBe(false)\n  })\n\n  test('should have correct fields', async () => {\n    const now = Date.now()\n    const {_id, __v, ...user} = (await User.create({\n      firstName: 'Tilly',\n      lastName: 'Mills',\n      email: 'tg@gmail.com',\n      birthDate: now, // they were born today 😎\n      address: {\n        street: 'Heming way',\n        houseNumber: 1234,\n        zip: 91917,\n        city: 'SF',\n        State: 'CA'\n      },\n      pets: ['tido', 'miguel']\n    })).toObject()\n\n    expect(user).toEqual({\n      firstName: 'Tilly',\n      lastName: 'Mills',\n      email: 'tg@gmail.com',\n      birthDate: new Date(now),\n      betaUser: false,\n      address: {\n        street: 'Heming way',\n        houseNumber: 1234,\n        zip: 91917,\n        city: 'SF',\n        State: 'CA'\n      },\n      pets: ['tido', 'miguel']\n    })\n  })\n})\n"
  },
  {
    "path": "exercises/models/crud.js",
    "content": "const User = require('./user')\n\nconst getUserById = (id) => {\n  return User.findById(id)\n    .exec()\n}\n\nconst getAllUsers = () => {\n  return User.find({})\n    .exec()\n}\n\nconst createUser = (userDetails) => {\n  return User.create(userDetails)\n}\nconst removeUserById = (id) => {\n  return User.findByIdAndDelete(id).exec()\n}\n\nconst updateUserById = (id, update) => {\n  return User.findByIdAndUpdate(id, update, {new: true}).exec()\n}\n\nmodule.exports = {\n  getUserById,\n  getAllUsers,\n  createUser,\n  removeUserById,\n  updateUserById\n}\n"
  },
  {
    "path": "exercises/models/user.js",
    "content": "const mongoose = require('mongoose')\n\nconst userSchema = new mongoose.Schema({\n  firstName: {\n    type: String,\n    required: true\n  },\n  lastName: {\n    type: String,\n    required: true\n  },\n  email: {\n    type: String,\n    required: true,\n    unique: true\n  },\n  betaUser: {\n    type: Boolean,\n    default: false\n  },\n  birthDate: Date,\n  pets: [{type: String}],\n  address: {\n    other: Boolean,\n    street: String,\n    houseNumber: Number,\n    zip: Number,\n    city: String,\n    State: String\n  }\n})\n\nmodule.exports = mongoose.model('user', userSchema)\n"
  },
  {
    "path": "exercises/queries/__test__/post.spec.js",
    "content": "const Post = require('../post')\nconst Author = require('../author')\n\ndescribe('Post model', () => {\n  test('author is required and id type', async () => {\n    expect.assertions(2)\n    const content = 'There are a bunch books out there with movies. But which ones are legit?'\n    try {\n      await Post.create({\n        content,\n        title: 'Top ten movie books',\n        contentLength: content.length\n      })\n    } catch (e) {\n      expect(e).toBeTruthy()\n    }\n\n    try {\n      await Post.create({\n        content,\n        contentLength: content.length,\n        title: 'Top ten movie books',\n        author: 'hello'\n      })\n    } catch (e) {\n      expect(e).toBeTruthy()\n    }\n  })\n  test('author must ref author collection', async () => {\n    const name = 'JK Moose'\n    const content = 'There are a bunch books out there with movies. But which ones are legit?'\n    const author = await Author.create({\n      name,\n      bio: 'I have so many awards'\n    })\n\n    const post = await Post.create({\n      content,\n      contentLength: content.length,\n      title: 'Top ten movie books',\n      author: author.id\n    })\n\n    const p = await post.populate('author').execPopulate()\n    expect(p.author.name).toBe(name)\n  })\n})\n"
  },
  {
    "path": "exercises/queries/__test__/queries.spec.js",
    "content": "const {\n  postByTitle,\n  postByContentLength,\n  postsForAuthor,\n  fullPostById,\n  allPostsSlim,\n  addSimilarPosts\n} = require('../queries')\nconst Post = require('../post')\nconst Author = require('../author')\nconst mongoose = require('mongoose')\nconst createContent = (length, fill = 'b') => new Array(length).fill(fill).join('')\n\ndescribe('queries', () => {\n  describe('postByTitle', () => {\n    test('get post by title', async () => {\n      const title = 'cat bedtime'\n      const post = await Post.create({\n        title,\n        author: mongoose.Types.ObjectId(),\n        content: createContent(50),\n        contentLength: 50\n      })\n      \n      const match = await postByTitle(title)\n      expect(match.id).toBe(post.id)\n    })\n  })\n\n  describe('postsForAuthor', () => {\n    test('get post by author', async () => {\n      const author = mongoose.Types.ObjectId()\n      const post = await Post.create({\n        author,\n        title: 'Carter v',\n        content: createContent(50),\n        contentLength: 50\n      })\n      const [match] = await postsForAuthor(author)\n      expect(match.author.toString()).toBe(post.author.toString())\n    })\n  })\n\n  describe('postByContentLength', () => {\n    test('find posts in between content lengths', async () => {\n      const author = mongoose.Types.ObjectId()\n\n      const posts = await Post.create([\n        {title: 'Super Duper', author, content: createContent(1000), contentLength: 1000},\n        {title: 'Amazing', author, content: createContent(100), contentLength: 100},\n        {title: 'Other', author, content: createContent(800), contentLength: 800}\n      ])\n\n      const matches = await postByContentLength(1000, 100)\n      expect(matches).toHaveLength(1)\n    })\n  })\n  describe('fullPostById', () => {\n    test('finds post by id and populates everything', async () => {\n      const author = await Author.create({\n        name: 'Doodle Noodle',\n        bio: 'I am a noodle'\n      })\n      const post = await Post.create({\n        title: 'Super Duper',\n        author: author.id,\n        content: createContent(1000),\n        contentLength: 1000\n      })\n      const post2 = await Post.create({\n        author: author.id,\n        title: 'Post 2',\n        content: createContent(100),\n        contentLength: 100,\n        similarPosts: [post.id]\n      })\n\n      const match = await fullPostById(post2.id)\n      expect(match.author._id.toString()).toBe(author.id.toString())\n    })\n  })\n  describe('selectivePostsByLatest', () => {\n    test('only selects fields given', async () => {\n      const author = mongoose.Types.ObjectId()\n      await Post.create([\n        {title: 'learn things', content: createContent(100), contentLength: 100, author},\n        {title: 'lean more things', content: createContent(100), contentLength: 100, author},\n        {title: 'lean more things++', content: createContent(100), contentLength: 100, author}\n      ])\n\n      const matches = await allPostsSlim({title: 1, content: 1})\n      expect(matches).toHaveLength(3)\n      matches.forEach(match => {\n        const post = match.toJSON()\n        expect(post).not.toHaveProperty('contentLength')\n        expect(post).not.toHaveProperty('author')\n      })\n    })\n  })\n  describe('addRelatedPosts', () => {\n    test('should not override related posts that are there', async () => {\n      const author = mongoose.Types.ObjectId()\n      const post = await Post.create({\n        author,\n        title: 'Post',\n        content: createContent(100),\n        contentLength: 100,\n        similarPosts: [mongoose.Types.ObjectId()]\n      }) \n\n      const updated = await addSimilarPosts(post.id, [\n        mongoose.Types.ObjectId(),\n        mongoose.Types.ObjectId()\n      ])\n      expect(updated.similarPosts).toHaveLength(3)\n    })\n  })\n})\n"
  },
  {
    "path": "exercises/queries/author.js",
    "content": "const mongoose = require('mongoose')\n\nconst authorSchema = new mongoose.Schema({\n  name: {\n    type: String,\n    required: true,\n    trim: true\n  },\n  bio: {\n    type: String,\n    required: true\n  },\n  social: {\n    twitter: {\n      type: String,\n      unique: true,\n      sparse: true\n    },\n    linkedin: {\n      type: String,\n      unique: true,\n      sparse: true\n    }\n  }\n}, {timestamps: true})\n\nmodule.exports = mongoose.model('author', authorSchema)\n"
  },
  {
    "path": "exercises/queries/post.js",
    "content": "const mongoose = require('mongoose')\n\nconst postSchema = new mongoose.Schema({\n  title: {\n    type: String,\n    required: true,\n    unique: true\n  },\n  content: {\n    type: String,\n    required: true,\n    minlength: 50,\n    maxlength: 1200\n  },\n  contentLength: {\n    type: Number,\n    required: true\n  },\n  author: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: 'author',\n    required: true\n  },\n  isFeatured: {\n    type: Boolean,\n    default: false\n  },\n  similarPosts: [{\n    type: mongoose.Schema.Types.ObjectId,\n    ref: 'post',\n  }]\n}, {timestamps: true})\n\nmodule.exports = mongoose.model('post', postSchema)\n"
  },
  {
    "path": "exercises/queries/queries.js",
    "content": "const Post = require('./post')\n\nconst postByTitle = (title) => {\n  return Post.findOne({title}).exec()\n}\n\nconst postsForAuthor = (authorId) => {\n  return Post.find({author: authorId}).exec()\n}\n\nconst fullPostById = (id) => {\n  return Post.findById(id)\n    .populate('author')\n    .populate('similarPosts')\n    .exec()\n}\n\nconst allPostsSlim = (fieldsToSelect) => {\n  return Post.find({})\n    .select(fieldsToSelect)\n    .sort('-createdAt')\n    .exec()\n}\n\nconst postByContentLength = (maxContentLength, minContentLength) => {\n  return Post.find({\n    contentLength: {$lt: maxContentLength, $gt: minContentLength}\n  })\n    .exec()\n}\n\nconst addSimilarPosts = (postId, similarPosts) => {\n  return Post.findByIdAndUpdate(postId, {\n    $push: {similarPosts: {$each: similarPosts}}\n  },{new: true})\n}\n\nmodule.exports = {\n  postByTitle,\n  postsForAuthor,\n  fullPostById,\n  allPostsSlim,\n  postByContentLength,\n  addSimilarPosts\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"intro-to-mongodb\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"author\": \"Scott Moss <willscottmoss@gmail.com>\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"test\": \"jest\"\n  },\n  \"dependencies\": {\n    \"body-parser\": \"^1.18.3\",\n    \"cuid\": \"^2.1.4\",\n    \"express\": \"^4.16.4\",\n    \"mongoose\": \"^5.3.2\",\n    \"morgan\": \"^1.9.1\"\n  },\n  \"jest\": {\n    \"verbose\": true,\n    \"testURL\": \"http://localhost/\",\n    \"testEnvironment\": \"node\",\n    \"setupTestFrameworkScriptFile\": \"<rootDir>/testconfig.js\",\n    \"restoreMocks\": true,\n    \"testPathIgnorePatterns\": [\n      \"dist/\"\n    ]\n  },\n  \"devDependencies\": {\n    \"jest\": \"^23.6.0\"\n  }\n}\n"
  },
  {
    "path": "testconfig.js",
    "content": "const mongoose = require('mongoose')\nconst cuid = require('cuid')\nconst connect = require('./exercises/connect')\nconst url = 'mongodb://localhost:27017/intro-mongodb-testing'\n\nglobal.newId = () => {\n  return mongoose.Types.ObjectId()\n}\n\nbeforeEach(async done => {\n  const db = cuid()\n  function clearDB() {\n    for (var i in mongoose.connection.collections) {\n      mongoose.connection.collections[i].remove(function() {})\n    }\n    return done()\n  }\n  if (mongoose.connection.readyState === 0) {\n    try {\n      await connect(url + db)\n      clearDB()\n    } catch (e) {\n      throw e\n    }\n  } else {\n    clearDB()\n  }\n})\nafterEach(done => {\n  mongoose.disconnect()\n  return done()\n})\nafterAll(done => {\n  return done()\n})\n"
  }
]