text: const requireInject = require('require-inject')
  const { test } = require('tap')
  
  let log = ''
  
  const token = '24528a24f240'
  const profile = {}
  const read = {}
  const legacy = requireInject('../../../lib/auth/legacy.js', {
    npmlog: {
      info: (...msgs) => {
        log += msgs.join(' ')
      },
    },
    'npm-profile': profile,
    '../../../lib/utils/open-url.js': (npm, url, msg) => {
      if (!url)
        throw Object.assign(new Error('failed open url'), { code: 'ERROR' })
    },
    '../../../lib/utils/read-user-info.js': read,
  })
  
  const npm = {
    config: {
      get: () => null,
    },
  }
  
  test('login using username/password with token result', async (t) => {
    profile.login = () => {
      return { token }
    }
  
    const {
      message,
      newCreds,
    } = await legacy(npm, {
      creds: {
        username: 'u',
        password: 'p',
        email: 'u@npmjs.org',
        alwaysAuth: false,
      },
      registry: 'https://registry.npmjs.org/',
      scope: '',
    })
  
    t.equal(
      message,
      'Logged in as u on https://registry.npmjs.org/.',
      'should have correct message result'
    )
  
    t.equal(
      log,
      'login Authorized user u',
      'should have correct message result'
    )
  
    t.deepEqual(
      newCreds,
      { token },
      'should return expected obj from profile.login'
    )
  
    log = ''
    delete profile.login
  })
  
  test('login using username/password with user info result', async (t) => {
    profile.login = () => {
      return null
    }
  
    const {
      message,
      newCreds,
    } = await legacy(npm, {
      creds: {
        username: 'u',
        password: 'p',
        email: 'u@npmjs.org',
        alwaysAuth: false,
      },
      registry: 'https://registry.npmjs.org/',
      scope: '',
    })
  
    t.equal(
      message,
      'Logged in as u on https://registry.npmjs.org/.',
      'should have correct message result'
    )
  
    t.deepEqual(
      newCreds,
      {
        username: 'u',
        password: 'p',
        email: 'u@npmjs.org',
        alwaysAuth: false,
      },
      'should return used credentials'
    )
  
    log = ''
    delete profile.login
  })
  
  test('login otp requested', async (t) => {
    t.plan(5)
  
    profile.login = () => Promise.reject(Object.assign(
      new Error('needs otp'),
      { code: 'EOTP' }
    ))
    profile.loginCouch = (username, password, { otp }) => {
      t.equal(username, 'u', 'should use provided username to loginCouch')
      t.equal(password, 'p', 'should use provided password to loginCouch')
      t.equal(otp, '1234', 'should use provided otp code to loginCouch')
  
      return { token }
    }
    read.otp = () => Promise.resolve('1234')
  
    const {
      message,
      newCreds,
    } = await legacy(npm, {
      creds: {
        username: 'u',
        password: 'p',
        email: 'u@npmjs.org',
        alwaysAuth: false,
      },
      registry: 'https://registry.npmjs.org/',
      scope: '',
    })
  
    t.equal(
      message,
      'Logged in as u on https://registry.npmjs.org/.',
      'should have correct message result'
    )
  
    t.deepEqual(
      newCreds,
      { token },
      'should return token from loginCouch result'
    )
  
    log = ''
    delete profile.login
    delete profile.loginCouch
    delete read.otp
  })
  
  test('login missing basic credential info', async (t) => {
    profile.login = () => Promise.reject(Object.assign(
      new Error('missing info'),
      { code: 'ERROR' }
    ))
  
    await t.rejects(
      legacy(npm, {
        creds: {
          username: 'u',
          password: 'p',
        },
        registry: 'https://registry.npmjs.org/',
        scope: '',
      }),
      { code: 'ERROR' },
      'should throw server response error'
    )
  
    log = ''
    delete profile.login
  })
  
  test('create new user when user not found', async (t) => {
    t.plan(6)
  
    profile.login = () => Promise.reject(Object.assign(
      new Error('User does not exist'),
      { code: 'ERROR' }
    ))
    profile.adduserCouch = (username, email, password) => {
      t.equal(username, 'u', 'should use provided username to adduserCouch')
      t.equal(email, 'u@npmjs.org', 'should use provided email to adduserCouch')
      t.equal(password, 'p', 'should use provided password to adduserCouch')
  
      return { token }
    }
  
    const {
      message,
      newCreds,
    } = await legacy(npm, {
      creds: {
        username: 'u',
        password: 'p',
        email: 'u@npmjs.org',
        alwaysAuth: false,
      },
      registry: 'https://registry.npmjs.org/',
      scope: '',
    })
  
    t.equal(
      message,
      'Logged in as u on https://registry.npmjs.org/.',
      'should have correct message result'
    )
  
    t.equal(
      log,
      'login Authorized user u',
      'should have correct message result'
    )
  
    t.deepEqual(
      newCreds,
      { token },
      'should return expected obj from profile.login'
    )
  
    log = ''
    delete profile.adduserCouch
    delete profile.login
  })
  
  test('prompts for user info if required', async (t) => {
    t.plan(4)
  
    profile.login = async (opener, prompt, opts) => {
      t.equal(opts.creds.alwaysAuth, true, 'should have refs to creds if any')
      await opener('https://registry.npmjs.org/-/v1/login')
      const creds = await prompt(opts.creds)
      return creds
    }
    read.username = () => Promise.resolve('foo')
    read.password = () => Promise.resolve('pass')
    read.email = () => Promise.resolve('foo@npmjs.org')
  
    const {
      message,
      newCreds,
    } = await legacy(npm, {
      creds: {
        alwaysAuth: true,
      },
      registry: 'https://registry.npmjs.org/',
      scope: '',
    })
  
    t.equal(
      message,
      'Logged in as foo on https://registry.npmjs.org/.',
      'should have correct message result'
    )
  
    t.equal(
      log,
      'login Authorized user foo',
      'should have correct message result'
    )
  
    t.deepEqual(
      newCreds,
      {
        username: 'foo',
        password: 'pass',
        email: 'foo@npmjs.org',
        alwaysAuth: true,
      },
      'should return result from profile.login containing prompt info'
    )
  
    log = ''
    delete profile.login
    delete read.username
    delete read.password
    delete read.email
  })
  
  test('request otp when creating new user', async (t) => {
    t.plan(3)
  
    profile.login = () => Promise.reject(Object.assign(
      new Error('User does not exist'),
      { code: 'ERROR' }
    ))
    profile.adduserCouch = () => Promise.reject(Object.assign(
      new Error('needs otp'),
      { code: 'EOTP' }
    ))
    profile.loginCouch = (username, password, { otp }) => {
      t.equal(username, 'u', 'should use provided username to loginCouch')
      t.equal(password, 'p', 'should use provided password to loginCouch')
      t.equal(otp, '1234', 'should now use provided otp code to loginCouch')
  
      return { token }
    }
    read.otp = () => Promise.resolve('1234')
  
    await legacy(npm, {
      creds: {
        username: 'u',
        password: 'p',
        email: 'u@npmjs.org',
        alwaysAuth: false,
      },
      registry: 'https://registry.npmjs.org/',
      scope: '',
    })
  
    log = ''
    delete profile.adduserCouch
    delete profile.login
    delete profile.loginCouch
    delete read.otp
  })
  
  test('unknown error during user creation', async (t) => {
    profile.login = () => Promise.reject(Object.assign(
      new Error('missing info'),
      { code: 'ERROR' }
    ))
    profile.adduserCouch = () => Promise.reject(Object.assign(
      new Error('unkown error'),
      { code: 'ERROR' }
    ))
  
    await t.rejects(
      legacy(npm, {
        creds: {
          username: 'u',
          password: 'p',
          email: 'u@npmjs.org',
          alwaysAuth: false,
        },
        registry: 'https://registry.npmjs.org/',
        scope: '',
      }),
      { code: 'ERROR' },
      'should throw unknown error'
    )
  
    log = ''
    delete profile.adduserCouch
    delete profile.login
  })
  
  test('open url error', async (t) => {
    profile.login = async (opener, prompt, opts) => {
      await opener()
    }
  
    await t.rejects(
      legacy(npm, {
        creds: {
          username: 'u',
          password: 'p',
        },
        registry: 'https://registry.npmjs.org/',
        scope: '',
      }),
      { message: 'failed open url', code: 'ERROR' },
      'should throw unknown error'
    )
  
    log = ''
    delete profile.login
  })
  
  test('login no credentials provided', async (t) => {
    profile.login = () => ({ token })
  
    await legacy(npm, {
      creds: {
        username: undefined,
        password: undefined,
        email: undefined,
        alwaysAuth: undefined,
      },
      registry: 'https://registry.npmjs.org/',
      scope: '',
    })
  
    t.equal(
      log,
      'login Authorized',
      'should have correct message result'
    )
  
    log = ''
    delete profile.login
  })
  
  test('scoped login', async (t) => {
    profile.login = () => ({ token })
  
    const { message } = await legacy(npm, {
      creds: {
        username: 'u',
        password: 'p',
        email: 'u@npmjs.org',
        alwaysAuth: false,
      },
      registry: 'https://diff-registry.npmjs.org/',
      scope: 'myscope',
    })
  
    t.equal(
      message,
      'Logged in as u to scope myscope on https://diff-registry.npmjs.org/.',
      'should have correct message result'
    )
  
    t.equal(
      log,
      'login Authorized user u',
      'should have correct message result'
    )
  
    log = ''
    delete profile.login
  })
  