From 89ab9b3c04a58f6a5f783f16c39195a129c0e4d2 Mon Sep 17 00:00:00 2001 From: vdemedes Date: Sun, 25 Oct 2015 00:30:59 +0200 Subject: [PATCH] update repository --- .editorconfig | 6 +- .gitignore | 1 + .travis.yml | 6 + License.md | 2 +- Makefile | 11 -- Readme.md | 32 ++--- circle.yml | 3 - index.js | 360 +++++++++++++++++++++++++------------------------- package.json | 16 ++- test.js | 354 ++++++++++++++++++++++++------------------------- 10 files changed, 398 insertions(+), 393 deletions(-) create mode 100644 .travis.yml delete mode 100644 Makefile delete mode 100644 circle.yml diff --git a/.editorconfig b/.editorconfig index 2f3caa2..59fb5c3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,15 +1,17 @@ root = true [*] -indent_style = space +indent_style = tab indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true +[{package.json,*.yml}] +indent_style = space + [Makefile] -indent_style = tab indent_size = 4 [*.md] diff --git a/.gitignore b/.gitignore index 3c3629e..c9106a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +.nyc_output diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..3fbe3ae --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - 'stable' + - '0.12' + - '0.10' +after_success: npm run coveralls diff --git a/License.md b/License.md index 249a2d8..4154323 100644 --- a/License.md +++ b/License.md @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) vdemedes (https://github.com/vdemedes) +Copyright (c) Vadym Demedes (https://github.com/vdemedes) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile deleted file mode 100644 index 8488442..0000000 --- a/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -SRC = index.js - -default: - @echo "No default task" - -test: - @./node_modules/.bin/ava - -include node_modules/make-lint/index.mk - -.PHONY: test diff --git a/Readme.md b/Readme.md index aac0813..a4064ab 100644 --- a/Readme.md +++ b/Readme.md @@ -1,4 +1,6 @@ -# crown [![Circle CI](https://circleci.com/gh/vdemedes/crown.svg?style=svg)](https://circleci.com/gh/vdemedes/crown) +# Crown + +[![Build Status](https://travis-ci.org/vdemedes/crown.svg?branch=master)](https://travis-ci.org/vdemedes/crown) [![Coverage Status](https://coveralls.io/repos/vdemedes/crown/badge.svg?branch=master&service=github)](https://coveralls.io/github/vdemedes/crown?branch=master) Give access to your new features gradually. Make them available to a percentage of your users, certain group or specific users. @@ -16,7 +18,7 @@ Inspired by Ruby's [rollout](https://github.com/FetLife/rollout) gem. -### Features +## Features - Configurable backend - Roll out features to percentage of users, groups or specific users @@ -24,14 +26,14 @@ Inspired by Ruby's [rollout](https://github.com/FetLife/rollout) gem. - Promise-based API -### Installation +## Installation ``` $ npm install crown --save ``` -### Usage +## Usage ```js const Crown = require('crown'); @@ -51,7 +53,7 @@ yield rollout.enablePercentage('chat', 20); var hasChat = yield rollout.isEnabled('chat', { id: 1 }); // true ``` -#### Check if user has access to a feature +### Check if user has access to a feature To validate access of a certain user to a feature, use `isEnabled()` method. It accepts 2 arguments: `name` of the feature and `user` object. @@ -71,7 +73,7 @@ rollout.idAttribute = '_id'; ``` -#### Enable feature for everyone +### Enable feature for everyone `enable()` method gives access to all users, regardless of any other rules. @@ -86,7 +88,7 @@ yield rollout.disable('chat'); ``` -#### Enable feature for a percentage of users +### Enable feature for a percentage of users You can enable certain feature for only a percentage of all users: @@ -101,7 +103,7 @@ CRC32(user_id + feature_name) % 100 < percentage ``` -#### Enable feature for a group of users +### Enable feature for a group of users You can register a group of users, that satisfy some custom criteria: @@ -130,7 +132,7 @@ yield rollout.disableGroup('chat', 'beta-testers'); ``` -#### Enable feature for a specific user +### Enable feature for a specific user You can also restrict access to specific users: @@ -151,7 +153,7 @@ yield rollout.disableUser('chat', goodUser); ``` -### Backend stores +## Backend stores Crown can use whatever backend you want, as soon as there is an adapter for it. Take a look how easy it is to write one, check out built-in [MemoryStore](https://github.com/vdemedes/crown-memory-store/blob/master/index.js). @@ -173,15 +175,13 @@ let rollout = new Crown({ ``` -### Tests - -[![Circle CI](https://circleci.com/gh/vdemedes/crown.svg?style=svg)](https://circleci.com/gh/vdemedes/crown) +## Tests ``` -$ make test +$ npm test ``` -### License +## License -MIT © [vdemedes](https://github.com/vdemedes) +MIT © [Vadym Demedes](https://github.com/vdemedes) diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 6d74323..0000000 --- a/circle.yml +++ /dev/null @@ -1,3 +0,0 @@ -machine: - node: - version: stable diff --git a/index.js b/index.js index 29b27db..fe2b623 100644 --- a/index.js +++ b/index.js @@ -22,15 +22,17 @@ module.exports = Crown; */ function Crown (options) { - if (!(this instanceof Crown)) return new Crown(options); + if (!(this instanceof Crown)) { + return new Crown(options); + } - if (!options) { - options = {}; - } + if (!options) { + options = {}; + } - this.idAttribute = options.idAttribute || 'id'; - this.store = options.store || new MemoryStore(); - this.groups = []; + this.idAttribute = options.idAttribute || 'id'; + this.store = options.store || new MemoryStore(); + this.groups = []; } @@ -43,12 +45,12 @@ function Crown (options) { */ Crown.prototype.get = function (name) { - return this.store.get(name) - .catch(function () { - var message = format('Feature `%s` does not exist', name); + return this.store.get(name) + .catch(function () { + var message = format('Feature `%s` does not exist', name); - return Promise.reject(message); - }); + return Promise.reject(message); + }); }; @@ -61,10 +63,10 @@ Crown.prototype.get = function (name) { */ Crown.prototype.group = function (name, validator) { - this.groups.push({ - name: name, - validate: validator - }); + this.groups.push({ + name: name, + validate: validator + }); }; @@ -77,7 +79,7 @@ Crown.prototype.group = function (name, validator) { */ Crown.prototype.enable = function (name) { - return this.enablePercentage(name, 100); + return this.enablePercentage(name, 100); }; @@ -90,7 +92,7 @@ Crown.prototype.enable = function (name) { */ Crown.prototype.disable = function (name) { - return this.store.destroy(name); + return this.store.destroy(name); }; @@ -103,9 +105,9 @@ Crown.prototype.disable = function (name) { */ Crown.prototype.enablePercentage = function (name, percentage) { - return this.store.set(name, { - percentage: percentage - }); + return this.store.set(name, { + percentage: percentage + }); }; @@ -119,28 +121,28 @@ Crown.prototype.enablePercentage = function (name, percentage) { */ Crown.prototype.enableGroups = function (name, groups) { - if (!Array.isArray(groups)) { - groups = [groups]; - } - - var store = this.store; - - return store.get(name) - .catch(function () { - // initialize a new feature - // if it does not exist - return {}; - }) - .then(function (feature) { - if (!feature.groups) { - feature.groups = []; - } - - // merge group names - feature.groups.push.apply(feature.groups, groups); - - return store.set(name, feature); - }); + if (!Array.isArray(groups)) { + groups = [groups]; + } + + var store = this.store; + + return store.get(name) + .catch(function () { + // initialize a new feature + // if it does not exist + return {}; + }) + .then(function (feature) { + if (!feature.groups) { + feature.groups = []; + } + + // merge group names + feature.groups.push.apply(feature.groups, groups); + + return store.set(name, feature); + }); }; @@ -149,7 +151,7 @@ Crown.prototype.enableGroups = function (name, groups) { */ Crown.prototype.enableGroup = function () { - return this.enableGroups.apply(this, arguments); + return this.enableGroups.apply(this, arguments); }; @@ -163,28 +165,28 @@ Crown.prototype.enableGroup = function () { */ Crown.prototype.disableGroups = function (name, groups) { - if (!Array.isArray(groups)) { - groups = [groups]; - } + if (!Array.isArray(groups)) { + groups = [groups]; + } - var store = this.store; + var store = this.store; - return this.get(name) - .then(function (feature) { - if (!feature.groups) { - return; - } + return this.get(name) + .then(function (feature) { + if (!feature.groups) { + return; + } - groups.forEach(function (group) { - var index = feature.groups.indexOf(group); + groups.forEach(function (group) { + var index = feature.groups.indexOf(group); - if (index >= 0) { - feature.groups.splice(index, 1); - } - }); + if (index >= 0) { + feature.groups.splice(index, 1); + } + }); - return store.set(name, feature); - }); + return store.set(name, feature); + }); }; @@ -193,7 +195,7 @@ Crown.prototype.disableGroups = function (name, groups) { */ Crown.prototype.disableGroup = function () { - return this.disableGroups.apply(this, arguments); + return this.disableGroups.apply(this, arguments); }; @@ -207,32 +209,32 @@ Crown.prototype.disableGroup = function () { */ Crown.prototype.enableUsers = function (name, users) { - if (!Array.isArray(users)) { - users = [users]; - } - - // extract ids from each array item - // include only truthy values in a result - users = users.map(this._extractId, this).filter(truthy); - - var store = this.store; - - return store.get(name) - .catch(function () { - // initialize a new feature - // when it does not exist - return {}; - }) - .then(function (feature) { - if (!feature.users) { - feature.users = []; - } - - // merge user ids - feature.users.push.apply(feature.users, users); - - return store.set(name, feature); - }); + if (!Array.isArray(users)) { + users = [users]; + } + + // extract ids from each array item + // include only truthy values in a result + users = users.map(this._extractId, this).filter(truthy); + + var store = this.store; + + return store.get(name) + .catch(function () { + // initialize a new feature + // when it does not exist + return {}; + }) + .then(function (feature) { + if (!feature.users) { + feature.users = []; + } + + // merge user ids + feature.users.push.apply(feature.users, users); + + return store.set(name, feature); + }); }; @@ -241,7 +243,7 @@ Crown.prototype.enableUsers = function (name, users) { */ Crown.prototype.enableUser = function () { - return this.enableUsers.apply(this, arguments); + return this.enableUsers.apply(this, arguments); }; @@ -255,32 +257,32 @@ Crown.prototype.enableUser = function () { */ Crown.prototype.disableUsers = function (name, users) { - if (!Array.isArray(users)) { - users = [users]; - } + if (!Array.isArray(users)) { + users = [users]; + } - // extract ids from each array item - // include only truthy values in a result - users = users.map(this._extractId, this).filter(truthy); + // extract ids from each array item + // include only truthy values in a result + users = users.map(this._extractId, this).filter(truthy); - var store = this.store; + var store = this.store; - return this.get(name) - .then(function (feature) { - if (!feature.users) { - return; - } + return this.get(name) + .then(function (feature) { + if (!feature.users) { + return; + } - users.forEach(function (id) { - var index = feature.users.indexOf(id); + users.forEach(function (id) { + var index = feature.users.indexOf(id); - if (index >= 0) { - feature.users.splice(index, 1); - } - }); + if (index >= 0) { + feature.users.splice(index, 1); + } + }); - return store.set(name, feature); - }); + return store.set(name, feature); + }); }; @@ -289,7 +291,7 @@ Crown.prototype.disableUsers = function (name, users) { */ Crown.prototype.disableUser = function () { - return this.disableUsers.apply(this, arguments); + return this.disableUsers.apply(this, arguments); }; @@ -303,57 +305,57 @@ Crown.prototype.disableUser = function () { */ Crown.prototype.isEnabled = function (name, user) { - var id = this._extractId(user); - - var self = this; - - return this.store.get(name) - .then(function (feature) { - // if feature has groups - var hasGroups = feature.groups && feature.groups.length > 0; - - if (user && hasGroups) { - // validate that this user - // belongs to at least one group - var groups = self.groups.filter(function (group) { - return group.validate(user); - }); - - // extract group names - var groupNames = groups.map(function (group) { - return group.name; - }); - - // check if feature includes any of user's groups - if (has(feature.groups, groupNames)) { - return true; - } - } - - // if feature has users - var hasUsers = feature.users && feature.users.length > 0; - - if (user && hasUsers) { - // check if feature includes this user's id - if (has(feature.users, [id])) { - return true; - } - } - - // if feature has percentage - var hasPercentage = Number.isInteger(feature.percentage); - - if (hasPercentage) { - // calculate if this user belongs to an enabled sector - // CRC32(user_id + feature_name) % 100 < percentage - return crc32.unsigned(id + name) % 100 < feature.percentage; - } - - return false; - }) - .catch(function () { - return false; - }); + var id = this._extractId(user); + + var self = this; + + return this.store.get(name) + .then(function (feature) { + // if feature has groups + var hasGroups = feature.groups && feature.groups.length > 0; + + if (user && hasGroups) { + // validate that this user + // belongs to at least one group + var groups = self.groups.filter(function (group) { + return group.validate(user); + }); + + // extract group names + var groupNames = groups.map(function (group) { + return group.name; + }); + + // check if feature includes any of user's groups + if (has(feature.groups, groupNames)) { + return true; + } + } + + // if feature has users + var hasUsers = feature.users && feature.users.length > 0; + + if (user && hasUsers) { + // check if feature includes this user's id + if (has(feature.users, [id])) { + return true; + } + } + + // if feature has percentage + var hasPercentage = Number.isInteger(feature.percentage); + + if (hasPercentage) { + // calculate if this user belongs to an enabled sector + // CRC32(user_id + feature_name) % 100 < percentage + return crc32.unsigned(id + name) % 100 < feature.percentage; + } + + return false; + }) + .catch(function () { + return false; + }); }; @@ -366,19 +368,19 @@ Crown.prototype.isEnabled = function (name, user) { */ Crown.prototype._extractId = function (user) { - var id = ''; + var id = ''; - if (typeof user === 'object') { - // if `user` object has get() method - // use it to get the value - id = user.get ? user.get(this.idAttribute) : user[this.idAttribute]; - } + if (typeof user === 'object') { + // if `user` object has get() method + // use it to get the value + id = user.get ? user.get(this.idAttribute) : user[this.idAttribute]; + } - if (typeof user === 'string' || typeof user === 'number') { - id = user.toString(); - } + if (typeof user === 'string' || typeof user === 'number') { + id = user.toString(); + } - return id; + return id; }; @@ -388,18 +390,18 @@ Crown.prototype._extractId = function (user) { // used for .filter() to eliminate falthy values function truthy (item) { - return !!item; + return !!item; } // check if `arr` has any of `items` array values function has (arr, items) { - var result = false; + var result = false; - items.forEach(function (item) { - if (arr.indexOf(item) >= 0) { - result = true; - } - }); + items.forEach(function (item) { + if (arr.indexOf(item) >= 0) { + result = true; + } + }); - return result; + return result; } diff --git a/package.json b/package.json index 35cda42..0ccdacb 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,13 @@ "main": "index.js", "repository": "vdemedes/crown", "author": { - "name": "Vadim", + "name": "Vadim Demedes", "email": "vdemedes@gmail.com", "url": "https://github.com/vdemedes" }, "scripts": { - "test": "make test" + "test": "xo && nyc ava", + "coveralls": "nyc report --reporter=text-lcov | coveralls" }, "dependencies": { "buffer-crc32": "^0.2.5", @@ -20,9 +21,16 @@ }, "devDependencies": { "ava": "sindresorhus/ava", - "make-lint": "^1.0.1" + "coveralls": "^2.11.4", + "eslint-config-vdemedes": "*", + "nyc": "^3.2.2", + "xo": "^0.10.0" }, "files": [ "index.js" - ] + ], + "xo": { + "extends": "vdemedes", + "env": "node" + } } diff --git a/test.js b/test.js index 9e49bb9..9dffb3d 100644 --- a/test.js +++ b/test.js @@ -12,253 +12,253 @@ const test = require('ava'); * Tests */ -test ('enable feature for all users', function * (t) { - t.plan(3); +test('enable feature for all users', function * (t) { + t.plan(3); - let rollout = Crown(); + let rollout = new Crown(); - yield rollout.enable('chat'); + yield rollout.enable('chat'); - let feature = yield rollout.get('chat'); - t.same(feature, { - percentage: 100 - }); + let feature = yield rollout.get('chat'); + t.same(feature, { + percentage: 100 + }); - // check if random user has access - let isEnabled = yield rollout.isEnabled('chat', { id: 1 }); - t.true(isEnabled); + // check if random user has access + let isEnabled = yield rollout.isEnabled('chat', { id: 1 }); + t.true(isEnabled); - // check if all users have access - isEnabled = yield rollout.isEnabled('chat'); - t.true(isEnabled); + // check if all users have access + isEnabled = yield rollout.isEnabled('chat'); + t.true(isEnabled); }); -test ('disable feature for all users', function * (t) { - t.plan(2); +test('disable feature for all users', function * (t) { + t.plan(2); - let rollout = Crown(); + let rollout = new Crown(); - yield rollout.enable('chat'); + yield rollout.enable('chat'); - let isEnabled = yield rollout.isEnabled('chat'); - t.true(isEnabled); + let isEnabled = yield rollout.isEnabled('chat'); + t.true(isEnabled); - yield rollout.disable('chat'); + yield rollout.disable('chat'); - isEnabled = yield rollout.isEnabled('chat'); - t.false(isEnabled); + isEnabled = yield rollout.isEnabled('chat'); + t.false(isEnabled); }); -test ('enable feature for a group of users', function * (t) { - t.plan(4); +test('enable feature for a group of users', function * (t) { + t.plan(4); - let rollout = Crown(); + let rollout = new Crown(); - rollout.group('beta-testers', function (user) { - return user.role === 'beta-tester'; - }); + rollout.group('beta-testers', function (user) { + return user.role === 'beta-tester'; + }); - rollout.group('alpha-testers', function (user) { - return user.role === 'alpha-tester'; - }); + rollout.group('alpha-testers', function (user) { + return user.role === 'alpha-tester'; + }); - yield rollout.enableGroup('chat', 'beta-testers'); - yield rollout.enableGroup('chat', 'alpha-testers'); + yield rollout.enableGroup('chat', 'beta-testers'); + yield rollout.enableGroup('chat', 'alpha-testers'); - let feature = yield rollout.get('chat'); - t.same(feature, { - groups: ['beta-testers', 'alpha-testers'] - }); + let feature = yield rollout.get('chat'); + t.same(feature, { + groups: ['beta-testers', 'alpha-testers'] + }); - // check if beta-tester has access - let isEnabled = yield rollout.isEnabled('chat', { id: 1, role: 'beta-tester' }); - t.true(isEnabled); + // check if beta-tester has access + let isEnabled = yield rollout.isEnabled('chat', { id: 1, role: 'beta-tester' }); + t.true(isEnabled); - // check if alpha-tester has access - isEnabled = yield rollout.isEnabled('chat', { id: 1, role: 'alpha-tester' }); - t.true(isEnabled); + // check if alpha-tester has access + isEnabled = yield rollout.isEnabled('chat', { id: 1, role: 'alpha-tester' }); + t.true(isEnabled); - // check if regular user has access - isEnabled = yield rollout.isEnabled('chat', { id: 1 }); - t.false(isEnabled); + // check if regular user has access + isEnabled = yield rollout.isEnabled('chat', { id: 1 }); + t.false(isEnabled); }); -test ('disable feature for a group', function * (t) { - t.plan(6); +test('disable feature for a group', function * (t) { + t.plan(6); - let rollout = Crown(); + let rollout = new Crown(); - rollout.group('beta-testers', function (user) { - return user.role === 'beta-tester'; - }); + rollout.group('beta-testers', function (user) { + return user.role === 'beta-tester'; + }); - rollout.group('alpha-testers', function (user) { - return user.role === 'alpha-tester'; - }); + rollout.group('alpha-testers', function (user) { + return user.role === 'alpha-tester'; + }); - yield rollout.enableGroup('chat', 'beta-testers'); - yield rollout.enableGroup('chat', 'alpha-testers'); + yield rollout.enableGroup('chat', 'beta-testers'); + yield rollout.enableGroup('chat', 'alpha-testers'); - let feature = yield rollout.get('chat'); - t.same(feature, { - groups: ['beta-testers', 'alpha-testers'] - }); + let feature = yield rollout.get('chat'); + t.same(feature, { + groups: ['beta-testers', 'alpha-testers'] + }); - // check if beta-tester has access - let isEnabled = yield rollout.isEnabled('chat', { id: 1, role: 'beta-tester'}); - t.true(isEnabled); + // check if beta-tester has access + let isEnabled = yield rollout.isEnabled('chat', { id: 1, role: 'beta-tester' }); + t.true(isEnabled); - // check if alpha-tester has access - isEnabled = yield rollout.isEnabled('chat', { id: 1, role: 'alpha-tester' }); - t.true(isEnabled); + // check if alpha-tester has access + isEnabled = yield rollout.isEnabled('chat', { id: 1, role: 'alpha-tester' }); + t.true(isEnabled); - yield rollout.disableGroup('chat', 'beta-testers'); + yield rollout.disableGroup('chat', 'beta-testers'); - feature = yield rollout.get('chat'); - t.same(feature, { - groups: ['alpha-testers'] - }); + feature = yield rollout.get('chat'); + t.same(feature, { + groups: ['alpha-testers'] + }); - // check if beta-tester has access - isEnabled = yield rollout.isEnabled('chat', { id: 1, role: 'beta-tester'}); - t.false(isEnabled); + // check if beta-tester has access + isEnabled = yield rollout.isEnabled('chat', { id: 1, role: 'beta-tester' }); + t.false(isEnabled); - // check if alpha-tester has access - isEnabled = yield rollout.isEnabled('chat', { id: 1, role: 'alpha-tester' }); - t.true(isEnabled); + // check if alpha-tester has access + isEnabled = yield rollout.isEnabled('chat', { id: 1, role: 'alpha-tester' }); + t.true(isEnabled); }); -test ('enable feature for specific users', function * (t) { - t.plan(3); +test('enable feature for specific users', function * (t) { + t.plan(3); - let rollout = Crown(); + let rollout = new Crown(); - yield rollout.enableUser('chat', { id: 1 }); + yield rollout.enableUser('chat', { id: 1 }); - let feature = yield rollout.get('chat'); - t.same(feature, { - users: [1] - }); + let feature = yield rollout.get('chat'); + t.same(feature, { + users: [1] + }); - // check if allowed user has access - let isEnabled = yield rollout.isEnabled('chat', { id: 1 }); - t.true(isEnabled); + // check if allowed user has access + let isEnabled = yield rollout.isEnabled('chat', { id: 1 }); + t.true(isEnabled); - // check if 3rd-party user has access - isEnabled = yield rollout.isEnabled('chat', { id: 2 }); - t.false(isEnabled); + // check if 3rd-party user has access + isEnabled = yield rollout.isEnabled('chat', { id: 2 }); + t.false(isEnabled); }); -test ('enable feature for a specific user by id', function * (t) { - t.plan(3); +test('enable feature for a specific user by id', function * (t) { + t.plan(3); - let rollout = Crown(); + let rollout = new Crown(); - yield rollout.enableUser('chat', 1); + yield rollout.enableUser('chat', 1); - let feature = yield rollout.get('chat'); - t.same(feature, { - users: [1] - }); + let feature = yield rollout.get('chat'); + t.same(feature, { + users: ['1'] + }); - // check if allowed user has access - let isEnabled = yield rollout.isEnabled('chat', 1); - t.true(isEnabled); + // check if allowed user has access + let isEnabled = yield rollout.isEnabled('chat', 1); + t.true(isEnabled); - // check if 3rd-party user has access - isEnabled = yield rollout.isEnabled('chat', 2); - t.false(isEnabled); + // check if 3rd-party user has access + isEnabled = yield rollout.isEnabled('chat', 2); + t.false(isEnabled); }); -test ('enable feature for a specific user by string id', function * (t) { - t.plan(3); +test('enable feature for a specific user by string id', function * (t) { + t.plan(3); - let rollout = Crown(); + let rollout = new Crown(); - yield rollout.enableUser('chat', '1'); + yield rollout.enableUser('chat', '1'); - let feature = yield rollout.get('chat'); - t.same(feature, { - users: [1] - }); + let feature = yield rollout.get('chat'); + t.same(feature, { + users: ['1'] + }); - // check if allowed user has access - let isEnabled = yield rollout.isEnabled('chat', '1'); - t.true(isEnabled); + // check if allowed user has access + let isEnabled = yield rollout.isEnabled('chat', '1'); + t.true(isEnabled); - // check if 3rd-party user has access - isEnabled = yield rollout.isEnabled('chat', '2'); - t.false(isEnabled); -}) + // check if 3rd-party user has access + isEnabled = yield rollout.isEnabled('chat', '2'); + t.false(isEnabled); +}); -test ('disable feature for specific users', function * (t) { - t.plan(6); +test('disable feature for specific users', function * (t) { + t.plan(6); - let rollout = Crown(); + let rollout = new Crown(); - yield rollout.enableUser('chat', 1); - yield rollout.enableUser('chat', 2); + yield rollout.enableUser('chat', 1); + yield rollout.enableUser('chat', 2); - let feature = yield rollout.get('chat'); - t.same(feature, { - users: [1, 2] - }); + let feature = yield rollout.get('chat'); + t.same(feature, { + users: ['1', '2'] + }); - // check if allowed users have access - let isEnabled = yield rollout.isEnabled('chat', 1); - t.true(isEnabled); + // check if allowed users have access + let isEnabled = yield rollout.isEnabled('chat', 1); + t.true(isEnabled); - isEnabled = yield rollout.isEnabled('chat', 2); - t.true(isEnabled); + isEnabled = yield rollout.isEnabled('chat', 2); + t.true(isEnabled); - yield rollout.disableUser('chat', 1); + yield rollout.disableUser('chat', 1); - feature = yield rollout.get('chat'); - t.same(feature, { - users: [2] - }); + feature = yield rollout.get('chat'); + t.same(feature, { + users: ['2'] + }); - // check if allowed user has access - isEnabled = yield rollout.isEnabled('chat', 1); - t.false(isEnabled); + // check if allowed user has access + isEnabled = yield rollout.isEnabled('chat', 1); + t.false(isEnabled); - isEnabled = yield rollout.isEnabled('chat', 2); - t.true(isEnabled); + isEnabled = yield rollout.isEnabled('chat', 2); + t.true(isEnabled); }); -test ('enable feature for a percentage of users', function * (t) { - t.plan(5); +test('enable feature for a percentage of users', function * (t) { + t.plan(5); - let rollout = Crown(); + let rollout = new Crown(); - // test 20% with 120 users - yield rollout.enablePercentage('chat', 20); + // test 20% with 120 users + yield rollout.enablePercentage('chat', 20); - let feature = yield rollout.get('chat'); - t.same(feature, { - percentage: 20 - }); + let feature = yield rollout.get('chat'); + t.same(feature, { + percentage: 20 + }); - let users = yield testFeature(rollout, 'chat', 120); + let users = yield testFeature(rollout, 'chat', 120); - t.true(users >= 19 && users <= 21); + t.true(users >= 19 && users <= 21); - // test 20% with 200 users - users = yield testFeature(rollout, 'chat', 200); + // test 20% with 200 users + users = yield testFeature(rollout, 'chat', 200); - t.true(users >= 35 && users <= 45); + t.true(users >= 35 && users <= 45); - // test 5% with 100 users - yield rollout.enablePercentage('chat', 5); + // test 5% with 100 users + yield rollout.enablePercentage('chat', 5); - feature = yield rollout.get('chat'); - t.same(feature, { - percentage: 5 - }); + feature = yield rollout.get('chat'); + t.same(feature, { + percentage: 5 + }); - users = yield testFeature(rollout, 'chat', 100); + users = yield testFeature(rollout, 'chat', 100); - t.true(users >= 3 && users <= 7); + t.true(users >= 3 && users <= 7); }); @@ -267,17 +267,17 @@ test ('enable feature for a percentage of users', function * (t) { */ function * testFeature (rollout, feature, total) { - let users = 0; + let users = 0; - while (total > 0) { - let isEnabled = yield rollout.isEnabled(feature, { id: total }); + while (total > 0) { + let isEnabled = yield rollout.isEnabled(feature, { id: total }); - if (isEnabled) { - users++; - } + if (isEnabled) { + users++; + } - total--; - } + total--; + } - return users; + return users; }