Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Major overhaul / 2.0 #51

Open
wants to merge 61 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
fba3858
Fix typo in release notes
baranga Apr 15, 2019
8113b3f
Replace mocha by jest
baranga May 27, 2019
f14d9f3
Rewrite middleware layer
baranga May 27, 2019
c1e2d15
Rewrite api middleware layer
baranga Jun 4, 2019
f4758d8
Add options builder
baranga Jun 4, 2019
749ac46
Rewrite schema middleware layer
baranga Jun 19, 2019
fa90849
Add new entrypoint
baranga Jun 19, 2019
e5b5931
Add more api middleware layer tests
baranga Jun 19, 2019
dedb564
Add some plugin level tests
baranga Jun 19, 2019
58e88cb
Add empty unit test suites to include all files in coverage
baranga Jun 19, 2019
af75cb9
Fix documentation of default value
baranga Jun 19, 2019
9eed2ce
Fix hinting
baranga Jun 19, 2019
6c05e16
Fix jshint issues
baranga Jun 19, 2019
3c69811
Replace jshint with prettier
baranga Jun 19, 2019
d8b91a1
Update nodejs version to test for to currently supported ones
baranga Jun 19, 2019
be4a53d
Specify jest test env to get rid of mongoose warnings
baranga Jun 19, 2019
8592363
Improve travis runtime by separating integration testing
baranga Jun 19, 2019
5e9fd49
Revert "Improve travis runtime by separating integration testing"
baranga Jun 19, 2019
d8d6235
Implement missing tests
baranga Jun 19, 2019
61922b2
Add first integration tests for rewrite
baranga Jun 21, 2019
528fa31
Adjust travis to change test commands
baranga Jun 21, 2019
f8054c1
Fix issue with tenant id getter
baranga Jun 21, 2019
1cbbe82
Reformat code
baranga Jun 21, 2019
3e081b8
Add findOneAndReplace middleware guards
baranga Jun 21, 2019
6fb5075
Extend code doc
baranga Jun 21, 2019
3c793d3
Fix code style issue
baranga Jun 21, 2019
d9b35c5
Stabilize some integration tests
baranga Jun 21, 2019
d5bc4c7
Fix issue with mongoose 4 aggregate
baranga Jun 21, 2019
53d4731
Extract aggregate argument parsing into dedicated module for better t…
baranga Jun 22, 2019
7fe1786
Add some tenant id override protection integration tests
baranga Jun 22, 2019
64f2045
Add skiped tests for missing methods
baranga Jun 22, 2019
85eba55
Fix missing protection against tenant id override for `updateOne` and…
baranga Jun 22, 2019
d6e03f3
Add experimental handling of bulkWrite
baranga Jun 23, 2019
495fab3
Implement missing tests for findById and findByIdAnd*
baranga Jun 23, 2019
e04e49c
Fix typo in comment
baranga Jun 23, 2019
8f4ae65
Implement missing tests for save middleware
baranga Jun 23, 2019
92bb632
Add integtration tests for compounded indexes
baranga Jun 25, 2019
adf082b
Fix field level compound index creation
baranga Jun 25, 2019
43ce13e
Document first breaking changes to keep track of them
baranga Jun 25, 2019
889e7b8
Update release-notes cli dependency
baranga Jun 25, 2019
c8811dd
Fix issue with field level indexes
baranga Jun 25, 2019
e5e81ce
Upgrade mongoose and mongodb dev dependencies
baranga Jun 25, 2019
81be9df
Port integration tests to mongodb 3.x client
baranga Jun 25, 2019
aab3481
Prevent long running failed integration tests on ci
baranga Jun 25, 2019
d6372ba
Consider index options of field level indexes as well
baranga Jun 25, 2019
815ea66
Fix potenttial mongodb / mongodb driver issue
baranga Jun 25, 2019
f0f4ee2
Fix broken tests
baranga Jun 25, 2019
76bb242
Add integration test for subschemas and discriminators
baranga Jun 26, 2019
7217431
Fix broken unit tests
baranga Jun 26, 2019
efd0886
Implement missing handling of findOneAndReplace and replaceOne
baranga Jun 26, 2019
df2c51d
Add integration test for insertMany
baranga Jun 26, 2019
8721d04
Improve insertMany integration test
baranga Jun 26, 2019
6e16c99
Fix insertMany
baranga Jun 27, 2019
b9f0516
Fix casting of result of insertMany
baranga Jun 28, 2019
23db6b2
Improve robustness of integration testing index handling
baranga Jun 28, 2019
29f99bc
Modify signature of sub components to be plugin compatible
baranga Jun 29, 2019
8d7fadd
Make tenantId required by default and fix issue with save revealed by…
baranga Jul 1, 2019
bcdd565
Rework plugin to allow multi dimensional setups
baranga Jul 3, 2019
b65f0e7
Implement simple collection separation by dimensio
baranga Jul 3, 2019
86aac44
Fix failing test
baranga Jul 3, 2019
0da3fd1
Fix integration test
baranga Jul 3, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .jshintignore

This file was deleted.

5 changes: 0 additions & 5 deletions .jshintrc

This file was deleted.

5 changes: 5 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"bracketSpacing": false,
"singleQuote": true,
"trailingComma": "es5"
}
11 changes: 5 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
language: node_js
node_js:
- "12"
- "10"
- "8"
- "6"
- "4"
env:
- MONGOOSE_VERSION=5
- MONGOOSE_VERSION=4
Expand All @@ -16,13 +16,12 @@ install:
- yarn
- yarn add --dev mongoose@^$MONGOOSE_VERSION
script:
- yarn hint
- yarn test-and-cover
- yarn test:all
jobs:
include:
- stage: deploy
if: env(MONGOOSE_VERSION) = 5
node_js: "8"
node_js: "12"
script:
- yarn test-and-cover
- yarn test:coverage
- yarn coveralls
5 changes: 5 additions & 0 deletions jest.config.integration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const testConfig = require('./jest.config');
module.exports = {
...testConfig,
testMatch: ['**/?(*.)+(test.integration).js'],
};
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
testEnvironment: 'node',
};
27 changes: 14 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@
"mongo"
],
"scripts": {
"hint": "jshint .",
"test": "mocha --exit",
"test-and-cover": "nyc --reporter=html --reporter=text npm run test",
"coveralls": "nyc report --reporter=text-lcov | coveralls",
"test": "yarn test:all",
"test:all": "yarn test:style && yarn test:coverage && yarn test:integration",
"test:style": "prettier -c src/**/*.js",
"test:unit": "jest",
"test:coverage": "jest --coverage",
"test:integration": "jest --config ./jest.config.integration.js --forceExit",
"coveralls": "coveralls < ./coverage/lcov.info",
"validate-release-notes": "release-notes validate"
},
"main": "index.js",
"main": "src/index.js",
"bugs": {
"url": "https://github.com/craftup/node-mongo-tenant/issues"
},
Expand All @@ -32,15 +35,13 @@
},
"license": "MIT",
"devDependencies": {
"@release-notes/cli": "^0.1.0",
"chai": "^4.1.2",
"@release-notes/cli": "^0.3.0",
"coveralls": "^3.0.0",
"jshint": "^2.9.5",
"mocha": "^5.0.4",
"mocha-mongoose": "^1.2.0",
"mongodb": "^2.2.35",
"mongoose": "^5.0.11",
"nyc": "^11.6.0"
"jest": "^24.8.0",
"mongodb": "^3.2.7",
"mongoose": "^5.6.1",
"nyc": "^11.6.0",
"prettier": "^1.18.2"
},
"peerDependencies": {
"mongoose": ">=4.3.0 <=4.8.0 || >=4.8.3"
Expand Down
23 changes: 22 additions & 1 deletion release-notes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,30 @@ description: >
document level (for now...). It creates a tenant-reference field and takes care of unique indexes.
Also it provides access to tenant-bound model-classes, that prohibit the exploid of the given tenant scope.
Last but not least the "MAGIC" can be disabled so that shipping of the same code in single- and
multi-tenancy environment (on premis vs. cloud hosted) is a question of a single line of config.
multi-tenancy environment (on premise vs. cloud hosted) is a question of a single line of config.

releases:
- version: Unreleased
added:
- >
Plugin can now be applied multiple times on single schema to achieve multi dimensional setups.

To achieve this a new config option named `dimension` is available. This is the prime indicator for compatibility
between two different plugin instances. That option is optional with `tenant` as default so backward compatibility
is guaranteed.
- 'Full support of path level index options (`new Schema({t: {type: String, index: {...}})`).'
changed:
- >
**BREAKING** Default value of option to make tenant id required is now `true` instead of `false`. This changes the
default behaviour.
removed:
- >
**BREAKING** Schemas, Models and Documents no longer expose `hasTenantContext` to indicate if the plugin is
applied to them.
- >
**BREAKING** Schema types no longer support the shorthand `partialFilterExpression` option. That shorthand option
was never supported by mongoose in the first place. If that option is needed please use
`{..., index: { partialFilterExpression: ...}}` instead.
- version: 1.6.0
date: 2019-03-21
fixed:
Expand Down
28 changes: 28 additions & 0 deletions src/api/are-plugins-compatible.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Check if something looks like options
* @param {MongoTenantOptions} options
* @returns {boolean}
*/
const isPluginOptions = options =>
(options &&
options.dimension &&
options.accessorMethod &&
options.dimensionIdKey &&
true) ||
false;
/**
* Checks if instance is compatible to other plugin instance
*
* For population of referenced models it's necessary to detect if the tenant
* plugin installed in these models is compatible to the plugin of the host
* model. This is done by comparing the dimension key.
*
* @param {MongoTenantOptions} a
* @param {MongoTenantOptions} b
* @returns {boolean}
*/
module.exports = (a, b) => {
return (
isPluginOptions(a) && isPluginOptions(b) && a.dimension === b.dimension
);
};
28 changes: 28 additions & 0 deletions src/api/are-plugins-compatible.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const arePluginsCompatible = require('./are-plugins-compatible');

describe('are-plugins-compatible', () => {
describe('when called with proper plugin options', () => {
const options = {
dimension: 'dim',
accessorMethod: 'byDim',
dimensionIdKey: 'dimId',
};

it("returns true if they have equal dimension's", () => {
const a = {...options};
const b = {...options};
const result = arePluginsCompatible(a, b);
expect(result).toBe(true);
});

it("returns false if they have different dimension's", () => {
const a = {...options};
const b = {
...options,
dimension: 'universe',
};
const result = arePluginsCompatible(a, b);
expect(result).toBe(false);
});
});
});
27 changes: 27 additions & 0 deletions src/api/dimension-aware-db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const arePluginsCompatible = require('./are-plugins-compatible');
const dimensionInterface = require('../dimension-interface');

/**
* Create db connection bound to a specific dimension
*
* @param {Connection} db
* @param {*} dimensionId
* @param {MongoTenantOptions} options
* @returns {Connection}
*/
module.exports = ({db, dimensionId, options}) => {
const awareDb = Object.create(db);
awareDb.model = name => {
const unawareModel = db.model(name);
const otherPluginOptions = dimensionInterface(unawareModel.schema).get(
options.dimension
);

if (!arePluginsCompatible(options, otherPluginOptions)) {
return unawareModel;
}

return unawareModel[otherPluginOptions.accessorMethod](dimensionId);
};
return awareDb;
};
52 changes: 52 additions & 0 deletions src/api/dimension-aware-db.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const buildOptions = require('../options');
const createDimensionAwareDb = require('./dimension-aware-db');
const dimensionInterface = require('../dimension-interface');

describe('dimension-aware-db', () => {
describe('when called with proper parameters', () => {
const dimension = 'dim';
const dimensionId = '23';
const options = buildOptions({dimension});

it('overwrites the model method', () => {
const db = {
model: () => {},
};
const result = createDimensionAwareDb({db, dimensionId, options});
expect(result).toHaveProperty('model');
expect(result.model).toBeInstanceOf(Function);
expect(result.model).not.toBe(db.model);
});

it('returns a dimension aware model if compatible', () => {
const awareModel = {};
const unawareModel = {
schema: {},
[options.accessorMethod]: () => awareModel,
};
dimensionInterface(unawareModel.schema).add(dimension, options);
const db = {
model: () => unawareModel,
};

const awareDb = createDimensionAwareDb({db, dimensionId, options});
const result = awareDb.model('test');

expect(result).toBe(awareModel);
});

it('returns a dimension unaware model if not compatible', () => {
const unawareModel = {
schema: {},
};
const db = {
model: () => unawareModel,
};

const awareDb = createDimensionAwareDb({db, dimensionId, options});
const result = awareDb.model('test');

expect(result).toBe(unawareModel);
});
});
});
Loading