<commit_before>'use strict'

const test = require('tape')

const config = require('../config.js')
const adapterOptions = {dsn: config.d2alias}

const {recordTypes, initialData, prepareTestTables} = require('../adapter/_prepare-test-db')

const Context = require('./context')
const DataMapper = require('./index')

test('I&T datamapper.find()', (t) => {
  const mapper = new DataMapper(recordTypes, adapterOptions)

  prepareTestTables(initialData)

  .then(() => mapper.find(new Context({
    type: 'user'
  })))
  .then((context) => t.deepEqual(
    context.response.payload.records,
    [
      {id: 1, name: 'John', deleted: false, group: 1},
      {id: 2, name: 'Smith', deleted: false, group: 1},
      {id: 3, name: 'Johanna', deleted: false, group: 2},
      {id: 4, name: 'Ann', deleted: true, group: 2},
      {id: 5, name: 'Makbeth', deleted: false, group: 2}
    ],
    'by default it fetches all records'
  ))

  .then(() => mapper.find(new Context({
    type: 'user',
    ids: [1, 2, 3, 5]
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {
        records: [
          {id: 1, name: 'John', deleted: false, group: 1},
          {id: 2, name: 'Smith', deleted: false, group: 1},
          {id: 3, name: 'Johanna', deleted: false, group: 2},
          {id: 5, name: 'Makbeth', deleted: false, group: 2}
        ]
      }
    },
    'with ids'
  ))

  .then(() => mapper.find(new Context({
    type: 'user',
    options: {
      match: {group: 1}
    }
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {
        records: [
          {id: 1, name: 'John', deleted: false, group: 1},
          {id: 2, name: 'Smith', deleted: false, group: 1}
        ]
      }
    },
    'with options.match belongsTo'
  ))

  .catch(t.fail)
  .then(t.end)
})

test('I&T datamapper.find() include belongsTo', (t) => {
  const mapper = new DataMapper(recordTypes, adapterOptions)

  prepareTestTables(initialData)

  .then(() => mapper.find(new Context({
    type: 'user',
    include: [['group']]
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {
        records: [
          {id: 1, name: 'John', deleted: false, group: 1},
          {id: 2, name: 'Smith', deleted: false, group: 1},
          {id: 3, name: 'Johanna', deleted: false, group: 2},
          {id: 4, name: 'Ann', deleted: true, group: 2},
          {id: 5, name: 'Makbeth', deleted: false, group: 2}
        ],
        include: {
          group: [
            {id: 1, name: 'Admins', deleted: false},
            {id: 2, name: 'Users', deleted: false}
            // {id: 3, name: 'Officers', deleted: true} - this group is not used
          ]
        }
      }
    },
    '"include" option with belongsTo'
  ))

  .then(() => mapper.find(new Context({
    type: 'user',
    options: {
      match: {deleted: false},
      fieldsOnly: ['id', 'name'] // 'group' will be added b/c of 'include'
    },
    include: [['group', {fieldsOnly: ['id', 'name']}]]
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {
        records: [
          {id: 1, name: 'John', group: 1},
          {id: 2, name: 'Smith', group: 1},
          {id: 3, name: 'Johanna', group: 2},
          {id: 5, name: 'Makbeth', group: 2}
        ],
        include: {
          group: [
            {id: 1, name: 'Admins'},
            {id: 2, name: 'Users'}
          ]
        }
      }
    },
    '"include" belongsTo with additional options'
  ))

  .catch(t.fail)
  .then(t.end)
})

test('I&T datamapper.find() include hasMany', (t) => {
  const recordTypesHasMany = Object.assign({}, recordTypes)
  recordTypesHasMany.group.users = { link: 'user', isArray: true }
  const mapper = new DataMapper(recordTypesHasMany, adapterOptions)

  prepareTestTables(initialData)

  .then(() => mapper.find(new Context({
    type: 'group',
    include: [['users']]
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {
        records: [
          {id: 1, name: 'Admins', deleted: false, users: [1, 2]},
          {id: 2, name: 'Users', deleted: false, users: [3, 4, 5]},
          {id: 3, name: 'Officers', deleted: true, users: []}
        ],
        include: {
          user: [
            {id: 1, name: 'John', deleted: false, group: 1},
            {id: 2, name: 'Smith', deleted: false, group: 1},
            {id: 3, name: 'Johanna', deleted: false, group: 2},
            {id: 4, name: 'Ann', deleted: true, group: 2},
            {id: 5, name: 'Makbeth', deleted: false, group: 2}
          ]
        }
      }
    },
    '"include" everything with hasMany'
  ))

  .catch(t.fail)
  .then(t.end)
})

test('I&T datamapper.find() w/o `include` but w/ hasMany fields', (t) => {
  const recordTypesHasMany = Object.assign({}, recordTypes)
  recordTypesHasMany.group.users = { link: 'user', isArray: true }
  const mapper = new DataMapper(recordTypesHasMany, adapterOptions)

  prepareTestTables(initialData)

  .then(() => mapper.find(new Context({
    type: 'group'
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {<commit_msg>add I&T datamapper.find() include hasMany w/ additional options<commit_after>'use strict'

const test = require('tape')

const config = require('../config.js')
const adapterOptions = {dsn: config.d2alias}

const {recordTypes, initialData, prepareTestTables} = require('../adapter/_prepare-test-db')

const Context = require('./context')
const DataMapper = require('./index')

test('I&T datamapper.find()', (t) => {
  const mapper = new DataMapper(recordTypes, adapterOptions)

  prepareTestTables(initialData)

  .then(() => mapper.find(new Context({
    type: 'user'
  })))
  .then((context) => t.deepEqual(
    context.response.payload.records,
    [
      {id: 1, name: 'John', deleted: false, group: 1},
      {id: 2, name: 'Smith', deleted: false, group: 1},
      {id: 3, name: 'Johanna', deleted: false, group: 2},
      {id: 4, name: 'Ann', deleted: true, group: 2},
      {id: 5, name: 'Makbeth', deleted: false, group: 2}
    ],
    'by default it fetches all records'
  ))

  .then(() => mapper.find(new Context({
    type: 'user',
    ids: [1, 2, 3, 5]
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {
        records: [
          {id: 1, name: 'John', deleted: false, group: 1},
          {id: 2, name: 'Smith', deleted: false, group: 1},
          {id: 3, name: 'Johanna', deleted: false, group: 2},
          {id: 5, name: 'Makbeth', deleted: false, group: 2}
        ]
      }
    },
    'with ids'
  ))

  .then(() => mapper.find(new Context({
    type: 'user',
    options: {
      match: {group: 1}
    }
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {
        records: [
          {id: 1, name: 'John', deleted: false, group: 1},
          {id: 2, name: 'Smith', deleted: false, group: 1}
        ]
      }
    },
    'with options.match belongsTo'
  ))

  .catch(t.fail)
  .then(t.end)
})

test('I&T datamapper.find() include belongsTo: w/ and w/o additional options', (t) => {
  const mapper = new DataMapper(recordTypes, adapterOptions)

  prepareTestTables(initialData)

  .then(() => mapper.find(new Context({
    type: 'user',
    include: [['group']]
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {
        records: [
          {id: 1, name: 'John', deleted: false, group: 1},
          {id: 2, name: 'Smith', deleted: false, group: 1},
          {id: 3, name: 'Johanna', deleted: false, group: 2},
          {id: 4, name: 'Ann', deleted: true, group: 2},
          {id: 5, name: 'Makbeth', deleted: false, group: 2}
        ],
        include: {
          group: [
            {id: 1, name: 'Admins', deleted: false},
            {id: 2, name: 'Users', deleted: false}
            // {id: 3, name: 'Officers', deleted: true} - this group is not used
          ]
        }
      }
    },
    '"include" option with belongsTo'
  ))

  .then(() => mapper.find(new Context({
    type: 'user',
    options: {
      match: {deleted: false},
      fieldsOnly: ['id', 'name'] // 'group' will be added b/c of 'include'
    },
    include: [['group', {fieldsOnly: ['id', 'name']}]]
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {
        records: [
          {id: 1, name: 'John', group: 1},
          {id: 2, name: 'Smith', group: 1},
          {id: 3, name: 'Johanna', group: 2},
          {id: 5, name: 'Makbeth', group: 2}
        ],
        include: {
          group: [
            {id: 1, name: 'Admins'},
            {id: 2, name: 'Users'}
          ]
        }
      }
    },
    '"include" belongsTo with additional options'
  ))

  .catch(t.fail)
  .then(t.end)
})

test('I&T datamapper.find() include hasMany', (t) => {
  const recordTypesHasMany = Object.assign({}, recordTypes)
  recordTypesHasMany.group.users = { link: 'user', isArray: true }
  const mapper = new DataMapper(recordTypesHasMany, adapterOptions)

  prepareTestTables(initialData)

  .then(() => mapper.find(new Context({
    type: 'group',
    include: [['users']]
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {
        records: [
          {id: 1, name: 'Admins', deleted: false, users: [1, 2]},
          {id: 2, name: 'Users', deleted: false, users: [3, 4, 5]},
          {id: 3, name: 'Officers', deleted: true, users: []}
        ],
        include: {
          user: [
            {id: 1, name: 'John', deleted: false, group: 1},
            {id: 2, name: 'Smith', deleted: false, group: 1},
            {id: 3, name: 'Johanna', deleted: false, group: 2},
            {id: 4, name: 'Ann', deleted: true, group: 2},
            {id: 5, name: 'Makbeth', deleted: false, group: 2}
          ]
        }
      }
    },
    '"include" everything with hasMany'
  ))

  .catch(t.fail)
  .then(t.end)
})

test('I&T datamapper.find() include hasMany w/ additional options', (t) => {
  const recordTypesHasMany = Object.assign({}, recordTypes)
  recordTypesHasMany.group.users = { link: 'user', isArray: true }
  const mapper = new DataMapper(recordTypesHasMany, adapterOptions)

  prepareTestTables(initialData)

  .then(() => mapper.find(new Context({
    type: 'group',
    include: [['users', {match: {deleted: false}, fieldsOnly: ['name']}]]
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {
        records: [
          {id: 1, name: 'Admins', deleted: false, users: [1, 2]},
          {id: 2, name: 'Users', deleted: false, users: [3, 5]},
          {id: 3, name: 'Officers', deleted: true, users: []}
        ],
        include: {
          user: [
            {id: 1, name: 'John', group: 1},
            {id: 2, name: 'Smith', group: 1},
            {id: 3, name: 'Johanna', group: 2},
            {id: 5, name: 'Makbeth', group: 2}
          ]
        }
      }
    },
    '"include" hasMany merges additional options'
  ))

  .catch(t.fail)
  .then(t.end)
})

test('I&T datamapper.find() w/o `include` but w/ hasMany fields', (t) => {
  const recordTypesHasMany = Object.assign({}, recordTypes)
  recordTypesHasMany.group.users = { link: 'user', isArray: true }
  const mapper = new DataMapper(recordTypesHasMany, adapterOptions)

  prepareTestTables(initialData)

  .then(() => mapper.find(new Context({
    type: 'group'
  })))
  .then((context) => t.deepEqual(
    context.response,
    {
      payload: {
{'fraction_non_alphanumeric': 0.18165217391304347, 'fraction_numerical': 0.013304347826086957, 'mean_word_length': 2.3589369158878504, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4310659', 'n_tokens_mistral': 4124, 'n_tokens_neox': 3913, 'n_words': 1052}