import { describe, it } from 'vitest'
import assert from 'assert'
import { HookContext } from '../index.js'
import * as http from './utils.js'

describe('@feathersjs/transport-commons HTTP helpers', () => {
  it('getResponse body', () => {
    const plainData = { message: 'hi' }
    const dispatch = { message: 'from dispatch' }
    const resultContext = {
      result: plainData
    }
    const dispatchContext = {
      dispatch
    }

    assert.strictEqual(http.getResponse(resultContext as HookContext).body, plainData)
    assert.strictEqual(http.getResponse(dispatchContext as HookContext).body, dispatch)
  })

  it('getResponse status', () => {
    const statusContext = {
      http: { status: 202 }
    }
    const createContext = {
      method: 'create',
      result: {}
    }
    const createEmptyContext = {
      method: 'create'
    }
    const redirectContext = {
      http: { location: '/' }
    }
    const redirectCreateContext = {
      method: 'create',
      http: { location: '/' }
    }

    assert.strictEqual(http.getResponse(statusContext as HookContext).status, 202)
    assert.strictEqual(http.getResponse(createContext as HookContext).status, http.statusCodes.created)
    assert.strictEqual(http.getResponse(redirectContext as HookContext).status, http.statusCodes.seeOther)
    assert.strictEqual(
      http.getResponse(redirectCreateContext as HookContext).status,
      http.statusCodes.seeOther
    )
    assert.strictEqual(http.getResponse({} as HookContext).status, http.statusCodes.noContent)
    assert.strictEqual(http.getResponse(createEmptyContext as HookContext).status, http.statusCodes.noContent)
    assert.strictEqual(http.getResponse({ result: true } as HookContext).status, http.statusCodes.success)
  })

  it('getResponse headers', () => {
    const headers = { key: 'value' } as any
    const headersContext = {
      http: { headers }
    }
    const locationContext = {
      http: { location: '/' }
    }

    assert.deepStrictEqual(http.getResponse({} as HookContext).headers, {})
    assert.deepStrictEqual(http.getResponse({ http: {} } as HookContext).headers, {})
    assert.strictEqual(http.getResponse(headersContext as HookContext).headers, headers)
    assert.deepStrictEqual(http.getResponse(locationContext as HookContext).headers, {
      Location: '/'
    })

    assert.deepStrictEqual(
      http.getResponse({
        http: {
          location:
            'https://github.com/login/oauth/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A8787%2Foauth%2Fgithub%2Fcallback'
        }
      } as HookContext).headers,
      {
        Location:
          'https://github.com/login/oauth/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A8787%2Foauth%2Fgithub%2Fcallback'
      }
    )
  })

  it('getServiceMethod', () => {
    assert.strictEqual(http.getServiceMethod('GET', 2), 'get')
    assert.strictEqual(http.getServiceMethod('GET', null), 'find')
    assert.strictEqual(http.getServiceMethod('PoST', null), 'create')
    assert.strictEqual(http.getServiceMethod('PoST', null, 'customMethod'), 'customMethod')
    assert.strictEqual(http.getServiceMethod('delete', null), 'remove')
    assert.throws(() => http.getServiceMethod('nonsense', null))
  })
})
