Home Reference Source Test

src/lib/core/md-seed-runner.test.js

import test from 'ava';
import sinon from 'sinon';
import { toArray } from 'rxjs/operators';

import { mockImports, resetImports } from '../utils/test-helpers';

import MdSeedRunnerError from './md-seed-runner-error';

import MdSeedRunner, {
  __RewireAPI__ as moduleRewireAPI,
} from './md-seed-runner';

const helpData = {
  connect: sinon.stub().resolves(),
  dropdb: sinon.stub().resolves(),
  seedersList: {
    Users: 'users-seeder',
    Posts: 'posts-seeder',
  },
};

test.beforeEach('mock imports', t => {
  const mocks = {
    getObjectWithSelectedKeys: sinon.stub(),
    normalizeSeederName: sinon.stub().returnsArg(0),
  };

  t.context = { mocks };

  mockImports({ moduleRewireAPI, mocks });
});

test.afterEach.always('unmock imports', t => {
  const imports = Object.keys(t.context.mocks);

  resetImports({ moduleRewireAPI, imports });
});

test('Should create a run-logger instance', t => {
  const seedRunner = new MdSeedRunner({ ...helpData });

  t.is(seedRunner.connect, helpData.connect);
  t.is(seedRunner.dropdb, helpData.dropdb);
  t.is(seedRunner.seedersList, helpData.seedersList);
  t.is(typeof seedRunner.run, 'function');
});

test('Should run', t => {
  const seedRunner = new MdSeedRunner({ ...helpData });

  sinon.stub(seedRunner, '_run');

  const observable = seedRunner.run();

  t.true(
    seedRunner._run.calledWith({ selectedSeeders: [], dropDatabase: false })
  );
  t.is(typeof observable.subscribe, 'function');
});

test('Should run with args', t => {
  const seedRunner = new MdSeedRunner({ ...helpData });

  sinon.stub(seedRunner, '_run');

  const selectedSeeders = Object.keys(helpData.seedersList);
  const dropDatabase = true;

  const observable = seedRunner.run({ selectedSeeders, dropDatabase });

  t.true(seedRunner._run.calledWith({ selectedSeeders, dropDatabase }));
  t.is(typeof observable.subscribe, 'function');
});

test('Should _run', async t => {
  t.plan(4);

  const seedRunner = new MdSeedRunner({ ...helpData });

  sinon.stub(seedRunner, '_connectToMongodb').resolves();
  sinon.stub(seedRunner, '_dropDatabase').resolves();
  sinon.stub(seedRunner, '_runSeeders').resolves();

  const selectedSeeders = Object.keys(helpData.seedersList);
  const dropDatabase = false;

  seedRunner._subject
    .asObservable()
    .pipe(toArray())
    .toPromise()
    .then(results => t.snapshot(results));

  await seedRunner._run({ selectedSeeders, dropDatabase });

  t.true(seedRunner._connectToMongodb.called);
  t.true(seedRunner._runSeeders.calledWith(selectedSeeders));
  t.false(seedRunner._dropDatabase.called);
});

test('Should _run and drop database', async t => {
  t.plan(4);

  const seedRunner = new MdSeedRunner({ ...helpData });

  sinon.stub(seedRunner, '_connectToMongodb').resolves();
  sinon.stub(seedRunner, '_dropDatabase').resolves();
  sinon.stub(seedRunner, '_runSeeders').resolves();

  const selectedSeeders = Object.keys(helpData.seedersList);
  const dropDatabase = true;

  seedRunner._subject
    .asObservable()
    .pipe(toArray())
    .toPromise()
    .then(results => t.snapshot(results));

  await seedRunner._run({ selectedSeeders, dropDatabase });

  t.true(seedRunner._connectToMongodb.called);
  t.true(seedRunner._runSeeders.calledWith(selectedSeeders));
  t.true(seedRunner._dropDatabase.called);
});

test('Should _run and fail', async t => {
  t.plan(4);

  const seedRunner = new MdSeedRunner({ ...helpData });

  sinon.stub(seedRunner, '_connectToMongodb').rejects();
  sinon.stub(seedRunner, '_dropDatabase').resolves();
  sinon.stub(seedRunner, '_runSeeders').resolves();

  const selectedSeeders = Object.keys(helpData.seedersList);
  const dropDatabase = true;

  seedRunner._subject
    .asObservable()
    .pipe(toArray())
    .toPromise()
    .catch(error => t.snapshot(error));

  await seedRunner._run({ selectedSeeders, dropDatabase });

  t.true(seedRunner._connectToMongodb.called);
  t.false(seedRunner._runSeeders.called);
  t.false(seedRunner._dropDatabase.called);
});

test('Should _run and fail with type and payload', async t => {
  t.plan(4);

  const seedRunner = new MdSeedRunner({ ...helpData });

  const error = new MdSeedRunnerError({
    type: 'some-type',
    payload: { some: 'data' },
    error: new Error('some error message'),
  });

  sinon.stub(seedRunner, '_connectToMongodb').rejects(error);
  sinon.stub(seedRunner, '_dropDatabase').resolves();
  sinon.stub(seedRunner, '_runSeeders').resolves();

  const selectedSeeders = Object.keys(helpData.seedersList);
  const dropDatabase = true;

  seedRunner._subject
    .asObservable()
    .pipe(toArray())
    .toPromise()
    .catch(error => t.snapshot(error));

  await seedRunner._run({ selectedSeeders, dropDatabase });

  t.true(seedRunner._connectToMongodb.called);
  t.false(seedRunner._runSeeders.called);
  t.false(seedRunner._dropDatabase.called);
});

test('Should _connectToMongodb', async t => {
  t.plan(2);

  const seedRunner = new MdSeedRunner({ ...helpData });

  seedRunner._subject
    .asObservable()
    .pipe(toArray())
    .toPromise()
    .then(results => t.snapshot(results));

  await seedRunner._connectToMongodb();

  seedRunner._subject.complete();

  t.true(helpData.connect.called);
});

test('Should _connectToMongodb and fail', async t => {
  t.plan(3);

  const data = {
    ...helpData,
    connect: sinon.stub().rejects(new Error('some-error')),
  };

  const seedRunner = new MdSeedRunner({ ...data });

  seedRunner._subject
    .asObservable()
    .pipe(toArray())
    .toPromise()
    .then(results => t.snapshot(results, 'observable results'));

  try {
    await seedRunner._connectToMongodb();
  } catch (error) {
    t.snapshot(error, 'connect to mongodb error');
  }

  seedRunner._subject.complete();

  t.true(data.connect.called);
});

test('Should _dropDatabase', async t => {
  t.plan(2);

  const seedRunner = new MdSeedRunner({ ...helpData });

  seedRunner._subject
    .asObservable()
    .pipe(toArray())
    .toPromise()
    .then(results => t.snapshot(results));

  await seedRunner._dropDatabase();

  seedRunner._subject.complete();

  t.true(helpData.dropdb.called);
});

test('Should _dropDatabase and fail', async t => {
  t.plan(3);

  const data = {
    ...helpData,
    dropdb: sinon.stub().rejects(new Error('some-error')),
  };

  const seedRunner = new MdSeedRunner({ ...data });

  seedRunner._subject
    .asObservable()
    .pipe(toArray())
    .toPromise()
    .then(results => t.snapshot(results, 'observable results'));

  try {
    await seedRunner._dropDatabase();
  } catch (error) {
    t.snapshot(error, 'dropdb error');
  }

  seedRunner._subject.complete();

  t.true(data.dropdb.called);
});

test('Should _runSeeders', async t => {
  t.plan(3);

  const selectedSeeders = Object.keys(helpData.seedersList);

  const seedRunner = new MdSeedRunner({ ...helpData });

  sinon
    .stub(seedRunner, '_loadSelectedSeeders')
    .withArgs(selectedSeeders)
    .returns(selectedSeeders);
  sinon.stub(seedRunner, '_runSeeder').resolves();

  seedRunner._subject
    .asObservable()
    .pipe(toArray())
    .toPromise()
    .then(results => t.snapshot(results, 'observable results'));

  await seedRunner._runSeeders(selectedSeeders);

  seedRunner._subject.complete();

  t.true(seedRunner._loadSelectedSeeders.calledWith(selectedSeeders));
  t.snapshot(seedRunner._runSeeder.args, '_runSeeder args');
});

test('Should _runSeeder', async t => {
  t.plan(3);

  const name = 'User';
  const Seeder = sinon.stub();
  Seeder.prototype.seed = sinon.stub().resolves('some-results');

  const seedRunner = new MdSeedRunner({ ...helpData });

  seedRunner._subject
    .asObservable()
    .pipe(toArray())
    .toPromise()
    .then(results => t.snapshot(results, 'observable results'));

  await seedRunner._runSeeder({ Seeder, name });

  seedRunner._subject.complete();

  t.true(Seeder.called);
  t.true(Seeder.prototype.seed.called);
});

test('Should _runSeeder and fail', async t => {
  t.plan(4);

  const name = 'User';
  const Seeder = sinon.stub();
  Seeder.prototype.seed = sinon.stub().rejects(new Error('some-error'));

  const seedRunner = new MdSeedRunner({ ...helpData });

  seedRunner._subject
    .asObservable()
    .pipe(toArray())
    .toPromise()
    .then(results => t.snapshot(results, 'observable results'));

  try {
    await seedRunner._runSeeder({ Seeder, name });
  } catch (error) {
    t.snapshot(error, '_runSeeder error');
  }

  seedRunner._subject.complete();

  t.true(Seeder.called);
  t.true(Seeder.prototype.seed.called);
});

test('should _loadSelectedSeeders with no args', t => {
  const seedRunner = new MdSeedRunner({ ...helpData });

  const selectedSeeders = seedRunner._loadSelectedSeeders();

  t.is(selectedSeeders, helpData.seedersList);
});

test('should _loadSelectedSeeders with empty array', t => {
  const seedRunner = new MdSeedRunner({ ...helpData });

  const selectedSeeders = seedRunner._loadSelectedSeeders([]);

  t.is(selectedSeeders, helpData.seedersList);
});

test('should _loadSelectedSeeders', t => {
  const { getObjectWithSelectedKeys } = t.context.mocks;

  const seedRunner = new MdSeedRunner({ ...helpData });

  seedRunner._loadSelectedSeeders(['User']);

  t.true(getObjectWithSelectedKeys.calledWith(helpData.seedersList, ['User']));
});