UNPKG

8.77 kBJavaScriptView Raw
1/*eslint no-magic-numbers: "off"*/
2/*eslint no-invalid-this: "off"*/
3const _ = require('lodash');
4const chai = require('chai');
5const expect = chai.expect;
6const asPromised = require('chai-as-promised');
7const Promise = require('bluebird');
8const TestConfig = require('../config');
9const Utils = require('../utils');
10const Mutators = require('../../app/services/mutators');
11const ObjectId = require('../../app/models/objectId');
12const createRedisClient = require('../../config/redis');
13const config = require('../../config/index');
14chai.use(asPromised);
15
16const log = config.log;
17
18Promise.longStackTraces();
19Promise.onPossiblyUnhandledRejection((error) => log.error('Likely error: ', error.stack));
20
21const ns = 'namespace';
22const id = 'id';
23const topLevelArguments = {
24 first: 'this thing',
25 second: 'other thing'
26};
27const specificArguments = {
28 second: 'second thing',
29 third: 'last thing'
30};
31const validateMutator = (mutator) => {
32 expect(_.isFunction(mutator.predicate)).is.true;
33 expect(_.isFunction(mutator.mutate)).is.true;
34};
35
36describe('mutators service', function () {
37 this.timeout(5000);
38
39 let redis = null;
40 let mutators = null;
41 let objectId = null;
42 let utils = null;
43
44 before((done) => {
45 redis = createRedisClient(TestConfig.redis.host, TestConfig.redis.port);
46 mutators = new Mutators(redis);
47 utils = new Utils();
48 done();
49 });
50
51 after((done) => {
52 redis.flushdb().finally(() => done());
53 });
54
55 beforeEach((done) => {
56 objectId = new ObjectId({namespace: ns, id: id});
57 redis.flushdb().finally(() => done());
58 });
59
60 it('invalid id', (done) => {
61 objectId.id = '~badId';
62 mutators.add(objectId, 'dummySrc')
63 .then(() => done('fail'))
64 .catch((e) => expect(e.message).equals("Id must be string of 1-40 alphanumeric characters, given '~badId'"))
65 .then(() => done());
66 });
67
68 it('invalid src type', (done) => {
69 mutators.add(objectId, {})
70 .then(() => done('fail'))
71 .catch((e) => expect(e.message).equals('mutatorSrc must be string'))
72 .then(() => done());
73 });
74
75 it('invalid javascript', (done) => {
76 mutators.add(objectId, utils.loadFile(`${__dirname}/invalidMutators/notAJsFile`))
77 .then(() => done('fail'))
78 .catch((e) => expect(e.message).equals("Unable to load external module due to 'SyntaxError - Unexpected identifier'"))
79 .then(() => done());
80 });
81
82 it('mutator missing type', (done) => {
83 mutators.add(objectId, utils.loadFile(`${__dirname}/invalidMutators/noType.js`))
84 .then(() => done('fail'))
85 .catch((e) => expect(e.message).equals('Mutator type string not provided'))
86 .then(() => done());
87 }
88 );
89
90 it('mutator invalid type', (done) => {
91 mutators.add(objectId, utils.loadFile(`${__dirname}/invalidMutators/invalidType.js`))
92 .then(() => done('fail'))
93 .catch((e) => expect(e.message).equals(`Mutator type 'wrong' not one of: [${Mutators.TYPES}]`))
94 .then(() => done());
95 });
96
97 it('mutator missing predicate', (done) => {
98 mutators.add(objectId, utils.loadFile(`${__dirname}/invalidMutators/noPredicate.js`))
99 .then(() => done('fail'))
100 .catch((e) => expect(e.message).equals('Mutator predicate() not provided'))
101 .then(() => done());
102 });
103
104 it('mutator missing mutate', (done) => {
105 mutators.add(objectId, utils.loadFile(`${__dirname}/invalidMutators/noMutate.js`))
106 .then(() => done('fail'))
107 .catch((e) => expect(e.message).equals('Mutator mutate() not provided'))
108 .then(() => done());
109 });
110
111 it('get ids in empty namespace', (done) => {
112 mutators.getIds(ns)
113 .then((ids) => expect(ids).to.be.empty)
114 .then(() => done());
115 });
116
117 it('basic crud', (done) => {
118 mutators.add(objectId, utils.loadFile(`${__dirname}/validMutators/data.js`))
119 .then(() => mutators.exists(objectId))
120 .then((exists) => expect(exists).to.be.equals(1))
121 .then(() => mutators.getIds(ns)
122 .then((ids) => {
123 expect(ids).to.have.length(1);
124 expect(ids[0]).to.be.equals('id');
125 })
126 )
127 .then(() => mutators.remove(objectId))
128 .then(() => mutators.exists(objectId))
129 .then((exists) => expect(exists).to.be.equals(0))
130 .then(() => mutators.getIds(ns))
131 .then((ids) => expect(ids).to.be.empty)
132 .then(() => done());
133 });
134
135 it('add twice', (done) => {
136 mutators.add(objectId, utils.loadFile(`${__dirname}/validMutators/data.js`))
137 .then(() => mutators.exists(objectId))
138 .then((exists) => expect(exists).to.be.equals(1))
139 .then(() => mutators.add(objectId, utils.loadFile(`${__dirname}/validMutators/data.js`)))
140 .catch((e) => expect(e.message).to.be.equals('Mutator \'namespace/id\' exists, delete first.'))
141 .then(() => done());
142 });
143
144 it('load a specific mutator with top-level args', (done) => {
145 mutators.add(objectId, utils.loadFile(`${__dirname}/validMutators/data.js`))
146 .then(() => mutators.load(ns, {
147 actions: [
148 {id: id}
149 ],
150 arguments: topLevelArguments
151 }))
152 .then((loadedMutators) => {
153 expect(_.size(loadedMutators)).to.be.equals(1);
154 expect(loadedMutators['data']).to.have.length(1);
155
156 const data = loadedMutators['data'][0];
157 expect(data.type).to.be.equals('data');
158 expect(data.arguments).to.be.equals(topLevelArguments);
159 validateMutator(data);
160 done();
161 })
162 .catch(done);
163 });
164
165 it('load a specific mutator with arg overrides', (done) => {
166 mutators.add(objectId, utils.loadFile(`${__dirname}/validMutators/data.js`))
167 .then(() => mutators.load(ns, {
168 actions: [
169 {
170 id: id,
171 arguments: specificArguments
172 }
173 ],
174 arguments: topLevelArguments
175 }))
176 .then((loadedMutators) => {
177 expect(_.size(loadedMutators)).to.be.equals(1);
178 expect(loadedMutators['data']).to.have.length(1);
179
180 const data = loadedMutators['data'][0];
181 expect(data.type).to.be.equals('data');
182 expect(data.arguments).to.be.equals(specificArguments);
183 validateMutator(data);
184 done();
185 })
186 .catch(done);
187 });
188
189 it('load a multiple mutators in different namespaces', (done) => {
190 const objectId1 = new ObjectId({namespace: 'task', id: id});
191 const objectId2 = new ObjectId({namespace: 'global', id: id});
192 const objectId3 = new ObjectId({namespace: 'othernamespace', id: id});
193 const objectId4 = new ObjectId({namespace: 'othernamespace', id: 'other'});
194
195 mutators.add(objectId1, utils.loadFile(`${__dirname}/validMutators/data.js`))
196 .then(() => mutators.add(objectId2, utils.loadFile(`${__dirname}/validMutators/index.js`)))
197 .then(() => mutators.add(objectId3, utils.loadFile(`${__dirname}/validMutators/indexWithArgs.js`)))
198 .then(() => mutators.add(objectId4, utils.loadFile(`${__dirname}/validMutators/template.js`)))
199 .then(() => mutators.load('task', {
200 actions: [
201 {
202 namespace: objectId3.namespace,
203 id: objectId3.id,
204 arguments: specificArguments
205 },
206 {
207 namespace: objectId2.namespace,
208 id: objectId2.id
209 },
210 {
211 id: objectId1.id,
212 arguments: specificArguments
213 },
214 {
215 namespace: objectId4.namespace,
216 id: objectId4.id
217 }
218 ],
219 arguments: topLevelArguments
220 }))
221 .then((loadedMutators) => {
222 expect(_.size(loadedMutators)).to.be.equals(3);
223 expect(loadedMutators['data']).to.have.length(1);
224 expect(loadedMutators['index']).to.have.length(2);
225 expect(loadedMutators['template']).to.have.length(1);
226
227 const data = loadedMutators['data'][0];
228 expect(data.type).to.be.equals('data');
229 expect(data.arguments).to.be.equals(specificArguments);
230 validateMutator(data);
231
232 const index1 = loadedMutators['index'][0];
233 expect(index1.type).to.be.equals('index');
234 expect(index1.arguments).to.be.equals(specificArguments);
235 validateMutator(index1);
236
237 const index2 = loadedMutators['index'][1];
238 expect(index2.type).to.be.equals('index');
239 expect(index2.arguments).to.be.equals(topLevelArguments);
240 validateMutator(index2);
241
242 const template = loadedMutators['template'][0];
243 expect(template.type).to.be.equals('template');
244 expect(template.arguments).to.be.equals(topLevelArguments);
245 validateMutator(template);
246 done();
247 })
248 .catch(done);
249 });
250});