Skip to content

Commit

Permalink
feat(type): ObjectID with reference
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Marton committed Aug 2, 2015
1 parent ddba1d3 commit 653e1d1
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 16 deletions.
12 changes: 8 additions & 4 deletions fixture/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,21 @@ let UserSchema = new mongoose.Schema({
type: Number,
index: true
},
mother: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
friends: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}],
weight: Number, // to test "floatish" numbers
createdAt: Date,
removed: Boolean,
nums: [Number],
strings: [String],
bools: [Boolean],
dates: [Date],
friends: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}],
sub: {
foo: String,
nums: [Number],
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@
"lodash": "^3.10.0"
},
"devDependencies": {
"babel": "^5.8.19",
"babel-eslint": "^3.1.26",
"babel": "^5.8.20",
"babel-eslint": "^4.0.5",
"chai": "^3.2.0",
"chai-subset": "^1.0.1",
"co-mocha": "^1.1.2",
"eslint": "1.0.0-rc-3",
"eslint": "1.0.0",
"mocha": "^2.2.5",
"mongoose": "^4.0.6",
"pre-commit": "^1.0.10",
"pre-commit": "^1.1.1",
"sinon": "^1.15.4",
"sinon-chai": "^2.8.0"
},
Expand Down
19 changes: 18 additions & 1 deletion src/e2e.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,21 @@ describe('e2e', () => {
});

describe('get schema', () => {
let motherUser;
let user1;
let user2;
let schema;

beforeEach(function* () {
schema = getSchema([User]);

motherUser = new User({
name: 'Mother',
age: 54
});

yield motherUser.save();

user1 = new User({
name: 'Foo',
age: 28
Expand All @@ -49,14 +57,15 @@ describe('e2e', () => {
user2 = new User({
name: 'Bar',
age: 28,
mother: motherUser._id,
friends: [user1._id]
});

yield user2.save();
});

afterEach(function* () {
yield [user1.remove(), user2.remove()];
yield [motherUser.remove(), user1.remove(), user2.remove()];
});

it('should generate schema from mongoose models', () => {
Expand All @@ -77,6 +86,10 @@ describe('e2e', () => {
_id
name
age
mother {
_id
name
}
friends {
_id
name
Expand All @@ -90,6 +103,10 @@ describe('e2e', () => {
_id: user2._id.toString(),
name: 'Bar',
age: 28,
mother: {
_id: motherUser._id.toString(),
name: 'Mother'
},
friends: [{
_id: user1._id.toString(),
name: 'Foo'
Expand Down
25 changes: 23 additions & 2 deletions src/field.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {isDate} from 'lodash';
import ObjectID from 'bson-objectid';

import {
GraphQLString,
Expand Down Expand Up @@ -44,8 +45,28 @@ function getField(field, types, models, model) {

var refModelName;

// ObjectID
if (field.instance === 'ObjectID') {

// with reference
if (field.ref) {
graphQLfield.description += ` and reference to "${field.ref}" model`;

graphQLfield.type = types[field.ref];
graphQLfield.resolve = (modelInstance, params, source, fieldASTs) => {
var projections = getProjection(fieldASTs);

return models[field.ref].model.findOne({
_id: new ObjectID(modelInstance[field.name])
}, projections);
};
} else {
graphQLfield.type = GraphQLString;
}
}

// String
if (['String', 'ObjectID'].indexOf(field.instance) > -1) {
else if (field.instance === 'String') {
graphQLfield.type = GraphQLString;
}

Expand Down Expand Up @@ -107,7 +128,7 @@ function getField(field, types, models, model) {

// Object
else if (field.instance === 'Object') {
console.log(field.instance);
// TODO: implement
}

return graphQLfield;
Expand Down
19 changes: 17 additions & 2 deletions src/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,29 @@ function getField (schemaPath) {
indexed: options.index ? true : false
};

// Field options
if (schemaPath.options) {

// ObjectID ref
if (schemaPath.options.ref) {
field.ref = schemaPath.options.ref;
}
}

// Caster
if (schemaPath.caster) {
field.caster = {
path: schemaPath.caster.path,
instance: schemaPath.caster.instance
};

if (schemaPath.caster.options && schemaPath.caster.options.ref) {
field.caster.ref = schemaPath.caster.options.ref;
// Caster options
if (schemaPath.caster.options) {

// ObjectID ref
if (schemaPath.caster.options.ref) {
field.caster.ref = schemaPath.caster.options.ref;
}
}
}

Expand Down
55 changes: 52 additions & 3 deletions src/schema.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,56 @@ describe('schema', () => {
});
});

it('should get data with ref fields', function* () {
it.only('should get data with ref fields', function* () {
var mother = new User({
name: 'Mother'
});

var user = new User({
name: 'User',
mother: mother
});

var findOneStub = this.sandbox.stub(User, 'findOne');

findOneStub.onFirstCall().returns(Promise.resolve(user));
findOneStub.onSecondCall().returns(Promise.resolve(mother));

var result = yield graphql(schema, `{
user(_id: "${user._id}") {
name
mother {
name
}
}
}`);

// FIXME: "Cannot read property 'map' of undefined"
// expect(findOneStub).to.calledWith({
// _id: new ObjectID(user._id.toString())
// }, {
// name: 1
// });
//
// expect(findOneStub).to.calledWith({
// _id: new ObjectID(mother._id.toString())
// }, {
// name: 1
// });

expect(result).to.be.eql({
data: {
user: {
name: 'User',
mother: {
name: 'Mother'
}
}
}
});
});

it('should get data with array of ref(s) fields', function* () {
var user1 = new User({
name: 'Foo'
});
Expand All @@ -156,7 +205,7 @@ describe('schema', () => {
friends: [user1._id]
});

var findByIdStub = this.sandbox.stub(User, 'findOne').returnsWithResolve(user2);
var findOneStub = this.sandbox.stub(User, 'findOne').returnsWithResolve(user2);
var findStub = this.sandbox.stub(User, 'find').returnsWithResolve([user1]);

var result = yield graphql(schema, `{
Expand All @@ -168,7 +217,7 @@ describe('schema', () => {
}
}`);

expect(findByIdStub).to.calledWith({
expect(findOneStub).to.calledWith({
_id: new ObjectID(user2._id.toString())
}, {
name: 1,
Expand Down

0 comments on commit 653e1d1

Please sign in to comment.