{"size": 9788, "ext": "js", "max_stars_repo_path": "tests/unit/migrations/extract-person-contacts.js", "max_stars_repo_name": "medic/medic-api", "max_stars_repo_stars_event_min_datetime": "2015-03-21T20:29:12.000Z", "max_stars_repo_stars_event_max_datetime": "2021-11-08T12:14:25.000Z", "max_issues_repo_path": "tests/unit/migrations/extract-person-contacts.js", "max_issues_repo_name": "medic/medic-api", "max_issues_repo_issues_event_min_datetime": "2015-02-23T20:46:32.000Z", "max_issues_repo_issues_event_max_datetime": "2019-01-11T01:09:04.000Z", "max_forks_repo_path": "tests/unit/migrations/extract-person-contacts.js", "max_forks_repo_name": "medic/medic-api", "max_forks_repo_forks_event_min_datetime": "2015-06-11T07:20:21.000Z", "max_forks_repo_forks_event_max_datetime": "2018-12-05T15:48:42.000Z"}
{"max_stars_count": 3, "max_issues_count": 91, "max_forks_count": 8, "avg_line_length": 32.4105960265, "max_line_length": 88, "alphanum_fraction": 0.6265835717}
var sinon = require('sinon').sandbox.create(),
    db = require('../../../db'),
    people = require('../../../controllers/people'),
    places = require('../../../controllers/places'),
    migration = require('../../../migrations/extract-person-contacts');

var createPerson, getDoc, getView, insertDoc, updatePlace;

exports.setUp = function(done) {
  getView = sinon.stub(db.medic, 'view');
  getDoc = sinon.stub(db.medic, 'get');
  insertDoc = sinon.stub(db.medic, 'insert');
  updatePlace = sinon.stub(places, 'updatePlace');
  createPerson = sinon.stub(people, 'createPerson');
  done();
};

exports.tearDown = function (callback) {
  sinon.restore();
  callback();
};

exports['run does nothing if no facilities'] = function(test) {
  test.expect(6);
  getView.callsArgWith(3, null, { rows: [] });
  getDoc.callsArgWith(1, null, {  });
  migration.run(function(err) {
    test.equals(err, undefined);
    // Called once per place type.
    test.equals(getView.callCount, 3);
    test.equals(getDoc.callCount, 0);
    // No edits happened.
    test.equals(insertDoc.callCount, 0);
    test.equals(updatePlace.callCount, 0);
    test.equals(createPerson.callCount, 0);
    test.done();
  });
};

var testParentUpdated = function(test, doc, docWithoutParent) {
  test.expect(13);

  // Get the 3 levels of hierarchy
  getView.onCall(0).callsArgWith(3, null, { rows: [ { id: 'a' }] });
  getView.onCall(1).callsArgWith(3, null, { rows: [ ] });
  getView.onCall(2).callsArgWith(3, null, { rows: [ ] });

  // Get doc for parent update
  getDoc.onCall(0).callsArgWith(1, null, doc);
  // Get parent doc
  getDoc.onCall(1).callsArgWith(1, null, { _id: 'b', contact: {}, newKey: 'newValue' });
  getDoc.onCall(2).callsArgWith(1, null, { _id: 'b', contact: {}, newKey: 'newValue' });

  // Update doc : deleted parent
  insertDoc.onCall(0).callsArgWith(1, null);
  // Update doc : update the parent field
  updatePlace.onCall(0).callsArgWith(2, null);
  // Get doc for contact update : no contact, so skipped.
  getDoc.onCall(3).callsArgWith(1, null, { _id: 'a', parent: { _id: 'b'} });

  migration.run(function(err) {
    test.equals(err, undefined);
    // Called once per place type.
    test.equals(getView.callCount, 3);

    test.equals(getDoc.callCount, 4);
    test.equals(getDoc.firstCall.args[0], 'a');
    test.equals(getDoc.secondCall.args[0], 'b');
    test.equals(getDoc.thirdCall.args[0], 'b');
    test.equals(getDoc.lastCall.args[0], 'a');

    // Parent was deleted, then reset.
    test.equals(insertDoc.callCount, 1);
    test.deepEqual(insertDoc.firstCall.args[0], docWithoutParent);
    test.equals(updatePlace.callCount, 1);
    test.equals(updatePlace.firstCall.args[0], 'a');
    test.deepEqual(updatePlace.firstCall.args[1], { parent: 'b'});

    // No contact created.
    test.equals(createPerson.callCount, 0);

    test.done();
  });
};

exports['run still updates parent if facility have no contact'] = function(test) {
  testParentUpdated(
    test,
    {
      _id: 'a',
      parent: { _id: 'b', contact: {}}
    },
    {
      _id: 'a',
    });
};

exports['run still updates parent if facility has migrated contact'] = function(test) {
  testParentUpdated(test,
    {
      _id: 'a',
      parent: { _id: 'b', contact: {}},
      contact: { _id: 'd' }
    },
    {
      _id: 'a',
      contact: { _id: 'd' }
    });
};

var testContactUpdated = function(test, doc, docWithoutContact) {
  test.expect(12);

  // Get the 3 levels of hierarchy
  getView.onCall(0).callsArgWith(3, null, { rows: [ { id: 'a' }] });
  getView.onCall(1).callsArgWith(3, null, { rows: [ ] });
  getView.onCall(2).callsArgWith(3, null, { rows: [ ] });

  // Get doc for parent update : no parent, so parent update is skipped.
  getDoc.onCall(0).callsArgWith(1, null, doc);
  // Get doc for contact update.
  getDoc.onCall(1).callsArgWith(1, null, doc);
  // Update doc : deleted contact
  insertDoc.onCall(0).callsArgWith(1, null);
  // Create person doc
  createPerson.onCall(0).callsArgWith(1, null, { id: 'c'});
  // Update doc : reset the contact field
  updatePlace.onCall(0).callsArgWith(2, null);

  migration.run(function(err) {
    test.equals(err, undefined);
    // Called once per place type.
    test.equals(getView.callCount, 3);

    test.equals(getDoc.callCount, 2);
    test.equals(getDoc.firstCall.args[0], 'a');
    test.equals(getDoc.secondCall.args[0], 'a');

    // Contact was deleted, then reset.
    test.equals(insertDoc.callCount, 1);
    test.deepEqual(insertDoc.firstCall.args[0], docWithoutContact);
    test.equals(updatePlace.callCount, 1);
    test.equals(updatePlace.firstCall.args[0], 'a');
    test.deepEqual(updatePlace.firstCall.args[1], { contact: 'c'});

    // Contact was created.
    test.equals(createPerson.callCount, 1);
    test.deepEqual(createPerson.firstCall.args[0], {
        name: 'name',
        phone: 'phone',
        place: 'a'
      });

    test.done();
  });

};

exports['run still updates contact if facility has no parent'] = function(test) {
  testContactUpdated(
    test,
    { _id: 'a', contact: { name: 'name', 'phone': 'phone'} },
    { _id: 'a'});
};

exports['run still updates contact if facility has migrated parent'] = function(test) {
  testContactUpdated(
    test,
    {
      _id: 'a',
      contact: { name: 'name', 'phone': 'phone'},
      parent: {_id: 'b', contact: {_id: 'f'}}
    },
    {
      _id: 'a',
      parent: {_id: 'b', contact: {_id: 'f'}}
    });
};

exports['run updates contact and parent'] = function(test) {
  test.expect(17);

  // Get the 3 levels of hierarchy
  getView.onCall(0).callsArgWith(3, null, { rows: [ { id: 'a' }] });
  getView.onCall(1).callsArgWith(3, null, { rows: [ ] });
  getView.onCall(2).callsArgWith(3, null, { rows: [ ] });

  // Get doc for parent update
  getDoc.onCall(0).callsArgWith(1, null, {
    _id: 'a',
    contact: { name: 'name', 'phone': 'phone'},
    parent: {_id: 'b', contact: { name: 'name1', 'phone': 'phone1' }}
  });
  // Get parent doc
  getDoc.onCall(1).callsArgWith(1, null, { _id: 'b', contact: {}, newKey: 'newValue' });
  getDoc.onCall(2).callsArgWith(1, null, { _id: 'b', contact: {}, newKey: 'newValue' });
  // Update doc : deleted parent
  insertDoc.onCall(0).callsArgWith(1, null);
  // Update doc : update the parent field
  updatePlace.onCall(0).callsArgWith(2, null);
  // Get doc for contact update
  getDoc.onCall(3).callsArgWith(1, null, {
    _id: 'a',
    contact: { name: 'name', phone: 'phone', rc_code: 'oldRcCode' },
    parent: { _id: 'b', contact: {_id: 'f'}}
  });
  // Update doc : deleted contact
  insertDoc.onCall(1).callsArgWith(1, null);
  // Create person doc
  createPerson.onCall(0).callsArgWith(1, null, { id: 'c'});
  // Update doc : reset the contact field
  updatePlace.onCall(1).callsArgWith(2, null);

  migration.run(function(err) {
    test.equals(err, undefined);
    // Called once per place type.
    test.equals(getView.callCount, 3);

    test.equals(getDoc.callCount, 4);
    test.equals(getDoc.firstCall.args[0], 'a');
    test.equals(getDoc.secondCall.args[0], 'b');
    test.equals(getDoc.thirdCall.args[0], 'b');
    test.equals(getDoc.lastCall.args[0], 'a');

    test.equals(insertDoc.callCount, 2);
    test.equals(updatePlace.callCount, 2);
    // Parent was deleted, then reset.
    test.deepEqual(insertDoc.firstCall.args[0], {
      _id: 'a',
      contact: { name: 'name', phone: 'phone'},
    });
    test.equals(updatePlace.firstCall.args[0], 'a');
    test.deepEqual(updatePlace.firstCall.args[1], { parent: 'b'});

    // Contact was deleted, then reset.
    test.deepEqual(insertDoc.secondCall.args[0], {
      _id: 'a',
      parent: { _id: 'b', contact: {_id: 'f'}}
    });
    test.equals(updatePlace.secondCall.args[0], 'a');
    test.deepEqual(updatePlace.secondCall.args[1], {
      contact: 'c',
      place_id: 'oldRcCode'
    });
    // Contact created.
    test.equals(createPerson.callCount, 1);
    test.deepEqual(createPerson.firstCall.args[0], {
      name: 'name',
      phone: 'phone',
      place: 'a'
    });

    test.done();
  });
};

exports['run attempts to revert the contact on error'] = function(test) {
  test.expect(4);

  // Get the 3 levels of hierarchy
  getView.onCall(0).callsArgWith(3, null, { rows: [ { id: 'a' }] });
  getView.onCall(1).callsArgWith(3, null, { rows: [ ] });
  getView.onCall(2).callsArgWith(3, null, { rows: [ ] });

  // Get doc for parent update
  getDoc.onCall(0).callsArgWith(1, null, {
      _id: 'a',
      contact: { name: 'name', phone: 'phone'},
      parent: {_id: 'b', contact: { name: 'name1', 'phone': 'phone1' }}
    });
  // Get parent doc
  getDoc.onCall(1).callsArgWith(1, null, { _id: 'b', contact: {}, newKey: 'newValue' });
  getDoc.onCall(2).callsArgWith(1, null, { _id: 'b', contact: {}, newKey: 'newValue' });
  // Update doc : deleted parent
  insertDoc.onCall(0).callsArg(1);
  // Update doc : update the parent field
  updatePlace.onCall(0).callsArg(2);
  // Get doc for contact update
  getDoc.onCall(3).callsArgWith(1, null,
    {
      _id: 'a',
      contact: { name: 'name', phone: 'phone'},
      parent: { _id: 'b', contact: {_id: 'f'}}
    });
  // Update doc : deleted contact
  insertDoc.onCall(1).callsArg(1);
  // Create person doc
  createPerson.onCall(0).callsArgWith(1, null, { id: 'c'});
  // Update doc : reset the contact field
  updatePlace.onCall(1).callsArgWith(2, 'error');
  // Restore the parent
  updatePlace.onCall(2).callsArg(2);

  migration.run(function(err) {
    test.equals(err.message, 'Failed to update contact on facility a: "error"');
    test.equals(updatePlace.thirdCall.args[0], 'a');
    test.equals(updatePlace.thirdCall.args[1].contact.name, 'name');
    test.equals(updatePlace.thirdCall.args[1].contact.phone, 'phone');
    test.done();
  });
};
