GithubHelp home page GithubHelp logo

mocks-server / core Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 3.0 6.84 MB

Mocks Server core. For programmatic usage only.

Home Page: https://www.mocks-server.org

api api-rest api-server express middlewares mock mocks-server nodejs programmatic routes

core's People

Contributors

greenkeeper[bot] avatar javierbrea avatar methadata avatar renovate-bot avatar renovate[bot] avatar

Stargazers

 avatar

Watchers

 avatar  avatar

core's Issues

New format for defining fixtures and behaviors

Currently there is a "pain point" when defining fixtures: All fixtures responding to the same request have to redefined its url, and there is no a clear mechanism to identify how many of them correspond to a single url. You can know the total amount of fixtures you have defined (in the CLI, for example), but you can't know how many single routes are you listening to.

As a proposal, fixtures should be renamed into routes, which I consider can be clearer, and should have a variants property, which should contain all possible responses for the same url, as in:

{
  "id":"get-users",
  "url":"/api/users",
  "method":"GET",
  "variants":[
    {
      "id":"empty",
      "response":{
        "status":200,
        "body":[
          
        ]
      }
    },
    {
      "id":"error",
      "response":{
        "status":500,
        "body":{
          "message":"Internal server error"
        }
      }
    }
  ]
}

Then, behaviors (which could be renamed into mocks for more clarity), should be defined as in:

[
  {
    "id": "base",
    "routes": ["get-users:success"]
  },
  {
    "id": "users-error",
    "from": "base",
    "routes": ["get-users:error"]
  }
]

Routes and variants could also include a handler property which should decide the routesHandler to use when loading it, as in:

{
  "id":"get-users",
  "url":"/api/users",
  "method":"GET",
  "variants":[
    {
      "id":"empty",
      "response":{
        "status":200,
        "body":[]
      }
    },
    {
      "id":"real",
      "handler": "proxy",
      "redirect": "http://localhost:8080/users"
    }
  ]
}

Dependency Dashboard

This issue provides visibility into Renovate updates and their statuses. Learn more

Rate Limited

These updates are currently rate limited. Click on a checkbox below to force their creation now.

  • chore(deps): update dependency prettier to v2.6.1
  • chore(deps): update dependency eslint to v8.12.0
  • fix(deps): update dependency ajv to v8.11.0
  • fix(deps): update dependency winston to v3.6.0
  • chore(deps): update actions/cache action to v3
  • chore(deps): update actions/checkout action to v3
  • chore(deps): update actions/download-artifact action to v3
  • chore(deps): update actions/setup-node action to v3
  • chore(deps): update actions/upload-artifact action to v3
  • fix(deps): update dependency commander to v9

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.


  • Check this box to trigger a request for Renovate to run again on this repository

Stricter folders and files structure

Currently mocks-server supports autodetection of fixtures and behaviors inside all subfolders and files in the mocks folder. This may produce errors and undesirable effects, and it is a kind of "magic". It also require fixture handlers to implement a mechanism to detect fixtures which should handle, etc.

In order to promote best practices, avoid package complexity and possible bugs, it is desirable to add an option for defining the folder from which the fixtures will be loaded, and the folder or file from which the behaviors will be loaded (probably a single file better). Fixtures should also include an identifier about the fixture handler to be used to load it, so handlers should not provide a function to let the mocks-server know it an object is desired to be handled by one or another.

Configuration through "mocks-server.config.js" file

It is desirable to allow configuring the server through a mocks-server.config.js file created at the root of the project. It could contain the core options (as plugins to be loaded) and all other main options, including plugin options.

The file could contain something like:

//mocks-server.config.js
const AwesomePlugin = require("mocks-server-plugin-awesome-feature");

module.exports = {
  plugins: [AwesomePlugin],
  options: {
    delay: 1000,
    path: "custom-mocks-folder",
    behavior: "default-behavior"
  }
};

Note that the "main" distribution also contains his own plugins definitions, so maybe a function could be provided too in order to allow extending already existent configuration:

//mocks-server.config.js
const AwesomePlugin = require("mocks-server-plugin-awesome-feature");

module.exports = config => {
  config.plugins.push(AwesomePlugin);
  config.options.delay = 1000;
  return config;
};

Maybe it could be also defined as a "json" or "yaml" file, but then a mechanism to define plugins should be provided. Maybe defining the plugin package name could be a good choice:

{
  "plugins": ["mocks-server-plugin-awesome-feature"],
  "options": {
      "delay": 1000,
      "path": "custom-mocks-folder",
      "behavior": "default-behavior"
   }
}

Negative options format

Negative options, such as cli=false, should have the commander recommended format, as --no-cli.

  • watch=false : --no-watch
  • cli=false: --no-cli

This format should be added to boolean options which default value is true

Handle Form Post

Still there are APIs out that requires body encoding application/x-www-form-urlencoded (consider mocking OIDC)

expressjs is configured to parse JSON, but not the form encoding
add export
const urlencodedBodyParser = express.urlencoded({ extended: true })
to middleware.js and apply in Server.js to the expressjs server

Describe alternatives you've considered
Not clear how to do that in a safe way through plugin as the expressjs is not exposed

Behaviors class accepting fixtures as multiple arguments

Currently, when defining behaviors, an array has to be provided to the Behavior class. It is desirable to accept multiple arguments too:

const { Behavior } = require("@mocks-server/main");

const { getUsers, getUser } = require("./fixtures/users");

const standard = new Behavior(getUser, getUsers);

module.exports = {
  standard
};

Provide core methods to fixtures express middlewares

It is desirable to provide the core methods to fixtures that defines the response as an "express middleware".

Doing this, it would be possible to change the behavior of the server from a fixture itself, for example:

module.exports = {
  id: "foo-fixture",
  url: "/api/user/:id",
  method: "UPDATE",
  response: (req, res, next, core) => {
     core.settings.set("behavior", "user-updated");
     res.status(204);
     res.send();
  }
};

Add "path" option

Currently, the option for defining the path from which read the behaviors is called "behaviors". Maybe it is a little confusing, because there is another option called "behavior" which defines the default one.
It is desirable to add a new option called "path", maintaining also the old one due to compatibility reasons (a deprecation warning should be printed in that case).

Default mocks folder

It is desirable to define a default "behaviors" folder. The Mocks Server should search by default issues and behaviors at the "/mocks" folder in the project, and create it if it doesn't exist (only when "--behaviors" option is not defined).

Delay option to fixtures

It is desirable to allow to define a delay option in fixtures to allow only some fixtures to be delayed without the need of changing the global delay setting.

File names conflict

When there are two files with the same name but different extension in the mocks folder, only definitions of one of them are loaded.

For example, if you create a file named behaviors.json and another one called behaviors.js, the definitions of the .json file are ignored.

Typescript support

Is your feature request related to a problem? Please describe.
We have a bunch of mocks as .ts files for other tests and would like use them for mocks-server.

Describe the solution you'd like
Provide a way to configure node to use typescript.

Support array of methods in route variants

It is desirable to support an array of methods in the route variants definitions. It makes sense for defining middlewares that should be executed in every method, as described in mocks-server/main#140.

Using the middleware example from the documentation, this is how it should look like:

module.exports = [
  {
    id: "add-headers",
    url: "*",
    method: ["GET", "POST", "PUT", "DELETE"],
    variants: [
      {
        id: "enabled",
        response: (req, res, next) => {
          res.set('Content-Type', 'application/json; charset=utf-8');
          next();
        }
      },
      {
        id: "disabled",
        response: (req, res, next) => next()
      }
    ]
  }  
];

Automatically create default behavior

Supposing that the issue mocks-server/main#16 is implemented, the usability for new users would improve if the Mocks Server created automatically a default behavior with all fixtures found in the folder.

In case there were more than one fixture for the same url, a "default" property could be added to fixtures, indicating whether it should be used by default or not.

For creating more behaviors extending the default one, a new extendDefaultBehavior method could be exposed in the library:

Following the example shown in mocks-server/main#16

const { extendDefaultBehavior } = require("@mocks-server/main");

const getUserError = extendDefaultBehavior(["fixtures/getUserError"]);

module.exports = {
  getUserError
};

Accept single export in behaviors files

Currently behaviors files has to export an object containing the behaviors definitions.
It is desirable to accept also a single export. In that case, the name given to the behavior should be the file name, as it is suggested to do with fixtures in the mocks-server/main#6 issue.

In case mocks-server/main#6 is implemented, the same concept described above should be applied to fixtures defined in .js files with a single export.

Create fixtures from "json" files

It should be great if it would be possible to create fixtures simply adding a "json" or "yaml" containing the fixture properties. The mocks server should search for any file of this type in the "mocks" folder, and automatically create the fixture, assigning to it a name based on the file name, or full file path from the "behaviors" root path.

For assigning the fixture to a behavior, the assigned "name" as "string" should be used.

For example:

Given a files structure:

|-- mocks
|   |-- behaviors.js
|   |-- fixtures
|   |   |-- getUser.yaml
|   |   |-- getUsers.json
|   |   |-- getUserError.json

The user could create a behavior like:

//mocks/behaviors.js

const { Behavior } = require("@mocks-server/main");

const standard = new Behavior(["fixtures/getUser", "fixtures/getUsers"]);

module.exports = {
  standard
};

Improve traces handling

It is desirable to "save" traces and provide an interface to recover them. Currently, the "mocks-server-cli" plugin is hidding the traces when it loads, because it clean the CLI screen, so errors and other traces are lost. If the core provides such traces interface, the plugin could display error traces in the top, or it could display a new option for displaying all previous traces, which would improve the user experience.

FilesLoader error shouldn't be masked

Is your feature request related to a problem? Please describe.
Errors like file imports or other stuff are masked because the exception is not passed to the logger.

Describe the solution you'd like
Change this line

this._tracer.error(`Error loading files from folder ${this._path}`);

By this one:
this._tracer.error(``Error loading files from folder ${this._path} with error: ${error.message}``);

Add option for adding middlewares

It is desirable to add the possibility of adding middlewares to the mocks-server. Two methods should be implemented: appendMiddleware and prependMiddleware in order to add them before or after the fixtures middlewares.

Middlewares should be standard express middlewares, but receiving also the mocks-server core object allowing to use its methods.

It is also desirable to allow adding middlewares using the configuration file, for example:

module.exports = {
  addPlugins: [FooPlugin],
  options: {
    port: 3200,
  },
  middlewares: {
    prepend: [(req, res, next, mocksServer) => {
      mocksServer.tracer.info("Request received");
      next();
    }],
   append: [(req, res, next, mocksServer) => {
      mocksServer.tracer.info("Request finished");
      next();
    }]
  }
};

Support method OPTIONS for routes

The API I would like to mock, uses OPTIONS requests. When I try to use this in a route, I get an error

{
  "id": "options-a",
  "url": "/api/v1/a",
  "method": "OPTIONS",
  "variants": [
    {
      "id": "default",
      "response": {"status": 200, "body": true}
    }
  ]
}

The error I see in the sever log

this._router[METHODS[routeVariant.method]] is not a function

However, when I set the method to GET or POST everything seems to work fine.

I have also noticed that the server tries to respond to CORS preflight requests and this seems to be the reason for this problem. When I try to extend the constant METHODS in Mock.js with a line for OPTIONS, there is no error, but the response from the server contains

access-control-allow-origin: *
access-control-allow-methods: GET,HEAD,PUT,PATCH,POST,DELETE

Although, I never included these headers in the request

If there is no easy way to implement this, is there a possible workaround?

Control over headers

Currently fixtures have no control over request or response headers.

It is desirable to define request headers to make the fixture handle the request or not depending if they match, and to define response headers.

To build headers matchers, json schema could be used, as:

[
  {
    "id": "get-user",
    "url": "/api/users/:id",
    "method": "GET",
    "headers": {
      "authentication":  {
        "type": "string",
        "pattern": "^Bearer:.*"
       }
    },
    "response": {
      "status": 200,
      "body": {
        "id": 1,
        "name": "John Doe"
      },
      "headers": {
        "location": "/api/users/2"
      }
    }
  },
  {
    "id": "get-user",
    "url": "/api/users/:id",
    "method": "GET",
    "headers": {
      "authentication":  {
        "type": "null"
       }
    },
    "response": {
      "status": 401,
      "body": {
        "message": "Unauthorized"
      },
      "headers": {
        "WWW-Authenticate": "Bearer realm=\"example\""
      }
    }
  }
]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.