Skip to content

Commit

Permalink
feat: add toJSON tests
Browse files Browse the repository at this point in the history
  • Loading branch information
saisilinus committed Apr 11, 2022
1 parent c9f83bf commit 86a9fbe
Show file tree
Hide file tree
Showing 17 changed files with 235 additions and 15 deletions.
2 changes: 1 addition & 1 deletion dist/modules/toJSON/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import toJSON from './toJSON.plugin';
import toJSON from './toJSON';
// eslint-disable-next-line import/prefer-default-export
export { toJSON };
// # sourceMappingURL=index.js.map
2 changes: 1 addition & 1 deletion dist/modules/toJSON/index.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions dist/modules/toJSON/toJSON.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint-disable no-param-reassign */
/**
* A mongoose schema plugin which applies the following in the toJSON transform call:
* - removes __v, createdAt, updatedAt, and any path that has private: true
* - replaces _id with id
*/
const deleteAtPath = (obj, path, index) => {
if (index === path.length - 1) {
delete obj[path[index]];
return;
}
deleteAtPath(obj[path[index]], path, index + 1);
};
const toJSON = (schema) => {
let transform;
if (schema.options.toJSON && schema.options.toJSON.transform) {
transform = schema.options.toJSON.transform;
}
schema.options.toJSON = Object.assign(schema.options.toJSON || {}, {
transform(doc, ret, options) {
Object.keys(schema.paths).forEach((path) => {
if (schema.paths[path].options && schema.paths[path].options.private) {
deleteAtPath(ret, path.split('.'), 0);
}
});
ret.id = ret._id.toString();
delete ret._id;
delete ret.__v;
delete ret.createdAt;
delete ret.updatedAt;
if (transform) {
return transform(doc, ret, options);
}
},
});
};
export default toJSON;
// # sourceMappingURL=toJSON.js.map
1 change: 1 addition & 0 deletions dist/modules/toJSON/toJSON.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 83 additions & 0 deletions dist/modules/toJSON/toJSON.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import mongoose from 'mongoose';
import { toJSON } from '.';

describe('toJSON plugin', () => {
let connection;
beforeEach(() => {
connection = mongoose.createConnection();
});
it('should replace _id with id', () => {
const schema = new mongoose.Schema();
schema.plugin(toJSON);
const SampleModel = connection.model('Model', schema);
const doc = new SampleModel();
expect(doc.toJSON()).not.toHaveProperty('_id');
expect(doc.toJSON()).toHaveProperty('id', doc._id.toString());
});
it('should remove __v', () => {
const schema = new mongoose.Schema();
schema.plugin(toJSON);
const SampleModel = connection.model('Model', schema);
const doc = new SampleModel();
expect(doc.toJSON()).not.toHaveProperty('__v');
});
it('should remove createdAt and updatedAt', () => {
const schema = new mongoose.Schema({}, { timestamps: true });
schema.plugin(toJSON);
const SampleModel = connection.model('Model', schema);
const doc = new SampleModel();
expect(doc.toJSON()).not.toHaveProperty('createdAt');
expect(doc.toJSON()).not.toHaveProperty('updatedAt');
});
it('should remove any path set as private', () => {
const schema = new mongoose.Schema({
public: { type: String },
private: { type: String, private: true },
});
schema.plugin(toJSON);
const SampleModel = connection.model('Model', schema);
const doc = new SampleModel({ public: 'some public value', private: 'some private value' });
expect(doc.toJSON()).not.toHaveProperty('private');
expect(doc.toJSON()).toHaveProperty('public');
});
it('should remove any nested paths set as private', () => {
const schema = new mongoose.Schema({
public: { type: String },
nested: {
private: { type: String, private: true },
},
});
schema.plugin(toJSON);
const SampleModel = connection.model('Model', schema);
const doc = new SampleModel({
public: 'some public value',
nested: {
private: 'some nested private value',
},
});
expect(doc.toJSON()).not.toHaveProperty('nested.private');
expect(doc.toJSON()).toHaveProperty('public');
});
it('should also call the schema toJSON transform function', () => {
const schema = new mongoose.Schema(
{
public: { type: String },
private: { type: String },
},
{
toJSON: {
transform: (_doc, ret) => {
// eslint-disable-next-line no-param-reassign
delete ret.private;
},
},
}
);
schema.plugin(toJSON);
const SampleModel = connection.model('Model', schema);
const doc = new SampleModel({ public: 'some public value', private: 'some private value' });
expect(doc.toJSON()).not.toHaveProperty('private');
expect(doc.toJSON()).toHaveProperty('public');
});
});
// # sourceMappingURL=toJSON.test.js.map
1 change: 1 addition & 0 deletions dist/modules/toJSON/toJSON.test.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/modules/token/token.model.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import mongoose from 'mongoose';
import tokenTypes from './token.types';
import toJSON from '../toJSON/toJSON.plugin';
import toJSON from '../toJSON/toJSON';

const tokenSchema = new mongoose.Schema(
{
Expand Down
2 changes: 1 addition & 1 deletion dist/modules/token/token.model.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/modules/user/user.model.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import mongoose from 'mongoose';
import validator from 'validator';
import bcrypt from 'bcryptjs';
import toJSON from '../toJSON/toJSON.plugin';
import toJSON from '../toJSON/toJSON';
import paginate from '../paginate/paginate';
import { roles } from '../../config/roles';

Expand Down
2 changes: 1 addition & 1 deletion dist/modules/user/user.model.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/modules/toJSON/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import toJSON from './toJSON.plugin';
import toJSON from './toJSON';

// eslint-disable-next-line import/prefer-default-export
export { toJSON };
100 changes: 100 additions & 0 deletions src/modules/toJSON/toJSON.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import mongoose, { Model, Document } from 'mongoose';
import { toJSON } from '.';

interface SampleSchema {
public: string;
private: string;
nested: {
private: string;
};
}

interface SampleSchemaDoc extends SampleSchema, Document {}
interface SampleSchemaModel extends Model<SampleSchemaDoc> {}

describe('toJSON plugin', () => {
let connection: mongoose.Connection;

beforeEach(() => {
connection = mongoose.createConnection();
});

it('should replace _id with id', () => {
const schema = new mongoose.Schema<SampleSchemaDoc, SampleSchemaModel>();
schema.plugin(toJSON);
const SampleModel = connection.model<SampleSchemaDoc, SampleSchemaModel>('Model', schema);
const doc = new SampleModel();
expect(doc.toJSON()).not.toHaveProperty('_id');
expect(doc.toJSON()).toHaveProperty('id', doc._id.toString());
});

it('should remove __v', () => {
const schema = new mongoose.Schema<SampleSchemaDoc, SampleSchemaModel>();
schema.plugin(toJSON);
const SampleModel = connection.model<SampleSchemaDoc, SampleSchemaModel>('Model', schema);
const doc = new SampleModel();
expect(doc.toJSON()).not.toHaveProperty('__v');
});

it('should remove createdAt and updatedAt', () => {
const schema = new mongoose.Schema<SampleSchemaDoc, SampleSchemaModel>({}, { timestamps: true });
schema.plugin(toJSON);
const SampleModel = connection.model<SampleSchemaDoc, SampleSchemaModel>('Model', schema);
const doc = new SampleModel();
expect(doc.toJSON()).not.toHaveProperty('createdAt');
expect(doc.toJSON()).not.toHaveProperty('updatedAt');
});

it('should remove any path set as private', () => {
const schema = new mongoose.Schema<SampleSchemaDoc, SampleSchemaModel>({
public: { type: String },
private: { type: String, private: true },
});
schema.plugin(toJSON);
const SampleModel = connection.model<SampleSchemaDoc, SampleSchemaModel>('Model', schema);
const doc = new SampleModel({ public: 'some public value', private: 'some private value' });
expect(doc.toJSON()).not.toHaveProperty('private');
expect(doc.toJSON()).toHaveProperty('public');
});

it('should remove any nested paths set as private', () => {
const schema = new mongoose.Schema<SampleSchemaDoc, SampleSchemaModel>({
public: { type: String },
nested: {
private: { type: String, private: true },
},
});
schema.plugin(toJSON);
const SampleModel = connection.model<SampleSchemaDoc, SampleSchemaModel>('Model', schema);
const doc = new SampleModel({
public: 'some public value',
nested: {
private: 'some nested private value',
},
});
expect(doc.toJSON()).not.toHaveProperty('nested.private');
expect(doc.toJSON()).toHaveProperty('public');
});

it('should also call the schema toJSON transform function', () => {
const schema = new mongoose.Schema<SampleSchemaDoc, SampleSchemaModel>(
{
public: { type: String },
private: { type: String },
},
{
toJSON: {
transform: (_doc, ret) => {
// eslint-disable-next-line no-param-reassign
delete ret.private;
},
},
}
);
schema.plugin(toJSON);
const SampleModel = connection.model<SampleSchemaDoc, SampleSchemaModel>('Model', schema);
const doc = new SampleModel({ public: 'some public value', private: 'some private value' });
expect(doc.toJSON()).not.toHaveProperty('private');
expect(doc.toJSON()).toHaveProperty('public');
});
});
File renamed without changes.

0 comments on commit 86a9fbe

Please sign in to comment.