npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

test-fake-server

v2.9.3

Published

simple way to create node http server

Downloads

510

Readme

Usage

  • Build simple fake server with routing, params, static content
  • GET, POST, PUT, DELETE, supported methods, status, bodies etc

npm downloads

Install

npm install -SD test-fake-server || npm i -g test-fake-server

Example

base usage example

const fakeServer = require('test-fake-server')
const model = {
  port: 9090,
  api: [{
    method: "GET",
    path: "/",
    response: "Hello world"
  }]
}
fakeServer(model).then((server) => {
  setTimeout(() => {
    server.stop()
  }, 25000)
})
// open browser
// url 'http://localhost:9090/

mocha test example

const fakeServer = require('test-fake-server')
const fetch = require('node-fetch')
const {expect} = require('chai')

const model = {
  "port": 8888,
  "api": [
    {
      "method": "GET",
      "path": "/user",
      "response": {
        "user_name": "test user"
      }
    },
    {
      "method": "POST",
      "path": "/user",
      "response": {"created": true}
    }
  ]
}

describe('Example', () => {
  let server = null
  beforeEach(async () => {
    server = await fakeServer(model)
  })
  after(async () => {
    await server.stop()
  })
  it('test post user', async function() {
    const responseBody = await fetch('http://localhost:8888/user', {method: 'POST'}).then((res) => res.json())
    expect(responseBody.created).to.eql(true)
  })
  it('test get user', async function ()  {
    const responseBody = await fetch('http://localhost:8888/user').then((res) => res.json())
    expect(responseBody.user_name).to.eql('test user')
  })
})

Example from command line

./test.json

{
  "port": 8081,
  "host": "0.0.0.0",
  "api": [
    {
      "method": "GET",
      "path": "/example",
      "response": {
        "example": "example GET"
      }
    }
  ]
}
test-fake-server -m ./test.json

More examples

Model Structure

Endpoint Model Object

const APIModelObject =   {
  "method": "GET",                    // required field, http methods: GET, POST, PUT, DELETE
  "path": "/example/:param1/:param2", // required field, params can be presented here
  "status": 200,                      // status in option field, default is 200

   "authorization":{                  // if full server model inludes authorization property, this will take part
                                      // in our endpoint response
    "unauthorized": {                 // this property will be used as body for respose if request does not have credentials,
                                      // unauthorized is optional, default is {unauthorized: 'unauthorized'}
      "foo": "bar"
    },                                // status what will be used, it is optional, default is 401
    "status": 401,                    //
    "token":"testToken"               //
  },

  "params_response": {                // params_response is optional, it required if you want to work with
    "response": {                     // properties of this object shoulb be equal params declaration in url
        "allParamsAreEqual": {        // for example our path is "/example/:param1/:param2"
          "param1": "success",        // params_response object includes properties : param1 and param2
          "param2": "success"         // object param should have propertie "value" what will uses as a assertion
        }                             // for example  curl http://localhost:8888/example/testFirst/someItemWhatNotExists
    },                                // response will be from param1 object - { "testId": "testFirst" }
    "param1": {                       // if all params value equal our request url params we will get general response
      "status": 201,                  // in case if custom status code is required put it in param object
      "value": "testFirst",           // from params_response object or it it is not exists
      "response": {                   // responses from params objects will be merged
          "testId": "testFirst"
    },
    "param2": [{                      // in case if response should depends on request param you can use array
      "value": "testSecondSuccess",   // if /example/some/testSecondSuccess response will be next and status code 200
      "status": 200,
      "response": {
          "testId": "testSecond"
      }
    },
    {
      "value": "testSecondFailed",   //  if /example/some/testSecondFailed response will be "Not found" and status code 401
      "status": 401
      "response": "Not found"
    }]
  },
  "request_body_equal": {             // this property will work with PUT, POST, DELETE, PATCH only
    "allow_partial_request_body": true, // allow send not all keys and get success response
    "status": 404,
    "not_equal_response": {         // this field is optional, default is {"data": "invalid request"}
       "success": false
    },
    "expected_body": {              // request body should equal expected_body property
      "username": "test",
      "password": "test_pass"
    }
  },
  "response": {                       // response is option field, default is {ok: 'OK'}
    "example": "example GET"
  },
}

HTTP methods

const fakeServer = require('test-fake-server')
const fetch = require('node-fetch')
const model =
{
  "port": 8081,
  "api": [
    {
      "method": "GET",
      "path": "/example",
      "response": {
        "example": "example GET"
      }
    },
    {
      "method": "POST",
      "path": "/example",
      "response": {
        "example": "example POST"
      }
    },
    {
      "method": "DELETE",
      "path": "/example",
      "response": {
        "example": "example DELETE"
      }
    },
    {
      "method": "PUT",
      "path": "/example",
      "response": {
        "example": "example PUT"
      }
    }
  ]
}


async function callToServer() {
  const server = await fakeServer(model)
  const postData = await fetch('http://localhost:8888/example', {method: 'POST'}).then((res) => res.json())
  // {example: "example POST"}
  const getData = await fetch('http://localhost:8888/example', {method: 'GET'}).then((res) => res.json())
  // {example: "example GET"}
  const putData = await fetch('http://localhost:8888/example', {method: 'PUT'}).then((res) => res.json())
  // {example: "example PUT"}
  const deleteData = await fetch('http://localhost:8888/example', {method: 'DELETE'}).then((res) => res.json())
  // {example: "example DELETE"}
}

Authorization

const fakeServer = require('test-fake-server')
const fetch = require('node-fetch')

const authorizationInApiObj = {
        "unauthorized": {   // this property will be used as body for respose
          "foo": "bar"      //
        },                  //
        "status": 401,      // this property will be used as unsuccess status if token is not equal
        "token":"testToken" // to this toke property value
      }

const model = {
  "port": 8081,
  "authorization": {"type": "headers"},
  "api": [
    {
      "method": "GET",
      "path": "/example",
      "response": {"example": "example GET"},
      // default properties are
      // unauthorized : {unauthorized: 'unauthorized'}
      // status : 401
      "authorization": authorizationInApiObj
    }
  ]
}

async function callToServerHeaderAuthorization() {
  const server = await fakeServer(model)
  const withoutTokenData = await fetch('http://localhost:8888/example', {method: 'GET'}).then((res) => res.json())
  // {foo: "bar"}
  const withTokenData = await fetch('http://localhost:8888/example', {
    headers: {Authorization: 'Bearer testToken'},
    method: 'GET'}).then((res) => res.json())
  // {example: "example GET"}
}
callToServerHeaderAuthorization()

Params

const fakeServer = require('test-fake-server')
const fetch = require('node-fetch')

const model = {
  "port": "8081",
  "api": [{
    "method": "GET",
    // after : name of param shoulb be used in params_response object
    // lets check :user
    "path": "/user/:user/id/:id",

    "params_response": {
      "id": {
        "value": "testId",
        "response": {
          "testId": "testId"
        }
      },
      // user
      // if user will contain /user/testUser/id/:id
      // we will get next response from user object
      "user": {
        "value": "testUser",
        "response": {
          "user": "testId"
        }
      },

      // if we have full uquals between params
      // we will get general response - response property from params_response object
      // in this case we heed
      // http://localhost:8081/user/testUser/id/testId
      "response": {
        "full_params_equal": {
          "username": "test user1",
          "password": "test password"
        }
      }
    },
    // this response will be used in other cases
    // as example http://localhost:8081/user/unknown/id/unknown
    "response": {
      "example": "example GET"
    }
  }]
}
async function callToServer() {
  const server = await fakeServer(model)
  const defaultGetData = await fetch('http://localhost:8081/user/unknown/id/unknown', {method: 'GET'}).then((res) => res.text())
  // {"example": "example GET"}
  console.log(defaultGetData)

  const fullPramsEqual = await fetch('http://localhost:8081/user/testUser/id/testId', {method: 'GET'}).then((res) => res.text())
  // {"full_params_equal": {
  //   "username": "test user1",
  //   "password": "test password"
  // }}
  console.log(fullPramsEqual)

  const userEqualParamEqual = await fetch('http://localhost:8081/user/testUser/id/unknown', {method: 'GET'}).then((res) => res.text())
  // {"user": "testId"}
  console.log(userEqualParamEqual)

  const idEqualParamEqual = await fetch('http://localhost:8081/user/unknown/id/testId', {method: 'GET'}).then((res) => res.text())
  // {"testId": "testId"}
  console.log(idEqualParamEqual)
}

callToServer()

Queries

const fakeServer = require('../')
const fetch = require('node-fetch')

const model_obj = {
  "port": "8081",
  "api": [{
    "method": "GET",
    "path": "/test",
    "response": {
      "testOne": 1,
      "testTwo": 2,
      "testThree": 3,
      "testFour": 4,
    }
  }]
}

const model_array = {
  "port": "8082",
  "api": [{
    "method": "GET",
    "path": "/test",
    "response": [
      {
        "testOne": 1,
        "testTwo": 2,
        "testThree": 3,
        "testFour": 4,
      },
      {
        "testOne": 1,
        "testTwo": 2,
        "testThree": 3,
        "testFour": 4,
      },
      {
        "testOne": 1,
        "testTwo": 2,
        "testThree": 3,
        "testFour": 4,
      }
    ]
  }]
}

async function callToServer() {

  server_obj = await  fakeServer(model_obj)
  server_array = await fakeServer(model_array)

  const query_resp_obj = await fetch('http://localhost:8081/test?testOne=1&testTwo=2', {method: 'GET'}).then((res) => res.text())
  // {"testOne":1,"testTwo":2}
  console.log(query_resp_obj)

  const query_resp_array = await fetch('http://localhost:8082/test?testOne=1&testTwo=2', {method: 'GET'}).then((res) => res.text())
  // [{"testOne":1,"testTwo":2},{"testOne":1,"testTwo":2},{"testOne":1,"testTwo":2}]
  console.log(query_resp_array)
  await server_obj.stop()
  await server_array.stop()
}

HTML

const fakeServer = require('test-fake-server')
const fetch = require('node-fetch')
const path = require('path')

const indexHtml = path.resolve(__dirname, './index.html')
const model = {
  "port": "8081",
  "api": [{
    "method": "GET",
    "path": "/",
    "response": indexHtml
  }]
}
async function callToServer() {
  const server = await fakeServer(model)
const indexHtmlText = await fetch('http://localhost:8081/', {method: 'GET'}).then((res) => res.text())
  // <html lang="en">
  //   <head>
  //     <meta charset="UTF-8">
  //     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  //     <meta http-equiv="X-UA-Compatible" content="ie=edge">
  //     <title>Document</title>
  //   </head>
  //   <body>
  //     TEST FAKE SERVER
  //     <div>A</div>
  //     <div>B</div>
  //     <div>C</div>
  //     <div>D</div>
  //     <div>E</div>
  //   </body>
  //   </html>
  console.log(indexHtmlText)
  await server.stop()
}

Request body assertion

const fakeServer = require('test-fake-server')
const fetch = require('node-fetch')

// full equalty check
async function callToServer() {
  const model_obj = {
  "port": "8081",
  "debug": true, // if this prop exists log will show all results in console, defailt is false
  "api": [{
    "method": "POST",
    "path": "/test",
    "request_body_equal": {
      "status": 404,
      "not_equal_response": { // this field is optional, default is {"data": "invalid request"}
         "success": false
      },
      "expected_body": {
        "username": "test_",
        "password": "test_pass"
      }
    },
    "response": {
      "success": true
    }
    }]
  }

  const serser = await fakeServer(model_obj)

  const body_equal_success = await fetch('http://localhost:8081/test', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({"username": "test_", "password": "test_pass"})
  }).then((res) => res.text())
  // {"success":true}
  console.log(body_equal_success)

  const body_not_equal = await fetch('http://localhost:8081/test', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({
      "username": "test_1",
      "password": "test_pass"
    })
  }).then((res) => res.text())
  // {"success": false}
  console.log(body_not_equal)
  await serser.stop()
}

async function callToServerPartialRequest() {
  const model_obj = {
    "port": "8081",
    "debug": true, // if this prop exists log will show all results in console, defailt is false
    "api": [{
      "method": "POST",
      "path": "/user",
      "request_body_equal": {
        "status": 404,
        "not_equal_response": { // this field is optional, default is {"data": "invalid request"}
          "success": false
        },
        "allow_partial_request_body": true,
        "expected_body": {
          "username": "test_",
          "password": "test_pass"
        }
      },
      "response": {
        "success": true
      }
    }]
  }

  const serser = await fakeServer(model_obj)

  const body_equal_success = await fetch('http://localhost:8081/test', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({"username": "test_",}) // partial body matches
  }).then((res) => res.text())
  // {"success":true}
  console.log(body_equal_success)

  const body_not_equal = await fetch('http://localhost:8081/test', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({
      "username": "test_1",
      "password": "test_pass"
    })
  }).then((res) => res.text())
  // {"success": false}
  console.log(body_not_equal)
  await serser.stop()
}

async function callToServerPartialExpected() {
  const model_obj = {
    "port": "8081",
    "debug": true, // if this prop exists log will show all results in console, defailt is false
    "api": [{
      "method": "POST",
      "path": "/user",
      "request_body_equal": {
        "status": 404,
        "not_equal_response": { // this field is optional, default is {"data": "invalid request"}
          "success": false
        },
        "allow_partial_expected_body": true,
        "expected_body": {
          "username": "test_",
          "password": "test_pass"
        }
      },
      "response": {
        "success": true
      }
    }]
  }

  const serser = await fakeServer(model_obj)

  const body_equal_success = await fetch('http://localhost:8081/test', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({"username": "test_", "password": "test_pass", "x": 2, "Y": 2}) // more that required keys are in request body
  }).then((res) => res.text())
  // {"success":true}
  console.log(body_equal_success)

  const body_not_equal = await fetch('http://localhost:8081/test', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({
      "username": "test_1",
      "password": "test_pass"
    })
  }).then((res) => res.text())
  // {"success": false}
  console.log(body_not_equal)
  await serser.stop()
}

Several server nodes in one environment

const fakeServer = require('test-fake-server')
const fetch = require('node-fetch')

const model_entry_point = {
  "port": 8081,
  "api": [
    {
      "method": "GET",
      "path": "/user",

      "response_from_url": { // if this property exists this endpoint will try to use it as main
        "status": 201, // response status
        "method": "GET", // method what will use for request for other HTTP service
        "url": "http://localhost:8888/userData",  // URL to other service endpoint
        "merge_with": { // if this property exists response from URL will merged with this property value
                        // for example from http://localhost:8888/userData we will get {user: "exists"}
                        // after merge with this property value {user: "exists", part_from_entrypoint: "entry point"}
                        // so after request to http://localhost:8081/user
                        // we will get {user: "exists", part_from_entrypoint: "entry point"}
          "part_from_entrypoint": "entry point"
        }
      }
    }
  ]
}

const model_user = {
  "port": 8888,
  "api": [
    {
      "method": "GET",
      "path": "/userData",
      "response": {
        "part_from_user_service": {
          "user_profile": {
            "username": "some username",
            "postal_code": 3212654
          }
        }
      }
    }
  ]
}



async function callToServer() {
  const entry = await fakeServer(model_entry_point)
  const userSerice = await fakeServer(model_user)
  const getData = await fetch('http://localhost:8081/user',
    {method: 'GET'}).then((res) => res.json())
  // {
  // part_from_user_service:
  //   { user_profile: { username: 'some username', postal_code: 3212654 } },
  //  part_from_entrypoint: 'entry point'
  //  }
  console.log(getData)
 await entry.stop()
  await userSerice.stop()
}