'use strict';

/* jshint undef: true, unused: true */
/* globals it, describe */

// var request = require('supertest');

// const should = require('should'),
//    testUtils = require('../../test/testUtils'),
//     moment          = require('moment-timezone'),
//     momenttz        = require('moment-timezone');

// request = request.agent(testUtils.url);

// var API_KEY_ADMIN = '',
//     APP_ID = '',
//     APP_KEY = '';

// // var API_KEY_ADMIN = '64d5918128cb8fa78b4d45340605d139',
// //     APP_ID = '5a2647e0387dc404b0d79fa3',
// //     APP_KEY = '3e265b2a3fc5392a6215832c2bd4e8215c5ed22c';

// var USERS = {
//     'ru': {tkip: 'ios_ru', locale: 'ru', tz: 180},
//     'lv': {tkip: 'ios_lv', locale: 'lv', tz: 120},
//     'tk': {tkip: 'ios_tk', locale: 'tk', tz: 180},
//     'gb': {tkip: 'ios_gb', locale: 'gb', tz: 0},
//     'us': {tkip: 'ios_us', locale: 'us', tz: -420},
//     'es': {tkip: 'ios_es', locale: 'es', tz: -60},
//     'no': {tkip: 'ios_no', locale: 'no'},
//     'tk_a': {tkap: 'android_tk', locale: 'tk', tz: 180},
//     'gb_a': {tkap: 'android_gb', locale: 'gb', tz: 0},
//     'us_a': {tkap: 'android_us', locale: 'us', tz: -420},
// };

// const  pluginManager = require('../pluginManager.js'),
//        db = pluginManager.singleDefaultConnection(),
//        N = require('./api/parts/note.js'),
//        Divider = require('./api/parts/divider.js'),
//        Streamer = require('./api/parts/streamer.js'),
//        creds = require('./api/parts/credentials.js'),
//        Credentials = creds.Credentials,
//        common = require('../../api/utils/common.js');

// const p12 = 'data:application/x-pkcs12;base64, ',
//       p12pp = 'data:application/x-pkcs12;base64, ',
//       p12dev = 'data:application/x-pkcs12;base64, ',
//       p12devpp = 'data:application/x-pkcs12;base64, ',
//       p8 = 'data:;base64,LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JR1RBZ0VBTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEJIa3dkd0lCQVFRZ2Y2bUJUbkM1Vk5OelMvUmEKRlJ2R1FUbU4yYk5rN24xOW5qaG9tVExESm1HZ0NnWUlLb1pJemowREFRZWhSQU5DQUFSMjZKMkI0aDdOSXkzYwpVeTVySHdwSVJDN1NzcjV2Z1BFd0FVOGM0L0ZwcWN0M1NRNVJjN1gwZ0VOQkkycmdyRW9tdlFHU1llWTA2WlJXCkdZUy93RVpkCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=';

// process.on('unhandledRejection', (reason, p) => {
//     console.log('Unhandled rejection for %j with reason %j stack ', p, reason, reason ? reason.stack : undefined, new Error().stack);
// });

// common.db = db;

// describe('Push', function(){
//     it('should validate correct GCM key', done => {
//         API_KEY_ADMIN = testUtils.get('API_KEY_ADMIN');
//         APP_ID = testUtils.get('APP_ID');
//         APP_KEY = testUtils.get('APP_KEY');

//         request.post(`/i/pushes/validate?api_key=${API_KEY_ADMIN}&platform=a&key=AIzaSyBLaYw9HYPUxlrTLAomA3O3Dp44E2MFT0A&secret=`)
//             .expect(200)
//             .expect('Content-Type', /json/)
//             .end((err, res) => {
//                 if (err) return done(err);
//                 var ob = JSON.parse(res.text);
//                 ob.should.have.property('cid').with.a.lengthOf(24);
//                 done();
//             });
//     });
//     it('should validate correct FCM key', done => {
//         request.post(`/i/pushes/validate?api_key=${API_KEY_ADMIN}&platform=a&key=AAAAyhsteIE:APA91bFySIoL-BMQjLEsje6sOY0W4PoXTHKn79mZvW2vZtE4Bwo1KntYOkwmnTYo_DASwWcywOvqlniOei_L6g7Lf4zZXcU1KmOhE4LQuClEExxzyappw90_zjOufiHTBtUJFqpsEJ9Q&secret=`)
//             .expect(200)
//             .expect('Content-Type', /json/)
//             .end((err, res) => {
//                 if (err) return done(err);
//                 var ob = JSON.parse(res.text);
//                 ob.should.have.property('cid').with.a.lengthOf(24);
//                 done();
//             });
//     });
//     it('should return error for invalid GCM key', done => {
//         request.post(`/i/pushes/validate?api_key=${API_KEY_ADMIN}&platform=a&key=aaabbbb&secret=`)
//             .expect(200)
//             .expect('Content-Type', /json/)
//             .end((err, res) => {
//                 if (err) return done(err);
//                 var ob = JSON.parse(res.text);
//                 ob.should.have.property('error').which.equal('401: GCM Unauthorized');
//                 done();
//             });
//     });

//     it('should validate correct APN certificate without passphrase', done => {
//         request.post(`/i/pushes/validate?api_key=${API_KEY_ADMIN}&platform=i&secret=`)
//             .attach('key', Buffer.from(p12))
//             .expect(200)
//             .end((err, res) => {
//                 if (err) return done(err);
//                 var ob = JSON.parse(res.text);
//                 ob.should.have.property('cid').with.a.lengthOf(24);
//                 done();
//             });
//     });

//     it('should validate correct APN certificate with passphrase', done => {
//         request.post(`/i/pushes/validate?api_key=${API_KEY_ADMIN}&platform=i&secret=Passphrase`)
//             .attach('key', Buffer.from(p12pp))
//             .expect(200)
//             .end((err, res) => {
//                 if (err) return done(err);
//                 var ob = JSON.parse(res.text);
//                 ob.should.have.property('cid').with.a.lengthOf(24);
//                 done();
//             });
//     });

//     // it('should validate correct APN key file', done => {
//     //     request.post(`/i/pushes/validate?api_key=${API_KEY_ADMIN}&platform=i&secret=6A6MVM6HQF[CLY]EQ43JUC8GV[CLY]ly.count.Countly-Tester`)
//     //         .attach('key', Buffer.from(p8))
//     //         .expect(200)
//     //         .end((err, res) => {
//     //             if (err) return done(err);
//     //             var ob = JSON.parse(res.text);
//     //             ob.should.have.property('cid').with.a.lengthOf(24);
//     //             done();
//     //         });
//     // });

//     it('should return error for Sandbox APN certificate without passphrase', done => {
//         request.post(`/i/pushes/validate?api_key=${API_KEY_ADMIN}&platform=i&secret=`)
//             .attach('key', Buffer.from(p12dev))
//             .expect(200)
//             .end((err, res) => {
//                 if (err) return done(err);
//                 var ob = JSON.parse(res.text);
//                 ob.should.have.property('error').which.equal('Not a universal (Sandbox & Production) certificate');
//                 done();
//             });
//     });

//     it('should return error for Sandbox APN certificate with passphrase', done => {
//         request.post(`/i/pushes/validate?api_key=${API_KEY_ADMIN}&platform=i&secret=Passphrase`)
//             .attach('key', Buffer.from(p12devpp))
//             .expect(200)
//             .end((err, res) => {
//                 if (err) return done(err);
//                 var ob = JSON.parse(res.text);
//                 ob.should.have.property('error').which.equal('Not a universal (Sandbox & Production) certificate');
//                 done();
//             });
//     });

//     it('should return error for correct APN certificate with invalid passphrase', done => {
//         request.post(`/i/pushes/validate?api_key=${API_KEY_ADMIN}&platform=i&secret=InvalidPassphrase`)
//             .attach('key', Buffer.from(p12pp))
//             .expect(200)
//             .end((err, res) => {
//                 if (err) return done(err);
//                 var ob = JSON.parse(res.text);
//                 ob.should.have.property('error').which.equal('PKCS#12 MAC could not be verified. Invalid password?');
//                 done();
//             });
//     });

//     function createUser(id, callback, events) {
//         request.get(`/i?device_id=${id}&app_key=${APP_KEY}&begin_session=1&tz=${USERS[id].tz}`).expect(200).end((err, res) => {
//             if (err) {
//                 return callback(err);
//             }

//             var ob = JSON.parse(res.text);
//             ob.should.have.property('result','Success');

//             // console.log(`/i?device_id=${id}&app_key=${APP_KEY}&token_session=1&${USERS[id].tkip ? 'ios_token=' + USERS[id].tkip : 'android_token=' + USERS[id].tkap}&test_mode=0&locale=${USERS[id].locale}`);
//             setTimeout(() => { 
//                 request.get(`/i?device_id=${id}&app_key=${APP_KEY}&token_session=1&${USERS[id].tkip ? 'ios_token=' + USERS[id].tkip : 'android_token=' + USERS[id].tkap}&test_mode=0&locale=${USERS[id].locale}`).expect(200).end((err, res) => {
//                     if (err) {
//                         return callback(err);
//                     }

//                     var ob = JSON.parse(res.text);
//                     ob.should.have.property('result','Success');

//                     if (events && events.length) {
//                         sendEvents(id, events, callback);
//                     } else if (callback) {
//                         // console.log('created user ' + id);
//                         callback();
//                     }

//                 });
//             }, 6000);
//         });
//     }

//     function sendEvents(id, events, callback) {
//         // console.log('%s: sending events %j', id, events);
//         request.get(`/i?device_id=${id}&app_key=${APP_KEY}&session_duration=10&events=${JSON.stringify(events)}`).expect(200).end((err, res) => {
//             if (err) {
//                 return callback(err);
//             }

//             var ob = JSON.parse(res.text);
//             ob.should.have.property('result','Success');

//             if (callback) {
//                 callback();
//             }
//         });
//     }

//     function createAll(callback, next) {
//         next = next || 0;
//         if (Object.keys(USERS).length === next) {
//             setTimeout(callback, 5000);
//         } else {
//             createUser(Object.keys(USERS)[next], createAll.bind(null, callback, next + 1));
//         }
//     }

//     describe('streaming', () => {
//         // require('../../api/utils/log.js').setDefault('debug');

//         var credentialsIOS = new Credentials('cidIOS'),
//             credentialsAndroid = new Credentials('cidAndroid'),
//             appsubcredentialsIOS, appsubcredentialsAndroid;

//         credentialsIOS.type = 'apn_universal';
//         credentialsIOS.platform = 'i';
//         credentialsAndroid.type = 'gcm';
//         credentialsAndroid.platform = 'a';

//         for (let k in creds.DB_MAP) {
//             common.dbMap[k] = creds.DB_MAP[k];
//         }
//         for (let k in creds.DB_USER_MAP) {
//             common.dbUserMap[k] = creds.DB_USER_MAP[k];
//         }

//         describe('(timezoned)', () => {
//             it('should clear app data', done => {
//                 const subcredentialsIOS = credentialsIOS.divide(false)[0],
//                       subcredentialsAndroid = credentialsAndroid.divide(false)[0];

//                 appsubcredentialsIOS = subcredentialsIOS.app(APP_ID, {tz: 'Europe/Moscow', offset: 180}),
//                 appsubcredentialsAndroid = subcredentialsAndroid.app(APP_ID, {tz: 'Europe/Moscow', offset: 180});

//                 request.get(`/i/apps/reset?args=${JSON.stringify({app_id: APP_ID, period: 'reset'})}&api_key=${API_KEY_ADMIN}`)
//                 .expect(200)
//                 .end((err, res) => {
//                      // console.log('app clear', err, res.text);
//                      if (err) { 
//                          return done(err); 
//                      }
//                      done();
//                  });
//             });

//             it('should create all USERS', (done) => {
//                 USERS = {
//                     'ru': {tkip: 'ios_ru', locale: 'ru', tz: 180},
//                     'lv': {tkip: 'ios_lv', locale: 'lv', tz: 120},
//                     'tk': {tkip: 'ios_tk', locale: 'tk', tz: 180},
//                     'gb': {tkip: 'ios_gb', locale: 'gb', tz: 0},
//                     'us': {tkip: 'ios_us', locale: 'us', tz: -420},
//                     'es': {tkip: 'ios_es', locale: 'es', tz: -60},
//                     'no': {tkip: 'ios_no', locale: 'no'},
//                     'tk_a': {tkap: 'android_tk', locale: 'tk', tz: 180},
//                     'gb_a': {tkap: 'android_gb', locale: 'gb', tz: 0},
//                     'us_a': {tkap: 'android_us', locale: 'us', tz: -420},
//                 };
//                 createAll(done, 0);
//             }).timeout(10 * 10000);

//             it('should have all USERS', done => {
//                 db.collection('app_users' + APP_ID).count({$or: [{tkip: true}, {tkap: true}]}, (err, count) => {
//                     if (err) { done(err); }
//                     else {
//                         count.should.equal(Object.keys(USERS).length);
//                         done();
//                     }
//                 });
//             });

//             it('should clear', done => {
//                 let date = new Date(),
//                     note = new N.Note({date: date, apps: [APP_ID], appNames: [], platforms: ['i'], data: {a: 1}}),
//                     anote = note.appsub(0, appsubcredentialsIOS);

//                 anote.nobuild = true;
//                 new Streamer(anote).clear(db).then(done.bind(null, null), done);
//             });

//             var date = momenttz.tz('2017-12-01 15:00', 'Europe/Moscow').toDate();

//             it('should count without tz fine', done => {
//                 let note = new N.Note({date: date, apps: [APP_ID], appNames: [], platforms: ['i'], data: {a: 1}}),
//                     anote = note.appsub(0, appsubcredentialsIOS),
//                     streamer = new Streamer(anote);

//                 streamer.count(db).then(count => {
//                     count.should.equal(7);
//                     done();
//                 }, done);
//             });

//             it('should load all users without tz fine', done => {
//                 let note = new N.Note({date: date, apps: [APP_ID], appNames: [], platforms: ['i'], data: {a: 1}}),
//                     anote = note.appsub(0, appsubcredentialsIOS),
//                     streamer = new Streamer(anote);

//                 streamer.load(db).then(us => {
//                     us.length.should.equal(7);
//                     done();
//                 }, done);
//             });

//             it('should clear', done => {
//                 let date = new Date(),
//                     note = new N.Note({date: date, apps: [APP_ID], appNames: [], platforms: ['i'], data: {a: 1}}),
//                     anote = note.appsub(0, appsubcredentialsIOS);

//                 anote.nobuild = true;
//                 new Streamer(anote).clear(db).then(done.bind(null, null), done);
//             });

//             it('should load with tz correctly', done => {
//                 let note = new N.Note({date: date, tz: -180, apps: [APP_ID], appNames: [], platforms: ['i'], data: {a: 1}}),
//                     anote = note.appsub(0, appsubcredentialsIOS),
//                     streamer = new Streamer(anote);

//                 var now = momenttz.tz('2017-12-01 14:00', 'Europe/Moscow').toDate(),
//                     min = momenttz.tz('2017-12-01 13:45', 'Europe/Moscow').toDate(),
//                     max = momenttz.tz('2017-12-01 14:15', 'Europe/Moscow').toDate();

//                 console.log(now, min, max);

//                 streamer.load(db, null, null, 100, min.getTime(), max.getTime()).then(arr => {
//                     arr.length.should.equal(0); // nobody's after GMT+3

//                     now = momenttz.tz('2017-12-01 15:00', 'Europe/Moscow').toDate();
//                     min = momenttz.tz('2017-12-01 14:45', 'Europe/Moscow').toDate();
//                     max = momenttz.tz('2017-12-01 15:15', 'Europe/Moscow').toDate();

//                     streamer.load(db, null, null, 100, min.getTime(), max.getTime()).then(arr => {
//                       console.log(arr);
//                         arr.length.should.equal(3); // ru, tk, unknown

//                         streamer.unload(db, arr.map(u => u._id)).then(ok => {
//                             ok.next.should.equal(momenttz.tz('2017-12-01 15:00', 'Europe/Riga').toDate().getTime());
//                             ok.unloaded.should.equal(3);

//                             min = ok.next - 15 * 60000;
//                             max = ok.next + 15 * 60000;

//                             streamer.load(db, null, null, 100, min, max).then(arr => {
//                                 arr.length.should.equal(1); // lv

//                                 streamer.unload(db, arr.map(u => u._id)).then(ok => {
//                                     ok.next.should.equal(momenttz.tz('2017-12-01 15:00', 'Europe/London').toDate().getTime());
//                                     ok.unloaded.should.equal(1);

//                                     min = ok.next - 15 * 60000;
//                                     max = ok.next + 15 * 60000;

//                                     streamer.load(db, null, null, 100, min, max).then(arr => {
//                                         arr.length.should.equal(1); // gb

//                                         streamer.unload(db, max).then(ok => {
//                                             ok.next.should.equal(momenttz.tz('2017-12-01 15:00', 'Atlantic/Azores').toDate().getTime());
//                                             ok.unloaded.should.equal(1);
// >>>>>>> Stashed changes

//                                             min = ok.next - 15 * 60000;
//                                             max = ok.next + 15 * 60000;

//                                             streamer.load(db, null, null, 100, min, max).then(arr => {
//                                                 arr.length.should.equal(1); // es

//                                                 streamer.unload(db, max).then(ok => {
//                                                     ok.next.should.equal(momenttz.tz('2017-12-01 15:00', 'America/Chihuahua').toDate().getTime());
//                                                     ok.unloaded.should.equal(1);

//                                                     min = ok.next - 15 * 60000;
//                                                     max = ok.next + 15 * 60000;

//                                                     streamer.load(db, null, null, 100, min, max).then(arr => {
//                                                         arr.length.should.equal(1); // us

//                                                         streamer.unload(db, arr.map(u => u._id)).then((ok) => {
//                                                             should.not.exist(ok.next); // nobody left
//                                                             ok.unloaded.should.equal(1);
//                                                             done();
//                                                         }, done);
//                                                     }, done);
//                                                 }, done);
//                                             }, done);
//                                         }, done);
//                                     }, done);
//                                 }, done);
//                             }, done);

//                         }, done);
//                     }, done);

//                 }, done);
//             });
//         });

//         describe('(auto)', () => {   
//             var usrs = [];

//             function findUser(token) {
//                 for (var i = 0; i < usrs.length; i++) {
//                     if (usrs[i].tk.ip === token || usrs[i].tk.ap === token) { 
//                         return usrs[i];
//                     }
//                 }
//             }

//             it('should have all users', done => {
//                 db.collection('app_users' + APP_ID).find().toArray((err, arr) => {
//                     if (err) { done(err); }
//                     else {
//                         usrs = arr;
//                         usrs.length.should.equal(Object.keys(USERS).length);
//                         done();
//                     }
//                 });
//             });

//             it('should clear', done => {
//                 let note = new N.Note({
//                         apps: [APP_ID], appNames: [], platforms: ['i'], data: {a: 1},
//                         auto: true, autoOnEntry: true, autoCohorts: ['cohort_id'], 
//                         date: momenttz.tz('2017-12-01 10:00', 'Europe/Moscow').toDate(), 
//                         autoEnd: momenttz.tz('2017-12-02 19:00', 'Europe/Moscow').toDate(), autoDelay: 50 * 60000,
//                         autoTime: 13 * 60 * 60000,
//                         autoCapMessages: 2,
//                         autoCapSleep: 2 * 60 * 60000
//                     }),
//                     anote = note.appsub(0, appsubcredentialsIOS);

//                 anote.nobuild = true;
//                 new Streamer(anote).clear(db).then(done.bind(null, null), done);
//             });

//             it('should process simple auto messages correctly', done => {
//                 let note = new N.Note({
//                         apps: [db.ObjectID(APP_ID)], appNames: [], platforms: ['i', 'a'], data: {a: 1},
//                         auto: true, autoOnEntry: true, autoCohorts: ['cohort_id'], 
//                         date: momenttz.tz('2017-12-01 10:00', 'Europe/Moscow').toDate(), 
//                         autoEnd: momenttz.tz('2017-12-02 19:00', 'Europe/Moscow').toDate(), 
//                         autoDelay: 50 * 60000,
//                         autoTime: 13 * 60 * 60000,
//                         autoCapMessages: 2,
//                         autoCapSleep: 2 * 60 * 60000
//                     }),
//                     anoteIOS = note.appsub(0, appsubcredentialsIOS),
//                     anoteAndroid = note.appsub(0, appsubcredentialsAndroid),
//                     streamerIOS = new Streamer(anoteIOS),
//                     divider = new Divider(note);

//                 divider.streamers = function(){
//                     return new Promise(resolve => {
//                         resolve([
//                             {appsub: anoteIOS, streamer: new Streamer(anoteIOS)},
//                             {appsub: anoteAndroid, streamer: new Streamer(anoteAndroid)},
//                         ]);
//                     });
//                 };

//                 var now = momenttz.tz('2017-12-01 11:00', 'Europe/Moscow').toDate();

//                 db.collection('apps').findOne({key: APP_KEY}, (err, app) => {
//                     should.not.exist(err);
//                     app.should.not.be.null();

//                     // console.log('user %j', findUser('ios_ru'));
//                     divider.store(db, app, [findUser('ios_ru').uid], now).then((count) => {
//                         count.should.equal(1);

//                         db.collection(streamerIOS.collection()).find().toArray((err, arr) => {
//                             // console.log('arr %j', arr);
//                             should.not.exist(err);
//                             arr.length.should.equal(1);
//                             arr[0].tkip.should.equal('ios_ru');
//                             arr[0].da.should.equal(momenttz.tz('2017-12-01 13:00', 'Europe/Moscow').toDate().getTime());

//                             // should overwrite old note
//                             now = momenttz.tz('2017-12-01 13:01', 'Europe/Moscow').toDate();
//                             divider.store(db, app, [findUser('ios_ru').uid], now).then(() => {
//                                 db.collection(streamerIOS.collection()).find().toArray((err, arr) => {
//                                     should.not.exist(err);
//                                     arr.length.should.equal(1);
//                                     arr[0].tkip.should.equal('ios_ru');
//                                     arr[0].da.should.equal(momenttz.tz('2017-12-02 13:00', 'Europe/Moscow').toDate().getTime());


//                                     // shouldn't do anything since 12-02 13:01 is after autoEnd date
//                                     now = momenttz.tz('2017-12-02 13:01', 'Europe/Moscow').toDate();
//                                     divider.store(db, app, [findUser('ios_ru').uid], now).then(() => {
//                                         db.collection(streamerIOS.collection()).find().toArray((err, arr) => {
//                                             should.not.exist(err);
//                                             arr.length.should.equal(1);
//                                             arr[0].tkip.should.equal('ios_ru');
//                                             arr[0].da.should.equal(momenttz.tz('2017-12-02 13:00', 'Europe/Moscow').toDate().getTime());
//                                             done();
//                                         }, done);
//                                     }, done);
//                                 }, done);
//                             }, done);

//                         }, done);
//                     }, done);
//                 });
//             });

//             it('should process capped auto messages correctly', done => {
//                 let note = new N.Note({
//                         _id: db.ObjectID(),
//                         apps: [db.ObjectID(APP_ID)], appNames: [], platforms: ['i', 'a'], data: {a: 1},
//                         auto: true, autoOnEntry: true, autoCohorts: ['cohort_id'], 
//                         date: momenttz.tz('2017-11-01 10:00', 'Europe/Moscow').toDate(), 
//                         autoEnd: momenttz.tz('2017-12-02 19:00', 'Europe/Moscow').toDate(), 
//                         autoDelay: 50 * 60000,
//                         autoCapMessages: 2,
//                         autoCapSleep: 24 * 60 * 60000
//                     }),
//                     anoteIOS = note.appsub(0, appsubcredentialsIOS),
//                     anoteAndroid = note.appsub(0, appsubcredentialsAndroid),
//                     streamerIOS = new Streamer(anoteIOS),
//                     streamerAndroid = new Streamer(anoteAndroid),
//                     divider = new Divider(note);

//                 divider.streamers = function(){
//                     return new Promise(resolve => {
//                         resolve([
//                             {appsub: anoteIOS, streamer: new Streamer(anoteIOS)},
//                             {appsub: anoteAndroid, streamer: new Streamer(anoteAndroid)},
//                         ]);
//                     });
//                 };

//                 // console.log(streamerIOS.collection(), streamerAndroid.collection());

//                 db.collection('app_users' + APP_ID).update({'tk.ip': 'ios_ru'}, {$set: {msgs: [[note._id, momenttz.tz('2017-11-15 13:00', 'Europe/Moscow').toDate().getTime()]]}}, err => {
//                     if (err) { return done(err); }
//                     db.collection('app_users' + APP_ID).update({'tk.ap': 'android_gb'}, {$set: {msgs: [[note._id, momenttz.tz('2017-11-10 13:00', 'Europe/London').toDate().getTime()], [note._id, momenttz.tz('2017-11-13 13:00', 'Europe/Moscow').toDate().getTime()]]}}, err => {
//                         if (err) { return done(err); }
//                         db.collection('app_users' + APP_ID).update({'tk.ap': 'android_tk'}, {$set: {msgs: [[note._id, momenttz.tz('2017-11-15 13:00', 'Europe/Moscow').toDate().getTime()]]}}, err => {
//                             if (err) { return done(err); }
//                             db.collection('app_users' + APP_ID).update({'tk.ip': 'ios_us'}, {$set: {msgs: [[note._id, momenttz.tz('2017-11-15 13:00', 'America/Chihuahua').toDate().getTime()]]}}, err => {
//                                 if (err) { return done(err); }

//                                 db.collection('apps').findOne({key: APP_KEY}, (err, app) => {
//                                     should.not.exist(err);
//                                     app.should.not.be.null();
//                                     db.collection('app_users' + APP_ID).find().toArray((err, arr) => {
//                                         if (err) { done(err); }
//                                         else {
//                                             usrs = arr;

//                                             var now = momenttz.tz('2017-11-16 13:30', 'Europe/Moscow').toDate();
//                                             divider.store(db, app, [findUser('ios_ru'), findUser('android_gb'), findUser('android_tk'), findUser('ios_us')].map(u => u.uid), now).then(() => {

//                                                 db.collection(streamerIOS.collection()).find().toArray((err, usersIOS) => {
//                                                     should.not.exist(err);
//                                                     db.collection(streamerAndroid.collection()).find().toArray((err, usersAndroid) => {
//                                                         should.not.exist(err);

//                                                         // console.log('ios', usersIOS);
//                                                         // console.log('usersAndroid', usersAndroid);

//                                                         usersIOS.length.should.equal(1);
//                                                         usersIOS[0].tkip.should.equal('ios_ru');
//                                                         usersIOS[0].da.should.equal(momenttz.tz('2017-11-16 14:20', 'Europe/Moscow').toDate().getTime());

//                                                         usersAndroid.length.should.equal(1);
//                                                         usersAndroid[0].tkap.should.equal('android_tk');
//                                                         usersAndroid[0].da.should.equal(momenttz.tz('2017-11-16 14:20', 'Europe/Moscow').toDate().getTime());

//                                                         done();
//                                                     });
//                                                 });

//                                             });
//                                         }
//                                     });

//                                 });

//                             });
//                         });
//                     });
//                 });
//             });
//         });
//     });

//     if (pluginManager.getPluginsApis().cohorts) {

//         describe('cohorts', () => {
//             var morning = new Date();
//             morning.setHours(0);
//             morning.setHours(0);
//             morning.setHours(0);
//             var cohorts = {
//                 Now: {name: 'Now', steps: [{event: "Simple_" + db.ObjectID(), type:"did", period: "1days"}]},
//                 Sleep: {name: 'Sleep', steps: [{event: "Simple_" + db.ObjectID(), type:"did", period: "1days"}]},
//                 Delay: {name: 'Delay', steps: [{event: "Simple_" + db.ObjectID(), type:"did", period: "1days"}]},
//                 Tz: {name: 'Tz', steps: [{event: "Simple_" + db.ObjectID(), type:"did", period: "1days"}]},
//                 // Simple: {name: 'Simple', steps: [{event: "Simple_" + db.ObjectID(), type:"did", period: "1days"}, {event: "Exit_" + db.ObjectID(), type:"didnot", period: "1days"}]},
//                 manual: {_id:"manual", type:"manual"}
//             }, eventTs = Date.now(), event = (chr) => {return {key: chr.steps[0].event, timestamp: eventTs, count: 1}; }, 
//             credentialsIOS,
//             credentialsAndroid,
//             appsubcredentialsAndroid;

//             function createCohort(name, done) {
//                 request.get(`/o?api_key=${API_KEY_ADMIN}&app_id=${APP_ID}&method=get_cohorts`)
//                     .expect(200)
//                     .end((err, res) => {
//                         // console.log('cohorts', err, res.text);
//                         if (err) { 
//                             return done(err); 
//                         }

//                         var json = JSON.parse(res.text),
//                             cohort = json.filter(c => c.name === name)[0];

//                         if (cohort) {
//                             request.get(`/i/cohorts/delete?cohort_id=${cohort._id}&app_id=${APP_ID}&api_key=${API_KEY_ADMIN}`)
//                                 .expect(200)
//                                 .end((err, res) => {
//                                     // console.log('deleted', err, res.text);
//                                     request.get("/i/cohorts/add?api_key="+API_KEY_ADMIN+"&app_id="+APP_ID+"&cohort_name="+name+"&steps="+JSON.stringify(cohorts[name].steps))
//                                         .expect(200)
//                                         .end((err, res) => {
//                                             // console.log('created', err, res.text);
//                                             if (err) {
//                                                 return done(err);
//                                             }
//                                             cohorts[name]._id = JSON.parse(res.text).result;
//                                             setTimeout(done, 1000);
//                                         });
//                                 });
//                         } else {
//                             request.get("/i/cohorts/add?api_key="+API_KEY_ADMIN+"&app_id="+APP_ID+"&cohort_name="+name+"&steps="+JSON.stringify(cohorts[name].steps))
//                                 .expect(200)
//                                 .end((err, res) => {
//                                     // console.log('cohort created', err, res.text);
//                                     if (err) {
//                                         return done(err);
//                                     }
//                                     cohorts[name]._id = JSON.parse(res.text).result;
//                                     setTimeout(done, 1000);
//                                 });
//                         }
//                     });
//             }

//             it('should clear app data', done => {
//                 USERS = {    
//                     'no': {tkip: 'ios_no', locale: 'no'},
//                     'tk_a': {tkap: 'f_qKFXO8HVY:APA91bHI8qmPEMsDrnKjywph5DqbL1Dj-4XrMSEdyDpjTNKHpuKJfSzCK02xwfS41OoHrPnSvi8P_61M44WrlgBD2NzVBntFVSTUcVU3Z32QVi67aZQCrIph3ZrZgY_hXSrbyH6Np_1a', locale: 'tr_TR', tz: 180},
//                     'gb_a': {tkap: 'f_qKFXO8HVY:APA91bHI8qmPEMsDrnKjywph5DqbL1Dj-4XrMSEdyDpjTNKHpuKJfSzCK02xwfS41OoHrPnSvi8P_61M44WrlgBD2NzVBntFVSTUcVU3Z32QVi67aZQCrIph3ZrZgY_hXSrbyH6Np_1a', locale: 'en_GB', tz: 0},
//                     'gb_2a': {tkap: 'f_qKFXO8HVY:APA91bHI8qmPEMsDrnKjywph5DqbL1Dj-4XrMSEdyDpjTNKHpuKJfSzCK02xwfS41OoHrPnSvi8P_61M44WrlgBD2NzVBntFVSTUcVU3Z32QVi67aZQCrIph3ZrZgY_hXSrbyH6Np_1a', locale: 'en_GB', tz: 0},
//                     'gb_3a': {tkap: 'f_qKFXO8HVY:APA91bHI8qmPEMsDrnKjywph5DqbL1Dj-4XrMSEdyDpjTNKHpuKJfSzCK02xwfS41OoHrPnSvi8P_61M44WrlgBD2NzVBntFVSTUcVU3Z32QVi67aZQCrIph3ZrZgY_hXSrbyH6Np_1a', locale: 'en_GB', tz: 0},
//                     'de_a': {tkap: 'f_qKFXO8HVY:APA91bHI8qmPEMsDrnKjywph5DqbL1Dj-4XrMSEdyDpjTNKHpuKJfSzCK02xwfS41OoHrPnSvi8P_61M44WrlgBD2NzVBntFVSTUcVU3Z32QVi67aZQCrIph3ZrZgY_hXSrbyH6Np_1a', locale: 'de_DE', tz: -1},
//                     'us_a': {tkap: 'f_qKFXO8HVY:APA91bHI8qmPEMsDrnKjywph5DqbL1Dj-4XrMSEdyDpjTNKHpuKJfSzCK02xwfS41OoHrPnSvi8P_61M44WrlgBD2NzVBntFVSTUcVU3Z32QVi67aZQCrIph3ZrZgY_hXSrbyH6Np_1a', locale: 'en_US', tz: -420},
//                 };
//                 request.get(`/i/apps/reset?args=${JSON.stringify({app_id: APP_ID, period: 'reset'})}&api_key=${API_KEY_ADMIN}`)
//                     .expect(200)
//                     .end((err, res) => {
//                         // console.log('app clear', err, res.text);
//                         if (err) { 
//                             return done(err); 
//                         }
//                         done();
//                     });
//             });

//             it('should set FCM key', done => {
//                 request.post(`/i/pushes/validate?api_key=${API_KEY_ADMIN}&platform=a&key=AAAAyhsteIE:APA91bFySIoL-BMQjLEsje6sOY0W4PoXTHKn79mZvW2vZtE4Bwo1KntYOkwmnTYo_DASwWcywOvqlniOei_L6g7Lf4zZXcU1KmOhE4LQuClEExxzyappw90_zjOufiHTBtUJFqpsEJ9Q&secret=`)
//                     .expect(200)
//                     .expect('Content-Type', /json/)
//                     .end((err, res) => {
//                         if (err) return done(err);
//                         var ob = JSON.parse(res.text);
//                         ob.should.have.property('cid').with.a.lengthOf(24);
//                         credentialsAndroid = new Credentials(ob.cid);

//                         request.get(`/i/apps/update?args=${JSON.stringify({app_id: APP_ID, timezone: 'Europe/Moscow', 
//                                 apn: credentialsIOS ? [{_id: credentialsIOS._id, type: 'apn_universal'}] : undefined, 
//                                 gcm: credentialsAndroid ? [{_id: credentialsAndroid._id, type: 'gcm'}] : undefined})}&api_key=${API_KEY_ADMIN}`)
//                             .expect(200)
//                             .end((err, res) => {
//                                 // console.log('app creds', err, res.text);
//                                 if (err) { 
//                                     return done(err); 
//                                 }
//                                 credentialsAndroid.load(db).then(() => {
//                                     appsubcredentialsAndroid = credentialsAndroid.divide(false)[0].app(APP_ID, {tz: 'Europe/Moscow', offset: 180});
//                                     done();
//                                 }, done);
//                             });
//                     });
//             }); 

//             // it('should set APN certificate', done => {
//             //     request.post(`/i/pushes/validate?api_key=${API_KEY_ADMIN}&platform=i&secret=`)
//             //         .attach('key', Buffer.from(p12))
//             //         .expect(200)
//             //         .end((err, res) => {
//             //             if (err) return done(err);
//             //             var ob = JSON.parse(res.text);
//             //             ob.should.have.property('cid').with.a.lengthOf(24);

//             //             credentialsIOS = new Credentials(ob.cid);

//             //             request.get(`/i/apps/update?args=${JSON.stringify({app_id: APP_ID, timezone: 'Europe/Moscow',
//             //                     apn: credentialsIOS ? [{_id: credentialsIOS._id, type: 'apn_universal'}] : undefined, 
//             //                     gcm: credentialsAndroid ? [{_id: credentialsAndroid._id, type: 'gcm'}] : undefined})}&api_key=${API_KEY_ADMIN}`)
//             //                 .expect(200)
//             //                 .end((err, res) => {
//             //                     console.log('app creds', err, res.text);
//             //                     if (err) { 
//             //                         return done(err); 
//             //                     }
//             //                     credentialsIOS.load(db).then(() => {
//             //                         appsubcredentialsIOS = credentialsIOS.divide(false)[0].app(APP_ID, {tz: 'Europe/Moscow', offset: 180});
//             //                         done();
//             //                     }, done);
//             //                 });
//             //         });
//             // });

//             it('should create first user', (done) => {
//               createUser('no', done, [event(cohorts.Now), event(cohorts.Sleep), event(cohorts.Delay), event(cohorts.Tz)]);
//             });

//             it('should create cohorts', (done) => {
//                 createCohort('Now', createCohort.bind(null, 'Sleep', createCohort.bind(null, 'Delay', createCohort.bind(null, 'Tz', done))));
//             });

//             var defaults = {
//                     type: 'data',
//                     data: {a: 1},
//                     apps: [APP_ID],
//                     platforms: ['a'],
//                     date: new Date(),
//                     auto: true,
//                 }, 
//                 msgNow, msgSleep, msgDelay, msgTz,

//                 createMessage = (json, done) => {
//                     request.get(`/i/pushes/create?args=${JSON.stringify(json)}&api_key=${API_KEY_ADMIN}`)
//                         .expect(200)
//                         .end((err, res) => {
//                             if (err) { return done(err); }
//                             Object.assign(json, JSON.parse(res.text));
//                             if (!json._id) { return done('no id'); }
//                             json._id = db.ObjectID(json._id);
//                             json.apps[0] = db.ObjectID(json.apps[0]);
//                             json.date = new Date(json.date);
//                             setTimeout(done, 1000);
//                         });
//                 },

//                 regenerateCohort = (_id, done, uids) => {
//                     request.get(`/o?api_key=${API_KEY_ADMIN}&app_id=${APP_ID}&method=cohort&generate=true&cohort=${_id}`)
//                         .expect(200)
//                         .end((err, res) => {
//                             if (err) return done(err);

//                             // console.log('cohort regenerated', res.text);
//                             var ob = JSON.parse(res.text);
//                             if (uids) {
//                                 uids.forEach(uid => {
//                                     ob.indexOf(uid).should.not.equal(-1);
//                                 });
//                             }
//                             setTimeout(done.bind(null, null, ob), 1000);
//                         });
//                 },

//                 checkEach = (f, delay, timeout, error, done) => {
//                     var expires = Date.now() + timeout,
//                         check = () => {
//                             f(ok => {
//                                 if (ok) { 
//                                     setTimeout(() => {
//                                         done();
//                                     }, delay); 
//                                 } else if (Date.now() > expires) { 
//                                     done(error); 
//                                 } else {
//                                    setTimeout(check, delay);
//                                 }
//                             });
//                         };
//                     check();
//                 },

//                 delayedCount = (streamer, delay) => {
//                     return new Promise((res, rej) => {
//                         setTimeout(() => {
//                             streamer.count(db).then(res, rej);
//                         }, delay);
//                     });
//                 };

//             // it('should create auto messages', done => {
//             //     msgNow = Object.assign({}, defaults, {autoCohorts: [cohorts.Simple._id], autoOnEntry: true, autoCapMessages: 2});
//             //     msgSleep = Object.assign({}, defaults, {autoCohorts: [cohorts.Simple._id], autoOnEntry: true, autoCapMessages: 2, autoCapSleep: 60 * 60000});
//             //     msgDelay = Object.assign({}, defaults, {autoCohorts: [cohorts.Simple._id], autoOnEntry: true, autoDelay: 60 * 60000});
//             //     msgTz = Object.assign({}, defaults, {autoCohorts: [cohorts.Simple._id], autoOnEntry: true, autoTime: 18 * 60 * 60000});
//             //     // createMessage(msgNow, createMessage.bind(null, msgSleep, createMessage.bind(null, msgDelay, createMessage.bind(null, msgTz, done))));
//             // });

//             it('should send tz message correctly', done => {
//                 if (new Date().getHours() >= 22) {
//                     return done();
//                 }

//                 var dt = new Date(),
//                     h = dt.getHours(),
//                     m = dt.getMinutes(),
//                     s = dt.getSeconds();

//                 msgTz = Object.assign({}, defaults, {autoCohorts: [cohorts.Tz._id], autoOnEntry: true, autoTime: h * 60 * 60000 + m * 60000 + s * 1000 + 10000});
//                 // console.log('Reference time will be %d ms, %d:%d:%d', msgTz.autoTime, h, m, s + 10);

//                 createMessage(msgTz, () => {
//                     let note = new N.Note(msgTz),
//                         anote = note.appsub(0, appsubcredentialsAndroid),
//                         streamer = new Streamer(anote);

//                     createUser('tk_a', () => {}, [event(cohorts.Tz)]);
//                     createUser('gb_a', () => {}, [event(cohorts.Tz)]);
//                     createUser('us_a', setTimeout.bind(null, () => { 

//                         regenerateCohort(cohorts.Tz._id, (err, uids) => {
//                             if (err) { return done(err); }

//                             uids.length.should.equal(4);

//                             streamer.count(db).then(count => {
//                                 count.should.equal(3);

//                                 checkEach((clb) => {
//                                     streamer.count(db).then(count => {
//                                         clb(count === 2);
//                                     });
//                                 }, 2000, 20000, '1 message should be sent', (err) => {
//                                     if (err) { return done(err); }

//                                     db.collection('messages').findOne(note._id, (err, msg) => {
//                                         if (err) { return done(err); }

//                                         msg.result.total.should.equal(3);
//                                         msg.result.processed.should.equal(1);
//                                         msg.result.sent.should.equal(1);
//                                         msg.result.errors.should.equal(0);

//                                         db.collection(streamer.collection()).find().toArray((err, arr) => {
//                                             if (err) { return done(err); }

//                                             arr.length.should.equal(2);

//                                             var tk = arr.filter(u => u.tz === 180)[0],
//                                                 us = arr.filter(u => u.tz === -420)[0];

//                                             msg.result.nextbatch.getTime().should.equal(us.da);
//                                             msg.result.status.should.equal(4);
//                                             should.not.exist(msg.result.error);

//                                             db.collection(`app_users${APP_ID}`).findOne({did: 'gb_a'}, (err, gb) => {
//                                                 if (err) { return done(err); }

//                                                 gb.msgs.length.should.equal(1);
//                                                 ('' + gb.msgs[0][0]).should.equal('' + msg._id);

//                                                 db.collection('jobs').find({'data.mid': msg._id}).toArray((err, jobs) => {
//                                                     if (err) { return done(err); }

//                                                     jobs.length.should.equal(3);
//                                                     var first = jobs.filter(j => j.status === 2).sort((a, b) => b.next - a.next),
//                                                         start = first[0],
//                                                         finished = first[1],
//                                                         next = jobs.filter(j => j.status === 0)[0];

//                                                     should.exist(start);
//                                                     should.exist(finished);
//                                                     should.exist(next);

//                                                     next.next.should.equal(us.da);

//                                                     // now let's push another user with 1 minute later tz
//                                                     createUser('de_a', setTimeout.bind(null, () => { 
//                                                         regenerateCohort(cohorts.Tz._id, (err, uids) => {
//                                                             uids.length.should.equal(5);

//                                                             streamer.count(db).then(count => {
//                                                                 count.should.equal(3);

//                                                                 checkEach((clb) => {
//                                                                     streamer.count(db).then(count => {
//                                                                         clb(count === 2);
//                                                                     });
//                                                                 }, 2000, 120000, 'another 1 message should be sent', (err) => {
//                                                                     if (err) { return done(err); }

//                                                                     db.collection('messages').findOne(note._id, (err, msg) => {
//                                                                         if (err) { return done(err); }

//                                                                         should.exist(msg);
//                                                                         msg.result.total.should.equal(4);
//                                                                         msg.result.processed.should.equal(2);
//                                                                         msg.result.sent.should.equal(2);
//                                                                         msg.result.errors.should.equal(0);
//                                                                         msg.result.nextbatch.getTime().should.equal(us.da);
//                                                                         msg.result.status.should.equal(4);
//                                                                         should.not.exist(msg.result.error);

//                                                                         db.collection(`app_users${APP_ID}`).findOne({did: 'de_a'}, (err, de) => {
//                                                                             if (err) { return done(err); }

//                                                                             should.exist(de);
//                                                                             should.exist(de.msgs);
//                                                                             de.msgs.length.should.equal(1);
//                                                                             ('' + de.msgs[0][0]).should.equal('' + msg._id);

//                                                                             db.collection('jobs').find({'data.mid': msg._id}).toArray((err, jobs) => {
//                                                                                 if (err) { return done(err); }

//                                                                                 jobs.length.should.equal(4);
//                                                                                 jobs.filter(j => j.status !== 0).length.should.equal(3);
//                                                                                 next = jobs.filter(j => j.status === 0);
//                                                                                 next.length.should.equal(1);
//                                                                                 next[0].next.should.equal(us.da);

//                                                                                 done();
//                                                                             });
//                                                                         });
//                                                                     });

//                                                                 });
//                                                             });
//                                                         });

//                                                     }, 2000), [event(cohorts.Tz)]);


//                                                 });

//                                             });


//                                             // user.msgs.length.should.equal(1);
//                                             // user.msgs[0][0].toString().should.equal('' + msg._id);

//                                             // if (user.msgs[0][1] < (Date.now() - 60000) || user.msgs[0][1] > Date.now()) {
//                                             //     done('invalid date: ' + arr[0].da + ' | ' + (arr.da - Date.now()) / 60000);
//                                             // } else {
//                                             //     done();
//                                             // }
//                                         });
//                                     });
//                                 });
//                             });
//                         });
//                     }, 2000), [event(cohorts.Tz)]);
//                 });
//             }).timeout(170000);

//             var firstSend = null;
//             it('should send first capped delay message correctly', done => {
//                 msgSleep = Object.assign({}, defaults, {autoCohorts: [cohorts.Sleep._id], autoOnEntry: true, autoCapMessages: 2, autoCapSleep: 60 * 60000});
//                 createMessage(msgSleep, () => {
//                     let note = new N.Note(msgSleep),
//                         anote = note.appsub(0, appsubcredentialsAndroid),
//                         streamer = new Streamer(anote);

//                     anote.nobuild = true;

//                     // event.timestamp = Date.now() - 24 * 60 * 60000 + 20000;
//                     createUser('gb_2a', (err) => {
//                         if (err) { return done(err); }

//                         regenerateCohort(cohorts.Sleep._id, (err, uids) => {
//                             if (err) { return done(err); }

//                             uids.length.should.equal(2);

//                             checkEach((clb) => {
//                                 streamer.count(db).then(count => {
//                                     clb(count === 0);
//                                 });
//                             }, 2000, 20000, 'streamer.count should equal 0', (err) => {
//                                 if (err) { return done(err); }

//                                 db.collection('messages').findOne(note._id, (err, msg) => {
//                                     if (err) { return done(err); }

//                                     msg.result.processed.should.equal(1);
//                                     msg.result.sent.should.equal(1);
//                                     msg.result.errors.should.equal(0);

//                                     db.collection(`app_users${APP_ID}`).findOne({did: 'gb_2a'}, (err, user) => {
//                                         if (err) { return done(err); }

//                                         user.msgs.length.should.equal(1);
//                                         user.msgs[0][0].toString().should.equal('' + msg._id);
//                                         firstSend = user.msgs[0][1];

//                                         if (firstSend < (Date.now() - 60000) || firstSend > Date.now()) {
//                                             done('invalid date: ' + firstSend + ' | ' + (firstSend - Date.now()) / 60000);
//                                         } else {
//                                             done();
//                                         }
//                                     });
//                                 });
//                             });
//                         });
//                     }, [event(cohorts.Sleep)]);
//                 });
//             });

//             it('should not send second capped delay message', done => {
//                 let note = new N.Note(msgSleep),
//                     anote = note.appsub(0, appsubcredentialsAndroid),
//                     streamer = new Streamer(anote);

//                 anote.nobuild = true;

//                 // exit from cohort
//                 db.collection(`app_users${APP_ID}`).update({did: 'gb_2a'}, {$unset: {chr: 1}}, (err) => {
//                     if (err) { return done(err); }

//                     regenerateCohort(cohorts.Sleep._id, (err, uids) => {
//                         if (err) { return done(err); }

//                         uids.length.should.equal(2);

//                         delayedCount(streamer, 3000).then((count) => {
//                             count.should.equal(0);
//                             done();
//                         }, done);
//                     });
//                 });
//             });

//             it('should process delayed message correctly', done => {
//                 msgDelay = Object.assign({}, defaults, {autoCohorts: [cohorts.Delay._id], autoOnEntry: true, autoDelay: 60 * 60000});
//                 createMessage(msgDelay, () => {
//                     let note = new N.Note(msgDelay),
//                         anote = note.appsub(0, appsubcredentialsAndroid),
//                         streamer = new Streamer(anote);

//                     anote.nobuild = true;

//                     // event.timestamp = Date.now() - 24 * 60 * 60000 + 20000;
//                     createUser('gb_3a', (err) => {
//                         if (err) { return done(err); }

//                         regenerateCohort(cohorts.Delay._id, (err, uids) => {
//                             if (err) { return done(err); }

//                             uids.length.should.equal(2);

//                             delayedCount(streamer, 2000).then((count) => {
//                                 count.should.equal(1);

//                                 db.collection('messages').findOne(note._id, (err, msg) => {
//                                     if (err) { return done(err); }

//                                     msg.result.processed.should.equal(0);
//                                     msg.result.sent.should.equal(0);

//                                     db.collection(`app_users${APP_ID}`).findOne({did: 'gb_3a'}, (err, user) => {
//                                         if (err) { return done(err); }
//                                         if (user.msgs) { return done('user has msgs'); }

//                                         db.collection(streamer.collection()).find().toArray((err, arr) => {
//                                             if (err) { return done(err); }

//                                             // console.log(arr);
//                                             arr.length.should.equal(1);
//                                             if (arr[0].da > Date.now() + 60 * 60000 || arr[0].da < Date.now() + 59 * 60000) {
//                                                 done('invalid date: ' + arr[0].da + ' | ' + (arr[0].da - Date.now()) / 60000);
//                                             } else {
//                                                 done();
//                                             }
//                                         });
//                                     });
//                                 });
//                             }, done);
//                         });
//                     }, [event(cohorts.Delay)]);
//                 });
//             });

//             it('should send now message first time', done => {
//                 msgNow = Object.assign({}, defaults, {autoCohorts: [cohorts.Now._id], autoOnEntry: true, autoCapMessages: 2});
//                 createMessage(msgNow, () => {
//                     let note = new N.Note(msgNow),
//                         anote = note.appsub(0, appsubcredentialsAndroid),
//                         streamer = new Streamer(anote);

//                     anote.nobuild = true;

//                     // event.timestamp = Date.now() - 24 * 60 * 60000 + 20000;
//                     createUser('tk_a', (err) => {
//                         if (err) { return done(err); }

//                         regenerateCohort(cohorts.Now._id, (err, uids) => {
//                             if (err) { return done(err); }

//                             uids.length.should.equal(2);

//                             checkEach((clb) => {
//                                 streamer.count(db).then(count => {
//                                     clb(count === 0);
//                                 });
//                             }, 2000, 20000, 'streamer.count should equal 0', (err) => {
//                                 if (err) { return done(err); }

//                                 db.collection('messages').findOne(note._id, (err, msg) => {
//                                     if (err) { return done(err); }

//                                     msg.result.processed.should.equal(1);
//                                     msg.result.sent.should.equal(1);
//                                     msg.result.errors.should.equal(0);

//                                     db.collection(`app_users${APP_ID}`).findOne({did: 'tk_a'}, (err, user) => {
//                                         if (err) { return done(err); }

//                                         user.msgs.length.should.equal(1);
//                                         user.msgs[0][0].toString().should.equal('' + msg._id);
//                                         done();
//                                     });
//                                 });
//                             });
//                         });
//                     }, [event(cohorts.Now)]);
//                 });
//             });

//             it('should send message second time', done => {
//                 let note = new N.Note(msgNow),
//                     anote = note.appsub(0, appsubcredentialsAndroid),
//                     streamer = new Streamer(anote);

//                 anote.nobuild = true;

//                 // exit from cohort
//                 db.collection(`app_users${APP_ID}`).update({did: 'tk_a'}, {$unset: {chr: 1}}, (err) => {
//                     if (err) { return done(err); }

//                     regenerateCohort(cohorts.Now._id, (err, uids) => {
//                         if (err) { return done(err); }

//                         uids.length.should.equal(2);

//                         checkEach((clb) => {
//                             streamer.count(db).then(count => {
//                                 clb(count === 0);
//                             });
//                         }, 2000, 20000, 'streamer.count should equal 0', (err) => {
//                             if (err) { return done(err); }

//                             db.collection('messages').findOne(note._id, (err, msg) => {
//                                 if (err) { return done(err); }

//                                 msg.result.processed.should.equal(2);
//                                 msg.result.sent.should.equal(2);
//                                 msg.result.errors.should.equal(0);

//                                 db.collection(`app_users${APP_ID}`).findOne({did: 'tk_a'}, (err, user) => {
//                                     if (err) { return done(err); }

//                                     user.msgs.length.should.equal(2);
//                                     user.msgs[0][0].toString().should.equal('' + msg._id);
//                                     user.msgs[1][0].toString().should.equal('' + msg._id);
//                                     done();
//                                 });
//                             });
//                         });
//                     });
//                 });
//             });

//             it('should not send message third time', done => {
//                 let note = new N.Note(msgNow),
//                     anote = note.appsub(0, appsubcredentialsAndroid),
//                     streamer = new Streamer(anote);

//                 anote.nobuild = true;

//                 // exit from cohort
//                 db.collection(`app_users${APP_ID}`).update({did: 'tk_a'}, {$unset: {chr: 1}}, (err) => {
//                     if (err) { return done(err); }

//                     regenerateCohort(cohorts.Now._id, (err, uids) => {
//                         if (err) { return done(err); }

//                         uids.length.should.equal(2);

//                         delayedCount(streamer, 1000).then(count => {
//                             count.should.equal(0);

//                             db.collection('messages').findOne(note._id, (err, msg) => {
//                                 if (err) { return done(err); }

//                                 msg.result.processed.should.equal(2);
//                                 msg.result.sent.should.equal(2);
//                                 msg.result.errors.should.equal(0);

//                                 db.collection(`app_users${APP_ID}`).findOne({did: 'tk_a'}, (err, user) => {
//                                     if (err) { return done(err); }

//                                     user.msgs.length.should.equal(2);
//                                     user.msgs[0][0].toString().should.equal('' + msg._id);
//                                     user.msgs[1][0].toString().should.equal('' + msg._id);
//                                     done();
//                                 });
//                             });
//                         }, done);
//                     });
//                 });
//             });
//         });
//     }

//     //Reset app
//     describe('Reset app', function(){
//       it('should reset data', function(done){
//       	var params = {app_id:APP_ID, period:"reset"};
//       	request
//       	.get('/i/apps/reset?api_key='+API_KEY_ADMIN+"&args="+JSON.stringify(params))
//       	.expect(200)
//       	.end(function(err, res){
//       		if (err) return done(err);
//       		var ob = JSON.parse(res.text);
//       		ob.should.have.property('result', 'Success');
//       		setTimeout(done, 5000)
//                   db.close();
//       	});
//       });
//     });

// });