
<%- tplTsOnly(`/// <reference types="mocha"/>${EOL}`) -%>
<%- tplImports('assert', null) %>
<%- tplImports('feathersClient', '@feathersjs/client') %>
<%- tplImports('io', 'socket.io-client') %>
<%- tplTsOnly(`import { Server } from 'http'${sc}`) %>
<%- tplImports('{ join }', 'path') %>
<%- tplImports('{ localStorage, readJsonFileSync }', '@feathers-plus/test-utils') %>

<%- tplImports('config', `${ pathTestToApp }config/default.json`) %>

const delayAfterServerOnce = 500<%- sc %>
const delayAfterServerClose = 500<%- sc %>
const timeoutForStartingServerAndClient = 30000<%- sc %>
const timeoutForClosingingServerAndClient = 30000<%- sc %>

const email = 'login@example.com'<%- sc %>
const password = 'login'<%- sc %>

// Determine if environment allows test to mutate existing DB data.
const env = (config.tests || {}).environmentsAllowingSeedData || []<%- sc %>
if (!env.includes(process.env.NODE_ENV) || process.argv.includes('--noclient')) {
  // <%- lintDisableNextLineNoConsole %>
  console.log('SKIPPED - Test <%- serviceFileName -%>/<%- serviceFileName -%>.service<%- stt%>.test.<%- js -%>')<%- sc %>
<%- tplTsOnly('  // @ts-ignore') %>
  return<%- sc %>
}

// Get generated fake data
// <%- lintDisableNextLineUnused %>
const fakeData = readJsonFileSync(join(__dirname, '<%- pathTestToApp -%>seeds/fake-data.json')) || {}<%- sc %>

describe('Test <%- serviceFileName -%>/<%- serviceFileName -%>.service<%- stt %>.test.<%- js -%>', () => {
  let app<%- sc %>
  let client<%- tplTsOnly(': any') -%><%- sc %>
  let server<%- tplTsOnly(': Server') -%><%- sc %>

  before(async function () {
    this.timeout(timeoutForStartingServerAndClient)<%- sc %>

    // Restarting src/app.*s is required if a previous server make a service call
    // using the REST transport and we want to make one using a WebSocket transport.
    delete require.cache[require.resolve('<%- pathTestToApp %><%- specs.app.src -%>/app')]<%- sc %>
    app = require('<%- pathTestToApp %><%- specs.app.src %>/app')<%- sc %>

    const host = app.get('host')<%- sc %>
    const port = app.get('port')<%- sc %>

    const result = await app.service('<%- servicePath -%>').find({ query: { email }})<%- sc %>
    if ((<%- tplJsOrTs('result', '(result as any)') %>.data || result).length === 0) {
      await app.service('<%- servicePath -%>').create({ email, password })<%- sc %>
    }

    server = app.listen(port)<%- sc %>
    return await new Promise(resolve => {
      server.once('listening', () => {
        setTimeout(async () => {
          client = await makeClient(host, port, email, password)<%- sc %>
          resolve()<%- sc %>
        }, delayAfterServerOnce)<%- sc %>
      })<%- sc %>
    })<%- sc %>
  })<%- sc %>

  beforeEach(async () => {
    await app.service('<%- servicePath -%>').remove(null)<%- sc %>
  })<%- sc %>

  after(function (done) {
    this.timeout(timeoutForClosingingServerAndClient)<%- sc %>
    client.logout()<%- sc %>
    server.close()<%- sc %>
    setTimeout(() => done(), delayAfterServerClose)<%- sc %>
  })<%- sc %>

  it('registered the service', () => {
    const service = client.service('<%- servicePath -%>')<%- sc %>

    assert.ok(service, 'Registered the service')<%- sc %>
  })<%- sc %>

  it('???', async () => {
    // Setting `provider` indicates an external request
    // <%- lintDisableNextLineUnused %>
    const params = { provider: 'socketio' }<%- sc %>
    assert(true)<%- sc %>

    /*
    const record = await client.service('<%- servicePath -%>').create({

    }, params)<%- sc %>

    assert.deepEqual(record, {

    })<%- sc %>
    */
  })<%- sc %>
})<%- sc %>

async function makeClient(host<%- tplTsOnly(': string') -%>, port<%- tplTsOnly(': number') -%>, email1<%- tplTsOnly(': string') -%>, password1<%- tplTsOnly(': string') -%>) {
  const client = feathersClient()<%- sc %>
  const socket = io(`http://${host}:${port}`, {
    transports: ['websocket'], forceNew: true, reconnection: false, extraHeaders: {}
  })<%- sc %>
  client.configure(feathersClient.socketio(socket))<%- sc %>
  client.configure(feathersClient.authentication({
    storage: localStorage
  }))<%- sc %>

  try {
    await client.authenticate({
      strategy: 'local',
      email: email1,
      password: password1,
    })<%- sc %>
  } catch (err) {
    throw new Error(`Unable to authenticate: ${err.message}`)<%- sc %>
  }

  return client<%- sc %>
}
