Routes
diff --git a/mocks/admin-api-client-data-provider-e2e-vanilla-app/public/main.js b/mocks/admin-api-client-data-provider-e2e-vanilla-app/public/main.js
index 9d30eaa78..94ccfdca9 100644
--- a/mocks/admin-api-client-data-provider-e2e-vanilla-app/public/main.js
+++ b/mocks/admin-api-client-data-provider-e2e-vanilla-app/public/main.js
@@ -2,23 +2,23 @@ var $ = window.$;
var adminApiClient = window.mocksServerAdminApiClientDataProvider;
var dataProvider = window.dataProvider;
-var $mocksContainer;
+var $collectionsContainer;
var $routesContainer;
var $aboutContainer;
-var $settingsContainer;
-var $currentMockNameContainer;
-var $currentMockContainer;
-var $currentRouteVariantIdContainer;
-var $currentRouteVariantContainer;
-var $setMockBaseButton;
-var $setMockUser2Button;
+var $configContainer;
+var $currentCollectionNameContainer;
+var $currentCollectionContainer;
+var $currentVariantIdContainer;
+var $currentVariantContainer;
+var $setCollectionBaseButton;
+var $setCollectionUser2Button;
var $alertsContainer;
-var currentMock = new dataProvider.Selector(
- adminApiClient.settings,
- adminApiClient.mocks,
- function (_query, settingsResults, mocksResults) {
- return adminApiClient.mocksModel.queries.byId(settingsResults.mocks.selected || mocksResults[0].id);
+var currentCollection = new dataProvider.Selector(
+ adminApiClient.config,
+ adminApiClient.collections,
+ function (_query, configResults, collectionsResults) {
+ return adminApiClient.collection.queries.byId(configResults.mock.collections.selected || collectionsResults[0].id);
},
{
initialState: {
@@ -27,10 +27,10 @@ var currentMock = new dataProvider.Selector(
}
);
-var currentRouteVariant = new dataProvider.Selector(
- currentMock,
- function (_query, mockResults) {
- return adminApiClient.routesVariantsModel.queries.byId(mockResults.routesVariants[0]);
+var currentVariant = new dataProvider.Selector(
+ currentCollection,
+ function (_query, collectionResults) {
+ return adminApiClient.variant.queries.byId(collectionResults.definedRoutes[0]);
},
{
initialState: {
@@ -42,42 +42,42 @@ var currentRouteVariant = new dataProvider.Selector(
var loadAbout = function () {
return adminApiClient.about.read().then(function (about) {
$aboutContainer.empty();
- Object.keys(about).forEach(function (key) {
+ Object.keys(about.versions).forEach(function (key) {
$aboutContainer.append(
- `
version : ${about[key]} `
+ `
version : ${about.versions[key]} `
);
});
});
};
-var formatSettings = function(settings) {
- if(typeof settings === "boolean") {
- return settings.toString();
+var formatConfig = function(config) {
+ if(typeof config === "boolean") {
+ return config.toString();
}
- if(typeof settings === "object") {
- return JSON.stringify(settings);
+ if(typeof config === "object") {
+ return JSON.stringify(config);
}
- return settings;
+ return config;
}
-var loadSettings = function () {
- return adminApiClient.settings.read().then(function (settings) {
- $settingsContainer.empty();
- Object.keys(settings).forEach(function (key) {
- $settingsContainer.append(
- `
${key} : ${formatSettings(settings[key])} `
+var loadConfig = function () {
+ return adminApiClient.config.read().then(function (config) {
+ $configContainer.empty();
+ Object.keys(config).forEach(function (key) {
+ $configContainer.append(
+ `
${key} : ${formatConfig(config[key])} `
);
});
});
};
-var loadMocks = function () {
- return adminApiClient.mocks.read().then(function (mocksCollection) {
- $mocksContainer.empty();
- mocksCollection.forEach(function (mock) {
- $mocksContainer.append(
- `
${JSON.stringify(
- mock
+var loadCollections = function () {
+ return adminApiClient.collections.read().then(function (collectionsCollection) {
+ $collectionsContainer.empty();
+ collectionsCollection.forEach(function (collection) {
+ $collectionsContainer.append(
+ ` ${JSON.stringify(
+ collection
)} `
);
});
@@ -110,63 +110,67 @@ var loadAlerts = function () {
});
};
-var loadCurrentMock = function () {
- return currentMock.read().then(function (currentMockResult) {
- $currentMockNameContainer.text(currentMockResult.id);
- $currentMockContainer.text(JSON.stringify(currentMockResult));
+var loadCurrentCollection = function () {
+ return currentCollection.read().then(function (currentCollectionResult) {
+ $currentCollectionNameContainer.text(currentCollectionResult.id);
+ $currentCollectionContainer.text(JSON.stringify(currentCollectionResult));
});
};
-var loadCurrentRouteVariant = function () {
- return currentRouteVariant.read().then(function (currentRouteVariantResult) {
- $currentRouteVariantIdContainer.text(currentRouteVariantResult.id);
- $currentRouteVariantContainer.text(JSON.stringify(currentRouteVariantResult));
+var loadCurrentVariant = function () {
+ return currentVariant.read().then(function (currentVariantResult) {
+ $currentVariantIdContainer.text(currentVariantResult.id);
+ $currentVariantContainer.text(JSON.stringify(currentVariantResult));
});
};
$.when($.ready).then(function () {
- $mocksContainer = $("#mocks-container");
+ $collectionsContainer = $("#collections-container");
$routesContainer = $("#routes-container");
$alertsContainer = $("#alerts-container");
$aboutContainer = $("#about-container");
- $settingsContainer = $("#settings-container");
- $currentMockNameContainer = $("#current-mock-id");
- $currentMockContainer = $("#current-mock");
- $currentRouteVariantIdContainer = $("#current-route-variant-id");
- $currentRouteVariantContainer = $("#current-route-variant");
- $setMockBaseButton = $("#set-mock-base");
- $setMockUser2Button = $("#set-mock-user2");
-
- $setMockBaseButton.click(function () {
- adminApiClient.settings.update({
- mocks: { selected: "base" },
+ $configContainer = $("#config-container");
+ $currentCollectionNameContainer = $("#current-collection-id");
+ $currentCollectionContainer = $("#current-collection");
+ $currentVariantIdContainer = $("#current-variant-id");
+ $currentVariantContainer = $("#current-variant");
+ $setCollectionBaseButton = $("#set-collection-base");
+ $setCollectionUser2Button = $("#set-collection-user2");
+
+ $setCollectionBaseButton.click(function () {
+ adminApiClient.config.update({
+ mock: {
+ collections: { selected: "base" },
+ }
});
});
- $setMockUser2Button.click(function () {
- adminApiClient.settings.update({
- mocks: { selected: "user2" },
+ $setCollectionUser2Button.click(function () {
+ adminApiClient.config.update({
+ mock: {
+ collections: { selected: "user2" },
+ }
});
});
- adminApiClient.settings.on("cleanCache", function () {
- loadSettings();
+ adminApiClient.config.on("cleanCache", function () {
+ loadConfig();
});
- currentMock.on("cleanCache", function () {
- loadCurrentMock();
+ currentCollection.on("cleanCache", function () {
+ loadCurrentCollection();
});
- currentRouteVariant.on("cleanCache", function () {
- loadCurrentRouteVariant();
+ currentVariant.on("cleanCache", function () {
+ loadCurrentVariant();
});
Promise.all([
- loadMocks(),
+ loadCollections(),
loadRoutes(),
loadAbout(),
- loadSettings(),
- loadCurrentMock(),
- loadCurrentRouteVariant(),
+ loadConfig(),
+ loadCurrentCollection(),
+ loadCurrentVariant(),
loadAlerts(),
]);
});
diff --git a/mocks/admin-api-client-data-provider-e2e-vanilla-app/scripts/copyLibrary.js b/mocks/admin-api-client-data-provider-e2e-vanilla-app/scripts/copyLibrary.js
index ed9d7b85b..c855bb5bd 100644
--- a/mocks/admin-api-client-data-provider-e2e-vanilla-app/scripts/copyLibrary.js
+++ b/mocks/admin-api-client-data-provider-e2e-vanilla-app/scripts/copyLibrary.js
@@ -13,8 +13,22 @@ const libPath = path.resolve(
);
const publicJsPath = path.resolve(__dirname, "..", "public", "js");
+const adminApiPathsLib = path.resolve(
+ __dirname,
+ "..",
+ "..",
+ "..",
+ "packages",
+ "admin-api-paths",
+ "dist",
+ "index.umd.js"
+);
+
const copyLib = () => {
- return fsExtra.copy(libPath, path.resolve(publicJsPath, "admin-api-client.js"));
+ return Promise.all([
+ fsExtra.copy(libPath, path.resolve(publicJsPath, "admin-api-client.js")),
+ fsExtra.copy(adminApiPathsLib, path.resolve(publicJsPath, "admin-api-paths.js")),
+ ]);
};
copyLib();
diff --git a/mocks/admin-api-client-unit-mocks/mocks-with-error/mocks.js b/mocks/admin-api-client-unit-mocks/mocks-with-error/collections.js
similarity index 100%
rename from mocks/admin-api-client-unit-mocks/mocks-with-error/mocks.js
rename to mocks/admin-api-client-unit-mocks/mocks-with-error/collections.js
diff --git a/mocks/admin-api-client-unit-mocks/mocks/mocks.js b/mocks/admin-api-client-unit-mocks/mocks/collections.js
similarity index 50%
rename from mocks/admin-api-client-unit-mocks/mocks/mocks.js
rename to mocks/admin-api-client-unit-mocks/mocks/collections.js
index 49b523b85..6ca6c644c 100644
--- a/mocks/admin-api-client-unit-mocks/mocks/mocks.js
+++ b/mocks/admin-api-client-unit-mocks/mocks/collections.js
@@ -1,10 +1,10 @@
module.exports = [
{
id: "base",
- routesVariants: ["get-user:1"],
+ routes: ["get-user:1"],
},
{
id: "user2",
- routesVariants: ["get-user:2"],
+ routes: ["get-user:2"],
},
];
diff --git a/mocks/admin-api-client-unit-mocks/mocks/routes/users.js b/mocks/admin-api-client-unit-mocks/mocks/routes/users.js
index 78c3ba7f2..b64b15fc5 100644
--- a/mocks/admin-api-client-unit-mocks/mocks/routes/users.js
+++ b/mocks/admin-api-client-unit-mocks/mocks/routes/users.js
@@ -6,16 +6,16 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: [{ email: "foo@foo.com" }],
},
},
{
id: "2",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: [{ email: "foo2@foo2.com" }],
},
diff --git a/package.json b/package.json
index 761818218..89cbcb583 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,7 @@
"@rollup/plugin-babel": "5.3.1",
"@rollup/plugin-commonjs": "21.1.0",
"@rollup/plugin-node-resolve": "13.3.0",
- "@testing-library/cypress": "8.0.2",
+ "@testing-library/cypress": "8.0.3",
"@typescript-eslint/eslint-plugin": "5.26.0",
"@typescript-eslint/parser": "5.27.0",
"babel-jest": "27.5.1",
diff --git a/packages/admin-api-client-data-provider/CHANGELOG.md b/packages/admin-api-client-data-provider/CHANGELOG.md
index 2e583bccd..ebedcaccb 100644
--- a/packages/admin-api-client-data-provider/CHANGELOG.md
+++ b/packages/admin-api-client-data-provider/CHANGELOG.md
@@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Removed
### BREAKING CHANGES
+## [6.0.0] - 2022-07-22
+
+### Changed
+
+- feat: BREAKING CHANGE. Modify methods to adapt them to the new plugin-admin-api@3.2.0 REST API
+
## [5.0.1] - 2022-06-03
### Changed
diff --git a/packages/admin-api-client-data-provider/README.md b/packages/admin-api-client-data-provider/README.md
index ab40d1e7a..d34458fd1 100644
--- a/packages/admin-api-client-data-provider/README.md
+++ b/packages/admin-api-client-data-provider/README.md
@@ -13,9 +13,9 @@
# Mocks-server administration api client built with @data-provider
-This package provides an API client for administrating Mocks Server _(it performs requests to the [Admin API plugin][plugin-admin-api-url] under the hood)_.
+This package provides an API client for administrating Mocks Server through HTTP requests to the [Admin API plugin][plugin-admin-api-url].
-Built using [`data-provider`](https://github.com/data-provider), it can be used in Node.js, browsers, and it is also compatible with other `data-provider` packages, such as [`@data-provider/react`](https://github.com/data-provider/react), so it can be easily integrated with frameworks.
+Built using [`data-provider`](https://github.com/data-provider), it can be used in Node.js, browsers, and it is also compatible with other `data-provider` packages, such as [`@data-provider/react`](https://github.com/data-provider/react), so it can be easily integrated in other ecosystems.
## Installation
@@ -25,23 +25,29 @@ npm i --save redux @data-provider/core @data-provider/axios @mocks-server/admin-
## Usage with promises
-All methods described in the [Api](#api) (expect the `config` method) return Promises when executed:
+All methods described in the [Api](#api) return Promises when executed (except the `configClient` method):
```js
-import { about, settings } from "@mocks-server/admin-api-client-data-provider";
+import { about, config } from "@mocks-server/admin-api-client-data-provider";
const example = async () => {
const { version } = await about.read();
console.log(`Current plugin-admin-api version is ${version}`);
- const currentSettings = await settings.read();
- console.log("Current mocks-server settings are", currentSettings);
-
- await settings.update({
- mock: "user-super-admin",
- delay: 1000
+ const currentConfig = await config.read();
+ console.log("Current mocks-server config is", JSON.stringify(currentConfig));
+
+ await config.update({
+ mock: {
+ collections: {
+ selected: "user-super-admin",
+ },
+ routes: {
+ delay: 1000,
+ },
+ },
});
- console.log("Mock and delay changed");
+ console.log("Collection and delay changed");
};
example();
@@ -49,47 +55,47 @@ example();
## Usage with data-provider
-Exported properties `about`, `settings`, `mocks`, `mocksModel`, `routes`, `routesModel`, `routesVariants` and `routesVariantsModel` are [`@data-provider/axios`](https://github.com/data-provider/axios) providers, so can be used to define @data-provider Selectors. Methods can also be connected to frameworks using another `data-provider` packages, such as [`@data-provider/react`](https://github.com/data-provider/react).
+All exported properties are [`@data-provider/axios`](https://github.com/data-provider/axios) providers, so can be used to define @data-provider Selectors. Methods can also be connected to frameworks using another `data-provider` packages, such as [`@data-provider/react`](https://github.com/data-provider/react).
## Api
-* `about.read()` - Returns info about `mocks-server/plugin-admin-api`, such as current version.
-* `settings.read()` - Returns current `mocks-server` settings.
-* `settings.update(settingsObject)` - Updates `mocks-server` settings. A settings object has to be provided. Read the [`mocks-server` configuration documentation](https://www.mocks-server.org/docs/configuration-options) for further info.
-* `alerts.read()` - Returns collection of current alerts.
-* `alert(id).read()` - Returns a specific alert.
-* `alertsModel.queries.byId(id).read()` - Returns a specific alert.
-* `mocks.read()` - Returns collection of available mocks.
-* `mock(mockId).read()` - Returns a specific mock.
-* `mocksModel.queries.byId(mockId).read()` - Returns a specific mock.
-* `routes.read()` - Returns collection of available routes.
-* `route(id).read()` - Returns a specific route.
-* `routesModel.queries.byId(id).read()` - Returns an specific route.
-* `routesVariants.read()` - Returns collection of available routes variants.
-* `routeVariant(id).read()` - Returns a specific route variant.
-* `routesVariantsModel.queries.byId(id).read()` - Returns an specific route variant.
-* `customRouteVariants.read()` - Returns collection of current custom route variants.
-* `customRouteVariants.create(id)` - Sets a specific route variant to be used by current mock.
-* `customRouteVariants.delete()` - Restore routes variants to those defined in current mock.
+* `about.read()` - Returns info about current version of Mocks Server and plugins.
+* `config.read()` - Returns current Mocks Server config.
+* `config.update(configObject)` - Updates Mocks Server config. A configuration object has to be provided. Read the [Mocks Server configuration documentation](https://www.mocks-server.org/docs/configuration/options) for further info.
+* `alerts.read()` - Returns current alerts.
+* `alert.queries.byId(id).read()` - Returns an alert by ID.
+* `collections.read()` - Returns available collections.
+* `collection.queries.byId(mockId).read()` - Returns a specific mock.
+* `routes.read()` - Returns available routes.
+* `route.queries.byId(id).read()` - Returns a route by id.
+* `variants.read()` - Returns available route variants.
+* `variant.queries.byId(id).read()` - Returns an specific route variant.
+* `customRouteVariants.read()` - Returns current custom route variants.
+* `customRouteVariants.create(id)` - Sets a specific route variant to be used by current collection.
+* `customRouteVariants.delete()` - Restore route variants to those defined in the current collection.
## Configuration
-By default, the client is configured to request to http://localhost:3100/admin, based in the [default options of `mocks-server`](https://www.mocks-server.org/docs/configuration-options)
+By default, the client is configured to request to http://127.0.0.1:3110/api, based in the [default options of Mocks Server admin API plugin](https://www.mocks-server.org/docs/configuration/options)
-You can change both the base url of `mocks-server`, and the base api path of `mocks-server/plugin-admin-api` using the `config` method:
+You can change both the port and the host using the `configClient` method:
```js
-import { config } from "@mocks-server/admin-api-client-data-provider";
+import { configClient } from "@mocks-server/admin-api-client-data-provider";
-config({
- apiPath: "/foo-admin",
- baseUrl: "http://my-mocks-server:3000"
+configClient({
+ port: 3500,
+ host: "localhost"
});
```
+## Release notes
+
+Current major release is compatible only with `@mocks-server/main` versions upper or equal than `3.6`. Use prior releases for lower versions. If you don't want to update to the latest major version of this package yet but you want to update `@mocks-server/main`, you can also use any `5.x` version of this package with any `@mocks-server/main@3.x` version.
+
## Contributing
Contributors are welcome.
Please read the [contributing guidelines](.github/CONTRIBUTING.md) and [code of conduct](.github/CODE_OF_CONDUCT.md).
-[plugin-admin-api-url]: https://github.com/mocks-server/plugin-admin-api
+[plugin-admin-api-url]: https://github.com/mocks-server/main/blob/master/packages/admin-api-client
diff --git a/packages/admin-api-client-data-provider/package.json b/packages/admin-api-client-data-provider/package.json
index eb849a413..a5f22d392 100644
--- a/packages/admin-api-client-data-provider/package.json
+++ b/packages/admin-api-client-data-provider/package.json
@@ -1,6 +1,6 @@
{
"name": "@mocks-server/admin-api-client-data-provider",
- "version": "5.0.1",
+ "version": "6.0.0",
"description": "Client of @mocks-server/plugin-admin-api built with @data-provider",
"keywords": [
"administration",
diff --git a/packages/admin-api-client-data-provider/project.json b/packages/admin-api-client-data-provider/project.json
index b7d277961..fdd85b18a 100644
--- a/packages/admin-api-client-data-provider/project.json
+++ b/packages/admin-api-client-data-provider/project.json
@@ -1,5 +1,6 @@
{
"root": "packages/admin-api-client-data-provider/",
"projectType": "library",
+ "implicitDependencies": ["admin-api-paths"],
"tags": ["type:lib"]
}
diff --git a/packages/admin-api-client-data-provider/sonar-project.properties b/packages/admin-api-client-data-provider/sonar-project.properties
index 8f048b09d..cf327fb19 100644
--- a/packages/admin-api-client-data-provider/sonar-project.properties
+++ b/packages/admin-api-client-data-provider/sonar-project.properties
@@ -1,7 +1,7 @@
sonar.organization=mocks-server
sonar.projectKey=mocks-server_main_admin-api-client-data-provider
sonar.projectName=admin-api-client-data-provider
-sonar.projectVersion=5.0.1
+sonar.projectVersion=6.0.0
sonar.javascript.file.suffixes=.js
sonar.sourceEncoding=UTF-8
diff --git a/packages/admin-api-client-data-provider/src/config.js b/packages/admin-api-client-data-provider/src/config.js
index ac954e537..d56f8e83e 100644
--- a/packages/admin-api-client-data-provider/src/config.js
+++ b/packages/admin-api-client-data-provider/src/config.js
@@ -1,21 +1,22 @@
import { providers } from "@data-provider/core";
-import { DEFAULT_BASE_PATH } from "@mocks-server/admin-api-paths";
+import { BASE_PATH } from "@mocks-server/admin-api-paths";
+
import TAG from "./tag";
const DEFAULT_OPTIONS = {
- apiPath: DEFAULT_BASE_PATH,
- baseUrl: "http://127.0.0.1:3100",
+ port: 3110,
+ host: "127.0.0.1",
};
-export const config = (options) => {
+export const configClient = (options) => {
const finalOptions = {
...DEFAULT_OPTIONS,
...options,
};
providers.getByTag(TAG).config({
- baseUrl: `${finalOptions.baseUrl}${finalOptions.apiPath}`,
+ baseUrl: `http://${finalOptions.host}:${finalOptions.port}${BASE_PATH}`,
});
};
-config();
+configClient();
diff --git a/packages/admin-api-client-data-provider/src/providers.js b/packages/admin-api-client-data-provider/src/providers.js
index b4dc6995b..9c85ab9e3 100644
--- a/packages/admin-api-client-data-provider/src/providers.js
+++ b/packages/admin-api-client-data-provider/src/providers.js
@@ -1,11 +1,11 @@
import {
- SETTINGS,
+ CONFIG,
ABOUT,
ALERTS,
- MOCKS,
+ COLLECTIONS,
ROUTES,
- ROUTES_VARIANTS,
- MOCK_CUSTOM_ROUTES_VARIANTS,
+ VARIANTS,
+ CUSTOM_ROUTE_VARIANTS,
} from "@mocks-server/admin-api-paths";
import { Axios } from "@data-provider/axios";
@@ -57,13 +57,6 @@ function createModelOrigin({ id, baseUrl, modelId }) {
});
}
-function modelGetter(modelOrigin, methodName) {
- const method = getModelMethod(methodName);
- return (modelId) => {
- return modelOrigin.queries[method](modelId);
- };
-}
-
function createRestEntityOrigins({ id, baseUrl, modelId, modelGetterMethod, modelGetterParam }) {
const collectionOrigin = createCollectionOrigin({
id,
@@ -77,7 +70,7 @@ function createRestEntityOrigins({ id, baseUrl, modelId, modelGetterMethod, mode
});
addModelQuery(modelOrigin, modelGetterMethod, modelGetterParam);
- return [collectionOrigin, modelOrigin, modelGetter(modelOrigin, modelGetterMethod)];
+ return [collectionOrigin, modelOrigin];
}
export const about = new Axios({
@@ -87,9 +80,9 @@ export const about = new Axios({
...initialState({}),
});
-export const settings = new Axios({
- id: "settings",
- url: SETTINGS,
+export const config = new Axios({
+ id: "config",
+ url: CONFIG,
updateMethod: "patch",
tags: [TAG],
...initialState({}),
@@ -97,28 +90,24 @@ export const settings = new Axios({
const alertsOrigins = createRestEntityOrigins({ id: "alerts", baseUrl: ALERTS });
export const alerts = alertsOrigins[0];
-export const alertsModel = alertsOrigins[1];
-export const alert = alertsOrigins[2];
+export const alert = alertsOrigins[1];
-const mocksOrigins = createRestEntityOrigins({ id: "mocks", baseUrl: MOCKS });
-export const mocks = mocksOrigins[0];
-export const mocksModel = mocksOrigins[1];
-export const mock = mocksOrigins[2];
+const collectionsOrigins = createRestEntityOrigins({ id: "collections", baseUrl: COLLECTIONS });
+export const collections = collectionsOrigins[0];
+export const collection = collectionsOrigins[1];
const routesOrigins = createRestEntityOrigins({ id: "routes", baseUrl: ROUTES });
export const routes = routesOrigins[0];
-export const routesModel = routesOrigins[1];
-export const route = routesOrigins[2];
+export const route = routesOrigins[1];
-const routesVariantsOrigins = createRestEntityOrigins({
- id: "routes-variants",
- baseUrl: ROUTES_VARIANTS,
+const variantsOrigins = createRestEntityOrigins({
+ id: "route-variants",
+ baseUrl: VARIANTS,
});
-export const routesVariants = routesVariantsOrigins[0];
-export const routesVariantsModel = routesVariantsOrigins[1];
-export const routeVariant = routesVariantsOrigins[2];
+export const variants = variantsOrigins[0];
+export const variant = variantsOrigins[1];
-export const customRoutesVariants = createCollectionOrigin({
+export const customRouteVariants = createCollectionOrigin({
id: "custom-routes-variants",
- url: MOCK_CUSTOM_ROUTES_VARIANTS,
+ url: CUSTOM_ROUTE_VARIANTS,
});
diff --git a/packages/admin-api-client-data-provider/test/index.spec.js b/packages/admin-api-client-data-provider/test/index.spec.js
index 65302702a..f688483f3 100644
--- a/packages/admin-api-client-data-provider/test/index.spec.js
+++ b/packages/admin-api-client-data-provider/test/index.spec.js
@@ -1,16 +1,16 @@
-import { config, about, settings, alerts, alert, alertsModel } from "../index";
+import { configClient, about, config, alerts, alert } from "../index";
describe("Exported methods", () => {
- it("should include config", () => {
- expect(config).toBeDefined();
+ it("should include configClient", () => {
+ expect(configClient).toBeDefined();
});
it("should include about", () => {
expect(about).toBeDefined();
});
- it("should include settings", () => {
- expect(settings).toBeDefined();
+ it("should include config", () => {
+ expect(config).toBeDefined();
});
it("should include alerts", () => {
@@ -20,8 +20,4 @@ describe("Exported methods", () => {
it("should include alert", () => {
expect(alert).toBeDefined();
});
-
- it("should include alertsModel", () => {
- expect(alertsModel).toBeDefined();
- });
});
diff --git a/packages/admin-api-client-data-provider/test/src/config.spec.js b/packages/admin-api-client-data-provider/test/src/config.spec.js
deleted file mode 100644
index 51c949f29..000000000
--- a/packages/admin-api-client-data-provider/test/src/config.spec.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import sinon from "sinon";
-import { providers } from "@data-provider/core";
-import { DEFAULT_BASE_PATH } from "@mocks-server/admin-api-paths";
-
-import { config } from "../../src/config";
-import TAG from "../../src/tag";
-
-describe("config method", () => {
- const BASE_URL = "http://127.0.0.1:3001";
- const API_PATH = "/foo-admin";
-
- let sandbox;
- beforeAll(() => {
- sandbox = sinon.createSandbox();
- sandbox.spy(providers.getByTag(TAG), "config");
- });
-
- afterAll(() => {
- sandbox.restore();
- });
-
- it("should set baseUrl in admin-api-client tagged providers", () => {
- config({
- baseUrl: BASE_URL,
- });
- expect(providers.getByTag(TAG).config.getCall(0).args[0].baseUrl).toEqual(
- `${BASE_URL}${DEFAULT_BASE_PATH}`
- );
- });
-
- it("should set apiPath in admin-api-client tagged providers", () => {
- config({
- baseUrl: BASE_URL,
- apiPath: API_PATH,
- });
- expect(providers.getByTag(TAG).config.getCall(1).args[0].baseUrl).toEqual(
- `${BASE_URL}${API_PATH}`
- );
- });
-});
diff --git a/packages/admin-api-client-data-provider/test/src/configClient.spec.js b/packages/admin-api-client-data-provider/test/src/configClient.spec.js
new file mode 100644
index 000000000..2b187e8d3
--- /dev/null
+++ b/packages/admin-api-client-data-provider/test/src/configClient.spec.js
@@ -0,0 +1,31 @@
+import sinon from "sinon";
+import { providers } from "@data-provider/core";
+import { BASE_PATH } from "@mocks-server/admin-api-paths";
+
+import { configClient } from "../../src/config";
+import TAG from "../../src/tag";
+
+describe("configClient method", () => {
+ const PORT = 3002;
+ const HOST = "foo-host";
+
+ let sandbox;
+ beforeAll(() => {
+ sandbox = sinon.createSandbox();
+ sandbox.spy(providers.getByTag(TAG), "config");
+ });
+
+ afterAll(() => {
+ sandbox.restore();
+ });
+
+ it("should set baseUrl in admin-api-client tagged providers", () => {
+ configClient({
+ host: HOST,
+ port: PORT,
+ });
+ expect(providers.getByTag(TAG).config.getCall(0).args[0].baseUrl).toEqual(
+ `http://${HOST}:${PORT}${BASE_PATH}`
+ );
+ });
+});
diff --git a/packages/admin-api-client-data-provider/test/src/providers.spec.js b/packages/admin-api-client-data-provider/test/src/providers.spec.js
index 9eebeca0c..43231a44d 100644
--- a/packages/admin-api-client-data-provider/test/src/providers.spec.js
+++ b/packages/admin-api-client-data-provider/test/src/providers.spec.js
@@ -1,17 +1,11 @@
-import { alertsModel, alert } from "../../src/providers";
+import { alert } from "../../src/providers";
-describe("alertsModel findById custom query", () => {
+describe("alert findById custom query", () => {
it("should return name urlParam", () => {
- expect(alertsModel.queryMethods.byId("foo")).toEqual({
+ expect(alert.queryMethods.byId("foo")).toEqual({
urlParams: {
id: "foo",
},
});
});
});
-
-describe("alert alias", () => {
- it("should return queried alertsModel", () => {
- expect(alert("foo")).toEqual(alertsModel.queries.byId("foo"));
- });
-});
diff --git a/packages/admin-api-client/CHANGELOG.md b/packages/admin-api-client/CHANGELOG.md
index 70d175285..e1e8997ff 100644
--- a/packages/admin-api-client/CHANGELOG.md
+++ b/packages/admin-api-client/CHANGELOG.md
@@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Removed
### Breaking change
+## [6.0.0] - 2022-07-22
+
+### Changed
+
+- feat: BREAKING CHANGE. Modify methods to adapt them to the new plugin-admin-api@3.2.0 REST API
+
## [5.0.2] - 2022-07-05
### Changed
diff --git a/packages/admin-api-client/README.md b/packages/admin-api-client/README.md
index 2c8aa1979..5047701de 100644
--- a/packages/admin-api-client/README.md
+++ b/packages/admin-api-client/README.md
@@ -13,7 +13,7 @@
# Mocks-server administration api client
-This package provides an API client for administrating Mocks Server _(it performs requests to the [Admin API plugin][plugin-admin-api-url] under the hood)_.
+This package provides an API client for administrating Mocks Server through HTTP requests to the [Admin API plugin][plugin-admin-api-url].
Requests to the Mocks Server administration API are made using [`cross-fetch`](https://www.npmjs.com/package/cross-fetch), which makes this package compatible with browsers and Node.js environments, but, if you are going to build a browser application, you'll probably prefer to use the [`@mocks-server/admin-api-client-data-provider` package](https://www.npmjs.com/package/@mocks-server/admin-api-client-data-provider), which uses [Data Provider](https://www.data-provider.org), and works well with Redux, React, etc.
@@ -34,23 +34,29 @@ The UMD build is also available on unpkg. When UMD package is loaded, it creates
## Usage
-All methods described in the [Api](#api) (except the `config` method) return Promises when executed:
+All methods described in the [Api](#api) return Promises when executed (except the `configClient` method):
```js
-import { readAbout, readSettings, updateSettings } from "@mocks-server/admin-api-client";
+import { readAbout, readConfig, updateConfig } from "@mocks-server/admin-api-client";
const example = async () => {
const { version } = await readAbout();
- console.log(`Current Admin API plugin version is ${version}`);
-
- const currentSettings = await readSettings();
- console.log("Current Mocks Server settings are", currentSettings);
-
- await updateSettings({
- mock: "user-super-admin",
- delay: 1000
+ console.log(`Current Admin API plugin version is ${versions.adminApi}`);
+
+ const currentConfig = await readConfig();
+ console.log("Current Mocks Server config is", JSON.stringify(currentConfig));
+
+ await updateConfig({
+ mock: {
+ collections: {
+ selected: "user-super-admin"
+ },
+ routes: {
+ delay: 1000
+ },
+ },
});
- console.log("Mock and delay changed");
+ console.log("Collection and delay changed");
};
example();
@@ -59,38 +65,42 @@ example();
## Api
* `readAbout()` - Returns info about the Admin API plugin, such as current version.
-* `readSettings()` - Returns current Mocks Server settings.
-* `updateSettings(settingsObject)` - Updates Mocks Server settings. A settings object has to be provided. Read the [Mocks Server configuration docs](https://www.mocks-server.org/docs/configuration-options) for further info.
+* `readConfig()` - Returns current configuration.
+* `updateConfig(configObject)` - Updates Mocks Server configuration. A configuration object has to be provided. Read the [Mocks Server configuration docs](https://www.mocks-server.org/docs/configuration/options) for further info.
* `readAlerts()` - Returns array of current alerts.
* `readAlert(alertId)` - Returns an specific alert.
-* `readMocks()` - Returns available mocks.
-* `readMock(id)` - Returns data of a specific mock.
+* `readCollections()` - Returns available collections.
+* `readCollection(id)` - Returns a collection by ID.
* `readRoutes()` - Returns available routes.
-* `readRoute(id)` - Returns data of a specific route.
-* `readRoutesVariants()` - Returns available routes variants.
-* `readRouteVariant(id)` - Returns data of a specific route variant.
-* `readCustomRoutesVariants()` - Returns current routes variants manually added to current mock.
-* `useRouteVariant(id)` - Sets a specific route variant to be used by current mock.
-* `restoreRoutesVariants()` - Restore routes variants to those defined in current mock.
+* `readRoute(id)` - Returns a route by ID.
+* `readVariants()` - Returns available route variants.
+* `readVariant(id)` - Returns a route variant by ID.
+* `readCustomRouteVariants()` - Returns current custom route variants of the current collection.
+* `useRouteVariant(id)` - Sets a custom route variant to be used by current collection.
+* `restoreRouteVariants()` - Restore route variants to those defined in current collection.
## Configuration
-By default, the client is configured to request to `http://127.0.0.1:3100/admin`, based in the [default options of Mocks Server](https://www.mocks-server.org/docs/configuration-options)
+By default, the client is configured to request to `http://127.0.0.1:3110/api`, based in the [default options of Mocks Server](https://www.mocks-server.org/docs/configuration/options)
-You can change both the base url of Mocks Server, and the path of the [Admin API plugin][plugin-admin-api-url] using the `config` method:
+You can change both the the host and port of the administration API:
```js
-import { config } from "@mocks-server/admin-api-client";
+import { configClient } from "@mocks-server/admin-api-client";
-config({
- adminApiPath: "/foo-admin",
- baseUrl: "http://my-mocks-server:3000"
+configClient({
+ host: "localhost",
+ port: 3500
});
```
+## Release notes
+
+Current major release is compatible only with `@mocks-server/main` versions upper or equal than `3.6`. Use prior releases for lower versions. If you don't want to update to the latest major version of this package yet but you want to update `@mocks-server/main`, you can also use any `5.x` version of this package with any `@mocks-server/main@3.x` version.
+
## Contributing
Contributors are welcome.
Please read the [contributing guidelines](.github/CONTRIBUTING.md) and [code of conduct](.github/CODE_OF_CONDUCT.md).
-[plugin-admin-api-url]: https://github.com/mocks-server/plugin-admin-api
+[plugin-admin-api-url]: https://github.com/mocks-server/main/blob/master/packages/admin-api-client
diff --git a/packages/admin-api-client/index.js b/packages/admin-api-client/index.js
index ec677ac27..58f8a1297 100644
--- a/packages/admin-api-client/index.js
+++ b/packages/admin-api-client/index.js
@@ -1,2 +1,2 @@
-export { config } from "./src/entities";
+export { configClient } from "./src/entities";
export * from "./src/methods";
diff --git a/packages/admin-api-client/package.json b/packages/admin-api-client/package.json
index b24223e32..1853d1dc0 100644
--- a/packages/admin-api-client/package.json
+++ b/packages/admin-api-client/package.json
@@ -1,6 +1,6 @@
{
"name": "@mocks-server/admin-api-client",
- "version": "5.0.2",
+ "version": "6.0.0",
"description": "Client of @mocks-server/plugin-admin-api",
"keywords": [
"mocks-server",
diff --git a/packages/admin-api-client/sonar-project.properties b/packages/admin-api-client/sonar-project.properties
index 9a1efe20a..2a7510c2e 100644
--- a/packages/admin-api-client/sonar-project.properties
+++ b/packages/admin-api-client/sonar-project.properties
@@ -1,7 +1,7 @@
sonar.organization=mocks-server
sonar.projectKey=mocks-server_main_admin-api-client
sonar.projectName=admin-api-client
-sonar.projectVersion=5.0.2
+sonar.projectVersion=6.0.0
sonar.javascript.file.suffixes=.js
sonar.sourceEncoding=UTF-8
diff --git a/packages/admin-api-client/src/entities.js b/packages/admin-api-client/src/entities.js
index dd83ce2be..51bd8fbb8 100644
--- a/packages/admin-api-client/src/entities.js
+++ b/packages/admin-api-client/src/entities.js
@@ -1,22 +1,22 @@
import crossFetch from "cross-fetch";
import {
- DEFAULT_BASE_PATH,
- SETTINGS,
+ BASE_PATH,
+ CONFIG,
ABOUT,
ALERTS,
- MOCKS,
+ COLLECTIONS,
ROUTES,
- ROUTES_VARIANTS,
- MOCK_CUSTOM_ROUTES_VARIANTS,
+ VARIANTS,
+ CUSTOM_ROUTE_VARIANTS,
} from "@mocks-server/admin-api-paths";
const DEFAULT_OPTIONS = {
- adminApiPath: DEFAULT_BASE_PATH,
- baseUrl: "http://127.0.0.1:3100",
+ port: 3110,
+ host: "127.0.0.1",
};
-let configuration = {
+let clientConfiguration = {
...DEFAULT_OPTIONS,
};
@@ -29,9 +29,9 @@ function handleResponse(res) {
});
}
-export function config(options) {
- configuration = {
- ...configuration,
+export function configClient(options) {
+ clientConfiguration = {
+ ...clientConfiguration,
...options,
};
}
@@ -43,7 +43,7 @@ class Fetcher {
}
get url() {
- return `${configuration.baseUrl}${configuration.adminApiPath}${this._url}${this._id}`;
+ return `http://${clientConfiguration.host}:${clientConfiguration.port}${BASE_PATH}${this._url}${this._id}`;
}
_read() {
@@ -95,7 +95,7 @@ class Fetcher {
export const about = new Fetcher(ABOUT);
-export const settings = new Fetcher(SETTINGS);
+export const config = new Fetcher(CONFIG);
export const alerts = new Fetcher(ALERTS);
@@ -103,10 +103,10 @@ export const alert = (id) => {
return new Fetcher(ALERTS, id);
};
-export const mocks = new Fetcher(MOCKS);
+export const collections = new Fetcher(COLLECTIONS);
-export const mock = (id) => {
- return new Fetcher(MOCKS, id);
+export const collection = (id) => {
+ return new Fetcher(COLLECTIONS, id);
};
export const routes = new Fetcher(ROUTES);
@@ -115,10 +115,10 @@ export const route = (id) => {
return new Fetcher(ROUTES, id);
};
-export const routesVariants = new Fetcher(ROUTES_VARIANTS);
+export const variants = new Fetcher(VARIANTS);
-export const routeVariant = (id) => {
- return new Fetcher(ROUTES_VARIANTS, id);
+export const variant = (id) => {
+ return new Fetcher(VARIANTS, id);
};
-export const mockCustomRoutesVariants = new Fetcher(MOCK_CUSTOM_ROUTES_VARIANTS);
+export const customRouteVariants = new Fetcher(CUSTOM_ROUTE_VARIANTS);
diff --git a/packages/admin-api-client/src/methods.js b/packages/admin-api-client/src/methods.js
index 67e682aa6..363f0c331 100644
--- a/packages/admin-api-client/src/methods.js
+++ b/packages/admin-api-client/src/methods.js
@@ -1,27 +1,27 @@
import {
about,
- settings,
+ config,
alerts,
alert,
- mocks,
- mock,
+ collections,
+ collection,
routes,
route,
- routesVariants,
- routeVariant,
- mockCustomRoutesVariants,
+ variants,
+ variant,
+ customRouteVariants,
} from "./entities";
export function readAbout() {
return about.read();
}
-export function readSettings() {
- return settings.read();
+export function readConfig() {
+ return config.read();
}
-export function updateSettings(newSettings) {
- return settings.update(newSettings);
+export function updateConfig(newConfig) {
+ return config.update(newConfig);
}
export function readAlerts() {
@@ -32,12 +32,12 @@ export function readAlert(id) {
return alert(id).read();
}
-export function readMocks() {
- return mocks.read();
+export function readCollections() {
+ return collections.read();
}
-export function readMock(id) {
- return mock(id).read();
+export function readCollection(id) {
+ return collection(id).read();
}
export function readRoutes() {
@@ -48,24 +48,24 @@ export function readRoute(id) {
return route(id).read();
}
-export function readRoutesVariants() {
- return routesVariants.read();
+export function readVariants() {
+ return variants.read();
}
-export function readRouteVariant(id) {
- return routeVariant(id).read();
+export function readVariant(id) {
+ return variant(id).read();
}
-export function readCustomRoutesVariants() {
- return mockCustomRoutesVariants.read();
+export function readCustomRouteVariants() {
+ return customRouteVariants.read();
}
export function useRouteVariant(id) {
- return mockCustomRoutesVariants.create({
+ return customRouteVariants.create({
id,
});
}
-export function restoreRoutesVariants() {
- return mockCustomRoutesVariants.delete();
+export function restoreRouteVariants() {
+ return customRouteVariants.delete();
}
diff --git a/packages/admin-api-client/test/index.spec.js b/packages/admin-api-client/test/index.spec.js
index 81148883a..1404ab863 100644
--- a/packages/admin-api-client/test/index.spec.js
+++ b/packages/admin-api-client/test/index.spec.js
@@ -2,26 +2,26 @@ import { wait } from "./support/helpers";
import {
readAbout,
- readSettings,
- updateSettings,
+ readConfig,
+ updateConfig,
readAlerts,
readAlert,
- readMocks,
- readMock,
+ readCollections,
+ readCollection,
readRoutes,
readRoute,
- readRoutesVariants,
- readRouteVariant,
- readCustomRoutesVariants,
+ readVariants,
+ readVariant,
+ readCustomRouteVariants,
useRouteVariant,
- restoreRoutesVariants,
+ restoreRouteVariants,
} from "../index";
-describe("react-admin-client methods used with node", () => {
+describe("admin api client methods", () => {
describe("when reading about", () => {
it("should return current version", async () => {
const about = await readAbout();
- expect(about.version).toBeDefined();
+ expect(about.versions.adminApi).toBeDefined();
});
});
@@ -32,10 +32,10 @@ describe("react-admin-client methods used with node", () => {
expect(alerts.length).toEqual(1);
});
- it("should return alert about mock not defined", async () => {
+ it("should return alert about collection not defined", async () => {
const alerts = await readAlerts();
expect(alerts[0].message).toEqual(
- expect.stringContaining("Option 'mock' was not defined")
+ expect.stringContaining("Option 'mock.collections.selected' was not defined")
);
});
});
@@ -43,7 +43,7 @@ describe("react-admin-client methods used with node", () => {
describe("when there are alerts about files with error", () => {
it("should return 3 alerts", async () => {
expect.assertions(1);
- await updateSettings({
+ await updateConfig({
files: { path: "mocks-with-error" },
});
await wait(2000);
@@ -51,20 +51,22 @@ describe("react-admin-client methods used with node", () => {
expect(alerts.length).toEqual(3);
});
- it("alert about mocks settings should exist", async () => {
+ it("alert about config should exist", async () => {
const alerts = await readAlerts();
const alertId = alerts[0].id;
const alert = await readAlert(alertId);
expect(alert.id).toEqual(alertId);
- expect(alert.message).toEqual(expect.stringContaining("Option 'mock' was not defined"));
+ expect(alert.message).toEqual(
+ expect.stringContaining("Option 'mock.collections.selected' was not defined")
+ );
});
- it("alert about no mocks should exist", async () => {
+ it("alert about empty collections should exist", async () => {
const alerts = await readAlerts();
const alertId = alerts[1].id;
const alert = await readAlert(alertId);
expect(alert.id).toEqual(alertId);
- expect(alert.message).toEqual(expect.stringContaining("No mocks found"));
+ expect(alert.message).toEqual(expect.stringContaining("No collections found"));
});
it("alert about files error should exist", async () => {
@@ -72,16 +74,18 @@ describe("react-admin-client methods used with node", () => {
const alertId = alerts[2].id;
const alert = await readAlert(alertId);
expect(alert.id).toEqual(alertId);
- expect(alert.message).toEqual(expect.stringContaining("Error loading mocks"));
+ expect(alert.message).toEqual(expect.stringContaining("Error loading collections"));
});
});
describe("when alerts are removed", () => {
it("should return no alerts", async () => {
- await updateSettings({
+ await updateConfig({
files: { path: "mocks" },
- mocks: {
- selected: "base",
+ mock: {
+ collections: {
+ selected: "base",
+ },
},
});
await wait(2000);
@@ -91,46 +95,58 @@ describe("react-admin-client methods used with node", () => {
});
});
- describe("when updating settings", () => {
- it("should update current delay", async () => {
- await updateSettings({
+ describe("when updating config", () => {
+ it("should update current delay using legacy option", async () => {
+ await updateConfig({
mocks: {
delay: 1000,
},
});
- const settings = await readSettings();
+ const settings = await readConfig();
expect(settings.mocks.delay).toEqual(1000);
});
+
+ it("should update current delay", async () => {
+ await updateConfig({
+ mock: {
+ routes: {
+ delay: 2000,
+ },
+ },
+ });
+ const settings = await readConfig();
+ expect(settings.mock.routes.delay).toEqual(2000);
+ });
});
- describe("when reading mocks", () => {
- it("should return mocks", async () => {
- const mocks = await readMocks();
- expect(mocks).toEqual([
+ describe("when reading collections", () => {
+ it("should return collections", async () => {
+ const collections = await readCollections();
+ expect(collections).toEqual([
{
id: "base",
from: null,
- routesVariants: ["get-user:1"],
- appliedRoutesVariants: ["get-user:1"],
+ definedRoutes: ["get-user:1"],
+ routes: ["get-user:1"],
},
{
id: "user2",
from: null,
- routesVariants: ["get-user:2"],
- appliedRoutesVariants: ["get-user:2"],
+ definedRoutes: ["get-user:2"],
+ routes: ["get-user:2"],
},
]);
});
});
- describe("when reading mock", () => {
- it("should return mock data", async () => {
- const mock = await readMock("base");
- expect(mock).toEqual({
+ describe("when reading collection", () => {
+ it("should return collection data", async () => {
+ const collection = await readCollection("base");
+ expect(collection).toEqual({
id: "base",
from: null,
- routesVariants: ["get-user:1"],
- appliedRoutesVariants: ["get-user:1"],
+ definedRoutes: ["get-user:1"],
+ routes: ["get-user:1"],
});
});
});
@@ -143,7 +159,7 @@ describe("react-admin-client methods used with node", () => {
id: "get-user",
delay: null,
url: "/api/user",
- method: "GET",
+ method: "get",
variants: ["get-user:1", "get-user:2"],
},
]);
@@ -152,61 +168,61 @@ describe("react-admin-client methods used with node", () => {
describe("when reading route", () => {
it("should return route data", async () => {
- const mock = await readRoute("get-user");
- expect(mock).toEqual({
+ const data = await readRoute("get-user");
+ expect(data).toEqual({
id: "get-user",
delay: null,
url: "/api/user",
- method: "GET",
+ method: "get",
variants: ["get-user:1", "get-user:2"],
});
});
});
- describe("when reading routes variants", () => {
- it("should return routes variants", async () => {
- const data = await readRoutesVariants();
+ describe("when reading variants", () => {
+ it("should return route variants", async () => {
+ const data = await readVariants();
expect(data).toEqual([
{
id: "get-user:1",
- routeId: "get-user",
- handler: "json",
- response: { body: [{ email: "foo@foo.com" }], status: 200 },
+ route: "get-user",
+ type: "json",
+ preview: { body: [{ email: "foo@foo.com" }], status: 200 },
delay: null,
},
{
id: "get-user:2",
- routeId: "get-user",
- handler: "json",
- response: { body: [{ email: "foo2@foo2.com" }], status: 200 },
+ route: "get-user",
+ type: "json",
+ preview: { body: [{ email: "foo2@foo2.com" }], status: 200 },
delay: null,
},
]);
});
});
- describe("when reading route variant", () => {
- it("should return route variant data", async () => {
- const data = await readRouteVariant("get-user:2");
+ describe("when reading variant", () => {
+ it("should return variant data", async () => {
+ const data = await readVariant("get-user:2");
expect(data).toEqual({
id: "get-user:2",
- routeId: "get-user",
- handler: "json",
- response: { body: [{ email: "foo2@foo2.com" }], status: 200 },
+ route: "get-user",
+ type: "json",
+ preview: { body: [{ email: "foo2@foo2.com" }], status: 200 },
delay: null,
});
});
});
- describe("mock custom route variants", () => {
+ describe("custom route variants", () => {
it("should be empty", async () => {
- const data = await readCustomRoutesVariants();
+ const data = await readCustomRouteVariants();
expect(data).toEqual([]);
});
it("should be able to add one", async () => {
await useRouteVariant("get-user:2");
- const data = await readCustomRoutesVariants();
+ const data = await readCustomRouteVariants();
expect(data).toEqual(["get-user:2"]);
});
@@ -217,9 +233,9 @@ describe("react-admin-client methods used with node", () => {
});
});
- it("should be empty after restoring them to the mock defaults", async () => {
- await restoreRoutesVariants();
- const data = await readCustomRoutesVariants();
+ it("should be empty after restoring them to the collection defaults", async () => {
+ await restoreRouteVariants();
+ const data = await readCustomRouteVariants();
expect(data).toEqual([]);
});
});
diff --git a/packages/admin-api-client/test/support/helpers.js b/packages/admin-api-client/test/support/helpers.js
index bee7eab35..215876b19 100644
--- a/packages/admin-api-client/test/support/helpers.js
+++ b/packages/admin-api-client/test/support/helpers.js
@@ -1,7 +1,7 @@
-import { config } from "../../index";
+import { configClient } from "../../index";
-config({
- baseUrl: "http://127.0.0.1:3200",
+configClient({
+ port: 3110,
});
const wait = (time = 1000) => {
diff --git a/packages/admin-api-paths/CHANGELOG.md b/packages/admin-api-paths/CHANGELOG.md
index 4671b9315..cf3d1a2e0 100644
--- a/packages/admin-api-paths/CHANGELOG.md
+++ b/packages/admin-api-paths/CHANGELOG.md
@@ -10,6 +10,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
### Removed
+## [4.0.0] - 2022-07-22
+
+### Added
+
+- feat: Add new paths for admin-api-plugin
+
+### Changed
+
+- feat: BREAKING CHANGE. Add `LEGACY_` prefix to all previous paths.
+
## [3.0.1] - 2022-06-03
### Changed
diff --git a/packages/admin-api-paths/README.md b/packages/admin-api-paths/README.md
index fc8900143..a93cd763a 100644
--- a/packages/admin-api-paths/README.md
+++ b/packages/admin-api-paths/README.md
@@ -13,14 +13,15 @@
# Api paths of the Mocks-Server Plugin Admin Api
-Constants defining API paths of the [Mocks Server plugin-admin-api][plugin-admin-api-url]. They can also be used to build plugin API clients.
+Constants defining API paths of the [Mocks Server Plugin Admin API][plugin-admin-api-url]. They can be used to build plugin API clients.
## Usage
```js
-import { SETTINGS } from "@mocks-server/admin-api-paths";
+import { BASE_PATH, CONFIG } from "@mocks-server/admin-api-paths";
-console.log(SETTINGS); // "/settings"
+console.log(BASE_PATH); // "/api"
+console.log(CONFIG); // "/config"
```
## Contributing
@@ -28,4 +29,4 @@ console.log(SETTINGS); // "/settings"
Contributors are welcome.
Please read the [contributing guidelines](.github/CONTRIBUTING.md) and [code of conduct](.github/CODE_OF_CONDUCT.md).
-[plugin-admin-api-url]: https://github.com/mocks-server/plugin-admin-api
+[plugin-admin-api-url]: https://github.com/mocks-server/main/blob/master/packages/admin-api-client
diff --git a/packages/admin-api-paths/index.js b/packages/admin-api-paths/index.js
index 8ffdf6eed..4f840075b 100644
--- a/packages/admin-api-paths/index.js
+++ b/packages/admin-api-paths/index.js
@@ -1,9 +1,19 @@
-export const DEFAULT_BASE_PATH = "/admin";
-export const SETTINGS = "/settings";
+export const LEGACY_DEFAULT_BASE_PATH = "/admin";
+export const LEGACY_SETTINGS = "/settings";
+export const LEGACY_ABOUT = "/about";
+export const LEGACY_ALERTS = "/alerts";
+
+export const LEGACY_MOCKS = "/mocks";
+export const LEGACY_ROUTES = "/routes";
+export const LEGACY_ROUTES_VARIANTS = "/routes-variants";
+export const LEGACY_MOCK_CUSTOM_ROUTES_VARIANTS = "/mock-custom-routes-variants";
+
+export const BASE_PATH = "/api";
+export const CONFIG = "/config";
export const ABOUT = "/about";
export const ALERTS = "/alerts";
-export const MOCKS = "/mocks";
-export const ROUTES = "/routes";
-export const ROUTES_VARIANTS = "/routes-variants";
-export const MOCK_CUSTOM_ROUTES_VARIANTS = "/mock-custom-routes-variants";
+export const COLLECTIONS = "/mock/collections";
+export const ROUTES = "/mock/routes";
+export const VARIANTS = "/mock/variants";
+export const CUSTOM_ROUTE_VARIANTS = "/mock/custom-route-variants";
diff --git a/packages/admin-api-paths/package.json b/packages/admin-api-paths/package.json
index 25b7a1274..f24812253 100644
--- a/packages/admin-api-paths/package.json
+++ b/packages/admin-api-paths/package.json
@@ -1,6 +1,6 @@
{
"name": "@mocks-server/admin-api-paths",
- "version": "3.0.1",
+ "version": "4.0.0",
"description": "Api paths of @mocks-server/plugin-admin-api",
"keywords": [
"administration",
diff --git a/packages/admin-api-paths/sonar-project.properties b/packages/admin-api-paths/sonar-project.properties
index fc0a39fdb..79eba7051 100644
--- a/packages/admin-api-paths/sonar-project.properties
+++ b/packages/admin-api-paths/sonar-project.properties
@@ -1,7 +1,7 @@
sonar.organization=mocks-server
sonar.projectKey=mocks-server_main_admin-api-paths
sonar.projectName=admin-api-paths
-sonar.projectVersion=3.0.1
+sonar.projectVersion=4.0.0
sonar.javascript.file.suffixes=.js
sonar.sourceEncoding=UTF-8
diff --git a/packages/admin-api-paths/test/index.spec.js b/packages/admin-api-paths/test/index.spec.js
index 85c423dc3..be1e84769 100644
--- a/packages/admin-api-paths/test/index.spec.js
+++ b/packages/admin-api-paths/test/index.spec.js
@@ -1,44 +1,89 @@
import {
- DEFAULT_BASE_PATH,
+ BASE_PATH,
ABOUT,
- SETTINGS,
+ CONFIG,
ALERTS,
- MOCKS,
+ COLLECTIONS,
ROUTES,
- ROUTES_VARIANTS,
- MOCK_CUSTOM_ROUTES_VARIANTS,
+ VARIANTS,
+ CUSTOM_ROUTE_VARIANTS,
+ // Legacy, to be removed
+ LEGACY_DEFAULT_BASE_PATH,
+ LEGACY_ABOUT,
+ LEGACY_SETTINGS,
+ LEGACY_ALERTS,
+ LEGACY_MOCKS,
+ LEGACY_ROUTES,
+ LEGACY_ROUTES_VARIANTS,
+ LEGACY_MOCK_CUSTOM_ROUTES_VARIANTS,
} from "../index";
describe("Exported paths", () => {
- it("should contain the default api base path", () => {
- expect(DEFAULT_BASE_PATH).toBeDefined();
- });
+ describe("legacy", () => {
+ it("should contain the default api base path", () => {
+ expect(LEGACY_DEFAULT_BASE_PATH).toBeDefined();
+ });
- it("should contain the about path", () => {
- expect(ABOUT).toBeDefined();
- });
+ it("should contain the about path", () => {
+ expect(LEGACY_ABOUT).toBeDefined();
+ });
- it("should contain the settings path", () => {
- expect(SETTINGS).toBeDefined();
- });
+ it("should contain the settings path", () => {
+ expect(LEGACY_SETTINGS).toBeDefined();
+ });
- it("should contain the alerts path", () => {
- expect(ALERTS).toBeDefined();
- });
+ it("should contain the alerts path", () => {
+ expect(LEGACY_ALERTS).toBeDefined();
+ });
- it("should contain the mocks path", () => {
- expect(MOCKS).toBeDefined();
- });
+ it("should contain the mocks path", () => {
+ expect(LEGACY_MOCKS).toBeDefined();
+ });
- it("should contain the routes path", () => {
- expect(ROUTES).toBeDefined();
- });
+ it("should contain the routes path", () => {
+ expect(LEGACY_ROUTES).toBeDefined();
+ });
+
+ it("should contain the routes-variants path", () => {
+ expect(LEGACY_ROUTES_VARIANTS).toBeDefined();
+ });
- it("should contain the routes-variants path", () => {
- expect(ROUTES_VARIANTS).toBeDefined();
+ it("should contain the mock-custom-routes-variants path", () => {
+ expect(LEGACY_MOCK_CUSTOM_ROUTES_VARIANTS).toBeDefined();
+ });
});
- it("should contain the mock-custom-routes-variants path", () => {
- expect(MOCK_CUSTOM_ROUTES_VARIANTS).toBeDefined();
+ describe("paths", () => {
+ it("should contain the base path", () => {
+ expect(BASE_PATH).toBeDefined();
+ });
+
+ it("should contain the about path", () => {
+ expect(ABOUT).toBeDefined();
+ });
+
+ it("should contain the config path", () => {
+ expect(CONFIG).toBeDefined();
+ });
+
+ it("should contain the alerts path", () => {
+ expect(ALERTS).toBeDefined();
+ });
+
+ it("should contain the collections path", () => {
+ expect(COLLECTIONS).toBeDefined();
+ });
+
+ it("should contain the routes path", () => {
+ expect(ROUTES).toBeDefined();
+ });
+
+ it("should contain the variants path", () => {
+ expect(VARIANTS).toBeDefined();
+ });
+
+ it("should contain the custom route variants path", () => {
+ expect(CUSTOM_ROUTE_VARIANTS).toBeDefined();
+ });
});
});
diff --git a/packages/config/CHANGELOG.md b/packages/config/CHANGELOG.md
index b785f687e..c0e33194f 100644
--- a/packages/config/CHANGELOG.md
+++ b/packages/config/CHANGELOG.md
@@ -10,6 +10,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
### Removed
+## [1.2.0] - 2022-07-22
+
+### Added
+- feat: Add `hasBeenSet` property to option
+- feat: Add `getValidationSchema` method to root config object. It returns a validation schema for all namespaces.
+
+### Fixed
+- fix: Remove unused folder
+
## [1.1.0] - 2022-06-27
### Added
diff --git a/packages/config/README.md b/packages/config/README.md
index 987704ed7..0d817e389 100644
--- a/packages/config/README.md
+++ b/packages/config/README.md
@@ -331,6 +331,9 @@ const config = new Config({ moduleName: "mocks", mergeArrays: false });
* `configuration` _(Object)_: Object with configuration. Levels in the object correspond to namespaces names, and last level keys correspond to option names.
* `options` _(Object)_: Object with extra options for validation:
* `allowAdditionalProperties` _(Boolean)_: _Default `false`_. If true, additional properties in the configuration would not produce validation errors.
+* __`getValidationSchema(options)`__: Returns a validation schema compatible with AJV for validating the configuration of all nested namespaces.
+ * `options` _(Object)_: Object with extra options for validation:
+ * `allowAdditionalProperties` _(Boolean)_: _Default `false`_. If true, the validation schema will allow additional properties.
* __`value`__: Getter returning the current values from all namespaces and options as an object. Levels in the object correspond to namespaces names, and last level keys correspond to option names. It can be also used as setter as an alias of the `set` method, with default options.
* __`loadedFile`__: Getter returning the file path of the loaded configuration file. It returns `null` if no configuration file was loaded.
* __`namespaces`__: Getter returning array with all root namespaces.
@@ -384,7 +387,7 @@ const rootOption = config.addOption("name2");
* __`description`__: Getter returning the option description.
* __`extraData`__: Getter returning the option extra data.
* __`default`__: Getter returning the option default value.
+* __`hasBeenSet`__: Returns true if the option value has been actively set, no matter the source or method used to set it. Otherwise returns false.
[website-url]: https://www.mocks-server.org
[logo-url]: https://www.mocks-server.org/img/logo_120.png
-[main-url]: https://www.npmjs.com/package/@mocks-server/main
diff --git a/packages/config/jest.config.js b/packages/config/jest.config.js
index 2a740eaab..f8bf2543a 100644
--- a/packages/config/jest.config.js
+++ b/packages/config/jest.config.js
@@ -26,7 +26,7 @@ module.exports = {
// The glob patterns Jest uses to detect test files
testMatch: ["
/test/**/*.spec.js"],
- // testMatch: ["/test/src/namespaces.spec.js"],
+ // testMatch: ["/test/src/getValidationSchema.spec.js"],
// The test environment that will be used for testing
testEnvironment: "node",
diff --git a/packages/config/package.json b/packages/config/package.json
index f5325fc9b..24fdcadfc 100644
--- a/packages/config/package.json
+++ b/packages/config/package.json
@@ -1,6 +1,6 @@
{
"name": "@mocks-server/config",
- "version": "1.1.0",
+ "version": "1.2.0",
"description": "Modular configuration provider. Read it from file, environment and arguments",
"keywords": [
"configuration",
@@ -27,7 +27,6 @@
"access": "public"
},
"files": [
- "scaffold",
"src",
"index.js"
],
diff --git a/packages/config/scaffold/mocks.config.js b/packages/config/scaffold/mocks.config.js
deleted file mode 100644
index bfa583ce0..000000000
--- a/packages/config/scaffold/mocks.config.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// For a detailed explanation regarding each configuration property, visit:
-// https://mocks-server.org/docs/configuration-options
-// https://mocks-server.org/docs/configuration-file
-
-module.exports = {
- // options
- options: {
- // mock to use on start
- mock: "base",
-
- // mocks and routes path
- // path: "mocks",
-
- // files watch enabled
- // watch: true,
-
- // server delay
- // delay: 0,
-
- // log level. One of "error", "warn", "info", "verbose", "debug", "silly"
- // log: "info",
-
- // Interactive CLI enabled
- // cli: true,
-
- // Administration REST API path
- // adminApiPath: "/admin",
-
- // Server port
- // port: 3100,
-
- // Server host
- // host: "0.0.0.0",
-
- // Cors middleware
- // cors: true,
-
- // Cors pre-flight
- // corsPreFlight: true,
- },
-
- // low level config
-
- // babelRegister: false,
- // babelRegisterOptions: {} // For a detailed explanation regarding each Babel register option, visit: https://babeljs.io/docs/en/babel-register
- // addPlugins: [],
- // addRoutesHandlers: [],
-};
diff --git a/packages/config/sonar-project.properties b/packages/config/sonar-project.properties
index 170ea37de..a187f2267 100644
--- a/packages/config/sonar-project.properties
+++ b/packages/config/sonar-project.properties
@@ -1,7 +1,7 @@
sonar.organization=mocks-server
sonar.projectKey=mocks-server_main_config
sonar.projectName=config
-sonar.projectVersion=1.1.0
+sonar.projectVersion=1.2.0
sonar.javascript.file.suffixes=.js
sonar.sourceEncoding=UTF-8
diff --git a/packages/config/src/Config.js b/packages/config/src/Config.js
index 12d38cf91..e95738c3f 100644
--- a/packages/config/src/Config.js
+++ b/packages/config/src/Config.js
@@ -5,7 +5,7 @@ const Environment = require("./Environment");
const Files = require("./Files");
const Namespace = require("./Namespace");
const { types, avoidArraysMerge } = require("./types");
-const { validateConfigAndThrow, validateConfig } = require("./validation");
+const { validateConfigAndThrow, validateConfig, getValidationSchema } = require("./validation");
const { checkNamespaceName, findObjectWithName, getNamespacesValues } = require("./namespaces");
const CONFIG_NAMESPACE = "config";
@@ -115,6 +115,13 @@ class Config {
});
}
+ getValidationSchema({ allowAdditionalProperties = false } = {}) {
+ return getValidationSchema({
+ namespaces: this._namespaces,
+ allowAdditionalProperties,
+ });
+ }
+
_validateAndThrow({ allowAdditionalProperties }) {
validateConfigAndThrow(this._config, {
namespaces: this._namespaces,
diff --git a/packages/config/src/Option.js b/packages/config/src/Option.js
index 64afb3c5d..b0b79cad3 100644
--- a/packages/config/src/Option.js
+++ b/packages/config/src/Option.js
@@ -19,6 +19,7 @@ class Option {
this._default = this._clone(properties.default);
this._value = this._default;
this._eventsStarted = false;
+ this._hasBeenSet = false;
}
get extraData() {
@@ -89,6 +90,7 @@ class Option {
set(value, { merge = false } = {}) {
if (!isUndefined(value)) {
+ this._hasBeenSet = true;
if (merge && this.type === types.OBJECT) {
this._merge(value);
} else {
@@ -103,6 +105,10 @@ class Option {
startEvents() {
this._eventsStarted = true;
}
+
+ get hasBeenSet() {
+ return this._hasBeenSet;
+ }
}
module.exports = Option;
diff --git a/packages/config/src/validation.js b/packages/config/src/validation.js
index 1bf0a5f32..936214f41 100644
--- a/packages/config/src/validation.js
+++ b/packages/config/src/validation.js
@@ -184,6 +184,10 @@ function validateConfig(config, { namespaces, allowAdditionalProperties }) {
);
}
+function getValidationSchema({ namespaces, allowAdditionalProperties }) {
+ return getConfigValidationSchema({ namespaces, allowAdditionalProperties });
+}
+
function validateOptionAndThrow(properties) {
validateSchemaAndThrow(properties, optionSchema, optionValidator);
}
@@ -197,4 +201,5 @@ module.exports = {
validateConfigAndThrow,
validateOptionAndThrow,
validateValueTypeAndThrow,
+ getValidationSchema,
};
diff --git a/packages/config/test/src/arguments.spec.js b/packages/config/test/src/arguments.spec.js
index 9707383ab..6718cf0e2 100644
--- a/packages/config/test/src/arguments.spec.js
+++ b/packages/config/test/src/arguments.spec.js
@@ -24,6 +24,13 @@ describe("arguments", () => {
expect(option.value).toEqual("foo-from-arg");
});
+ it("hasBeenSet property should be true", async () => {
+ commander.Command.prototype.opts.returns({ "fooNamespace.fooOption": "foo-from-arg" });
+ ({ config, namespace, option } = createConfig({ moduleName: "testD" }));
+ await config.init();
+ expect(option.hasBeenSet).toEqual(true);
+ });
+
it("should return value from arguments in argsLoadedValues getter", async () => {
commander.Command.prototype.opts.returns({ "fooNamespace.fooOption": "foo-from-arg" });
({ config, namespace, option } = createConfig({ moduleName: "testD" }));
diff --git a/packages/config/test/src/environment.spec.js b/packages/config/test/src/environment.spec.js
index ce872740e..3c590aab2 100644
--- a/packages/config/test/src/environment.spec.js
+++ b/packages/config/test/src/environment.spec.js
@@ -24,6 +24,13 @@ describe("environment", () => {
expect(option.value).toEqual("foo-from-env");
});
+ it("hasBeenSet property should be true", async () => {
+ ({ config, namespace, option } = createConfig({ moduleName: "testA" }));
+ process.env["TEST_A_FOO_NAMESPACE_FOO_OPTION"] = "foo-from-env";
+ await config.init();
+ expect(option.hasBeenSet).toEqual(true);
+ });
+
it("should return value from environment in envLoadedValues getter", async () => {
({ config, namespace, option } = createConfig({ moduleName: "testA" }));
process.env["TEST_A_FOO_NAMESPACE_FOO_OPTION"] = "foo-from-env";
diff --git a/packages/config/test/src/files.spec.js b/packages/config/test/src/files.spec.js
index 08e621928..13312c5ec 100644
--- a/packages/config/test/src/files.spec.js
+++ b/packages/config/test/src/files.spec.js
@@ -65,6 +65,14 @@ describe("files", () => {
expect(option.value).toEqual("value-from-file");
});
+ it("hasBeenSet property should be true", async () => {
+ cosmiconfigStub.search.resolves({
+ config: { fooNamespace: { fooOption: "value-from-file" } },
+ });
+ await config.init();
+ expect(option.hasBeenSet).toEqual(true);
+ });
+
it("should return value from files in fileLoadedValues getter", async () => {
cosmiconfigStub.search.resolves({
config: { fooNamespace: { fooOption: "value-from-file" } },
diff --git a/packages/config/test/src/getValidationSchema.spec.js b/packages/config/test/src/getValidationSchema.spec.js
new file mode 100644
index 000000000..393677420
--- /dev/null
+++ b/packages/config/test/src/getValidationSchema.spec.js
@@ -0,0 +1,105 @@
+const { createConfigBeforeElements } = require("../support/helpers");
+
+const Config = require("../../src/Config");
+
+describe("getValidationSchema method", () => {
+ let sandbox, config, namespace;
+
+ beforeEach(() => {
+ ({ sandbox, config, namespace } = createConfigBeforeElements());
+ });
+
+ afterEach(() => {
+ sandbox.restore();
+ });
+
+ describe("when option is created in root", () => {
+ it("should return a valid validation schema", async () => {
+ config = new Config();
+ config.addOption({
+ name: "fooOption",
+ type: "string",
+ default: "default-str",
+ });
+ const validationSchema = config.getValidationSchema();
+ expect(validationSchema).toEqual({
+ type: "object",
+ properties: {
+ fooOption: { type: "string" },
+ config: {
+ type: "object",
+ properties: {
+ readFile: { type: "boolean" },
+ readArguments: { type: "boolean" },
+ readEnvironment: { type: "boolean" },
+ fileSearchPlaces: { type: "array", items: { type: "string" } },
+ allowUnknownArguments: { type: "boolean" },
+ },
+ additionalProperties: false,
+ },
+ },
+ additionalProperties: false,
+ });
+ });
+ });
+
+ describe("when option is created in namespace", () => {
+ it("should return a valid validation schema", async () => {
+ config = new Config();
+ namespace = config.addNamespace("foo");
+ namespace.addOption({ name: "fooOption", type: "number" });
+ const validationSchema = config.getValidationSchema();
+ expect(validationSchema).toEqual({
+ type: "object",
+ properties: {
+ config: {
+ type: "object",
+ properties: {
+ readFile: { type: "boolean" },
+ readArguments: { type: "boolean" },
+ readEnvironment: { type: "boolean" },
+ fileSearchPlaces: { type: "array", items: { type: "string" } },
+ allowUnknownArguments: { type: "boolean" },
+ },
+ additionalProperties: false,
+ },
+ foo: {
+ type: "object",
+ properties: { fooOption: { type: "number" } },
+ additionalProperties: false,
+ },
+ },
+ additionalProperties: false,
+ });
+ });
+
+ it("should return a valid validation schema when additionalProperties are allowed", async () => {
+ config = new Config();
+ namespace = config.addNamespace("foo");
+ namespace.addOption({ name: "fooOption", type: "number" });
+ const validationSchema = config.getValidationSchema({ allowAdditionalProperties: true });
+ expect(validationSchema).toEqual({
+ type: "object",
+ properties: {
+ config: {
+ type: "object",
+ properties: {
+ readFile: { type: "boolean" },
+ readArguments: { type: "boolean" },
+ readEnvironment: { type: "boolean" },
+ fileSearchPlaces: { type: "array", items: { type: "string" } },
+ allowUnknownArguments: { type: "boolean" },
+ },
+ additionalProperties: true,
+ },
+ foo: {
+ type: "object",
+ properties: { fooOption: { type: "number" } },
+ additionalProperties: true,
+ },
+ },
+ additionalProperties: true,
+ });
+ });
+ });
+});
diff --git a/packages/config/test/src/options.spec.js b/packages/config/test/src/options.spec.js
index be20c05cb..81bc87550 100644
--- a/packages/config/test/src/options.spec.js
+++ b/packages/config/test/src/options.spec.js
@@ -67,6 +67,39 @@ describe("options", () => {
});
});
+ describe("hasBeenSet property", () => {
+ it("should have hasBeenSet as false if value is not actively set", async () => {
+ config = new Config();
+ option = config.addOption({
+ name: "fooOption",
+ type: "string",
+ default: "default-str",
+ });
+ expect(option.hasBeenSet).toEqual(false);
+ await config.load();
+ expect(option.hasBeenSet).toEqual(false);
+ expect(option.value).toEqual("default-str");
+ option.set("foo");
+ expect(option.hasBeenSet).toEqual(true);
+ expect(option.value).toEqual("foo");
+ });
+
+ it("should have hasBeenSet as true if value is actively set", async () => {
+ config = new Config();
+ option = config.addOption({
+ name: "fooOption",
+ type: "string",
+ default: "default-str",
+ });
+ expect(option.hasBeenSet).toEqual(false);
+ await config.load({
+ fooOption: "new-str",
+ });
+ expect(option.hasBeenSet).toEqual(true);
+ expect(option.value).toEqual("new-str");
+ });
+ });
+
describe("config value getter", () => {
it("should return namespaces and options values", async () => {
config = new Config();
diff --git a/packages/config/test/src/programmatic.spec.js b/packages/config/test/src/programmatic.spec.js
index 8b9342f5e..a775731fd 100644
--- a/packages/config/test/src/programmatic.spec.js
+++ b/packages/config/test/src/programmatic.spec.js
@@ -72,6 +72,13 @@ describe("programmatic", () => {
expect(option.value).toEqual("foo-value-2");
});
+ it("hasBeenSet property should be true", async () => {
+ await config.init({
+ fooNamespace: { fooOption: "foo-value-2" },
+ });
+ expect(option.hasBeenSet).toEqual(true);
+ });
+
it("should return value in programmaticLoadedValues getter", async () => {
await config.init({
fooNamespace: { fooOption: "foo-value-2" },
@@ -83,13 +90,20 @@ describe("programmatic", () => {
});
});
- it("option should get value from it when calling to start", async () => {
+ it("option should get value from it when calling to load", async () => {
await config.load({
fooNamespace: { fooOption: "foo-value-2" },
});
expect(option.value).toEqual("foo-value-2");
});
+ it("hasBeenSet property should be true when calling to load", async () => {
+ await config.load({
+ fooNamespace: { fooOption: "foo-value-2" },
+ });
+ expect(option.hasBeenSet).toEqual(true);
+ });
+
it("option should have cloned value", async () => {
config = new Config({ moduleName: "testObjectClone" });
namespace = config.addNamespace("fooNamespace");
@@ -170,6 +184,11 @@ describe("programmatic", () => {
await config.init({});
expect(option.value).toEqual("default-str");
});
+
+ it("hasBeenSet property should return false", async () => {
+ await config.init({});
+ expect(option.hasBeenSet).toEqual(false);
+ });
});
describe("when programmatic config and namespace are provided but option is undefined", () => {
@@ -183,5 +202,12 @@ describe("programmatic", () => {
});
expect(option.value).toEqual("default-str");
});
+
+ it("hasBeenSet property should return false", async () => {
+ await config.init({
+ fooNamespace: {},
+ });
+ expect(option.hasBeenSet).toEqual(false);
+ });
});
});
diff --git a/packages/config/test/src/set.spec.js b/packages/config/test/src/set.spec.js
index 5d1807011..c15580d8d 100644
--- a/packages/config/test/src/set.spec.js
+++ b/packages/config/test/src/set.spec.js
@@ -83,6 +83,67 @@ describe("set method", () => {
]);
});
+ it("should set only defined options", async () => {
+ config = new Config();
+ config.addOptions([
+ {
+ name: "fooOption",
+ type: "string",
+ default: "default-str",
+ },
+ {
+ name: "fooOption2",
+ type: "number",
+ default: 2,
+ },
+ ]);
+ namespace = config.addNamespace("fooNamespace");
+ namespace.addOption({
+ name: "foo",
+ type: "boolean",
+ default: false,
+ });
+ namespace.addOption({
+ name: "foo2",
+ type: "boolean",
+ default: true,
+ });
+ await config.init();
+ config.set({
+ config: {
+ allowUnknownArguments: false,
+ },
+ fooOption: "foo",
+ fooNamespace: {
+ foo: true,
+ },
+ });
+ expect(config.value).toEqual({
+ config: {
+ allowUnknownArguments: false,
+ fileSearchPlaces: undefined,
+ readArguments: true,
+ readEnvironment: true,
+ readFile: true,
+ },
+ fooOption: "foo",
+ fooOption2: 2,
+ fooNamespace: {
+ foo: true,
+ foo2: true,
+ },
+ });
+
+ expect(config.option("fooOption").value).toEqual("foo");
+ expect(config.option("fooOption").hasBeenSet).toEqual(true);
+ expect(config.option("fooOption2").value).toEqual(2);
+ expect(config.option("fooOption2").hasBeenSet).toEqual(false);
+ expect(config.namespace("fooNamespace").option("foo").value).toEqual(true);
+ expect(config.namespace("fooNamespace").option("foo").hasBeenSet).toEqual(true);
+ expect(config.namespace("fooNamespace").option("foo2").value).toEqual(true);
+ expect(config.namespace("fooNamespace").option("foo2").hasBeenSet).toEqual(false);
+ });
+
it("should change namespaces and options values when using value setter", async () => {
config = new Config();
config.addOptions([
diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md
index b958c58f7..b1702a493 100644
--- a/packages/core/CHANGELOG.md
+++ b/packages/core/CHANGELOG.md
@@ -10,6 +10,39 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
### Removed
+## [3.6.0] - 2022-07-22
+
+### Added
+
+- feat(#334): Expose new `core.mock` API
+- feat(#334): Add new option `mock.routes.delay`. Deprecate `mocks.delay`
+- feat(#334): Add new option `mock.collections.selected`. Deprecate `mocks.selected`
+- feat(#334): Support `type` and `options` properties in variants
+- feat(#334): Support `routes` and `routeVariants` properties in collections. Deprecate `routesVariants`
+- feat: Add `core.version` getter
+- feat: Add `files.enabled` option
+
+### Changed
+- refactor(#334): Reorganize files and folders
+- feat(#334): Deprecate `core.restartServer`, `core.addRouter` and `core.removeRouter` methods. Add alerts when used. `core.server` methods must be used instead.
+- feat(#334): Deprecate `core.addRoutesHandler` method. Add alerts when used. `core.variantHandlers.register` method must be used instead.
+- feat(#334): Deprecate `routesHandlers` option. `variantHandlers.register` option must be used instead.
+- feat(#334): Deprecate `core.mocks.restoreRoutesVariants` method. `core.mock.restoreRouteVariants` method must be used instead.
+- feat(#334): Deprecate `core.mocks.customRoutesVariants` method. `core.mock.customRouteVariants` method must be used instead.
+- feat(#334): Deprecate `core.onChangeMocks` method. `core.mock.onChange` method must be used instead.
+- feat(#334): Deprecate `core.loadMocks` method. `core.mock.createLoaders` method must be used instead.
+- feat(#334): Deprecate `core.loadRoutes` method. `core.mock.createLoaders` method must be used instead.
+- feat(#334): Deprecate `core.mocks.plainRoutes` getter. `core.mock.routes.plain` getter must be used instead.
+- feat(#334): Deprecate `core.mocks.plainRoutesVariants` getter. `core.mock.routes.plainVariants` getter must be used instead. The format of items has changed in the new getter.
+- feat(#334): Deprecate `core.mocks.current` getter. `core.mock.collections.selected` getter must be used instead.
+- feat(#334): Deprecate `core.mocks.current` setter. `core.mock.collections.select` method must be used instead.
+- feat(#334): Deprecate `core.mocks.ids` getter. `core.mock.collections.ids` getter must be used instead.
+- feat(#334): Deprecate `core.mocks.plainMocks` getter. `core.mock.collections.plain` getter must be used instead. The format of items has changed in the new getter.
+- feat(#334): Deprecate `core.onChangeAlerts` method. `core.alerts.root.onChange` method must be used instead.
+- feat(#334): Deprecate `core.logs` getter. `core.logger.globalStore` getter must be used instead.
+- feat(#334): Deprecate `core.onChangeLogs` method. `core.logger.onChangeGlobalStore` method must be used instead.
+- feat(#334): Deprecate `core.alerts` when used out of plugins, because it is a getter returning a flat collection of alerts. In next major version, it will return the alerts API.
+
## [3.5.0] - 2022-07-05
### Added
diff --git a/packages/core/README.md b/packages/core/README.md
index 445255133..ba183d7ec 100644
--- a/packages/core/README.md
+++ b/packages/core/README.md
@@ -15,18 +15,16 @@
This package provides the plugabble core of the [Mocks Server][website-url] project.
-Use it if you want to start Mocks Server programmatically by your own, or even create your own Mocks Server distribution with the plugins of your choice. If this is not the case, you would probably prefer using the [main distribution of the Mocks Server project][main-url].
+Use it if you want to [start Mocks Server programmatically by yourself](https://www.mocks-server.org/docs/api/javascript), or even [create your own Mocks Server distribution](https://www.mocks-server.org/docs/integrations/javascript) with the plugins of your choice. If this is not the case, you would probably prefer using the [main distribution of the Mocks Server project][main-url].
## Documentation
Please refer to the [project documentation website][website-url]:
-* [Get started](https://www.mocks-server.org/docs/get-started-intro)
-* [Guides](https://www.mocks-server.org/docs/guides-organizing-files)
-* [Configuration](https://www.mocks-server.org/docs/configuration-options)
-* [Plugins](https://www.mocks-server.org/docs/plugins-adding-plugins)
-* [Integrations](https://www.mocks-server.org/docs/integrations-cypress)
-* [API](https://www.mocks-server.org/docs/api-mocks-server-api)
+* [Overview](https://www.mocks-server.org/docs/overview)
+* [Usage](https://www.mocks-server.org/docs/usage/basics)
+* [Configuration](https://www.mocks-server.org/docs/configuration/how-to-change-settings)
+* [API](https://www.mocks-server.org/docs/api/javascript)
[website-url]: https://www.mocks-server.org
[logo-url]: https://www.mocks-server.org/img/logo_120.png
diff --git a/packages/core/jest.config.js b/packages/core/jest.config.js
index d67ec1e8d..52d8f667f 100644
--- a/packages/core/jest.config.js
+++ b/packages/core/jest.config.js
@@ -26,7 +26,7 @@ module.exports = {
// The glob patterns Jest uses to detect test files
testMatch: ["/test/**/*.spec.js"],
- // testMatch: ["/test/**/mocks/helpers.spec.js"],
+ // testMatch: ["/test/**/FilesLoaders.spec.js"],
// The test environment that will be used for testing
testEnvironment: "node",
diff --git a/packages/core/package.json b/packages/core/package.json
index 3b9522429..16b20bfb9 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,6 +1,6 @@
{
"name": "@mocks-server/core",
- "version": "3.5.0",
+ "version": "3.6.0",
"description": "Pluggable mock server supporting multiple route variants and mocks",
"keywords": [
"mocks",
@@ -51,14 +51,14 @@
"express": "4.18.1",
"express-request-id": "1.4.1",
"fs-extra": "10.1.0",
- "globule": "1.3.3",
+ "globule": "1.3.4",
"handlebars": "4.7.7",
"is-promise": "4.0.0",
"lodash": "4.17.21",
"node-watch": "0.7.3",
"update-notifier": "5.1.0",
"winston": "3.7.2",
- "winston-array-transport": "1.1.9"
+ "winston-array-transport": "1.1.10"
},
"engines": {
"node": ">=14.x"
diff --git a/packages/core/sonar-project.properties b/packages/core/sonar-project.properties
index d2fffa787..ecc435602 100644
--- a/packages/core/sonar-project.properties
+++ b/packages/core/sonar-project.properties
@@ -1,7 +1,7 @@
sonar.organization=mocks-server
sonar.projectKey=mocks-server_main_core
sonar.projectName=core
-sonar.projectVersion=3.5.0
+sonar.projectVersion=3.6.0
sonar.javascript.file.suffixes=.js
sonar.sourceEncoding=UTF-8
diff --git a/packages/core/src/Core.js b/packages/core/src/Core.js
index 9cf153195..2f54cc461 100644
--- a/packages/core/src/Core.js
+++ b/packages/core/src/Core.js
@@ -8,25 +8,26 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
-const deepMerge = require("deepmerge");
const EventEmitter = require("events");
+const deepMerge = require("deepmerge");
const Config = require("@mocks-server/config");
const { Logger } = require("@mocks-server/logger");
-const { CHANGE_MOCKS, CHANGE_ALERTS, CHANGE_LOGS } = require("./eventNames");
-const tracer = require("./tracer");
-const Loaders = require("./Loaders");
-const AlertsLegacy = require("./AlertsLegacy");
-const RoutesHandlers = require("./routes-handlers/RoutesHandlers");
-const Mocks = require("./mocks/Mocks");
+const tracer = require("./common/legacyTracer");
+const AlertsLegacy = require("./alerts/AlertsLegacy");
+const VariantHandlers = require("./variant-handlers/VariantHandlers");
+const Mock = require("./mock/Mock");
const Plugins = require("./plugins/Plugins");
const Server = require("./server/Server");
-const FilesLoader = require("./files-loader/FilesLoader");
+const FilesLoaders = require("./files/FilesLoaders");
const Scaffold = require("./scaffold/Scaffold");
-const Alerts = require("./Alerts");
-const UpdateNotifier = require("./UpdateNotifier");
-const { scopedAlertsMethods, addEventListener, arrayMerge } = require("./support/helpers");
+const Alerts = require("./alerts/Alerts");
+const UpdateNotifier = require("./update-notifier/UpdateNotifier");
+const { scopedAlertsMethods } = require("./alerts/legacyHelpers");
+const { addEventListener, CHANGE_MOCK, CHANGE_ALERTS, CHANGE_LOGS } = require("./common/events");
+const { arrayMerge, deprecatedMessage } = require("./common/helpers");
+const { version } = require("../package.json");
const MODULE_NAME = "mocks";
@@ -38,7 +39,7 @@ const ROOT_OPTIONS = [
default: "info",
},
{
- description: "Array of RouteHandlers to be added",
+ description: "Array of VariantHandlers to be added. Legacy",
name: "routesHandlers",
type: "array",
default: [],
@@ -55,6 +56,8 @@ class Core {
// Create logger
this._logger = new Logger();
this._configLogger = this._logger.namespace("config");
+
+ // LEGACY, to be removed
this._logger.onChangeGlobalStore(() => {
this._eventEmitter.emit(CHANGE_LOGS);
});
@@ -62,11 +65,14 @@ class Core {
// Create config
this._config = new Config({ moduleName: MODULE_NAME });
this._configPlugins = this._config.addNamespace(Plugins.id);
- this._configMocks = this._config.addNamespace(Mocks.id);
+ this._configMock = this._config.addNamespace(Mock.id);
this._configServer = this._config.addNamespace(Server.id);
- this._configFilesLoader = this._config.addNamespace(FilesLoader.id);
+ this._configFilesLoaders = this._config.addNamespace(FilesLoaders.id);
- [this._logOption, this._routesHandlersOption] = this._config.addOptions(ROOT_OPTIONS);
+ // LEGACY, to be removed
+ this._configMocksLegacy = this._config.addNamespace(Mock.legacyId);
+
+ [this._logOption, this._variantHandlersOption] = this._config.addOptions(ROOT_OPTIONS);
this._logOption.onChange((level) => {
this._logger.setLevel(level);
});
@@ -93,28 +99,29 @@ class Core {
pkg: advancedOptions.pkg,
});
- // Create mocks loaders
- this._mocksLoaders = new Loaders({
- onLoad: () => {
- this._loadedMocks = true;
- if (this._loadedRoutes) {
- this._mocks.load();
- }
- },
+ // Create variant handlers
+ this._variantHandlers = new VariantHandlers({
+ logger: this._logger.namespace(VariantHandlers.id),
+ config: this._config.addNamespace(VariantHandlers.id),
});
- // Create routes loaders
- this._routesLoaders = new Loaders({
- onLoad: () => {
- this._loadedRoutes = true;
- if (this._loadedMocks) {
- this._mocks.load();
- }
+ // Create mock
+ this._mock = new Mock(
+ {
+ config: this._configMock,
+ alerts: this._alerts.collection(Mock.id),
+ logger: this._logger.namespace(Mock.id),
+ // LEGACY, to be removed
+ legacyConfig: this._configMocksLegacy,
+ onChange: () => this._eventEmitter.emit(CHANGE_MOCK),
},
- });
+ this // To be used only by routeHandlers
+ );
- this._loadMocks = this._mocksLoaders.new();
- this._loadRoutes = this._routesLoaders.new();
+ // LEGACY, to be removed
+ const loaders = this._mock.createLoaders();
+ this._loadCollections = loaders.loadCollections;
+ this._loadRoutes = loaders.loadRoutes;
// Create plugins
this._plugins = new Plugins(
@@ -122,11 +129,36 @@ class Core {
config: this._configPlugins,
alerts: this._alerts.collection(Plugins.id),
logger: this._logger.namespace(Plugins.id),
- createMocksLoader: () => {
- return this._mocksLoaders.new();
+ // LEGACY, to be removed
+ createCollectionsLoader: () => {
+ const { loadCollections } = this._mock.createLoaders();
+ return (collections) => {
+ this._deprecationAlerts.set(
+ "loadMocks",
+ deprecatedMessage(
+ "method",
+ "core.loadMocks",
+ "core.mock.createLoaders",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ return loadCollections(collections);
+ };
},
createRoutesLoader: () => {
- return this._routesLoaders.new();
+ const { loadRoutes } = this._mock.createLoaders();
+ return (routes) => {
+ this._deprecationAlerts.set(
+ "loadRoutes",
+ deprecatedMessage(
+ "method",
+ "core.loadRoutes",
+ "core.mock.createLoaders",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ return loadRoutes(routes);
+ };
},
// LEGACY, remove when legacy alerts are removed
...scopedAlertsMethods(
@@ -139,39 +171,23 @@ class Core {
this //To be used only by plugins
);
- // Create routes handlers
- this._routesHandlers = new RoutesHandlers({
- logger: this._logger.namespace("routesHandlers"),
- });
-
- // Create mocks
- this._mocks = new Mocks(
- {
- config: this._configMocks,
- alerts: this._alerts.collection(Mocks.id),
- logger: this._logger.namespace(Mocks.id),
- getLoadedMocks: () => this._mocksLoaders.contents,
- getLoadedRoutes: () => this._routesLoaders.contents,
- onChange: () => this._eventEmitter.emit(CHANGE_MOCKS),
- },
- this // To be used only by routeHandlers
- );
-
// Create server
this._server = new Server({
config: this._configServer,
logger: this._logger.namespace(Server.id),
alerts: this._alerts.collection(Server.id),
- mocksRouter: this._mocks.router,
+ routesRouter: this._mock.router,
});
+ const fileLoaders = this._mock.createLoaders();
+
// Create files loaders
- this._filesLoader = new FilesLoader({
- config: this._configFilesLoader,
- logger: this._logger.namespace(FilesLoader.id),
- alerts: this._alerts.collection(FilesLoader.id),
- loadMocks: this._mocksLoaders.new(),
- loadRoutes: this._routesLoaders.new(),
+ this._filesLoader = new FilesLoaders({
+ config: this._configFilesLoaders,
+ logger: this._logger.namespace(FilesLoaders.id),
+ alerts: this._alerts.collection(FilesLoaders.id),
+ loadCollections: fileLoaders.loadCollections,
+ loadRoutes: fileLoaders.loadRoutes,
});
// Create scaffold
@@ -245,8 +261,19 @@ class Core {
// Register plugins, let them add their custom config
await this._plugins.register();
- // Register routes handlers
- await this._routesHandlers.register(this._routesHandlersOption.value);
+ if (this._variantHandlersOption.hasBeenSet) {
+ this._deprecationAlerts.set(
+ "routesHandlers",
+ deprecatedMessage(
+ "option",
+ "routesHandlers",
+ "variantHandlers.register",
+ "configuration/migrating-from-v3#options"
+ )
+ );
+ }
+
+ await this._variantHandlers.registerConfig(this._variantHandlersOption.value);
await this._scaffold.init({
filesLoaderPath: this._filesLoader.path,
@@ -255,7 +282,7 @@ class Core {
await this._loadConfig();
// Config is ready, init all
- this._mocks.init(this._routesHandlers.handlers);
+ this._mock.init(this._variantHandlers.handlers);
await this._server.init();
await this._filesLoader.init();
return this._plugins.init();
@@ -274,72 +301,190 @@ class Core {
return this._stopPlugins();
}
- addRoutesHandler(RoutesHandler) {
- this._routesHandlers.add(RoutesHandler);
+ // LEGACY, to be removed
+ addRoutesHandler(VariantHandler) {
+ this._deprecationAlerts.set(
+ "addRoutesHandler",
+ deprecatedMessage(
+ "method",
+ "core.addRoutesHandler",
+ "core.variantHandlers.register",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ this._variantHandlers.register([VariantHandler]);
}
- loadMocks(mocks) {
- this._loadMocks(mocks);
+ // LEGACY, to be removed
+ loadMocks(collections) {
+ this._deprecationAlerts.set(
+ "loadMocks",
+ deprecatedMessage(
+ "method",
+ "core.loadMocks",
+ "core.mock.createLoaders",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ this._loadCollections(collections);
}
+ // LEGACY, to be removed
loadRoutes(routes) {
+ this._deprecationAlerts.set(
+ "loadRoutes",
+ deprecatedMessage(
+ "method",
+ "core.loadRoutes",
+ "core.mock.createLoaders",
+ "releases/migrating-from-v3#api"
+ )
+ );
this._loadRoutes(routes);
}
// Listeners
+ // LEGACY, to be removed
onChangeMocks(listener) {
- return addEventListener(listener, CHANGE_MOCKS, this._eventEmitter);
+ this._deprecationAlerts.set(
+ "onChangeMocks",
+ deprecatedMessage(
+ "method",
+ "core.onChangeMocks",
+ "core.mock.onChange",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ return addEventListener(listener, CHANGE_MOCK, this._eventEmitter);
}
+ // LEGACY, to be removed
onChangeAlerts(listener) {
+ this._deprecationAlerts.set(
+ "onChangeAlerts",
+ deprecatedMessage(
+ "method",
+ "core.onChangeAlerts",
+ "core.alerts.root.onChange",
+ "releases/migrating-from-v3#api"
+ )
+ );
return addEventListener(listener, CHANGE_ALERTS, this._eventEmitter);
}
+ // LEGACY, to be removed
onChangeLogs(listener) {
+ this._deprecationAlerts.set(
+ "onChangeLogs",
+ deprecatedMessage(
+ "method",
+ "core.onChangeLogs",
+ "core.logger.onChangeGlobalStore",
+ "releases/migrating-from-v3#api"
+ )
+ );
return addEventListener(listener, CHANGE_LOGS, this._eventEmitter);
}
// Expose Server methods and getters
+ // LEGACY, to be removed
restartServer() {
+ this._deprecationAlerts.set(
+ "restartServer",
+ deprecatedMessage(
+ "method",
+ "core.restartServer",
+ "core.server.restart",
+ "releases/migrating-from-v3#api"
+ )
+ );
return this._server.restart();
}
+ // LEGACY, to be removed
addRouter(path, router) {
- return this._server.addCustomRouter(path, router);
+ this._deprecationAlerts.set(
+ "addRouter",
+ deprecatedMessage(
+ "method",
+ "core.addRouter",
+ "core.server.addRouter",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ return this._server.addRouter(path, router);
}
+ // LEGACY, to be removed
removeRouter(path, router) {
- return this._server.removeCustomRouter(path, router);
+ this._deprecationAlerts.set(
+ "removeRouter",
+ deprecatedMessage(
+ "method",
+ "core.removeRouter",
+ "core.server.removeRouter",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ return this._server.removeRouter(path, router);
}
- // Expose child objects
-
// LEGACY, change by whole alerts object in next major version
get alerts() {
+ this._deprecationAlerts.set(
+ "alerts",
+ deprecatedMessage(
+ "method",
+ "core.alerts",
+ "core.alertsApi",
+ "releases/migrating-from-v3#api"
+ )
+ );
return this._alerts.customFlat;
}
// Provides access to alerts API while alerts legacy is maintained
+ // LEGACY, to be removed
get alertsApi() {
return this._alerts;
}
+ // LEGACY, to be removed
get mocks() {
- return this._mocks;
+ this._deprecationAlerts.set(
+ "mocks",
+ deprecatedMessage("getter", "core.mocks", "core.mock", "releases/migrating-from-v3#api")
+ );
+ return this._mock;
}
// LEGACY, to be removed
get tracer() {
this._deprecationAlerts.set(
"tracer",
- "Usage of tracer is deprecated. Use logger instead: https://www.mocks-server.org/docs/next/guides-migrating-from-v3#logger"
+ deprecatedMessage(
+ "object",
+ "core.tracer",
+ "core.logger",
+ "releases/migrating-from-v3#logger"
+ )
);
return tracer;
}
+ // LEGACY, to be removed
get logs() {
+ this._deprecationAlerts.set(
+ "logs",
+ deprecatedMessage(
+ "getter",
+ "core.logs",
+ "core.logger.globalStore",
+ "releases/migrating-from-v3#logger"
+ )
+ );
return this._logger.globalStore;
}
@@ -350,6 +495,22 @@ class Core {
get config() {
return this._config;
}
+
+ get server() {
+ return this._server;
+ }
+
+ get mock() {
+ return this._mock;
+ }
+
+ get variantHandlers() {
+ return this._variantHandlers;
+ }
+
+ get version() {
+ return version;
+ }
}
module.exports = Core;
diff --git a/packages/core/src/Alerts.js b/packages/core/src/alerts/Alerts.js
similarity index 89%
rename from packages/core/src/Alerts.js
rename to packages/core/src/alerts/Alerts.js
index 39752aafd..e8b75ffa7 100644
--- a/packages/core/src/Alerts.js
+++ b/packages/core/src/alerts/Alerts.js
@@ -32,9 +32,9 @@ class Alerts extends NestedCollections {
return super.remove(id);
}
- // LEGACY, to be removed in next major version
+ // LEGACY, to be changed by flat in next major version
get customFlat() {
- return this.flat.map((item) => {
+ return this._flat.map((item) => {
let context = item.collection;
let sep = ":";
if (context.startsWith("alerts:")) {
@@ -44,9 +44,12 @@ class Alerts extends NestedCollections {
sep = "";
}
+ const id = `${context}${sep}${item.id}`;
+
return {
...item.value,
- context: `${context}${sep}${item.id}`,
+ id,
+ context: id,
};
});
}
diff --git a/packages/core/src/AlertsLegacy.js b/packages/core/src/alerts/AlertsLegacy.js
similarity index 86%
rename from packages/core/src/AlertsLegacy.js
rename to packages/core/src/alerts/AlertsLegacy.js
index 600f55d07..702eb8679 100644
--- a/packages/core/src/AlertsLegacy.js
+++ b/packages/core/src/alerts/AlertsLegacy.js
@@ -8,6 +8,8 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
+const { deprecatedMessage } = require("../common/helpers");
+
// LEGACY, remove when legacy alerts are removed
class AlertsLegacy {
constructor({ alerts, logger }) {
@@ -22,7 +24,7 @@ class AlertsLegacy {
add(context, message, error) {
this._deprecatedAlerts.set(
"addAlert",
- `Detected usage of deprecated method 'addAlert'. Use alerts instead: https://www.mocks-server.org/docs/api-mocks-server-api#alerts`
+ deprecatedMessage("method", "addAlert", "alerts", "api/core/alerts")
);
const collectionIds = context.split(":");
const alertId = collectionIds.pop();
@@ -35,9 +37,9 @@ class AlertsLegacy {
remove(context) {
this._deprecatedAlerts.set(
"removeAlert",
- `Detected usage of deprecated method 'removeAlerts'. Use alerts instead: https://www.mocks-server.org/docs/api-mocks-server-api#alerts`
+ deprecatedMessage("method", "removeAlert", "alerts", "api/core/alerts")
);
- this._logger.silly(`Removing alerts with context "${context}"`);
+ this._logger.silly(`Removing alerts with context '${context}'`);
// Clean collection with whole context
const collectionIds = context.split(":");
const contextCollection = collectionIds.reduce((currentCollection, collectionId) => {
@@ -54,7 +56,7 @@ class AlertsLegacy {
}
rename(oldContext, newContext) {
- this._logger.silly(`Renaming alerts with context "${oldContext}" to context "${newContext}"`);
+ this._logger.silly(`Renaming alerts with context '${oldContext}' to context '${newContext}'`);
const collectionIds = oldContext.split(":");
const newCollectionsIds = newContext.split(":");
collectionIds.reduce((currentCollection, collectionId, currentIndex) => {
diff --git a/packages/core/src/support/helpers.js b/packages/core/src/alerts/legacyHelpers.js
similarity index 88%
rename from packages/core/src/support/helpers.js
rename to packages/core/src/alerts/legacyHelpers.js
index 1b17ea898..6ec3a598d 100644
--- a/packages/core/src/support/helpers.js
+++ b/packages/core/src/alerts/legacyHelpers.js
@@ -1,5 +1,5 @@
/*
-Copyright 2021 Javier Brea
+Copyright 2021-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -88,20 +88,6 @@ function scopedAlertsMethods(
};
}
-function addEventListener(listener, eventName, eventEmitter) {
- const removeCallback = () => {
- eventEmitter.removeListener(eventName, listener);
- };
- eventEmitter.on(eventName, listener);
- return removeCallback;
-}
-
-function arrayMerge(_destinationArray, sourceArray) {
- return sourceArray;
-}
-
module.exports = {
scopedAlertsMethods,
- addEventListener,
- arrayMerge,
};
diff --git a/packages/core/src/CustomCore.js b/packages/core/src/common/CoreApi.js
similarity index 66%
rename from packages/core/src/CustomCore.js
rename to packages/core/src/common/CoreApi.js
index b6154ab1f..c40bf781b 100644
--- a/packages/core/src/CustomCore.js
+++ b/packages/core/src/common/CoreApi.js
@@ -1,14 +1,25 @@
+const { docsUrl } = require("./helpers");
+
const CORE_METHODS = [
"start",
"stop",
+ // LEGACY, to be removed
"addRoutesHandler",
+ // LEGACY, to be removed
"onChangeMocks",
+ // LEGACY, to be removed
"onChangeAlerts",
+ // LEGACY, to be removed
"onChangeLogs",
+ // LEGACY, to be removed
"restartServer",
+ // LEGACY, to be removed
"addRouter",
+ // LEGACY, to be removed
"removeRouter",
+ // LEGACY, to be removed
"loadMocks",
+ // LEGACY, to be removed
"loadRoutes",
];
@@ -18,7 +29,7 @@ function cloneMethods(origin, dest) {
});
}
-class CustomCore {
+class CoreApi {
constructor({
core,
loadMocks,
@@ -61,19 +72,24 @@ class CustomCore {
// TODO, add link to releases URL.
this._deprecationAlerts.set(
"core",
- "Usage of core property is deprecated. Use properties at first level instead: https://www.mocks-server.org/docs/next/guides-migrating-from-v3#plugins"
+ `Usage of core property is deprecated. Use properties at first level instead: ${docsUrl(
+ "releases/migrating-from-v3#plugins"
+ )}`
);
return this._core;
}
+ // LEGACY, to be removed
get mocks() {
return this._core.mocks;
}
+ // LEGACY, to be removed
get tracer() {
return this._core.tracer;
}
+ // LEGACY, to be removed
get logs() {
return this._core.logs;
}
@@ -89,6 +105,22 @@ class CustomCore {
get logger() {
return this._logger;
}
+
+ get server() {
+ return this._core.server;
+ }
+
+ get mock() {
+ return this._core.mock;
+ }
+
+ get variantHandlers() {
+ return this._core.variantHandlers;
+ }
+
+ get version() {
+ return this._core.version;
+ }
}
-module.exports = CustomCore;
+module.exports = CoreApi;
diff --git a/packages/core/src/eventNames.js b/packages/core/src/common/events.js
similarity index 66%
rename from packages/core/src/eventNames.js
rename to packages/core/src/common/events.js
index 4323b5cc6..5e4c6d063 100644
--- a/packages/core/src/eventNames.js
+++ b/packages/core/src/common/events.js
@@ -1,5 +1,5 @@
/*
-Copyright 2019-2022 Javier Brea
+Copyright 2021-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -8,8 +8,17 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
+function addEventListener(listener, eventName, eventEmitter) {
+ const removeCallback = () => {
+ eventEmitter.removeListener(eventName, listener);
+ };
+ eventEmitter.on(eventName, listener);
+ return removeCallback;
+}
+
module.exports = {
- CHANGE_MOCKS: "change:mocks",
+ CHANGE_MOCK: "change:mock",
CHANGE_ALERTS: "change:alerts",
CHANGE_LOGS: "change:logs",
+ addEventListener,
};
diff --git a/packages/core/src/common/helpers.js b/packages/core/src/common/helpers.js
new file mode 100644
index 000000000..adb5d5825
--- /dev/null
+++ b/packages/core/src/common/helpers.js
@@ -0,0 +1,27 @@
+/*
+Copyright 2021-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+function arrayMerge(_destinationArray, sourceArray) {
+ return sourceArray;
+}
+
+function docsUrl(url) {
+ return `https://www.mocks-server.org/docs/${url}`;
+}
+
+function deprecatedMessage(type, oldName, newName, url) {
+ return `Usage of '${oldName}' ${type} is deprecated. Use '${newName}' instead: ${docsUrl(url)}`;
+}
+
+module.exports = {
+ arrayMerge,
+ deprecatedMessage,
+ docsUrl,
+};
diff --git a/packages/core/src/tracer.js b/packages/core/src/common/legacyTracer.js
similarity index 100%
rename from packages/core/src/tracer.js
rename to packages/core/src/common/legacyTracer.js
diff --git a/packages/core/src/files-loader/FilesLoader.js b/packages/core/src/files/FilesLoaders.js
similarity index 73%
rename from packages/core/src/files-loader/FilesLoader.js
rename to packages/core/src/files/FilesLoaders.js
index a7fe8ed36..b07d6e71e 100644
--- a/packages/core/src/files-loader/FilesLoader.js
+++ b/packages/core/src/files/FilesLoaders.js
@@ -16,7 +16,7 @@ const fsExtra = require("fs-extra");
const { map, debounce, flatten } = require("lodash");
const {
- mocksFileToUse,
+ collectionsFileToUse,
babelRegisterDefaultOptions,
getFilesGlobule,
validateFileContent,
@@ -25,9 +25,15 @@ const {
const ROUTES_FOLDER = "routes";
const OPTIONS = [
+ {
+ name: "enabled",
+ description: "Allows to disable files load",
+ type: "boolean",
+ default: true,
+ },
{
name: "path",
- description: "Define folder from where to load mocks",
+ description: "Define folder from where to load collections and routes",
type: "string",
default: "mocks",
},
@@ -56,24 +62,25 @@ const BABEL_REGISTER_OPTIONS = [
},
];
-class FilesLoaderBase {
+class FilesLoaders {
static get id() {
return "files";
}
- constructor({ config, loadMocks, logger, loadRoutes, alerts }, extraOptions = {}) {
+ constructor({ config, loadCollections, logger, loadRoutes, alerts }, extraOptions = {}) {
this._logger = logger;
- this._loadMocks = loadMocks;
+ this._loadCollections = loadCollections;
this._loadRoutes = loadRoutes;
this._alerts = alerts;
- this._mocksAlerts = alerts.collection("mocks");
+ this._deprecationAlerts = alerts.collection("deprecated");
+ this._collectionsAlerts = alerts.collection("collections");
this._routesAlerts = alerts.collection("routes");
this._routesFilesAlerts = this._routesAlerts.collection("file");
this._customRequireCache = extraOptions.requireCache;
this._require = extraOptions.require || require;
this._config = config;
- [this._pathOption, this._watchOption] = this._config.addOptions(OPTIONS);
+ [this._enabledOption, this._pathOption, this._watchOption] = this._config.addOptions(OPTIONS);
[this._babelRegisterOption, this._babelRegisterOptionsOption] = this._config
.addNamespace(BABEL_REGISTER_NAMESPACE)
.addOptions(BABEL_REGISTER_OPTIONS);
@@ -82,8 +89,11 @@ class FilesLoaderBase {
}
init() {
+ this._enabled = this._enabledOption.value;
try {
- this._loadFiles();
+ if (this._enabled) {
+ this._loadFiles();
+ }
return Promise.resolve();
} catch (err) {
return Promise.reject(err);
@@ -91,11 +101,13 @@ class FilesLoaderBase {
}
start() {
- this._switchWatch();
+ if (this._enabled) {
+ this._switchWatch();
+ }
}
stop() {
- if (this._watcher) {
+ if (this._enabled && this._watcher) {
this._logger.debug("Stopping files watch");
this._watcher.close();
}
@@ -143,7 +155,7 @@ class FilesLoaderBase {
_ensurePath() {
if (!fsExtra.existsSync(this._path)) {
- this._alerts.set("folder", `Created folder "${this._path}"`);
+ this._alerts.set("folder", `Created folder '${this._path}'`);
fsExtra.ensureDirSync(this._path);
}
}
@@ -159,7 +171,7 @@ class FilesLoaderBase {
}
this._cleanRequireCacheFolder();
this._loadRoutesFiles();
- this._loadMocksFile();
+ this._loadCollectionsFile();
}
_loadRoutesFiles() {
@@ -198,29 +210,47 @@ class FilesLoaderBase {
}
}
- _loadMocksFile() {
- let mocksFile = mocksFileToUse(
+ _loadCollectionsFile() {
+ let collectionsFile = collectionsFileToUse(
this._path,
this._babelRegisterOption.value,
this._babelRegisterOptionsOption.value
);
- if (mocksFile) {
+
+ if (collectionsFile) {
+ const fileName = path.basename(collectionsFile);
+ // LEGACY, to be removed
+ if (fileName.startsWith("mocks")) {
+ this._deprecationAlerts.set(
+ "mocks",
+ `Defining collections in '${fileName}' file is deprecated. Please rename it to '${fileName.replace(
+ "mocks",
+ "collections"
+ )}'`
+ );
+ } else {
+ this._deprecationAlerts.remove("mocks");
+ }
try {
- const mocks = this._readFile(mocksFile);
- const fileErrors = validateFileContent(mocks);
+ const collections = this._readFile(collectionsFile);
+ const fileErrors = validateFileContent(collections);
if (!!fileErrors) {
throw new Error(fileErrors);
}
- this._loadMocks(mocks);
- this._logger.silly(`Loaded mocks from file ${mocksFile}`);
- this._mocksAlerts.clean();
+ this._loadCollections(collections);
+ this._logger.silly(`Loaded collections from file ${collectionsFile}`);
+ this._collectionsAlerts.clean();
} catch (error) {
- this._loadMocks([]);
- this._mocksAlerts.set("error", `Error loading mocks from file ${mocksFile}`, error);
+ this._loadCollections([]);
+ this._collectionsAlerts.set(
+ "error",
+ `Error loading collections from file ${collectionsFile}`,
+ error
+ );
}
} else {
- this._loadMocks([]);
- this._mocksAlerts.set("not-found", `No mocks file was found in ${this._path}`);
+ this._loadCollections([]);
+ this._collectionsAlerts.set("not-found", `No collections file was found in ${this._path}`);
}
}
@@ -255,4 +285,4 @@ class FilesLoaderBase {
}
}
-module.exports = FilesLoaderBase;
+module.exports = FilesLoaders;
diff --git a/packages/core/src/files-loader/helpers.js b/packages/core/src/files/helpers.js
similarity index 62%
rename from packages/core/src/files-loader/helpers.js
rename to packages/core/src/files/helpers.js
index 456d43643..199827149 100644
--- a/packages/core/src/files-loader/helpers.js
+++ b/packages/core/src/files/helpers.js
@@ -12,7 +12,9 @@ const fsExtra = require("fs-extra");
const path = require("path");
// **/*
-const MOCKS_FILE_NAME = "mocks";
+const COLLECTIONS_FILE_NAME = "collections";
+// Legacy, to be removed
+const LEGACY_COLLECTIONS_FILE_NAME = "mocks";
const DEFAULT_EXTENSIONS = [".json", ".js"];
const BABEL_DEFAULT_EXTENSIONS = [".es6", ".es", ".jsx", ".js", ".mjs", ".ts"];
@@ -42,38 +44,61 @@ function getFilesGlobule(babelRegister, babelRegisterOptions) {
return getGlobulePatterns(getFilesExtensions(babelRegister, babelRegisterOptions));
}
-function babelRegisterOnlyFilter(mocksFolder) {
+function babelRegisterOnlyFilter(collectionsFolder) {
return (filePath) => {
- return filePath.indexOf(mocksFolder) === 0;
+ return filePath.indexOf(collectionsFolder) === 0;
};
}
-function babelRegisterDefaultOptions(mocksFolder, babelRegisterOptions) {
+function babelRegisterDefaultOptions(collectionsFolder, babelRegisterOptions) {
return {
- only: [babelRegisterOnlyFilter(mocksFolder)],
+ only: [babelRegisterOnlyFilter(collectionsFolder)],
cache: false,
extensions: BABEL_DEFAULT_EXTENSIONS,
...babelRegisterOptions,
};
}
-function mocksFilePath(mocksFolder, extension) {
- return path.resolve(mocksFolder, `${MOCKS_FILE_NAME}${extension}`);
+function collectionsFilePath(collectionsFolder, extension, fileName) {
+ return path.resolve(collectionsFolder, `${fileName}${extension}`);
}
-function mocksFileToUse(mocksFolder, babelRegister, babelRegisterOptions) {
+function collectionsFileNameToUse(
+ collectionsFolder,
+ babelRegister,
+ babelRegisterOptions,
+ fileName
+) {
const extensions = getFilesExtensions(babelRegister, babelRegisterOptions);
const existentExtension = extensions.find((extension) => {
- return fsExtra.existsSync(mocksFilePath(mocksFolder, extension));
+ return fsExtra.existsSync(collectionsFilePath(collectionsFolder, extension, fileName));
});
if (existentExtension) {
- return mocksFilePath(mocksFolder, existentExtension);
+ return collectionsFilePath(collectionsFolder, existentExtension, fileName);
}
return null;
}
+function collectionsFileToUse(collectionsFolder, babelRegister, babelRegisterOptions) {
+ return (
+ collectionsFileNameToUse(
+ collectionsFolder,
+ babelRegister,
+ babelRegisterOptions,
+ COLLECTIONS_FILE_NAME
+ ) ||
+ // LEGACY, to be removed
+ collectionsFileNameToUse(
+ collectionsFolder,
+ babelRegister,
+ babelRegisterOptions,
+ LEGACY_COLLECTIONS_FILE_NAME
+ )
+ );
+}
+
function validateFileContent(fileContent) {
if (!Array.isArray(fileContent)) {
return "File does not export an array";
@@ -82,7 +107,7 @@ function validateFileContent(fileContent) {
}
module.exports = {
- mocksFileToUse,
+ collectionsFileToUse,
babelRegisterDefaultOptions,
getFilesGlobule,
validateFileContent,
diff --git a/packages/core/src/mocks/Mock.js b/packages/core/src/mock/Collection.js
similarity index 84%
rename from packages/core/src/mocks/Mock.js
rename to packages/core/src/mock/Collection.js
index 761749b8d..b34b12887 100644
--- a/packages/core/src/mocks/Mock.js
+++ b/packages/core/src/mock/Collection.js
@@ -12,28 +12,29 @@ const express = require("express");
const { HTTP_METHODS } = require("./validations");
-class Mock {
- constructor({ id, routesVariants, getDelay, logger }) {
+class Collection {
+ constructor({ id, routeVariants, getDelay, logger }) {
this._logger = logger;
this._id = id;
- this._routesVariants = routesVariants;
+ this._routeVariants = routeVariants;
this._getDelay = getDelay;
this._initRouter();
}
_initRouter() {
this._router = express.Router();
- this._routesVariants.forEach((routeVariant) => {
+ this._routeVariants.forEach((routeVariant) => {
const methods = Array.isArray(routeVariant.method)
? routeVariant.method
: [routeVariant.method];
methods.forEach((method) => {
const httpMethod = HTTP_METHODS[method.toUpperCase()];
+ // TODO, add methods matcher
this._router[httpMethod](routeVariant.url, (req, _res, next) => {
this._logger.info(`Request ${req.method} => ${req.url} | req: ${req.id}`);
const delay = routeVariant.delay !== null ? routeVariant.delay : this._getDelay();
if (delay > 0) {
- this._logger.verbose(`Applying delay of ${delay}ms to route variant "${this._id}"`);
+ this._logger.verbose(`Applying delay of ${delay}ms to route variant '${this._id}'`);
setTimeout(() => {
next();
}, delay);
@@ -46,8 +47,8 @@ class Mock {
});
}
- get routesVariants() {
- return this._routesVariants;
+ get routeVariants() {
+ return this._routeVariants;
}
get id() {
@@ -59,4 +60,4 @@ class Mock {
}
}
-module.exports = Mock;
+module.exports = Collection;
diff --git a/packages/core/src/mock/Collections.js b/packages/core/src/mock/Collections.js
new file mode 100644
index 000000000..190e62fa7
--- /dev/null
+++ b/packages/core/src/mock/Collections.js
@@ -0,0 +1,62 @@
+/*
+Copyright 2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const OPTIONS = [
+ {
+ description: "Selected collection",
+ name: "selected",
+ type: "string",
+ // LEGACY, remove and set value from scaffold when legacy option is removed
+ default: "base",
+ },
+];
+
+class Collections {
+ static get id() {
+ return "collections";
+ }
+
+ constructor({
+ logger,
+ config,
+ onChangeSelected,
+ getIds,
+ getSelectedCollection,
+ getPlainCollections,
+ }) {
+ this._logger = logger;
+ this._config = config;
+ this._onChangeSelected = onChangeSelected;
+ this._getSelectedCollection = getSelectedCollection;
+ this._getPlainCollections = getPlainCollections;
+ this._getIds = getIds;
+
+ [this._selectedOption] = this._config.addOptions(OPTIONS);
+ this._selectedOption.onChange(onChangeSelected);
+ }
+
+ get selected() {
+ return this._getSelectedCollection();
+ }
+
+ get ids() {
+ return this._getIds();
+ }
+
+ get plain() {
+ return this._getPlainCollections();
+ }
+
+ select(collection) {
+ this._selectedOption.value = collection;
+ }
+}
+
+module.exports = Collections;
diff --git a/packages/core/src/Loaders.js b/packages/core/src/mock/Loaders.js
similarity index 100%
rename from packages/core/src/Loaders.js
rename to packages/core/src/mock/Loaders.js
diff --git a/packages/core/src/mock/Mock.js b/packages/core/src/mock/Mock.js
new file mode 100644
index 000000000..c4b01e79d
--- /dev/null
+++ b/packages/core/src/mock/Mock.js
@@ -0,0 +1,507 @@
+/*
+Copyright 2021-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+const EventEmitter = require("events");
+
+const express = require("express");
+
+const { addEventListener, CHANGE_MOCK } = require("../common/events");
+const Loaders = require("./Loaders");
+const Collections = require("./Collections");
+const Routes = require("./Routes");
+const { deprecatedMessage } = require("../common/helpers");
+const {
+ getPlainCollections,
+ getPlainRoutes,
+ getPlainRouteVariants,
+ addCustomVariant,
+ getRouteVariants,
+ getCollections,
+ getCollection,
+ plainCollectionsToLegacy,
+ plainRouteVariantsToLegacy,
+} = require("./helpers");
+const { getIds, compileRouteValidator } = require("./validations");
+
+const LEGACY_OPTIONS = [
+ // LEGACY, to be removed
+ {
+ description: "Selected collection. Legacy",
+ name: "selected",
+ type: "string",
+ extraData: {
+ scaffold: {
+ omit: true,
+ },
+ },
+ },
+ {
+ description: "Global delay to apply to routes. Legacy",
+ name: "delay",
+ type: "number",
+ default: 0,
+ extraData: {
+ scaffold: {
+ omit: true,
+ },
+ },
+ },
+];
+
+const SELECTED_COLLECTION_ID = "selected";
+const EMPTY_ALERT_ID = "empty";
+const LOAD_NAMESPACE = "load";
+
+class Mock {
+ static get id() {
+ return "mock";
+ }
+
+ static get legacyId() {
+ return "mocks";
+ }
+
+ constructor({ config, legacyConfig, logger, onChange, alerts }, core) {
+ this._eventEmitter = new EventEmitter();
+ this._logger = logger;
+
+ this._legacyConfig = legacyConfig;
+ [this._selectedCollectionOptionLegacy, this._currentDelayOptionLegacy] =
+ this._legacyConfig.addOptions(LEGACY_OPTIONS);
+ this._selectedCollectionOptionLegacy.onChange(this._setCurrentLegacy.bind(this));
+ this._currentDelayOptionLegacy.onChange(this._emitChange.bind(this));
+
+ this._config = config;
+
+ this._onChange = onChange;
+ this._core = core;
+
+ this._alerts = alerts;
+ this._alertsDeprecation = alerts.collection("deprecated");
+
+ this._routesConfig = this._config.addNamespace(Routes.id);
+ this._routesLogger = logger.namespace(Routes.id);
+ this._loggerLoadRoutes = this._routesLogger.namespace(LOAD_NAMESPACE);
+ this._alertsRoutes = alerts.collection(Routes.id);
+ this._alertsLoadRoutes = this._alertsRoutes.collection(LOAD_NAMESPACE);
+
+ // TODO, move routes logic to Routes Class
+ this._routes = new Routes({
+ logger: this._routesLogger,
+ config: this._routesConfig,
+ onChangeDelay: this._emitChange.bind(this),
+ getPlainRoutes: this._getPlainRoutes.bind(this),
+ getPlainVariants: this._getPlainVariants.bind(this),
+ });
+
+ // TODO, move collections logic to Collections Class
+ this._collectionsConfig = this._config.addNamespace(Collections.id);
+ this._collectionsLogger = logger.namespace(Collections.id);
+ this._loggerLoadCollections = this._collectionsLogger.namespace(LOAD_NAMESPACE);
+ this._alertsCollections = alerts.collection(Collections.id);
+ this._alertsLoadCollections = this._alertsCollections.collection(LOAD_NAMESPACE);
+
+ this._collectionsInstance = new Collections({
+ logger: this._collectionsLogger,
+ config: this._collectionsConfig,
+ onChangeSelected: this._setCurrent.bind(this),
+ getSelectedCollection: this._getSelectedCollection.bind(this),
+ getIds: this._getCollectionsIds.bind(this),
+ getPlainCollections: this._getPlainCollections.bind(this),
+ });
+
+ // Create collections loaders
+ this._collectionsLoaders = new Loaders({
+ onLoad: () => {
+ // First time wait for other loader to have finished
+ this._loadedCollections = true;
+ if (this._loadedRoutes) {
+ this.load();
+ }
+ },
+ });
+
+ // Create routes loaders
+ this._routesLoaders = new Loaders({
+ onLoad: () => {
+ // First time wait for other loader to have finished
+ this._loadedRoutes = true;
+ if (this._loadedCollections) {
+ this.load();
+ }
+ },
+ });
+
+ this._router = null;
+ this._collectionsDefinitions = [];
+ this._collections = [];
+ this._plainCollections = [];
+ this._routesDefinitions = [];
+ this._plainRoutes = [];
+ this._plainVariants = [];
+ this._routeVariants = [];
+ this._customVariants = [];
+ this._customVariantsCollection = null;
+
+ this.router = this.router.bind(this);
+ this._getDelay = this._getDelay.bind(this);
+ }
+
+ _emitChange() {
+ this._eventEmitter.emit(CHANGE_MOCK);
+ this._onChange();
+ }
+
+ _getDelay() {
+ // Temportal workaround to know current delay in this class
+ // TODO, move to Routes class
+ if (this._currentDelayOptionLegacy.hasBeenSet) {
+ this._alertsDeprecation.set(
+ "mocks.delay",
+ deprecatedMessage(
+ "option",
+ "mocks.delay",
+ "mock.routes.delay",
+ "releases/migrating-from-v3#options"
+ )
+ );
+ }
+ return this._routes._delayOption.hasBeenSet
+ ? this._routes._delayOption.value
+ : this._currentDelayOptionLegacy.value;
+ }
+
+ // LEGACY, to be removed
+ _addCollectionsSelectedOptionAlert() {
+ this._alertsDeprecation.set(
+ "mocks.selected",
+ deprecatedMessage(
+ "option",
+ "mocks.selected",
+ "mock.collections.selected",
+ "releases/migrating-from-v3#options"
+ )
+ );
+ }
+
+ // Temportal workaround to know selected collection in this class while it has a deprecated option setting the same value.
+ // TODO, move to Collections class
+ _getCollectionSelected() {
+ if (this._selectedCollectionOptionLegacy.hasBeenSet) {
+ this._addCollectionsSelectedOptionAlert();
+ }
+ return this._collectionsInstance._selectedOption.hasBeenSet
+ ? this._collectionsInstance._selectedOption.value
+ : this._selectedCollectionOptionLegacy.value;
+ }
+
+ _reloadRouter() {
+ if (this._customVariantsCollection) {
+ this._router = this._customVariantsCollection.router;
+ } else if (this._selectedCollection) {
+ this._router = this._selectedCollection.router;
+ } else {
+ this._router = express.Router();
+ }
+ this._emitChange();
+ }
+
+ _processCollections() {
+ this._loggerLoadCollections.debug("Processing loaded collections");
+ this._loggerLoadCollections.silly(JSON.stringify(this._collectionsDefinitions));
+ this._collections = getCollections({
+ collectionsDefinitions: this._collectionsDefinitions,
+ alerts: this._alertsLoadCollections,
+ logger: this._loggerLoadCollections,
+ loggerRoutes: this._routesLogger,
+ routeVariants: this._routeVariants,
+ getGlobalDelay: this._getDelay,
+ });
+ }
+
+ _processRoutes() {
+ this._loggerLoadRoutes.debug("Processing loaded routes");
+ this._loggerLoadRoutes.silly(JSON.stringify(this._routesDefinitions));
+ this._routeVariants = getRouteVariants({
+ routesDefinitions: this._routesDefinitions,
+ alerts: this._alertsLoadRoutes,
+ alertsRoutes: this._alertsRoutes,
+ logger: this._loggerLoadRoutes,
+ loggerRoutes: this._routesLogger,
+ routeHandlers: this._variantHandlers,
+ core: this._core,
+ });
+ this._loggerLoadRoutes.debug(`Processed ${this._routeVariants.length} route variants`);
+ }
+
+ load() {
+ this._routesDefinitions = this._routesLoaders.contents;
+ this._collectionsDefinitions = this._collectionsLoaders.contents;
+ this._processRoutes();
+ this._processCollections();
+ this._collectionsIds = getIds(this._collections);
+ this._plainRoutes = getPlainRoutes(this._routesDefinitions, this._routeVariants);
+ this._plainVariants = getPlainRouteVariants(this._routeVariants);
+ this._plainCollections = getPlainCollections(this._collections, this._collectionsDefinitions);
+ this._setCurrent(this._getCollectionSelected());
+ }
+
+ init(variantHandlers) {
+ compileRouteValidator(variantHandlers);
+ this._variantHandlers = variantHandlers;
+ }
+
+ router(req, res, next) {
+ this._router(req, res, next);
+ }
+
+ _setCurrent(id) {
+ this._logger.verbose(`Trying to select collection '${id}'`);
+ let selected;
+ this._alertsCollections.remove(SELECTED_COLLECTION_ID);
+ if (!id) {
+ selected = this._collections[0];
+ if (selected) {
+ this._alertsCollections.set(
+ SELECTED_COLLECTION_ID,
+ "Option 'mock.collections.selected' was not defined. Selecting the first collection found"
+ );
+ } else {
+ this._alertsCollections.set(
+ SELECTED_COLLECTION_ID,
+ "Option 'mock.collections.selected' was not defined"
+ );
+ }
+ } else {
+ selected = this._collections.find((collection) => collection.id === id);
+ if (!selected) {
+ selected = this._collections[0];
+ if (selected) {
+ this._alertsCollections.set(
+ SELECTED_COLLECTION_ID,
+ `Collection '${id}' was not found. Selecting the first one found`
+ );
+ }
+ }
+ }
+ if (!selected) {
+ this._alertsCollections.set(EMPTY_ALERT_ID, "No collections found");
+ } else {
+ this._logger.info(`Selected collection: '${selected.id}'`);
+ this._alertsCollections.remove(EMPTY_ALERT_ID);
+ }
+
+ this._selectedCollection = selected;
+ this._selectedId = (selected && selected.id) || null;
+ this._stopUsingVariants();
+ this._reloadRouter();
+ }
+
+ _setCurrentLegacy(id) {
+ this._addCollectionsSelectedOptionAlert();
+ this._setCurrent(id);
+ }
+
+ // Legacy, to be removed
+ set current(id) {
+ this._alertsDeprecation.set(
+ "current",
+ deprecatedMessage(
+ "setter",
+ "mocks.current",
+ "mock.collections.select()",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ this._setCurrent(id);
+ }
+
+ _stopUsingVariants() {
+ this._customVariants = [];
+ this._customVariantsCollection = null;
+ }
+
+ _createCustomCollection() {
+ const selectedCollectionId = this._selectedId;
+ const alerts = this._alertsLoadCollections.collection("custom");
+ alerts.clean();
+ this._customVariantsCollection = getCollection({
+ collectionDefinition: {
+ id: `custom-variants:from:${selectedCollectionId}`,
+ from: selectedCollectionId,
+ routes: this._customVariants,
+ },
+ collectionsDefinitions: this._collectionsDefinitions,
+ routeVariants: this._routeVariants,
+ getGlobalDelay: this._getDelay,
+ alerts,
+ logger: this._loggerLoadCollections,
+ loggerRoutes: this._routesLogger,
+ });
+ }
+
+ // Legacy, to be removed
+ restoreRoutesVariants() {
+ this._alertsDeprecation.set(
+ "restorerouteVariants",
+ deprecatedMessage(
+ "method",
+ "mocks.restoreRoutesVariants",
+ "mock.restoreRouteVariants",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ this.restoreRouteVariants();
+ }
+
+ restoreRouteVariants() {
+ this._stopUsingVariants();
+ this._reloadRouter();
+ }
+
+ useRouteVariant(variantId) {
+ // TODO, validate variantId
+ this._customVariants = addCustomVariant(variantId, this._customVariants);
+ this._createCustomCollection();
+ this._reloadRouter();
+ }
+
+ onChange(listener) {
+ return addEventListener(listener, CHANGE_MOCK, this._eventEmitter);
+ }
+
+ createLoaders() {
+ return {
+ loadRoutes: this._routesLoaders.new(),
+ loadCollections: this._collectionsLoaders.new(),
+ };
+ }
+
+ _getPlainCustomRouteVariants() {
+ return [...this._customVariants];
+ }
+
+ get customRouteVariants() {
+ return this._getPlainCustomRouteVariants();
+ }
+
+ // Legacy, to be removed
+ get customRoutesVariants() {
+ this._alertsDeprecation.set(
+ "customrouteVariants",
+ deprecatedMessage(
+ "method",
+ "mocks.customrouteVariants",
+ "mock.plainCustomRouteVariants",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ return this._getPlainCustomRouteVariants();
+ }
+
+ _getSelectedCollection() {
+ return this._selectedId;
+ }
+
+ // Legacy, to be removed
+ get current() {
+ this._alertsDeprecation.set(
+ "current",
+ deprecatedMessage(
+ "getter",
+ "mocks.current",
+ "mock.collections.selected",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ return this._getSelectedCollection();
+ }
+
+ _getCollectionsIds() {
+ return [...this._collectionsIds];
+ }
+
+ // Legacy, to be removed
+ get ids() {
+ this._alertsDeprecation.set(
+ "ids",
+ deprecatedMessage(
+ "getter",
+ "mocks.ids",
+ "mock.collections.ids",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ return this._getCollectionsIds();
+ }
+
+ _getPlainCollections() {
+ return [...this._plainCollections];
+ }
+
+ // Legacy, to be removed
+ get plainMocks() {
+ this._alertsDeprecation.set(
+ "plainMocks",
+ deprecatedMessage(
+ "getter",
+ "mocks.plainMocks",
+ "mock.collections.plain",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ return plainCollectionsToLegacy(this._getPlainCollections());
+ }
+
+ _getPlainRoutes() {
+ return [...this._plainRoutes];
+ }
+
+ _getPlainVariants() {
+ return [...this._plainVariants];
+ }
+
+ // Legacy, to be removed
+ get plainRoutes() {
+ this._alertsDeprecation.set(
+ "plainRoutes",
+ deprecatedMessage(
+ "getter",
+ "mocks.plainRoutes",
+ "mock.routes.plain",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ return this._getPlainRoutes();
+ }
+
+ // Legacy, to be removed
+ get plainRoutesVariants() {
+ this._alertsDeprecation.set(
+ "plainRoutesVariants",
+ deprecatedMessage(
+ "getter",
+ "mocks.plainRoutesVariants",
+ "mock.routes.plainVariants",
+ "releases/migrating-from-v3#api"
+ )
+ );
+ return plainRouteVariantsToLegacy(this._getPlainVariants());
+ }
+
+ get routes() {
+ return this._routes;
+ }
+
+ get collections() {
+ return this._collectionsInstance;
+ }
+}
+
+module.exports = Mock;
diff --git a/packages/core/src/mock/Routes.js b/packages/core/src/mock/Routes.js
new file mode 100644
index 000000000..48177aa94
--- /dev/null
+++ b/packages/core/src/mock/Routes.js
@@ -0,0 +1,35 @@
+const OPTIONS = [
+ {
+ description: "Global delay to apply to routes",
+ name: "delay",
+ type: "number",
+ default: 0,
+ },
+];
+
+class Routes {
+ static get id() {
+ return "routes";
+ }
+
+ constructor({ logger, config, onChangeDelay, getPlainRoutes, getPlainVariants }) {
+ this._logger = logger;
+ this._config = config;
+
+ this._getPlainRoutes = getPlainRoutes;
+ this._getPlainVariants = getPlainVariants;
+
+ [this._delayOption] = this._config.addOptions(OPTIONS);
+ this._delayOption.onChange(onChangeDelay);
+ }
+
+ get plain() {
+ return this._getPlainRoutes();
+ }
+
+ get plainVariants() {
+ return this._getPlainVariants();
+ }
+}
+
+module.exports = Routes;
diff --git a/packages/core/src/mocks/helpers.js b/packages/core/src/mock/helpers.js
similarity index 54%
rename from packages/core/src/mocks/helpers.js
rename to packages/core/src/mock/helpers.js
index 0fdf120f9..0c73b4d7f 100644
--- a/packages/core/src/mocks/helpers.js
+++ b/packages/core/src/mock/helpers.js
@@ -10,65 +10,85 @@ Unless required by applicable law or agreed to in writing, software distributed
const { flatten, compact, isUndefined } = require("lodash");
-const { getDataFromVariant, getPreview } = require("../routes-handlers/helpers");
-const CustomCore = require("../CustomCore");
-const Mock = require("./Mock");
+const { getDataFromVariant, getPreview } = require("../variant-handlers/helpers");
+const CoreApi = require("../common/CoreApi");
+const Collection = require("./Collection");
const {
variantValidationErrors,
routeValidationErrors,
- mockValidationErrors,
+ collectionValidationErrors,
findRouteVariantByVariantId,
- mockRouteVariantsValidationErrors,
+ collectionRouteVariantsValidationErrors,
+ getCollectionRouteVariantsProperty,
} = require("./validations");
const DEFAULT_ROUTES_HANDLER = "default";
-function findEqualRouteVariant(routesVariants, routeVariantToFind) {
- return routesVariants.find((routeVariant) => {
+function findEqualRouteVariant(routeVariants, routeVariantToFind) {
+ return routeVariants.find((routeVariant) => {
return routeVariant.routeId === routeVariantToFind.routeId;
});
}
-function addMockRoutesVariants(mockRoutesVariants, routesVariantsToAdd) {
- const replacedMocksRoutesVariants = mockRoutesVariants.reduce((result, mockRouteVariant) => {
- const routesVariantToReplace = findEqualRouteVariant(routesVariantsToAdd, mockRouteVariant);
- result.push(routesVariantToReplace || mockRouteVariant);
- return result;
- }, []);
+function addCollectionRouteVariants(collectionRouteVariants, routeVariantsToAdd) {
+ const replacedCollectionRouteVariants = collectionRouteVariants.reduce(
+ (result, collectionRouteVariant) => {
+ const routesVariantToReplace = findEqualRouteVariant(
+ routeVariantsToAdd,
+ collectionRouteVariant
+ );
+ result.push(routesVariantToReplace || collectionRouteVariant);
+ return result;
+ },
+ []
+ );
- routesVariantsToAdd.forEach((routeVariantToAdd) => {
+ routeVariantsToAdd.forEach((routeVariantToAdd) => {
const hasBeenReplaced = !!findEqualRouteVariant(
- replacedMocksRoutesVariants,
+ replacedCollectionRouteVariants,
routeVariantToAdd
);
if (!hasBeenReplaced) {
- replacedMocksRoutesVariants.push(routeVariantToAdd);
+ replacedCollectionRouteVariants.push(routeVariantToAdd);
}
});
- return replacedMocksRoutesVariants;
+ return replacedCollectionRouteVariants;
}
-function getMockRoutesVariants(mock, mocks, routesVariants, alerts, routesVariantsToAdd = []) {
- const mockRoutesVariants = compact(
- mock.routesVariants.map((variantId) => {
- return findRouteVariantByVariantId(routesVariants, variantId);
+function getCollectionRouteVariants(
+ collection,
+ collections,
+ routeVariants,
+ alerts,
+ alertsCollections,
+ routeVariantsToAdd = []
+) {
+ const collectionRouteVariants = compact(
+ getCollectionRouteVariantsProperty(collection, alertsCollections).map((variantId) => {
+ return findRouteVariantByVariantId(routeVariants, variantId);
})
);
- if (mock.from) {
- const from = mocks.find((mockCandidate) => mockCandidate.id === mock.from);
+ if (collection.from) {
+ const from = collections.find(
+ (collectionCandidate) => collectionCandidate.id === collection.from
+ );
if (from) {
- return getMockRoutesVariants(
+ return getCollectionRouteVariants(
from,
- mocks,
- routesVariants,
+ collections,
+ routeVariants,
alerts,
- addMockRoutesVariants(mockRoutesVariants, routesVariantsToAdd)
+ alertsCollections,
+ addCollectionRouteVariants(collectionRouteVariants, routeVariantsToAdd)
);
}
// TODO, throw an error in strict validation mode
- alerts.set("from", `Mock with invalid 'from' property detected, '${mock.from}' was not found`);
+ alerts.set(
+ "from",
+ `Collection with invalid 'from' property detected, '${collection.from}' was not found`
+ );
}
- return addMockRoutesVariants(mockRoutesVariants, routesVariantsToAdd);
+ return addCollectionRouteVariants(collectionRouteVariants, routeVariantsToAdd);
}
function getVariantId(routeId, variantId) {
@@ -78,19 +98,22 @@ function getVariantId(routeId, variantId) {
return null;
}
-function getPlainMocks(mocks, mocksDefinitions) {
- return mocks.map((mock) => {
- const mockDefinition = mocksDefinitions.find((mockCandidate) => mockCandidate.id === mock.id);
+function getPlainCollections(collections, collectionsDefinitions) {
+ return collections.map((collection) => {
+ const collectionDefinition = collectionsDefinitions.find(
+ (collectionCandidate) => collectionCandidate.id === collection.id
+ );
return {
- id: mock.id,
- from: (mockDefinition && mockDefinition.from) || null,
- routesVariants: mockDefinition && mockDefinition.routesVariants,
- appliedRoutesVariants: mock.routesVariants.map((routeVariant) => routeVariant.variantId),
+ id: collection.id,
+ from: (collectionDefinition && collectionDefinition.from) || null,
+ definedRoutes:
+ (collectionDefinition && getCollectionRouteVariantsProperty(collectionDefinition)) || [],
+ routes: collection.routeVariants.map((routeVariant) => routeVariant.variantId),
};
});
}
-function getPlainRouteVariants(route, routesVariants) {
+function getRoutePlainRouteVariants(route, routeVariants) {
if (!route.variants || !Array.isArray(route.variants)) {
return [];
}
@@ -100,7 +123,7 @@ function getPlainRouteVariants(route, routesVariants) {
return null;
}
const variantId = getVariantId(route.id, variant.id);
- const variantHandler = routesVariants.find(
+ const variantHandler = routeVariants.find(
(routeVariant) => routeVariant.variantId === variantId
);
if (variantHandler) {
@@ -110,7 +133,7 @@ function getPlainRouteVariants(route, routesVariants) {
);
}
-function getPlainRoutes(routes, routesVariants) {
+function getPlainRoutes(routes, routeVariants) {
let ids = [];
return compact(
routes.map((route) => {
@@ -118,7 +141,7 @@ function getPlainRoutes(routes, routesVariants) {
!route ||
!route.id ||
ids.includes(route.id) ||
- !routesVariants.find((routeVariant) => routeVariant.routeId === route.id)
+ !routeVariants.find((routeVariant) => routeVariant.routeId === route.id)
) {
return null;
}
@@ -128,20 +151,20 @@ function getPlainRoutes(routes, routesVariants) {
url: route.url,
method: route.method,
delay: hasDelayProperty(route) ? route.delay : null,
- variants: getPlainRouteVariants(route, routesVariants),
+ variants: getRoutePlainRouteVariants(route, routeVariants),
};
})
);
}
-function getPlainRoutesVariants(routesVariants) {
- return routesVariants.map((routeVariant) => {
+function getPlainRouteVariants(routeVariants) {
+ return routeVariants.map((routeVariant) => {
const preview = getPreview(routeVariant);
return {
id: routeVariant.variantId,
- routeId: routeVariant.routeId,
- handler: routeVariant.constructor.id,
- response: isUndefined(preview) ? null : preview,
+ route: routeVariant.routeId,
+ type: routeVariant.constructor.id,
+ preview: isUndefined(preview) ? null : preview,
delay: routeVariant.delay,
};
});
@@ -181,6 +204,10 @@ function findRouteHandler(routeHandlers, handlerId) {
return routeHandlers.find((routeHandlerCandidate) => routeHandlerCandidate.id === handlerId);
}
+function getHandlerId(variant) {
+ return variant.type || variant.handler || DEFAULT_ROUTES_HANDLER;
+}
+
function getVariantHandler({
route,
variant,
@@ -194,16 +221,16 @@ function getVariantHandler({
}) {
let routeHandler = null;
const variantId = getVariantId(route.id, variant.id);
- const handlerId = variant.handler || DEFAULT_ROUTES_HANDLER;
+ const variantAlerts = alerts.collection(variant.id || variantIndex);
+ const handlerId = getHandlerId(variant);
const Handler = findRouteHandler(routeHandlers, handlerId);
const variantErrors = variantValidationErrors(route, variant, Handler);
- const variantAlerts = alerts.collection(variant.id || variantIndex);
const variantNamespace = variantId || getVariantId(route.id, variantIndex);
const routeVariantLogger = loggerRoutes.namespace(variantNamespace);
const routeVariantAlerts = alertsRoutes.collection(variantNamespace);
const handlersAlerts = alertsRoutes.collection("handlers");
- const routeVariantCustomCore = new CustomCore({
+ const routeVariantCoreApi = new CoreApi({
core,
logger: routeVariantLogger,
alerts: routeVariantAlerts,
@@ -218,13 +245,7 @@ function getVariantHandler({
}
try {
- const variantArgument = getDataFromVariant(variant, Handler);
- if (Handler.deprecated) {
- handlersAlerts.set(
- Handler.id,
- `Handler '${Handler.id}' is deprecated and will be removed in next major version. Consider using another handler. https://www.mocks-server.org/docs/guides-migrating-from-v3#route-variants-handlers`
- );
- }
+ const variantArgument = getDataFromVariant(variant, Handler, handlersAlerts);
routeHandler = new Handler(
{
...variantArgument,
@@ -232,7 +253,7 @@ function getVariantHandler({
url: route.url,
method: route.method,
},
- routeVariantCustomCore
+ routeVariantCoreApi
);
// TODO, do not add properties to handler. Store it in "handler" property
routeHandler.delay = getRouteHandlerDelay(variant, route);
@@ -259,12 +280,12 @@ function getRouteVariants({
}) {
let routeIds = [];
alerts.clean();
- alertsRoutes.clean();
+
return compact(
flatten(
routesDefinitions.map((route, index) => {
let routeVariantsIds = [];
- const routeAlerts = alerts.collection(route.id || index);
+ const routeAlerts = alerts.collection((route && route.id) || index);
const routeErrors = routeValidationErrors(route);
if (!!routeErrors) {
routeAlerts.set("validation", routeErrors.message);
@@ -311,54 +332,61 @@ function getRouteVariants({
);
}
-function getMock({
- mockDefinition,
- mocksDefinitions,
+function getCollection({
+ collectionDefinition,
+ collectionsDefinitions,
routeVariants,
logger,
loggerRoutes,
getGlobalDelay,
alerts,
+ alertsCollections,
}) {
- let mock = null;
+ let collection = null;
- const mockRouteVariantsErrors = mockRouteVariantsValidationErrors(mockDefinition, routeVariants);
- if (!!mockRouteVariantsErrors) {
- alerts.set("variants", mockRouteVariantsErrors.message);
+ const collectionRouteVariantsErrors = collectionRouteVariantsValidationErrors(
+ collectionDefinition,
+ routeVariants
+ );
+ if (!!collectionRouteVariantsErrors) {
+ alerts.set("variants", collectionRouteVariantsErrors.message);
logger.silly(
- `Mock variants validation errors: ${JSON.stringify(mockRouteVariantsErrors.errors)}`
+ `Collection route variants validation errors: ${JSON.stringify(
+ collectionRouteVariantsErrors.errors
+ )}`
);
// TODO, add strict validation mode
// return null;
}
- const mockErrors = mockValidationErrors(mockDefinition, routeVariants);
- if (!!mockErrors) {
- alerts.set("validation", mockErrors.message);
- logger.silly(`Mock validation errors: ${JSON.stringify(mockErrors.errors)}`);
+ const collectionErrors = collectionValidationErrors(collectionDefinition, routeVariants);
+ if (!!collectionErrors) {
+ alerts.set("validation", collectionErrors.message);
+ logger.silly(`Collection validation errors: ${JSON.stringify(collectionErrors.errors)}`);
return null;
}
try {
- mock = new Mock({
- id: mockDefinition.id,
- routesVariants: getMockRoutesVariants(
- mockDefinition,
- mocksDefinitions,
+ collection = new Collection({
+ id: collectionDefinition.id,
+ routeVariants: getCollectionRouteVariants(
+ collectionDefinition,
+ collectionsDefinitions,
routeVariants,
- alerts
+ alerts,
+ alertsCollections
),
logger: loggerRoutes,
getDelay: getGlobalDelay,
});
} catch (error) {
- alerts.set("process", "Error processing mock", error);
+ alerts.set("process", "Error processing collection", error);
}
- return mock;
+ return collection;
}
-function getMocks({
- mocksDefinitions,
+function getCollections({
+ collectionsDefinitions,
alerts,
logger,
loggerRoutes,
@@ -368,54 +396,87 @@ function getMocks({
alerts.clean();
let errorsProcessing = 0;
let ids = [];
- const mocks = compact(
- mocksDefinitions.map((mockDefinition, index) => {
- const mockDefinitionId = mockDefinition && mockDefinition.id;
+ const collections = compact(
+ collectionsDefinitions.map((collectionDefinition, index) => {
+ const collectionDefinitionId = collectionDefinition && collectionDefinition.id;
const alertsCollectionId =
- !mockDefinitionId || ids.includes(mockDefinitionId) ? index : mockDefinitionId;
- const alertsMock = alerts.collection(alertsCollectionId);
- const mock = getMock({
- mockDefinition,
- mocksDefinitions,
+ !collectionDefinitionId || ids.includes(collectionDefinitionId)
+ ? index
+ : collectionDefinitionId;
+ const alertsCollection = alerts.collection(alertsCollectionId);
+ const collection = getCollection({
+ collectionDefinition,
+ collectionsDefinitions,
routeVariants,
getGlobalDelay,
logger,
loggerRoutes,
- alerts: alertsMock,
+ alerts: alertsCollection,
+ alertsCollections: alerts,
});
- if (!mock) {
+ if (!collection) {
errorsProcessing++;
return null;
}
- if (ids.includes(mock.id)) {
- alertsMock.set(
+ if (ids.includes(collection.id)) {
+ alertsCollection.set(
"duplicated",
- `Mock with duplicated id '${mock.id}' detected. It has been ignored`
+ `Collection with duplicated id '${collection.id}' detected. It has been ignored`
);
return null;
}
- ids.push(mock.id);
- return mock;
+ ids.push(collection.id);
+ return collection;
})
);
if (errorsProcessing > 0) {
- alerts.set("critical-error", `Critical errors found while loading mocks: ${errorsProcessing}`);
+ alerts.set(
+ "critical-error",
+ `Critical errors found while loading collections: ${errorsProcessing}`
+ );
}
- return mocks;
+ return collections;
+}
+
+// LEGACY, to be removed
+function plainCollectionsToLegacy(plainCollections) {
+ return plainCollections.map((collection) => {
+ return {
+ id: collection.id,
+ from: collection.from,
+ routesVariants: collection.definedRoutes,
+ appliedRoutesVariants: collection.routes,
+ };
+ });
+}
+
+// LEGACY, to be removed
+function plainRouteVariantsToLegacy(plainRouteVariants) {
+ return plainRouteVariants.map((routeVariant) => {
+ return {
+ id: routeVariant.id,
+ routeId: routeVariant.route,
+ handler: routeVariant.type,
+ response: routeVariant.preview,
+ delay: routeVariant.delay,
+ };
+ });
}
module.exports = {
- getMockRoutesVariants,
+ getCollectionRouteVariants,
getVariantId,
- getPlainMocks,
+ getPlainCollections,
getPlainRoutes,
- getPlainRoutesVariants,
+ getPlainRouteVariants,
addCustomVariant,
getRouteHandlerDelay,
getVariantHandler,
getRouteVariants,
hasDelayProperty,
- getMock,
- getMocks,
+ getCollection,
+ getCollections,
+ plainCollectionsToLegacy,
+ plainRouteVariantsToLegacy,
};
diff --git a/packages/core/src/mocks/validations.js b/packages/core/src/mock/validations.js
similarity index 60%
rename from packages/core/src/mocks/validations.js
rename to packages/core/src/mock/validations.js
index 4417da1be..333dd2697 100644
--- a/packages/core/src/mocks/validations.js
+++ b/packages/core/src/mock/validations.js
@@ -12,7 +12,8 @@ const Ajv = require("ajv");
const { compact } = require("lodash");
const betterAjvErrors = require("better-ajv-errors").default;
-const { getDataFromVariant, isVersion4 } = require("../routes-handlers/helpers");
+const { getDataFromVariant, isVersion4 } = require("../variant-handlers/helpers");
+const { deprecatedMessage } = require("../common/helpers");
const ajv = new Ajv({ allErrors: true });
@@ -38,25 +39,69 @@ ajv.addKeyword({
errors: false,
});
-const mocksSchema = {
- type: "object",
- properties: {
- id: {
- type: "string",
+const collectionsSchema = {
+ oneOf: [
+ {
+ type: "object",
+ properties: {
+ id: {
+ type: "string",
+ },
+ from: {
+ type: "string",
+ },
+ routesVariants: {
+ type: "array",
+ uniqueItems: true,
+ items: {
+ type: "string",
+ },
+ },
+ },
+ required: ["id", "routesVariants"],
+ additionalProperties: false,
},
- from: {
- type: "string",
+ {
+ type: "object",
+ properties: {
+ id: {
+ type: "string",
+ },
+ from: {
+ type: "string",
+ },
+ routeVariants: {
+ type: "array",
+ uniqueItems: true,
+ items: {
+ type: "string",
+ },
+ },
+ },
+ required: ["id", "routeVariants"],
+ additionalProperties: false,
},
- routesVariants: {
- type: "array",
- uniqueItems: true,
- items: {
- type: "string",
+ {
+ type: "object",
+ properties: {
+ id: {
+ type: "string",
+ },
+ from: {
+ type: "string",
+ },
+ routes: {
+ type: "array",
+ uniqueItems: true,
+ items: {
+ type: "string",
+ },
+ },
},
+ required: ["id", "routes"],
+ additionalProperties: false,
},
- },
- required: ["id", "routesVariants"],
- additionalProperties: false,
+ ],
};
const routesSchema = {
@@ -107,6 +152,10 @@ const routesSchema = {
type: "string",
enum: [], // this enum is defined when validator is compiled
},
+ type: {
+ type: "string",
+ enum: [], // this enum is defined when validator is compiled
+ },
delay: {
oneOf: [
{
@@ -119,7 +168,7 @@ const routesSchema = {
],
},
},
- // TODO, require "response" in all variants to be an object, do not allow additionalProperties
+ // TODO, require "options" in all variants to be an object, do not allow additionalProperties. Deprecate "response"
required: ["id"],
},
},
@@ -128,7 +177,7 @@ const routesSchema = {
additionalProperties: false,
};
-const mockValidator = ajv.compile(mocksSchema);
+const collectionValidator = ajv.compile(collectionsSchema);
let routeValidator, routeSchema;
@@ -136,10 +185,12 @@ function getIds(objs) {
return objs.map((obj) => obj.id);
}
-function compileRouteValidator(routesHandlers) {
- const supportedRouteHandlersIds = getIds(routesHandlers);
+function compileRouteValidator(variantHandlers) {
+ const supportedRouteHandlersIds = getIds(variantHandlers);
const schema = { ...routesSchema };
+ // LEGACY, handler property
schema.properties.variants.items.properties.handler.enum = supportedRouteHandlersIds;
+ schema.properties.variants.items.properties.type.enum = supportedRouteHandlersIds;
routeSchema = { ...schema };
routeValidator = ajv.compile(schema);
}
@@ -182,12 +233,12 @@ function routeValidationMessage(data, errors) {
return validationSingleMessage(routeSchema, data, errors);
}
-function mockValidationMessage(data, errors) {
- return validationSingleMessage(mocksSchema, data, errors);
+function collectionValidationMessage(data, errors) {
+ return validationSingleMessage(collectionsSchema, data, errors);
}
-function findRouteVariantByVariantId(routesVariants, variantId) {
- return routesVariants.find((routeVariant) => routeVariant.variantId === variantId);
+function findRouteVariantByVariantId(routeVariants, variantId) {
+ return routeVariants.find((routeVariant) => routeVariant.variantId === variantId);
}
function traceId(id) {
@@ -204,11 +255,11 @@ function notFoundRouteVariantMessage(variantId) {
function duplicatedRouteMessage(routeId) {
return {
- message: `route ${traceId(routeId)} is used more than once in the same mock`,
+ message: `route ${traceId(routeId)} is used more than once in the same collection`,
};
}
-function mockRouteVariantsErrors(variants, routeVariants) {
+function collectionRouteVariantsErrors(variants, routeVariants) {
let routes = [];
return compact(
variants.map((variantId) => {
@@ -225,24 +276,41 @@ function mockRouteVariantsErrors(variants, routeVariants) {
);
}
-function mockInvalidRouteVariants(mock, routeVariants) {
+function getCollectionRouteVariantsProperty(collection, alertsCollections) {
+ if (alertsCollections && collection && collection.routesVariants) {
+ alertsCollections.set(
+ "routesVariants",
+ deprecatedMessage(
+ "property",
+ "collection.routesVariants",
+ "collection.routes",
+ "releases/migrating-from-v3#main-concepts"
+ )
+ );
+ }
+ // LEGACY, remove routesVariants support
+ return collection.routes || collection.routeVariants || collection.routesVariants;
+}
+
+function collectionInvalidRouteVariants(collection, routeVariants) {
+ const variantsInCollection = collection && getCollectionRouteVariantsProperty(collection);
const variants =
- mock && mock.routesVariants && Array.isArray(mock.routesVariants) ? mock.routesVariants : [];
+ variantsInCollection && Array.isArray(variantsInCollection) ? variantsInCollection : [];
return {
- errors: mockRouteVariantsErrors(variants, routeVariants),
+ errors: collectionRouteVariantsErrors(variants, routeVariants),
};
}
-function mockErrorsMessagePrefix(mock) {
- const idTrace = mock && mock.id ? `${traceId(mock.id)} ` : "";
- return `Mock ${idTrace}is invalid:`;
+function collectionErrorsMessagePrefix(collection) {
+ const idTrace = collection && collection.id ? `${traceId(collection.id)} ` : "";
+ return `Collection ${idTrace}is invalid:`;
}
-function mockRouteVariantsValidationErrors(mock, routeVariants) {
- const invalidRouteVariants = mockInvalidRouteVariants(mock, routeVariants);
+function collectionRouteVariantsValidationErrors(collection, routeVariants) {
+ const invalidRouteVariants = collectionInvalidRouteVariants(collection, routeVariants);
if (invalidRouteVariants.errors.length) {
return {
- message: `${mockErrorsMessagePrefix(mock)} ${customValidationSingleMessage(
+ message: `${collectionErrorsMessagePrefix(collection)} ${customValidationSingleMessage(
invalidRouteVariants.errors
)}`,
errors: invalidRouteVariants.errors,
@@ -251,15 +319,15 @@ function mockRouteVariantsValidationErrors(mock, routeVariants) {
return null;
}
-function mockValidationErrors(mock) {
- const isValid = mockValidator(mock);
+function collectionValidationErrors(collection) {
+ const isValid = collectionValidator(collection);
if (!isValid) {
return {
- message: `${mockErrorsMessagePrefix(mock)} ${mockValidationMessage(
- mock,
- mockValidator.errors
+ message: `${collectionErrorsMessagePrefix(collection)} ${collectionValidationMessage(
+ collection,
+ collectionValidator.errors
)}`,
- errors: mockValidator.errors,
+ errors: collectionValidator.errors,
};
}
return null;
@@ -286,7 +354,7 @@ function variantValidationErrors(route, variant, Handler) {
}
const variantValidator = ajv.compile(Handler.validationSchema);
const dataToCheck = getDataFromVariant(variant, Handler);
- const dataMessage = isVersion4(Handler) ? "Invalid 'response' property:" : "";
+ const dataMessage = isVersion4(Handler) ? "Invalid 'options' property:" : "";
const isValid = variantValidator(dataToCheck);
if (!isValid) {
let validationMessage;
@@ -313,12 +381,13 @@ function variantValidationErrors(route, variant, Handler) {
module.exports = {
HTTP_METHODS,
getIds,
- mockValidationErrors,
+ collectionValidationErrors,
routeValidationErrors,
variantValidationErrors,
compileRouteValidator,
validationSingleMessage,
findRouteVariantByVariantId,
- mockRouteVariantsValidationErrors,
+ collectionRouteVariantsValidationErrors,
customValidationSingleMessage,
+ getCollectionRouteVariantsProperty,
};
diff --git a/packages/core/src/mocks/Mocks.js b/packages/core/src/mocks/Mocks.js
deleted file mode 100644
index 7c1333ba9..000000000
--- a/packages/core/src/mocks/Mocks.js
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
-Copyright 2021-2022 Javier Brea
-
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-*/
-
-const express = require("express");
-
-const OPTIONS = [
- {
- description: "Selected mock",
- name: "selected",
- type: "string",
- extraData: {
- scaffold: {
- commented: false,
- },
- },
- },
- {
- description: "Global delay to apply to routes",
- name: "delay",
- type: "number",
- default: 0,
- },
-];
-
-const {
- getPlainMocks,
- getPlainRoutes,
- getPlainRoutesVariants,
- addCustomVariant,
- getRouteVariants,
- getMocks,
- getMock,
-} = require("./helpers");
-const { getIds, compileRouteValidator } = require("./validations");
-
-const SETTINGS_ALERT_ID = "settings";
-const EMPTY_ALERT_ID = "empty";
-const LOAD_MOCKS_NAMESPACE = "loadMocks";
-const LOAD_ROUTES_NAMESPACE = "loadRoutes";
-const ROUTES_NAMESPACE = "routes";
-
-class Mocks {
- static get id() {
- return "mocks";
- }
-
- constructor({ config, getLoadedMocks, logger, getLoadedRoutes, onChange, alerts }, core) {
- this._logger = logger;
- this._loggerLoadRoutes = logger.namespace(LOAD_ROUTES_NAMESPACE);
- this._loggerLoadMocks = logger.namespace(LOAD_MOCKS_NAMESPACE);
- this._loggerRoutes = logger.namespace(ROUTES_NAMESPACE);
-
- this._config = config;
- [this._currentMockOption, this._currentDelayOption] = this._config.addOptions(OPTIONS);
- this._currentMockOption.onChange(this._setCurrent.bind(this));
-
- this._getLoadedMocks = getLoadedMocks;
- this._getLoadedRoutes = getLoadedRoutes;
- this._onChange = onChange;
- this._core = core;
-
- this._alerts = alerts;
- this._alertsLoadRoutes = alerts.collection(LOAD_ROUTES_NAMESPACE);
- this._alertsMocks = alerts.collection(LOAD_MOCKS_NAMESPACE);
- this._alertsRoutes = alerts.collection(ROUTES_NAMESPACE);
-
- this._router = null;
- this._mocksDefinitions = [];
- this._mocks = [];
- this._plainMocks = [];
- this._routesDefinitions = [];
- this._plainRoutes = [];
- this._plainRoutesVariants = [];
- this._routesVariants = [];
- this._customVariants = [];
- this._customVariantsMock = null;
-
- this.router = this.router.bind(this);
- this.getDelay = this.getDelay.bind(this);
- }
-
- getDelay() {
- return this._currentDelayOption.value;
- }
-
- _reloadRouter() {
- if (this._customVariantsMock) {
- this._router = this._customVariantsMock.router;
- } else if (this._currentMock) {
- this._router = this._currentMock.router;
- } else {
- this._router = express.Router();
- }
- this._onChange();
- }
-
- _processMocks() {
- this._loggerLoadMocks.debug("Processing loaded mocks");
- this._loggerLoadMocks.silly(JSON.stringify(this._mocksDefinitions));
- this._mocks = getMocks({
- mocksDefinitions: this._mocksDefinitions,
- alerts: this._alertsMocks,
- logger: this._loggerLoadMocks,
- loggerRoutes: this._loggerRoutes,
- routeVariants: this._routesVariants,
- getGlobalDelay: this.getDelay,
- });
- }
-
- _processRoutes() {
- this._loggerLoadRoutes.debug("Processing loaded routes");
- this._loggerLoadRoutes.silly(JSON.stringify(this._routesDefinitions));
- this._routesVariants = getRouteVariants({
- routesDefinitions: this._routesDefinitions,
- alerts: this._alertsLoadRoutes,
- alertsRoutes: this._alertsRoutes,
- logger: this._loggerLoadRoutes,
- loggerRoutes: this._loggerRoutes,
- routeHandlers: this._routesVariantsHandlers,
- core: this._core,
- });
- this._loggerLoadRoutes.debug(`Processed ${this._routesVariants.length} route variants`);
- }
-
- load() {
- this._routesDefinitions = this._getLoadedRoutes();
- this._mocksDefinitions = this._getLoadedMocks();
- this._processRoutes();
- this._processMocks();
- this._mocksIds = getIds(this._mocks);
- this._plainRoutes = getPlainRoutes(this._routesDefinitions, this._routesVariants);
- this._plainRoutesVariants = getPlainRoutesVariants(this._routesVariants);
- this._plainMocks = getPlainMocks(this._mocks, this._mocksDefinitions);
- this.current = this._currentMockOption.value;
- }
-
- init(routesHandlers) {
- compileRouteValidator(routesHandlers);
- this._routesVariantsHandlers = routesHandlers;
- }
-
- router(req, res, next) {
- this._router(req, res, next);
- }
-
- _setCurrent(id) {
- this._logger.verbose(`Trying to set current mock as "${id}"`);
- let current;
- this._alerts.remove(SETTINGS_ALERT_ID);
- if (!id) {
- current = this._mocks[0];
- if (current) {
- this._alerts.set(
- SETTINGS_ALERT_ID,
- "Option 'mock' was not defined. Using the first mock found"
- );
- } else {
- this._alerts.set(SETTINGS_ALERT_ID, "Option 'mock' was not defined");
- }
- } else {
- current = this._mocks.find((mock) => mock.id === id);
- if (!current) {
- current = this._mocks[0];
- if (current) {
- this._alerts.set(
- SETTINGS_ALERT_ID,
- `Mock '${id}' was not found. Using the first one found`
- );
- }
- }
- }
- if (!current) {
- this._alerts.set(EMPTY_ALERT_ID, "No mocks found");
- } else {
- this._logger.info(`Current mock: "${current.id}"`);
- this._alerts.remove(EMPTY_ALERT_ID);
- }
-
- this._currentMock = current;
- this._currentId = (current && current.id) || null;
- this._stopUsingVariants();
- this._reloadRouter();
- }
-
- set current(id) {
- this._setCurrent(id);
- }
-
- _stopUsingVariants() {
- this._customVariants = [];
- this._customVariantsMock = null;
- }
-
- _createCustomMock() {
- const currentMockId = this._currentId;
- const alerts = this._alertsMocks.collection("custom");
- alerts.clean();
- this._customVariantsMock = getMock({
- mockDefinition: {
- id: `custom-variants:from:${currentMockId}`,
- from: currentMockId,
- routesVariants: this._customVariants,
- },
- mocksDefinitions: this._mocksDefinitions,
- routeVariants: this._routesVariants,
- getGlobalDelay: this.getDelay,
- alerts,
- logger: this._loggerLoadMocks,
- loggerRoutes: this._loggerRoutes,
- });
- }
-
- restoreRoutesVariants() {
- this._stopUsingVariants();
- this._reloadRouter();
- }
-
- useRouteVariant(variantId) {
- // TODO, validate variantId
- this._customVariants = addCustomVariant(variantId, this._customVariants);
- this._createCustomMock();
- this._reloadRouter();
- }
-
- get customRoutesVariants() {
- return [...this._customVariants];
- }
-
- get current() {
- return this._currentId;
- }
-
- get ids() {
- return [...this._mocksIds];
- }
-
- get plainMocks() {
- return [...this._plainMocks];
- }
-
- get plainRoutes() {
- return [...this._plainRoutes];
- }
-
- get plainRoutesVariants() {
- return [...this._plainRoutesVariants];
- }
-}
-
-module.exports = Mocks;
diff --git a/packages/core/src/plugins/Plugins.js b/packages/core/src/plugins/Plugins.js
index 62bce4ea6..f3ccdc943 100644
--- a/packages/core/src/plugins/Plugins.js
+++ b/packages/core/src/plugins/Plugins.js
@@ -11,8 +11,9 @@ Unless required by applicable law or agreed to in writing, software distributed
const isPromise = require("is-promise");
const { isObject, isFunction } = require("lodash");
-const { scopedAlertsMethods } = require("../support/helpers");
-const CustomCore = require("../CustomCore");
+const { scopedAlertsMethods } = require("../alerts/legacyHelpers");
+const CoreApi = require("../common/CoreApi");
+const { docsUrl } = require("../common/helpers");
const OPTIONS = [
{
@@ -29,7 +30,9 @@ const OPTIONS = [
];
function formatDeprecatedMessage(format) {
- return `Defining Plugins as ${format} is deprecated and it won't be supported in next major version. Consider migrating it to a Class Plugin: https://www.mocks-server.org/docs/plugins-developing-plugins`;
+ return `Defining Plugins as ${format} is deprecated and it won't be supported in next major version. Consider migrating it to a Class Plugin: ${docsUrl(
+ "plugins/development"
+ )}`;
}
class Plugins {
@@ -45,7 +48,7 @@ class Plugins {
addAlert,
removeAlerts,
renameAlerts,
- createMocksLoader,
+ createCollectionsLoader,
createRoutesLoader,
},
core
@@ -66,7 +69,7 @@ class Plugins {
this._addAlert = addAlert;
this._removeAlerts = removeAlerts;
this._renameAlerts = renameAlerts;
- this._createMocksLoader = createMocksLoader;
+ this._createCollectionsLoader = createCollectionsLoader;
this._createRoutesLoader = createRoutesLoader;
this._core = core;
this._pluginsInstances = [];
@@ -124,7 +127,7 @@ class Plugins {
_catchRegisterError(error, index) {
const pluginId = this._pluginId(index);
- this._alertsRegister.set(pluginId, `Error registering plugin "${pluginId}"`, error);
+ this._alertsRegister.set(pluginId, `Error registering plugin '${pluginId}'`, error);
return {};
}
@@ -136,7 +139,7 @@ class Plugins {
pluginAlerts,
pluginLogger,
optionsAdded = false,
- customCore;
+ coreApi;
const pluginOptions = { core: this._core, ...pluginMethods };
if (isObject(Plugin) && !isFunction(Plugin)) {
pluginInstance = Plugin;
@@ -156,9 +159,9 @@ class Plugins {
alerts: pluginAlerts,
logger: pluginLogger,
};
- customCore = new CustomCore(pluginFinalOptions);
- pluginInstance = new Plugin(customCore);
- this._pluginsOptions.push(customCore);
+ coreApi = new CoreApi(pluginFinalOptions);
+ pluginInstance = new Plugin(coreApi);
+ this._pluginsOptions.push(coreApi);
optionsAdded = true;
this._pluginsInstances.push(pluginInstance);
this._pluginsRegistered++;
@@ -166,7 +169,7 @@ class Plugins {
if (error.message.includes("is not a constructor")) {
try {
const pluginFunc = Plugin;
- pluginInstance = pluginFunc(new CustomCore(pluginOptions)) || {};
+ pluginInstance = pluginFunc(new CoreApi(pluginOptions)) || {};
this._pluginsInstances.push(pluginInstance);
this._pluginsRegistered++;
formatIsFunction = true;
@@ -200,20 +203,20 @@ class Plugins {
alerts: pluginAlerts,
logger: pluginLogger,
};
- customCore = new CustomCore(pluginFinalOptions);
+ coreApi = new CoreApi(pluginFinalOptions);
if (optionsAdded) {
this._pluginsOptions.pop();
}
- this._pluginsOptions.push(customCore);
+ this._pluginsOptions.push(coreApi);
} else {
- if (!customCore) {
- customCore = new CustomCore(pluginFinalOptions);
+ if (!coreApi) {
+ coreApi = new CoreApi(pluginFinalOptions);
}
- this._pluginsOptions.push(customCore);
+ this._pluginsOptions.push(coreApi);
}
if (isFunction(pluginInstance.register)) {
try {
- pluginInstance.register(customCore);
+ pluginInstance.register(coreApi);
} catch (error) {
this._catchRegisterError(error, pluginIndex);
this._pluginsRegistered = this._pluginsRegistered - 1;
@@ -233,7 +236,7 @@ class Plugins {
if (pluginIndex === this._plugins.length) {
return Promise.resolve();
}
- const loadMocks = this._createMocksLoader();
+ const loadMocks = this._createCollectionsLoader();
const loadRoutes = this._createRoutesLoader();
const pluginMethods = {
loadMocks,
@@ -255,7 +258,7 @@ class Plugins {
_catchInitError(error, index) {
this._pluginsInitialized = this._pluginsInitialized - 1;
const pluginId = this._pluginId(index);
- this._alertsInit.set(pluginId, `Error initializating plugin "${pluginId}"`, error);
+ this._alertsInit.set(pluginId, `Error initializating plugin '${pluginId}'`, error);
this._logger.debug(error.toString());
return Promise.resolve();
}
@@ -273,7 +276,7 @@ class Plugins {
this._pluginsInitialized = this._pluginsInitialized - 1;
return initNextPlugin();
}
- this._logger.debug(`Initializing plugin "${pluginId}"`);
+ this._logger.debug(`Initializing plugin '${pluginId}'`);
let pluginInit;
try {
pluginInit = this._pluginsInstances[pluginIndex].init(this._pluginsOptions[pluginIndex]);
@@ -294,7 +297,7 @@ class Plugins {
_catchStartError(error, index) {
this._pluginsStarted = this._pluginsStarted - 1;
const pluginId = this._pluginId(index);
- this._alertsStart.set(pluginId, `Error starting plugin "${pluginId}"`, error);
+ this._alertsStart.set(pluginId, `Error starting plugin '${pluginId}'`, error);
this._logger.debug(error.toString());
return Promise.resolve();
}
@@ -312,7 +315,7 @@ class Plugins {
this._pluginsStarted = this._pluginsStarted - 1;
return startNextPlugin();
}
- this._logger.debug(`Starting plugin "${pluginId}"`);
+ this._logger.debug(`Starting plugin '${pluginId}'`);
let pluginStart;
try {
pluginStart = this._pluginsInstances[pluginIndex].start(this._pluginsOptions[pluginIndex]);
@@ -333,7 +336,7 @@ class Plugins {
_catchStopError(error, index) {
this._pluginsStopped = this._pluginsStopped - 1;
const pluginId = this._pluginId(index);
- this._alertsStop.set(pluginId, `Error stopping plugin "${pluginId}"`, error);
+ this._alertsStop.set(pluginId, `Error stopping plugin '${pluginId}'`, error);
this._logger.debug(error.toString());
return Promise.resolve();
}
@@ -352,7 +355,7 @@ class Plugins {
this._pluginsStopped = this._pluginsStopped - 1;
return stopNextPlugin();
}
- this._logger.debug(`Stopping plugin "${pluginId}"`);
+ this._logger.debug(`Stopping plugin '${pluginId}'`);
let pluginStop;
try {
pluginStop = this._pluginsInstances[pluginIndex].stop(this._pluginsOptions[pluginIndex]);
diff --git a/packages/core/src/routes-handlers/RoutesHandlers.js b/packages/core/src/routes-handlers/RoutesHandlers.js
deleted file mode 100644
index ce2bb34c3..000000000
--- a/packages/core/src/routes-handlers/RoutesHandlers.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-Copyright 2022 Javier Brea
-
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-*/
-
-// Default routes handler
-const DefaultRoutesHandler = require("./handlers/Default");
-const Json = require("./handlers/Json");
-const Middleware = require("./handlers/Middleware");
-
-class RoutesHandlers {
- constructor({ logger }) {
- this._logger = logger;
- this._registeredRouteHandlers = [];
- this._routeHandlers = [DefaultRoutesHandler, Json, Middleware];
- }
-
- add(RoutesHandler) {
- this._routeHandlers.push(RoutesHandler);
- }
-
- register(routeHandlers = []) {
- this._routeHandlers = this._routeHandlers.concat(routeHandlers);
- return this._registerHandlers().then(() => {
- this._logger.verbose(
- `Registered ${this._registeredRouteHandlers.length} routes handlers without errors`
- );
- return Promise.resolve();
- });
- }
-
- _registerHandlers() {
- this._routeHandlers.forEach((RouteHandler) => {
- // TODO, check id, etc..
- this._registeredRouteHandlers.push(RouteHandler);
- this._logger.verbose(`Registering "${RouteHandler.id}" routes handler`);
- });
- return Promise.resolve();
- }
-
- get handlers() {
- return this._registeredRouteHandlers;
- }
-}
-
-module.exports = RoutesHandlers;
diff --git a/packages/core/src/routes-handlers/helpers.js b/packages/core/src/routes-handlers/helpers.js
deleted file mode 100644
index 94e0c815a..000000000
--- a/packages/core/src/routes-handlers/helpers.js
+++ /dev/null
@@ -1,23 +0,0 @@
-function isVersion4(Handler) {
- return Handler.version === "4";
-}
-
-function getDataFromVariant(variant, Handler) {
- if (isVersion4(Handler)) {
- return variant.response;
- }
- return variant;
-}
-
-function getPreview(variantInstance) {
- if (isVersion4(variantInstance.constructor)) {
- return variantInstance.preview;
- }
- return variantInstance.plainResponsePreview;
-}
-
-module.exports = {
- isVersion4,
- getDataFromVariant,
- getPreview,
-};
diff --git a/packages/core/src/scaffold/Scaffold.js b/packages/core/src/scaffold/Scaffold.js
index 3ceffc161..df345ad85 100644
--- a/packages/core/src/scaffold/Scaffold.js
+++ b/packages/core/src/scaffold/Scaffold.js
@@ -18,7 +18,7 @@ const READ_WRITE_FILE_OPTIONS = {
encoding: "utf8",
};
-const MOCKS_SCAFFOLD_PATH = path.resolve(__dirname, "mocks");
+const FILES_SCAFFOLD_PATH = path.resolve(__dirname, "mocks");
const DEFAULT_CONFIG_FILE = "mocks.config.js";
function readTemplate(fileName) {
@@ -109,7 +109,11 @@ class Scaffold {
this._logger = logger;
this._config = config;
this._readConfigFileOption = this._config.namespace("config").option("readFile");
- this._mockSelectedOption = this._config.namespace("mocks").option("selected");
+ this._filesEnabledOption = this._config.namespace("files").option("enabled");
+ this._collectionSelectedOption = this._config
+ .namespace("mock")
+ .namespace("collections")
+ .option("selected");
this._alerts = alerts;
}
@@ -136,9 +140,9 @@ class Scaffold {
);
}
- _createMocks(destPath) {
- this._logger.info("Creating mocks folder");
- return fsExtra.copy(MOCKS_SCAFFOLD_PATH, destPath);
+ _createFolder(destPath) {
+ this._logger.info("Creating scaffold folder");
+ return fsExtra.copy(FILES_SCAFFOLD_PATH, destPath);
}
_checkAndCreateConfigScaffold() {
@@ -146,27 +150,24 @@ class Scaffold {
if (this._readConfigFileOption.value && !configFileLoaded) {
this._alerts.set("config", "Configuration file was not found. A scaffold was created");
- // Set base mock, which is the one created in the scaffold
- if (!this._mockSelectedOption.value) {
- this._mockSelectedOption.value = "base";
- }
-
+ // LEGACY, Set base collection, which is the one created in the scaffold, when selected collection is not defined in the option. (when legacy option is removed)
+ // If the collection selected option value is not set, it should be set as "base"
return this._createConfig();
}
return Promise.resolve();
}
- _checkAndCreateMocksScaffold(filesLoaderPath) {
- if (!fsExtra.existsSync(filesLoaderPath)) {
- this._alerts.set("mocks", "Mocks folder was not found. A scaffold was created");
- return this._createMocks(filesLoaderPath);
+ _checkAndCreateFolderScaffold(filesLoaderPath) {
+ if (this._filesEnabledOption.value && !fsExtra.existsSync(filesLoaderPath)) {
+ this._alerts.set("folder", "Mocks Server folder was not found. A scaffold was created");
+ return this._createFolder(filesLoaderPath);
}
return Promise.resolve();
}
init({ filesLoaderPath }) {
return Promise.all([
- this._checkAndCreateMocksScaffold(filesLoaderPath),
+ this._checkAndCreateFolderScaffold(filesLoaderPath),
this._checkAndCreateConfigScaffold(),
]);
}
diff --git a/packages/core/src/scaffold/config.hbs b/packages/core/src/scaffold/config.hbs
index 36bfa4512..0c69e3921 100644
--- a/packages/core/src/scaffold/config.hbs
+++ b/packages/core/src/scaffold/config.hbs
@@ -1,6 +1,6 @@
// For a detailed explanation regarding each configuration property, visit:
-// https://mocks-server.org/docs/configuration-options
-// https://mocks-server.org/docs/configuration-methods
+// https://www.mocks-server.org/docs/configuration/how-to-change-settings
+// https://www.mocks-server.org/docs/configuration/options
module.exports = {
{{#each options}}
diff --git a/packages/core/src/scaffold/mocks/collections.json b/packages/core/src/scaffold/mocks/collections.json
new file mode 100644
index 000000000..213cd8c45
--- /dev/null
+++ b/packages/core/src/scaffold/mocks/collections.json
@@ -0,0 +1,21 @@
+[
+ {
+ "id": "base",
+ "routes": ["add-headers:enabled", "get-users:success", "get-user:success"]
+ },
+ {
+ "id": "no-headers",
+ "from": "base",
+ "routes": ["add-headers:disabled"]
+ },
+ {
+ "id": "all-users",
+ "from": "base",
+ "routes": ["get-users:all", "get-user:id-3"]
+ },
+ {
+ "id": "user-real",
+ "from": "no-headers",
+ "routes": ["get-user:real"]
+ }
+]
diff --git a/packages/core/src/scaffold/mocks/routes/common.js b/packages/core/src/scaffold/mocks/routes/common.js
new file mode 100644
index 000000000..e5d2b63ce
--- /dev/null
+++ b/packages/core/src/scaffold/mocks/routes/common.js
@@ -0,0 +1,32 @@
+// Use this file only as a guide for first steps using middleware variants. You can delete it when you have understood the concepts.
+// For a detailed explanation about using middlewares, visit:
+// https://mocks-server.org/docs/usage/variants/middlewares
+
+module.exports = [
+ {
+ id: "add-headers", //route id
+ url: "*", // url in express format
+ method: ["GET", "POST", "PUT", "PATCH"], // HTTP methods
+ variants: [
+ {
+ id: "enabled", // variant id
+ handler: "middleware", // variant handler id
+ options: {
+ // Express middleware to execute
+ middleware: (_req, res, next, core) => {
+ res.set("x-mocks-server-example", "some-value");
+ core.logger.info("Custom header added by route variant middleware");
+ next();
+ },
+ },
+ },
+ {
+ id: "disabled", // variant id
+ handler: "middleware", // variant handler id
+ options: {
+ middleware: (_req, _res, next) => next(), // Express middleware to execute
+ },
+ },
+ ],
+ },
+];
diff --git a/packages/core/src/scaffold/mocks/routes/middlewares.js b/packages/core/src/scaffold/mocks/routes/middlewares.js
deleted file mode 100644
index 1bf5e421f..000000000
--- a/packages/core/src/scaffold/mocks/routes/middlewares.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Use this file only as a guide for first steps using middlewares. Delete it when no more needed.
-// For a detailed explanation about using middlewares, visit:
-// https://mocks-server.org/docs/guides-using-middlewares
-
-module.exports = [
- {
- id: "add-headers",
- url: "*",
- method: "GET",
- variants: [
- {
- id: "enabled",
- handler: "middleware",
- response: {
- middleware: (_req, res, next, core) => {
- res.set("x-mocks-server-example", "some-value");
- core.logger.info("Custom header added by route variant middleware");
- next();
- },
- },
- },
- {
- id: "disabled",
- handler: "middleware",
- response: {
- middleware: (_req, _res, next) => next(),
- },
- },
- ],
- },
-];
diff --git a/packages/core/src/scaffold/mocks/routes/users.js b/packages/core/src/scaffold/mocks/routes/users.js
index 00384b7a1..7445df806 100644
--- a/packages/core/src/scaffold/mocks/routes/users.js
+++ b/packages/core/src/scaffold/mocks/routes/users.js
@@ -1,6 +1,6 @@
-// Use this file only as a guide for first steps. Delete it when you have added your own routes files.
+// Use this file only as a guide for first steps using routes. Delete it when you have added your own route files.
// For a detailed explanation regarding each routes property, visit:
-// https://mocks-server.org/docs/get-started-routes
+// https://mocks-server.org/docs/usage/routes
// users data
const USERS = [
@@ -14,27 +14,47 @@ const USERS = [
},
];
+const ALL_USERS = [
+ ...USERS,
+ {
+ id: 3,
+ name: "Tommy",
+ },
+ {
+ id: 4,
+ name: "Timmy",
+ },
+];
+
module.exports = [
{
- id: "get-users", // id of the route
+ id: "get-users", // route id
url: "/api/users", // url in express format
method: "GET", // HTTP method
variants: [
{
- id: "success", // id of the variant
- handler: "json", // variant handler
- response: {
+ id: "success", // variant id
+ type: "json", // variant handler id
+ options: {
status: 200, // status to send
body: USERS, // body to send
},
},
{
- id: "error", // id of the variant
- handler: "json", // variant handler
- response: {
+ id: "all", // variant id
+ type: "json", // variant handler id
+ options: {
+ status: 200, // status to send
+ body: ALL_USERS, // body to send
+ },
+ },
+ {
+ id: "error", // variant id
+ type: "json", // variant handler id
+ options: {
status: 400, // status to send
+ // body to send
body: {
- // body to send
message: "Error",
},
},
@@ -42,22 +62,31 @@ module.exports = [
],
},
{
- id: "get-user", // id of the route
+ id: "get-user", // route id
url: "/api/users/:id", // url in express format
method: "GET", // HTTP method
variants: [
{
- id: "success", // id of the variant
- handler: "json", // variant handler
- response: {
+ id: "success", // variant id
+ type: "json", // variant handler id
+ options: {
status: 200, // status to send
body: USERS[0], // body to send
},
},
{
- id: "real", // id of the variant
- handler: "middleware", // variant handler
- response: {
+ id: "id-3", // variant id
+ type: "json", // variant handler id
+ options: {
+ status: 200, // status to send
+ body: ALL_USERS[2], // body to send
+ },
+ },
+ {
+ id: "real", // variant id
+ type: "middleware", // variant handler id
+ options: {
+ // Express middleware to execute
middleware: (req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
diff --git a/packages/core/src/server/Server.js b/packages/core/src/server/Server.js
index dd37720a0..8f7d1ce60 100644
--- a/packages/core/src/server/Server.js
+++ b/packages/core/src/server/Server.js
@@ -105,7 +105,7 @@ class Server {
return "server";
}
- constructor({ config, alerts, mocksRouter, logger }) {
+ constructor({ config, alerts, routesRouter, logger }) {
this._logger = logger;
this._config = config;
const corsConfigNamespace = this._config.addNamespace(CORS_NAMESPACE);
@@ -136,7 +136,7 @@ class Server {
this._urlEncodedBodyParserEnabledOption.onChange(this.restart);
this._urlEncodedBodyParserOptionsOption.onChange(this.restart);
- this._mocksRouter = mocksRouter;
+ this._routesRouter = routesRouter;
this._customRouters = [];
this._error = null;
this._alerts = alerts;
@@ -180,7 +180,7 @@ class Server {
// TODO, move to variants router. Add options to routes to configure it
this._express.use(logRequest({ logger: this._logger }));
this._registerCustomRouters();
- this._express.use(this._mocksRouter);
+ this._express.use(this._routesRouter);
// TODO, Add options to allow to disable or configure it
this._express.use(notFound({ logger: this._logger }));
@@ -293,7 +293,7 @@ class Server {
return routerIndex;
}
- addCustomRouter(path, router) {
+ addRouter(path, router) {
this._logger.info(`Adding custom router with path ${path}`);
this._customRouters.push({
path,
@@ -302,7 +302,7 @@ class Server {
return this._reinitServer();
}
- removeCustomRouter(path, router) {
+ removeRouter(path, router) {
this._logger.info(`Removing custom router with path ${path}`);
let indexToRemove = this._getCustomRouterIndex(path, router);
if (indexToRemove !== null) {
@@ -317,6 +317,7 @@ class Server {
return this.start();
}
+ // LEGACY, to be removed
get error() {
return this._error;
}
diff --git a/packages/core/src/server/middlewares.js b/packages/core/src/server/middlewares.js
index 85577848e..1fb334cce 100644
--- a/packages/core/src/server/middlewares.js
+++ b/packages/core/src/server/middlewares.js
@@ -42,7 +42,7 @@ const errorHandler =
const stack = isBoom ? null : err && err.stack;
const error = isBoom ? err : err && Boom.badImplementation(err);
if (error) {
- logger.error(`Sending Error "${error.message}" | ${req.id}`);
+ logger.error(`Sending Error '${error.message}' | ${req.id}`);
if (stack) {
logger.silly(stack.toString());
}
diff --git a/packages/core/src/UpdateNotifier.js b/packages/core/src/update-notifier/UpdateNotifier.js
similarity index 95%
rename from packages/core/src/UpdateNotifier.js
rename to packages/core/src/update-notifier/UpdateNotifier.js
index 1871ebaa8..24977cfe9 100644
--- a/packages/core/src/UpdateNotifier.js
+++ b/packages/core/src/update-notifier/UpdateNotifier.js
@@ -10,7 +10,7 @@ Unless required by applicable law or agreed to in writing, software distributed
const updateNotifier = require("update-notifier");
-const packageJson = require("../package.json");
+const packageJson = require("../../package.json");
class UpdateNotifier {
static get id() {
diff --git a/packages/core/src/variant-handlers/VariantHandlers.js b/packages/core/src/variant-handlers/VariantHandlers.js
new file mode 100644
index 000000000..152012bb2
--- /dev/null
+++ b/packages/core/src/variant-handlers/VariantHandlers.js
@@ -0,0 +1,70 @@
+/*
+Copyright 2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const DefaultVariantHandler = require("./handlers/Default");
+const Json = require("./handlers/Json");
+const Middleware = require("./handlers/Middleware");
+
+const OPTIONS = [
+ {
+ description: "VariantHandlers to be registered",
+ name: "register",
+ type: "array",
+ default: [],
+ },
+];
+
+class VariantHandlers {
+ static get id() {
+ return "variantHandlers";
+ }
+
+ constructor({ logger, config }) {
+ this._logger = logger;
+ this._registeredVariantHandlers = [];
+ this._coreVariantHandlers = [DefaultVariantHandler, Json, Middleware];
+ this._config = config;
+
+ [this._registerOption] = this._config.addOptions(OPTIONS);
+ }
+
+ _registerOne(VariantHandler) {
+ // TODO, check id, etc..
+ this._logger.verbose(`Registering '${VariantHandler.id}' variant handler`);
+ this._registeredVariantHandlers.push(VariantHandler);
+ }
+
+ register(variantHandlers) {
+ variantHandlers.forEach((VariantHandler) => {
+ this._registerOne(VariantHandler);
+ });
+ }
+
+ // LEGACY, remove parameter
+ registerConfig(variantHandlersFromLegacyConfig) {
+ const variantHandlersToRegister = [
+ ...this._coreVariantHandlers,
+ ...variantHandlersFromLegacyConfig,
+ ...this._registerOption.value,
+ ];
+ this.register(variantHandlersToRegister);
+ this._logger.verbose(
+ `Registered ${variantHandlersToRegister.length} variant handlers without errors`
+ );
+
+ return Promise.resolve();
+ }
+
+ get handlers() {
+ return this._registeredVariantHandlers;
+ }
+}
+
+module.exports = VariantHandlers;
diff --git a/packages/core/src/routes-handlers/handlers/Default.js b/packages/core/src/variant-handlers/handlers/Default.js
similarity index 99%
rename from packages/core/src/routes-handlers/handlers/Default.js
rename to packages/core/src/variant-handlers/handlers/Default.js
index f3b663804..9265e7b7f 100644
--- a/packages/core/src/routes-handlers/handlers/Default.js
+++ b/packages/core/src/variant-handlers/handlers/Default.js
@@ -12,6 +12,7 @@ Unless required by applicable law or agreed to in writing, software distributed
const { isFunction } = require("lodash");
+// LEGACY, to be removed
class DefaultRoutesHandler {
static get id() {
return "default";
diff --git a/packages/core/src/routes-handlers/handlers/Json.js b/packages/core/src/variant-handlers/handlers/Json.js
similarity index 83%
rename from packages/core/src/routes-handlers/handlers/Json.js
rename to packages/core/src/variant-handlers/handlers/Json.js
index 5f8b921f0..e4a1ec970 100644
--- a/packages/core/src/routes-handlers/handlers/Json.js
+++ b/packages/core/src/variant-handlers/handlers/Json.js
@@ -45,26 +45,26 @@ class Json {
};
}
- constructor(response, core) {
- this._response = response;
+ constructor(options, core) {
+ this._options = options;
this._logger = core.logger;
this._core = core;
}
middleware(req, res) {
- if (this._response.headers) {
+ if (this._options.headers) {
this._logger.debug(`Setting headers | req: ${req.id}`);
- res.set(this._response.headers);
+ res.set(this._options.headers);
}
- res.status(this._response.status);
+ res.status(this._options.status);
this._logger.verbose(`Sending response | req: ${req.id}`);
- res.send(this._response.body);
+ res.send(this._options.body);
}
get preview() {
return {
- body: this._response.body,
- status: this._response.status,
+ body: this._options.body,
+ status: this._options.status,
};
}
}
diff --git a/packages/core/src/routes-handlers/handlers/Middleware.js b/packages/core/src/variant-handlers/handlers/Middleware.js
similarity index 90%
rename from packages/core/src/routes-handlers/handlers/Middleware.js
rename to packages/core/src/variant-handlers/handlers/Middleware.js
index b2e3b2b55..e5c8cbbc7 100644
--- a/packages/core/src/routes-handlers/handlers/Middleware.js
+++ b/packages/core/src/variant-handlers/handlers/Middleware.js
@@ -32,15 +32,15 @@ class Json {
};
}
- constructor(response, core) {
- this._response = response;
+ constructor(options, core) {
+ this._options = options;
this._logger = core.logger;
this._core = core;
}
middleware(req, res, next) {
this._logger.verbose(`Executing middleware | req: ${req.id}`);
- this._response.middleware(req, res, next, this._core);
+ this._options.middleware(req, res, next, this._core);
}
get preview() {
diff --git a/packages/core/src/variant-handlers/helpers.js b/packages/core/src/variant-handlers/helpers.js
new file mode 100644
index 000000000..df3204c69
--- /dev/null
+++ b/packages/core/src/variant-handlers/helpers.js
@@ -0,0 +1,44 @@
+const { docsUrl } = require("../common/helpers");
+
+function isVersion4(Handler) {
+ return Handler.version === "4";
+}
+
+function getDataFromVariant(variant, Handler, alerts) {
+ if (alerts && Handler.deprecated) {
+ alerts.set(
+ Handler.id,
+ `Handler '${
+ Handler.id
+ }' is deprecated and will be removed in next major version. Consider using another handler. ${docsUrl(
+ "releases/migrating-from-v3#route-variants-handlers"
+ )}`
+ );
+ }
+
+ if (isVersion4(Handler)) {
+ if (alerts && variant.response) {
+ alerts.set(
+ "response",
+ `'response' property in variants is deprecated and will be removed in next major version. Use 'options' instead.`
+ );
+ }
+
+ // LEGACY, deprecate "response"
+ return variant.options || variant.response;
+ }
+ return variant;
+}
+
+function getPreview(variantInstance) {
+ if (isVersion4(variantInstance.constructor)) {
+ return variantInstance.preview;
+ }
+ return variantInstance.plainResponsePreview;
+}
+
+module.exports = {
+ isVersion4,
+ getDataFromVariant,
+ getPreview,
+};
diff --git a/packages/core/test/Core.mocks.js b/packages/core/test/Core.mocks.js
index f942fc3c9..4f764bd0d 100644
--- a/packages/core/test/Core.mocks.js
+++ b/packages/core/test/Core.mocks.js
@@ -40,6 +40,7 @@ class CoreMock {
mocks: {
useRouteVariant: this._sandbox.stub(),
restoreRoutesVariants: this._sandbox.stub(),
+ restoreRouteVariants: this._sandbox.stub(),
},
logs: ["foo", "foo2"],
logger: {
@@ -55,6 +56,24 @@ class CoreMock {
_deprecationAlerts: {
set: this._sandbox.stub(),
},
+ server: {
+ restart: this._sandbox.stub(),
+ addRouter: this._sandbox.stub(),
+ removeRouter: this._sandbox.stub(),
+ },
+ mock: {
+ onChange: this._sandbox.stub(),
+ useRouteVariant: this._sandbox.stub(),
+ restoreRouteVariants: this._sandbox.stub(),
+ createLoaders: this._sandbox.stub().returns({
+ loadCollections: this._sandbox.stub(),
+ loadRoutes: this._sandbox.stub(),
+ }),
+ },
+ variantHandlers: {
+ register: this._sandbox.stub(),
+ },
+ version: "foo-version",
};
Core.mockImplementation(() => this._stubs);
diff --git a/packages/core/test/Core.spec.js b/packages/core/test/Core.spec.js
index 40dbc2e27..775512344 100644
--- a/packages/core/test/Core.spec.js
+++ b/packages/core/test/Core.spec.js
@@ -12,24 +12,24 @@ const sinon = require("sinon");
const { NestedCollections } = require("@mocks-server/nested-collections");
const { Logger } = require("@mocks-server/logger");
-const MocksMock = require("./mocks/Mocks.mock.js");
+const MockMock = require("./mock/Mock.mock.js");
const ServerMocks = require("./server/Server.mocks.js");
const PluginsMocks = require("./plugins/Plugins.mocks.js");
-const ConfigMocks = require("./Config.mocks.js");
-const AlertsMocks = require("./AlertsLegacy.mocks.js");
-const LoadersMocks = require("./Loaders.mocks.js");
-const FilesLoaderMocks = require("./files-loader/FilesLoader.mocks.js");
+const ConfigMocks = require("./common/Config.mocks.js");
+const AlertsMocks = require("./alerts/AlertsLegacy.mocks.js");
+const FilesLoadersMocks = require("./files/FilesLoaders.mocks.js");
const ScaffoldMocks = require("./scaffold/Scaffold.mocks.js");
-const UpdateNotifierMock = require("./UpdateNotifier.mock.js");
+const UpdateNotifierMock = require("./update-notifier/UpdateNotifier.mock.js");
const Core = require("../src/Core");
-const tracer = require("../src/tracer");
-const Alerts = require("../src/Alerts");
+const tracer = require("../src/common/legacyTracer");
+const Alerts = require("../src/alerts/Alerts");
+const { version } = require("../package.json");
describe("Core", () => {
let sandbox;
- let mocksMock;
- let mocksInstance;
+ let mockMock;
+ let mockInstance;
let serverMocks;
let serverInstance;
let pluginsMocks;
@@ -37,45 +37,42 @@ describe("Core", () => {
let configMocks;
let alertsMocks;
let loadersMocks;
- let filesLoaderMocks;
+ let filesLoadersMocks;
let scaffoldMocks;
let core;
- let mockedLoader;
let updateNotifierMock;
beforeEach(async () => {
sandbox = sinon.createSandbox();
updateNotifierMock = new UpdateNotifierMock();
- mocksMock = new MocksMock();
- mocksInstance = mocksMock.stubs.instance;
+ mockMock = new MockMock();
+ mockInstance = mockMock.stubs.instance;
serverMocks = new ServerMocks();
serverInstance = serverMocks.stubs.instance;
pluginsMocks = new PluginsMocks();
pluginsInstance = pluginsMocks.stubs.instance;
alertsMocks = new AlertsMocks();
- loadersMocks = new LoadersMocks();
+ loadersMocks = mockMock.stubs.loaders;
configMocks = new ConfigMocks();
- filesLoaderMocks = new FilesLoaderMocks();
+ filesLoadersMocks = new FilesLoadersMocks();
scaffoldMocks = new ScaffoldMocks();
sandbox.stub(NestedCollections.prototype, "onChange");
sandbox.stub(Logger.prototype, "onChangeGlobalStore");
sandbox.stub(Logger.prototype, "setLevel");
- mockedLoader = sandbox.stub();
- loadersMocks.stubs.instance.new.returns(mockedLoader);
core = new Core();
+ core.variantHandlers._registerOption.value = [];
await core.init();
});
afterEach(() => {
sandbox.restore();
- mocksMock.restore();
+ mockMock.restore();
serverMocks.restore();
configMocks.restore();
pluginsMocks.restore();
alertsMocks.restore();
- loadersMocks.restore();
- filesLoaderMocks.restore();
+ filesLoadersMocks.restore();
scaffoldMocks.restore();
updateNotifierMock.restore();
});
@@ -93,64 +90,53 @@ describe("Core", () => {
});
});
- describe("Plugins callbacks", () => {
- describe("createMocksLoader", () => {
+ describe("version", () => {
+ it("should return current version", async () => {
+ core = new Core();
+ expect(core.version).toEqual(version);
+ });
+ });
+
+ describe("Plugins parameters", () => {
+ describe("createCollectionsLoader", () => {
it("should return a new loader", () => {
- const FOO_LOADER = "foo";
- loadersMocks.stubs.instance.new.returns(FOO_LOADER);
- expect(pluginsMocks.stubs.Constructor.mock.calls[0][0].createMocksLoader()).toEqual(
- FOO_LOADER
+ pluginsMocks.stubs.Constructor.mock.calls[0][0].createCollectionsLoader()(
+ "foo-collection"
);
+ expect(loadersMocks.loadCollections.callCount).toEqual(1);
+ expect(loadersMocks.loadCollections.getCall(0).args[0]).toEqual("foo-collection");
});
});
describe("createRoutesLoader", () => {
it("should return a new loader", () => {
- const FOO_LOADER = "foo";
- loadersMocks.stubs.instance.new.returns(FOO_LOADER);
- expect(pluginsMocks.stubs.Constructor.mock.calls[0][0].createRoutesLoader()).toEqual(
- FOO_LOADER
- );
+ pluginsMocks.stubs.Constructor.mock.calls[0][0].createRoutesLoader()("foo-routes");
+ expect(loadersMocks.loadRoutes.callCount).toEqual(1);
+ expect(loadersMocks.loadRoutes.getCall(0).args[0]).toEqual("foo-routes");
});
});
});
describe("loadMocks method", () => {
- it("should call to mocks loader", () => {
+ it("should call to mock loader loadCollections", () => {
core.loadMocks("foo");
- expect(mockedLoader.getCall(0).args[0]).toEqual("foo");
+ expect(loadersMocks.loadCollections.getCall(0).args[0]).toEqual("foo");
});
});
describe("loadRoutes method", () => {
- it("should call to mocks loader", () => {
+ it("should call to mock loader loadRoutes", () => {
core.loadRoutes("foo");
- expect(mockedLoader.getCall(0).args[0]).toEqual("foo");
+ expect(loadersMocks.loadRoutes.getCall(0).args[0]).toEqual("foo");
});
});
describe("Mocks callbacks", () => {
- describe("getLoadedMocks", () => {
- it("should return mocksLoaders contents", () => {
- expect(mocksMock.stubs.Constructor.mock.calls[0][0].getLoadedMocks()).toEqual(
- core._mocksLoaders.contents
- );
- });
- });
-
- describe("getLoadedRoutes", () => {
- it("should return routesLoaders contents", () => {
- expect(mocksMock.stubs.Constructor.mock.calls[0][0].getLoadedRoutes()).toEqual(
- core._routesLoaders.contents
- );
- });
- });
-
describe("onChange", () => {
- it("should emit a change:mocks event", () => {
+ it("should emit a change:mock event", () => {
const spy = sandbox.spy();
core.onChangeMocks(spy);
- mocksMock.stubs.Constructor.mock.calls[0][0].onChange();
+ mockMock.stubs.Constructor.mock.calls[0][0].onChange();
expect(spy.callCount).toEqual(1);
});
});
@@ -191,6 +177,14 @@ describe("Core", () => {
expect(pluginsInstance.register.callCount).toEqual(1);
});
+ it("should add an Alert if legacy routesHandlers option is set", async () => {
+ core = new Core();
+ sandbox.spy(core._deprecationAlerts, "set");
+ core._variantHandlersOption.hasBeenSet = true;
+ await core.init();
+ expect(core._deprecationAlerts.set.callCount).toEqual(1);
+ });
+
it("should init server", () => {
expect(serverInstance.init.callCount).toEqual(1);
});
@@ -260,14 +254,14 @@ describe("Core", () => {
describe("addRouter method", () => {
it("should add router to server", () => {
core.addRouter();
- expect(serverInstance.addCustomRouter.callCount).toEqual(1);
+ expect(serverInstance.addRouter.callCount).toEqual(1);
});
});
describe("removeRouter method", () => {
it("should remove router from server", () => {
core.removeRouter();
- expect(serverInstance.removeCustomRouter.callCount).toEqual(1);
+ expect(serverInstance.removeRouter.callCount).toEqual(1);
});
});
@@ -275,8 +269,8 @@ describe("Core", () => {
it("should add Route Handler", () => {
core.addRoutesHandler("foo");
// TODO, do not use private properties in testing
- expect(core._routesHandlers._routeHandlers.length).toEqual(4);
- expect(core._routesHandlers._routeHandlers[3]).toEqual("foo");
+ expect(core._variantHandlers._registeredVariantHandlers.length).toEqual(4);
+ expect(core._variantHandlers._registeredVariantHandlers[3]).toEqual("foo");
});
});
@@ -284,7 +278,7 @@ describe("Core", () => {
it("should add listener to eventEmitter", () => {
const spy = sandbox.spy();
core.onChangeMocks(spy);
- core._eventEmitter.emit("change:mocks");
+ core._eventEmitter.emit("change:mock");
expect(spy.callCount).toEqual(1);
});
@@ -292,10 +286,10 @@ describe("Core", () => {
expect.assertions(2);
const spy = sandbox.spy();
const removeCallback = core.onChangeMocks(spy);
- core._eventEmitter.emit("change:mocks");
+ core._eventEmitter.emit("change:mock");
expect(spy.callCount).toEqual(1);
removeCallback();
- core._eventEmitter.emit("change:mocks");
+ core._eventEmitter.emit("change:mock");
expect(spy.callCount).toEqual(1);
});
});
@@ -340,36 +334,6 @@ describe("Core", () => {
});
});
- describe("when mocksLoaders load", () => {
- it("should not load mocks if routes are not loaded", () => {
- expect.assertions(1);
- loadersMocks.stubs.Constructor.mock.calls[0][0].onLoad();
- expect(core._mocks.load.callCount).toEqual(0);
- });
-
- it("should load mocks if routes are loaded", () => {
- expect.assertions(1);
- loadersMocks.stubs.Constructor.mock.calls[1][0].onLoad();
- loadersMocks.stubs.Constructor.mock.calls[0][0].onLoad();
- expect(core._mocks.load.callCount).toEqual(1);
- });
- });
-
- describe("when routesLoaders load", () => {
- it("should not load mocks if mocks are not loaded", () => {
- expect.assertions(1);
- loadersMocks.stubs.Constructor.mock.calls[1][0].onLoad();
- expect(core._mocks.load.callCount).toEqual(0);
- });
-
- it("should load mocks if mocks are loaded", () => {
- expect.assertions(1);
- loadersMocks.stubs.Constructor.mock.calls[0][0].onLoad();
- loadersMocks.stubs.Constructor.mock.calls[1][0].onLoad();
- expect(core._mocks.load.callCount).toEqual(1);
- });
- });
-
describe("stop method", () => {
it("should stop server", async () => {
await core.stop();
@@ -420,7 +384,13 @@ describe("Core", () => {
describe("mocks getter", () => {
it("should return mocks instance", () => {
- expect(core.mocks).toEqual(mocksInstance);
+ expect(core.mocks).toEqual(mockInstance);
+ });
+ });
+
+ describe("mock getter", () => {
+ it("should return routes instance", () => {
+ expect(core.mock).toEqual(mockInstance);
});
});
@@ -442,4 +412,16 @@ describe("Core", () => {
expect(core.alertsApi.id).toEqual("alerts");
});
});
+
+ describe("server getter", () => {
+ it("should return server", () => {
+ expect(core.server).toEqual(serverMocks.stubs.instance);
+ });
+ });
+
+ describe("variantHandlers getter", () => {
+ it("should return variantHandlers", () => {
+ expect(core.variantHandlers).toEqual(core._variantHandlers);
+ });
+ });
});
diff --git a/packages/core/test/Alerts.spec.js b/packages/core/test/alerts/Alerts.spec.js
similarity index 97%
rename from packages/core/test/Alerts.spec.js
rename to packages/core/test/alerts/Alerts.spec.js
index b600d77d3..dc32c7108 100644
--- a/packages/core/test/Alerts.spec.js
+++ b/packages/core/test/alerts/Alerts.spec.js
@@ -11,7 +11,7 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
const { Logger } = require("@mocks-server/logger");
-const Alerts = require("../src/Alerts");
+const Alerts = require("../../src/alerts/Alerts");
describe("Alerts", () => {
let sandbox;
diff --git a/packages/core/test/AlertsLegacy.mocks.js b/packages/core/test/alerts/AlertsLegacy.mocks.js
similarity index 91%
rename from packages/core/test/AlertsLegacy.mocks.js
rename to packages/core/test/alerts/AlertsLegacy.mocks.js
index 20cff06e2..8ffd442da 100644
--- a/packages/core/test/AlertsLegacy.mocks.js
+++ b/packages/core/test/alerts/AlertsLegacy.mocks.js
@@ -10,9 +10,9 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
-jest.mock("../src/AlertsLegacy");
+jest.mock("../../src/alerts/AlertsLegacy");
-const Alerts = require("../src/AlertsLegacy");
+const Alerts = require("../../src/alerts/AlertsLegacy");
class ConfigMock {
constructor() {
diff --git a/packages/core/test/AlertsLegacy.spec.js b/packages/core/test/alerts/AlertsLegacy.spec.js
similarity index 89%
rename from packages/core/test/AlertsLegacy.spec.js
rename to packages/core/test/alerts/AlertsLegacy.spec.js
index 8a80cbafb..b3d12ed1a 100644
--- a/packages/core/test/AlertsLegacy.spec.js
+++ b/packages/core/test/alerts/AlertsLegacy.spec.js
@@ -11,9 +11,9 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
const { Logger } = require("@mocks-server/logger");
-const Alerts = require("../src/Alerts");
+const Alerts = require("../../src/alerts/Alerts");
-const AlertsLegacy = require("../src/AlertsLegacy");
+const AlertsLegacy = require("../../src/alerts/AlertsLegacy");
function removeDeprecatedAlerts(alerts) {
return alerts.filter((alert) => !alert.context.startsWith("deprecated"));
@@ -51,6 +51,7 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "foo",
+ id: "foo",
message: "Foo message",
},
]);
@@ -63,6 +64,7 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "foo",
+ id: "foo",
message: "Foo message 3",
},
]);
@@ -74,10 +76,12 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "foo1",
+ id: "foo1",
message: "Foo message 1",
},
{
context: "foo2",
+ id: "foo2",
message: "Foo message 2",
},
]);
@@ -97,14 +101,17 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "foo",
+ id: "foo",
message: "Foo message",
},
{
context: "foo-alert",
+ id: "foo-alert",
message: "Foo message 2",
},
{
context: "foo-collection:foo-alert-2",
+ id: "foo-collection:foo-alert-2",
message: "Foo message 3",
},
]);
@@ -120,14 +127,17 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "foo",
+ id: "foo",
message: "Foo message 1",
},
{
context: "var",
+ id: "var",
message: "Var message 1",
},
{
context: "foo:2",
+ id: "foo:2",
message: "Foo message 2",
},
]);
@@ -135,6 +145,7 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "var",
+ id: "var",
message: "Var message 1",
},
]);
@@ -148,14 +159,17 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "foo",
+ id: "foo",
message: "Foo message 1",
},
{
context: "var",
+ id: "var",
message: "Var message 1",
},
{
context: "foo:2",
+ id: "foo:2",
message: "Foo message 2",
},
]);
@@ -163,10 +177,12 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "foo",
+ id: "foo",
message: "Foo message 1",
},
{
context: "var",
+ id: "var",
message: "Var message 1",
},
]);
@@ -182,14 +198,17 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "foo",
+ id: "foo",
message: "Foo message 1",
},
{
context: "var",
+ id: "var",
message: "Var message 1",
},
{
context: "foo:2",
+ id: "foo:2",
message: "Foo message 2",
},
]);
@@ -197,14 +216,17 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "var",
+ id: "var",
message: "Var message 1",
},
{
context: "testing",
+ id: "testing",
message: "Foo message 1",
},
{
context: "testing:2",
+ id: "testing:2",
message: "Foo message 2",
},
]);
@@ -218,14 +240,17 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "foo:var",
+ id: "foo:var",
message: "Foo message 1",
},
{
context: "foo:var:2",
+ id: "foo:var:2",
message: "Foo message 2",
},
{
context: "foo:var:x",
+ id: "foo:var:x",
message: "Var message 1",
},
]);
@@ -233,14 +258,17 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "testing:var",
+ id: "testing:var",
message: "Foo message 1",
},
{
context: "testing:var:2",
+ id: "testing:var:2",
message: "Foo message 2",
},
{
context: "testing:var:x",
+ id: "testing:var:x",
message: "Var message 1",
},
]);
@@ -254,14 +282,17 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "foo",
+ id: "foo",
message: "Foo message 1",
},
{
context: "var",
+ id: "var",
message: "Var message 1",
},
{
context: "foo:2",
+ id: "foo:2",
message: "Foo message 2",
},
]);
@@ -269,14 +300,17 @@ describe("Alerts Legacy", () => {
expect(removeDeprecatedAlerts(alertsLegacy.values)).toEqual([
{
context: "foo",
+ id: "foo",
message: "Foo message 1",
},
{
context: "var",
+ id: "var",
message: "Var message 1",
},
{
context: "foo:3",
+ id: "foo:3",
message: "Foo message 2",
},
]);
diff --git a/packages/core/test/support/helpers.spec.js b/packages/core/test/alerts/legacyHelpers.spec.js
similarity index 98%
rename from packages/core/test/support/helpers.spec.js
rename to packages/core/test/alerts/legacyHelpers.spec.js
index fab6fbf98..2776d1e93 100644
--- a/packages/core/test/support/helpers.spec.js
+++ b/packages/core/test/alerts/legacyHelpers.spec.js
@@ -9,9 +9,9 @@ Unless required by applicable law or agreed to in writing, software distributed
*/
const sinon = require("sinon");
-const helpers = require("../../src/support/helpers");
+const helpers = require("../../src/alerts/legacyHelpers");
-describe("helpers", () => {
+describe("events", () => {
let sandbox;
beforeEach(() => {
diff --git a/packages/core/test/Config.mocks.js b/packages/core/test/common/Config.mocks.js
similarity index 100%
rename from packages/core/test/Config.mocks.js
rename to packages/core/test/common/Config.mocks.js
diff --git a/packages/core/test/Libs.mocks.js b/packages/core/test/common/Libs.mocks.js
similarity index 100%
rename from packages/core/test/Libs.mocks.js
rename to packages/core/test/common/Libs.mocks.js
diff --git a/packages/core/test/tracer.spec.js b/packages/core/test/common/tracer.spec.js
similarity index 96%
rename from packages/core/test/tracer.spec.js
rename to packages/core/test/common/tracer.spec.js
index 063e8fe4d..d86745696 100644
--- a/packages/core/test/tracer.spec.js
+++ b/packages/core/test/common/tracer.spec.js
@@ -11,7 +11,7 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
-const tracer = require("../src/tracer");
+const tracer = require("../../src/common/legacyTracer");
describe("tracer", () => {
let sandbox;
diff --git a/packages/core/test/files-loader/FilesLoader.mocks.js b/packages/core/test/files/FilesLoaders.mocks.js
similarity index 90%
rename from packages/core/test/files-loader/FilesLoader.mocks.js
rename to packages/core/test/files/FilesLoaders.mocks.js
index f65650376..bc98c7ed1 100644
--- a/packages/core/test/files-loader/FilesLoader.mocks.js
+++ b/packages/core/test/files/FilesLoaders.mocks.js
@@ -10,9 +10,9 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
-jest.mock("../../src/files-loader/FilesLoader");
+jest.mock("../../src/files/FilesLoaders");
-const FilesLoader = require("../../src/files-loader/FilesLoader");
+const FilesLoader = require("../../src/files/FilesLoaders");
class Mock {
constructor() {
diff --git a/packages/core/test/files-loader/FilesLoader.spec.js b/packages/core/test/files/FilesLoaders.spec.js
similarity index 82%
rename from packages/core/test/files-loader/FilesLoader.spec.js
rename to packages/core/test/files/FilesLoaders.spec.js
index 557d9c560..378034c27 100644
--- a/packages/core/test/files-loader/FilesLoader.spec.js
+++ b/packages/core/test/files/FilesLoaders.spec.js
@@ -14,12 +14,12 @@ const sinon = require("sinon");
const { cloneDeep } = require("lodash");
const { Logger } = require("@mocks-server/logger");
-const Alerts = require("../../src/Alerts");
-const LibsMocks = require("../Libs.mocks");
+const Alerts = require("../../src/alerts/Alerts");
+const LibsMocks = require("../common/Libs.mocks");
const CoreMocks = require("../Core.mocks");
-const ConfigMock = require("../Config.mocks");
+const ConfigMock = require("../common/Config.mocks");
-const FilesLoader = require("../../src/files-loader/FilesLoader");
+const FilesLoaders = require("../../src/files/FilesLoaders");
const wait = () => {
return new Promise((resolve) => {
@@ -29,7 +29,7 @@ const wait = () => {
});
};
-describe("FilesLoader", () => {
+describe("FilesLoaders", () => {
const fooRequireCache = {
"foo-path": {
id: "foo-path",
@@ -70,6 +70,7 @@ describe("FilesLoader", () => {
let pluginMethods;
let pathOption;
let watchOption;
+ let enabledOption;
let babelRegisterOption;
let babelRegisterOptionsOption;
let alerts;
@@ -96,13 +97,13 @@ describe("FilesLoader", () => {
pluginMethods = {
core: coreInstance,
loadRoutes: sandbox.stub(),
- loadMocks: sandbox.stub(),
+ loadCollections: sandbox.stub(),
alerts,
config: configMock.stubs.namespace,
logger,
};
- filesLoader = new FilesLoader(pluginMethods, {
+ filesLoader = new FilesLoaders(pluginMethods, {
requireCache,
});
sandbox.stub(path, "isAbsolute").returns(true);
@@ -113,7 +114,9 @@ describe("FilesLoader", () => {
watchOption = { value: true };
babelRegisterOption = { value: false };
babelRegisterOptionsOption = { value: {} };
+ enabledOption = { value: true };
+ filesLoader._enabledOption = enabledOption;
filesLoader._pathOption = pathOption;
filesLoader._watchOption = watchOption;
filesLoader._babelRegisterOption = babelRegisterOption;
@@ -129,7 +132,7 @@ describe("FilesLoader", () => {
describe("id", () => {
it("should return files", async () => {
- expect(FilesLoader.id).toEqual("files");
+ expect(FilesLoaders.id).toEqual("files");
});
});
@@ -141,6 +144,12 @@ describe("FilesLoader", () => {
});
describe("when initialized", () => {
+ it("should not require files from mocks folders if it is disabled", async () => {
+ enabledOption.value = false;
+ await filesLoader.init();
+ expect(libsMocks.stubs.fsExtra.ensureDirSync.callCount).toEqual(0);
+ });
+
it("should require all files from mocks folders calculating it from cwd if path is not absolute", async () => {
path.isAbsolute.returns(false);
libsMocks.stubs.fsExtra.existsSync.returns(false);
@@ -158,7 +167,7 @@ describe("FilesLoader", () => {
it("should add an alert when a routes file content does not pass validation", async () => {
libsMocks.stubs.globule.find.returns(["foo"]);
- filesLoader = new FilesLoader(pluginMethods, {
+ filesLoader = new FilesLoaders(pluginMethods, {
requireCache,
require: () => ({}),
});
@@ -176,7 +185,7 @@ describe("FilesLoader", () => {
it("should not add an alert when a routes file content pass validation", async () => {
libsMocks.stubs.globule.find.returns(["foo"]);
- filesLoader = new FilesLoader(pluginMethods, {
+ filesLoader = new FilesLoaders(pluginMethods, {
requireCache,
require: () => [],
});
@@ -194,7 +203,7 @@ describe("FilesLoader", () => {
});
it("should remove alerts when mocks file loads successfully", async () => {
- filesLoader = new FilesLoader(pluginMethods, {
+ filesLoader = new FilesLoaders(pluginMethods, {
requireCache,
require: () => [],
});
@@ -206,8 +215,8 @@ describe("FilesLoader", () => {
expect(alerts.flat.length).toEqual(0);
});
- it("should call to loadMocks method when mocks file is loaded", async () => {
- filesLoader = new FilesLoader(pluginMethods, {
+ it("should call to loadCollections method when mocks file is loaded", async () => {
+ filesLoader = new FilesLoaders(pluginMethods, {
requireCache,
require: () => [],
});
@@ -216,11 +225,11 @@ describe("FilesLoader", () => {
filesLoader._babelRegisterOption = babelRegisterOption;
filesLoader._babelRegisterOptionsOption = babelRegisterOptionsOption;
await filesLoader.init();
- expect(pluginMethods.loadMocks.callCount).toEqual(1);
+ expect(pluginMethods.loadCollections.callCount).toEqual(1);
});
- it("should try to load mocks.json when mock.js file does not exists", async () => {
- filesLoader = new FilesLoader(pluginMethods, {
+ it("should try to load collections.json when collections.js file does not exists", async () => {
+ filesLoader = new FilesLoaders(pluginMethods, {
requireCache,
require: sandbox.spy,
});
@@ -235,6 +244,25 @@ describe("FilesLoader", () => {
expect(libsMocks.stubs.fsExtra.existsSync.callCount).toEqual(3);
});
+ it("should add an alert when file name is mocks", async () => {
+ filesLoader = new FilesLoaders(pluginMethods, {
+ requireCache,
+ require: sandbox.spy,
+ });
+ filesLoader._pathOption = pathOption;
+ filesLoader._watchOption = watchOption;
+ filesLoader._babelRegisterOption = babelRegisterOption;
+ filesLoader._babelRegisterOptionsOption = babelRegisterOptionsOption;
+ libsMocks.stubs.fsExtra.existsSync.onCall(0).returns(true);
+ libsMocks.stubs.fsExtra.existsSync.onCall(1).returns(false);
+ libsMocks.stubs.fsExtra.existsSync.onCall(2).returns(false);
+ libsMocks.stubs.fsExtra.existsSync.onCall(3).returns(true);
+ await filesLoader.init();
+ expect(alerts.flat[0].value.message).toEqual(
+ "Defining collections in 'mocks.json' file is deprecated. Please rename it to 'collections.json'"
+ );
+ });
+
it("should not throw and add an alert if there is an error in loadRoutesfiles method", async () => {
sandbox.stub(filesLoader, "_readFile").throws(new Error());
await filesLoader.init();
@@ -257,7 +285,7 @@ describe("FilesLoader", () => {
//do nothing
});
coreInstance.lowLevelConfig = { babelRegister: true, babelRegisterOptions: {} };
- filesLoader = new FilesLoader(pluginMethods, {
+ filesLoader = new FilesLoaders(pluginMethods, {
requireCache,
require: requireSpy,
});
@@ -278,7 +306,7 @@ describe("FilesLoader", () => {
});
it("should require cache in order to found the mocks folder", async () => {
- filesLoader = new FilesLoader(pluginMethods);
+ filesLoader = new FilesLoaders(pluginMethods);
filesLoader._pathOption = pathOption;
filesLoader._watchOption = watchOption;
filesLoader._babelRegisterOption = babelRegisterOption;
@@ -308,6 +336,13 @@ describe("FilesLoader", () => {
describe("start method", () => {
describe("when starting files watch", () => {
+ it("should do nothing if files was not enabled", async () => {
+ filesLoader._enabledOption.value = false;
+ await filesLoader.init();
+ await filesLoader.start();
+ expect(libsMocks.stubs.watch.callCount).toEqual(0);
+ });
+
it("should do nothing if watch was not enabled", async () => {
filesLoader._watchOption.value = false;
await filesLoader.init();
diff --git a/packages/core/test/files-loader/helpers.spec.js b/packages/core/test/files/helpers.spec.js
similarity index 98%
rename from packages/core/test/files-loader/helpers.spec.js
rename to packages/core/test/files/helpers.spec.js
index 5301990af..9b1fcf08f 100644
--- a/packages/core/test/files-loader/helpers.spec.js
+++ b/packages/core/test/files/helpers.spec.js
@@ -1,4 +1,4 @@
-const { babelRegisterDefaultOptions, getFilesGlobule } = require("../../src/files-loader/helpers");
+const { babelRegisterDefaultOptions, getFilesGlobule } = require("../../src/files/helpers");
describe("FilesLoader helpers", () => {
describe("babelRegisterDefaultOptions", () => {
diff --git a/packages/core/test/mocks/Mock.mock.js b/packages/core/test/mock/Collection.mock.js
similarity index 76%
rename from packages/core/test/mocks/Mock.mock.js
rename to packages/core/test/mock/Collection.mock.js
index 693e42d75..0b0b5e6f6 100644
--- a/packages/core/test/mocks/Mock.mock.js
+++ b/packages/core/test/mock/Collection.mock.js
@@ -10,26 +10,27 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
-jest.mock("../../src/mocks/Mock");
+jest.mock("../../src/mock/Collection");
-const Mock = require("../../src/mocks/Mock");
+const Collection = require("../../src/mock/Collection");
-class MockMock {
+class CollectionCollection {
constructor() {
this._sandbox = sinon.createSandbox();
this._stubs = {
id: "mock-id",
routesVariants: [],
+ routeVariants: [],
router: this._sandbox.stub(),
};
- Mock.mockImplementation(() => this._stubs);
+ Collection.mockImplementation(() => this._stubs);
}
get stubs() {
return {
- Constructor: Mock,
+ Constructor: Collection,
instance: this._stubs,
};
}
@@ -39,4 +40,4 @@ class MockMock {
}
}
-module.exports = MockMock;
+module.exports = CollectionCollection;
diff --git a/packages/core/test/mocks/Mock.spec.js b/packages/core/test/mock/Collection.spec.js
similarity index 88%
rename from packages/core/test/mocks/Mock.spec.js
rename to packages/core/test/mock/Collection.spec.js
index abc0bfd54..acdd9a187 100644
--- a/packages/core/test/mocks/Mock.spec.js
+++ b/packages/core/test/mock/Collection.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2021 Javier Brea
+Copyright 2021-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -10,23 +10,23 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
-const LibsMocks = require("../Libs.mocks.js");
+const LibsMocks = require("../common/Libs.mocks");
const { Logger } = require("@mocks-server/logger");
-const Mock = require("../../src/mocks/Mock");
+const Collection = require("../../src/mock/Collection");
-describe("Mock", () => {
+describe("Collection", () => {
let sandbox;
let libsMocks;
- let mock;
+ let collection;
let getDelay;
- let routesVariants;
+ let routeVariants;
let middlewareMethodsStubs;
let logger;
beforeEach(() => {
sandbox = sinon.createSandbox();
- routesVariants = [
+ routeVariants = [
{
method: "GET",
url: "url-1",
@@ -59,7 +59,7 @@ describe("Mock", () => {
getDelay = sandbox.stub();
libsMocks = new LibsMocks();
logger = new Logger();
- mock = new Mock({ id: "mock-id", routesVariants, getDelay, logger });
+ collection = new Collection({ id: "mock-id", routeVariants, getDelay, logger });
});
afterEach(() => {
@@ -69,19 +69,19 @@ describe("Mock", () => {
describe("id getter", () => {
it("should return mock id", () => {
- expect(mock.id).toEqual("mock-id");
+ expect(collection.id).toEqual("mock-id");
});
});
- describe("routesVariants getter", () => {
+ describe("routeVariants getter", () => {
it("should return routesVariants", () => {
- expect(mock.routesVariants).toEqual(routesVariants);
+ expect(collection.routeVariants).toEqual(routeVariants);
});
});
describe("router getter", () => {
it("should return express router", () => {
- expect(mock.router).toEqual(libsMocks.stubs.expressRouter);
+ expect(collection.router).toEqual(libsMocks.stubs.expressRouter);
});
});
diff --git a/packages/core/test/Loaders.mocks.js b/packages/core/test/mock/Loaders.mocks.js
similarity index 85%
rename from packages/core/test/Loaders.mocks.js
rename to packages/core/test/mock/Loaders.mocks.js
index 62bf059de..a3326f317 100644
--- a/packages/core/test/Loaders.mocks.js
+++ b/packages/core/test/mock/Loaders.mocks.js
@@ -11,9 +11,9 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
-jest.mock("../src/Loaders");
+jest.mock("../../src/mock/Loaders");
-const Loaders = require("../src/Loaders");
+const Loaders = require("../../src/mock/Loaders");
const INITIAL_FILES = {
file1: {
@@ -40,8 +40,10 @@ class Mock {
constructor() {
this._sandbox = sinon.createSandbox();
+ this._loader = this._sandbox.stub();
+
this._stubs = {
- new: this._sandbox.stub(),
+ new: this._sandbox.stub().returns(this._loader),
};
Loaders.mockImplementation(() => this._stubs);
@@ -51,6 +53,7 @@ class Mock {
return {
Constructor: Loaders,
instance: this._stubs,
+ loader: this._loader,
};
}
diff --git a/packages/core/test/Loaders.spec.js b/packages/core/test/mock/Loaders.spec.js
similarity index 97%
rename from packages/core/test/Loaders.spec.js
rename to packages/core/test/mock/Loaders.spec.js
index 7ccde66c8..705e59436 100644
--- a/packages/core/test/Loaders.spec.js
+++ b/packages/core/test/mock/Loaders.spec.js
@@ -10,7 +10,7 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
-const Loaders = require("../src/Loaders");
+const Loaders = require("../../src/mock/Loaders");
describe("Loaders", () => {
let sandbox;
diff --git a/packages/core/test/mocks/Mocks.mock.js b/packages/core/test/mock/Mock.mock.js
similarity index 62%
rename from packages/core/test/mocks/Mocks.mock.js
rename to packages/core/test/mock/Mock.mock.js
index c96afdc2c..4a77c50c7 100644
--- a/packages/core/test/mocks/Mocks.mock.js
+++ b/packages/core/test/mock/Mock.mock.js
@@ -1,5 +1,5 @@
/*
-Copyright 2021 Javier Brea
+Copyright 2021-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -10,36 +10,47 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
-jest.mock("../../src/mocks/Mocks");
+jest.mock("../../src/mock/Mock");
-const Mocks = require("../../src/mocks/Mocks");
+const Mock = require("../../src/mock/Mock");
const CURRENT = "foo";
-class Mock {
+class MockMock {
constructor() {
this._sandbox = sinon.createSandbox();
+ this._loadersStubs = {
+ loadCollections: this._sandbox.stub(),
+ loadRoutes: this._sandbox.stub(),
+ };
+
this._stubs = {
current: CURRENT,
load: this._sandbox.stub(),
init: this._sandbox.stub(),
+ createLoaders: this._sandbox.stub().returns(this._loadersStubs),
+ collections: {
+ selected: CURRENT,
+ },
};
- Mocks.mockImplementation(() => this._stubs);
+ Mock.mockImplementation(() => this._stubs);
}
get stubs() {
return {
- Constructor: Mocks,
+ Constructor: Mock,
instance: this._stubs,
+ loaders: this._loadersStubs,
};
}
restore() {
+ this._stubs.collections.selected = CURRENT;
this._stubs.current = CURRENT;
this._sandbox.restore();
}
}
-module.exports = Mock;
+module.exports = MockMock;
diff --git a/packages/core/test/mock/Mock.spec.js b/packages/core/test/mock/Mock.spec.js
new file mode 100644
index 000000000..efecde234
--- /dev/null
+++ b/packages/core/test/mock/Mock.spec.js
@@ -0,0 +1,442 @@
+/*
+Copyright 2021-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const sinon = require("sinon");
+const express = require("express");
+const { Logger } = require("@mocks-server/logger");
+
+const CollectionMock = require("./Collection.mock");
+const LoadersMock = require("./Loaders.mocks");
+
+const Alerts = require("../../src/alerts/Alerts");
+const Mock = require("../../src/mock/Mock");
+const ConfigMock = require("../common/Config.mocks");
+const DefaultRoutesHandler = require("../../src/variant-handlers/handlers/Default");
+
+describe("Mock", () => {
+ let configMock;
+ let legacyConfigMock;
+ let sandbox;
+ let collectionMock;
+ let mock;
+ let core;
+ let methods;
+ let routerMock;
+ let alerts;
+ let logger;
+ let loadersMock;
+
+ beforeEach(() => {
+ sandbox = sinon.createSandbox();
+ configMock = new ConfigMock();
+ loadersMock = new LoadersMock();
+ legacyConfigMock = new ConfigMock();
+ collectionMock = new CollectionMock();
+ routerMock = sandbox.stub();
+ sandbox.stub(express, "Router").returns(routerMock);
+ sandbox.stub(Logger.prototype, "warn");
+ sandbox.stub(Logger.prototype, "error");
+ logger = new Logger();
+ alerts = new Alerts("mocks", { logger });
+
+ core = {};
+ methods = {
+ config: configMock.stubs.namespace,
+ legacyConfig: legacyConfigMock.stubs.namespace,
+ getCurrentMock: sandbox.stub().returns(null),
+ onChange: sandbox.stub(),
+ alerts,
+ logger,
+ };
+
+ mock = new Mock(methods, core);
+ mock._routesLoaders.contents = [];
+ mock._collectionsLoaders.contents = [];
+ mock.init([DefaultRoutesHandler]);
+ });
+
+ afterEach(() => {
+ sandbox.restore();
+ collectionMock.restore();
+ });
+
+ describe("id", () => {
+ it("should return routes", async () => {
+ expect(Mock.id).toEqual("mock");
+ });
+ });
+
+ describe("legacyId", () => {
+ it("should return mocks", async () => {
+ expect(Mock.legacyId).toEqual("mocks");
+ });
+ });
+
+ describe("getDelay method", () => {
+ it("should return delay option value", () => {
+ mock._routes._delayOption.hasBeenSet = true;
+ mock._routes._delayOption.value = "foo-delay";
+ expect(mock._getDelay()).toEqual("foo-delay");
+ });
+
+ it("should set an alert if legacy delay option has been set", () => {
+ mock._currentDelayOptionLegacy.hasBeenSet = true;
+ mock._currentDelayOptionLegacy.value = "foo-delay";
+ mock._getDelay();
+ const alert = alerts.flat.pop();
+ expect(alert.id).toEqual("mocks.delay");
+ expect(alert.value.message).toEqual(
+ expect.stringContaining(
+ "Usage of 'mocks.delay' option is deprecated. Use 'mock.routes.delay' instead"
+ )
+ );
+ expect(alert.collection).toEqual("mocks:deprecated");
+ });
+
+ it("should return legacy delay option value if new option has not been set", () => {
+ mock._routes._delayOption.hasBeenSet = false;
+ mock._routes._delayOption.value = "foo-delay";
+ mock._currentDelayOptionLegacy.value = "foo-delay-legacy";
+ expect(mock._getDelay()).toEqual("foo-delay-legacy");
+ });
+ });
+
+ describe("onChange method", () => {
+ it("should add listener to eventEmitter", () => {
+ const spy = sandbox.spy();
+ mock.onChange(spy);
+ mock._eventEmitter.emit("change:mock");
+ expect(spy.callCount).toEqual(1);
+ });
+
+ it("should return a function to remove listener", () => {
+ expect.assertions(2);
+ const spy = sandbox.spy();
+ const removeCallback = mock.onChange(spy);
+ mock._eventEmitter.emit("change:mock");
+ expect(spy.callCount).toEqual(1);
+ removeCallback();
+ mock._eventEmitter.emit("change:mock");
+ expect(spy.callCount).toEqual(1);
+ });
+ });
+
+ describe("load method", () => {
+ it("should process loaded mocks", () => {
+ mock.load();
+ expect(mock.plainMocks).toEqual([]);
+ expect(mock.collections.plain).toEqual([]);
+ });
+
+ it("should process loaded routes", () => {
+ mock.load();
+ expect(mock.plainRoutes).toEqual([]);
+ });
+
+ it("should process routesVariants routes", () => {
+ mock.load();
+ expect(mock.plainRoutesVariants).toEqual([]);
+ });
+
+ it("should call onChange method", () => {
+ mock.load();
+ expect(methods.onChange.callCount).toEqual(1);
+ });
+ });
+
+ describe("when there are no mocks", () => {
+ it("should call to create express router", () => {
+ mock.load();
+ expect(express.Router.callCount).toEqual(1);
+ mock.router();
+ expect(routerMock.callCount).toEqual(1);
+ });
+
+ it("should return null as current", () => {
+ mock.load();
+ expect(mock.current).toEqual(null);
+ });
+
+ it("should return null as selected collection", () => {
+ mock.load();
+ expect(mock.collections.selected).toEqual(null);
+ });
+
+ it("should return empty array in ids", () => {
+ mock.load();
+ expect(mock.ids).toEqual([]);
+ });
+
+ it("should return empty array in collections ids", () => {
+ mock.load();
+ expect(mock.collections.ids).toEqual([]);
+ });
+ });
+
+ describe("routes", () => {
+ describe("plain", () => {
+ it("should return routes in plain format", () => {
+ mock._plainRoutes = ["foo", "foo-2"];
+ expect(mock.routes.plain).toEqual(["foo", "foo-2"]);
+ });
+ });
+
+ describe("plainVariants", () => {
+ it("should return variants in plain format", () => {
+ mock._plainVariants = ["foo", "foo-2"];
+ expect(mock.routes.plainVariants).toEqual(["foo", "foo-2"]);
+ });
+ });
+ });
+
+ describe("collections", () => {
+ describe("plain", () => {
+ it("should return collections in plain format", () => {
+ mock._plainCollections = ["foo", "foo-2"];
+ expect(mock.collections.plain).toEqual(["foo", "foo-2"]);
+ });
+ });
+ });
+
+ describe("when there are valid mocks and routes", () => {
+ beforeEach(() => {
+ mock._routesLoaders.contents = [
+ {
+ id: "route-1",
+ variants: [{ id: "variant-1", method: "GET", response: { body: {}, status: 200 } }],
+ },
+ {
+ id: "route-2",
+ delay: 500,
+ variants: [
+ { id: "variant-1", method: "GET", response: { body: {}, status: 200 } },
+ { id: "variant-2", delay: 1000, method: "GET", response: { body: {}, status: 200 } },
+ ],
+ },
+ ];
+ mock._collectionsLoaders.contents = [
+ {
+ id: "mock-1",
+ routesVariants: ["route-1:variant-1", "route-2:variant-1"],
+ },
+ {
+ id: "mock-2",
+ from: "mock-1",
+ routesVariants: ["route-2:variant-2"],
+ },
+ ];
+ });
+
+ describe("when loaded", () => {
+ it("should set current id", () => {
+ mock.load();
+ expect(mock.current).toEqual("mock-id");
+ });
+
+ it("should set selected collection id", () => {
+ mock.load();
+ expect(mock.collections.selected).toEqual("mock-id");
+ });
+
+ it("should return array of ids in ids getter", () => {
+ mock.load();
+ expect(mock.ids).toEqual(["mock-id"]);
+ });
+
+ it("should set selected collection id using new option if it was set", () => {
+ mock._collectionsInstance._selectedOption.hasBeenSet = true;
+ mock._collectionsInstance._selectedOption.value = "mock-id";
+ mock.load();
+ expect(mock.current).toEqual("mock-id");
+ });
+
+ it("should set selected collection id using legacy option if new was not set", () => {
+ mock._collectionsInstance._selectedOption.hasBeenSet = false;
+ mock._collectionsInstance._selectedOption.value = "foo";
+ mock._selectedCollectionOptionLegacy.hasBeenSet = true;
+ mock._selectedCollectionOptionLegacy.value = "mock-id";
+ mock.load();
+ expect(mock.current).toEqual("mock-id");
+ });
+ });
+
+ describe("when legacy option mocks.selected changes", () => {
+ it("should set current mock when it exists", () => {
+ mock.load();
+ mock._setCurrentLegacy("mock-id");
+ expect(mock.current).toEqual("mock-id");
+ });
+ });
+
+ describe("when setting current collection", () => {
+ it("should set current collection when it exists", () => {
+ mock.load();
+ mock.current = "mock-id";
+ expect(mock.current).toEqual("mock-id");
+ });
+
+ it("should set selected collection when it exists", () => {
+ mock.load();
+ mock.current = "mock-id";
+ expect(mock.collections.selected).toEqual("mock-id");
+ });
+
+ it("should set default collection when id does not exists", () => {
+ mock.load();
+ mock.current = "foo-id";
+ expect(mock.current).toEqual("mock-id");
+ });
+ });
+
+ describe("when setting current collection using select method", () => {
+ it("should set selected collection option", () => {
+ mock.load();
+ mock.collections.select("foo-mock-id");
+ expect(mock._collectionsInstance._selectedOption.value).toEqual("foo-mock-id");
+ });
+ });
+
+ describe("when setting custom route variant", () => {
+ it("should return customVariants", () => {
+ mock.load();
+ mock.useRouteVariant("route-2:variant-2");
+ expect(mock.customRoutesVariants).toEqual(["route-2:variant-2"]);
+ expect(mock.customRouteVariants).toEqual(["route-2:variant-2"]);
+ });
+ });
+
+ describe("when restoring custom route variants using legacy method", () => {
+ it("should return empty array", () => {
+ mock.load();
+ mock.useRouteVariant("route-2:variant-2");
+ expect(mock.customRoutesVariants).toEqual(["route-2:variant-2"]);
+ expect(mock.customRouteVariants).toEqual(["route-2:variant-2"]);
+ mock.restoreRoutesVariants();
+ expect(mock.customRoutesVariants).toEqual([]);
+ expect(mock.customRouteVariants).toEqual([]);
+ });
+ });
+
+ describe("when restoring custom route variants", () => {
+ it("should return empty array", () => {
+ mock.load();
+ mock.useRouteVariant("route-2:variant-2");
+ expect(mock.customRoutesVariants).toEqual(["route-2:variant-2"]);
+ expect(mock.customRouteVariants).toEqual(["route-2:variant-2"]);
+ mock.restoreRouteVariants();
+ expect(mock.customRoutesVariants).toEqual([]);
+ expect(mock.customRouteVariants).toEqual([]);
+ });
+ });
+ });
+
+ describe("when there are no valid collections", () => {
+ beforeEach(() => {
+ mock._routesLoaders.contents = [];
+ mock._collectionsLoaders.contents = [null];
+ });
+
+ describe("when loaded", () => {
+ it("should add alerts", () => {
+ mock.load();
+ expect(alerts.flat).toEqual([
+ {
+ id: "validation",
+ value: {
+ message: "Route is invalid: : type must be object",
+ error: undefined,
+ },
+ collection: "mocks:routes:load:0",
+ },
+ {
+ id: "selected",
+ value: {
+ message: "Option 'mock.collections.selected' was not defined",
+ error: undefined,
+ },
+ collection: "mocks:collections",
+ },
+ {
+ id: "empty",
+ value: { message: "No collections found", error: undefined },
+ collection: "mocks:collections",
+ },
+ {
+ id: "critical-error",
+ value: {
+ message: "Critical errors found while loading collections: 1",
+ error: undefined,
+ },
+ collection: "mocks:collections:load",
+ },
+ {
+ id: "validation",
+ value: {
+ message:
+ "Collection is invalid: : type must be object. : type must be object. : type must be object. : oneOf must match exactly one schema in oneOf",
+ error: undefined,
+ },
+ collection: "mocks:collections:load:0",
+ },
+ ]);
+ });
+ });
+
+ describe("when setting current collection", () => {
+ it("should not set collection when id does not exists", () => {
+ mock.load();
+ mock.current = "foo-id";
+ expect(mock.current).toEqual(null);
+ });
+ });
+ });
+
+ describe("createLoaders method", () => {
+ it("should return new loaders", () => {
+ const { loadRoutes, loadCollections } = mock.createLoaders();
+ expect(loadRoutes).toBe(loadersMock.stubs.loader);
+ expect(loadCollections).toBe(loadersMock.stubs.loader);
+ });
+ });
+
+ describe("when collections load", () => {
+ it("should not load collections if routes are not loaded", () => {
+ sandbox.spy(mock, "load");
+ expect.assertions(1);
+ loadersMock.stubs.Constructor.mock.calls[0][0].onLoad();
+ expect(mock.load.callCount).toEqual(0);
+ });
+
+ it("should load collections if routes are loaded", () => {
+ sandbox.spy(mock, "load");
+ expect.assertions(1);
+ loadersMock.stubs.Constructor.mock.calls[1][0].onLoad();
+ loadersMock.stubs.Constructor.mock.calls[0][0].onLoad();
+ expect(mock.load.callCount).toEqual(1);
+ });
+ });
+
+ describe("when routes load", () => {
+ it("should not load routes if collections are not loaded", () => {
+ sandbox.spy(mock, "load");
+ expect.assertions(1);
+ loadersMock.stubs.Constructor.mock.calls[1][0].onLoad();
+ expect(mock.load.callCount).toEqual(0);
+ });
+
+ it("should load routes if collections are loaded", () => {
+ sandbox.spy(mock, "load");
+ expect.assertions(1);
+ loadersMock.stubs.Constructor.mock.calls[0][0].onLoad();
+ loadersMock.stubs.Constructor.mock.calls[1][0].onLoad();
+ expect(mock.load.callCount).toEqual(1);
+ });
+ });
+});
diff --git a/packages/core/test/mocks/helpers.spec.js b/packages/core/test/mock/helpers.spec.js
similarity index 82%
rename from packages/core/test/mocks/helpers.spec.js
rename to packages/core/test/mock/helpers.spec.js
index 2cd9151d1..07548d1c4 100644
--- a/packages/core/test/mocks/helpers.spec.js
+++ b/packages/core/test/mock/helpers.spec.js
@@ -15,21 +15,23 @@ const { Logger } = require("@mocks-server/logger");
const CoreMocks = require("../Core.mocks.js");
const {
getVariantId,
- getMockRoutesVariants,
- getPlainMocks,
+ getCollectionRouteVariants,
+ getPlainCollections,
getPlainRoutes,
- getPlainRoutesVariants,
+ getPlainRouteVariants,
addCustomVariant,
hasDelayProperty,
getRouteHandlerDelay,
getVariantHandler,
getRouteVariants,
- getMock,
-} = require("../../src/mocks/helpers");
-const { compileRouteValidator } = require("../../src/mocks/validations");
-const DefaultRoutesHandler = require("../../src/routes-handlers/handlers/Default");
-const JsonRoutesHandler = require("../../src/routes-handlers/handlers/Json");
-const Alerts = require("../../src/Alerts");
+ getCollection,
+ plainCollectionsToLegacy,
+ plainRouteVariantsToLegacy,
+} = require("../../src/mock/helpers");
+const { compileRouteValidator } = require("../../src/mock/validations");
+const DefaultRoutesHandler = require("../../src/variant-handlers/handlers/Default");
+const JsonRoutesHandler = require("../../src/variant-handlers/handlers/Json");
+const Alerts = require("../../src/alerts/Alerts");
describe("mocks helpers", () => {
class FooHandler {
@@ -140,7 +142,7 @@ describe("mocks helpers", () => {
];
it("should return route variants of given mock", () => {
- expect(getMockRoutesVariants(MOCKS[0], MOCKS, ROUTES_VARIANTS)).toEqual([
+ expect(getCollectionRouteVariants(MOCKS[0], MOCKS, ROUTES_VARIANTS)).toEqual([
{
variantId: "route-1:success",
routeId: "route-1",
@@ -157,7 +159,7 @@ describe("mocks helpers", () => {
});
it("should return route variants of given mock when it extends from another", () => {
- expect(getMockRoutesVariants(MOCKS[1], MOCKS, ROUTES_VARIANTS)).toEqual([
+ expect(getCollectionRouteVariants(MOCKS[1], MOCKS, ROUTES_VARIANTS)).toEqual([
{
variantId: "route-1:success",
routeId: "route-1",
@@ -174,7 +176,7 @@ describe("mocks helpers", () => {
});
it("should return route variants of given mock when it extends recursively", () => {
- expect(getMockRoutesVariants(MOCKS[2], MOCKS, ROUTES_VARIANTS)).toEqual([
+ expect(getCollectionRouteVariants(MOCKS[2], MOCKS, ROUTES_VARIANTS)).toEqual([
{
variantId: "route-1:success",
routeId: "route-1",
@@ -191,7 +193,7 @@ describe("mocks helpers", () => {
});
it("should respect the order of routes defined in the base mocks when extending", () => {
- expect(getMockRoutesVariants(MOCKS[3], MOCKS, ROUTES_VARIANTS)).toEqual([
+ expect(getCollectionRouteVariants(MOCKS[3], MOCKS, ROUTES_VARIANTS)).toEqual([
{
variantId: "route-1:error",
routeId: "route-1",
@@ -208,14 +210,73 @@ describe("mocks helpers", () => {
});
});
- describe("getPlainMocks", () => {
+ describe("legacy getPlainCollections", () => {
it("should return mocks ids and routeVariants ids", () => {
expect(
- getPlainMocks(
+ plainCollectionsToLegacy(
+ getPlainCollections(
+ [
+ {
+ id: "mock-id-1",
+ routeVariants: [
+ {
+ variantId: "variant-id-1",
+ },
+ {
+ variantId: "variant-id-2",
+ },
+ {
+ variantId: "variant-id-3",
+ },
+ ],
+ },
+ {
+ id: "mock-id-2",
+ routeVariants: [
+ {
+ variantId: "variant-id-3",
+ },
+ ],
+ },
+ ],
+ [
+ {
+ id: "mock-id-1",
+ routes: ["variant-id-1"],
+ },
+ {
+ id: "mock-id-2",
+ from: "mock-id-1",
+ routes: ["variant-id-3"],
+ },
+ ]
+ )
+ )
+ ).toEqual([
+ {
+ id: "mock-id-1",
+ from: null,
+ routesVariants: ["variant-id-1"],
+ appliedRoutesVariants: ["variant-id-1", "variant-id-2", "variant-id-3"],
+ },
+ {
+ id: "mock-id-2",
+ from: "mock-id-1",
+ routesVariants: ["variant-id-3"],
+ appliedRoutesVariants: ["variant-id-3"],
+ },
+ ]);
+ });
+ });
+
+ describe("getPlainCollections", () => {
+ it("should return mocks ids and routeVariants ids", () => {
+ expect(
+ getPlainCollections(
[
{
id: "mock-id-1",
- routesVariants: [
+ routeVariants: [
{
variantId: "variant-id-1",
},
@@ -229,7 +290,7 @@ describe("mocks helpers", () => {
},
{
id: "mock-id-2",
- routesVariants: [
+ routeVariants: [
{
variantId: "variant-id-3",
},
@@ -239,12 +300,12 @@ describe("mocks helpers", () => {
[
{
id: "mock-id-1",
- routesVariants: ["variant-id-1"],
+ routes: ["variant-id-1"],
},
{
id: "mock-id-2",
from: "mock-id-1",
- routesVariants: ["variant-id-3"],
+ routes: ["variant-id-3"],
},
]
)
@@ -252,14 +313,14 @@ describe("mocks helpers", () => {
{
id: "mock-id-1",
from: null,
- routesVariants: ["variant-id-1"],
- appliedRoutesVariants: ["variant-id-1", "variant-id-2", "variant-id-3"],
+ definedRoutes: ["variant-id-1"],
+ routes: ["variant-id-1", "variant-id-2", "variant-id-3"],
},
{
id: "mock-id-2",
from: "mock-id-1",
- routesVariants: ["variant-id-3"],
- appliedRoutesVariants: ["variant-id-3"],
+ definedRoutes: ["variant-id-3"],
+ routes: ["variant-id-3"],
},
]);
});
@@ -465,10 +526,130 @@ describe("mocks helpers", () => {
});
});
+ describe("legacy getPlainRoutesVariants", () => {
+ it("should return routes variants in plain format when using legacy plainResponsePreview property", () => {
+ expect(
+ plainRouteVariantsToLegacy(
+ getPlainRouteVariants([
+ {
+ variantId: "route-1:variant-1",
+ routeId: "route-1",
+ constructor: { id: "handler-id-1" },
+ plainResponsePreview: "response-preview-1",
+ delay: "delay-1",
+ foo: "foo-1",
+ },
+ {
+ variantId: "route-2:variant-1",
+ routeId: "route-2",
+ constructor: { id: "handler-id-2" },
+ plainResponsePreview: "response-preview-2",
+ delay: "delay-2",
+ foo: "foo-2",
+ },
+ ])
+ )
+ ).toEqual([
+ {
+ id: "route-1:variant-1",
+ routeId: "route-1",
+ handler: "handler-id-1",
+ response: "response-preview-1",
+ delay: "delay-1",
+ },
+ {
+ id: "route-2:variant-1",
+ routeId: "route-2",
+ handler: "handler-id-2",
+ response: "response-preview-2",
+ delay: "delay-2",
+ },
+ ]);
+ });
+
+ it("should return routes variants in plain format when constructor is v4", () => {
+ expect(
+ plainRouteVariantsToLegacy(
+ getPlainRouteVariants([
+ {
+ variantId: "route-1:variant-1",
+ routeId: "route-1",
+ constructor: { id: "handler-id-1", version: "4" },
+ preview: "response-preview-1",
+ delay: "delay-1",
+ foo: "foo-1",
+ },
+ {
+ variantId: "route-2:variant-1",
+ routeId: "route-2",
+ constructor: { id: "handler-id-2", version: "4" },
+ preview: "response-preview-2",
+ delay: "delay-2",
+ foo: "foo-2",
+ },
+ ])
+ )
+ ).toEqual([
+ {
+ id: "route-1:variant-1",
+ routeId: "route-1",
+ handler: "handler-id-1",
+ response: "response-preview-1",
+ delay: "delay-1",
+ },
+ {
+ id: "route-2:variant-1",
+ routeId: "route-2",
+ handler: "handler-id-2",
+ response: "response-preview-2",
+ delay: "delay-2",
+ },
+ ]);
+ });
+
+ it("should return null in response when no preview is defined", () => {
+ expect(
+ plainRouteVariantsToLegacy(
+ getPlainRouteVariants([
+ {
+ variantId: "route-1:variant-1",
+ routeId: "route-1",
+ constructor: { id: "handler-id-1", version: "4" },
+ delay: "delay-1",
+ foo: "foo-1",
+ },
+ {
+ variantId: "route-2:variant-1",
+ routeId: "route-2",
+ constructor: { id: "handler-id-2", version: "4" },
+ delay: "delay-2",
+ foo: "foo-2",
+ },
+ ])
+ )
+ ).toEqual([
+ {
+ id: "route-1:variant-1",
+ routeId: "route-1",
+ handler: "handler-id-1",
+ response: null,
+ delay: "delay-1",
+ },
+ {
+ id: "route-2:variant-1",
+ routeId: "route-2",
+ handler: "handler-id-2",
+ response: null,
+ delay: "delay-2",
+ },
+ ]);
+ });
+ });
+
describe("getPlainRoutesVariants", () => {
it("should return routes variants in plain format when using legacy plainResponsePreview property", () => {
expect(
- getPlainRoutesVariants([
+ getPlainRouteVariants([
{
variantId: "route-1:variant-1",
routeId: "route-1",
@@ -489,16 +670,16 @@ describe("mocks helpers", () => {
).toEqual([
{
id: "route-1:variant-1",
- routeId: "route-1",
- handler: "handler-id-1",
- response: "response-preview-1",
+ route: "route-1",
+ type: "handler-id-1",
+ preview: "response-preview-1",
delay: "delay-1",
},
{
id: "route-2:variant-1",
- routeId: "route-2",
- handler: "handler-id-2",
- response: "response-preview-2",
+ route: "route-2",
+ type: "handler-id-2",
+ preview: "response-preview-2",
delay: "delay-2",
},
]);
@@ -506,7 +687,7 @@ describe("mocks helpers", () => {
it("should return routes variants in plain format when constructor is v4", () => {
expect(
- getPlainRoutesVariants([
+ getPlainRouteVariants([
{
variantId: "route-1:variant-1",
routeId: "route-1",
@@ -527,16 +708,16 @@ describe("mocks helpers", () => {
).toEqual([
{
id: "route-1:variant-1",
- routeId: "route-1",
- handler: "handler-id-1",
- response: "response-preview-1",
+ route: "route-1",
+ type: "handler-id-1",
+ preview: "response-preview-1",
delay: "delay-1",
},
{
id: "route-2:variant-1",
- routeId: "route-2",
- handler: "handler-id-2",
- response: "response-preview-2",
+ route: "route-2",
+ type: "handler-id-2",
+ preview: "response-preview-2",
delay: "delay-2",
},
]);
@@ -544,7 +725,7 @@ describe("mocks helpers", () => {
it("should return null in response when no preview is defined", () => {
expect(
- getPlainRoutesVariants([
+ getPlainRouteVariants([
{
variantId: "route-1:variant-1",
routeId: "route-1",
@@ -563,16 +744,16 @@ describe("mocks helpers", () => {
).toEqual([
{
id: "route-1:variant-1",
- routeId: "route-1",
- handler: "handler-id-1",
- response: null,
+ route: "route-1",
+ type: "handler-id-1",
+ preview: null,
delay: "delay-1",
},
{
id: "route-2:variant-1",
- routeId: "route-2",
- handler: "handler-id-2",
- response: null,
+ route: "route-2",
+ type: "handler-id-2",
+ preview: null,
delay: "delay-2",
},
]);
@@ -773,7 +954,7 @@ describe("mocks helpers", () => {
id: "validation",
value: {
message:
- "Variant in route with id 'undefined' is invalid: Invalid 'response' property:: type must be object",
+ "Variant in route with id 'undefined' is invalid: Invalid 'options' property:: type must be object",
},
},
]);
@@ -799,7 +980,7 @@ describe("mocks helpers", () => {
id: "validation",
value: {
message:
- "Variant with id 'foo-variant' in route with id 'foo-route' is invalid: Invalid 'response' property:: type must be object",
+ "Variant with id 'foo-variant' in route with id 'foo-route' is invalid: Invalid 'options' property:: type must be object",
},
},
]);
@@ -1043,14 +1224,14 @@ describe("mocks helpers", () => {
});
});
- describe("getMock", () => {
+ describe("getCollection", () => {
it("should add an alert if mock contains not valid routeVariants", () => {
- const mock = getMock({
- mockDefinition: {
+ const mock = getCollection({
+ collectionDefinition: {
id: "foo-id",
routesVariants: ["foo-route:foo-id"],
},
- mocksDefinitions: [],
+ collectionsDefinitions: [],
routeVariants: [],
getGlobalDelay: () => {
//do nothing
@@ -1062,18 +1243,18 @@ describe("mocks helpers", () => {
expect(alerts.flat[0].id).toEqual("variants");
expect(alerts.flat[0].value.message).toEqual(
- "Mock with id 'foo-id' is invalid: routeVariant with id 'foo-route:foo-id' was not found, use a valid 'routeId:variantId' identifier"
+ "Collection with id 'foo-id' is invalid: routeVariant with id 'foo-route:foo-id' was not found, use a valid 'routeId:variantId' identifier"
);
});
it("should add an alert if instantiating Mock throws an error", () => {
- sandbox.stub(express, "Router").throws(new Error("Error creating mock"));
- const mock = getMock({
- mockDefinition: {
+ sandbox.stub(express, "Router").throws(new Error("Error creating collection"));
+ const mock = getCollection({
+ collectionDefinition: {
id: "foo-id",
routesVariants: ["foo-route:foo-id"],
},
- mocksDefinitions: [],
+ collectionsDefinitions: [],
routeVariants: [
{
id: "foo-route",
@@ -1089,7 +1270,7 @@ describe("mocks helpers", () => {
expect(mock).toEqual(null);
expect(alerts.flat[0].id).toEqual("process");
- expect(alerts.flat[0].value.message).toEqual("Error processing mock");
+ expect(alerts.flat[0].value.message).toEqual("Error processing collection");
});
});
});
diff --git a/packages/core/test/mocks/validations.spec.js b/packages/core/test/mock/validations.spec.js
similarity index 85%
rename from packages/core/test/mocks/validations.spec.js
rename to packages/core/test/mock/validations.spec.js
index a7a8bc0b2..98087e295 100644
--- a/packages/core/test/mocks/validations.spec.js
+++ b/packages/core/test/mock/validations.spec.js
@@ -14,12 +14,12 @@ const {
compileRouteValidator,
routeValidationErrors,
variantValidationErrors,
- mockValidationErrors,
- mockRouteVariantsValidationErrors,
-} = require("../../src/mocks/validations");
-const DefaultRoutesHandler = require("../../src/routes-handlers/handlers/Default");
-const JsonRoutesHandler = require("../../src/routes-handlers/handlers/Json");
-const MiddlewareRoutesHandler = require("../../src/routes-handlers/handlers/Middleware");
+ collectionValidationErrors,
+ collectionRouteVariantsValidationErrors,
+} = require("../../src/mock/validations");
+const DefaultRoutesHandler = require("../../src/variant-handlers/handlers/Default");
+const JsonRoutesHandler = require("../../src/variant-handlers/handlers/Json");
+const MiddlewareRoutesHandler = require("../../src/variant-handlers/handlers/Middleware");
describe("mocks validations", () => {
const VALID_ROUTE = {
@@ -322,7 +322,7 @@ describe("mocks validations", () => {
JsonRoutesHandler
);
expect(errors.message).toEqual(
- "Variant in route with id 'foo-route' is invalid: Invalid 'response' property:: type must be object"
+ "Variant in route with id 'foo-route' is invalid: Invalid 'options' property:: type must be object"
);
});
@@ -333,7 +333,7 @@ describe("mocks validations", () => {
JsonRoutesHandler
);
expect(errors.message).toEqual(
- "Variant with id 'foo-variant' in route with id 'foo-route' is invalid: Invalid 'response' property:: type must be object"
+ "Variant with id 'foo-variant' in route with id 'foo-route' is invalid: Invalid 'options' property:: type must be object"
);
});
@@ -349,7 +349,7 @@ describe("mocks validations", () => {
JsonRoutesHandler
);
expect(errors.message).toEqual(
- "Variant with id 'foo-variant' in route with id 'foo-route' is invalid: Invalid 'response' property: must have required property 'body'. /headers: type must be object"
+ "Variant with id 'foo-variant' in route with id 'foo-route' is invalid: Invalid 'options' property: must have required property 'body'. /headers: type must be object"
);
});
@@ -365,7 +365,7 @@ describe("mocks validations", () => {
JsonRoutesHandler
);
expect(errors.message).toEqual(
- "Variant with id 'foo-variant' in route with id 'foo-route' is invalid: Invalid 'response' property: Wrong type"
+ "Variant with id 'foo-variant' in route with id 'foo-route' is invalid: Invalid 'options' property: Wrong type"
);
});
});
@@ -392,7 +392,7 @@ describe("mocks validations", () => {
MiddlewareRoutesHandler
);
expect(errors.message).toEqual(
- "Variant in route with id 'foo-route' is invalid: Invalid 'response' property:: type must be object"
+ "Variant in route with id 'foo-route' is invalid: Invalid 'options' property:: type must be object"
);
});
@@ -403,7 +403,7 @@ describe("mocks validations", () => {
MiddlewareRoutesHandler
);
expect(errors.message).toEqual(
- "Variant with id 'foo-variant' in route with id 'foo-route' is invalid: Invalid 'response' property:: type must be object"
+ "Variant with id 'foo-variant' in route with id 'foo-route' is invalid: Invalid 'options' property:: type must be object"
);
});
@@ -414,15 +414,15 @@ describe("mocks validations", () => {
MiddlewareRoutesHandler
);
expect(errors.message).toEqual(
- "Variant with id 'foo-variant' in route with id 'foo-route' is invalid: Invalid 'response' property: must have required property 'middleware'"
+ "Variant with id 'foo-variant' in route with id 'foo-route' is invalid: Invalid 'options' property: must have required property 'middleware'"
);
});
});
- describe("mockValidationErrors", () => {
- it("should return null if mock is valid", () => {
+ describe("collectionValidationErrors", () => {
+ it("should return null if collection is valid", () => {
expect(
- mockValidationErrors({
+ collectionValidationErrors({
id: "foo",
from: "foo-base",
routesVariants: [],
@@ -431,29 +431,29 @@ describe("mocks validations", () => {
});
it("should return error if mock has not id", () => {
- const errors = mockValidationErrors({
- routesVariants: [],
+ const errors = collectionValidationErrors({
+ routes: [],
});
- expect(errors.errors.length).toEqual(1);
- expect(errors.message).toEqual("Mock is invalid: must have required property 'id'");
+ expect(errors.message).toEqual("Collection is invalid: must have required property 'id'");
+ expect(errors.errors.length).toEqual(8);
});
- it("should return error if mock has not routesVariants", () => {
- const errors = mockValidationErrors({
+ it("should return error if mock has not routes", () => {
+ const errors = collectionValidationErrors({
id: "foo",
});
expect(errors.message).toEqual(
- "Mock with id 'foo' is invalid: must have required property 'routesVariants'"
+ "Collection with id 'foo' is invalid: must have required property 'routes'"
);
});
it("should return all errors together", () => {
- const errors = mockValidationErrors({
+ const errors = collectionValidationErrors({
from: 5,
foo: "foo",
});
expect(errors.message).toEqual(
- "Mock is invalid: must have required property 'routesVariants'. /from: type must be string"
+ "Collection is invalid: must have required property 'routes'. /from: type must be string. /from: type must be string. /from: type must be string"
);
});
});
@@ -476,7 +476,7 @@ describe("mocks validations", () => {
it("should return null if all routeVariants exist", () => {
expect(
- mockRouteVariantsValidationErrors(
+ collectionRouteVariantsValidationErrors(
{
id: "foo",
from: "foo-base",
@@ -488,7 +488,7 @@ describe("mocks validations", () => {
});
it("should return error containing one message for each non existant routeVariant", () => {
- const errors = mockRouteVariantsValidationErrors(
+ const errors = collectionRouteVariantsValidationErrors(
{
id: "foo",
from: "foo-base",
@@ -497,12 +497,12 @@ describe("mocks validations", () => {
ROUTE_VARIANTS
);
expect(errors.message).toEqual(
- "Mock with id 'foo' is invalid: routeVariant with id 'foo:fake' was not found, use a valid 'routeId:variantId' identifier. routeVariant with id 'foo2:success' was not found, use a valid 'routeId:variantId' identifier"
+ "Collection with id 'foo' is invalid: routeVariant with id 'foo:fake' was not found, use a valid 'routeId:variantId' identifier. routeVariant with id 'foo2:success' was not found, use a valid 'routeId:variantId' identifier"
);
});
it("should return error containing one message for each duplicated route in variants", () => {
- const errors = mockRouteVariantsValidationErrors(
+ const errors = collectionRouteVariantsValidationErrors(
{
id: "foo",
from: "foo-base",
@@ -511,12 +511,12 @@ describe("mocks validations", () => {
ROUTE_VARIANTS
);
expect(errors.message).toEqual(
- "Mock with id 'foo' is invalid: route with id 'foo' is used more than once in the same mock"
+ "Collection with id 'foo' is invalid: route with id 'foo' is used more than once in the same collection"
);
});
it("should return all error messages together", () => {
- const errors = mockRouteVariantsValidationErrors(
+ const errors = collectionRouteVariantsValidationErrors(
{
id: "foo",
from: "foo-base",
@@ -525,12 +525,12 @@ describe("mocks validations", () => {
ROUTE_VARIANTS
);
expect(errors.message).toEqual(
- "Mock with id 'foo' is invalid: route with id 'foo' is used more than once in the same mock. routeVariant with id 'foo2:success' was not found, use a valid 'routeId:variantId' identifier"
+ "Collection with id 'foo' is invalid: route with id 'foo' is used more than once in the same collection. routeVariant with id 'foo2:success' was not found, use a valid 'routeId:variantId' identifier"
);
});
it("should work when no routeVariants are provided in mock", () => {
- const errors = mockRouteVariantsValidationErrors({
+ const errors = collectionRouteVariantsValidationErrors({
id: "foo",
from: "foo-base",
});
diff --git a/packages/core/test/mocks/Mocks.spec.js b/packages/core/test/mocks/Mocks.spec.js
deleted file mode 100644
index 2f7eb8253..000000000
--- a/packages/core/test/mocks/Mocks.spec.js
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
-Copyright 2021-2022 Javier Brea
-
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-*/
-
-const sinon = require("sinon");
-const express = require("express");
-const { Logger } = require("@mocks-server/logger");
-
-const MockMock = require("./Mock.mock.js");
-
-const Alerts = require("../../src/Alerts");
-const Mocks = require("../../src/mocks/Mocks");
-const ConfigMock = require("../Config.mocks");
-const DefaultRoutesHandler = require("../../src/routes-handlers/handlers/Default");
-
-describe("Mocks", () => {
- let configMock;
- let sandbox;
- let mockMock;
- let mocks;
- let core;
- let methods;
- let routerMock;
- let alerts;
- let logger;
-
- beforeEach(() => {
- sandbox = sinon.createSandbox();
- configMock = new ConfigMock();
- mockMock = new MockMock();
- routerMock = sandbox.stub();
- sandbox.stub(express, "Router").returns(routerMock);
- sandbox.stub(Logger.prototype, "warn");
- sandbox.stub(Logger.prototype, "error");
- logger = new Logger();
- alerts = new Alerts("mocks", { logger });
-
- core = {};
- methods = {
- config: configMock.stubs.namespace,
- getLoadedMocks: sandbox.stub().returns([]),
- getLoadedRoutes: sandbox.stub().returns([]),
- getCurrentMock: sandbox.stub().returns(null),
- onChange: sandbox.stub(),
- alerts,
- logger,
- };
-
- mocks = new Mocks(methods, core);
- mocks.init([DefaultRoutesHandler]);
- });
-
- afterEach(() => {
- sandbox.restore();
- mockMock.restore();
- });
-
- describe("id", () => {
- it("should return mocks", async () => {
- expect(Mocks.id).toEqual("mocks");
- });
- });
-
- describe("getDelay method", () => {
- it("should return delay option value", () => {
- mocks._currentDelayOption.value = "foo-delay";
- expect(mocks.getDelay()).toEqual("foo-delay");
- });
- });
-
- describe("load method", () => {
- it("should process loaded mocks", () => {
- mocks.load();
- expect(mocks.plainMocks).toEqual([]);
- });
-
- it("should process loaded routes", () => {
- mocks.load();
- expect(mocks.plainRoutes).toEqual([]);
- });
-
- it("should process routesVariants routes", () => {
- mocks.load();
- expect(mocks.plainRoutesVariants).toEqual([]);
- });
-
- it("should call onChange method", () => {
- mocks.load();
- expect(methods.onChange.callCount).toEqual(1);
- });
- });
-
- describe("when there are no mocks", () => {
- it("should call to create express router", () => {
- mocks.load();
- expect(express.Router.callCount).toEqual(1);
- mocks.router();
- expect(routerMock.callCount).toEqual(1);
- });
-
- it("should return null as current", () => {
- mocks.load();
- expect(mocks.current).toEqual(null);
- });
-
- it("should return empty array in ids", () => {
- mocks.load();
- expect(mocks.ids).toEqual([]);
- });
- });
-
- describe("when there are valid mocks and routes", () => {
- beforeEach(() => {
- methods.getLoadedMocks.returns([
- {
- id: "mock-1",
- routesVariants: ["route-1:variant-1", "route-2:variant-1"],
- },
- {
- id: "mock-2",
- from: "mock-1",
- routesVariants: ["route-2:variant-2"],
- },
- ]);
- methods.getLoadedRoutes.returns([
- {
- id: "route-1",
- variants: [{ id: "variant-1", method: "GET", response: { body: {}, status: 200 } }],
- },
- {
- id: "route-2",
- delay: 500,
- variants: [
- { id: "variant-1", method: "GET", response: { body: {}, status: 200 } },
- { id: "variant-2", delay: 1000, method: "GET", response: { body: {}, status: 200 } },
- ],
- },
- ]);
- });
-
- describe("when loaded", () => {
- it("should return mock id", () => {
- mocks.load();
- expect(mocks.current).toEqual("mock-id");
- });
-
- it("should return array of ids in ids getter", () => {
- mocks.load();
- expect(mocks.ids).toEqual(["mock-id"]);
- });
- });
-
- describe("when setting current mock", () => {
- it("should set current mock when it exists", () => {
- mocks.load();
- mocks.current = "mock-id";
- expect(mocks.current).toEqual("mock-id");
- });
-
- it("should set default mock when id does not exists", () => {
- mocks.load();
- mocks.current = "foo-id";
- expect(mocks.current).toEqual("mock-id");
- });
- });
-
- describe("when setting custom route variant", () => {
- it("should return customVariants", () => {
- mocks.load();
- mocks.useRouteVariant("route-2:variant-2");
- expect(mocks.customRoutesVariants).toEqual(["route-2:variant-2"]);
- });
- });
-
- describe("when restoring custom route variants", () => {
- it("should return empty array", () => {
- mocks.load();
- mocks.useRouteVariant("route-2:variant-2");
- expect(mocks.customRoutesVariants).toEqual(["route-2:variant-2"]);
- mocks.restoreRoutesVariants();
- expect(mocks.customRoutesVariants).toEqual([]);
- });
- });
- });
-
- describe("when there are no valid mocks", () => {
- beforeEach(() => {
- methods.getLoadedMocks.returns([null]);
- methods.getLoadedRoutes.returns([]);
- });
-
- describe("when loaded", () => {
- it("should add alerts", () => {
- mocks.load();
- expect(alerts.flat).toEqual([
- {
- id: "settings",
- value: { message: "Option 'mock' was not defined", error: undefined },
- collection: "mocks",
- },
- {
- id: "empty",
- value: { message: "No mocks found", error: undefined },
- collection: "mocks",
- },
- {
- id: "critical-error",
- value: {
- message: "Critical errors found while loading mocks: 1",
- error: undefined,
- },
- collection: "mocks:loadMocks",
- },
- {
- id: "validation",
- value: {
- message: "Mock is invalid: : type must be object",
- error: undefined,
- },
- collection: "mocks:loadMocks:0",
- },
- ]);
- });
- });
-
- describe("when setting current mock", () => {
- it("should not set mock when id does not exists", () => {
- mocks.load();
- mocks.current = "foo-id";
- expect(mocks.current).toEqual(null);
- });
- });
- });
-});
diff --git a/packages/core/test/plugins/Plugins.spec.js b/packages/core/test/plugins/Plugins.spec.js
index 49950ae48..5fb6b1c94 100644
--- a/packages/core/test/plugins/Plugins.spec.js
+++ b/packages/core/test/plugins/Plugins.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2019 Javier Brea
+Copyright 2019-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -12,11 +12,11 @@ const sinon = require("sinon");
const { Logger } = require("@mocks-server/logger");
const CoreMocks = require("../Core.mocks.js");
-const ConfigMocks = require("../Config.mocks.js");
-const LibsMocks = require("../Libs.mocks.js");
+const ConfigMocks = require("../common/Config.mocks.js");
+const LibsMocks = require("../common/Libs.mocks");
const Plugins = require("../../src/plugins/Plugins");
-const Alerts = require("../../src/Alerts.js");
+const Alerts = require("../../src/alerts/Alerts");
const NATIVE_PLUGINS_QUANTITY = 0;
@@ -73,7 +73,7 @@ describe("Plugins", () => {
addAlert: sandbox.stub(),
removeAlerts: sandbox.stub(),
renameAlerts: sandbox.stub(),
- createMocksLoader: sandbox.stub().returns(loadMocks),
+ createCollectionsLoader: sandbox.stub().returns(loadMocks),
createRoutesLoader: sandbox.stub().returns(loadRoutes),
};
plugins = new Plugins(callbacks, coreInstance);
@@ -273,6 +273,51 @@ describe("Plugins", () => {
expect(coreInstance.restartServer.callCount).toEqual(1);
});
+ it("should have core.server available", async () => {
+ const fooPlugin = {
+ register: ({ server }) => {
+ server.restart();
+ },
+ };
+ pluginsOption.value = [fooPlugin];
+ await plugins.register();
+ expect(coreInstance.server.restart.callCount).toEqual(1);
+ });
+
+ it("should have core.mock available", async () => {
+ const fooPlugin = {
+ register: ({ mock }) => {
+ mock.onChange();
+ },
+ };
+ pluginsOption.value = [fooPlugin];
+ await plugins.register();
+ expect(coreInstance.mock.onChange.callCount).toEqual(1);
+ });
+
+ it("should have core.variantHandlers available", async () => {
+ const fooPlugin = {
+ register: ({ variantHandlers }) => {
+ variantHandlers.register();
+ },
+ };
+ pluginsOption.value = [fooPlugin];
+ await plugins.register();
+ expect(coreInstance.variantHandlers.register.callCount).toEqual(1);
+ });
+
+ it("should have core.version available", async () => {
+ let version;
+ const fooPlugin = {
+ register: ({ version: coreVersion }) => {
+ version = coreVersion;
+ },
+ };
+ pluginsOption.value = [fooPlugin];
+ await plugins.register();
+ expect(version).toEqual("foo-version");
+ });
+
it("should have core addRouter method available", async () => {
const fooPlugin = {
register: ({ addRouter }) => {
@@ -397,7 +442,7 @@ describe("Plugins", () => {
it("should not register strings as plugins", async () => {
pluginsOption.value = ["foo"];
await plugins.register();
- expect(alerts.flat[0].value.message).toEqual('Error registering plugin "0"');
+ expect(alerts.flat[0].value.message).toEqual("Error registering plugin '0'");
expect(alerts.flat[0].collection).toEqual("plugins:register");
expect(logger.verbose.calledWith(pluginsTraceAddingNative(METHOD, 0))).toEqual(true);
});
@@ -405,7 +450,7 @@ describe("Plugins", () => {
it("should not register booleans as plugins", async () => {
pluginsOption.value = [true];
await plugins.register();
- expect(alerts.flat[0].value.message).toEqual('Error registering plugin "0"');
+ expect(alerts.flat[0].value.message).toEqual("Error registering plugin '0'");
expect(alerts.flat[0].collection).toEqual("plugins:register");
expect(logger.verbose.calledWith(pluginsTraceAddingNative(METHOD, 0))).toEqual(true);
});
@@ -549,7 +594,7 @@ describe("Plugins", () => {
}
pluginsOption.value = [FooPlugin];
await plugins.register();
- expect(alerts.flat[0].value.message).toEqual('Error registering plugin "0"');
+ expect(alerts.flat[0].value.message).toEqual("Error registering plugin '0'");
expect(alerts.flat[0].collection).toEqual("plugins:register");
expect(logger.verbose.calledWith(pluginsTraceAddingNative(METHOD, 0))).toEqual(true);
});
@@ -609,10 +654,10 @@ describe("Plugins", () => {
];
await plugins.register();
expect(alerts.flat.length).toEqual(6);
- expect(alerts.flat[0].value.message).toEqual('Error registering plugin "0"');
- expect(alerts.flat[1].value.message).toEqual('Error registering plugin "3"');
- expect(alerts.flat[2].value.message).toEqual('Error registering plugin "4"');
- expect(alerts.flat[3].value.message).toEqual('Error registering plugin "5"');
+ expect(alerts.flat[0].value.message).toEqual("Error registering plugin '0'");
+ expect(alerts.flat[1].value.message).toEqual("Error registering plugin '3'");
+ expect(alerts.flat[2].value.message).toEqual("Error registering plugin '4'");
+ expect(alerts.flat[3].value.message).toEqual("Error registering plugin '5'");
expect(logger.verbose.calledWith(pluginsTraceAddingNative(METHOD, 3))).toEqual(true);
});
});
@@ -646,7 +691,7 @@ describe("Plugins", () => {
pluginsOption.value = [fooPlugin];
await plugins.register();
await plugins.init();
- expect(logger.debug.calledWith('Initializing plugin "foo-plugin"')).toEqual(true);
+ expect(logger.debug.calledWith("Initializing plugin 'foo-plugin'")).toEqual(true);
});
it("should trace the plugin id when it is a static property in the class", async () => {
@@ -662,7 +707,7 @@ describe("Plugins", () => {
await plugins.register();
await plugins.init();
expect(plugins._pluginId(0)).toEqual("foo-plugin");
- expect(logger.debug.calledWith('Initializing plugin "foo-plugin"')).toEqual(true);
+ expect(logger.debug.calledWith("Initializing plugin 'foo-plugin'")).toEqual(true);
});
it("should accept init methods non returning a Promise", async () => {
@@ -695,7 +740,7 @@ describe("Plugins", () => {
await plugins.register();
await plugins.init();
expect(alerts.flat.length).toEqual(4);
- expect(alerts.flat[0].value.message).toEqual('Error initializating plugin "0"');
+ expect(alerts.flat[0].value.message).toEqual("Error initializating plugin '0'");
expect(logger.verbose.calledWith(pluginsTraceAddingNative(METHOD, 2))).toEqual(true);
});
@@ -813,7 +858,7 @@ describe("Plugins", () => {
pluginsOption.value = [fooPlugin];
await plugins.register();
await plugins.start();
- expect(logger.debug.calledWith('Starting plugin "foo-plugin"')).toEqual(true);
+ expect(logger.debug.calledWith("Starting plugin 'foo-plugin'")).toEqual(true);
});
it("should accept start methods non returning a Promise", async () => {
@@ -846,7 +891,7 @@ describe("Plugins", () => {
await plugins.register();
await plugins.start();
expect(alerts.flat.length).toEqual(4);
- expect(alerts.flat[0].value.message).toEqual('Error starting plugin "0"');
+ expect(alerts.flat[0].value.message).toEqual("Error starting plugin '0'");
expect(logger.verbose.calledWith(pluginsTraceAddingNative(METHOD, 2))).toEqual(true);
});
@@ -949,7 +994,7 @@ describe("Plugins", () => {
pluginsOption.value = [fooPlugin];
await plugins.register();
await plugins.stop();
- expect(logger.debug.calledWith('Stopping plugin "foo-plugin"')).toEqual(true);
+ expect(logger.debug.calledWith("Stopping plugin 'foo-plugin'")).toEqual(true);
});
it("should accept stop methods non returning a Promise", async () => {
@@ -983,7 +1028,7 @@ describe("Plugins", () => {
await plugins.register();
await plugins.stop();
expect(alerts.flat.length).toEqual(4);
- expect(alerts.flat[0].value.message).toEqual('Error stopping plugin "0"');
+ expect(alerts.flat[0].value.message).toEqual("Error stopping plugin '0'");
expect(logger.verbose.calledWith(pluginsTraceAddingNative(METHOD, 2))).toEqual(true);
});
diff --git a/packages/core/test/scaffold/Scaffold.spec.js b/packages/core/test/scaffold/Scaffold.spec.js
index 1dd5a0b6a..3ad22016e 100644
--- a/packages/core/test/scaffold/Scaffold.spec.js
+++ b/packages/core/test/scaffold/Scaffold.spec.js
@@ -14,8 +14,8 @@ const fsExtra = require("fs-extra");
const sinon = require("sinon");
const { Logger } = require("@mocks-server/logger");
-const LibsMocks = require("../Libs.mocks");
-const ConfigMock = require("../Config.mocks");
+const LibsMocks = require("../common/Libs.mocks");
+const ConfigMock = require("../common/Config.mocks");
const Scaffold = require("../../src/scaffold/Scaffold");
@@ -103,7 +103,8 @@ describe("Scaffold", () => {
expect(libsMocks.stubs.fsExtra.writeFile.callCount).toEqual(0);
});
- it("should set the selected mock value if it has not value before creating config", async () => {
+ // LEGACY, enable test when legacy mocks.selected option is removed
+ it.skip("should set the selected mock value if it has not value before creating config", async () => {
scaffold._mockSelectedOption.value = null;
await scaffold.init({ filesLoaderPath: "foo" });
expect(scaffold._mockSelectedOption.value).toEqual("base");
diff --git a/packages/core/test/scaffold/snapshots/config-1.js b/packages/core/test/scaffold/snapshots/config-1.js
index 6eee5270d..cab682821 100644
--- a/packages/core/test/scaffold/snapshots/config-1.js
+++ b/packages/core/test/scaffold/snapshots/config-1.js
@@ -1,6 +1,6 @@
// For a detailed explanation regarding each configuration property, visit:
-// https://mocks-server.org/docs/configuration-options
-// https://mocks-server.org/docs/configuration-methods
+// https://www.mocks-server.org/docs/configuration/how-to-change-settings
+// https://www.mocks-server.org/docs/configuration/options
module.exports = {
// It contains a string
diff --git a/packages/core/test/server/Server.mocks.js b/packages/core/test/server/Server.mocks.js
index f0234c2e0..a2aa2497a 100644
--- a/packages/core/test/server/Server.mocks.js
+++ b/packages/core/test/server/Server.mocks.js
@@ -1,5 +1,5 @@
/*
-Copyright 2019 Javier Brea
+Copyright 2019-2022 Javier Brea
Copyright 2019 XbyOrange
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -25,8 +25,8 @@ class Mock {
restart: this._sandbox.stub().resolves(),
stop: this._sandbox.stub().resolves(),
init: this._sandbox.stub().resolves(),
- addCustomRouter: this._sandbox.stub().resolves(),
- removeCustomRouter: this._sandbox.stub().resolves(),
+ addRouter: this._sandbox.stub().resolves(),
+ removeRouter: this._sandbox.stub().resolves(),
};
Server.mockImplementation(() => this._stubs);
diff --git a/packages/core/test/server/Server.spec.js b/packages/core/test/server/Server.spec.js
index 7ea16020f..30e0d826e 100644
--- a/packages/core/test/server/Server.spec.js
+++ b/packages/core/test/server/Server.spec.js
@@ -13,9 +13,9 @@ const sinon = require("sinon");
const http = require("http");
const { Logger } = require("@mocks-server/logger");
-const LibsMocks = require("../Libs.mocks.js");
-const ConfigMock = require("../Config.mocks");
-const Alerts = require("../../src/Alerts");
+const LibsMocks = require("../common/Libs.mocks");
+const ConfigMock = require("../common/Config.mocks");
+const Alerts = require("../../src/alerts/Alerts");
const bodyParser = require("body-parser");
const Server = require("../../src/server/Server");
@@ -124,7 +124,7 @@ describe("Server", () => {
describe("add custom routers method", () => {
it("should be registered when initializating http server", async () => {
const fooRouter = sandbox.spy();
- server.addCustomRouter("fooPath", fooRouter);
+ server.addRouter("fooPath", fooRouter);
libsMocks.stubs.http.createServer.onListen.returns(null);
await server.start();
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(true);
@@ -135,7 +135,7 @@ describe("Server", () => {
const fooRouter = sandbox.spy();
libsMocks.stubs.http.createServer.onListen.returns(null);
await server.start();
- await server.addCustomRouter("fooPath", fooRouter);
+ await server.addRouter("fooPath", fooRouter);
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(true);
expect(http.createServer.callCount).toEqual(2);
expect(libsMocks.stubs.http.createServer.listen.callCount).toEqual(2);
@@ -149,7 +149,7 @@ describe("Server", () => {
server.start();
server.start();
server.start();
- await server.addCustomRouter("fooPath", fooRouter);
+ await server.addRouter("fooPath", fooRouter);
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(true);
expect(http.createServer.callCount).toEqual(2);
expect(libsMocks.stubs.http.createServer.listen.callCount).toEqual(2);
@@ -162,7 +162,7 @@ describe("Server", () => {
libsMocks.stubs.http.createServer.onListen.returns(null);
await server.start();
await server.stop();
- await server.addCustomRouter("fooPath", fooRouter);
+ await server.addRouter("fooPath", fooRouter);
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(false);
await server.start();
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(true);
@@ -174,8 +174,8 @@ describe("Server", () => {
describe("remove custom routers method", () => {
it("should not be registered when initializating http server if called before it is started", async () => {
const fooRouter = sandbox.spy();
- server.addCustomRouter("fooPath", fooRouter);
- server.removeCustomRouter("fooPath", fooRouter);
+ server.addRouter("fooPath", fooRouter);
+ server.removeRouter("fooPath", fooRouter);
libsMocks.stubs.http.createServer.onListen.returns(null);
await server.start();
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(false);
@@ -185,11 +185,11 @@ describe("Server", () => {
expect.assertions(4);
const fooRouter = sandbox.spy();
libsMocks.stubs.http.createServer.onListen.returns(null);
- server.addCustomRouter("fooPath", fooRouter);
+ server.addRouter("fooPath", fooRouter);
await server.start();
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(true);
libsMocks.stubs.express.use.reset();
- await server.removeCustomRouter("fooPath", fooRouter);
+ await server.removeRouter("fooPath", fooRouter);
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(false);
expect(http.createServer.callCount).toEqual(2);
expect(libsMocks.stubs.http.createServer.listen.callCount).toEqual(2);
@@ -199,11 +199,11 @@ describe("Server", () => {
expect.assertions(3);
const fooRouter = sandbox.spy();
libsMocks.stubs.http.createServer.onListen.returns(null);
- server.addCustomRouter("fooPath", fooRouter);
+ server.addRouter("fooPath", fooRouter);
await server.start();
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(true);
libsMocks.stubs.express.use.reset();
- await server.removeCustomRouter("foooooPath", fooRouter);
+ await server.removeRouter("foooooPath", fooRouter);
expect(http.createServer.callCount).toEqual(1);
expect(libsMocks.stubs.http.createServer.listen.callCount).toEqual(1);
});
@@ -212,11 +212,11 @@ describe("Server", () => {
expect.assertions(3);
const fooRouter = sandbox.spy();
libsMocks.stubs.http.createServer.onListen.returns(null);
- server.addCustomRouter("fooPath", fooRouter);
+ server.addRouter("fooPath", fooRouter);
await server.start();
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(true);
libsMocks.stubs.express.use.reset();
- await server.removeCustomRouter("fooPath", () => {
+ await server.removeRouter("fooPath", () => {
// do nothing
});
expect(http.createServer.callCount).toEqual(1);
@@ -228,14 +228,14 @@ describe("Server", () => {
const fooRouter = sandbox.spy();
libsMocks.stubs.http.createServer.onListen.delay(500);
libsMocks.stubs.http.createServer.onListen.returns(null);
- server.addCustomRouter("fooPath", fooRouter);
+ server.addRouter("fooPath", fooRouter);
server.start();
await server.start();
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(true);
libsMocks.stubs.express.use.reset();
await server.stop();
server.start();
- await server.removeCustomRouter("fooPath", fooRouter);
+ await server.removeRouter("fooPath", fooRouter);
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(false);
expect(http.createServer.callCount).toEqual(2);
expect(libsMocks.stubs.http.createServer.listen.callCount).toEqual(3);
@@ -246,12 +246,12 @@ describe("Server", () => {
const fooRouter = sandbox.spy();
libsMocks.stubs.http.createServer.onListen.delay(500);
libsMocks.stubs.http.createServer.onListen.returns(null);
- server.addCustomRouter("fooPath", fooRouter);
+ server.addRouter("fooPath", fooRouter);
await server.start();
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(true);
libsMocks.stubs.express.use.reset();
await server.stop();
- await server.removeCustomRouter("fooPath", fooRouter);
+ await server.removeRouter("fooPath", fooRouter);
await server.start();
expect(libsMocks.stubs.express.use.calledWith("fooPath", fooRouter)).toEqual(false);
expect(http.createServer.callCount).toEqual(2);
diff --git a/packages/core/test/UpdateNotifier.mock.js b/packages/core/test/update-notifier/UpdateNotifier.mock.js
similarity index 88%
rename from packages/core/test/UpdateNotifier.mock.js
rename to packages/core/test/update-notifier/UpdateNotifier.mock.js
index 1997b6eb9..f37d2bd84 100644
--- a/packages/core/test/UpdateNotifier.mock.js
+++ b/packages/core/test/update-notifier/UpdateNotifier.mock.js
@@ -10,9 +10,9 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
-jest.mock("../src/UpdateNotifier");
+jest.mock("../../src/update-notifier/UpdateNotifier");
-const UpdateNotifier = require("../src/UpdateNotifier");
+const UpdateNotifier = require("../../src/update-notifier/UpdateNotifier");
class Mock {
constructor() {
diff --git a/packages/core/test/UpdateNotifier.spec.js b/packages/core/test/update-notifier/UpdateNotifier.spec.js
similarity index 94%
rename from packages/core/test/UpdateNotifier.spec.js
rename to packages/core/test/update-notifier/UpdateNotifier.spec.js
index 3056ac99a..cf256e4c1 100644
--- a/packages/core/test/UpdateNotifier.spec.js
+++ b/packages/core/test/update-notifier/UpdateNotifier.spec.js
@@ -9,13 +9,13 @@ Unless required by applicable law or agreed to in writing, software distributed
*/
const sinon = require("sinon");
-const packageJson = require("../package.json");
+const packageJson = require("../../package.json");
jest.mock("update-notifier");
const { Logger } = require("@mocks-server/logger");
const updateNotifier = require("update-notifier");
-const UpdateNotifier = require("../src/UpdateNotifier");
-const Alerts = require("../src/Alerts");
+const UpdateNotifier = require("../../src/update-notifier/UpdateNotifier");
+const Alerts = require("../../src/alerts/Alerts");
describe("UpdateNotifier", () => {
let sandbox, alerts, logger, updateNotifierMock;
diff --git a/packages/core/test/routes-handlers/handlers/Default.spec.js b/packages/core/test/variant-handlers/handlers/Default.spec.js
similarity index 97%
rename from packages/core/test/routes-handlers/handlers/Default.spec.js
rename to packages/core/test/variant-handlers/handlers/Default.spec.js
index 0b7cad625..705b6a2a9 100644
--- a/packages/core/test/routes-handlers/handlers/Default.spec.js
+++ b/packages/core/test/variant-handlers/handlers/Default.spec.js
@@ -12,9 +12,9 @@ const sinon = require("sinon");
const { Logger } = require("@mocks-server/logger");
const CoreMocks = require("../../Core.mocks.js");
-const DefaultRoutesHandler = require("../../../src/routes-handlers/handlers/Default");
+const DefaultRoutesHandler = require("../../../src/variant-handlers/handlers/Default");
-describe("Default routes handler", () => {
+describe("Default variant handler", () => {
const FOO_ROUTE = {
variantId: "foo-id",
method: "POST",
diff --git a/packages/core/test/routes-handlers/handlers/Json.spec.js b/packages/core/test/variant-handlers/handlers/Json.spec.js
similarity index 97%
rename from packages/core/test/routes-handlers/handlers/Json.spec.js
rename to packages/core/test/variant-handlers/handlers/Json.spec.js
index 4cb5bcd33..2da09ed50 100644
--- a/packages/core/test/routes-handlers/handlers/Json.spec.js
+++ b/packages/core/test/variant-handlers/handlers/Json.spec.js
@@ -11,7 +11,7 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
const CoreMocks = require("../../Core.mocks.js");
-const Json = require("../../../src/routes-handlers/handlers/Json");
+const Json = require("../../../src/variant-handlers/handlers/Json");
describe("Json routes handler", () => {
const FOO_VARIANT = {
diff --git a/packages/core/test/routes-handlers/handlers/Middleware.spec.js b/packages/core/test/variant-handlers/handlers/Middleware.spec.js
similarity index 96%
rename from packages/core/test/routes-handlers/handlers/Middleware.spec.js
rename to packages/core/test/variant-handlers/handlers/Middleware.spec.js
index cf9051f20..a1c50533d 100644
--- a/packages/core/test/routes-handlers/handlers/Middleware.spec.js
+++ b/packages/core/test/variant-handlers/handlers/Middleware.spec.js
@@ -11,7 +11,7 @@ Unless required by applicable law or agreed to in writing, software distributed
const sinon = require("sinon");
const CoreMocks = require("../../Core.mocks.js");
-const Middleware = require("../../../src/routes-handlers/handlers/Middleware");
+const Middleware = require("../../../src/variant-handlers/handlers/Middleware");
describe("Json routes handler", () => {
const FOO_VARIANT = {
diff --git a/packages/cypress-commands/CHANGELOG.md b/packages/cypress-commands/CHANGELOG.md
index 85b43b8d5..a33adcb89 100644
--- a/packages/cypress-commands/CHANGELOG.md
+++ b/packages/cypress-commands/CHANGELOG.md
@@ -10,6 +10,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
### Removed
+## [5.0.0] - 2022-07-22
+
+### Changed
+- feat: BREAKING CHANGE. Rename command `mocksSetMock` to `setCollection`
+- feat: BREAKING CHANGE. Rename command `mocksSetSettings` to `mocksSetConfig`
+- feat: BREAKING CHANGE. Rename command `mocksRestoreRoutesVariants` to `mocksRestoreRouteVariants`
+- feat: BREAKING CHANGE. Rename command `mocksConfig` to `mocksConfigAdminApiClient`
+
+### Removed
+- feat: BREAKING CHANGE. Remove environment variable `MOCKS_SERVER_BASE_URL`
+- feat: BREAKING CHANGE. Remove environment variable `MOCKS_SERVER_ADMIN_API_PATH`
+
+### Added
+- feat: Add environment variable `MOCKS_SERVER_ADMIN_API_PORT`
+- feat: Add environment variable `MOCKS_SERVER_ADMIN_API_HOST`
+
## [4.0.2] - 2022-07-05
### Changed
diff --git a/packages/cypress-commands/README.md b/packages/cypress-commands/README.md
index 3efa71719..5cabbc924 100644
--- a/packages/cypress-commands/README.md
+++ b/packages/cypress-commands/README.md
@@ -13,7 +13,7 @@
# Mocks Server Cypress commands
-Extends Cypress' cy commands with methods for easily changing [Mocks Server settings][mocks-server-options-url], such as current mock, route variants, delay time, etc.
+Extends Cypress' cy commands with methods for easily changing [Mocks Server configuration][mocks-server-options-url] while it is running, such as current collection, custom route variants, delay time, etc.
## Installation
@@ -37,48 +37,48 @@ You can now use all next commands:
### Commands
-##### `cy.mocksSetMock("users-error")`
+#### `cy.mocksSetCollection("users-error")`
-Set current mock.
+Set current collection.
-##### `cy.mocksUseRouteVariant("users:success")`
+#### `cy.mocksUseRouteVariant("users:success")`
-Set a specific route variant to be used by current mock.
+Set a specific route variant to be used by the current collection.
-##### `cy.mocksRestoreRoutesVariants()`
+#### `cy.mocksRestoreRouteVariants()`
-Restore routes variants to those defined in current mock.
+Restore route variants to those defined in the current collection.
-##### `cy.mocksSetDelay(2000)`
+#### `cy.mocksSetDelay(2000)`
-Set routes delay.
+Set routes default delay.
-##### `cy.mocksSetSettings({ files: { watch: false}, mocks: { delay: 0 }})`
+#### `cy.mocksSetConfig({ files: { watch: false}, mock: { routes: { delay: 0 }}})`
Set any [Mocks Server setting][mocks-server-options-url].
-##### `cy.mocksConfig({ adminApiPath: "/foo", baseUrl: "http://localhost:3000" })`
+#### `cy.mocksConfigAdminApiClient({ port: 3110, host: "127.0.0.1" })`
-Configures the [Mocks Server administration API client](https://github.com/mocks-server/admin-api-client), used under the hood.
+Configures the [Mocks Server administration API client](https://github.com/mocks-server/admin-api-client), used under the hood to communicate with the administration REST API. Use this command only if you changed the administration API configuration and you need to configure the client properly.
## Configuration
-By default, the API client is configured to request to `http://127.0.0.1:3100/admin`, based in the [default Mocks Server options][mocks-server-options-url]
+By default, the API client is configured to request to `http://127.0.0.1:3110/api`, based in the [default Mocks Server options][mocks-server-options-url]
-You can change both the base url of Mocks Server, and the api path of the administration API using the `cy.mocksConfig` command mentioned above, or the plugin environment variables:
+You can change both the host and port of the administration API using the `cy.mocksConfigAdminApiClient` command mentioned above, or the plugin environment variables:
-* __`MOCKS_SERVER_BASE_URL`__: Modifies the base url of Mocks Server. Default is `http://127.0.0.1:3100`.
-* __`MOCKS_SERVER_ADMIN_API_PATH`__: Modifies the path of the Mocks Server administration API. Default is `/admin`.
-* __`MOCKS_SERVER_ENABLED`__: Disables requests to Mocks Server, so the commands will not fail even when Mocks Server is not running. This is useful to reuse same tests with mocks and a real API, because commands to change Mocks Server settings will be ignored.
+* __`MOCKS_SERVER_ADMIN_API_PORT`__: Modifies the admin API client port. Default is `3110`.
+* __`MOCKS_SERVER_ADMIN_API_HOST`__: Modifies the admin API client host. Default is `127.0.0.1`.
+* __`MOCKS_SERVER_ENABLED`__: Disables requests to the Mocks Server admin API, so the commands will not fail even when Mocks Server is not running. This is useful to reuse same tests with a mocked API and a real API, because commands to change Mocks Server configuration will be ignored.
### Using commands
-You should usually change Mocks Server settings in a `before` statement:
+You should usually change Mocks Server configuration in a `before` statement:
```js
describe("user with default role", () => {
before(() => {
- cy.mocksSetMock("normal-user");
+ cy.mocksSetCollection("normal-user");
cy.visit("/");
});
@@ -89,7 +89,7 @@ describe("user with default role", () => {
describe("user with admin role", () => {
before(() => {
- cy.mocksSetMock("admin-user");
+ cy.mocksSetCollection("admin-user");
cy.visit("/");
});
@@ -99,9 +99,13 @@ describe("user with admin role", () => {
});
```
+## Release notes
+
+Current major release (`5.x`) is compatible only with `@mocks-server/main` versions upper or equal than `3.6`. Use prior releases for lower versions. If you don't want to update to the latest major version of this package yet but you want to update `@mocks-server/main`, you can also use any `4.x` version of this package with any `@mocks-server/main@3.x` version.
+
## License
MIT, see [LICENSE](./LICENSE) for details.
[mocks-server-url]: https://www.mocks-server.org
-[mocks-server-options-url]: https://www.mocks-server.org/docs/configuration-options
+[mocks-server-options-url]: https://www.mocks-server.org/docs/configuration/options
diff --git a/packages/cypress-commands/package.json b/packages/cypress-commands/package.json
index 05df4c37d..04a6d6028 100644
--- a/packages/cypress-commands/package.json
+++ b/packages/cypress-commands/package.json
@@ -1,6 +1,6 @@
{
"name": "@mocks-server/cypress-commands",
- "version": "4.0.2",
+ "version": "5.0.0",
"description": "Extends Cypress' cy commands with methods for administrating Mocks Server",
"keywords": [
"cypress",
diff --git a/packages/cypress-commands/sonar-project.properties b/packages/cypress-commands/sonar-project.properties
index 82faeeeda..f62e809b8 100644
--- a/packages/cypress-commands/sonar-project.properties
+++ b/packages/cypress-commands/sonar-project.properties
@@ -1,7 +1,7 @@
sonar.organization=mocks-server
sonar.projectKey=mocks-server_main_cypress-commands
sonar.projectName=cypress-commands
-sonar.projectVersion=4.0.2
+sonar.projectVersion=5.0.0
sonar.javascript.file.suffixes=.js
sonar.sourceEncoding=UTF-8
diff --git a/packages/cypress-commands/src/commands.js b/packages/cypress-commands/src/commands.js
index 25a0cebbd..0f4e89bb5 100644
--- a/packages/cypress-commands/src/commands.js
+++ b/packages/cypress-commands/src/commands.js
@@ -3,8 +3,8 @@ const apiClient = require("@mocks-server/admin-api-client");
const {
isFalsy,
ENABLED_ENVIRONMENT_VAR,
- BASE_URL_ENVIRONMENT_VAR,
- ADMIN_API_PATH_ENVIRONMENT_VAR,
+ ADMIN_API_PORT_ENVIRONMENT_VAR,
+ ADMIN_API_HOST_ENVIRONMENT_VAR,
} = require("./helpers");
function commands(Cypress) {
@@ -16,12 +16,14 @@ function commands(Cypress) {
return Promise.resolve();
};
- const setMock = (id) => {
+ const setCollection = (id) => {
if (isDisabled()) {
return doNothing();
}
- return apiClient.updateSettings({
- mocks: { selected: id },
+ return apiClient.updateConfig({
+ mock: {
+ collections: { selected: id },
+ },
});
};
@@ -29,16 +31,18 @@ function commands(Cypress) {
if (isDisabled()) {
return doNothing();
}
- return apiClient.updateSettings({
- mocks: { delay },
+ return apiClient.updateConfig({
+ mock: {
+ routes: { delay },
+ },
});
};
- const setSettings = (newSettings) => {
+ const setConfig = (newConfig) => {
if (isDisabled()) {
return doNothing();
}
- return apiClient.updateSettings(newSettings);
+ return apiClient.updateConfig(newConfig);
};
const useRouteVariant = (id) => {
@@ -48,31 +52,31 @@ function commands(Cypress) {
return apiClient.useRouteVariant(id);
};
- const restoreRoutesVariants = () => {
+ const restoreRouteVariants = () => {
if (isDisabled()) {
return doNothing();
}
- return apiClient.restoreRoutesVariants();
+ return apiClient.restoreRouteVariants();
};
- const config = (customConfig) => {
- return apiClient.config(customConfig);
+ const configClient = (customConfig) => {
+ return apiClient.configClient(customConfig);
};
- if (Cypress.env(ADMIN_API_PATH_ENVIRONMENT_VAR)) {
- config({ adminApiPath: Cypress.env(ADMIN_API_PATH_ENVIRONMENT_VAR) });
+ if (Cypress.env(ADMIN_API_PORT_ENVIRONMENT_VAR)) {
+ configClient({ port: Cypress.env(ADMIN_API_PORT_ENVIRONMENT_VAR) });
}
- if (Cypress.env(BASE_URL_ENVIRONMENT_VAR)) {
- config({ baseUrl: Cypress.env(BASE_URL_ENVIRONMENT_VAR) });
+ if (Cypress.env(ADMIN_API_HOST_ENVIRONMENT_VAR)) {
+ configClient({ host: Cypress.env(ADMIN_API_HOST_ENVIRONMENT_VAR) });
}
return {
- setMock,
+ setCollection,
setDelay,
- setSettings,
- config,
+ setConfig,
useRouteVariant,
- restoreRoutesVariants,
+ restoreRouteVariants,
+ configClient,
};
}
diff --git a/packages/cypress-commands/src/helpers.js b/packages/cypress-commands/src/helpers.js
index 3c22972d0..94070aeea 100644
--- a/packages/cypress-commands/src/helpers.js
+++ b/packages/cypress-commands/src/helpers.js
@@ -1,6 +1,6 @@
const ENABLED_ENVIRONMENT_VAR = "MOCKS_SERVER_ENABLED";
-const BASE_URL_ENVIRONMENT_VAR = "MOCKS_SERVER_BASE_URL";
-const ADMIN_API_PATH_ENVIRONMENT_VAR = "MOCKS_SERVER_ADMIN_API_PATH";
+const ADMIN_API_HOST_ENVIRONMENT_VAR = "MOCKS_SERVER_ADMIN_API_HOST";
+const ADMIN_API_PORT_ENVIRONMENT_VAR = "MOCKS_SERVER_ADMIN_API_PORT";
const FALSY_VALUES = [false, "false", 0, "0"];
@@ -14,7 +14,7 @@ function isFalsy(value) {
module.exports = {
ENABLED_ENVIRONMENT_VAR,
- BASE_URL_ENVIRONMENT_VAR,
- ADMIN_API_PATH_ENVIRONMENT_VAR,
+ ADMIN_API_HOST_ENVIRONMENT_VAR,
+ ADMIN_API_PORT_ENVIRONMENT_VAR,
isFalsy,
};
diff --git a/packages/cypress-commands/src/register.js b/packages/cypress-commands/src/register.js
index da30c75c2..fdc293c00 100644
--- a/packages/cypress-commands/src/register.js
+++ b/packages/cypress-commands/src/register.js
@@ -1,15 +1,22 @@
const commands = require("./commands");
const register = (Cypress) => {
- const { config, setMock, setDelay, setSettings, useRouteVariant, restoreRoutesVariants } =
- commands(Cypress);
+ const {
+ configClient,
+ setCollection,
+ setDelay,
+ setConfig,
+ useRouteVariant,
+ restoreRouteVariants,
+ } = commands(Cypress);
- Cypress.Commands.add("mocksConfig", config);
- Cypress.Commands.add("mocksSetMock", setMock);
+ Cypress.Commands.add("mocksSetCollection", setCollection);
Cypress.Commands.add("mocksSetDelay", setDelay);
- Cypress.Commands.add("mocksSetSettings", setSettings);
+ Cypress.Commands.add("mocksSetConfig", setConfig);
Cypress.Commands.add("mocksUseRouteVariant", useRouteVariant);
- Cypress.Commands.add("mocksRestoreRoutesVariants", restoreRoutesVariants);
+ Cypress.Commands.add("mocksRestoreRouteVariants", restoreRouteVariants);
+
+ Cypress.Commands.add("mocksConfigAdminApiClient", configClient);
};
module.exports = register;
diff --git a/packages/cypress-commands/test/commands.spec.js b/packages/cypress-commands/test/commands.spec.js
index 655589a49..701d53519 100644
--- a/packages/cypress-commands/test/commands.spec.js
+++ b/packages/cypress-commands/test/commands.spec.js
@@ -8,18 +8,17 @@ const commands = require("../src/commands");
describe("commands", () => {
let sandbox;
let cypressMock;
- let setMock, setDelay, setSettings, useRouteVariant, restoreRoutesVariants, config;
+ let setCollection, setDelay, setConfig, useRouteVariant, restoreRouteVariants, configClient;
beforeEach(() => {
sandbox = sinon.createSandbox();
- sandbox.stub(apiClient, "updateSettings");
+ sandbox.stub(apiClient, "updateConfig");
sandbox.stub(apiClient, "useRouteVariant");
- sandbox.stub(apiClient, "restoreRoutesVariants");
- sandbox.stub(apiClient, "config");
+ sandbox.stub(apiClient, "restoreRouteVariants");
+ sandbox.stub(apiClient, "configClient");
cypressMock = new CypressMock();
- ({ setMock, setDelay, setSettings, useRouteVariant, restoreRoutesVariants, config } = commands(
- cypressMock.stubs
- ));
+ ({ setCollection, setDelay, setConfig, useRouteVariant, restoreRouteVariants, configClient } =
+ commands(cypressMock.stubs));
});
afterEach(() => {
@@ -27,34 +26,36 @@ describe("commands", () => {
});
describe("when initializing", () => {
- it("should call to set adminApiPath config if env var is defined", () => {
- cypressMock.stubs.env.withArgs("MOCKS_SERVER_ADMIN_API_PATH").returns("foo");
+ it("should call to set port config if env var is defined", () => {
+ cypressMock.stubs.env.withArgs("MOCKS_SERVER_ADMIN_API_PORT").returns("foo");
commands(cypressMock.stubs);
expect(
- apiClient.config.calledWith({
- adminApiPath: "foo",
+ apiClient.configClient.calledWith({
+ port: "foo",
})
).toBe(true);
});
it("should call to set baseUrl config if env var is defined", () => {
- cypressMock.stubs.env.withArgs("MOCKS_SERVER_BASE_URL").returns("foo");
+ cypressMock.stubs.env.withArgs("MOCKS_SERVER_ADMIN_API_HOST").returns("foo");
commands(cypressMock.stubs);
expect(
- apiClient.config.calledWith({
- baseUrl: "foo",
+ apiClient.configClient.calledWith({
+ host: "foo",
})
).toBe(true);
});
});
- describe("setMock command", () => {
- it("should call to update delay", () => {
- setMock("foo");
+ describe("setCollection command", () => {
+ it("should call to set current collection", () => {
+ setCollection("foo");
expect(
- apiClient.updateSettings.calledWith({
- mocks: {
- selected: "foo",
+ apiClient.updateConfig.calledWith({
+ mock: {
+ collections: {
+ selected: "foo",
+ },
},
})
).toBe(true);
@@ -62,8 +63,8 @@ describe("commands", () => {
it("should do nothing if plugin is disabled", () => {
cypressMock.stubs.env.returns("false");
- setMock("foo");
- expect(apiClient.updateSettings.callCount).toEqual(0);
+ setCollection("foo");
+ expect(apiClient.updateConfig.callCount).toEqual(0);
});
});
@@ -71,9 +72,11 @@ describe("commands", () => {
it("should call to update delay", () => {
setDelay(3000);
expect(
- apiClient.updateSettings.calledWith({
- mocks: {
- delay: 3000,
+ apiClient.updateConfig.calledWith({
+ mock: {
+ routes: {
+ delay: 3000,
+ },
},
})
).toBe(true);
@@ -82,20 +85,20 @@ describe("commands", () => {
it("should do nothing if plugin is disabled", () => {
cypressMock.stubs.env.returns("false");
setDelay("foo");
- expect(apiClient.updateSettings.callCount).toEqual(0);
+ expect(apiClient.updateConfig.callCount).toEqual(0);
});
});
- describe("setSettings command", () => {
- it("should call to update delay", () => {
- setSettings("foo");
- expect(apiClient.updateSettings.calledWith("foo")).toBe(true);
+ describe("setConfig command", () => {
+ it("should call to update config", () => {
+ setConfig("foo");
+ expect(apiClient.updateConfig.calledWith("foo")).toBe(true);
});
it("should do nothing if plugin is disabled", () => {
cypressMock.stubs.env.returns("0");
- setSettings("foo");
- expect(apiClient.updateSettings.callCount).toEqual(0);
+ setConfig("foo");
+ expect(apiClient.updateConfig.callCount).toEqual(0);
});
});
@@ -112,38 +115,40 @@ describe("commands", () => {
});
});
- describe("restoreRoutesVariants command", () => {
+ describe("restoreRouteVariants command", () => {
it("should call to useRoute variant", () => {
- restoreRoutesVariants();
- expect(apiClient.restoreRoutesVariants.callCount).toEqual(1);
+ restoreRouteVariants();
+ expect(apiClient.restoreRouteVariants.callCount).toEqual(1);
});
it("should do nothing if plugin is disabled", () => {
cypressMock.stubs.env.returns(false);
- restoreRoutesVariants();
- expect(apiClient.restoreRoutesVariants.callCount).toEqual(0);
+ restoreRouteVariants();
+ expect(apiClient.restoreRouteVariants.callCount).toEqual(0);
});
});
- describe("config method", () => {
- it("should call to config admin-api-client baseUrl", () => {
- config({
- baseUrl: "foo",
+ describe("configClient method", () => {
+ it("should call to config admin-api-client host", () => {
+ configClient({
+ host: "foo",
});
expect(
- apiClient.config.calledWith({
- baseUrl: "foo",
+ apiClient.configClient.calledWith({
+ host: "foo",
})
).toBe(true);
});
- it("should call to config admin-api-client apiPath with adminApiPath value", () => {
- config({
- adminApiPath: "foo",
+ it("should call to config admin-api-client apiPath port and host", () => {
+ configClient({
+ host: "foo",
+ port: "foo-2",
});
expect(
- apiClient.config.calledWith({
- adminApiPath: "foo",
+ apiClient.configClient.calledWith({
+ host: "foo",
+ port: "foo-2",
})
).toBe(true);
});
diff --git a/packages/cypress-commands/test/register.spec.js b/packages/cypress-commands/test/register.spec.js
index c8976b7aa..eac4692b9 100644
--- a/packages/cypress-commands/test/register.spec.js
+++ b/packages/cypress-commands/test/register.spec.js
@@ -15,28 +15,28 @@ describe("register", () => {
});
describe("commands", () => {
- it("should register mocksConfig command", () => {
- expect(cypressMock.stubs.Commands.add.calledWith("mocksConfig")).toBe(true);
+ it("should register mocksConfigAdminApiClient command", () => {
+ expect(cypressMock.stubs.Commands.add.calledWith("mocksConfigAdminApiClient")).toBe(true);
});
- it("should register mocksSetMock command", () => {
- expect(cypressMock.stubs.Commands.add.calledWith("mocksSetMock")).toBe(true);
+ it("should register mocksSetCollection command", () => {
+ expect(cypressMock.stubs.Commands.add.calledWith("mocksSetCollection")).toBe(true);
});
it("should register mocksSetDelay command", () => {
expect(cypressMock.stubs.Commands.add.calledWith("mocksSetDelay")).toBe(true);
});
- it("should register mocksSetSettings command", () => {
- expect(cypressMock.stubs.Commands.add.calledWith("mocksSetSettings")).toBe(true);
+ it("should register mocksSetConfig command", () => {
+ expect(cypressMock.stubs.Commands.add.calledWith("mocksSetConfig")).toBe(true);
});
it("should register mocksUseRouteVariant command", () => {
expect(cypressMock.stubs.Commands.add.calledWith("mocksUseRouteVariant")).toBe(true);
});
- it("should register mocksRestoreRoutesVariants command", () => {
- expect(cypressMock.stubs.Commands.add.calledWith("mocksRestoreRoutesVariants")).toBe(true);
+ it("should register mocksRestoreRouteVariants command", () => {
+ expect(cypressMock.stubs.Commands.add.calledWith("mocksRestoreRouteVariants")).toBe(true);
});
});
});
diff --git a/packages/main/CHANGELOG.md b/packages/main/CHANGELOG.md
index 17ff82381..71a1fd00a 100644
--- a/packages/main/CHANGELOG.md
+++ b/packages/main/CHANGELOG.md
@@ -14,6 +14,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Removed
### Breaking change
+## [3.6.0] - 2022-07-22
+
+### Added
+- feat: Export createServer function returning a core instance with preinstalled plugins
+
## [3.5.0] - 2022-07-05
### Changed
diff --git a/packages/main/index.js b/packages/main/index.js
index 1ffe04912..dc8ba8f76 100644
--- a/packages/main/index.js
+++ b/packages/main/index.js
@@ -1,5 +1,5 @@
/*
-Copyright 2019-present Javier Brea
+Copyright 2019-2022 Javier Brea
Copyright 2019 XbyOrange
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -12,5 +12,7 @@ Unless required by applicable law or agreed to in writing, software distributed
"use strict";
const Core = require("@mocks-server/core");
+const { createCore } = require("./src/createCore");
module.exports = Core;
+module.exports.createServer = createCore;
diff --git a/packages/main/package.json b/packages/main/package.json
index c7128a42b..05c8547b8 100644
--- a/packages/main/package.json
+++ b/packages/main/package.json
@@ -1,6 +1,6 @@
{
"name": "@mocks-server/main",
- "version": "3.5.0",
+ "version": "3.6.0",
"description": "Mock Server supporting multiple route variants and mocks",
"keywords": [
"mock",
@@ -45,7 +45,8 @@
"@mocks-server/core": "workspace:*",
"@mocks-server/plugin-admin-api": "workspace:*",
"@mocks-server/plugin-inquirer-cli": "workspace:*",
- "@mocks-server/plugin-proxy": "workspace:*"
+ "@mocks-server/plugin-proxy": "workspace:*",
+ "deepmerge": "4.2.2"
},
"engines": {
"node": ">=14.0.0"
diff --git a/packages/main/sonar-project.properties b/packages/main/sonar-project.properties
index 6870dcafd..c0f9e2417 100644
--- a/packages/main/sonar-project.properties
+++ b/packages/main/sonar-project.properties
@@ -1,7 +1,7 @@
sonar.organization=mocks-server
sonar.projectKey=mocks-server_main
sonar.projectName=main
-sonar.projectVersion=3.5.0
+sonar.projectVersion=3.6.0
sonar.javascript.file.suffixes=.js
sonar.sourceEncoding=UTF-8
diff --git a/packages/main/src/createCore.js b/packages/main/src/createCore.js
new file mode 100644
index 000000000..7401e635b
--- /dev/null
+++ b/packages/main/src/createCore.js
@@ -0,0 +1,48 @@
+/*
+Copyright 2019-2022 Javier Brea
+Copyright 2019 XbyOrange
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+"use strict";
+
+const Core = require("@mocks-server/core");
+const PluginProxy = require("@mocks-server/plugin-proxy");
+const AdminApi = require("@mocks-server/plugin-admin-api");
+const InquirerCli = require("@mocks-server/plugin-inquirer-cli");
+const deepMerge = require("deepmerge");
+
+const pkg = require("../package.json");
+
+const DEFAULT_CONFIG = {
+ config: {
+ readArguments: false,
+ readEnvironment: false,
+ readFile: false,
+ },
+ plugins: {
+ register: [PluginProxy, AdminApi, InquirerCli],
+ inquirerCli: {
+ enabled: false,
+ },
+ },
+ files: {
+ enabled: false,
+ },
+};
+
+const createCore = (userConfig) => {
+ const config = userConfig ? deepMerge(DEFAULT_CONFIG, userConfig) : DEFAULT_CONFIG;
+ return new Core(config, {
+ pkg,
+ });
+};
+
+module.exports = {
+ createCore,
+};
diff --git a/packages/main/src/start.js b/packages/main/src/start.js
index ee878c1c1..405731eff 100644
--- a/packages/main/src/start.js
+++ b/packages/main/src/start.js
@@ -1,5 +1,5 @@
/*
-Copyright 2019-present Javier Brea
+Copyright 2019-2022 Javier Brea
Copyright 2019 XbyOrange
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -10,11 +10,8 @@ Unless required by applicable law or agreed to in writing, software distributed
*/
"use strict";
-const Core = require("@mocks-server/core");
-const PluginProxy = require("@mocks-server/plugin-proxy");
-const AdminApi = require("@mocks-server/plugin-admin-api");
-const InquirerCli = require("@mocks-server/plugin-inquirer-cli");
-const pkg = require("../package.json");
+
+const { createCore } = require("./createCore");
const handleError = (error) => {
console.error(`Error: ${error.message}`);
@@ -23,16 +20,21 @@ const handleError = (error) => {
const start = () => {
try {
- const mocksServer = new Core(
- {
- plugins: {
- register: [PluginProxy, AdminApi, InquirerCli],
+ const mocksServer = createCore({
+ config: {
+ readArguments: true,
+ readEnvironment: true,
+ readFile: true,
+ },
+ plugins: {
+ inquirerCli: {
+ enabled: true,
},
},
- {
- pkg,
- }
- );
+ files: {
+ enabled: true,
+ },
+ });
return mocksServer.start().catch(handleError);
} catch (error) {
return handleError(error);
diff --git a/packages/main/test/createCore.spec.js b/packages/main/test/createCore.spec.js
new file mode 100644
index 000000000..1e292da0e
--- /dev/null
+++ b/packages/main/test/createCore.spec.js
@@ -0,0 +1,93 @@
+/*
+Copyright 2019-present Javier Brea
+Copyright 2019 XbyOrange
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const sinon = require("sinon");
+const PluginProxy = require("@mocks-server/plugin-proxy");
+const AdminApi = require("@mocks-server/plugin-admin-api");
+const InquirerCli = require("@mocks-server/plugin-inquirer-cli");
+
+const CoreMocks = require("./Core.mocks.js");
+
+const { createCore } = require("../src/createCore");
+
+describe("createCore method", () => {
+ let sandbox;
+ let coreMocks;
+
+ beforeEach(() => {
+ sandbox = sinon.createSandbox();
+ coreMocks = new CoreMocks();
+ expect.assertions(1);
+ });
+
+ afterEach(() => {
+ sandbox.restore();
+ coreMocks.restore();
+ });
+
+ it("should create a new Core, passing to it default options", async () => {
+ createCore();
+ expect(coreMocks.stubs.Constructor.mock.calls[0][0]).toEqual({
+ config: {
+ readArguments: false,
+ readEnvironment: false,
+ readFile: false,
+ },
+ plugins: {
+ register: [PluginProxy, AdminApi, InquirerCli],
+ inquirerCli: {
+ enabled: false,
+ },
+ },
+ files: {
+ enabled: false,
+ },
+ });
+ });
+
+ it("should merge provided config", async () => {
+ class FooPlugin {}
+ createCore({
+ plugins: {
+ register: [FooPlugin],
+ },
+ files: {
+ enabled: true,
+ },
+ mock: {
+ collections: {
+ selected: "foo",
+ },
+ },
+ });
+ expect(coreMocks.stubs.Constructor.mock.calls[0][0]).toEqual({
+ config: {
+ readArguments: false,
+ readEnvironment: false,
+ readFile: false,
+ },
+ plugins: {
+ register: [PluginProxy, AdminApi, InquirerCli, FooPlugin],
+ inquirerCli: {
+ enabled: false,
+ },
+ },
+ files: {
+ enabled: true,
+ },
+ mock: {
+ collections: {
+ selected: "foo",
+ },
+ },
+ });
+ });
+});
diff --git a/packages/main/test/start.spec.js b/packages/main/test/start.spec.js
index dc3d6a278..13c51dfb0 100644
--- a/packages/main/test/start.spec.js
+++ b/packages/main/test/start.spec.js
@@ -33,12 +33,15 @@ describe("start method", () => {
coreMocks.restore();
});
- it("should create a new Core, passing to it Proxy, AdminApi and CLI plugins", async () => {
+ it("should create a new Core, passing to it options for CLI", async () => {
await start();
expect(coreMocks.stubs.Constructor.mock.calls[0][0]).toEqual({
+ config: { readArguments: true, readEnvironment: true, readFile: true },
plugins: {
register: [PluginProxy, AdminApi, InquirerCli],
+ inquirerCli: { enabled: true },
},
+ files: { enabled: true },
});
});
diff --git a/packages/plugin-admin-api/CHANGELOG.md b/packages/plugin-admin-api/CHANGELOG.md
index c4638a740..4351c4a37 100644
--- a/packages/plugin-admin-api/CHANGELOG.md
+++ b/packages/plugin-admin-api/CHANGELOG.md
@@ -12,6 +12,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
### Removed
+## [3.2.0] - 2022-07-22
+
+### Added
+- feat(#364): Start API in a different server. Change urls and models.
+- feat(#360): Add Swagger-ui
+
+### Changed
+- feat: Use new core.server API
+- feat: Use core.mock.restoreRouteVariants
+- feat: Use core.mock.routes.plain getter
+- feat: Use core.mock.routes.plainVariants getter
+- feat: Use core.mock.customRouteVariants getter
+- feat: Use core.mock.collections.plain getter
+
## [3.1.0] - 2022-06-27
### Changed
diff --git a/packages/plugin-admin-api/README.md b/packages/plugin-admin-api/README.md
index 994ef5001..54a5512c5 100644
--- a/packages/plugin-admin-api/README.md
+++ b/packages/plugin-admin-api/README.md
@@ -13,51 +13,31 @@
# Mocks Server Plugin Admin Api
-Plugin for [Mocks Server][website-url] that provides an API REST that allows to change the current mock, change delay time, and another [Mocks Server options][options-url].
+Plugin for [Mocks Server][website-url] that provides a REST API allowing to interact with the server while it is running.
-This is __very useful when running acceptance tests, as you can change the current mock__ simply with a HTTP request in the `before` method of your tests, for example.
+This is __very useful when running E2E tests, because you can change the responses of the API mock__ simply with a HTTP request in the `before` method of your tests, for example.
A __client for the administration api__ is also distributed as a separated package: [@mocks-server/admin-api-client](https://www.npmjs.com/package/@mocks-server/admin-api-client).
## Usage
-This plugin is included in the [main distribution of the Mocks Server project][main-distribution-url], so you can refer to the [official documentation website][website-url].
+This plugin is included in the main distribution of the Mocks Server project, so you can refer to the [official documentation website][website-url].
## Options
-* __`adminApiPath`__ _(String)_: Path for the administration api. Default is `/admin`. You should change it only in case there is any conflict with the api you are mocking.
-
-Read more about [how to set options in Mocks Server here](https://www.mocks-server.org/docs/configuration-options).
-
-## API Resources
-
-Available api resources are:
-
-* `GET` `/admin/about` Returns "plugin-admin-api" information.
- * Response body example: `{ "version": "1.2.0" }`
-* `GET` `/admin/mocks` Returns mocks.
-* `GET` `/admin/mocks/:id` Returns a specific mock.
-* `GET` `/admin/routes` Returns routes collection.
-* `GET` `/admin/routes/:id` Returns a specific route.
-* `GET` `/admin/routes-variants` Returns routes variants collection.
-* `GET` `/admin/routes-variants/:id` Returns a specific route variant.
-* `GET` `/admin/mock-custom-routes-variants` Returns an array of currently custom routes variants ids.
-* `POST` `/admin/mock-custom-routes-variants` Defines a route variant to be used by current mock.
- * Request body example: `{ "id": "users:error" }`
-* `DELETE` `/admin/mock-custom-routes-variants` Restore routes variants to those defined in current mock.
-* `GET` `/admin/settings` Returns current server settings.
- * Response body example: `{ "delay": 0, mock: "foo-mock", path: "mocks" }`
-* `PATCH` `/admin/settings` Changes current server settings.
- * Request body example: `{ "delay": 3000 }`
-* `GET` `/admin/alerts` Returns current alerts.
-* `GET` `/admin/alerts/:id` Returns a specific alert. The alert `id` is equivalent to the alert `context` _(read the [developing plugins chapter](plugins-developing-plugins.md) for further info about alerts)_.
+* __`plugins.adminApi.port`__ _(Number)_: Port for the administration REST API. Default is `3110`.
+* __`plugins.adminApi.host`__ _(String)_: Host for the administration REST API. Default is `0.0.0.0` (Reachable to all IPv4 addresses on the local machine).
+
+Read more about [how to set options in Mocks Server here](https://www.mocks-server.org/docs/configuration/how-to-change-settings).
+
+## API resources
+
+Available API resources are described in the OpenAPI specification provided by the API server itself at [http://localhost:3110/docs/open-api.json](http://localhost:3110/docs/open-api.json) once it is started.
## Contributing
Contributors are welcome.
Please read the [contributing guidelines](.github/CONTRIBUTING.md) and [code of conduct](.github/CODE_OF_CONDUCT.md).
-[website-url]: https://www.mocks-server.org
-[main-distribution-url]: https://www.npmjs.com/package/@mocks-server/main
-[options-url]: https://www.mocks-server.org/docs/configuration-options
+[website-url]: https://www.mocks-server.org/docs/integrations/rest-api
[logo-url]: https://www.mocks-server.org/img/logo_120.png
diff --git a/packages/plugin-admin-api/jest.config.js b/packages/plugin-admin-api/jest.config.js
index 33305c705..07ea720d3 100644
--- a/packages/plugin-admin-api/jest.config.js
+++ b/packages/plugin-admin-api/jest.config.js
@@ -26,7 +26,7 @@ module.exports = {
// The glob patterns Jest uses to detect test files
testMatch: ["/test/**/*.spec.js"],
- // testMatch: ["/test/**/mock-custom-routes-variants-api.spec.js"],
+ // testMatch: ["/test/legacy/settings-api.spec.js"],
// The test environment that will be used for testing
testEnvironment: "node",
diff --git a/packages/plugin-admin-api/package.json b/packages/plugin-admin-api/package.json
index 05c6bd29e..cedc02a7d 100644
--- a/packages/plugin-admin-api/package.json
+++ b/packages/plugin-admin-api/package.json
@@ -1,7 +1,7 @@
{
"name": "@mocks-server/plugin-admin-api",
- "version": "3.1.0",
- "description": "Mocks Server plugin providing a REST API for administration",
+ "version": "3.2.0",
+ "description": "Mocks Server plugin providing an administration REST API",
"keywords": [
"mocks-server-plugin",
"administration",
@@ -24,6 +24,7 @@
},
"files": [
"src",
+ "static",
"index.js"
],
"main": "index.js",
@@ -31,13 +32,16 @@
"test:unit": "jest --runInBand"
},
"peerDependencies": {
- "@mocks-server/core": ">=3.2.0 <4.x"
+ "@mocks-server/core": ">=3.6.0 <4.x"
},
"dependencies": {
"@hapi/boom": "9.1.4",
"@mocks-server/admin-api-paths": "workspace:*",
+ "swagger-ui-dist": "4.13.0",
+ "body-parser": "1.20.0",
"cors": "2.8.5",
- "express": "4.18.1"
+ "express": "4.18.1",
+ "express-request-id": "1.4.1"
},
"devDependencies": {
"@mocks-server/core": "workspace:*"
diff --git a/packages/plugin-admin-api/sonar-project.properties b/packages/plugin-admin-api/sonar-project.properties
index 9770942a6..795dc4dd9 100644
--- a/packages/plugin-admin-api/sonar-project.properties
+++ b/packages/plugin-admin-api/sonar-project.properties
@@ -1,7 +1,7 @@
sonar.organization=mocks-server
sonar.projectKey=mocks-server_main_plugin-admin-api
sonar.projectName=plugin-admin-api
-sonar.projectVersion=3.1.0
+sonar.projectVersion=3.2.0
sonar.javascript.file.suffixes=.js
sonar.sourceEncoding=UTF-8
diff --git a/packages/plugin-admin-api/src/About.js b/packages/plugin-admin-api/src/About.js
index 3fbc39db1..15de1be4e 100644
--- a/packages/plugin-admin-api/src/About.js
+++ b/packages/plugin-admin-api/src/About.js
@@ -13,21 +13,18 @@ Unless required by applicable law or agreed to in writing, software distributed
const express = require("express");
-const { version } = require("../package.json");
-
class AboutApi {
- constructor({ logger }) {
+ constructor({ logger, getResponse }) {
this._logger = logger;
this._router = express.Router();
this._router.get("/", this.getAbout.bind(this));
+ this._getResponse = getResponse;
}
getAbout(req, res) {
this._logger.verbose(`Sending about | ${req.id}`);
res.status(200);
- res.send({
- version,
- });
+ res.send(this._getResponse());
}
get router() {
diff --git a/packages/plugin-admin-api/src/Alerts.js b/packages/plugin-admin-api/src/Alerts.js
index 5d9c5399d..0444a195b 100644
--- a/packages/plugin-admin-api/src/Alerts.js
+++ b/packages/plugin-admin-api/src/Alerts.js
@@ -16,7 +16,8 @@ const express = require("express");
const { addCollectionMiddleware, addModelMiddleware } = require("./support/middlewares");
class AlertsApi {
- constructor({ logger, alerts }) {
+ constructor({ logger, alerts, parseAlert }) {
+ this._parseAlert = parseAlert;
this._alerts = alerts;
this._logger = logger;
this._router = express.Router();
@@ -35,22 +36,11 @@ class AlertsApi {
}
_parseModel(alert) {
- return {
- id: alert.context,
- context: alert.context,
- message: alert.message,
- error: alert.error
- ? {
- name: alert.error.name,
- message: alert.error.message,
- stack: alert.error.stack,
- }
- : null,
- };
+ return this._parseAlert(alert);
}
_parseCollection() {
- return this._alerts.root.customFlat.map(this._parseModel);
+ return this._alerts.root.customFlat.map(this._parseModel.bind(this));
}
_getCollection() {
diff --git a/packages/plugin-admin-api/src/Api.js b/packages/plugin-admin-api/src/Api.js
new file mode 100644
index 000000000..044f72eb5
--- /dev/null
+++ b/packages/plugin-admin-api/src/Api.js
@@ -0,0 +1,117 @@
+/*
+Copyright 2019-2022 Javier Brea
+Copyright 2019 XbyOrange
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const express = require("express");
+
+const {
+ ABOUT,
+ CONFIG,
+ ALERTS,
+ COLLECTIONS,
+ ROUTES,
+ VARIANTS,
+ CUSTOM_ROUTE_VARIANTS,
+} = require("@mocks-server/admin-api-paths");
+
+const About = require("./About");
+const Settings = require("./Settings");
+const Alerts = require("./Alerts");
+const CustomRoutesVariants = require("./CustomRoutesVariants");
+
+const { readCollectionAndModelRouter } = require("./support/routers");
+const { version } = require("../package.json");
+
+class Api {
+ constructor({ logger, config, mock, alerts, coreVersion }) {
+ this._logger = logger;
+ this._router = express.Router();
+ this._coreVersion = coreVersion;
+
+ this._configApi = new Settings({
+ logger: this._logger.namespace("config"),
+ config,
+ });
+ this._alertsApi = new Alerts({
+ alerts,
+ logger: this._logger.namespace("alerts"),
+ parseAlert: (alert) => {
+ return {
+ id: alert.id,
+ message: alert.message,
+ error: alert.error
+ ? {
+ name: alert.error.name,
+ message: alert.error.message,
+ stack: alert.error.stack,
+ }
+ : null,
+ };
+ },
+ });
+ this._aboutApi = new About({
+ logger: this._logger.namespace("about"),
+ getResponse: () => ({
+ versions: {
+ adminApi: version,
+ core: this._coreVersion,
+ },
+ }),
+ });
+ this._customRoutesVariantsApi = new CustomRoutesVariants({
+ logger: this._logger.namespace("customRouteVariants"),
+ getRouteVariants: () => mock.routes.plainVariants,
+ mock,
+ });
+
+ this._collectionsApi = readCollectionAndModelRouter({
+ collectionName: "collections",
+ modelName: "collection",
+ getItems: () => mock.collections.plain,
+ logger: this._logger.namespace("collections"),
+ });
+
+ const parseRoute = (route) => {
+ return {
+ ...route,
+ method: route.method.toLowerCase(),
+ };
+ };
+
+ this._routesApi = readCollectionAndModelRouter({
+ collectionName: "routes",
+ modelName: "route",
+ getItems: () => mock.routes.plain.map(parseRoute),
+ parseItem: parseRoute,
+ logger: this._logger.namespace("routes"),
+ });
+
+ this._routeVariantsApi = readCollectionAndModelRouter({
+ collectionName: "route variants",
+ modelName: "route variant",
+ getItems: () => mock.routes.plainVariants,
+ logger: this._logger.namespace("routeVariants"),
+ });
+
+ this._router.use(ABOUT, this._aboutApi.router);
+ this._router.use(CONFIG, this._configApi.router);
+ this._router.use(ALERTS, this._alertsApi.router);
+ this._router.use(COLLECTIONS, this._collectionsApi);
+ this._router.use(ROUTES, this._routesApi);
+ this._router.use(VARIANTS, this._routeVariantsApi);
+ this._router.use(CUSTOM_ROUTE_VARIANTS, this._customRoutesVariantsApi.router);
+ }
+
+ get router() {
+ return this._router;
+ }
+}
+
+module.exports = Api;
diff --git a/packages/plugin-admin-api/src/CustomRoutesVariants.js b/packages/plugin-admin-api/src/CustomRoutesVariants.js
index b09889299..a21f80505 100644
--- a/packages/plugin-admin-api/src/CustomRoutesVariants.js
+++ b/packages/plugin-admin-api/src/CustomRoutesVariants.js
@@ -17,12 +17,13 @@ const Boom = require("@hapi/boom");
const { addCollectionMiddleware } = require("./support/middlewares");
class CustomRoutesVariants {
- constructor({ logger, mocks }) {
- this._mocks = mocks;
+ constructor({ logger, mock, getRouteVariants }) {
+ this._mock = mock;
this._logger = logger;
this._router = express.Router();
+ this._getRouteVariants = getRouteVariants;
addCollectionMiddleware(this._router, {
- name: "custom routes variants",
+ name: "custom route variants",
getItems: this._getCollection.bind(this),
logger: this._logger,
});
@@ -32,16 +33,16 @@ class CustomRoutesVariants {
}
_getCollection() {
- return this._mocks.customRoutesVariants;
+ return this._mock.customRouteVariants;
}
add(req, res, next) {
const id = req.body.id;
- const routeVariant = this._mocks.plainRoutesVariants.find(
+ const routeVariant = this._getRouteVariants().find(
(routeVariantCandidate) => routeVariantCandidate.id === id
);
if (routeVariant) {
- this._mocks.useRouteVariant(id);
+ this._mock.useRouteVariant(id);
res.status(204);
res.send();
} else {
@@ -50,7 +51,7 @@ class CustomRoutesVariants {
}
delete(_req, res) {
- this._mocks.restoreRoutesVariants();
+ this._mock.restoreRouteVariants();
res.status(204);
res.send();
}
diff --git a/packages/plugin-admin-api/src/Plugin.js b/packages/plugin-admin-api/src/Plugin.js
index 851a37a71..bb4fd40d5 100644
--- a/packages/plugin-admin-api/src/Plugin.js
+++ b/packages/plugin-admin-api/src/Plugin.js
@@ -9,94 +9,156 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
-const cors = require("cors");
const express = require("express");
const {
- DEFAULT_BASE_PATH,
- SETTINGS,
- MOCKS,
- ABOUT,
- ROUTES,
- ROUTES_VARIANTS,
- MOCK_CUSTOM_ROUTES_VARIANTS,
- ALERTS,
+ BASE_PATH,
+ // Legacy, to be removed
+ LEGACY_DEFAULT_BASE_PATH,
+ LEGACY_SETTINGS,
+ LEGACY_MOCKS,
+ LEGACY_ABOUT,
+ LEGACY_ROUTES,
+ LEGACY_ROUTES_VARIANTS,
+ LEGACY_MOCK_CUSTOM_ROUTES_VARIANTS,
+ LEGACY_ALERTS,
} = require("@mocks-server/admin-api-paths");
const About = require("./About");
const Settings = require("./Settings");
const Alerts = require("./Alerts");
const CustomRoutesVariants = require("./CustomRoutesVariants");
+const Root = require("./Root");
+const AdminServer = require("./server/Server");
+const Swagger = require("./swagger/Swagger");
+const { enableCors, addLegacyApiAlert } = require("./server/middlewares");
+const Api = require("./Api");
const { PLUGIN_NAME } = require("./support/constants");
const { readCollectionAndModelRouter } = require("./support/routers");
+const { version } = require("../package.json");
const OPTION = {
name: "path",
- description: `Root path for admin routes`,
+ description: `Legacy root path for admin routes`,
type: "string",
- default: DEFAULT_BASE_PATH,
+ default: LEGACY_DEFAULT_BASE_PATH,
};
-const corsMiddleware = cors({
- preflightContinue: false,
-});
+const OPTION_ALERT_ID = "path-option";
+const OPTION_ALERT_MESSAGE =
+ "Usage of 'adminApi.path' option is deprecated. Consider using the new REST API: https://www.mocks-server.org/docs/integrations/rest-api";
class Plugin {
static get id() {
return PLUGIN_NAME;
}
- constructor({ config, logger, mocks, addRouter, removeRouter, alerts }) {
- this._addRouterMethod = addRouter;
- this._removeRouterMethod = removeRouter;
+ constructor({ config, logger, mock, server, alerts, version: coreVersion }) {
+ this._server = server;
this._logger = logger;
this._config = config;
+ this._coreVersion = coreVersion;
+ this._alerts = alerts;
+
+ this._adminServer = new AdminServer({
+ alerts,
+ logger: this._logger.namespace("server"),
+ config,
+ onChangeOptions: ({ host, port }) => {
+ this._swagger.setOptions({
+ version,
+ host,
+ port,
+ });
+ },
+ });
this._adminApiPathOption = this._config.addOption(OPTION);
- this._settingsApi = new Settings({
- logger: this._logger.namespace("settings"),
+ // LEGACY APIS
+ this._settingsApiLegacy = new Settings({
+ logger: this._logger.namespace("settingsLegacy"),
config,
});
- this._alertsApi = new Alerts({
+ this._alertsApiLegacy = new Alerts({
alerts,
- logger: this._logger.namespace("alerts"),
+ logger: this._logger.namespace("alertsLegacy"),
+ parseAlert: (alert) => {
+ return {
+ id: alert.context,
+ context: alert.context,
+ message: alert.message,
+ error: alert.error
+ ? {
+ name: alert.error.name,
+ message: alert.error.message,
+ stack: alert.error.stack,
+ }
+ : null,
+ };
+ },
});
- this._aboutApi = new About({
- logger: this._logger.namespace("about"),
+ this._aboutApiLegacy = new About({
+ logger: this._logger.namespace("aboutLegacy"),
+ getResponse: () => ({
+ version,
+ }),
});
- this._customRoutesVariantsApi = new CustomRoutesVariants({
- logger: this._logger.namespace("customRouteVariants"),
- mocks,
+ this._customRoutesVariantsApiLegacy = new CustomRoutesVariants({
+ logger: this._logger.namespace("customRouteVariantsLegacy"),
+ getRouteVariants: () => mock.plainRoutesVariants,
+ mock,
});
- this._mocksApi = readCollectionAndModelRouter({
- collectionName: "mocks",
- modelName: "mock",
- getItems: () => mocks.plainMocks,
- logger: this._logger.namespace("mocks"),
+ this._mocksApiLegacy = readCollectionAndModelRouter({
+ collectionName: "legacy mocks",
+ modelName: "legacy mock",
+ getItems: () => mock.plainMocks,
+ logger: this._logger.namespace("mocksLegacy"),
});
- this._routesApi = readCollectionAndModelRouter({
- collectionName: "routes",
- modelName: "route",
- getItems: () => mocks.plainRoutes,
- logger: this._logger.namespace("routes"),
+ this._routesApiLegacy = readCollectionAndModelRouter({
+ collectionName: "legacy routes",
+ modelName: "legacy route",
+ getItems: () => mock.plainRoutes,
+ logger: this._logger.namespace("routesLegacy"),
});
- this._routesVariantsApi = readCollectionAndModelRouter({
- collectionName: "routes variants",
- modelName: "route variant",
- getItems: () => mocks.plainRoutesVariants,
- logger: this._logger.namespace("routeVariants"),
+ this._routesVariantsApiLegacy = readCollectionAndModelRouter({
+ collectionName: "legacy routes variants",
+ modelName: "legacy route variant",
+ getItems: () => mock.plainRoutesVariants,
+ logger: this._logger.namespace("routeVariantsLegacy"),
});
+ // APIS
+ this._root = new Root({
+ redirectUrl: "/docs",
+ });
+ this._swagger = new Swagger({ config });
+
+ this._apiRouter = new Api({
+ logger: this._logger.namespace("api"),
+ config,
+ mock,
+ alerts,
+ coreVersion,
+ });
+
+ this._adminServer.addRouter({ path: BASE_PATH, router: this._apiRouter.router });
+ this._adminServer.addRouter({ path: "/docs", router: this._swagger.router });
+ this._adminServer.addRouter({ path: "/", router: this._root.router });
+
this._onChangeAdminApiPath = this._onChangeAdminApiPath.bind(this);
}
init() {
this._initRouter();
+ this._adminServer.init();
+ if (this._adminApiPathOption.hasBeenSet) {
+ this._alerts.set(OPTION_ALERT_ID, OPTION_ALERT_MESSAGE);
+ }
}
start() {
@@ -104,40 +166,48 @@ class Plugin {
this._onChangeAdminApiPath
);
this._addRouter();
+ return this._adminServer.start();
}
stop() {
this._stopListeningOnChangeAdminApiPath();
this._removeRouter();
+ return this._adminServer.stop();
}
_initRouter() {
this._router = express.Router();
- this._router.use(corsMiddleware);
- this._router.use(ABOUT, this._aboutApi.router);
- this._router.use(SETTINGS, this._settingsApi.router); // TODO, add config route. deprecate settings
- this._router.use(ALERTS, this._alertsApi.router);
-
- this._router.use(MOCKS, this._mocksApi);
- this._router.use(ROUTES, this._routesApi);
- this._router.use(ROUTES_VARIANTS, this._routesVariantsApi);
- this._router.use(MOCK_CUSTOM_ROUTES_VARIANTS, this._customRoutesVariantsApi.router);
+ this._router.use(enableCors());
+ this._router.use(addLegacyApiAlert(this._alerts));
+ // LEGACY APIs
+ this._router.use(LEGACY_ABOUT, this._aboutApiLegacy.router);
+ this._router.use(LEGACY_SETTINGS, this._settingsApiLegacy.router); // TODO, add config route. deprecate settings
+ this._router.use(LEGACY_ALERTS, this._alertsApiLegacy.router);
+
+ this._router.use(LEGACY_MOCKS, this._mocksApiLegacy);
+ this._router.use(LEGACY_ROUTES, this._routesApiLegacy);
+ this._router.use(LEGACY_ROUTES_VARIANTS, this._routesVariantsApiLegacy);
+ this._router.use(
+ LEGACY_MOCK_CUSTOM_ROUTES_VARIANTS,
+ this._customRoutesVariantsApiLegacy.router
+ );
}
_addRouter() {
this._removeRouter();
this._routersPath = this._adminApiPathOption.value;
- this._addRouterMethod(this._routersPath, this._router);
+ this._server.addRouter(this._routersPath, this._router);
}
_removeRouter() {
if (this._routersPath) {
- this._removeRouterMethod(this._routersPath, this._router);
+ this._server.removeRouter(this._routersPath, this._router);
this._routersPath = null;
}
}
_onChangeAdminApiPath() {
+ this._alerts.set(OPTION_ALERT_ID, OPTION_ALERT_MESSAGE);
this._addRouter();
}
}
diff --git a/packages/plugin-admin-api/src/Root.js b/packages/plugin-admin-api/src/Root.js
new file mode 100644
index 000000000..635ce4117
--- /dev/null
+++ b/packages/plugin-admin-api/src/Root.js
@@ -0,0 +1,32 @@
+/*
+Copyright 2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const path = require("path");
+
+const express = require("express");
+
+class Root {
+ constructor({ redirectUrl }) {
+ this._router = express.Router();
+ this._router.use(express.static(path.resolve(__dirname, "..", "static", "root")));
+ const redirect = (_req, res) => {
+ res.redirect(redirectUrl);
+ };
+ this._router.get("/", redirect);
+ this._router.get("/index.html", redirect);
+ this._router.get("/index.htm", redirect);
+ }
+
+ get router() {
+ return this._router;
+ }
+}
+
+module.exports = Root;
diff --git a/packages/plugin-admin-api/src/common/helpers.js b/packages/plugin-admin-api/src/common/helpers.js
new file mode 100644
index 000000000..d107e3923
--- /dev/null
+++ b/packages/plugin-admin-api/src/common/helpers.js
@@ -0,0 +1,12 @@
+const ALL_HOSTS = "0.0.0.0";
+const LOCALHOST = "localhost";
+
+function serverUrl({ host, port }) {
+ const hostName = host === ALL_HOSTS ? LOCALHOST : host;
+ return `http://${hostName}:${port}`;
+}
+
+module.exports = {
+ serverUrl,
+ ALL_HOSTS,
+};
diff --git a/packages/plugin-admin-api/src/server/Server.js b/packages/plugin-admin-api/src/server/Server.js
new file mode 100644
index 000000000..3fccce27c
--- /dev/null
+++ b/packages/plugin-admin-api/src/server/Server.js
@@ -0,0 +1,169 @@
+/*
+Copyright 2019-2022 Javier Brea
+Copyright 2019 XbyOrange
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const http = require("http");
+
+const express = require("express");
+const {
+ addRequestId,
+ enableCors,
+ jsonBodyParser,
+ notFound,
+ errorHandler,
+ logRequest,
+} = require("./middlewares");
+
+const { ALL_HOSTS, serverUrl } = require("../common/helpers");
+
+const START_ALERT_ID = "start";
+const START_ERROR_MESSAGE = "Error starting server";
+const SERVER_ALERT_ID = "server";
+
+const OPTIONS = [
+ {
+ description: "Port number for the admin API server to be listening at",
+ name: "port",
+ type: "number",
+ default: 3110,
+ },
+ {
+ description: "Host for the admin API server",
+ name: "host",
+ type: "string",
+ default: ALL_HOSTS,
+ },
+];
+
+class Server {
+ constructor({ alerts, logger, config, onChangeOptions }) {
+ this._routers = [];
+ this._config = config;
+ this._alerts = alerts;
+ this._logger = logger;
+ this._error = null;
+ [this._portOption, this._hostOption] = this._config.addOptions(OPTIONS);
+ this._onChangeOptions = onChangeOptions;
+
+ this._optionsChanged = this._optionsChanged.bind(this);
+ this._startServer = this._startServer.bind(this);
+
+ this._portOption.onChange(this._optionsChanged);
+ this._hostOption.onChange(this._optionsChanged);
+ }
+
+ init() {
+ this._emitOptionsChange();
+ }
+
+ _initServer() {
+ this._express = express();
+ this._server = http.createServer(this._express);
+
+ this._express.use(addRequestId());
+ this._express.use(enableCors());
+ this._express.use(jsonBodyParser());
+ this._express.use(logRequest({ logger: this._logger }));
+
+ this._routers.forEach((router) => {
+ this._express.use(router.path, router.router);
+ });
+
+ this._express.use(notFound({ logger: this._logger }));
+ this._express.use(errorHandler({ logger: this._logger }));
+
+ this._alerts.remove(SERVER_ALERT_ID);
+ this._server.on("error", (error) => {
+ this._alerts.set(SERVER_ALERT_ID, "Server error", error);
+ this._error = error;
+ });
+ }
+
+ _startServer(resolve) {
+ const host = this._hostOption.value;
+ const port = this._portOption.value;
+
+ const timedOut = setTimeout(() => {
+ callback(new Error("Server timed out trying to start"));
+ }, 3000);
+
+ const callback = (error) => {
+ clearTimeout(timedOut);
+ if (error) {
+ this._serverStarting = false;
+ this._alerts.set(START_ALERT_ID, START_ERROR_MESSAGE, error);
+ this._error = error;
+ resolve();
+ } else {
+ this._logger.info(`Server started and listening at ${serverUrl({ host, port })}`);
+ this._error = null;
+ this._serverStarting = false;
+ this._alerts.remove(START_ALERT_ID);
+ resolve();
+ }
+ };
+ this._server.listen(
+ {
+ port,
+ host,
+ },
+ callback
+ );
+ }
+
+ async restart() {
+ await this.stop();
+ return this.start();
+ }
+
+ _emitOptionsChange() {
+ this._onChangeOptions({
+ port: this._portOption.value,
+ host: this._hostOption.value,
+ });
+ }
+
+ _optionsChanged() {
+ this._emitOptionsChange();
+ this.restart();
+ }
+
+ async start() {
+ if (this._serverStarting) {
+ this._logger.debug("Server is already starting, returning same promise");
+ return this._serverStarting;
+ }
+ this._initServer();
+ this._serverStarting = new Promise(this._startServer);
+ return this._serverStarting;
+ }
+
+ addRouter(router) {
+ this._routers.push(router);
+ }
+
+ stop() {
+ if (this._serverStopping) {
+ this._logger.debug("Server is already stopping, returning same promise");
+ return this._serverStopping;
+ }
+ this._serverStopping = new Promise((resolve) => {
+ this._logger.verbose("Stopping server");
+ this._server.close(() => {
+ this._logger.info("Server stopped");
+ this._serverStopping = false;
+ resolve();
+ });
+ });
+ return this._serverStopping;
+ }
+}
+
+module.exports = Server;
diff --git a/packages/plugin-admin-api/src/server/middlewares.js b/packages/plugin-admin-api/src/server/middlewares.js
new file mode 100644
index 000000000..991d32c61
--- /dev/null
+++ b/packages/plugin-admin-api/src/server/middlewares.js
@@ -0,0 +1,76 @@
+/*
+Copyright 2019-2022 Javier Brea
+Copyright 2019 XbyOrange
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+"use strict";
+
+const cors = require("cors");
+const bodyParser = require("body-parser");
+const Boom = require("@hapi/boom");
+
+const expressRequestId = require("express-request-id");
+
+const addRequestId = () => expressRequestId();
+
+const jsonBodyParser = () => bodyParser.json();
+
+const logRequest =
+ ({ logger }) =>
+ (req, _res, next) => {
+ logger.debug(`Request received | ${req.method} => ${req.url} | Assigned id: ${req.id}`);
+ next();
+ };
+
+const notFound =
+ ({ logger }) =>
+ (req, _res, next) => {
+ logger.debug(`Sending Not found response | ${req.id}`);
+ next(Boom.notFound());
+ };
+
+const errorHandler =
+ ({ logger }) =>
+ // eslint-disable-next-line no-unused-vars
+ (err, req, res, _next) => {
+ const isBoom = Boom.isBoom(err);
+ const stack = isBoom ? null : err && err.stack;
+ const error = isBoom ? err : err && Boom.badImplementation(err);
+ logger.error(`Sending Error '${error.message}' | ${req.id}`);
+ if (stack) {
+ logger.silly(stack.toString());
+ }
+ res.status(error.output.statusCode);
+ res.send(error.output.payload);
+ };
+
+const enableCors = () =>
+ cors({
+ preflightContinue: false,
+ });
+
+const addLegacyApiAlert = (alerts) => {
+ return (_req, _res, next) => {
+ alerts.set(
+ "legacy-api",
+ "Usage of legacy REST API detected. Consider using the new REST API: https://www.mocks-server.org/docs/integrations/rest-api"
+ );
+ next();
+ };
+};
+
+module.exports = {
+ addRequestId,
+ jsonBodyParser,
+ logRequest,
+ notFound,
+ errorHandler,
+ enableCors,
+ addLegacyApiAlert,
+};
diff --git a/packages/plugin-admin-api/src/swagger/Swagger.js b/packages/plugin-admin-api/src/swagger/Swagger.js
new file mode 100644
index 000000000..7872bd52a
--- /dev/null
+++ b/packages/plugin-admin-api/src/swagger/Swagger.js
@@ -0,0 +1,36 @@
+const path = require("path");
+const express = require("express");
+
+const swaggerUIDist = require("swagger-ui-dist");
+
+const { serverUrl } = require("../common/helpers");
+const openApi = require("./openapi");
+
+class Swagger {
+ constructor({ config }) {
+ this._openApiMiddleware = this._openApiMiddleware.bind(this);
+ this._openApi = openApi;
+ this._config = config;
+
+ this._router = express.Router();
+ this._router.get("/openapi.json", this._openApiMiddleware);
+ this._router.use(express.static(path.resolve(__dirname, "..", "..", "static", "swagger")));
+ this._router.use(express.static(swaggerUIDist.absolutePath()));
+ }
+
+ setOptions({ version, port, host }) {
+ this._openApi.info.version = version;
+ this._openApi.servers[0].url = `${serverUrl({ host, port })}/api`;
+ this._openApi.components.schemas.Config = this._config.root.getValidationSchema();
+ }
+
+ _openApiMiddleware(_req, res) {
+ res.status(200).send(this._openApi);
+ }
+
+ get router() {
+ return this._router;
+ }
+}
+
+module.exports = Swagger;
diff --git a/packages/plugin-admin-api/src/swagger/openapi.js b/packages/plugin-admin-api/src/swagger/openapi.js
new file mode 100644
index 000000000..bbf34af85
--- /dev/null
+++ b/packages/plugin-admin-api/src/swagger/openapi.js
@@ -0,0 +1,851 @@
+const {
+ ABOUT,
+ CONFIG,
+ ALERTS,
+ COLLECTIONS,
+ ROUTES,
+ VARIANTS,
+ CUSTOM_ROUTE_VARIANTS,
+} = require("@mocks-server/admin-api-paths");
+
+module.exports = {
+ openapi: "3.0.1",
+ info: {
+ title: "Mocks Server admin API",
+ description:
+ "This API is provided by the Mocks Server's plugin [@mocks-server/plugin-admin-api](https://www.npmjs.com/package/@mocks-server/plugin-admin-api). It allows to administrate the mock server while it is running, allowing to change its configuration, etc.",
+ contact: {
+ email: "info@mocks-server.org",
+ },
+ license: {
+ name: "Apache 2.0",
+ url: "https://www.apache.org/licenses/LICENSE-2.0.html",
+ },
+ version: "3.1.0",
+ },
+ externalDocs: {
+ description: "Find out more about Mocks Server administration API",
+ url: "https://www.mocks-server.org/docs/integrations/rest-api",
+ },
+ servers: [
+ {
+ url: "",
+ },
+ ],
+ tags: [
+ {
+ name: "about",
+ description: "Server and plugins info",
+ },
+ {
+ name: "config",
+ description: "Access to Mocks Server configuration",
+ externalDocs: {
+ description: "Find out more",
+ url: "https://www.mocks-server.org/docs/configuration/options",
+ },
+ },
+ {
+ name: "alerts",
+ description: "Access to Mocks Server alerts",
+ externalDocs: {
+ description: "Find out more",
+ url: "https://www.mocks-server.org/docs/api/javascript/alerts",
+ },
+ },
+ {
+ name: "mock",
+ description: "Operations about the API mock",
+ externalDocs: {
+ description: "Find out more",
+ url: "https://www.mocks-server.org/docs/usage/basics",
+ },
+ },
+ ],
+ paths: {
+ [ABOUT]: {
+ get: {
+ tags: ["about"],
+ summary: "Returns info about server and plugins",
+ description: "Use it to get current versions of Mocks Server packages",
+ responses: {
+ "200": {
+ description: "successful operation",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/About",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ [CONFIG]: {
+ get: {
+ tags: ["config"],
+ summary: "Returns current configuration",
+ description: "Current configuration object from all config namespaces",
+ responses: {
+ "200": {
+ description: "successful operation",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Config",
+ },
+ },
+ },
+ },
+ },
+ },
+ patch: {
+ tags: ["config"],
+ summary: "Updates configuration",
+ description: "Accepts an object with configuration properties to be changed",
+ requestBody: {
+ description: "Partially updated configuration object",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Config",
+ },
+ examples: {
+ "mock.collections.selected": {
+ summary: "Change current collection",
+ value: {
+ mock: {
+ collections: {
+ selected: "foo",
+ },
+ },
+ },
+ },
+ log: {
+ summary: "Change log level",
+ value: {
+ log: "silly",
+ },
+ },
+ "server.port": {
+ summary: "Change server port",
+ value: {
+ server: {
+ port: 3200,
+ },
+ },
+ },
+ },
+ },
+ },
+ required: true,
+ },
+ responses: {
+ "204": {
+ description:
+ "configuration updated. Note that some configuration properties may take time to have real effect",
+ },
+ "400": {
+ description: "Invalid config supplied",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Error",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ [ALERTS]: {
+ get: {
+ tags: ["alerts"],
+ summary: "Returns current alerts",
+ description: "Mocks Server alerts from all namespaces",
+ responses: {
+ "200": {
+ description: "successful operation",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Alerts",
+ },
+ examples: {
+ "mock:collections:selected": {
+ summary: "Option mocks.collections.selected was not defined",
+ value: [
+ {
+ id: "mock:collections:selected",
+ message:
+ "Option 'mock.collections.selected' was not defined. Selecting the first collection found",
+ error: null,
+ },
+ ],
+ },
+ "files:collections:error": {
+ summary: "Error loading collections",
+ value: [
+ {
+ id: "files:collections:error",
+ message:
+ "Error loading collections from file /Users/foo/project/mocks/collections.js",
+ error: {
+ name: "ReferenceError",
+ message: "foo is not defined",
+ stack:
+ "ReferenceError: foo is not defined\n at Object. (/Users/foo/project/mocks/collections.js:10:4)",
+ },
+ },
+ ],
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ [`${ALERTS}/{alertId}`]: {
+ get: {
+ tags: ["alerts"],
+ summary: "Find alert by ID",
+ description: "Returns a single alert",
+ parameters: [
+ {
+ name: "alertId",
+ in: "path",
+ description: "ID of alert to return",
+ required: true,
+ schema: {
+ type: "string",
+ },
+ },
+ ],
+ responses: {
+ "200": {
+ description: "successful operation",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Alert",
+ },
+ examples: {
+ "mock:collections:selected": {
+ summary: "Option mocks.collections.selected was not defined",
+ value: {
+ id: "mock:collections:selected",
+ message:
+ "Option 'mock.collections.selected' was not defined. Selecting the first collection found",
+ error: null,
+ },
+ },
+ "files:collections:error": {
+ summary: "Error loading collections",
+ value: {
+ id: "files:collections:error",
+ message:
+ "Error loading collections from file /Users/foo/project/mocks/collections.js",
+ error: {
+ name: "ReferenceError",
+ message: "foo is not defined",
+ stack:
+ "ReferenceError: foo is not defined\n at Object. (/Users/foo/project/mocks/collections.js:10:4)",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ "404": {
+ description: "Alert not found",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Error",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ [ROUTES]: {
+ get: {
+ tags: ["mock"],
+ summary: "Returns routes",
+ description:
+ "Returns available routes. Find out more about [routes](https://www.mocks-server.org/docs/usage/routes)",
+ responses: {
+ "200": {
+ description: "successful operation",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Routes",
+ },
+ examples: {
+ "one-routes": {
+ summary: "One route",
+ value: [
+ {
+ id: "get-user",
+ url: "/api/user",
+ method: "get",
+ delay: null,
+ variants: ["get-user:1", "get-user:2"],
+ },
+ ],
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ [`${ROUTES}/{routeId}`]: {
+ get: {
+ tags: ["mock"],
+ summary: "Find collection by ID",
+ description: "Returns a single [route](https://www.mocks-server.org/docs/usage/routes)",
+ parameters: [
+ {
+ name: "routeId",
+ in: "path",
+ description: "ID of route to return",
+ required: true,
+ schema: {
+ type: "string",
+ },
+ },
+ ],
+ responses: {
+ "200": {
+ description: "successful operation",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Route",
+ },
+ examples: {
+ "one-route": {
+ summary: "One route",
+ value: {
+ id: "get-user",
+ url: "/api/user",
+ method: "get",
+ delay: null,
+ variants: ["get-user:1", "get-user:2"],
+ },
+ },
+ },
+ },
+ },
+ },
+ "404": {
+ description: "Route not found",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Error",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ [VARIANTS]: {
+ get: {
+ tags: ["mock"],
+ summary: "Returns route variants",
+ description:
+ "Returns available route variants. Find out more about [variants](https://www.mocks-server.org/docs/usage/variants)",
+ responses: {
+ "200": {
+ description: "successful operation",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Variants",
+ },
+ examples: {
+ "two-variants": {
+ summary: "Two variants",
+ value: [
+ {
+ id: "get-user:1",
+ route: "get-user",
+ type: "json",
+ preview: {
+ body: {
+ email: "foo@foo.com",
+ },
+ status: 200,
+ },
+ delay: null,
+ },
+ {
+ id: "get-user:2",
+ route: "get-user",
+ type: "json",
+ preview: {
+ body: {
+ email: "foo@foo.com",
+ },
+ status: 200,
+ },
+ delay: null,
+ },
+ ],
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ [`${VARIANTS}/{variantId}`]: {
+ get: {
+ tags: ["mock"],
+ summary: "Find route variant by ID",
+ description:
+ "Returns a single [route variant](https://www.mocks-server.org/docs/usage/variants)",
+ parameters: [
+ {
+ name: "variantId",
+ in: "path",
+ description: "ID of the variant to return",
+ required: true,
+ schema: {
+ type: "string",
+ },
+ },
+ ],
+ responses: {
+ "200": {
+ description: "successful operation",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Variant",
+ },
+ examples: {
+ "one-variant": {
+ summary: "Variant",
+ value: {
+ id: "get-user:2",
+ route: "get-user",
+ type: "json",
+ preview: {
+ body: {
+ email: "foo@foo.com",
+ },
+ status: 200,
+ },
+ delay: null,
+ },
+ },
+ },
+ },
+ },
+ },
+ "404": {
+ description: "Variant not found",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Error",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ [COLLECTIONS]: {
+ get: {
+ tags: ["mock"],
+ summary: "Returns collections",
+ description:
+ "Returns available collections. Find out more about [collections](https://www.mocks-server.org/docs/usage/collections)",
+ responses: {
+ "200": {
+ description: "successful operation",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Collections",
+ },
+ examples: {
+ "two-collections": {
+ summary: "Two collections",
+ value: [
+ {
+ id: "base",
+ from: null,
+ definedRoutes: ["get-users", "get-user:1"],
+ routes: ["get-user:1"],
+ },
+ {
+ id: "user-2",
+ from: "base",
+ definedRoutes: ["get-user:2"],
+ routes: ["get-users", "get-user:2"],
+ },
+ ],
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ [`${COLLECTIONS}/{collectionId}`]: {
+ get: {
+ tags: ["mock"],
+ summary: "Find collection by ID",
+ description:
+ "Returns a single [collection](https://www.mocks-server.org/docs/usage/collections)",
+ parameters: [
+ {
+ name: "collectionId",
+ in: "path",
+ description: "ID of collection to return",
+ required: true,
+ schema: {
+ type: "string",
+ },
+ },
+ ],
+ responses: {
+ "200": {
+ description: "successful operation",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Collection",
+ },
+ examples: {
+ collection: {
+ summary: "Collection",
+ value: {
+ id: "base",
+ from: null,
+ definedRoutes: ["get-users", "get-user:1"],
+ routes: ["get-user:1"],
+ },
+ },
+ },
+ },
+ },
+ },
+ "404": {
+ description: "Collection not found",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Error",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ [CUSTOM_ROUTE_VARIANTS]: {
+ get: {
+ tags: ["mock"],
+ summary: "Returns current custom route variants",
+ description:
+ "Returns route variant ids that are currently used instead of those defined in the current collection. [Find out more](https://www.mocks-server.org/docs/usage/collections#defining-custom-route-variants)",
+ responses: {
+ "200": {
+ description: "successful operation",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/CustomRouteVariants",
+ },
+ examples: {
+ "two-custom-route-variants": {
+ summary: "One custom route variant",
+ value: ["get-user:2"],
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ post: {
+ tags: ["mock"],
+ summary: "Adds a custom route variant",
+ description:
+ "Defines a route variant to be used instead of the one defined in the current collection. [Find out more](https://www.mocks-server.org/docs/usage/collections#defining-custom-route-variants)",
+ requestBody: {
+ content: {
+ "application/json": {
+ schema: {
+ properties: {
+ id: {
+ $ref: "#/components/schemas/RouteVariantId",
+ },
+ },
+ },
+ examples: {
+ "add-custom-route-variant": {
+ summary: "Add custom route variant",
+ value: {
+ id: "get-user:2",
+ },
+ },
+ },
+ },
+ },
+ },
+ responses: {
+ "204": {
+ description: "successful operation",
+ },
+ "400": {
+ description: "Invalid route variant id supplied",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: "#/components/schemas/Error",
+ },
+ },
+ },
+ },
+ },
+ },
+ delete: {
+ tags: ["mock"],
+ summary: "Removes all custom route variants",
+ description:
+ "Restores current collection route variants. [Find out more](https://www.mocks-server.org/docs/usage/collections#defining-custom-route-variants)",
+ responses: {
+ "204": {
+ description: "successful operation",
+ },
+ },
+ },
+ },
+ },
+ components: {
+ schemas: {
+ About: {
+ type: "object",
+ properties: {
+ version: {
+ type: "object",
+ properties: {
+ core: {
+ type: "string",
+ description: "@mocks-server/core version",
+ },
+ adminApi: {
+ type: "string",
+ description: "@mocks-server/plugin-admin-api version",
+ },
+ },
+ },
+ },
+ },
+ Config: {},
+ Alert: {
+ type: "object",
+ properties: {
+ id: {
+ type: "string",
+ description: "Alert id. Includes all of the parents namespaces ids joined with ':'",
+ },
+ message: {
+ type: "string",
+ description: "Alert message",
+ },
+ error: {
+ type: "object",
+ description: "If the alert was produced by an error, it is described here",
+ properties: {
+ name: {
+ type: "string",
+ description: "Error name",
+ },
+ message: {
+ type: "string",
+ description: "Error description",
+ },
+ stack: {
+ type: "string",
+ description: "Error stack",
+ },
+ },
+ nullable: true,
+ },
+ },
+ },
+ Alerts: {
+ type: "array",
+ items: {
+ $ref: "#/components/schemas/Alert",
+ },
+ },
+ Route: {
+ type: "object",
+ properties: {
+ id: {
+ type: "string",
+ description: "Route id",
+ },
+ url: {
+ type: "string",
+ description: "Route url",
+ },
+ method: {
+ description: "Route HTTP method or methods",
+ oneOf: [
+ {
+ type: "array",
+ items: {
+ $ref: "#/components/schemas/RouteMethod",
+ },
+ },
+ {
+ $ref: "#/components/schemas/RouteMethod",
+ },
+ ],
+ },
+ delay: {
+ type: "string",
+ description: "Route delay. When defined, it overrides the global routes delay setting",
+ nullable: true,
+ },
+ variants: {
+ type: "array",
+ description: "Route variants IDs belonging to this route",
+ items: {
+ $ref: "#/components/schemas/RouteVariantId",
+ },
+ },
+ },
+ },
+ Routes: {
+ type: "array",
+ items: {
+ $ref: "#/components/schemas/Route",
+ },
+ },
+ Variant: {
+ type: "object",
+ properties: {
+ id: {
+ $ref: "#/components/schemas/RouteVariantId",
+ },
+ route: {
+ type: "string",
+ description: "Route ID",
+ },
+ type: {
+ type: "string",
+ description: "Variant handler ID",
+ },
+ preview: {
+ type: "object",
+ description:
+ "Approached preview of the response that will be sent when the route variant is used. Null when it is not possible to have an idea of the response",
+ nullable: true,
+ },
+ delay: {
+ type: "number",
+ description:
+ "Route delay. When defined, it overrides the route delay and the global routes delay setting. If it is null, the route delay is ignored and the global delay setting is used",
+ nullable: true,
+ },
+ },
+ },
+ Variants: {
+ type: "array",
+ items: {
+ $ref: "#/components/schemas/Variant",
+ },
+ },
+ Collection: {
+ type: "object",
+ properties: {
+ id: {
+ type: "string",
+ description: "Collection id",
+ },
+ from: {
+ type: "string",
+ description: "Id of other collection from which this one extends",
+ nullable: true,
+ },
+ routes: {
+ type: "array",
+ description:
+ "Ids of the route variants applied to this collection. It takes into account routes from the base collections",
+ items: {
+ $ref: "#/components/schemas/RouteVariantId",
+ },
+ },
+ definedRoutes: {
+ type: "array",
+ description: "Ids of the route variants explicitly defined for the collection",
+ items: {
+ $ref: "#/components/schemas/RouteVariantId",
+ },
+ },
+ },
+ },
+ Collections: {
+ type: "array",
+ items: {
+ $ref: "#/components/schemas/Collection",
+ },
+ },
+ RouteVariantId: {
+ type: "string",
+ description: "Route and variant id joined with ':'",
+ },
+ RouteMethod: {
+ type: "string",
+ enum: ["get", "post", "patch", "delete", "put", "options", "head", "trace"],
+ description: "HTTP method",
+ },
+ CustomRouteVariants: {
+ type: "array",
+ description:
+ "Ids of the route variants that are currently used instead of those defined in the current collection",
+ items: {
+ $ref: "#/components/schemas/RouteVariantId",
+ },
+ },
+ Error: {
+ type: "object",
+ properties: {
+ statusCode: {
+ type: "integer",
+ description: "Response status code",
+ format: "int16",
+ },
+ error: {
+ type: "string",
+ description: "Error description",
+ },
+ message: {
+ type: "string",
+ description: "Error message",
+ },
+ },
+ },
+ },
+ },
+};
diff --git a/packages/plugin-admin-api/static/root/favicon.ico b/packages/plugin-admin-api/static/root/favicon.ico
new file mode 100644
index 000000000..db1a1e153
Binary files /dev/null and b/packages/plugin-admin-api/static/root/favicon.ico differ
diff --git a/packages/plugin-admin-api/static/swagger/index.html b/packages/plugin-admin-api/static/swagger/index.html
new file mode 100644
index 000000000..f01c703fe
--- /dev/null
+++ b/packages/plugin-admin-api/static/swagger/index.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ Mocks Server REST API SwaggerUI
+
+
+
+
+
+
+
+
+
diff --git a/packages/plugin-admin-api/test/about-api.spec.js b/packages/plugin-admin-api/test/about-api.spec.js
index 2ce4c6a8b..0ba0661a0 100644
--- a/packages/plugin-admin-api/test/about-api.spec.js
+++ b/packages/plugin-admin-api/test/about-api.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2019 Javier Brea
+Copyright 2019-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -8,8 +8,9 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
-const { startServer, doFetch, waitForServer } = require("./support/helpers");
+const { startServer, doApiFetch, waitForServer } = require("./support/helpers");
const { version } = require("../package.json");
+const { version: coreVersion } = require("../../core/package.json");
describe("about api", () => {
let server;
@@ -24,9 +25,12 @@ describe("about api", () => {
describe("get /", () => {
it("should return current version", async () => {
- const response = await doFetch("/admin/about");
+ const response = await doApiFetch("/about");
expect(response.body).toEqual({
- version,
+ versions: {
+ adminApi: version,
+ core: coreVersion,
+ },
});
});
});
diff --git a/packages/plugin-admin-api/test/alerts-api.spec.js b/packages/plugin-admin-api/test/alerts-api.spec.js
index c49b81364..228fb7992 100644
--- a/packages/plugin-admin-api/test/alerts-api.spec.js
+++ b/packages/plugin-admin-api/test/alerts-api.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2020 Javier Brea
+Copyright 2020-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -8,15 +8,25 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
-const { startServer, doFetch, waitForServer, wait, fixturesFolder } = require("./support/helpers");
+const {
+ startServer,
+ doFetch,
+ doApiFetch,
+ waitForServer,
+ wait,
+ fixturesFolder,
+} = require("./support/helpers");
describe("alerts api", () => {
let server;
beforeAll(async () => {
server = await startServer("web-tutorial", {
- mocks: {
- selected: "foo",
+ mock: {
+ collections: {
+ selected: "foo",
+ },
},
+ log: "silly",
});
await waitForServer();
});
@@ -26,18 +36,17 @@ describe("alerts api", () => {
});
describe("when started", () => {
- it("should return mock not found alert", async () => {
- const response = await doFetch("/admin/alerts");
+ it("should return collection not found alert", async () => {
+ const response = await doApiFetch("/alerts");
// one alert is caused by deprecated handler
expect(response.body.length).toEqual(2);
});
it("should return specific alert when requested by id", async () => {
- const response = await doFetch("/admin/alerts/mocks%3Asettings");
+ const response = await doApiFetch("/alerts/mock%3Acollections%3Aselected");
expect(response.body).toEqual({
- id: "mocks:settings",
- context: "mocks:settings",
- message: "Mock 'foo' was not found. Using the first one found",
+ id: "mock:collections:selected",
+ message: "Collection 'foo' was not found. Selecting the first one found",
error: null,
});
});
@@ -51,13 +60,15 @@ describe("alerts api", () => {
});
});
- describe("when mock is modified", () => {
+ describe("when collection is modified", () => {
beforeAll(async () => {
- await doFetch("/admin/settings", {
+ await doApiFetch("/config", {
method: "PATCH",
body: {
- mocks: {
- selected: "base",
+ mock: {
+ collections: {
+ selected: "base",
+ },
},
},
});
@@ -65,7 +76,7 @@ describe("alerts api", () => {
}, 10000);
it("should return no alerts", async () => {
- const response = await doFetch("/admin/alerts");
+ const response = await doApiFetch("/alerts");
// one alert is caused by deprecated handler
expect(response.body.length).toEqual(1);
});
@@ -73,7 +84,7 @@ describe("alerts api", () => {
describe("when there is an error loading files", () => {
beforeAll(async () => {
- await doFetch("/admin/settings", {
+ await doApiFetch("/config", {
method: "PATCH",
body: {
files: {
@@ -85,9 +96,9 @@ describe("alerts api", () => {
}, 10000);
it("should return alert containing error", async () => {
- const response = await doFetch("/admin/alerts");
- expect(response.body.length).toEqual(4);
- expect(response.body[3].error.message).toEqual(
+ const response = await doApiFetch("/alerts");
+ expect(response.body.length).toEqual(5);
+ expect(response.body[4].error.message).toEqual(
expect.stringContaining("Cannot find module '../db/users'")
);
});
diff --git a/packages/plugin-admin-api/test/collections-api.spec.js b/packages/plugin-admin-api/test/collections-api.spec.js
new file mode 100644
index 000000000..ca93932a6
--- /dev/null
+++ b/packages/plugin-admin-api/test/collections-api.spec.js
@@ -0,0 +1,82 @@
+/*
+Copyright 2019-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const { startServer, doApiFetch, waitForServer } = require("./support/helpers");
+
+describe("mocks api", () => {
+ let server;
+
+ beforeAll(async () => {
+ server = await startServer("web-tutorial");
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ await server.stop();
+ });
+
+ describe("get /", () => {
+ it("should return current mocks", async () => {
+ const response = await doApiFetch("/mock/collections");
+ expect(response.body).toEqual([
+ {
+ id: "base",
+ from: null,
+ definedRoutes: ["get-users:success", "get-user:1"],
+ routes: ["get-users:success", "get-user:1"],
+ },
+ {
+ id: "user-2",
+ from: "base",
+ definedRoutes: ["get-user:2"],
+ routes: ["get-users:success", "get-user:2"],
+ },
+ {
+ id: "user-real",
+ from: "base",
+ definedRoutes: ["get-user:real"],
+ routes: ["get-users:success", "get-user:real"],
+ },
+ ]);
+ });
+ });
+
+ describe("get /base", () => {
+ it("should return base mock", async () => {
+ const response = await doApiFetch("/mock/collections/base");
+ expect(response.body).toEqual({
+ id: "base",
+ from: null,
+ definedRoutes: ["get-users:success", "get-user:1"],
+ routes: ["get-users:success", "get-user:1"],
+ });
+ });
+ });
+
+ describe("get /user-2", () => {
+ it("should return user-2 mock", async () => {
+ const response = await doApiFetch("/mock/collections/user-2");
+ expect(response.body).toEqual({
+ id: "user-2",
+ from: "base",
+ definedRoutes: ["get-user:2"],
+ routes: ["get-users:success", "get-user:2"],
+ });
+ });
+ });
+
+ describe("get unexistant mock", () => {
+ it("should return a not found error", async () => {
+ const response = await doApiFetch("/mock/collections/foo");
+ expect(response.status).toEqual(404);
+ expect(response.body.message).toEqual('Collection with id "foo" was not found');
+ });
+ });
+});
diff --git a/packages/plugin-admin-api/test/settings-api.spec.js b/packages/plugin-admin-api/test/config-api.spec.js
similarity index 75%
rename from packages/plugin-admin-api/test/settings-api.spec.js
rename to packages/plugin-admin-api/test/config-api.spec.js
index 33fa6be39..f39765909 100644
--- a/packages/plugin-admin-api/test/settings-api.spec.js
+++ b/packages/plugin-admin-api/test/config-api.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2019 Javier Brea
+Copyright 2019-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -11,10 +11,13 @@ Unless required by applicable law or agreed to in writing, software distributed
const {
startServer,
doFetch,
+ doApiFetch,
+ doLegacyFetch,
fixturesFolder,
TimeCounter,
wait,
waitForServer,
+ waitForServerUrl,
} = require("./support/helpers");
describe("settings api", () => {
@@ -29,8 +32,8 @@ describe("settings api", () => {
});
describe("get", () => {
- it("should return current settings", async () => {
- const settingsResponse = await doFetch("/admin/settings");
+ it("should return current config", async () => {
+ const settingsResponse = await doApiFetch("/config");
expect(settingsResponse.body).toEqual({
config: {
allowUnknownArguments: true,
@@ -41,7 +44,16 @@ describe("settings api", () => {
mocks: {
delay: 0,
},
+ mock: {
+ collections: {
+ selected: "base",
+ },
+ routes: {
+ delay: 0,
+ },
+ },
files: {
+ enabled: true,
babelRegister: {
enabled: false,
options: {},
@@ -53,6 +65,8 @@ describe("settings api", () => {
register: [null],
adminApi: {
path: "/admin",
+ host: "0.0.0.0",
+ port: 3110,
},
},
log: "silent",
@@ -77,6 +91,9 @@ describe("settings api", () => {
},
},
},
+ variantHandlers: {
+ register: [],
+ },
});
});
});
@@ -85,7 +102,7 @@ describe("settings api", () => {
describe("when changing an unexistant option", () => {
it("should response with a bad request containing errors", async () => {
expect.assertions(4);
- const settingsResponse = await doFetch("/admin/settings", {
+ const settingsResponse = await doApiFetch("/config", {
method: "PATCH",
body: {
foo: "foo-value",
@@ -103,17 +120,17 @@ describe("settings api", () => {
it("should not apply any change if request contains any error", async () => {
expect.assertions(3);
- const settingsUpdateResponse = await doFetch("/admin/settings", {
+ const settingsUpdateResponse = await doApiFetch("/config", {
method: "PATCH",
body: {
foo: "foo-value",
delay: 1000,
},
});
- const settingsResponse = await doFetch("/admin/settings");
+ const settingsResponse = await doApiFetch("/config");
expect(settingsUpdateResponse.status).toEqual(400);
expect(settingsUpdateResponse.body.message).toEqual(expect.stringContaining("foo"));
- expect(settingsResponse.body.mocks.delay).toEqual(0);
+ expect(settingsResponse.body.mock.routes.delay).toEqual(0);
});
});
@@ -127,7 +144,7 @@ describe("settings api", () => {
it("should set delay option and have effect on server response time", async () => {
const timeCounter = new TimeCounter();
- await doFetch("/admin/settings", {
+ await doApiFetch("/config", {
method: "PATCH",
body: {
mocks: {
@@ -140,9 +157,9 @@ describe("settings api", () => {
expect(timeCounter.total).toBeGreaterThan(2000);
});
- it("should set delay option to 0", async () => {
+ it("should set delay option to 0 when using legacy option", async () => {
const timeCounter = new TimeCounter();
- await doFetch("/admin/settings", {
+ await doApiFetch("/config", {
method: "PATCH",
body: {
mocks: {
@@ -154,6 +171,40 @@ describe("settings api", () => {
timeCounter.stop();
expect(timeCounter.total).toBeLessThan(200);
});
+
+ it("should set delay option to 1000", async () => {
+ await doApiFetch("/config", {
+ method: "PATCH",
+ body: {
+ mock: {
+ routes: {
+ delay: 1000,
+ },
+ },
+ },
+ });
+ const timeCounter = new TimeCounter();
+ await doFetch("/api/users");
+ timeCounter.stop();
+ expect(timeCounter.total).toBeGreaterThan(900);
+ });
+
+ it("should set delay option to 0", async () => {
+ await doApiFetch("/config", {
+ method: "PATCH",
+ body: {
+ mock: {
+ routes: {
+ delay: 0,
+ },
+ },
+ },
+ });
+ const timeCounter = new TimeCounter();
+ await doFetch("/api/users");
+ timeCounter.stop();
+ expect(timeCounter.total).toBeLessThan(200);
+ });
});
describe("when changing mock option", () => {
@@ -171,7 +222,7 @@ describe("settings api", () => {
describe('changing it to "user-2"', () => {
beforeAll(async () => {
- await doFetch("/admin/settings", {
+ await doApiFetch("/config", {
method: "PATCH",
body: {
mocks: {
@@ -182,7 +233,7 @@ describe("settings api", () => {
});
it("should return new mock when getting settings", async () => {
- const settingsResponse = await doFetch("/admin/settings");
+ const settingsResponse = await doApiFetch("/config");
expect(settingsResponse.body.mocks.selected).toEqual("user-2");
});
@@ -200,7 +251,7 @@ describe("settings api", () => {
describe("when changing path option", () => {
beforeAll(async () => {
- await doFetch("/admin/settings", {
+ await doApiFetch("/config", {
method: "PATCH",
body: {
files: {
@@ -212,7 +263,7 @@ describe("settings api", () => {
});
afterAll(async () => {
- await doFetch("/admin/settings", {
+ await doApiFetch("/config", {
method: "PATCH",
body: {
files: {
@@ -224,7 +275,7 @@ describe("settings api", () => {
});
it("should return new path option when getting settings", async () => {
- const settingsResponse = await doFetch("/admin/settings");
+ const settingsResponse = await doApiFetch("/config");
expect(settingsResponse.body.files.path).toEqual(fixturesFolder("web-tutorial-modified"));
});
@@ -239,20 +290,19 @@ describe("settings api", () => {
describe("when changing port option", () => {
beforeAll(async () => {
- await doFetch("/admin/settings", {
+ await doApiFetch("/config", {
method: "PATCH",
body: {
server: {
- port: 3101,
+ port: 3200,
},
},
});
- await wait(1000);
+ await waitForServer(3200);
});
afterAll(async () => {
- await doFetch("/admin/settings", {
- port: 3101,
+ await doApiFetch("/config", {
method: "PATCH",
body: {
server: {
@@ -260,19 +310,12 @@ describe("settings api", () => {
},
},
});
- await wait(1000);
- });
-
- it("should return new port option when getting settings, using new port", async () => {
- const settingsResponse = await doFetch("/admin/settings", {
- port: 3101,
- });
- expect(settingsResponse.body.server.port).toEqual(3101);
+ await waitForServer();
});
it("should serve user 2 under the /api/users/1 path using new port", async () => {
const users = await doFetch("/api/users/1", {
- port: 3101,
+ port: 3200,
});
expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
});
@@ -280,7 +323,7 @@ describe("settings api", () => {
describe("when changing adminApiPath option", () => {
beforeAll(async () => {
- await doFetch("/admin/settings", {
+ await doApiFetch("/config", {
method: "PATCH",
body: {
plugins: {
@@ -290,11 +333,11 @@ describe("settings api", () => {
},
},
});
- await wait(1000);
+ await waitForServerUrl("/administration/about");
});
afterAll(async () => {
- await doFetch("/administration/settings", {
+ await doApiFetch("/config", {
method: "PATCH",
body: {
plugins: {
@@ -304,18 +347,13 @@ describe("settings api", () => {
},
},
});
- await wait(1000);
+ await waitForServerUrl("/admin/about");
});
- it("should return new port adminApiPath when getting settings, using new admin api path", async () => {
- const settingsResponse = await doFetch("/administration/settings");
+ it("should return new port adminApiPath when getting legacy settings, using new admin api path", async () => {
+ const settingsResponse = await doLegacyFetch("/administration/settings");
expect(settingsResponse.body.plugins.adminApi.path).toEqual("/administration");
});
-
- it("should return not found adminApiPath when getting settings in old admin api path", async () => {
- const settingsResponse = await doFetch("/admin/settings");
- expect(settingsResponse.status).toEqual(404);
- });
});
});
});
diff --git a/packages/plugin-admin-api/test/cors.spec.js b/packages/plugin-admin-api/test/cors.spec.js
index 2deb1e7e3..6d3047409 100644
--- a/packages/plugin-admin-api/test/cors.spec.js
+++ b/packages/plugin-admin-api/test/cors.spec.js
@@ -8,7 +8,7 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
-const { startServer, doFetch, waitForServer } = require("./support/helpers");
+const { startServer, doFetch, doApiFetch, waitForServer } = require("./support/helpers");
describe("cors middleware", () => {
let server;
@@ -24,7 +24,7 @@ describe("cors middleware", () => {
});
it("should add cors headers to admin api routes", async () => {
- const response = await doFetch("/admin/about", { method: "OPTIONS" });
+ const response = await doApiFetch("/about", { method: "OPTIONS" });
expect(response.headers.get("access-control-allow-origin")).toEqual("*");
expect(response.headers.get("access-control-allow-methods")).toEqual(
"GET,HEAD,PUT,PATCH,POST,DELETE"
@@ -53,7 +53,7 @@ describe("cors middleware", () => {
});
it("should add cors headers to admin api routes", async () => {
- const response = await doFetch("/admin/about", { method: "OPTIONS" });
+ const response = await doApiFetch("/about", { method: "OPTIONS" });
expect(response.headers.get("access-control-allow-origin")).toEqual("*");
expect(response.headers.get("access-control-allow-methods")).toEqual(
"GET,HEAD,PUT,PATCH,POST,DELETE"
diff --git a/packages/plugin-admin-api/test/fixtures/files-error-routes/mocks.js b/packages/plugin-admin-api/test/fixtures/files-error-routes/collections.js
similarity index 84%
rename from packages/plugin-admin-api/test/fixtures/files-error-routes/mocks.js
rename to packages/plugin-admin-api/test/fixtures/files-error-routes/collections.js
index 82511e694..8af8046c4 100644
--- a/packages/plugin-admin-api/test/fixtures/files-error-routes/mocks.js
+++ b/packages/plugin-admin-api/test/fixtures/files-error-routes/collections.js
@@ -11,16 +11,16 @@ Unless required by applicable law or agreed to in writing, software distributed
module.exports = [
{
id: "base",
- routesVariants: ["get-users:success", "get-user:1"],
+ routes: ["get-users:success", "get-user:1"],
},
{
id: "user-2",
from: "base",
- routesVariants: ["get-user:2"],
+ routes: ["get-user:2"],
},
{
id: "user-real",
from: "base",
- routesVariants: ["get-user:real"],
+ routes: ["get-user:real"],
},
];
diff --git a/packages/plugin-admin-api/test/fixtures/files-error-routes/routes/user.js b/packages/plugin-admin-api/test/fixtures/files-error-routes/routes/user.js
index ac18756e6..23a7e4896 100644
--- a/packages/plugin-admin-api/test/fixtures/files-error-routes/routes/user.js
+++ b/packages/plugin-admin-api/test/fixtures/files-error-routes/routes/user.js
@@ -18,32 +18,37 @@ module.exports = [
variants: [
{
id: "1",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[1],
},
},
{
id: "real",
- response: (req, res) => {
- const userId = req.params.id;
- const user = USERS.find((userData) => userData.id === Number(userId));
- if (user) {
- res.status(200);
- res.send(user);
- } else {
- res.status(404);
- res.send({
- message: "User not found",
- });
- }
+ type: "middleware",
+ options: {
+ middleware: (req, res) => {
+ const userId = req.params.id;
+ const user = USERS.find((userData) => userData.id === Number(userId));
+ if (user) {
+ res.status(200);
+ res.send(user);
+ } else {
+ res.status(404);
+ res.send({
+ message: "User not found",
+ });
+ }
+ },
},
},
],
diff --git a/packages/plugin-admin-api/test/fixtures/web-tutorial-modified/mocks.js b/packages/plugin-admin-api/test/fixtures/web-tutorial-modified/collections.js
similarity index 79%
rename from packages/plugin-admin-api/test/fixtures/web-tutorial-modified/mocks.js
rename to packages/plugin-admin-api/test/fixtures/web-tutorial-modified/collections.js
index 0141b77f9..937139d37 100644
--- a/packages/plugin-admin-api/test/fixtures/web-tutorial-modified/mocks.js
+++ b/packages/plugin-admin-api/test/fixtures/web-tutorial-modified/collections.js
@@ -11,21 +11,21 @@ Unless required by applicable law or agreed to in writing, software distributed
module.exports = [
{
id: "base",
- routesVariants: ["get-users:success", "get-user:1", "get-users-new:success"],
+ routes: ["get-users:success", "get-user:1", "get-users-new:success"],
},
{
id: "user-2",
from: "base",
- routesVariants: ["get-user:2"],
+ routes: ["get-user:2"],
},
{
id: "user-real",
from: "base",
- routesVariants: ["get-user:real"],
+ routes: ["get-user:real"],
},
{
id: "users-error",
from: "base",
- routesVariants: ["get-users:error"],
+ routes: ["get-users:error"],
},
];
diff --git a/packages/plugin-admin-api/test/fixtures/web-tutorial/mocks.js b/packages/plugin-admin-api/test/fixtures/web-tutorial/collections.js
similarity index 84%
rename from packages/plugin-admin-api/test/fixtures/web-tutorial/mocks.js
rename to packages/plugin-admin-api/test/fixtures/web-tutorial/collections.js
index 82511e694..8af8046c4 100644
--- a/packages/plugin-admin-api/test/fixtures/web-tutorial/mocks.js
+++ b/packages/plugin-admin-api/test/fixtures/web-tutorial/collections.js
@@ -11,16 +11,16 @@ Unless required by applicable law or agreed to in writing, software distributed
module.exports = [
{
id: "base",
- routesVariants: ["get-users:success", "get-user:1"],
+ routes: ["get-users:success", "get-user:1"],
},
{
id: "user-2",
from: "base",
- routesVariants: ["get-user:2"],
+ routes: ["get-user:2"],
},
{
id: "user-real",
from: "base",
- routesVariants: ["get-user:real"],
+ routes: ["get-user:real"],
},
];
diff --git a/packages/plugin-admin-api/test/legacy/about-api.spec.js b/packages/plugin-admin-api/test/legacy/about-api.spec.js
new file mode 100644
index 000000000..c247d2eaf
--- /dev/null
+++ b/packages/plugin-admin-api/test/legacy/about-api.spec.js
@@ -0,0 +1,33 @@
+/*
+Copyright 2019-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const { startServer, doLegacyFetch, waitForServer } = require("../support/helpers");
+const { version } = require("../../package.json");
+
+describe("about api", () => {
+ let server;
+ beforeAll(async () => {
+ server = await startServer("web-tutorial");
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ await server.stop();
+ });
+
+ describe("get /", () => {
+ it("should return current version", async () => {
+ const response = await doLegacyFetch("/admin/about");
+ expect(response.body).toEqual({
+ version,
+ });
+ });
+ });
+});
diff --git a/packages/plugin-admin-api/test/legacy/alerts-api.spec.js b/packages/plugin-admin-api/test/legacy/alerts-api.spec.js
new file mode 100644
index 000000000..c2b680fc5
--- /dev/null
+++ b/packages/plugin-admin-api/test/legacy/alerts-api.spec.js
@@ -0,0 +1,105 @@
+/*
+Copyright 2020-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const {
+ startServer,
+ doLegacyFetch,
+ waitForServer,
+ wait,
+ fixturesFolder,
+} = require("../support/helpers");
+
+describe("alerts api", () => {
+ let server;
+ beforeAll(async () => {
+ server = await startServer("web-tutorial", {
+ mock: {
+ collections: {
+ selected: "foo",
+ },
+ },
+ });
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ await server.stop();
+ });
+
+ describe("when started", () => {
+ it("should return collection not found alert", async () => {
+ const response = await doLegacyFetch("/admin/alerts");
+ // one alert is caused by deprecated handler
+ expect(response.body.length).toEqual(3);
+ });
+
+ it("should return specific alert when requested by id", async () => {
+ const response = await doLegacyFetch("/admin/alerts/mock%3Acollections%3Aselected");
+ expect(response.body).toEqual({
+ id: "mock:collections:selected",
+ context: "mock:collections:selected",
+ message: "Collection 'foo' was not found. Selecting the first one found",
+ error: null,
+ });
+ });
+
+ it("should serve users collection mock under the /api/users path", async () => {
+ const users = await doLegacyFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ });
+ });
+
+ describe("when mock is modified", () => {
+ beforeAll(async () => {
+ await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ mock: {
+ collections: {
+ selected: "base",
+ },
+ },
+ },
+ });
+ await wait();
+ }, 10000);
+
+ it("should return no alerts", async () => {
+ const response = await doLegacyFetch("/admin/alerts");
+ // one alert is caused by deprecated handler
+ expect(response.body.length).toEqual(2);
+ });
+ });
+
+ describe("when there is an error loading files", () => {
+ beforeAll(async () => {
+ await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ files: {
+ path: fixturesFolder("files-error-routes"),
+ },
+ },
+ });
+ await wait();
+ }, 10000);
+
+ it("should return alert containing error", async () => {
+ const response = await doLegacyFetch("/admin/alerts");
+ expect(response.body.length).toEqual(6);
+ expect(response.body[5].error.message).toEqual(
+ expect.stringContaining("Cannot find module '../db/users'")
+ );
+ });
+ });
+});
diff --git a/packages/plugin-admin-api/test/legacy/cors.spec.js b/packages/plugin-admin-api/test/legacy/cors.spec.js
new file mode 100644
index 000000000..225cd0b0f
--- /dev/null
+++ b/packages/plugin-admin-api/test/legacy/cors.spec.js
@@ -0,0 +1,69 @@
+/*
+Copyright 2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const { startServer, doLegacyFetch, waitForServer } = require("../support/helpers");
+
+describe("cors middleware", () => {
+ let server;
+
+ afterEach(async () => {
+ await server.stop();
+ });
+
+ describe("when server cors is enabled", () => {
+ beforeEach(async () => {
+ server = await startServer("web-tutorial");
+ await waitForServer();
+ });
+
+ it("should add cors headers to admin api routes", async () => {
+ const response = await doLegacyFetch("/admin/about", { method: "OPTIONS" });
+ expect(response.headers.get("access-control-allow-origin")).toEqual("*");
+ expect(response.headers.get("access-control-allow-methods")).toEqual(
+ "GET,HEAD,PUT,PATCH,POST,DELETE"
+ );
+ });
+
+ it("should add cors headers to mock routes", async () => {
+ const response = await doLegacyFetch("/api/users/2", { method: "OPTIONS" });
+ expect(response.headers.get("access-control-allow-origin")).toEqual("*");
+ expect(response.headers.get("access-control-allow-methods")).toEqual(
+ "GET,HEAD,PUT,PATCH,POST,DELETE"
+ );
+ });
+ });
+
+ describe("when server cors is disabled", () => {
+ beforeEach(async () => {
+ server = await startServer("web-tutorial", {
+ server: {
+ cors: {
+ enabled: false,
+ },
+ },
+ });
+ await waitForServer();
+ });
+
+ it("should add cors headers to admin api routes", async () => {
+ const response = await doLegacyFetch("/admin/about", { method: "OPTIONS" });
+ expect(response.headers.get("access-control-allow-origin")).toEqual("*");
+ expect(response.headers.get("access-control-allow-methods")).toEqual(
+ "GET,HEAD,PUT,PATCH,POST,DELETE"
+ );
+ });
+
+ it("should disable cors headers in mock routes", async () => {
+ const response = await doLegacyFetch("/api/users/2", { method: "OPTIONS" });
+ expect(response.headers.get("access-control-allow-origin")).toEqual(null);
+ expect(response.headers.get("access-control-allow-methods")).toEqual(null);
+ });
+ });
+});
diff --git a/packages/plugin-admin-api/test/legacy/mock-custom-routes-variants-api.spec.js b/packages/plugin-admin-api/test/legacy/mock-custom-routes-variants-api.spec.js
new file mode 100644
index 000000000..5411bb1ef
--- /dev/null
+++ b/packages/plugin-admin-api/test/legacy/mock-custom-routes-variants-api.spec.js
@@ -0,0 +1,84 @@
+/*
+Copyright 2019-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const { startServer, doLegacyFetch, waitForServer } = require("../support/helpers");
+
+describe("mock custom routes variants api", () => {
+ let server;
+
+ beforeAll(async () => {
+ server = await startServer("web-tutorial", {
+ log: "silly",
+ });
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ await server.stop();
+ });
+
+ describe("get /", () => {
+ it("should return mock custom routes variants", async () => {
+ const response = await doLegacyFetch("/admin/mock-custom-routes-variants");
+ expect(response.body).toEqual([]);
+ });
+ });
+
+ describe("post /", () => {
+ it("should add mock custom route variant", async () => {
+ await doLegacyFetch("/admin/mock-custom-routes-variants", {
+ method: "POST",
+ body: {
+ id: "get-user:2",
+ },
+ });
+ const response = await doLegacyFetch("/admin/mock-custom-routes-variants");
+ expect(response.body).toEqual(["get-user:2"]);
+ });
+
+ it("should have changed user response", async () => {
+ const response = await doLegacyFetch("/api/users/1");
+ expect(response.body).toEqual({ id: 2, name: "Jane Doe" });
+ });
+ });
+
+ describe("delete /", () => {
+ it("should restore mock routes variants", async () => {
+ await doLegacyFetch("/admin/mock-custom-routes-variants", {
+ method: "DELETE",
+ });
+ const response = await doLegacyFetch("/admin/mock-custom-routes-variants");
+ expect(response.body).toEqual([]);
+ });
+
+ it("should have changed user response", async () => {
+ const response = await doLegacyFetch("/api/users/1");
+ expect(response.body).toEqual({ id: 1, name: "John Doe" });
+ });
+ });
+
+ describe("when trying to set an unexistent route variant", () => {
+ it("should not add mock custom route variant", async () => {
+ await doLegacyFetch("/admin/mock-custom-routes-variants", {
+ method: "POST",
+ body: {
+ id: "foo",
+ },
+ });
+ const response = await doLegacyFetch("/admin/mock-custom-routes-variants");
+ expect(response.body).toEqual([]);
+ });
+
+ it("should not have changed user response", async () => {
+ const response = await doLegacyFetch("/api/users/1");
+ expect(response.body).toEqual({ id: 1, name: "John Doe" });
+ });
+ });
+});
diff --git a/packages/plugin-admin-api/test/mocks-api.spec.js b/packages/plugin-admin-api/test/legacy/mocks-api.spec.js
similarity index 82%
rename from packages/plugin-admin-api/test/mocks-api.spec.js
rename to packages/plugin-admin-api/test/legacy/mocks-api.spec.js
index dc4c3dff9..bf95f4ae6 100644
--- a/packages/plugin-admin-api/test/mocks-api.spec.js
+++ b/packages/plugin-admin-api/test/legacy/mocks-api.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2019 Javier Brea
+Copyright 2019-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -8,7 +8,7 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
-const { startServer, doFetch, waitForServer } = require("./support/helpers");
+const { startServer, doLegacyFetch, waitForServer } = require("../support/helpers");
describe("mocks api", () => {
let server;
@@ -24,7 +24,7 @@ describe("mocks api", () => {
describe("get /", () => {
it("should return current mocks", async () => {
- const response = await doFetch("/admin/mocks");
+ const response = await doLegacyFetch("/admin/mocks");
expect(response.body).toEqual([
{
id: "base",
@@ -50,7 +50,7 @@ describe("mocks api", () => {
describe("get /base", () => {
it("should return base mock", async () => {
- const response = await doFetch("/admin/mocks/base");
+ const response = await doLegacyFetch("/admin/mocks/base");
expect(response.body).toEqual({
id: "base",
from: null,
@@ -62,7 +62,7 @@ describe("mocks api", () => {
describe("get /user-2", () => {
it("should return user-2 mock", async () => {
- const response = await doFetch("/admin/mocks/user-2");
+ const response = await doLegacyFetch("/admin/mocks/user-2");
expect(response.body).toEqual({
id: "user-2",
from: "base",
@@ -74,9 +74,9 @@ describe("mocks api", () => {
describe("get unexistant mock", () => {
it("should return a not found error", async () => {
- const response = await doFetch("/admin/mocks/foo");
+ const response = await doLegacyFetch("/admin/mocks/foo");
expect(response.status).toEqual(404);
- expect(response.body.message).toEqual('Mock with id "foo" was not found');
+ expect(response.body.message).toEqual('Legacy mock with id "foo" was not found');
});
});
});
diff --git a/packages/plugin-admin-api/test/plugin-options.spec.js b/packages/plugin-admin-api/test/legacy/plugin-options.spec.js
similarity index 85%
rename from packages/plugin-admin-api/test/plugin-options.spec.js
rename to packages/plugin-admin-api/test/legacy/plugin-options.spec.js
index 644f395fc..65f08afd2 100644
--- a/packages/plugin-admin-api/test/plugin-options.spec.js
+++ b/packages/plugin-admin-api/test/legacy/plugin-options.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2019 Javier Brea
+Copyright 2019-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -7,7 +7,7 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
-const { startServer, doFetch, waitForServer } = require("./support/helpers");
+const { startServer, doLegacyFetch, waitForServer } = require("../support/helpers");
describe("plugin options", () => {
let server;
@@ -29,7 +29,7 @@ describe("plugin options", () => {
});
it("should change the administration api path", async () => {
- const adminResponse = await doFetch("/foo/settings");
+ const adminResponse = await doLegacyFetch("/foo/settings");
expect(adminResponse.body.plugins.adminApi.path).toEqual("/foo");
});
});
diff --git a/packages/plugin-admin-api/test/legacy/routes-api.spec.js b/packages/plugin-admin-api/test/legacy/routes-api.spec.js
new file mode 100644
index 000000000..66aa5ad49
--- /dev/null
+++ b/packages/plugin-admin-api/test/legacy/routes-api.spec.js
@@ -0,0 +1,80 @@
+/*
+Copyright 2019-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const { startServer, doLegacyFetch, waitForServer } = require("../support/helpers");
+
+describe("routes api", () => {
+ let server;
+
+ beforeAll(async () => {
+ server = await startServer("web-tutorial");
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ await server.stop();
+ });
+
+ describe("get /", () => {
+ it("should return current routes", async () => {
+ const response = await doLegacyFetch("/admin/routes");
+ expect(response.body).toEqual([
+ {
+ id: "get-user",
+ delay: null,
+ url: "/api/users/:id",
+ method: "GET",
+ variants: ["get-user:1", "get-user:2", "get-user:real"],
+ },
+ {
+ id: "get-users",
+ delay: null,
+ url: "/api/users",
+ method: "GET",
+ variants: ["get-users:success", "get-users:error"],
+ },
+ ]);
+ });
+ });
+
+ describe("get /get-user", () => {
+ it("should return route with id get-user", async () => {
+ const response = await doLegacyFetch("/admin/routes/get-user");
+ expect(response.body).toEqual({
+ id: "get-user",
+ delay: null,
+ url: "/api/users/:id",
+ method: "GET",
+ variants: ["get-user:1", "get-user:2", "get-user:real"],
+ });
+ });
+ });
+
+ describe("get /get-users", () => {
+ it("should return route with id get-users", async () => {
+ const response = await doLegacyFetch("/admin/routes/get-users");
+ expect(response.body).toEqual({
+ id: "get-users",
+ delay: null,
+ url: "/api/users",
+ method: "GET",
+ variants: ["get-users:success", "get-users:error"],
+ });
+ });
+ });
+
+ describe("get unexistant route", () => {
+ it("should return a not found error", async () => {
+ const response = await doLegacyFetch("/admin/routes/foo");
+ expect(response.status).toEqual(404);
+ expect(response.body.message).toEqual('Legacy route with id "foo" was not found');
+ });
+ });
+});
diff --git a/packages/plugin-admin-api/test/routes-variants-api.spec.js b/packages/plugin-admin-api/test/legacy/routes-variants-api.spec.js
similarity index 84%
rename from packages/plugin-admin-api/test/routes-variants-api.spec.js
rename to packages/plugin-admin-api/test/legacy/routes-variants-api.spec.js
index 2445e379e..f5b72e195 100644
--- a/packages/plugin-admin-api/test/routes-variants-api.spec.js
+++ b/packages/plugin-admin-api/test/legacy/routes-variants-api.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2019 Javier Brea
+Copyright 2019-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -8,7 +8,7 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
-const { startServer, doFetch, waitForServer } = require("./support/helpers");
+const { startServer, doLegacyFetch, waitForServer } = require("../support/helpers");
describe("routes variants api", () => {
let server;
@@ -24,7 +24,7 @@ describe("routes variants api", () => {
describe("get /", () => {
it("should return routes variants", async () => {
- const response = await doFetch("/admin/routes-variants");
+ const response = await doLegacyFetch("/admin/routes-variants");
expect(response.body).toEqual([
{
id: "get-user:1",
@@ -73,7 +73,7 @@ describe("routes variants api", () => {
describe("get /get-user:1", () => {
it("should return route variant with id get-user:1", async () => {
- const response = await doFetch("/admin/routes-variants/get-user:1");
+ const response = await doLegacyFetch("/admin/routes-variants/get-user:1");
expect(response.body).toEqual({
id: "get-user:1",
routeId: "get-user",
@@ -86,7 +86,7 @@ describe("routes variants api", () => {
describe("get /get-user:2", () => {
it("should return route variant with id get-user:2", async () => {
- const response = await doFetch("/admin/routes-variants/get-user:2");
+ const response = await doLegacyFetch("/admin/routes-variants/get-user:2");
expect(response.body).toEqual({
id: "get-user:2",
routeId: "get-user",
@@ -99,9 +99,9 @@ describe("routes variants api", () => {
describe("get unexistant route variant", () => {
it("should return a not found error", async () => {
- const response = await doFetch("/admin/routes-variants/foo");
+ const response = await doLegacyFetch("/admin/routes-variants/foo");
expect(response.status).toEqual(404);
- expect(response.body.message).toEqual('Route variant with id "foo" was not found');
+ expect(response.body.message).toEqual('Legacy route variant with id "foo" was not found');
});
});
});
diff --git a/packages/plugin-admin-api/test/legacy/settings-api.spec.js b/packages/plugin-admin-api/test/legacy/settings-api.spec.js
new file mode 100644
index 000000000..3efce05f2
--- /dev/null
+++ b/packages/plugin-admin-api/test/legacy/settings-api.spec.js
@@ -0,0 +1,397 @@
+/*
+Copyright 2019-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const {
+ startServer,
+ doLegacyFetch,
+ fixturesFolder,
+ TimeCounter,
+ wait,
+ waitForServer,
+} = require("../support/helpers");
+
+describe("settings api", () => {
+ let server;
+ beforeAll(async () => {
+ server = await startServer("web-tutorial");
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ await server.stop();
+ });
+
+ describe("get", () => {
+ it("should return current settings", async () => {
+ const settingsResponse = await doLegacyFetch("/admin/settings");
+ expect(settingsResponse.body).toEqual({
+ config: {
+ allowUnknownArguments: true,
+ readArguments: false,
+ readEnvironment: false,
+ readFile: false,
+ },
+ mocks: {
+ delay: 0,
+ },
+ mock: {
+ collections: {
+ selected: "base",
+ },
+ routes: {
+ delay: 0,
+ },
+ },
+ files: {
+ enabled: true,
+ babelRegister: {
+ enabled: false,
+ options: {},
+ },
+ path: fixturesFolder("web-tutorial"),
+ watch: false,
+ },
+ plugins: {
+ register: [null],
+ adminApi: {
+ path: "/admin",
+ host: "0.0.0.0",
+ port: 3110,
+ },
+ },
+ log: "silent",
+ routesHandlers: [],
+ server: {
+ host: "0.0.0.0",
+ port: 3100,
+ cors: {
+ enabled: true,
+ options: {
+ preflightContinue: false,
+ },
+ },
+ jsonBodyParser: {
+ enabled: true,
+ options: {},
+ },
+ urlEncodedBodyParser: {
+ enabled: true,
+ options: {
+ extended: true,
+ },
+ },
+ },
+ variantHandlers: {
+ register: [],
+ },
+ });
+ });
+
+ it("should have added an API deprecation alert", async () => {
+ const alertsResponse = await doLegacyFetch("/admin/alerts");
+ const alert = alertsResponse.body.find(
+ (alertCandidate) => alertCandidate.id === "plugins:adminApi:legacy-api"
+ );
+ expect(alert).toEqual({
+ id: "plugins:adminApi:legacy-api",
+ context: "plugins:adminApi:legacy-api",
+ message:
+ "Usage of legacy REST API detected. Consider using the new REST API: https://www.mocks-server.org/docs/integrations/rest-api",
+ error: null,
+ });
+ });
+ });
+
+ describe("patch", () => {
+ describe("when changing an unexistant option", () => {
+ it("should response with a bad request containing errors", async () => {
+ expect.assertions(4);
+ const settingsResponse = await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ foo: "foo-value",
+ anotherFoo: 45,
+ third: {
+ foo: "foo",
+ },
+ },
+ });
+ expect(settingsResponse.status).toEqual(400);
+ expect(settingsResponse.body.message).toEqual(expect.stringContaining("foo"));
+ expect(settingsResponse.body.message).toEqual(expect.stringContaining("anotherFoo"));
+ expect(settingsResponse.body.message).toEqual(expect.stringContaining("third"));
+ });
+
+ it("should not apply any change if request contains any error", async () => {
+ expect.assertions(3);
+ const settingsUpdateResponse = await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ foo: "foo-value",
+ delay: 1000,
+ },
+ });
+ const settingsResponse = await doLegacyFetch("/admin/settings");
+ expect(settingsUpdateResponse.status).toEqual(400);
+ expect(settingsUpdateResponse.body.message).toEqual(expect.stringContaining("foo"));
+ expect(settingsResponse.body.mock.routes.delay).toEqual(0);
+ });
+ });
+
+ describe("when changing delay option", () => {
+ it("should respond with no delay", async () => {
+ const timeCounter = new TimeCounter();
+ await doLegacyFetch("/api/users");
+ timeCounter.stop();
+ expect(timeCounter.total).toBeLessThan(200);
+ });
+
+ it("should set delay option and have effect on server response time", async () => {
+ const timeCounter = new TimeCounter();
+ await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ mocks: {
+ delay: 2000,
+ },
+ },
+ });
+ await doLegacyFetch("/api/users");
+ timeCounter.stop();
+ expect(timeCounter.total).toBeGreaterThan(2000);
+ });
+
+ it("should set delay option to 0 when using legacy option", async () => {
+ const timeCounter = new TimeCounter();
+ await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ mocks: {
+ delay: 0,
+ },
+ },
+ });
+ await doLegacyFetch("/api/users");
+ timeCounter.stop();
+ expect(timeCounter.total).toBeLessThan(200);
+ });
+
+ it("should set delay option to 1000", async () => {
+ await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ mock: {
+ routes: {
+ delay: 1000,
+ },
+ },
+ },
+ });
+ const timeCounter = new TimeCounter();
+ await doLegacyFetch("/api/users");
+ timeCounter.stop();
+ expect(timeCounter.total).toBeGreaterThan(900);
+ });
+
+ it("should set delay option to 0", async () => {
+ await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ mock: {
+ routes: {
+ delay: 0,
+ },
+ },
+ },
+ });
+ const timeCounter = new TimeCounter();
+ await doLegacyFetch("/api/users");
+ timeCounter.stop();
+ expect(timeCounter.total).toBeLessThan(200);
+ });
+ });
+
+ describe("when changing mock option", () => {
+ describe("without changing it", () => {
+ it("should serve user 1 under the /api/users/1 path", async () => {
+ const users = await doLegacyFetch("/api/users/1");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+
+ it("should serve user 1 under the /api/users/2 path", async () => {
+ const users = await doLegacyFetch("/api/users/2");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+ });
+
+ describe('changing it to "user-2"', () => {
+ beforeAll(async () => {
+ await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ mocks: {
+ selected: "user-2",
+ },
+ },
+ });
+ });
+
+ it("should return new mock when getting settings", async () => {
+ const settingsResponse = await doLegacyFetch("/admin/settings");
+ expect(settingsResponse.body.mocks.selected).toEqual("user-2");
+ });
+
+ it("should serve user 2 under the /api/users/1 path", async () => {
+ const users = await doLegacyFetch("/api/users/1");
+ expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
+ });
+
+ it("should serve user 2 under the /api/users/2 path", async () => {
+ const users = await doLegacyFetch("/api/users/2");
+ expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
+ });
+ });
+ });
+
+ describe("when changing path option", () => {
+ beforeAll(async () => {
+ await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ files: {
+ path: fixturesFolder("web-tutorial-modified"),
+ },
+ },
+ });
+ await wait(1000);
+ });
+
+ afterAll(async () => {
+ await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ files: {
+ path: fixturesFolder("web-tutorial"),
+ },
+ },
+ });
+ await wait(1000);
+ });
+
+ it("should return new path option when getting settings", async () => {
+ const settingsResponse = await doLegacyFetch("/admin/settings");
+ expect(settingsResponse.body.files.path).toEqual(fixturesFolder("web-tutorial-modified"));
+ });
+
+ it("should serve users collection mock under the /api/users path", async () => {
+ const users = await doLegacyFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe modified" },
+ { id: 2, name: "Jane Doe modified" },
+ ]);
+ });
+ });
+
+ describe("when changing port option", () => {
+ beforeAll(async () => {
+ await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ server: {
+ port: 3200,
+ },
+ },
+ });
+ await wait(1000);
+ });
+
+ afterAll(async () => {
+ await doLegacyFetch("/admin/settings", {
+ port: 3200,
+ method: "PATCH",
+ body: {
+ server: {
+ port: 3100,
+ },
+ },
+ });
+ await wait(1000);
+ });
+
+ it("should return new port option when getting settings, using new port", async () => {
+ const settingsResponse = await doLegacyFetch("/admin/settings", {
+ port: 3200,
+ });
+ expect(settingsResponse.body.server.port).toEqual(3200);
+ });
+
+ it("should serve user 2 under the /api/users/1 path using new port", async () => {
+ const users = await doLegacyFetch("/api/users/1", {
+ port: 3200,
+ });
+ expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
+ });
+ });
+
+ describe("when changing adminApiPath option", () => {
+ beforeAll(async () => {
+ await doLegacyFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ plugins: {
+ adminApi: {
+ path: "/administration",
+ },
+ },
+ },
+ });
+ await wait(1000);
+ });
+
+ afterAll(async () => {
+ await doLegacyFetch("/administration/settings", {
+ method: "PATCH",
+ body: {
+ plugins: {
+ adminApi: {
+ path: "/admin",
+ },
+ },
+ },
+ });
+ await wait(1000);
+ });
+
+ it("should return new port adminApiPath when getting settings, using new admin api path", async () => {
+ const settingsResponse = await doLegacyFetch("/administration/settings");
+ expect(settingsResponse.body.plugins.adminApi.path).toEqual("/administration");
+ });
+
+ it("should have added an option deprecation alert", async () => {
+ const alertsResponse = await doLegacyFetch("/administration/alerts");
+ const alert = alertsResponse.body.find(
+ (alertCandidate) => alertCandidate.id === "plugins:adminApi:path-option"
+ );
+ expect(alert).toEqual({
+ id: "plugins:adminApi:path-option",
+ context: "plugins:adminApi:path-option",
+ message:
+ "Usage of 'adminApi.path' option is deprecated. Consider using the new REST API: https://www.mocks-server.org/docs/integrations/rest-api",
+ error: null,
+ });
+ });
+
+ it("should return not found adminApiPath when getting settings in old admin api path", async () => {
+ const settingsResponse = await doLegacyFetch("/admin/settings");
+ expect(settingsResponse.status).toEqual(404);
+ });
+ });
+ });
+});
diff --git a/packages/plugin-admin-api/test/stop-plugin.spec.js b/packages/plugin-admin-api/test/legacy/stop-plugin.spec.js
similarity index 80%
rename from packages/plugin-admin-api/test/stop-plugin.spec.js
rename to packages/plugin-admin-api/test/legacy/stop-plugin.spec.js
index de0bad408..6d6741f68 100644
--- a/packages/plugin-admin-api/test/stop-plugin.spec.js
+++ b/packages/plugin-admin-api/test/legacy/stop-plugin.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2020 Javier Brea
+Copyright 2020-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -8,7 +8,13 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
-const { startServer, doFetch, fixturesFolder, wait, waitForServer } = require("./support/helpers");
+const {
+ startServer,
+ doLegacyFetch,
+ fixturesFolder,
+ wait,
+ waitForServer,
+} = require("../support/helpers");
describe("when stopping plugin", () => {
let server;
@@ -23,7 +29,7 @@ describe("when stopping plugin", () => {
describe("when started", () => {
it("should return current settings", async () => {
- const response = await doFetch("/admin/settings");
+ const response = await doLegacyFetch("/admin/settings");
expect(response.body.files.path).toEqual(fixturesFolder("web-tutorial"));
});
});
@@ -32,13 +38,13 @@ describe("when stopping plugin", () => {
it("should respond not found when requesting setting", async () => {
await server._stopPlugins();
await waitForServer();
- const response = await doFetch("/admin/settings");
+ const response = await doLegacyFetch("/admin/settings");
expect(response.status).toEqual(404);
});
it("should respond to mocks requests", async () => {
await server._stopPlugins();
- const response = await doFetch("/api/users");
+ const response = await doLegacyFetch("/api/users");
expect(response.body).toEqual([
{
id: 1,
@@ -60,7 +66,7 @@ describe("when stopping plugin", () => {
},
});
await wait(1000);
- const response = await doFetch("/api/users/2");
+ const response = await doLegacyFetch("/api/users/2");
expect(response.body).toEqual({
id: 2,
name: "Jane Doe",
@@ -70,7 +76,7 @@ describe("when stopping plugin", () => {
it("should have not started the plugin", async () => {
await server._stopPlugins();
await waitForServer();
- const response = await doFetch("/admin/settings");
+ const response = await doLegacyFetch("/admin/settings");
expect(response.status).toEqual(404);
});
});
@@ -79,7 +85,7 @@ describe("when stopping plugin", () => {
it("should respond with same mock", async () => {
await server._startPlugins();
await waitForServer();
- const response = await doFetch("/api/users/2");
+ const response = await doLegacyFetch("/api/users/2");
expect(response.body).toEqual({
id: 2,
name: "Jane Doe",
@@ -87,7 +93,7 @@ describe("when stopping plugin", () => {
});
it("should have started the plugin", async () => {
- const response = await doFetch("/admin/settings");
+ const response = await doLegacyFetch("/admin/settings");
expect(response.body.files.path).toEqual(fixturesFolder("web-tutorial"));
});
});
diff --git a/packages/plugin-admin-api/test/mock-custom-routes-variants-api.spec.js b/packages/plugin-admin-api/test/mock-custom-route-variants-api.spec.js
similarity index 76%
rename from packages/plugin-admin-api/test/mock-custom-routes-variants-api.spec.js
rename to packages/plugin-admin-api/test/mock-custom-route-variants-api.spec.js
index ee85500f6..32c215274 100644
--- a/packages/plugin-admin-api/test/mock-custom-routes-variants-api.spec.js
+++ b/packages/plugin-admin-api/test/mock-custom-route-variants-api.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2019 Javier Brea
+Copyright 2019-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -8,13 +8,15 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
-const { startServer, doFetch, waitForServer } = require("./support/helpers");
+const { startServer, doFetch, doApiFetch, waitForServer } = require("./support/helpers");
describe("mock custom routes variants api", () => {
let server;
beforeAll(async () => {
- server = await startServer("web-tutorial");
+ server = await startServer("web-tutorial", {
+ log: "silly",
+ });
await waitForServer();
});
@@ -24,20 +26,20 @@ describe("mock custom routes variants api", () => {
describe("get /", () => {
it("should return mock custom routes variants", async () => {
- const response = await doFetch("/admin/mock-custom-routes-variants");
+ const response = await doApiFetch("/mock/custom-route-variants");
expect(response.body).toEqual([]);
});
});
describe("post /", () => {
it("should add mock custom route variant", async () => {
- await doFetch("/admin/mock-custom-routes-variants", {
+ await doApiFetch("/mock/custom-route-variants", {
method: "POST",
body: {
id: "get-user:2",
},
});
- const response = await doFetch("/admin/mock-custom-routes-variants");
+ const response = await doApiFetch("/mock/custom-route-variants");
expect(response.body).toEqual(["get-user:2"]);
});
@@ -49,10 +51,10 @@ describe("mock custom routes variants api", () => {
describe("delete /", () => {
it("should restore mock routes variants", async () => {
- await doFetch("/admin/mock-custom-routes-variants", {
+ await doApiFetch("/mock/custom-route-variants", {
method: "DELETE",
});
- const response = await doFetch("/admin/mock-custom-routes-variants");
+ const response = await doApiFetch("/mock/custom-route-variants");
expect(response.body).toEqual([]);
});
@@ -64,13 +66,13 @@ describe("mock custom routes variants api", () => {
describe("when trying to set an unexistent route variant", () => {
it("should not add mock custom route variant", async () => {
- await doFetch("/admin/mock-custom-routes-variants", {
+ await doApiFetch("/mock/custom-route-variants", {
method: "POST",
body: {
id: "foo",
},
});
- const response = await doFetch("/admin/mock-custom-routes-variants");
+ const response = await doApiFetch("/mock/custom-route-variants");
expect(response.body).toEqual([]);
});
diff --git a/packages/plugin-admin-api/test/route-variants-api.spec.js b/packages/plugin-admin-api/test/route-variants-api.spec.js
new file mode 100644
index 000000000..be90571b0
--- /dev/null
+++ b/packages/plugin-admin-api/test/route-variants-api.spec.js
@@ -0,0 +1,107 @@
+/*
+Copyright 2019-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const { startServer, doApiFetch, waitForServer } = require("./support/helpers");
+
+describe("routes variants api", () => {
+ let server;
+
+ beforeAll(async () => {
+ server = await startServer("web-tutorial");
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ await server.stop();
+ });
+
+ describe("get /", () => {
+ it("should return routes variants", async () => {
+ const response = await doApiFetch("/mock/variants");
+ expect(response.body).toEqual([
+ {
+ id: "get-user:1",
+ route: "get-user",
+ type: "default",
+ preview: { body: { id: 1, name: "John Doe" }, status: 200 },
+ delay: null,
+ },
+ {
+ id: "get-user:2",
+ route: "get-user",
+ type: "default",
+ preview: { body: { id: 2, name: "Jane Doe" }, status: 200 },
+ delay: null,
+ },
+ {
+ id: "get-user:real",
+ route: "get-user",
+ type: "default",
+ preview: null,
+ delay: null,
+ },
+ {
+ id: "get-users:success",
+ route: "get-users",
+ type: "default",
+ preview: {
+ body: [
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ],
+ status: 200,
+ },
+ delay: null,
+ },
+ {
+ id: "get-users:error",
+ route: "get-users",
+ type: "default",
+ preview: { body: { message: "Bad data" }, status: 403 },
+ delay: null,
+ },
+ ]);
+ });
+ });
+
+ describe("get /get-user:1", () => {
+ it("should return route variant with id get-user:1", async () => {
+ const response = await doApiFetch("/mock/variants/get-user:1");
+ expect(response.body).toEqual({
+ id: "get-user:1",
+ route: "get-user",
+ type: "default",
+ preview: { body: { id: 1, name: "John Doe" }, status: 200 },
+ delay: null,
+ });
+ });
+ });
+
+ describe("get /get-user:2", () => {
+ it("should return route variant with id get-user:2", async () => {
+ const response = await doApiFetch("/mock/variants/get-user:2");
+ expect(response.body).toEqual({
+ id: "get-user:2",
+ route: "get-user",
+ type: "default",
+ preview: { body: { id: 2, name: "Jane Doe" }, status: 200 },
+ delay: null,
+ });
+ });
+ });
+
+ describe("get unexistant route variant", () => {
+ it("should return a not found error", async () => {
+ const response = await doApiFetch("/mock/variants/foo");
+ expect(response.status).toEqual(404);
+ expect(response.body.message).toEqual('Route variant with id "foo" was not found');
+ });
+ });
+});
diff --git a/packages/plugin-admin-api/test/routes-api.spec.js b/packages/plugin-admin-api/test/routes-api.spec.js
index 7e16b78ef..a8aeae04b 100644
--- a/packages/plugin-admin-api/test/routes-api.spec.js
+++ b/packages/plugin-admin-api/test/routes-api.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2019 Javier Brea
+Copyright 2019-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -8,7 +8,7 @@ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
-const { startServer, doFetch, waitForServer } = require("./support/helpers");
+const { startServer, doApiFetch, waitForServer } = require("./support/helpers");
describe("routes api", () => {
let server;
@@ -24,20 +24,20 @@ describe("routes api", () => {
describe("get /", () => {
it("should return current routes", async () => {
- const response = await doFetch("/admin/routes");
+ const response = await doApiFetch("/mock/routes");
expect(response.body).toEqual([
{
id: "get-user",
delay: null,
url: "/api/users/:id",
- method: "GET",
+ method: "get",
variants: ["get-user:1", "get-user:2", "get-user:real"],
},
{
id: "get-users",
delay: null,
url: "/api/users",
- method: "GET",
+ method: "get",
variants: ["get-users:success", "get-users:error"],
},
]);
@@ -46,12 +46,12 @@ describe("routes api", () => {
describe("get /get-user", () => {
it("should return route with id get-user", async () => {
- const response = await doFetch("/admin/routes/get-user");
+ const response = await doApiFetch("/mock/routes/get-user");
expect(response.body).toEqual({
id: "get-user",
delay: null,
url: "/api/users/:id",
- method: "GET",
+ method: "get",
variants: ["get-user:1", "get-user:2", "get-user:real"],
});
});
@@ -59,12 +59,12 @@ describe("routes api", () => {
describe("get /get-users", () => {
it("should return route with id get-users", async () => {
- const response = await doFetch("/admin/routes/get-users");
+ const response = await doApiFetch("/mock/routes/get-users");
expect(response.body).toEqual({
id: "get-users",
delay: null,
url: "/api/users",
- method: "GET",
+ method: "get",
variants: ["get-users:success", "get-users:error"],
});
});
@@ -72,7 +72,7 @@ describe("routes api", () => {
describe("get unexistant route", () => {
it("should return a not found error", async () => {
- const response = await doFetch("/admin/routes/foo");
+ const response = await doApiFetch("/mock/routes/foo");
expect(response.status).toEqual(404);
expect(response.body.message).toEqual('Route with id "foo" was not found');
});
diff --git a/packages/plugin-admin-api/test/server.spec.js b/packages/plugin-admin-api/test/server.spec.js
new file mode 100644
index 000000000..f600ef077
--- /dev/null
+++ b/packages/plugin-admin-api/test/server.spec.js
@@ -0,0 +1,248 @@
+/*
+Copyright 2020-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const {
+ startServer,
+ doFetch,
+ doApiFetch,
+ fixturesFolder,
+ wait,
+ waitForServer,
+} = require("./support/helpers");
+
+describe("server", () => {
+ let server, hostOption, portOption;
+ beforeAll(async () => {
+ server = await startServer("web-tutorial", { log: "silly" });
+ hostOption = server.config.namespace("plugins").namespace("adminApi").option("host");
+ portOption = server.config.namespace("plugins").namespace("adminApi").option("port");
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ await server.stop();
+ });
+
+ describe("when started", () => {
+ it("should return current config", async () => {
+ const response = await doApiFetch("/config");
+ expect(response.body.files.path).toEqual(fixturesFolder("web-tutorial"));
+ });
+ });
+
+ describe("when stopped", () => {
+ it("should not respond when requesting setting", async () => {
+ await server._stopPlugins();
+ await waitForServer();
+ const error = await doApiFetch("/config").catch((err) => Promise.resolve(err));
+ expect(error.message).toEqual(expect.stringContaining("ECONNREFUSED"));
+ });
+
+ it("should respond to mock requests", async () => {
+ await server._stopPlugins();
+ const response = await doFetch("/api/users");
+ expect(response.body).toEqual([
+ {
+ id: 1,
+ name: "John Doe",
+ },
+ {
+ id: 2,
+ name: "Jane Doe",
+ },
+ ]);
+ });
+ });
+
+ describe("when collection is changed", () => {
+ it("should respond with new collection", async () => {
+ server.config.set({
+ mocks: {
+ selected: "user-2",
+ },
+ });
+ await wait(1000);
+ const response = await doFetch("/api/users/2");
+ expect(response.body).toEqual({
+ id: 2,
+ name: "Jane Doe",
+ });
+ });
+
+ it("should have not started the plugin", async () => {
+ await server._stopPlugins();
+ await waitForServer();
+ const error = await doApiFetch("/config").catch((err) => Promise.resolve(err));
+ expect(error.message).toEqual(expect.stringContaining("ECONNREFUSED"));
+ });
+ });
+
+ describe("when plugins are started", () => {
+ it("should respond with same collection", async () => {
+ await server._startPlugins();
+ await waitForServer();
+ const response = await doFetch("/api/users/2");
+ expect(response.body).toEqual({
+ id: 2,
+ name: "Jane Doe",
+ });
+ });
+
+ it("should have started the plugin", async () => {
+ const response = await doApiFetch("/config");
+ expect(response.body.files.path).toEqual(fixturesFolder("web-tutorial"));
+ });
+
+ it("should respond to mock requests", async () => {
+ const response = await doFetch("/api/users");
+ expect(response.body).toEqual([
+ {
+ id: 1,
+ name: "John Doe",
+ },
+ {
+ id: 2,
+ name: "Jane Doe",
+ },
+ ]);
+ });
+ });
+
+ describe("when url does not exist", () => {
+ it("should respond not found", async () => {
+ const response = await doApiFetch("/foo");
+ expect(response.status).toEqual(404);
+ expect(response.body).toEqual({ error: "Not Found", message: "Not Found", statusCode: 404 });
+ });
+ });
+
+ describe("when there is an error", () => {
+ let routes;
+ beforeAll(() => {
+ routes = server.mock.routes.plain;
+ server.mock._plainRoutes = null;
+ });
+
+ afterAll(() => {
+ server.mock._plainRoutes = routes;
+ });
+
+ it("should respond with error 500", async () => {
+ const response = await doApiFetch("/mock/routes");
+ expect(response.status).toEqual(500);
+ expect(response.body).toEqual({
+ error: "Internal Server Error",
+ message: "An internal server error occurred",
+ statusCode: 500,
+ });
+ });
+ });
+
+ describe("when port option changes", () => {
+ it("should respond at new port", async () => {
+ await doApiFetch("/config", {
+ method: "PATCH",
+ body: {
+ plugins: {
+ adminApi: {
+ port: 3102,
+ },
+ },
+ },
+ });
+ await waitForServer(3102);
+ const response = await doApiFetch("/config", {
+ port: 3102,
+ });
+ expect(response.body.files.path).toEqual(fixturesFolder("web-tutorial"));
+ });
+
+ it("should respond to mock requests at same port", async () => {
+ const response = await doFetch("/api/users");
+ expect(response.body).toEqual([
+ {
+ id: 1,
+ name: "John Doe",
+ },
+ {
+ id: 2,
+ name: "Jane Doe",
+ },
+ ]);
+ });
+ });
+
+ describe("when options change many times", () => {
+ it("should respond", async () => {
+ hostOption.value = "127.0.0.1";
+ hostOption.value = "0.0.0.0";
+ hostOption.value = "127.0.0.1";
+ hostOption.value = "0.0.0.0";
+ hostOption.value = "127.0.0.1";
+ portOption.value = 3102;
+ await waitForServer(3102);
+ await doApiFetch("/config", {
+ port: 3102,
+ method: "PATCH",
+ body: {
+ plugins: {
+ adminApi: {
+ host: "127.0.0.1",
+ port: 3103,
+ },
+ },
+ },
+ });
+ await waitForServer(3103);
+ const response = await doApiFetch("/config", {
+ port: 3103,
+ });
+ expect(response.body.files.path).toEqual(fixturesFolder("web-tutorial"));
+ });
+ });
+
+ describe("when host is wrong", () => {
+ it("should not respond", async () => {
+ hostOption.value = "foo";
+ await wait(1000);
+ const error = await doApiFetch("/config", { port: 3103 }).catch((err) =>
+ Promise.resolve(err)
+ );
+ expect(error.message).toEqual(expect.stringContaining("ECONNREFUSED"));
+ });
+ });
+
+ describe("when port is wrong", () => {
+ it("should not respond", async () => {
+ hostOption.value = "0.0.0.0";
+ portOption.value = 13240230;
+ await wait(3000);
+
+ const error = await doApiFetch("/config", { port: 3103 }).catch((err) =>
+ Promise.resolve(err)
+ );
+ expect(error.message).toEqual(expect.stringContaining("ECONNREFUSED"));
+ });
+ });
+
+ describe("when port is right", () => {
+ it("should respond again", async () => {
+ hostOption.value = "0.0.0.0";
+ portOption.value = 3115;
+
+ await waitForServer(3115);
+ const response = await doApiFetch("/config", {
+ port: 3115,
+ });
+ expect(response.body.plugins.adminApi.port).toEqual(3115);
+ expect(response.body.plugins.adminApi.host).toEqual("0.0.0.0");
+ });
+ });
+});
diff --git a/packages/plugin-admin-api/test/support/helpers.js b/packages/plugin-admin-api/test/support/helpers.js
index 74e1b8c88..6cefdb6c9 100644
--- a/packages/plugin-admin-api/test/support/helpers.js
+++ b/packages/plugin-admin-api/test/support/helpers.js
@@ -18,6 +18,7 @@ const Core = require("@mocks-server/core");
const AdminApiPlugin = require("../../index");
const SERVER_PORT = 3100;
+const API_SERVER_PORT = 3110;
const defaultOptions = {
server: {
@@ -30,7 +31,7 @@ const defaultOptions = {
};
const defaultRequestOptions = {
- method: "GET",
+ method: "get",
headers: {
"Content-Type": "application/json",
},
@@ -101,13 +102,32 @@ const doFetch = (uri, options = {}) => {
body: processedRes,
status: res.status,
headers: res.headers,
+ url: res.url,
}))
.catch(() => {
- return { status: res.status, headers: res.headers };
+ return { status: res.status, headers: res.headers, url: res.url };
});
});
};
+const doServerFetch = (uri, options = {}) => {
+ return doFetch(`${uri}`, {
+ port: API_SERVER_PORT,
+ ...options,
+ });
+};
+
+const doApiFetch = (uri, options) => {
+ return doServerFetch(`/api${uri}`, options);
+};
+
+const doLegacyFetch = (uri, options = {}) => {
+ return doFetch(uri, {
+ port: 3100,
+ ...options,
+ });
+};
+
class TimeCounter {
constructor() {
this._startTime = new Date();
@@ -155,7 +175,10 @@ module.exports = {
createCore,
startExistingCore,
startServer,
+ doLegacyFetch,
doFetch,
+ doServerFetch,
+ doApiFetch,
TimeCounter,
wait,
waitForServer,
diff --git a/packages/plugin-admin-api/test/swagger.spec.js b/packages/plugin-admin-api/test/swagger.spec.js
new file mode 100644
index 000000000..ba9fb0c0b
--- /dev/null
+++ b/packages/plugin-admin-api/test/swagger.spec.js
@@ -0,0 +1,75 @@
+/*
+Copyright 2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const { startServer, wait, doServerFetch, waitForServer } = require("./support/helpers");
+
+describe("swagger", () => {
+ let server, hostOption, portOption;
+
+ beforeAll(async () => {
+ server = await startServer("web-tutorial", { log: "silly" });
+ hostOption = server.config.namespace("plugins").namespace("adminApi").option("host");
+ portOption = server.config.namespace("plugins").namespace("adminApi").option("port");
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ await server.stop();
+ });
+
+ describe("when server is started", () => {
+ it("should return current API url", async () => {
+ const response = await doServerFetch("/docs/openapi.json");
+ expect(response.body.servers[0].url).toEqual(`http://localhost:${portOption.value}/api`);
+ });
+ });
+
+ describe("when port is changed", () => {
+ it("should return current API url", async () => {
+ portOption.value = 3102;
+ await waitForServer(3102);
+ const response = await doServerFetch("/docs/openapi.json", {
+ port: 3102,
+ });
+ expect(response.body.servers[0].url).toEqual(`http://localhost:3102/api`);
+ });
+ });
+
+ describe("when host is changed", () => {
+ it("should return current API url", async () => {
+ hostOption.value = "127.0.0.1";
+ portOption.value = 3110;
+ await wait(1000);
+ const response = await doServerFetch("/docs/openapi.json");
+ expect(response.body.servers[0].url).toEqual(`http://127.0.0.1:3110/api`);
+ });
+ });
+
+ describe("when root url is loaded", () => {
+ it("should redirect to swagger", async () => {
+ const response = await doServerFetch("/");
+ expect(response.url).toEqual("http://127.0.0.1:3110/docs/");
+ });
+ });
+
+ describe("when root index.html url is loaded", () => {
+ it("should redirect to swagger", async () => {
+ const response = await doServerFetch("/index.html");
+ expect(response.url).toEqual("http://127.0.0.1:3110/docs/");
+ });
+ });
+
+ describe("when root index.htm url is loaded", () => {
+ it("should redirect to swagger", async () => {
+ const response = await doServerFetch("/index.htm");
+ expect(response.url).toEqual("http://127.0.0.1:3110/docs/");
+ });
+ });
+});
diff --git a/packages/plugin-inquirer-cli/CHANGELOG.md b/packages/plugin-inquirer-cli/CHANGELOG.md
index a54f571e4..57baf2acf 100644
--- a/packages/plugin-inquirer-cli/CHANGELOG.md
+++ b/packages/plugin-inquirer-cli/CHANGELOG.md
@@ -11,10 +11,29 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Removed
### BREAKING CHANGE
+## [3.2.0] - 2022-07-22
+
+### Added
+- Add debounce to refresh menu function to avoid too much renders
+
+### Changed
+- feat: Use core v3.6 new options
+- feat: Use core.mock.restoreRouteVariants method
+- feat: Use core.mock.customRouteVariants getter
+- feat: Use core.server.restart method
+- feat: Use core.mock.onChange method
+- feat: Use core.mock.routes.plain getter
+- feat: Use core.mock.routes.plainVariants getter
+- feat: Use core.mock.collections.selected getter
+- feat: Use core.mock.collections.ids getter
+- feat: Use core.mock.collections.plain getter
+- feat: Use core.alerts.onChange method
+- feat: Rename concepts
+
## [3.1.0] - 2022-06-27
### Changed
- refactor: Remove unused property
-- feat: Use new custom core API
+- feat(#334): Use new custom core API
### Added
- feat: Display context in errors and warnings
diff --git a/packages/plugin-inquirer-cli/README.md b/packages/plugin-inquirer-cli/README.md
index b5f890b0a..d35b54e7a 100644
--- a/packages/plugin-inquirer-cli/README.md
+++ b/packages/plugin-inquirer-cli/README.md
@@ -17,14 +17,14 @@
## Usage
-This plugin is preinstalled in the [main distribution of the Mocks Server project][main-distribution-url]. _If you want ot install it by yourself, you can refer to the [plugins documentation][plugins-url]._
+This plugin is pre-installed in the [main distribution of the Mocks Server project][main-distribution-url]. _If you want to install it by yourself, you can refer to the [plugins documentation][plugins-url]._
![Interactive CLI][animated-image-url]
## Main features
-* __Displays current [settings][settings-url].__ _Settings will be refreshed automatically even when changed using other plugins, as the REST API, etc._
-* __Allows to change [settings][settings-url].__
+* __Displays current [configuration][settings-url].__ _Settings will be refreshed automatically even when changed using other plugins, as the REST API, etc._
+* __Allows to change some [settings][settings-url].__
* __Displays current alerts.__ _Alerts include errors when loading mock files, wrong options, etc._
* __Displays logs.__ _Mocks-server logs are displayed in real time._
@@ -33,7 +33,7 @@ This plugin is preinstalled in the [main distribution of the Mocks Server projec
* `enabled`: `` Start the interactive CLI or not. Default is `true`. Use `false` to disable it _(`--no-plugins.inquirerCli.enabled`) when using command line arguments)_
* `emojis`: `` Render emojis or not. Default is `true`.
-Read more about [how to set options in Mocks Server here](https://www.mocks-server.org/docs/configuration-options).
+Read more about [how to set options in Mocks Server here][settings-url].
## Support
@@ -47,9 +47,8 @@ Please read the [contributing guidelines](.github/CONTRIBUTING.md) and [code of
[inquirer-url]: https://www.npmjs.com/package/inquirer
[inquirer-support]: https://www.npmjs.com/package/inquirer#support-os-terminals
[website-url]: https://www.mocks-server.org
-[plugins-url]: https://www.mocks-server.org/docs/plugins-adding-plugins
-[settings-url]: https://www.mocks-server.org/docs/configuration-options
+[plugins-url]: https://www.mocks-server.org/docs/plugins/intro
+[settings-url]: https://www.mocks-server.org/docs/configuration/how-to-change-settings
[animated-image-url]: https://www.mocks-server.org/img/inquirer-cli.gif
[main-distribution-url]: https://www.npmjs.com/package/@mocks-server/main
-[options-url]: https://www.mocks-server.org/docs/configuration-options
[logo-url]: https://www.mocks-server.org/img/logo_120.png
diff --git a/packages/plugin-inquirer-cli/package.json b/packages/plugin-inquirer-cli/package.json
index 92167c6af..a39a86fdd 100644
--- a/packages/plugin-inquirer-cli/package.json
+++ b/packages/plugin-inquirer-cli/package.json
@@ -1,6 +1,6 @@
{
"name": "@mocks-server/plugin-inquirer-cli",
- "version": "3.1.0",
+ "version": "3.2.0",
"description": "Mocks server plugin providing an interactive CLI",
"keywords": [
"mocks-server-plugin",
@@ -32,7 +32,7 @@
"test:unit": "jest"
},
"peerDependencies": {
- "@mocks-server/core": ">=3.2.0 <4.x"
+ "@mocks-server/core": ">=3.6.0 <4.x"
},
"dependencies": {
"chalk": "4.1.1",
diff --git a/packages/plugin-inquirer-cli/sonar-project.properties b/packages/plugin-inquirer-cli/sonar-project.properties
index fed120cbe..e7f05f2a7 100644
--- a/packages/plugin-inquirer-cli/sonar-project.properties
+++ b/packages/plugin-inquirer-cli/sonar-project.properties
@@ -1,7 +1,7 @@
sonar.organization=mocks-server
sonar.projectKey=mocks-server_main_plugin-inquirer-cli
sonar.projectName=plugin-inquirer-cli
-sonar.projectVersion=3.1.0
+sonar.projectVersion=3.2.0
sonar.javascript.file.suffixes=.js
sonar.sourceEncoding=UTF-8
diff --git a/packages/plugin-inquirer-cli/src/Cli.js b/packages/plugin-inquirer-cli/src/Cli.js
index 86a5db208..fe0ab1cfb 100644
--- a/packages/plugin-inquirer-cli/src/Cli.js
+++ b/packages/plugin-inquirer-cli/src/Cli.js
@@ -11,22 +11,22 @@ Unless required by applicable law or agreed to in writing, software distributed
"use strict";
-const { isNumber } = require("lodash");
+const { isNumber, debounce } = require("lodash");
const inquirer = require("./Inquirer");
const { renderHeader, renderAlert, getCurrentMockMessageLevel } = require("./helpers");
const MAIN_CHOICES = [
{
- name: "Change current mock",
- value: "mock",
+ name: "Select collection",
+ value: "collection",
},
{
- name: "Change route variant",
+ name: "Use route variant",
value: "variant",
},
{
- name: "Restore routes variants",
+ name: "Restore route variants",
value: "restoreVariants",
},
{
@@ -46,7 +46,7 @@ const MAIN_CHOICES = [
value: "watch",
},
{
- name: "Display server logs",
+ name: "Display logs",
value: "logs",
},
];
@@ -64,10 +64,10 @@ const QUESTIONS = {
name: "value",
choices: ["silly", "debug", "verbose", "info", "warn", "error"],
},
- mock: {
+ collection: {
type: "autocomplete",
name: "value",
- message: "Please choose mock",
+ message: "Please choose collection",
},
variant: {
type: "autocomplete",
@@ -100,7 +100,7 @@ const getQuestions = () => {
const SCREENS = {
MAIN: "main",
- MOCK: "mock",
+ COLLECTION: "collection",
DELAY: "delay",
LOG_LEVEL: "log-level",
LOGS: "logs",
@@ -109,7 +109,7 @@ const SCREENS = {
const OPTIONS = [
{
name: "enabled",
- description: "Start interactive CLI plugin or not",
+ description: "Start interactive CLI or not",
type: "boolean",
default: true,
},
@@ -126,13 +126,12 @@ class Cli {
return "inquirerCli";
}
- constructor({ config, alerts, mocks, onChangeAlerts, onChangeMocks, restartServer }) {
+ constructor({ config, alerts, mock, server }) {
this._alerts = alerts;
- this._restartServerMethod = restartServer;
+ this._server = server;
this._config = config;
- this._mocks = mocks;
- this._onChangeAlerts = onChangeAlerts;
- this._onChangeMocks = onChangeMocks;
+ this._mock = mock;
+
this._inited = false;
this._started = false;
this._currentScreen = null;
@@ -140,14 +139,21 @@ class Cli {
this._onChangeOptionEmojis = this._onChangeOptionEmojis.bind(this);
this._onChangeOptionCli = this._onChangeOptionCli.bind(this);
this._onChangeOptionLog = this._onChangeOptionLog.bind(this);
- this._refreshMenuIfStarted = this._refreshMenuIfStarted.bind(this);
+ this._refreshMenuIfStarted = debounce(this._refreshMenuIfStarted.bind(this), 200, {
+ maxWait: 1000,
+ });
this._optionCli = this._config.addOption(OPTIONS[0]);
this._optionEmojis = this._config.addOption(OPTIONS[1]);
this._optionLog = this._config.root.option("log");
- this._optionMock = this._config.root.namespace("mocks").option("selected");
- this._optionDelay = this._config.root.namespace("mocks").option("delay");
+ this._optionCollection = this._config.root
+ .namespace("mock")
+ .namespace("collections")
+ .option("selected");
+ this._optionDelay = this._config.root.namespace("mock").namespace("routes").option("delay");
+ // LEGACY, to be removed
+ this._optionDelayLegacy = this._config.root.namespace("mocks").option("delay");
this._optionPort = this._config.root.namespace("server").option("port");
this._optionHost = this._config.root.namespace("server").option("host");
this._optionWatch = this._config.root.namespace("files").option("watch");
@@ -163,7 +169,7 @@ class Cli {
this._optionCli.onChange(this._onChangeOptionCli);
this._optionLog.onChange(this._onChangeOptionLog);
- this._optionMock.onChange(this._refreshMenuIfStarted);
+ this._optionCollection.onChange(this._refreshMenuIfStarted);
this._optionDelay.onChange(this._refreshMenuIfStarted);
this._optionHost.onChange(this._refreshMenuIfStarted);
this._optionWatch.onChange(this._refreshMenuIfStarted);
@@ -181,8 +187,8 @@ class Cli {
return Promise.resolve();
}
this._started = true;
- this._stopListeningChangeAlerts = this._onChangeAlerts(this._refreshMenuIfStarted);
- this._stopListeningChangeMocks = this._onChangeMocks(this._refreshMenuIfStarted);
+ this._stopListeningChangeAlerts = this._alerts.root.onChange(this._refreshMenuIfStarted);
+ this._stopListeningChangeMocks = this._mock.onChange(this._refreshMenuIfStarted);
this._logLevel = this._optionLog.value;
this._silentTraces();
this._displayMainMenu();
@@ -254,33 +260,31 @@ class Cli {
}
_header() {
- const delay = this._optionDelay.value;
+ const delay = this._optionDelay.hasBeenSet
+ ? this._optionDelay.value
+ : this._optionDelayLegacy.value;
const watchEnabled = this._optionWatch.value;
- const currentMock = this._mocks.current || "-";
- const availableMocks = this._mocks.plainMocks.length;
- const availableRoutes = this._mocks.plainRoutes.length;
- const availableRoutesVariants = this._mocks.plainRoutesVariants.length;
+ const currentCollection = this._mock.collections.selected || "-";
+ const availableCollections = this._mock.collections.plain.length;
+ const availableRoutes = this._mock.routes.plain.length;
+ const availableRoutesVariants = this._mock.routes.plainVariants.length;
- const currentMockMessage = this._mocks.customRoutesVariants.length
- ? `${currentMock} (custom variants: ${this._mocks.customRoutesVariants.join(",")})`
- : currentMock;
+ const currentCollectionMessage = this._mock.customRouteVariants.length
+ ? `${currentCollection} (custom variants: ${this._mock.customRouteVariants.join(",")})`
+ : currentCollection;
return [
- renderHeader(`Mocks server listening at`, this._serverUrl),
+ renderHeader(`Server listening at`, this._serverUrl),
renderHeader(`Delay`, delay, delay > 0 ? 1 : 0),
renderHeader(
- `Current mock`,
- currentMockMessage,
- getCurrentMockMessageLevel(this._mocks.customRoutesVariants, currentMock)
+ `Current collection`,
+ currentCollectionMessage,
+ getCurrentMockMessageLevel(this._mock.customRouteVariants, currentCollection)
),
- renderHeader(`Mocks`, availableMocks, availableMocks < 1 ? 2 : 0),
+ renderHeader(`Collections`, availableCollections, availableCollections < 1 ? 2 : 0),
renderHeader(`Routes`, availableRoutes, availableRoutes < 1 ? 2 : 0),
- renderHeader(
- `Routes variants`,
- availableRoutesVariants,
- availableRoutesVariants < 1 ? 2 : 0
- ),
+ renderHeader(`Route variants`, availableRoutesVariants, availableRoutesVariants < 1 ? 2 : 0),
renderHeader(`Log level`, this._logLevel),
renderHeader(`Watch enabled`, watchEnabled, !!watchEnabled ? 0 : 1),
];
@@ -297,12 +301,12 @@ class Cli {
this._currentScreen = SCREENS.MAIN;
const action = await this._cli.inquire("main");
switch (action) {
- case "mock":
- return this._changeCurrentMock();
+ case "collection":
+ return this._changeCurrentCollection();
case "variant":
return this._changeRouteVariant();
case "restoreVariants":
- return this._restoreRoutesVariants();
+ return this._restoreRouteVariants();
case "delay":
return this._changeDelay();
case "restart":
@@ -316,29 +320,31 @@ class Cli {
}
}
- async _changeCurrentMock() {
- this._currentScreen = SCREENS.MOCK;
+ async _changeCurrentCollection() {
+ this._currentScreen = SCREENS.COLLECTION;
this._cli.clearScreen();
- const mocksIds = this._mocks.ids;
- if (!mocksIds.length) {
+ const collectionsIds = this._mock.collections.ids;
+ if (!collectionsIds.length) {
return this._displayMainMenu();
}
- const mockId = await this._cli.inquire("mock", {
+ const collectionId = await this._cli.inquire("collection", {
source: (_answers, input) => {
if (!input || !input.length) {
- return Promise.resolve(mocksIds);
+ return Promise.resolve(collectionsIds);
}
- return Promise.resolve(mocksIds.filter((currentMock) => currentMock.includes(input)));
+ return Promise.resolve(
+ collectionsIds.filter((currentCollection) => currentCollection.includes(input))
+ );
},
});
- this._optionMock.value = mockId;
+ this._optionCollection.value = collectionId;
return this._displayMainMenu();
}
async _changeRouteVariant() {
- this._currentScreen = SCREENS.MOCK;
+ this._currentScreen = SCREENS.COLLECTION;
this._cli.clearScreen();
- const routeVariantsIds = this._mocks.plainRoutesVariants.map((variant) => variant.id);
+ const routeVariantsIds = this._mock.routes.plainVariants.map((variant) => variant.id);
if (!routeVariantsIds.length) {
return this._displayMainMenu();
}
@@ -350,12 +356,12 @@ class Cli {
return Promise.resolve(routeVariantsIds.filter((variant) => variant.includes(input)));
},
});
- this._mocks.useRouteVariant(variantId);
+ this._mock.useRouteVariant(variantId);
return this._displayMainMenu();
}
- async _restoreRoutesVariants() {
- this._mocks.restoreRoutesVariants();
+ async _restoreRouteVariants() {
+ this._mock.restoreRouteVariants();
return this._displayMainMenu();
}
@@ -369,7 +375,7 @@ class Cli {
async _restartServer() {
try {
- await this._restartServerMethod();
+ await this._server.restart();
} catch (err) {}
return this._displayMainMenu();
}
diff --git a/packages/plugin-inquirer-cli/src/Inquirer.js b/packages/plugin-inquirer-cli/src/Inquirer.js
index a83dd624e..db5f28de4 100644
--- a/packages/plugin-inquirer-cli/src/Inquirer.js
+++ b/packages/plugin-inquirer-cli/src/Inquirer.js
@@ -41,7 +41,7 @@ const QUIT_QUESTION = {
const exitProcess = () => process.exit();
-require("events").EventEmitter.defaultMaxListeners = 100;
+require("events").EventEmitter.defaultMaxListeners = 1000;
const Inquirer = class Inquirer {
constructor(header, alerts, options = {}) {
diff --git a/packages/plugin-inquirer-cli/test/Core.mocks.js b/packages/plugin-inquirer-cli/test/Core.mocks.js
index 2483d6b98..6810c535c 100644
--- a/packages/plugin-inquirer-cli/test/Core.mocks.js
+++ b/packages/plugin-inquirer-cli/test/Core.mocks.js
@@ -30,23 +30,37 @@ class CoreMock {
stop: this._sandbox.stub().resolves(),
restartServer: this._sandbox.stub().resolves(),
onChangeAlerts: this._sandbox.stub().returns(doNothing),
- onChangeMocks: this._sandbox.stub().returns(doNothing),
addRouter: this._sandbox.stub(),
addSetting: this._sandbox.stub(),
- mocks: {
+ mock: {
current: "foo-current",
plainMocks: [],
plainRoutes: [],
plainRoutesVariants: [],
customRoutesVariants: [],
+ customRouteVariants: [],
ids: [],
useRouteVariant: this._sandbox.stub(),
- restoreRoutesVariants: this._sandbox.stub(),
+ restoreRouteVariants: this._sandbox.stub(),
+ onChange: this._sandbox.stub().returns(doNothing),
+ routes: {
+ plain: [],
+ plainVariants: [],
+ },
+ collections: {
+ selected: "foo-current",
+ ids: [],
+ plain: [],
+ },
+ },
+ server: {
+ restart: this._sandbox.stub(),
},
config: new ConfigMock().stubs.instance,
alerts: {
root: {
customFlat: [],
+ onChange: this._sandbox.stub().returns(doNothing),
},
},
serverError: null,
diff --git a/packages/plugin-inquirer-cli/test/src/Cli.spec.js b/packages/plugin-inquirer-cli/test/src/Cli.spec.js
index 503ad408a..4b5dd78b6 100644
--- a/packages/plugin-inquirer-cli/test/src/Cli.spec.js
+++ b/packages/plugin-inquirer-cli/test/src/Cli.spec.js
@@ -18,6 +18,14 @@ const ConfigMocks = require("../Config.mocks.js");
const Cli = require("../../src/Cli");
+function wait(time = 250) {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve();
+ }, time);
+ });
+}
+
describe("Cli", () => {
let sandbox;
let inquirerMocks;
@@ -29,9 +37,10 @@ describe("Cli", () => {
let optionEmojis;
let optionLog;
let optionDelay;
+ let optionDelayLegacy;
let optionHost;
let optionWatch;
- let optionMock;
+ let optionCollection;
let mockOptions;
let onChangeEmojis;
let cliArgs;
@@ -40,7 +49,7 @@ describe("Cli", () => {
let onChangeDelay;
let onChangeHost;
let onChangeWatch;
- let onChangeMock;
+ let onChangeCollection;
beforeEach(async () => {
sandbox = sinon.createSandbox();
@@ -50,10 +59,8 @@ describe("Cli", () => {
coreInstance = coreMocks.stubs.instance;
cliArgs = {
alerts: coreMocks.stubs.instance.alerts,
- mocks: coreMocks.stubs.instance.mocks,
- onChangeAlerts: coreMocks.stubs.instance.onChangeAlerts,
- onChangeMocks: coreMocks.stubs.instance.onChangeMocks,
- restartServer: coreMocks.stubs.instance.restartServer,
+ mock: coreMocks.stubs.instance.mock,
+ server: coreMocks.stubs.instance.server,
config: configMock.stubs.namespace,
};
cli = new Cli(cliArgs);
@@ -63,23 +70,25 @@ describe("Cli", () => {
onChangeDelay = sandbox.stub();
onChangeHost = sandbox.stub();
onChangeWatch = sandbox.stub();
- onChangeMock = sandbox.stub();
+ onChangeCollection = sandbox.stub();
expect.assertions(1);
mockOptions = () => {
optionCli = { ...cli._optionCli, onChange: onChangeCli, value: true };
optionEmojis = { ...cli._optionEmojis, onChange: onChangeEmojis, value: true };
optionLog = { ...cli._optionLog, onChange: onChangeLog, value: "info" };
optionDelay = { ...cli._optionDelay, onChange: onChangeDelay, value: 0 };
+ optionDelayLegacy = { ...cli._optionDelayLegacy, value: 0 };
optionHost = { ...cli._optionHost, onChange: onChangeHost, value: "0.0.0.0" };
optionWatch = { ...cli._optionWatch, onChange: onChangeWatch, value: true };
- optionMock = { ...cli._optionMock, onChange: onChangeMock, value: "base" };
+ optionCollection = { ...cli._optionCollection, onChange: onChangeCollection, value: "base" };
cli._optionEmojis = optionEmojis;
cli._optionDelay = optionDelay;
cli._optionCli = optionCli;
cli._optionLog = optionLog;
cli._optionHost = optionHost;
cli._optionWatch = optionWatch;
- cli._optionMock = optionMock;
+ cli._optionCollection = optionCollection;
+ cli._optionDelayLegacy = optionDelayLegacy;
};
mockOptions();
await cli.init();
@@ -127,6 +136,7 @@ describe("Cli", () => {
it("should refresh main menu when delay option is changed and current screen is main menu", async () => {
expect.assertions(2);
optionDelay.onChange.getCall(0).args[0]("foo");
+ await wait();
expect(inquirerMocks.stubs.inquirer.inquire.callCount).toEqual(2);
expect(inquirerMocks.stubs.inquirer.inquire.getCall(1).args[0]).toEqual("main");
});
@@ -134,6 +144,7 @@ describe("Cli", () => {
it("should refresh main menu when host option is changed and current screen is main menu", async () => {
expect.assertions(2);
optionHost.onChange.getCall(0).args[0]("foo");
+ await wait();
expect(inquirerMocks.stubs.inquirer.inquire.callCount).toEqual(2);
expect(inquirerMocks.stubs.inquirer.inquire.getCall(1).args[0]).toEqual("main");
});
@@ -141,6 +152,7 @@ describe("Cli", () => {
it("should refresh main menu when log option is changed and current screen is main menu", async () => {
expect.assertions(2);
onChangeLog.getCall(0).args[0]("foo");
+ await wait();
expect(inquirerMocks.stubs.inquirer.inquire.callCount).toEqual(2);
expect(inquirerMocks.stubs.inquirer.inquire.getCall(1).args[0]).toEqual("main");
});
@@ -148,13 +160,14 @@ describe("Cli", () => {
it("should refresh main menu when watch option is changed and current screen is main menu", async () => {
expect.assertions(2);
onChangeWatch.getCall(0).args[0](false);
+ await wait();
expect(inquirerMocks.stubs.inquirer.inquire.callCount).toEqual(2);
expect(inquirerMocks.stubs.inquirer.inquire.getCall(1).args[0]).toEqual("main");
});
- it("should not display main menu when mock is changed and current screen is not main menu", async () => {
+ it("should not display main menu when collection is changed and current screen is not main menu", async () => {
cli._currentScreen = "FOO";
- onChangeMock.getCall(0).args[0]("foo");
+ onChangeCollection.getCall(0).args[0]("foo");
expect(inquirerMocks.stubs.inquirer.inquire.callCount).toEqual(1);
});
@@ -162,7 +175,7 @@ describe("Cli", () => {
await cli.stop();
inquirerMocks.reset();
cli._currentScreen = "FOO";
- onChangeMock.getCall(0).args[0]("foo");
+ onChangeCollection.getCall(0).args[0]("foo");
expect(inquirerMocks.stubs.inquirer.inquire.callCount).toEqual(0);
});
@@ -238,6 +251,7 @@ describe("Cli", () => {
it("should refresh main menu when emojis option is changed and current screen is main menu", async () => {
expect.assertions(2);
onChangeEmojis.getCall(0).args[0](false);
+ await wait();
expect(inquirerMocks.stubs.inquirer.inquire.callCount).toEqual(2);
expect(inquirerMocks.stubs.inquirer.inquire.getCall(1).args[0]).toEqual("main");
});
@@ -256,7 +270,8 @@ describe("Cli", () => {
it("should refresh main menu", async () => {
expect.assertions(2);
- coreInstance.onChangeAlerts.getCall(0).args[0]();
+ coreInstance.alerts.root.onChange.getCall(0).args[0]();
+ await wait();
expect(inquirerMocks.stubs.inquirer.inquire.callCount).toEqual(2);
expect(inquirerMocks.stubs.inquirer.inquire.getCall(1).args[0]).toEqual("main");
});
@@ -306,8 +321,8 @@ describe("Cli", () => {
beforeEach(async () => {
removeChangeMocksSpy = sinon.spy();
removeChangeAlertsSpy = sinon.spy();
- coreInstance.onChangeAlerts.returns(removeChangeAlertsSpy);
- coreInstance.onChangeMocks.returns(removeChangeMocksSpy);
+ coreInstance.alerts.root.onChange.returns(removeChangeAlertsSpy);
+ coreInstance.mock.onChange.returns(removeChangeMocksSpy);
await cli.start();
});
@@ -336,19 +351,19 @@ describe("Cli", () => {
});
});
- describe('when user selects "Change current mock"', () => {
+ describe('when user selects "Select collection"', () => {
const fooSelectedMock = "foo mock";
let originalIds;
beforeEach(() => {
- originalIds = coreInstance.mocks.ids;
- coreInstance.mocks.ids = ["foo-mock"];
- inquirerMocks.stubs.inquirer.inquire.onCall(0).resolves("mock");
+ originalIds = coreInstance.mock.collections.ids;
+ coreInstance.mock.collections.ids = ["foo-mock"];
+ inquirerMocks.stubs.inquirer.inquire.onCall(0).resolves("collection");
inquirerMocks.stubs.inquirer.inquire.onCall(1).resolves(fooSelectedMock);
});
afterEach(() => {
- coreInstance.mocks.ids = originalIds;
+ coreInstance.mock.collections.ids = originalIds;
});
it("should call to clear screen", async () => {
@@ -356,56 +371,56 @@ describe("Cli", () => {
expect(inquirerMocks.stubs.inquirer.clearScreen.callCount).toEqual(3);
});
- it("should display main menu if there are no mocks", async () => {
- coreInstance.mocks.ids = [];
+ it("should display main menu if there are no collections", async () => {
+ coreInstance.mock.collections.ids = [];
await cli.start();
expect(inquirerMocks.stubs.inquirer.inquire.getCall(1).args[0]).toEqual("main");
});
- it("should call to display mock menu", async () => {
+ it("should call to display collections menu", async () => {
await cli.start();
- expect(inquirerMocks.stubs.inquirer.inquire.getCall(1).args[0]).toEqual("mock");
+ expect(inquirerMocks.stubs.inquirer.inquire.getCall(1).args[0]).toEqual("collection");
});
- it("should set current selected mock", async () => {
+ it("should set current selected collection", async () => {
await cli.start();
- expect(optionMock.value).toEqual(fooSelectedMock);
+ expect(optionCollection.value).toEqual(fooSelectedMock);
});
- it("should not filter current mocks if there is no input", async () => {
+ it("should not filter current collections if there is no input", async () => {
const fooMocks = ["foo1", "foo2"];
inquirerMocks.stubs.inquirer.inquireFake.executeCb(true);
inquirerMocks.stubs.inquirer.inquireFake.returns(null);
inquirerMocks.stubs.inquirer.inquire
.onCall(0)
.callsFake(inquirerMocks.stubs.inquirer.inquireFake.runner);
- coreInstance.mocks.ids = fooMocks;
- await cli._changeCurrentMock();
- expect(optionMock.value).toEqual(["foo1", "foo2"]);
+ coreInstance.mock.collections.ids = fooMocks;
+ await cli._changeCurrentCollection();
+ expect(optionCollection.value).toEqual(["foo1", "foo2"]);
});
- it("should not filter current mocks if current input is empty", async () => {
+ it("should not filter current collections if current input is empty", async () => {
const fooMocks = ["foo1", "foo2"];
inquirerMocks.stubs.inquirer.inquireFake.executeCb(true);
inquirerMocks.stubs.inquirer.inquireFake.returns([]);
inquirerMocks.stubs.inquirer.inquire
.onCall(0)
.callsFake(inquirerMocks.stubs.inquirer.inquireFake.runner);
- coreInstance.mocks.ids = fooMocks;
- await cli._changeCurrentMock();
- expect(optionMock.value).toEqual(["foo1", "foo2"]);
+ coreInstance.mock.collections.ids = fooMocks;
+ await cli._changeCurrentCollection();
+ expect(optionCollection.value).toEqual(["foo1", "foo2"]);
});
- it("should filter current mocks and returns all that includes current input", async () => {
+ it("should filter current collections and returns all that includes current input", async () => {
const fooMocks = ["foo1", "foo2", "not-included"];
inquirerMocks.stubs.inquirer.inquireFake.executeCb(true);
inquirerMocks.stubs.inquirer.inquireFake.returns("foo");
inquirerMocks.stubs.inquirer.inquire
.onCall(0)
.callsFake(inquirerMocks.stubs.inquirer.inquireFake.runner);
- coreInstance.mocks.ids = fooMocks;
- await cli._changeCurrentMock();
- expect(optionMock.value).toEqual(["foo1", "foo2"]);
+ coreInstance.mock.collections.ids = fooMocks;
+ await cli._changeCurrentCollection();
+ expect(optionCollection.value).toEqual(["foo1", "foo2"]);
});
});
@@ -414,14 +429,14 @@ describe("Cli", () => {
let originalVariants;
beforeEach(() => {
- originalVariants = coreInstance.mocks.plainRoutesVariants;
- coreInstance.mocks.plainRoutesVariants = [{ id: "foo-variant" }];
+ originalVariants = coreInstance.mock.routes.plainVariants;
+ coreInstance.mock.routes.plainVariants = [{ id: "foo-variant" }];
inquirerMocks.stubs.inquirer.inquire.onCall(0).resolves("variant");
inquirerMocks.stubs.inquirer.inquire.onCall(1).resolves(fooSelectedVariant);
});
afterEach(() => {
- coreInstance.mocks.plainRoutesVariants = originalVariants;
+ coreInstance.mock.routes.plainVariants = originalVariants;
});
it("should call to clear screen", async () => {
@@ -430,7 +445,7 @@ describe("Cli", () => {
});
it("should display main menu if there are no routes variants", async () => {
- coreInstance.mocks.plainRoutesVariants = [];
+ coreInstance.mock.routes.plainVariants = [];
await cli.start();
expect(inquirerMocks.stubs.inquirer.inquire.getCall(1).args[0]).toEqual("main");
});
@@ -442,7 +457,7 @@ describe("Cli", () => {
it("should set current selected route variant", async () => {
await cli.start();
- expect(coreInstance.mocks.useRouteVariant.getCall(0).args).toEqual([fooSelectedVariant]);
+ expect(coreInstance.mock.useRouteVariant.getCall(0).args).toEqual([fooSelectedVariant]);
});
it("should not filter current routes variants if there is no input", async () => {
@@ -452,9 +467,9 @@ describe("Cli", () => {
inquirerMocks.stubs.inquirer.inquire
.onCall(0)
.callsFake(inquirerMocks.stubs.inquirer.inquireFake.runner);
- coreInstance.mocks.plainRoutesVariants = fooVariants;
+ coreInstance.mock.routes.plainVariants = fooVariants;
await cli._changeRouteVariant();
- expect(coreInstance.mocks.useRouteVariant.getCall(0).args).toEqual([["foo1", "foo2"]]);
+ expect(coreInstance.mock.useRouteVariant.getCall(0).args).toEqual([["foo1", "foo2"]]);
});
it("should not filter current routes variants if current input is empty", async () => {
@@ -464,9 +479,9 @@ describe("Cli", () => {
inquirerMocks.stubs.inquirer.inquire
.onCall(0)
.callsFake(inquirerMocks.stubs.inquirer.inquireFake.runner);
- coreInstance.mocks.plainRoutesVariants = fooVariants;
+ coreInstance.mock.routes.plainVariants = fooVariants;
await cli._changeRouteVariant();
- expect(coreInstance.mocks.useRouteVariant.getCall(0).args).toEqual([["foo1", "foo2"]]);
+ expect(coreInstance.mock.useRouteVariant.getCall(0).args).toEqual([["foo1", "foo2"]]);
});
it("should filter current variants and returns all that includes current input", async () => {
@@ -476,9 +491,9 @@ describe("Cli", () => {
inquirerMocks.stubs.inquirer.inquire
.onCall(0)
.callsFake(inquirerMocks.stubs.inquirer.inquireFake.runner);
- coreInstance.mocks.plainRoutesVariants = fooVariants;
+ coreInstance.mock.routes.plainVariants = fooVariants;
await cli._changeRouteVariant();
- expect(coreInstance.mocks.useRouteVariant.getCall(0).args).toEqual([["foo1", "foo2"]]);
+ expect(coreInstance.mock.useRouteVariant.getCall(0).args).toEqual([["foo1", "foo2"]]);
});
});
@@ -526,7 +541,7 @@ describe("Cli", () => {
it("should call to restart server", async () => {
await cli.start();
- expect(coreInstance.restartServer.callCount).toEqual(1);
+ expect(coreInstance.server.restart.callCount).toEqual(1);
});
});
@@ -537,7 +552,7 @@ describe("Cli", () => {
it("should call to restore variants", async () => {
await cli.start();
- expect(coreInstance.mocks.restoreRoutesVariants.callCount).toEqual(1);
+ expect(coreInstance.mock.restoreRouteVariants.callCount).toEqual(1);
});
});
@@ -607,7 +622,7 @@ describe("Cli", () => {
describe("when printing header", () => {
it("should print server url as first element", async () => {
await cli.start();
- expect(cli._header()[0]).toEqual(expect.stringContaining("Mocks server listening"));
+ expect(cli._header()[0]).toEqual(expect.stringContaining("Server listening"));
});
it("should print localhost as host when it is 0.0.0.0", async () => {
@@ -623,44 +638,53 @@ describe("Cli", () => {
});
it("should print delay in yellow if is greater than 0", async () => {
+ optionDelay.hasBeenSet = true;
optionDelay.value = 1000;
await cli.start();
expect(cli._header()[1]).toEqual(expect.stringContaining(chalk.yellow("1000")));
});
+ it("should print legacy delay in yellow if is greater than 0", async () => {
+ optionDelay.hasBeenSet = false;
+ optionDelayLegacy.value = 1000;
+ await cli.start();
+ expect(cli._header()[1]).toEqual(expect.stringContaining(chalk.yellow("1000")));
+ });
+
it("should print delay in green if is equal to 0", async () => {
+ optionDelay.hasBeenSet = true;
optionDelay.value = 0;
await cli.start();
expect(cli._header()[1]).toEqual(expect.stringContaining(chalk.green("0")));
});
it("should print mocks in red if are equal to 0", async () => {
- coreInstance.mocks.plainMocks = [];
+ coreInstance.mock.collections.plain = [];
await cli.start();
expect(cli._header()[3]).toEqual(expect.stringContaining(chalk.red("0")));
});
it("should print mocks in green if are greater than 0", async () => {
- coreInstance.mocks.plainMocks = [{}, {}, {}, {}];
+ coreInstance.mock.collections.plain = [{}, {}, {}, {}];
await cli.start();
expect(cli._header()[3]).toEqual(expect.stringContaining(chalk.green("4")));
});
it("should print current mock in red if it is null", async () => {
- coreInstance.mocks.current = null;
+ coreInstance.mock.collections.selected = null;
await cli.start();
expect(cli._header()[2]).toEqual(expect.stringContaining(chalk.red("-")));
});
it("should print current mock in green if it is defined", async () => {
- coreInstance.mocks.current = "foo";
+ coreInstance.mock.collections.selected = "foo";
await cli.start();
expect(cli._header()[2]).toEqual(expect.stringContaining(chalk.green("foo")));
});
it("should print current mock in yellow if there are custom routes variants", async () => {
- coreInstance.mocks.current = "foo";
- coreInstance.mocks.customRoutesVariants = ["foo-variant", "foo-variant-2"];
+ coreInstance.mock.collections.selected = "foo";
+ coreInstance.mock.customRouteVariants = ["foo-variant", "foo-variant-2"];
await cli.start();
expect(cli._header()[2]).toEqual(
expect.stringContaining(chalk.yellow("foo (custom variants: foo-variant,foo-variant-2)"))
@@ -668,25 +692,25 @@ describe("Cli", () => {
});
it("should print current routes in red if there are less than 1", async () => {
- coreInstance.mocks.plainRoutes = [];
+ coreInstance.mock.routes.plain = [];
await cli.start();
expect(cli._header()[4]).toEqual(expect.stringContaining(chalk.red("0")));
});
it("should print current routes in green if there are less than 1", async () => {
- coreInstance.mocks.plainRoutes = [{}, {}];
+ coreInstance.mock.routes.plain = [{}, {}];
await cli.start();
expect(cli._header()[4]).toEqual(expect.stringContaining(chalk.green("2")));
});
it("should print current routes variants in red if there are less than 1", async () => {
- coreInstance.mocks.plainRoutesVariants = [];
+ coreInstance.mock.routes.plainVariants = [];
await cli.start();
expect(cli._header()[5]).toEqual(expect.stringContaining(chalk.red("0")));
});
it("should not print current routes in green if there are more than 1", async () => {
- coreInstance.mocks.plainRoutesVariants = [{}, {}];
+ coreInstance.mock.routes.plainVariants = [{}, {}];
await cli.start();
expect(cli._header()[5]).toEqual(expect.stringContaining(chalk.green("2")));
});
@@ -706,7 +730,7 @@ describe("Cli", () => {
describe("when displaying alerts", () => {
it("should not display alerts if core alerts are empty", async () => {
- coreInstance.alerts = [];
+ coreInstance.alerts.root.customFlat = [];
await cli.start();
expect(cli._alertsHeader().length).toEqual(0);
});
@@ -757,13 +781,14 @@ describe("Cli", () => {
});
});
- describe("when server emits change:mocks event", () => {
+ describe("when server emits change:mock event", () => {
beforeEach(async () => {
await cli.start();
- coreInstance.onChangeMocks.getCall(0).args[0]();
+ coreInstance.mock.onChange.getCall(0).args[0]();
});
it("should exit logs mode", async () => {
+ await wait();
expect(inquirerMocks.stubs.inquirer.exitLogsMode.callCount).toEqual(2);
});
});
diff --git a/packages/plugin-proxy/CHANGELOG.md b/packages/plugin-proxy/CHANGELOG.md
index ee5e7bb83..81b044a36 100644
--- a/packages/plugin-proxy/CHANGELOG.md
+++ b/packages/plugin-proxy/CHANGELOG.md
@@ -12,6 +12,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
### Removed
+## [3.1.0] - 2022-07-22
+
+### Changed
+
+- refactor: Use new core method `variantHandlers.register` instead of the deprecated `addRoutesHandler`
+
## [3.0.0] - 2022-07-05
### Changed
diff --git a/packages/plugin-proxy/README.md b/packages/plugin-proxy/README.md
index f10305e43..f1959a1be 100644
--- a/packages/plugin-proxy/README.md
+++ b/packages/plugin-proxy/README.md
@@ -13,7 +13,7 @@
# Mocks Server Plugin Proxy
-Plugin for [Mocks Server][website-url] that provides a [route handler](https://www.mocks-server.org/docs/api-routes-handler) that proxy requests to another host and pass response back to original caller.
+Plugin for [Mocks Server][website-url] that provides a [variant handler](https://www.mocks-server.org/docs/variant-handlers/intro) that proxy requests to another host and pass response back to original caller.
It uses the [express-http-proxy](https://github.com/villadora/express-http-proxy) package under the hood, and supports all of its options.
@@ -25,7 +25,7 @@ This plugin is included in the [main distribution of the Mocks Server project][m
### Proxy routes
-If you want a [route variant](https://www.mocks-server.org/docs/get-started-routes) to use the `proxy-v4` handler, define its `handler` property as "proxy-v4". Use the `host` property to set the host for the route, and the `options` property to set any of the [express-http-proxy](https://github.com/villadora/express-http-proxy) options.
+If you want a [route variant](https://www.mocks-server.org/docs/usage/variants) to use the `proxy-v4` handler, define its `handler` property as "proxy-v4". Use the `host` property to set the host for the route, and the `options` property to set any of the [express-http-proxy](https://github.com/villadora/express-http-proxy) options.
```js
module.exports = [
@@ -36,8 +36,8 @@ module.exports = [
variants: [
{
id: "proxy-to-google",
- handler: "proxy-v4", // This route variant will use the "proxy" handler from this plugin
- response: {
+ type: "proxy-v4", // This route variant will use the "proxy" handler from this plugin
+ options: {
host: "https://www.google.com", // proxy host
options: {}, // Options for express-http-proxy
},
@@ -49,7 +49,7 @@ module.exports = [
### Options
-Here are listed the specific properties that can be defined in a `proxy-v4` route variant. They must be defined in the `response` property of the variant:
+Here are listed the specific properties that can be defined in a `proxy-v4` route variant. They must be defined in the `options` property of the variant:
* __`host`__ _(String|Function)_: The proxy host. Equivalent to the [`express-http-proxy` `host` option](https://github.com/villadora/express-http-proxy#host), so it can also be a function.
* __`options`__ _(Object)_: Object containing any of the [options supported by the `express-http-proxy` package](https://github.com/villadora/express-http-proxy#options). Some of them are:
@@ -63,7 +63,7 @@ Here are listed the specific properties that can be defined in a `proxy-v4` rout
### Proxy routes
-If you want a Mocks Server v3 [route variant](https://www.mocks-server.org/docs/get-started-routes) to use the `proxy` handler, define its `handler` property as "proxy". Use the `host` property to set the host for the route, and the `options` property to set any of the [express-http-proxy](https://github.com/villadora/express-http-proxy) options.
+If you want a Mocks Server v3 [route variant](https://www.mocks-server.org/docs/usage/variants) to use the `proxy` handler, define its `type` property as "proxy". Use the `host` property to set the host for the route, and the `options` property to set any of the [express-http-proxy](https://github.com/villadora/express-http-proxy) options.
```js
module.exports = [
@@ -74,7 +74,7 @@ module.exports = [
variants: [
{
id: "proxy-to-google",
- handler: "proxy", // This route variant will use the "proxy" handler from this plugin
+ type: "proxy", // This route variant will use the "proxy" handler from this plugin
host: "https://www.google.com", // proxy host
options: {}, // Options for express-http-proxy
},
@@ -87,9 +87,6 @@ module.exports = [
Mocks server common properties to all route handlers are in _cursive_. Specific properties of this plugin are in __bold__:
-* _`id`_ _(String)_: Id of the route variant.
-* _`handler`_ _(String)_: Must be "proxy" to let this plugin handle the route.
-* _`delay`_ _(Number|null)_: Milliseconds of delay for this variant.
* __`host`__ _(String|Function)_: The proxy host. Equivalent to the [`express-http-proxy` `host` option](https://github.com/villadora/express-http-proxy#host), so it can also be a function.
* __`options`__ _(Object)_: Object containing any of the [options supported by the `express-http-proxy` package](https://github.com/villadora/express-http-proxy#options). Some of them are:
* __filter__ _(Function)_: [`filter` option](https://github.com/villadora/express-http-proxy#filter-supports-promises) for `express-http-proxy`.
@@ -100,4 +97,4 @@ Mocks server common properties to all route handlers are in _cursive_. Specific
[website-url]: https://www.mocks-server.org
[main-distribution-url]: https://www.npmjs.com/package/@mocks-server/main
-[options-url]: https://www.mocks-server.org/docs/configuration-options
+[options-url]: https://www.mocks-server.org/docs/configuration/options
diff --git a/packages/plugin-proxy/jest.config.js b/packages/plugin-proxy/jest.config.js
index 788235c6d..59175af53 100644
--- a/packages/plugin-proxy/jest.config.js
+++ b/packages/plugin-proxy/jest.config.js
@@ -26,7 +26,7 @@ module.exports = {
// The glob patterns Jest uses to detect test files
testMatch: ["/test/**/*.spec.js"],
- // testMatch: ["/test/**/optionDelay.spec.js"],
+ // testMatch: ["/test/**/filters.spec.js"],
// The test environment that will be used for testing
testEnvironment: "node",
diff --git a/packages/plugin-proxy/package.json b/packages/plugin-proxy/package.json
index f406dd670..20c2ab3c0 100644
--- a/packages/plugin-proxy/package.json
+++ b/packages/plugin-proxy/package.json
@@ -1,7 +1,7 @@
{
"name": "@mocks-server/plugin-proxy",
- "version": "3.0.0",
- "description": "Mocks Server plugin providing http-proxy route handler",
+ "version": "3.1.0",
+ "description": "Mocks Server plugin providing proxy variant handler",
"keywords": [
"mocks-server-plugin",
"proxy",
@@ -33,7 +33,7 @@
"test:unit": "jest --runInBand"
},
"peerDependencies": {
- "@mocks-server/core": ">=3.5.0 <4.x"
+ "@mocks-server/core": ">=3.6.0 <4.x"
},
"dependencies": {
"express-http-proxy": "1.6.3"
diff --git a/packages/plugin-proxy/sonar-project.properties b/packages/plugin-proxy/sonar-project.properties
index 336150b4c..4cd6224a5 100644
--- a/packages/plugin-proxy/sonar-project.properties
+++ b/packages/plugin-proxy/sonar-project.properties
@@ -1,7 +1,7 @@
sonar.organization=mocks-server
sonar.projectKey=mocks-server_main_plugin-proxy
sonar.projectName=plugin-proxy
-sonar.projectVersion=3.0.0
+sonar.projectVersion=3.1.0
sonar.javascript.file.suffixes=.js
sonar.sourceEncoding=UTF-8
diff --git a/packages/plugin-proxy/src/Plugin.js b/packages/plugin-proxy/src/Plugin.js
index 464c6395d..c26d38a82 100644
--- a/packages/plugin-proxy/src/Plugin.js
+++ b/packages/plugin-proxy/src/Plugin.js
@@ -6,9 +6,8 @@ class Plugin {
return "proxyRoutesHandler";
}
- constructor({ addRoutesHandler }) {
- addRoutesHandler(ProxyRoutesHandler);
- addRoutesHandler(ProxyRoutesHandlerV4);
+ constructor({ variantHandlers }) {
+ variantHandlers.register([ProxyRoutesHandler, ProxyRoutesHandlerV4]);
}
}
diff --git a/packages/plugin-proxy/src/ProxyRoutesHandlerV4.js b/packages/plugin-proxy/src/ProxyRoutesHandlerV4.js
index 6e4d4cfa4..9b3dfcf33 100644
--- a/packages/plugin-proxy/src/ProxyRoutesHandlerV4.js
+++ b/packages/plugin-proxy/src/ProxyRoutesHandlerV4.js
@@ -31,12 +31,12 @@ class ProxyRoutesHandler {
};
}
- constructor(response, core) {
- this._response = response;
+ constructor(options, core) {
+ this._options = options;
this._core = core;
- this._host = this._response.host;
- this._options = this._response.options;
- this.middleware = httpProxy(this._host, this._options);
+ this._host = this._options.host;
+ this._optionsProxy = this._options.options;
+ this.middleware = httpProxy(this._host, this._optionsProxy);
}
get preview() {
diff --git a/packages/plugin-proxy/test/fixtures/host-2/mocks.js b/packages/plugin-proxy/test/fixtures/delay-legacy/collections.js
similarity index 54%
rename from packages/plugin-proxy/test/fixtures/host-2/mocks.js
rename to packages/plugin-proxy/test/fixtures/delay-legacy/collections.js
index 77b083681..1c624fa62 100644
--- a/packages/plugin-proxy/test/fixtures/host-2/mocks.js
+++ b/packages/plugin-proxy/test/fixtures/delay-legacy/collections.js
@@ -1,6 +1,6 @@
module.exports = [
{
id: "base",
- routesVariants: ["get-user:real"],
+ routes: ["proxy-all:enabled"],
},
];
diff --git a/packages/plugin-proxy/test/fixtures/docs-example/mocks.js b/packages/plugin-proxy/test/fixtures/delay/collections.js
similarity index 52%
rename from packages/plugin-proxy/test/fixtures/docs-example/mocks.js
rename to packages/plugin-proxy/test/fixtures/delay/collections.js
index eefbb4da7..1c624fa62 100644
--- a/packages/plugin-proxy/test/fixtures/docs-example/mocks.js
+++ b/packages/plugin-proxy/test/fixtures/delay/collections.js
@@ -1,6 +1,6 @@
module.exports = [
{
id: "base",
- routesVariants: ["proxy-all:enabled"],
+ routes: ["proxy-all:enabled"],
},
];
diff --git a/packages/plugin-proxy/test/fixtures/delay/routes/proxy.js b/packages/plugin-proxy/test/fixtures/delay/routes/proxy.js
index b608b995f..d2fa67c27 100644
--- a/packages/plugin-proxy/test/fixtures/delay/routes/proxy.js
+++ b/packages/plugin-proxy/test/fixtures/delay/routes/proxy.js
@@ -7,16 +7,16 @@ module.exports = [
{
id: "enabled",
delay: 1000,
- handler: "proxy-v4",
- response: {
+ type: "proxy-v4",
+ options: {
host: "http://127.0.0.1:3200",
options: {},
},
},
{
id: "disabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (_req, _res, next) => next(),
},
},
diff --git a/packages/plugin-proxy/test/fixtures/delay-legacy/mocks.js b/packages/plugin-proxy/test/fixtures/docs-example-legacy/collections.js
similarity index 52%
rename from packages/plugin-proxy/test/fixtures/delay-legacy/mocks.js
rename to packages/plugin-proxy/test/fixtures/docs-example-legacy/collections.js
index eefbb4da7..1c624fa62 100644
--- a/packages/plugin-proxy/test/fixtures/delay-legacy/mocks.js
+++ b/packages/plugin-proxy/test/fixtures/docs-example-legacy/collections.js
@@ -1,6 +1,6 @@
module.exports = [
{
id: "base",
- routesVariants: ["proxy-all:enabled"],
+ routes: ["proxy-all:enabled"],
},
];
diff --git a/packages/plugin-proxy/test/fixtures/docs-example-legacy/mocks.js b/packages/plugin-proxy/test/fixtures/docs-example-legacy/mocks.js
deleted file mode 100644
index eefbb4da7..000000000
--- a/packages/plugin-proxy/test/fixtures/docs-example-legacy/mocks.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = [
- {
- id: "base",
- routesVariants: ["proxy-all:enabled"],
- },
-];
diff --git a/packages/plugin-proxy/test/fixtures/delay/mocks.js b/packages/plugin-proxy/test/fixtures/docs-example/collections.js
similarity index 52%
rename from packages/plugin-proxy/test/fixtures/delay/mocks.js
rename to packages/plugin-proxy/test/fixtures/docs-example/collections.js
index eefbb4da7..1c624fa62 100644
--- a/packages/plugin-proxy/test/fixtures/delay/mocks.js
+++ b/packages/plugin-proxy/test/fixtures/docs-example/collections.js
@@ -1,6 +1,6 @@
module.exports = [
{
id: "base",
- routesVariants: ["proxy-all:enabled"],
+ routes: ["proxy-all:enabled"],
},
];
diff --git a/packages/plugin-proxy/test/fixtures/docs-example/routes/proxy.js b/packages/plugin-proxy/test/fixtures/docs-example/routes/proxy.js
index b22d21351..a7bb9779e 100644
--- a/packages/plugin-proxy/test/fixtures/docs-example/routes/proxy.js
+++ b/packages/plugin-proxy/test/fixtures/docs-example/routes/proxy.js
@@ -6,16 +6,16 @@ module.exports = [
variants: [
{
id: "enabled",
- handler: "proxy-v4",
- response: {
+ type: "proxy-v4",
+ options: {
host: "http://127.0.0.1:3200",
options: {},
},
},
{
id: "disabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (_req, _res, next) => next(),
},
},
diff --git a/packages/plugin-proxy/test/fixtures/filters-legacy/collections.js b/packages/plugin-proxy/test/fixtures/filters-legacy/collections.js
new file mode 100644
index 000000000..264544eef
--- /dev/null
+++ b/packages/plugin-proxy/test/fixtures/filters-legacy/collections.js
@@ -0,0 +1,6 @@
+module.exports = [
+ {
+ id: "base",
+ routes: ["proxy-all:enabled", "user-2:default"],
+ },
+];
diff --git a/packages/plugin-proxy/test/fixtures/filters-legacy/mocks.js b/packages/plugin-proxy/test/fixtures/filters-legacy/mocks.js
deleted file mode 100644
index 1cded4d47..000000000
--- a/packages/plugin-proxy/test/fixtures/filters-legacy/mocks.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = [
- {
- id: "base",
- routesVariants: ["proxy-all:enabled", "user-2:default"],
- },
-];
diff --git a/packages/plugin-proxy/test/fixtures/filters/collections.js b/packages/plugin-proxy/test/fixtures/filters/collections.js
new file mode 100644
index 000000000..264544eef
--- /dev/null
+++ b/packages/plugin-proxy/test/fixtures/filters/collections.js
@@ -0,0 +1,6 @@
+module.exports = [
+ {
+ id: "base",
+ routes: ["proxy-all:enabled", "user-2:default"],
+ },
+];
diff --git a/packages/plugin-proxy/test/fixtures/filters/mocks.js b/packages/plugin-proxy/test/fixtures/filters/mocks.js
deleted file mode 100644
index 1cded4d47..000000000
--- a/packages/plugin-proxy/test/fixtures/filters/mocks.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = [
- {
- id: "base",
- routesVariants: ["proxy-all:enabled", "user-2:default"],
- },
-];
diff --git a/packages/plugin-proxy/test/fixtures/filters/routes/proxy.js b/packages/plugin-proxy/test/fixtures/filters/routes/proxy.js
index c499b6a27..7e025b055 100644
--- a/packages/plugin-proxy/test/fixtures/filters/routes/proxy.js
+++ b/packages/plugin-proxy/test/fixtures/filters/routes/proxy.js
@@ -6,8 +6,8 @@ module.exports = [
variants: [
{
id: "enabled",
- handler: "proxy-v4",
- response: {
+ type: "proxy-v4",
+ options: {
host: "http://127.0.0.1:3200",
options: {
filter: (req) => {
@@ -18,8 +18,8 @@ module.exports = [
},
{
id: "disabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (_req, _res, next) => next(),
},
},
diff --git a/packages/plugin-proxy/test/fixtures/filters/routes/users.js b/packages/plugin-proxy/test/fixtures/filters/routes/users.js
index 997444e69..fb4e267d3 100644
--- a/packages/plugin-proxy/test/fixtures/filters/routes/users.js
+++ b/packages/plugin-proxy/test/fixtures/filters/routes/users.js
@@ -6,8 +6,8 @@ module.exports = [
variants: [
{
id: "default",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: {
id: 2,
diff --git a/packages/plugin-proxy/test/fixtures/host-2/collections.js b/packages/plugin-proxy/test/fixtures/host-2/collections.js
new file mode 100644
index 000000000..0f662e9cf
--- /dev/null
+++ b/packages/plugin-proxy/test/fixtures/host-2/collections.js
@@ -0,0 +1,6 @@
+module.exports = [
+ {
+ id: "base",
+ routes: ["get-user:real"],
+ },
+];
diff --git a/packages/plugin-proxy/test/fixtures/host-2/routes/user.js b/packages/plugin-proxy/test/fixtures/host-2/routes/user.js
index e7d0bbea6..4e30d4d98 100644
--- a/packages/plugin-proxy/test/fixtures/host-2/routes/user.js
+++ b/packages/plugin-proxy/test/fixtures/host-2/routes/user.js
@@ -8,18 +8,21 @@ module.exports = [
variants: [
{
id: "real",
- response: (req, res) => {
- const userId = req.params.id;
- const user = USERS.find((userData) => userData.id === Number(userId));
- if (user) {
- res.status(200);
- res.send(user);
- } else {
- res.status(404);
- res.send({
- message: "User not found",
- });
- }
+ type: "middleware",
+ options: {
+ middleware: (req, res) => {
+ const userId = req.params.id;
+ const user = USERS.find((userData) => userData.id === Number(userId));
+ if (user) {
+ res.status(200);
+ res.send(user);
+ } else {
+ res.status(404);
+ res.send({
+ message: "User not found",
+ });
+ }
+ },
},
},
],
diff --git a/packages/plugin-proxy/test/fixtures/host-function-legacy/collections.js b/packages/plugin-proxy/test/fixtures/host-function-legacy/collections.js
new file mode 100644
index 000000000..58483a67d
--- /dev/null
+++ b/packages/plugin-proxy/test/fixtures/host-function-legacy/collections.js
@@ -0,0 +1,6 @@
+module.exports = [
+ {
+ id: "base",
+ routes: ["proxy-user:enabled", "proxy-all:enabled"],
+ },
+];
diff --git a/packages/plugin-proxy/test/fixtures/host-function-legacy/mocks.js b/packages/plugin-proxy/test/fixtures/host-function-legacy/mocks.js
deleted file mode 100644
index 0606f2cc1..000000000
--- a/packages/plugin-proxy/test/fixtures/host-function-legacy/mocks.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = [
- {
- id: "base",
- routesVariants: ["proxy-user:enabled", "proxy-all:enabled"],
- },
-];
diff --git a/packages/plugin-proxy/test/fixtures/host-function/collections.js b/packages/plugin-proxy/test/fixtures/host-function/collections.js
new file mode 100644
index 000000000..58483a67d
--- /dev/null
+++ b/packages/plugin-proxy/test/fixtures/host-function/collections.js
@@ -0,0 +1,6 @@
+module.exports = [
+ {
+ id: "base",
+ routes: ["proxy-user:enabled", "proxy-all:enabled"],
+ },
+];
diff --git a/packages/plugin-proxy/test/fixtures/host-function/mocks.js b/packages/plugin-proxy/test/fixtures/host-function/mocks.js
deleted file mode 100644
index 0606f2cc1..000000000
--- a/packages/plugin-proxy/test/fixtures/host-function/mocks.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = [
- {
- id: "base",
- routesVariants: ["proxy-user:enabled", "proxy-all:enabled"],
- },
-];
diff --git a/packages/plugin-proxy/test/fixtures/host-function/routes/proxy.js b/packages/plugin-proxy/test/fixtures/host-function/routes/proxy.js
index c20b5b11c..354629108 100644
--- a/packages/plugin-proxy/test/fixtures/host-function/routes/proxy.js
+++ b/packages/plugin-proxy/test/fixtures/host-function/routes/proxy.js
@@ -6,8 +6,8 @@ module.exports = [
variants: [
{
id: "enabled",
- handler: "proxy-v4",
- response: {
+ type: "proxy-v4",
+ options: {
host: () => {
return "http://127.0.0.1:3200";
},
@@ -16,7 +16,10 @@ module.exports = [
},
{
id: "disabled",
- response: (_req, _res, next) => next(),
+ type: "middleware",
+ options: {
+ middleware: (_req, _res, next) => next(),
+ },
},
],
},
@@ -27,8 +30,8 @@ module.exports = [
variants: [
{
id: "enabled",
- handler: "proxy-v4",
- response: {
+ type: "proxy-v4",
+ options: {
host: () => {
return "http://127.0.0.1:3300";
},
diff --git a/packages/plugin-proxy/test/fixtures/host/collections.js b/packages/plugin-proxy/test/fixtures/host/collections.js
new file mode 100644
index 000000000..ad998ab51
--- /dev/null
+++ b/packages/plugin-proxy/test/fixtures/host/collections.js
@@ -0,0 +1,6 @@
+module.exports = [
+ {
+ id: "base",
+ routes: ["get-users:success", "get-user:real"],
+ },
+];
diff --git a/packages/plugin-proxy/test/fixtures/host/mocks.js b/packages/plugin-proxy/test/fixtures/host/mocks.js
deleted file mode 100644
index d538e7d76..000000000
--- a/packages/plugin-proxy/test/fixtures/host/mocks.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = [
- {
- id: "base",
- routesVariants: ["get-users:success", "get-user:real"],
- },
-];
diff --git a/packages/plugin-proxy/test/fixtures/host/routes/user.js b/packages/plugin-proxy/test/fixtures/host/routes/user.js
index e7d0bbea6..4e30d4d98 100644
--- a/packages/plugin-proxy/test/fixtures/host/routes/user.js
+++ b/packages/plugin-proxy/test/fixtures/host/routes/user.js
@@ -8,18 +8,21 @@ module.exports = [
variants: [
{
id: "real",
- response: (req, res) => {
- const userId = req.params.id;
- const user = USERS.find((userData) => userData.id === Number(userId));
- if (user) {
- res.status(200);
- res.send(user);
- } else {
- res.status(404);
- res.send({
- message: "User not found",
- });
- }
+ type: "middleware",
+ options: {
+ middleware: (req, res) => {
+ const userId = req.params.id;
+ const user = USERS.find((userData) => userData.id === Number(userId));
+ if (user) {
+ res.status(200);
+ res.send(user);
+ } else {
+ res.status(404);
+ res.send({
+ message: "User not found",
+ });
+ }
+ },
},
},
],
diff --git a/packages/plugin-proxy/test/fixtures/host/routes/users.js b/packages/plugin-proxy/test/fixtures/host/routes/users.js
index 605be6ebf..2be7b8564 100644
--- a/packages/plugin-proxy/test/fixtures/host/routes/users.js
+++ b/packages/plugin-proxy/test/fixtures/host/routes/users.js
@@ -8,7 +8,8 @@ module.exports = [
variants: [
{
id: "success",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS,
},
diff --git a/packages/plugin-proxy/test/fixtures/res-decorator-legacy/collections.js b/packages/plugin-proxy/test/fixtures/res-decorator-legacy/collections.js
new file mode 100644
index 000000000..1c624fa62
--- /dev/null
+++ b/packages/plugin-proxy/test/fixtures/res-decorator-legacy/collections.js
@@ -0,0 +1,6 @@
+module.exports = [
+ {
+ id: "base",
+ routes: ["proxy-all:enabled"],
+ },
+];
diff --git a/packages/plugin-proxy/test/fixtures/res-decorator-legacy/mocks.js b/packages/plugin-proxy/test/fixtures/res-decorator-legacy/mocks.js
deleted file mode 100644
index eefbb4da7..000000000
--- a/packages/plugin-proxy/test/fixtures/res-decorator-legacy/mocks.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = [
- {
- id: "base",
- routesVariants: ["proxy-all:enabled"],
- },
-];
diff --git a/packages/plugin-proxy/test/fixtures/res-decorator/collections.js b/packages/plugin-proxy/test/fixtures/res-decorator/collections.js
new file mode 100644
index 000000000..1c624fa62
--- /dev/null
+++ b/packages/plugin-proxy/test/fixtures/res-decorator/collections.js
@@ -0,0 +1,6 @@
+module.exports = [
+ {
+ id: "base",
+ routes: ["proxy-all:enabled"],
+ },
+];
diff --git a/packages/plugin-proxy/test/fixtures/res-decorator/mocks.js b/packages/plugin-proxy/test/fixtures/res-decorator/mocks.js
deleted file mode 100644
index eefbb4da7..000000000
--- a/packages/plugin-proxy/test/fixtures/res-decorator/mocks.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = [
- {
- id: "base",
- routesVariants: ["proxy-all:enabled"],
- },
-];
diff --git a/packages/plugin-proxy/test/fixtures/res-decorator/routes/proxy.js b/packages/plugin-proxy/test/fixtures/res-decorator/routes/proxy.js
index 65f5643e6..5cce6c224 100644
--- a/packages/plugin-proxy/test/fixtures/res-decorator/routes/proxy.js
+++ b/packages/plugin-proxy/test/fixtures/res-decorator/routes/proxy.js
@@ -13,8 +13,8 @@ module.exports = [
variants: [
{
id: "enabled",
- handler: "proxy-v4",
- response: {
+ type: "proxy-v4",
+ options: {
host: "http://127.0.0.1:3200",
options: {
userResDecorator: function (_proxyRes, proxyResData) {
@@ -33,8 +33,8 @@ module.exports = [
},
{
id: "disabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (_req, _res, next) => next(),
},
},
diff --git a/packages/plugin-proxy/test/optionDelay.spec.js b/packages/plugin-proxy/test/optionDelay.spec.js
index 1311745ff..1375bdf5a 100644
--- a/packages/plugin-proxy/test/optionDelay.spec.js
+++ b/packages/plugin-proxy/test/optionDelay.spec.js
@@ -13,8 +13,10 @@ describe("when using delay option in server", () => {
beforeAll(async () => {
host = await startHost();
server = await startServer("docs-example", {
- mocks: {
- delay: 1000,
+ mock: {
+ routes: {
+ delay: 1000,
+ },
},
});
await waitForHost();
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index eff8700f1..63f83574f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -17,7 +17,7 @@ importers:
'@rollup/plugin-babel': 5.3.1
'@rollup/plugin-commonjs': 21.1.0
'@rollup/plugin-node-resolve': 13.3.0
- '@testing-library/cypress': 8.0.2
+ '@testing-library/cypress': 8.0.3
'@typescript-eslint/eslint-plugin': 5.26.0
'@typescript-eslint/parser': 5.27.0
babel-jest: 27.5.1
@@ -75,7 +75,7 @@ importers:
'@rollup/plugin-babel': 5.3.1_e931bf24091652160a0c732af432d11d
'@rollup/plugin-commonjs': 21.1.0_rollup@2.73.0
'@rollup/plugin-node-resolve': 13.3.0_rollup@2.73.0
- '@testing-library/cypress': 8.0.2_cypress@9.7.0
+ '@testing-library/cypress': 8.0.3_cypress@9.7.0
'@typescript-eslint/eslint-plugin': 5.26.0_ebf6867741f3398a69467d87ff4602a6
'@typescript-eslint/parser': 5.27.0_eslint@8.19.0+typescript@4.6.4
babel-jest: 27.5.1_@babel+core@7.17.10
@@ -231,14 +231,14 @@ importers:
express: 4.18.1
express-request-id: 1.4.1
fs-extra: 10.1.0
- globule: 1.3.3
+ globule: 1.3.4
handlebars: 4.7.7
is-promise: 4.0.0
lodash: 4.17.21
node-watch: 0.7.3
update-notifier: 5.1.0
winston: 3.7.2
- winston-array-transport: 1.1.9
+ winston-array-transport: 1.1.10
dependencies:
'@babel/register': 7.17.7_@babel+core@7.17.10
'@hapi/boom': 9.1.4
@@ -253,14 +253,14 @@ importers:
express: 4.18.1
express-request-id: 1.4.1
fs-extra: 10.1.0
- globule: 1.3.3
+ globule: 1.3.4
handlebars: 4.7.7
is-promise: 4.0.0
lodash: 4.17.21
node-watch: 0.7.3
update-notifier: 5.1.0
winston: 3.7.2
- winston-array-transport: 1.1.9
+ winston-array-transport: 1.1.10
packages/cypress-commands:
specifiers:
@@ -291,12 +291,14 @@ importers:
'@mocks-server/plugin-admin-api': workspace:*
'@mocks-server/plugin-inquirer-cli': workspace:*
'@mocks-server/plugin-proxy': workspace:*
+ deepmerge: 4.2.2
dependencies:
'@babel/core': 7.17.10
'@mocks-server/core': link:../core
'@mocks-server/plugin-admin-api': link:../plugin-admin-api
'@mocks-server/plugin-inquirer-cli': link:../plugin-inquirer-cli
'@mocks-server/plugin-proxy': link:../plugin-proxy
+ deepmerge: 4.2.2
packages/nested-collections:
specifiers: {}
@@ -306,13 +308,19 @@ importers:
'@hapi/boom': 9.1.4
'@mocks-server/admin-api-paths': workspace:*
'@mocks-server/core': workspace:*
+ body-parser: 1.20.0
cors: 2.8.5
express: 4.18.1
+ express-request-id: 1.4.1
+ swagger-ui-dist: 4.13.0
dependencies:
'@hapi/boom': 9.1.4
'@mocks-server/admin-api-paths': link:../admin-api-paths
+ body-parser: 1.20.0
cors: 2.8.5
express: 4.18.1
+ express-request-id: 1.4.1
+ swagger-ui-dist: 4.13.0
devDependencies:
'@mocks-server/core': link:../core
@@ -405,6 +413,12 @@ importers:
'@mocks-server/inquirer-cli-runner': link:../../packages/inquirer-cli-runner
'@mocks-server/main': link:../../packages/main
+ test/plugin-admin-api-swagger-e2e:
+ specifiers:
+ '@mocks-server/main': workspace:*
+ dependencies:
+ '@mocks-server/main': link:../../packages/main
+
test/plugin-inquirer-cli-e2e:
specifiers:
'@mocks-server/cli-runner': workspace:*
@@ -3355,11 +3369,11 @@ packages:
defer-to-connect: 1.1.3
dev: false
- /@testing-library/cypress/8.0.2_cypress@9.7.0:
- resolution: {integrity: sha512-KVdm7n37sg/A4e3wKMD4zUl0NpzzVhx06V9Tf0hZHZ7nrZ4yFva6Zwg2EFF1VzHkEfN/ahUzRtT1qiW+vuWnJw==}
+ /@testing-library/cypress/8.0.3_cypress@9.7.0:
+ resolution: {integrity: sha512-nY2YaSbmuPo5k6kL0iLj/pGPPfka3iwb3kpTx8QN/vOCns92Saz9wfACqB8FJzcR7+lfA4d5HUOWqmTddBzczg==}
engines: {node: '>=12', npm: '>=6'}
peerDependencies:
- cypress: ^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
+ cypress: ^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0
dependencies:
'@babel/runtime': 7.17.8
'@testing-library/dom': 8.11.4
@@ -6100,7 +6114,7 @@ packages:
dev: true
/concat-map/0.0.1:
- resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
/concat-stream/1.6.2:
resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
@@ -8646,7 +8660,7 @@ packages:
dev: true
/fs.realpath/1.0.0:
- resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=}
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
/fsevents/1.2.13:
resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==}
@@ -8868,8 +8882,8 @@ packages:
pinkie-promise: 2.0.1
dev: true
- /globule/1.3.3:
- resolution: {integrity: sha512-mb1aYtDbIjTu4ShMB85m3UzjX9BVKe9WCzsnfMSZk+K5GpIbBOexgg4PPCt5eHDEG5/ZQAUX2Kct02zfiPLsKg==}
+ /globule/1.3.4:
+ resolution: {integrity: sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==}
engines: {node: '>= 0.10'}
dependencies:
glob: 7.1.7
@@ -9372,7 +9386,7 @@ packages:
dev: true
/inflight/1.0.6:
- resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=}
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
dependencies:
once: 1.4.0
wrappy: 1.0.2
@@ -11551,7 +11565,7 @@ packages:
yallist: 4.0.0
/lz-string/1.4.4:
- resolution: {integrity: sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=}
+ resolution: {integrity: sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==}
hasBin: true
dev: true
@@ -12590,7 +12604,7 @@ packages:
dev: true
/path-is-absolute/1.0.1:
- resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=}
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
/path-is-inside/1.0.2:
@@ -15518,6 +15532,10 @@ packages:
util.promisify: 1.0.1
dev: true
+ /swagger-ui-dist/4.13.0:
+ resolution: {integrity: sha512-5yqhkUU9uV5oT/MTMBeSgDGI0Vx6eCOU43AszQBs88poI8OB1v+FoXEFHv+NaBbEfTkXCMWlAJrH6iWyDzLETQ==}
+ dev: false
+
/symbol-tree/3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
dev: true
@@ -16037,7 +16055,7 @@ packages:
engines: {node: '>= 10.0.0'}
/unpipe/1.0.0:
- resolution: {integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=}
+ resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
engines: {node: '>= 0.8'}
/unquote/1.1.1:
@@ -16604,13 +16622,6 @@ packages:
winston-transport: 4.5.0
dev: false
- /winston-array-transport/1.1.9:
- resolution: {integrity: sha512-KBh1dlSuP8N3Whq5XQDO1eC9SsUbsukPLsL2rcJx3qFK2fKiQba2PFxoHPhGn1mvrVxAoW8SM3nbEvADj32c6A==}
- engines: {node: '>=10'}
- dependencies:
- winston-transport: 4.5.0
- dev: false
-
/winston-transport/4.5.0:
resolution: {integrity: sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==}
engines: {node: '>= 6.4.0'}
diff --git a/test/admin-api-client-data-provider-e2e-specs/cypress/integration/about.js b/test/admin-api-client-data-provider-e2e-specs/cypress/integration/about.js
index 8c277b18f..ad2942d2f 100644
--- a/test/admin-api-client-data-provider-e2e-specs/cypress/integration/about.js
+++ b/test/admin-api-client-data-provider-e2e-specs/cypress/integration/about.js
@@ -1,14 +1,21 @@
describe("About section", () => {
const SELECTORS = {
- VERSION: "about-version",
+ CORE_VERSION: "about-version-core",
+ ADMINAPI_VERSION: "about-version-adminApi",
};
before(() => {
cy.visit("/");
});
- it("should display current version", () => {
- cy.findByTestId(SELECTORS.VERSION)
+ it("should display current core version", () => {
+ cy.findByTestId(SELECTORS.CORE_VERSION)
+ .invoke("text")
+ .should("match", /^(?:\d+\.)(?:\d+\.)(?:\*|\d+)$/);
+ });
+
+ it("should display current core version", () => {
+ cy.findByTestId(SELECTORS.ADMINAPI_VERSION)
.invoke("text")
.should("match", /^(?:\d+\.)(?:\d+\.)(?:\*|\d+)$/);
});
diff --git a/test/admin-api-client-data-provider-e2e-specs/cypress/integration/collectionsAndVariants.js b/test/admin-api-client-data-provider-e2e-specs/cypress/integration/collectionsAndVariants.js
new file mode 100644
index 000000000..51619c6ff
--- /dev/null
+++ b/test/admin-api-client-data-provider-e2e-specs/cypress/integration/collectionsAndVariants.js
@@ -0,0 +1,50 @@
+describe("collections and routeVariants", () => {
+ const SELECTORS = {
+ COLLECTIONS_COLLECTION_ITEM: ".collections-collection-item",
+ ROUTES_COLLECTION_ITEM: ".routes-collection-item",
+ CURRENT_COLLECTION: "current-collection-id",
+ CURRENT_ROUTE_VARIANT: "current-variant-id",
+ SET_COLLECTION_BASE: "set-collection-base",
+ SET_COLLECTION_USER_2: "set-collection-user2",
+ };
+
+ before(() => {
+ cy.visit("/");
+ });
+
+ it("should display collections collection", () => {
+ cy.get(SELECTORS.COLLECTIONS_COLLECTION_ITEM).should("have.length", 2);
+ });
+
+ it("should display routes collection", () => {
+ cy.get(SELECTORS.ROUTES_COLLECTION_ITEM).should("have.length", 1);
+ });
+
+ describe("when collection is base", () => {
+ before(() => {
+ cy.findByTestId(SELECTORS.SET_COLLECTION_BASE).click();
+ });
+
+ it("should display current collection", () => {
+ cy.findByTestId(SELECTORS.CURRENT_COLLECTION).should("have.text", "base");
+ });
+
+ it("should display current route variant", () => {
+ cy.findByTestId(SELECTORS.CURRENT_ROUTE_VARIANT).should("have.text", "get-user:1");
+ });
+ });
+
+ describe("when collection is user2", () => {
+ before(() => {
+ cy.findByTestId(SELECTORS.SET_COLLECTION_USER_2).click();
+ });
+
+ it("should display current collection", () => {
+ cy.findByTestId(SELECTORS.CURRENT_COLLECTION).should("have.text", "user2");
+ });
+
+ it("should display current route variant", () => {
+ cy.findByTestId(SELECTORS.CURRENT_ROUTE_VARIANT).should("have.text", "get-user:2");
+ });
+ });
+});
diff --git a/test/admin-api-client-data-provider-e2e-specs/cypress/integration/settings.js b/test/admin-api-client-data-provider-e2e-specs/cypress/integration/config.js
similarity index 56%
rename from test/admin-api-client-data-provider-e2e-specs/cypress/integration/settings.js
rename to test/admin-api-client-data-provider-e2e-specs/cypress/integration/config.js
index f4321b7ab..944444056 100644
--- a/test/admin-api-client-data-provider-e2e-specs/cypress/integration/settings.js
+++ b/test/admin-api-client-data-provider-e2e-specs/cypress/integration/config.js
@@ -1,10 +1,10 @@
describe("Settings section", () => {
const SELECTORS = {
- CONFIG: "settings-config",
- PLUGINS: "settings-plugins",
- FILES: "settings-files",
- SERVER: "settings-server",
- MOCKS: "settings-mocks",
+ CONFIG: "config-config",
+ PLUGINS: "config-plugins",
+ FILES: "config-files",
+ SERVER: "config-server",
+ MOCK: "config-mock",
};
before(() => {
@@ -16,6 +16,6 @@ describe("Settings section", () => {
});
it("should display current delay", () => {
- cy.findByTestId(SELECTORS.MOCKS).should("contain.text", '"delay":0');
+ cy.findByTestId(SELECTORS.MOCK).should("contain.text", '"delay":0');
});
});
diff --git a/test/admin-api-client-data-provider-e2e-specs/cypress/integration/mocksAndRouteVariants.js b/test/admin-api-client-data-provider-e2e-specs/cypress/integration/mocksAndRouteVariants.js
deleted file mode 100644
index 4fc576919..000000000
--- a/test/admin-api-client-data-provider-e2e-specs/cypress/integration/mocksAndRouteVariants.js
+++ /dev/null
@@ -1,50 +0,0 @@
-describe("mocks and routeVariants", () => {
- const SELECTORS = {
- MOCKS_COLLECTION_ITEM: ".mocks-collection-item",
- ROUTES_COLLECTION_ITEM: ".routes-collection-item",
- CURRENT_MOCK: "current-mock-id",
- CURRENT_ROUTE_VARIANT: "current-route-variant-id",
- SET_MOCK_BASE: "set-mock-base",
- SET_MOCK_USER_2: "set-mock-user2",
- };
-
- before(() => {
- cy.visit("/");
- });
-
- it("should display mocks collection", () => {
- cy.get(SELECTORS.MOCKS_COLLECTION_ITEM).should("have.length", 2);
- });
-
- it("should display routes collection", () => {
- cy.get(SELECTORS.ROUTES_COLLECTION_ITEM).should("have.length", 1);
- });
-
- describe("when mock is base", () => {
- before(() => {
- cy.findByTestId(SELECTORS.SET_MOCK_BASE).click();
- });
-
- it("should display current mock", () => {
- cy.findByTestId(SELECTORS.CURRENT_MOCK).should("have.text", "base");
- });
-
- it("should display current route variant", () => {
- cy.findByTestId(SELECTORS.CURRENT_ROUTE_VARIANT).should("have.text", "get-user:1");
- });
- });
-
- describe("when mock is user2", () => {
- before(() => {
- cy.findByTestId(SELECTORS.SET_MOCK_USER_2).click();
- });
-
- it("should display current mock", () => {
- cy.findByTestId(SELECTORS.CURRENT_MOCK).should("have.text", "user2");
- });
-
- it("should display current route variant", () => {
- cy.findByTestId(SELECTORS.CURRENT_ROUTE_VARIANT).should("have.text", "get-user:2");
- });
- });
-});
diff --git a/test/admin-api-client-data-provider-nodejs-e2e/package.json b/test/admin-api-client-data-provider-nodejs-e2e/package.json
index 340b4341c..e8046802b 100644
--- a/test/admin-api-client-data-provider-nodejs-e2e/package.json
+++ b/test/admin-api-client-data-provider-nodejs-e2e/package.json
@@ -3,7 +3,7 @@
"scripts": {
"mocks:ci": "pnpm -w run nx start admin-api-client-data-provider-e2e-mocks",
"test": "jest",
- "test:e2e": "start-server-and-test mocks:ci http-get://127.0.0.1:3100/admin/about test"
+ "test:e2e": "start-server-and-test mocks:ci http-get://127.0.0.1:3110/api/about test"
},
"devDependencies": {
"@mocks-server/admin-api-client-data-provider": "workspace:*"
diff --git a/test/admin-api-client-data-provider-nodejs-e2e/project.json b/test/admin-api-client-data-provider-nodejs-e2e/project.json
index 50ce491f9..4c2d73498 100644
--- a/test/admin-api-client-data-provider-nodejs-e2e/project.json
+++ b/test/admin-api-client-data-provider-nodejs-e2e/project.json
@@ -2,6 +2,7 @@
"root": "test/admin-api-client-data-provider-nodejs-e2e/",
"projectType": "application",
"implicitDependencies": [
+ "admin-api-client-data-provider",
"admin-api-client-data-provider-e2e-mocks"
],
"tags": ["type:test"]
diff --git a/test/admin-api-client-data-provider-nodejs-e2e/src/index.js b/test/admin-api-client-data-provider-nodejs-e2e/src/index.js
index b38f48cfa..e185440de 100644
--- a/test/admin-api-client-data-provider-nodejs-e2e/src/index.js
+++ b/test/admin-api-client-data-provider-nodejs-e2e/src/index.js
@@ -1,11 +1,11 @@
const {
about,
- mocks,
- mock,
+ collections,
+ collection,
routes,
route,
- routeVariant,
- settings,
+ variant,
+ config,
alerts,
alert,
} = require("@mocks-server/admin-api-client-data-provider/dist/index.cjs");
@@ -14,12 +14,12 @@ const readAbout = () => {
return about.read();
};
-const readMocks = () => {
- return mocks.read();
+const readCollections = () => {
+ return collections.read();
};
-const readMock = (name) => {
- return mock(name).read();
+const readCollection = (name) => {
+ return collection.queries.byId(name).read();
};
const readRoutes = () => {
@@ -27,15 +27,15 @@ const readRoutes = () => {
};
const readRoute = (id) => {
- return route(id).read();
+ return route.queries.byId(id).read();
};
-const readSettings = () => {
- return settings.read();
+const readConfig = () => {
+ return config.read();
};
-const updateSettings = (newSettings) => {
- return settings.update(newSettings);
+const updateConfig = (newConfig) => {
+ return config.update(newConfig);
};
const readAlerts = () => {
@@ -43,22 +43,22 @@ const readAlerts = () => {
};
const readAlert = (id) => {
- return alert(id).read();
+ return alert.queries.byId(id).read();
};
-const readRouteVariant = (id) => {
- return routeVariant(id).read();
+const readVariant = (id) => {
+ return variant.queries.byId(id).read();
};
module.exports = {
readAbout,
- readMocks,
- readMock,
+ readCollections,
+ readCollection,
readRoutes,
readRoute,
- readSettings,
- updateSettings,
+ readConfig,
+ updateConfig,
readAlerts,
readAlert,
- readRouteVariant,
+ readVariant,
};
diff --git a/test/admin-api-client-data-provider-nodejs-e2e/src/index.spec.js b/test/admin-api-client-data-provider-nodejs-e2e/src/index.spec.js
index 796d87f65..b98d0d0c7 100644
--- a/test/admin-api-client-data-provider-nodejs-e2e/src/index.spec.js
+++ b/test/admin-api-client-data-provider-nodejs-e2e/src/index.spec.js
@@ -1,21 +1,21 @@
const {
readAbout,
- readMocks,
- readMock,
+ readCollections,
+ readCollection,
readRoutes,
readRoute,
- readRouteVariant,
- readSettings,
- updateSettings,
+ readVariant,
+ readConfig,
+ updateConfig,
readAlerts,
readAlert,
} = require("./index");
-describe("react-admin-client methods used through node", () => {
+describe("data provider methods used through node", () => {
describe("when reading about", () => {
- it("should return current version", async () => {
+ it("should return current versions", async () => {
const about = await readAbout();
- expect(about.version).toBeDefined();
+ expect(about.versions).toBeDefined();
});
});
@@ -47,73 +47,85 @@ describe("react-admin-client methods used through node", () => {
});
});
- describe("when reading mocks", () => {
- it("should return mocks collection", async () => {
- const mocks = await readMocks();
- expect(mocks.length).toEqual(2);
+ describe("when reading collections", () => {
+ it("should return collections", async () => {
+ const collections = await readCollections();
+ expect(collections.length).toEqual(2);
});
- it("first mock model should exist", async () => {
- const mocks = await readMocks();
- const mockId = mocks[0].id;
- const mock = await readMock(mockId);
- expect(mock.id).toEqual(mockId);
+ it("first collections model should exist", async () => {
+ const collections = await readCollections();
+ const collectionId = collections[0].id;
+ const collection = await readCollection(collectionId);
+ expect(collection.id).toEqual(collectionId);
});
- it("second mock model should exist", async () => {
- const mocks = await readMocks();
- const mockId = mocks[1].id;
- const mock = await readMock(mockId);
- expect(mock.id).toEqual(mockId);
+ it("second collection model should exist", async () => {
+ const collections = await readCollections();
+ const collectionId = collections[1].id;
+ const mock = await readCollection(collectionId);
+ expect(mock.id).toEqual(collectionId);
});
- it("route variant of mock base should exist", async () => {
- const mocks = await readMocks();
- const routeVariantId = mocks[0].routesVariants[0];
- const routeVariant = await readRouteVariant(routeVariantId);
+ it("route route variant of collection base should exist", async () => {
+ const collections = await readCollections();
+ const routeVariantId = collections[0].routes[0];
+ const routeVariant = await readVariant(routeVariantId);
expect(routeVariant.id).toEqual(routeVariantId);
});
- it("first routeVariant of mock user2 should exist", async () => {
- const mocks = await readMocks();
- const routeVariantId = mocks[1].routesVariants[0];
- const routeVariant = await readRouteVariant(routeVariantId);
+ it("first route variant of collection user2 should exist", async () => {
+ const collections = await readCollections();
+ const routeVariantId = collections[1].routes[0];
+ const routeVariant = await readVariant(routeVariantId);
expect(routeVariant.id).toEqual(routeVariantId);
});
});
- describe("when reading settings", () => {
- it("should return current mock", async () => {
- const settings = await readSettings();
- expect(settings.mocks.selected).toEqual(undefined);
+ describe("when reading config", () => {
+ it("should return current collection", async () => {
+ const config = await readConfig();
+ expect(config.mocks.selected).toEqual(undefined);
});
});
- describe("when updating settings", () => {
- it("should update current mock", async () => {
- await updateSettings({
+ describe("when updating config", () => {
+ it("should update current collection", async () => {
+ await updateConfig({
mocks: { selected: "user2" },
});
- const settings = await readSettings();
- expect(settings.mocks.selected).toEqual("user2");
+ const config = await readConfig();
+ expect(config.mocks.selected).toEqual("user2");
});
- it("should update current delay", async () => {
- await updateSettings({
+ it("should update current delay using legacy option", async () => {
+ await updateConfig({
mocks: {
delay: 1000,
},
});
- const settings = await readSettings();
- expect(settings.mocks.delay).toEqual(1000);
+ const config = await readConfig();
+ expect(config.mocks.delay).toEqual(1000);
+ });
+
+ it("should update current delay", async () => {
+ await updateConfig({
+ mock: {
+ routes: {
+ delay: 1000,
+ },
+ },
+ });
+ const config = await readConfig();
+ expect(config.mock.routes.delay).toEqual(1000);
});
- it("should update current mock again", async () => {
- await updateSettings({
- mocks: { selected: "base" },
+ it("should update current collection again", async () => {
+ await updateConfig({
+ mock: { collections: { selected: "base" } },
});
- const settings = await readSettings();
- expect(settings.mocks.selected).toEqual("base");
+ const config = await readConfig();
+ expect(config.mock.collections.selected).toEqual("base");
});
});
});
diff --git a/test/admin-api-client-data-provider-react-app-e2e/package.json b/test/admin-api-client-data-provider-react-app-e2e/package.json
index 35aca98fd..395479042 100644
--- a/test/admin-api-client-data-provider-react-app-e2e/package.json
+++ b/test/admin-api-client-data-provider-react-app-e2e/package.json
@@ -4,7 +4,7 @@
"mocks:ci": "pnpm -w run nx start admin-api-client-data-provider-e2e-mocks",
"cypress:run": "pnpm -w run nx cypress:run admin-api-client-data-provider-e2e-specs",
"start:app": "pnpm -w run nx serve admin-api-client-data-provider-e2e-react-app",
- "mocks:ci-and-start:app": "start-server-and-test mocks:ci http-get://127.0.0.1:3100/admin/about start:app",
+ "mocks:ci-and-start:app": "start-server-and-test mocks:ci http-get://127.0.0.1:3110/api/about start:app",
"test:e2e": "start-server-and-test mocks:ci-and-start:app http-get://127.0.0.1:3000 cypress:run"
}
}
diff --git a/test/admin-api-client-data-provider-vanilla-app-e2e/package.json b/test/admin-api-client-data-provider-vanilla-app-e2e/package.json
index 3793de54a..27fd0c11c 100644
--- a/test/admin-api-client-data-provider-vanilla-app-e2e/package.json
+++ b/test/admin-api-client-data-provider-vanilla-app-e2e/package.json
@@ -4,7 +4,7 @@
"mocks:ci": "pnpm -w run nx start admin-api-client-data-provider-e2e-mocks",
"cypress:run": "pnpm -w run nx cypress:run admin-api-client-data-provider-e2e-specs",
"start:app": "pnpm -w run nx serve admin-api-client-data-provider-e2e-vanilla-app",
- "mocks:ci-and-start:app": "start-server-and-test mocks:ci http-get://127.0.0.1:3100/admin/about start:app",
+ "mocks:ci-and-start:app": "start-server-and-test mocks:ci http-get://127.0.0.1:3110/api/about start:app",
"test:e2e": "start-server-and-test mocks:ci-and-start:app http-get://127.0.0.1:3000 cypress:run"
}
}
diff --git a/test/admin-api-client-nodejs-e2e/project.json b/test/admin-api-client-nodejs-e2e/project.json
index d778933f0..7158b6210 100644
--- a/test/admin-api-client-nodejs-e2e/project.json
+++ b/test/admin-api-client-nodejs-e2e/project.json
@@ -1,5 +1,8 @@
{
"root": "test/admin-api-client-nodejs-e2e/",
"projectType": "application",
+ "implicitDependencies": [
+ "admin-api-client-unit-mocks"
+ ],
"tags": ["type:test"]
}
diff --git a/test/admin-api-client-nodejs-e2e/src/index.spec.js b/test/admin-api-client-nodejs-e2e/src/index.spec.js
index ff0334c98..5e76b88f8 100644
--- a/test/admin-api-client-nodejs-e2e/src/index.spec.js
+++ b/test/admin-api-client-nodejs-e2e/src/index.spec.js
@@ -2,26 +2,26 @@ const { wait } = require("./support/helpers");
const {
readAbout,
- readSettings,
- updateSettings,
+ readConfig,
+ updateConfig,
readAlerts,
readAlert,
- readMocks,
- readMock,
+ readCollections,
+ readCollection,
readRoutes,
readRoute,
- readRoutesVariants,
- readRouteVariant,
- readCustomRoutesVariants,
+ readVariants,
+ readVariant,
+ readCustomRouteVariants,
useRouteVariant,
- restoreRoutesVariants,
+ restoreRouteVariants,
} = require("@mocks-server/admin-api-client");
-describe("react-admin-client methods used with node", () => {
+describe("admin api client methods", () => {
describe("when reading about", () => {
it("should return current version", async () => {
const about = await readAbout();
- expect(about.version).toBeDefined();
+ expect(about.versions.adminApi).toBeDefined();
});
});
@@ -32,18 +32,18 @@ describe("react-admin-client methods used with node", () => {
expect(alerts.length).toEqual(1);
});
- it("should return alert about mock not defined", async () => {
+ it("should return alert about collection not defined", async () => {
const alerts = await readAlerts();
expect(alerts[0].message).toEqual(
- expect.stringContaining("Option 'mock' was not defined")
+ expect.stringContaining("Option 'mock.collections.selected' was not defined")
);
});
});
describe("when there are alerts about files with error", () => {
- it("should return alerts array", async () => {
+ it("should return 3 alerts", async () => {
expect.assertions(1);
- await updateSettings({
+ await updateConfig({
files: { path: "mocks-with-error" },
});
await wait(2000);
@@ -51,21 +51,41 @@ describe("react-admin-client methods used with node", () => {
expect(alerts.length).toEqual(3);
});
+ it("alert about config should exist", async () => {
+ const alerts = await readAlerts();
+ const alertId = alerts[0].id;
+ const alert = await readAlert(alertId);
+ expect(alert.id).toEqual(alertId);
+ expect(alert.message).toEqual(
+ expect.stringContaining("Option 'mock.collections.selected' was not defined")
+ );
+ });
+
+ it("alert about empty collections should exist", async () => {
+ const alerts = await readAlerts();
+ const alertId = alerts[1].id;
+ const alert = await readAlert(alertId);
+ expect(alert.id).toEqual(alertId);
+ expect(alert.message).toEqual(expect.stringContaining("No collections found"));
+ });
+
it("alert about files error should exist", async () => {
const alerts = await readAlerts();
const alertId = alerts[2].id;
const alert = await readAlert(alertId);
expect(alert.id).toEqual(alertId);
- expect(alert.message).toEqual(expect.stringContaining("Error loading mocks"));
+ expect(alert.message).toEqual(expect.stringContaining("Error loading collections"));
});
});
describe("when alerts are removed", () => {
it("should return no alerts", async () => {
- await updateSettings({
+ await updateConfig({
files: { path: "mocks" },
- mocks: {
- selected: "base",
+ mock: {
+ collections: {
+ selected: "base",
+ },
},
});
await wait(2000);
@@ -75,46 +95,58 @@ describe("react-admin-client methods used with node", () => {
});
});
- describe("when updating settings", () => {
- it("should update current delay", async () => {
- await updateSettings({
+ describe("when updating config", () => {
+ it("should update current delay using legacy option", async () => {
+ await updateConfig({
mocks: {
delay: 1000,
},
});
- const settings = await readSettings();
+ const settings = await readConfig();
expect(settings.mocks.delay).toEqual(1000);
});
+
+ it("should update current delay", async () => {
+ await updateConfig({
+ mock: {
+ routes: {
+ delay: 2000,
+ },
+ },
+ });
+ const settings = await readConfig();
+ expect(settings.mock.routes.delay).toEqual(2000);
+ });
});
- describe("when reading mocks", () => {
- it("should return mocks", async () => {
- const mocks = await readMocks();
- expect(mocks).toEqual([
+ describe("when reading collections", () => {
+ it("should return collections", async () => {
+ const collections = await readCollections();
+ expect(collections).toEqual([
{
id: "base",
from: null,
- routesVariants: ["get-user:1"],
- appliedRoutesVariants: ["get-user:1"],
+ definedRoutes: ["get-user:1"],
+ routes: ["get-user:1"],
},
{
id: "user2",
from: null,
- routesVariants: ["get-user:2"],
- appliedRoutesVariants: ["get-user:2"],
+ definedRoutes: ["get-user:2"],
+ routes: ["get-user:2"],
},
]);
});
});
- describe("when reading mock", () => {
- it("should return mock data", async () => {
- const mock = await readMock("base");
- expect(mock).toEqual({
+ describe("when reading collection", () => {
+ it("should return collection data", async () => {
+ const collection = await readCollection("base");
+ expect(collection).toEqual({
id: "base",
from: null,
- routesVariants: ["get-user:1"],
- appliedRoutesVariants: ["get-user:1"],
+ definedRoutes: ["get-user:1"],
+ routes: ["get-user:1"],
});
});
});
@@ -127,7 +159,7 @@ describe("react-admin-client methods used with node", () => {
id: "get-user",
delay: null,
url: "/api/user",
- method: "GET",
+ method: "get",
variants: ["get-user:1", "get-user:2"],
},
]);
@@ -136,61 +168,61 @@ describe("react-admin-client methods used with node", () => {
describe("when reading route", () => {
it("should return route data", async () => {
- const mock = await readRoute("get-user");
- expect(mock).toEqual({
+ const data = await readRoute("get-user");
+ expect(data).toEqual({
id: "get-user",
delay: null,
url: "/api/user",
- method: "GET",
+ method: "get",
variants: ["get-user:1", "get-user:2"],
});
});
});
- describe("when reading routes variants", () => {
- it("should return routes variants", async () => {
- const data = await readRoutesVariants();
+ describe("when reading variants", () => {
+ it("should return route variants", async () => {
+ const data = await readVariants();
expect(data).toEqual([
{
id: "get-user:1",
- routeId: "get-user",
- handler: "json",
- response: { body: [{ email: "foo@foo.com" }], status: 200 },
+ route: "get-user",
+ type: "json",
+ preview: { body: [{ email: "foo@foo.com" }], status: 200 },
delay: null,
},
{
id: "get-user:2",
- routeId: "get-user",
- handler: "json",
- response: { body: [{ email: "foo2@foo2.com" }], status: 200 },
+ route: "get-user",
+ type: "json",
+ preview: { body: [{ email: "foo2@foo2.com" }], status: 200 },
delay: null,
},
]);
});
});
- describe("when reading route variant", () => {
- it("should return route variant data", async () => {
- const data = await readRouteVariant("get-user:2");
+ describe("when reading variant", () => {
+ it("should return variant data", async () => {
+ const data = await readVariant("get-user:2");
expect(data).toEqual({
id: "get-user:2",
- routeId: "get-user",
- handler: "json",
- response: { body: [{ email: "foo2@foo2.com" }], status: 200 },
+ route: "get-user",
+ type: "json",
+ preview: { body: [{ email: "foo2@foo2.com" }], status: 200 },
delay: null,
});
});
});
- describe("mock custom route variants", () => {
+ describe("custom route variants", () => {
it("should be empty", async () => {
- const data = await readCustomRoutesVariants();
+ const data = await readCustomRouteVariants();
expect(data).toEqual([]);
});
it("should be able to add one", async () => {
await useRouteVariant("get-user:2");
- const data = await readCustomRoutesVariants();
+ const data = await readCustomRouteVariants();
expect(data).toEqual(["get-user:2"]);
});
@@ -201,9 +233,9 @@ describe("react-admin-client methods used with node", () => {
});
});
- it("should be empty after restoring them to the mock defaults", async () => {
- await restoreRoutesVariants();
- const data = await readCustomRoutesVariants();
+ it("should be empty after restoring them to the collection defaults", async () => {
+ await restoreRouteVariants();
+ const data = await readCustomRouteVariants();
expect(data).toEqual([]);
});
});
diff --git a/test/admin-api-client-nodejs-e2e/src/support/helpers.js b/test/admin-api-client-nodejs-e2e/src/support/helpers.js
index e676900c4..0789ec6ab 100644
--- a/test/admin-api-client-nodejs-e2e/src/support/helpers.js
+++ b/test/admin-api-client-nodejs-e2e/src/support/helpers.js
@@ -1,7 +1,7 @@
-const { config } = require("@mocks-server/admin-api-client");
+const { configClient } = require("@mocks-server/admin-api-client");
-config({
- baseUrl: "http://127.0.0.1:3200",
+configClient({
+ port: 3110,
});
const wait = (time = 1000) => {
diff --git a/test/core-e2e-legacy/jest.config.js b/test/core-e2e-legacy/jest.config.js
index 5f8d8f9eb..4ed3b7ca6 100644
--- a/test/core-e2e-legacy/jest.config.js
+++ b/test/core-e2e-legacy/jest.config.js
@@ -6,7 +6,7 @@ module.exports = {
clearMocks: true,
testMatch: ["/src/**/*.spec.js"],
- // testMatch: ["/src/**/load-mocks-and-routes.spec.js"],
+ // testMatch: ["/src/**/validations.spec.js"],
// Indicates whether the coverage information should be collected while executing the test
collectCoverage: false,
diff --git a/test/core-e2e-legacy/src/events.spec.js b/test/core-e2e-legacy/src/events.spec.js
index abc8f157a..cdab67d2e 100644
--- a/test/core-e2e-legacy/src/events.spec.js
+++ b/test/core-e2e-legacy/src/events.spec.js
@@ -93,19 +93,19 @@ describe("events", () => {
describe("When alerts are added", () => {
let option, removeSpy;
- it("should have emitted event", async () => {
+ it("should have emitted events", async () => {
option = core.config.namespace("mocks").option("selected");
removeSpy = core.onChangeAlerts(spies.onChangeAlerts);
option.value = "unexistant";
await wait(500);
- expect(spies.onChangeAlerts.callCount).toEqual(1);
+ expect(spies.onChangeAlerts.callCount).toEqual(2);
});
it("should not execute callback when event listener is removed", async () => {
removeSpy();
option.value = "unexistant2";
await wait(500);
- expect(spies.onChangeAlerts.callCount).toEqual(1);
+ expect(spies.onChangeAlerts.callCount).toEqual(2);
});
});
});
diff --git a/test/core-e2e-legacy/src/files-error.spec.js b/test/core-e2e-legacy/src/files-error.spec.js
index 7a89539b7..b38985825 100644
--- a/test/core-e2e-legacy/src/files-error.spec.js
+++ b/test/core-e2e-legacy/src/files-error.spec.js
@@ -37,12 +37,14 @@ describe("when there is an error loading files", () => {
});
it("should have added an alert about not mock found", async () => {
- expect(findAlert("mocks:empty", core.alerts).message).toEqual("No mocks found");
+ expect(findAlert("mock:collections:empty", core.alerts).message).toEqual(
+ "No collections found"
+ );
});
- it("should have added an alert about error loading mocks", async () => {
- expect(findAlert("files:mocks", core.alerts).message).toEqual(
- expect.stringContaining("Error loading mocks from file")
+ it("should have added an alert about error loading collections", async () => {
+ expect(findAlert("files:collections", core.alerts).message).toEqual(
+ expect.stringContaining("Error loading collections from file")
);
});
});
diff --git a/test/core-e2e-legacy/src/json-files.spec.js b/test/core-e2e-legacy/src/json-files.spec.js
index f9b5f7f0d..517a8a95a 100644
--- a/test/core-e2e-legacy/src/json-files.spec.js
+++ b/test/core-e2e-legacy/src/json-files.spec.js
@@ -34,8 +34,8 @@ describe("json files", () => {
describe("mock by default", () => {
it("should have added an alert about mock was not defined", () => {
- expect(findAlert("mocks:settings", core.alerts).message).toEqual(
- expect.stringContaining("Option 'mock' was not defined")
+ expect(findAlert("mock:collections:selected", core.alerts).message).toEqual(
+ expect.stringContaining("Option 'mock.collections.selected' was not defined")
);
});
@@ -67,7 +67,7 @@ describe("json files", () => {
});
it("should have removed alert", () => {
- expect(findAlert("mocks:settings", core.alerts)).toEqual(undefined);
+ expect(findAlert("mock:collections:selected", core.alerts)).toEqual(undefined);
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -98,8 +98,8 @@ describe("json files", () => {
});
it("should have added an alert", () => {
- expect(findAlert("mocks:settings", core.alerts).message).toEqual(
- expect.stringContaining("Mock 'foo' was not found")
+ expect(findAlert("mock:collections:selected", core.alerts).message).toEqual(
+ expect.stringContaining("Collection 'foo' was not found")
);
});
diff --git a/test/core-e2e-legacy/src/load-mocks-and-routes.spec.js b/test/core-e2e-legacy/src/load-mocks-and-routes.spec.js
index aaef20f24..a1322dea2 100644
--- a/test/core-e2e-legacy/src/load-mocks-and-routes.spec.js
+++ b/test/core-e2e-legacy/src/load-mocks-and-routes.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2021 Javier Brea
+Copyright 2021-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
diff --git a/test/core-e2e-legacy/src/mock-argument.spec.js b/test/core-e2e-legacy/src/mock-argument.spec.js
index bb51c3b2f..926dd82fe 100644
--- a/test/core-e2e-legacy/src/mock-argument.spec.js
+++ b/test/core-e2e-legacy/src/mock-argument.spec.js
@@ -41,7 +41,9 @@ describe("mock argument", () => {
it("should print a warning", async () => {
mocks = mocksRunner([PATH_OPTION, "--mocks.selected=foo"]);
await waitForServer();
- expect(mocks.logs.current).toEqual(expect.stringContaining("Mock 'foo' was not found"));
+ expect(mocks.logs.current).toEqual(
+ expect.stringContaining("Collection 'foo' was not found")
+ );
});
it("should set as current mock the first one found", async () => {
diff --git a/test/core-e2e-legacy/src/mock-setting.spec.js b/test/core-e2e-legacy/src/mock-setting.spec.js
index 26a71acb8..3580e530e 100644
--- a/test/core-e2e-legacy/src/mock-setting.spec.js
+++ b/test/core-e2e-legacy/src/mock-setting.spec.js
@@ -34,8 +34,8 @@ describe("mock setting", () => {
describe("mock by default", () => {
it("should have added an alert about mock was not defined", () => {
- expect(findAlert("mocks:settings", core.alerts).message).toEqual(
- expect.stringContaining("Option 'mock' was not defined")
+ expect(findAlert("mock:collections:selected", core.alerts).message).toEqual(
+ expect.stringContaining("Option 'mock.collections.selected' was not defined")
);
});
@@ -67,7 +67,7 @@ describe("mock setting", () => {
});
it("should have removed alert", () => {
- expect(findAlert("mocks:settings", core.alerts)).toEqual(undefined);
+ expect(findAlert("mock:collections:selected", core.alerts)).toEqual(undefined);
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -130,8 +130,8 @@ describe("mock setting", () => {
});
it("should have added an alert", () => {
- expect(findAlert("mocks:settings", core.alerts).message).toEqual(
- expect.stringContaining("Mock 'foo' was not found")
+ expect(findAlert("mock:collections:selected", core.alerts).message).toEqual(
+ expect.stringContaining("Collection 'foo' was not found")
);
});
@@ -164,7 +164,7 @@ describe("mock setting", () => {
});
it("should have removed alert", () => {
- expect(findAlert("mocks:settings", core.alerts)).toEqual(undefined);
+ expect(findAlert("mock:collections:selected", core.alerts)).toEqual(undefined);
});
});
});
diff --git a/test/core-e2e-legacy/src/path-argument.spec.js b/test/core-e2e-legacy/src/path-argument.spec.js
index c2e2720a0..78bae1482 100644
--- a/test/core-e2e-legacy/src/path-argument.spec.js
+++ b/test/core-e2e-legacy/src/path-argument.spec.js
@@ -36,7 +36,9 @@ describe("path argument", () => {
});
it("should print a warning about creating folder", async () => {
- expect(mocks.logs.current).toEqual(expect.stringContaining("Mocks folder was not found"));
+ expect(mocks.logs.current).toEqual(
+ expect.stringContaining("Mocks Server folder was not found")
+ );
});
it("should have created a mocks folder", async () => {
@@ -45,7 +47,9 @@ describe("path argument", () => {
it("should have created scaffold folder", async () => {
expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "routes"))).toEqual(true);
- expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "mocks.json"))).toEqual(true);
+ expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "collections.json"))).toEqual(
+ true
+ );
});
});
diff --git a/test/core-e2e-legacy/src/path-not-exists.spec.js b/test/core-e2e-legacy/src/path-not-exists.spec.js
index f7571f1dc..8f363af7c 100644
--- a/test/core-e2e-legacy/src/path-not-exists.spec.js
+++ b/test/core-e2e-legacy/src/path-not-exists.spec.js
@@ -45,25 +45,27 @@ describe("when path not exists", () => {
it("should have created scaffold folder", async () => {
expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "routes"))).toEqual(true);
- expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "mocks.json"))).toEqual(true);
+ expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "collections.json"))).toEqual(
+ true
+ );
});
it("should have added an alert about folder not found", async () => {
- expect(findAlert("scaffold:mocks", core.alerts).message).toEqual(
- expect.stringContaining("Mocks folder was not found")
+ expect(findAlert("scaffold:folder", core.alerts).message).toEqual(
+ expect.stringContaining("Mocks Server folder was not found")
);
});
- it("should have three mocks", async () => {
- expect(core.mocks.plainMocks.length).toEqual(3);
+ it("should have 4 mocks", async () => {
+ expect(core.mocks.plainMocks.length).toEqual(4);
});
- it("should have three routes", async () => {
+ it("should have 3 routes", async () => {
expect(core.mocks.plainRoutes.length).toEqual(3);
});
- it("should have six routes", async () => {
- expect(core.mocks.plainRoutesVariants.length).toEqual(6);
+ it("should have 8 routes variants", async () => {
+ expect(core.mocks.plainRoutesVariants.length).toEqual(8);
});
});
diff --git a/test/core-e2e-legacy/src/plugin-load-collections-and-routes.spec.js b/test/core-e2e-legacy/src/plugin-load-collections-and-routes.spec.js
new file mode 100644
index 000000000..b70bdf19f
--- /dev/null
+++ b/test/core-e2e-legacy/src/plugin-load-collections-and-routes.spec.js
@@ -0,0 +1,168 @@
+/*
+Copyright 2021-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const {
+ startCore,
+ doFetch,
+ waitForServer,
+ waitForServerUrl,
+ removeConfigFile,
+} = require("./support/helpers");
+
+describe("loadCollections and loadRoutes methods", () => {
+ let core, changeMockAndWait;
+
+ beforeAll(async () => {
+ class Plugin {
+ static get id() {
+ return "test-plugin";
+ }
+ register({ loadMocks, loadRoutes }) {
+ this._loadMocks = loadMocks;
+ this._loadRoutes = loadRoutes;
+ }
+ start() {
+ this._loadRoutes([
+ {
+ id: "get-books",
+ url: "/api/books",
+ method: "GET",
+ variants: [
+ {
+ id: "success",
+ response: {
+ status: 200,
+ body: [{ id: 1, title: "1984" }],
+ },
+ },
+ {
+ id: "error",
+ response: {
+ status: 403,
+ body: {
+ message: "Bad data",
+ },
+ },
+ },
+ ],
+ },
+ {
+ id: "get-authors",
+ url: "/api/authors",
+ method: "GET",
+ variants: [
+ {
+ id: "success",
+ response: {
+ status: 200,
+ body: [{ id: 1, name: "George Orwell" }],
+ },
+ },
+ {
+ id: "error",
+ response: {
+ status: 403,
+ body: {
+ message: "Bad data",
+ },
+ },
+ },
+ ],
+ },
+ ]);
+ this._loadMocks([
+ {
+ id: "users-and-library",
+ from: "base",
+ routesVariants: ["get-books:success", "get-authors:success"],
+ },
+ {
+ id: "authors-error",
+ from: "users-and-library",
+ routesVariants: ["get-authors:error"],
+ },
+ ]);
+ }
+ }
+
+ core = await startCore(null, { plugins: { register: [Plugin] } });
+ changeMockAndWait = async (mockName) => {
+ core.config.namespace("mocks").option("selected").value = mockName;
+ await new Promise((resolve) => {
+ const interval = setInterval(() => {
+ if (core.mocks.current === mockName) {
+ clearInterval(interval);
+ resolve();
+ }
+ }, 200);
+ });
+ };
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ removeConfigFile();
+ await core.stop();
+ });
+
+ describe("When started", () => {
+ it("should return users", async () => {
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ });
+
+ it("should have loaded new mocks and routes", async () => {
+ core.config.namespace("mock").namespace("collections").option("selected").value =
+ "users-and-library";
+ await waitForServerUrl("/api/books");
+
+ const books = await doFetch("/api/books");
+ expect(books.body).toEqual([{ id: 1, title: "1984" }]);
+
+ const authors = await doFetch("/api/authors");
+ expect(authors.body).toEqual([{ id: 1, name: "George Orwell" }]);
+
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ });
+
+ it("should be able to change to a new mock", async () => {
+ await changeMockAndWait("authors-error");
+ const books = await doFetch("/api/books");
+ expect(books.body).toEqual([{ id: 1, title: "1984" }]);
+
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+
+ const authors = await doFetch("/api/authors");
+ expect(authors.status).toEqual(403);
+ });
+
+ it("should keep mocks loaded from files", async () => {
+ await changeMockAndWait("base");
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ const authors = await doFetch("/api/authors");
+ expect(authors.status).toEqual(404);
+ });
+ });
+});
diff --git a/test/core-e2e-legacy/src/plugins-legacy-alerts.spec.js b/test/core-e2e-legacy/src/plugins-legacy-alerts.spec.js
index 0140e4159..b7a81fd1f 100644
--- a/test/core-e2e-legacy/src/plugins-legacy-alerts.spec.js
+++ b/test/core-e2e-legacy/src/plugins-legacy-alerts.spec.js
@@ -146,7 +146,9 @@ describe("plugins using legacy alerts", () => {
const alerts = core.alerts;
const deprecationAlert = alerts.find((alert) => alert.context === "deprecated:addAlert");
expect(deprecationAlert.message).toEqual(
- expect.stringContaining("Detected usage of deprecated method 'addAlert'")
+ expect.stringContaining(
+ "Usage of 'addAlert' method is deprecated. Use 'alerts' instead"
+ )
);
});
});
@@ -174,7 +176,9 @@ describe("plugins using legacy alerts", () => {
(alert) => alert.context === "deprecated:removeAlert"
);
expect(deprecationAlert.message).toEqual(
- expect.stringContaining("Detected usage of deprecated method 'removeAlerts'")
+ expect.stringContaining(
+ "Usage of 'removeAlert' method is deprecated. Use 'alerts' instead"
+ )
);
});
@@ -183,7 +187,7 @@ describe("plugins using legacy alerts", () => {
const deprecationAlerts = alerts.filter((alert) =>
alert.context.startsWith("deprecated")
);
- expect(deprecationAlerts.length).toEqual(2);
+ expect(deprecationAlerts.length).toEqual(6);
});
it("should have removed all plugin alerts", async () => {
@@ -227,19 +231,22 @@ describe("plugins using legacy alerts", () => {
// Plugin id is still not available in register method
// It should have been renamed when start alert is received using a different context
context: "plugins:test-plugin:test-register",
+ id: "plugins:test-plugin:test-register",
message: "Warning registering plugin",
error: undefined,
},
{
context: "plugins:test-plugin:test-start",
+ id: "plugins:test-plugin:test-start",
message: "Warning starting plugin",
error: undefined,
},
{
context: "plugins:test-plugin:deprecated:core",
+ id: "plugins:test-plugin:deprecated:core",
error: undefined,
message:
- "Usage of core property is deprecated. Use properties at first level instead: https://www.mocks-server.org/docs/next/guides-migrating-from-v3#plugins",
+ "Usage of core property is deprecated. Use properties at first level instead: https://www.mocks-server.org/docs/releases/migrating-from-v3#plugins",
},
]);
});
diff --git a/test/core-e2e-legacy/src/plugins-legacy-formats.spec.js b/test/core-e2e-legacy/src/plugins-legacy-formats.spec.js
index f6015baf8..45e738d37 100644
--- a/test/core-e2e-legacy/src/plugins-legacy-formats.spec.js
+++ b/test/core-e2e-legacy/src/plugins-legacy-formats.spec.js
@@ -212,11 +212,13 @@ describe("plugins", () => {
// Plugin id is still not available in register method
// It should have been renamed when start alert is received using a different context
context: "plugins:test-plugin:test-register",
+ id: "plugins:test-plugin:test-register",
message: "Warning registering plugin",
error: undefined,
},
{
context: "plugins:test-plugin:test-start",
+ id: "plugins:test-plugin:test-start",
message: "Warning starting plugin",
error: undefined,
},
diff --git a/test/core-e2e-legacy/src/plugins.spec.js b/test/core-e2e-legacy/src/plugins.spec.js
index 22f931907..2398aa447 100644
--- a/test/core-e2e-legacy/src/plugins.spec.js
+++ b/test/core-e2e-legacy/src/plugins.spec.js
@@ -209,11 +209,13 @@ describe("plugins", () => {
// Plugin id is still not available in register method
// It should have been renamed when start alert is received using a different context
context: "plugins:test-plugin:test-register",
+ id: "plugins:test-plugin:test-register",
message: "Warning registering plugin",
error: undefined,
},
{
context: "plugins:test-plugin:test-start",
+ id: "plugins:test-plugin:test-start",
message: "Warning starting plugin",
error: undefined,
},
diff --git a/test/core-e2e-legacy/src/scaffold.spec.js b/test/core-e2e-legacy/src/scaffold.spec.js
index ea9251af6..2cb344cb1 100644
--- a/test/core-e2e-legacy/src/scaffold.spec.js
+++ b/test/core-e2e-legacy/src/scaffold.spec.js
@@ -45,7 +45,7 @@ describe("when nor config file nor mocks folder exists", () => {
describe("when started for the first time", () => {
it("should have created the mocks scaffold", async () => {
expect(
- fsExtra.existsSync(path.resolve(fixturesFolder("temp"), "mocks", "mocks.json"))
+ fsExtra.existsSync(path.resolve(fixturesFolder("temp"), "mocks", "collections.json"))
).toEqual(true);
});
@@ -53,11 +53,6 @@ describe("when nor config file nor mocks folder exists", () => {
expect(fsExtra.existsSync(configFile)).toEqual(true);
});
- it("should have base as selected mock in config file", async () => {
- const config = require(configFile);
- expect(config.mocks.selected).toEqual("base");
- });
-
it("should serve users under the /api/users path", async () => {
const users = await doFetch("/api/users");
expect(users.status).toEqual(200);
@@ -90,11 +85,6 @@ describe("when nor config file nor mocks folder exists", () => {
await waitForServer();
});
- it("should have base as selected mock in config file", async () => {
- const config = require(configFile);
- expect(config.mocks.selected).toEqual("base");
- });
-
it("should serve users under the /api/users path", async () => {
const users = await doFetch("/api/users");
expect(users.status).toEqual(200);
@@ -144,7 +134,9 @@ describe("when nor config file nor mocks folder exists", () => {
});
it("should have tried to load provided mocks", async () => {
- expect(mocks.logs.all).toEqual(expect.stringContaining("Mock with id 'user-2' is invalid"));
+ expect(mocks.logs.all).toEqual(
+ expect.stringContaining("Collection with id 'user-2' is invalid")
+ );
});
});
@@ -217,7 +209,7 @@ describe("when nor config file nor mocks folder exists", () => {
it("should have created the mocks scaffold", async () => {
expect(
- fsExtra.existsSync(path.resolve(fixturesFolder("temp"), "mocks", "mocks.json"))
+ fsExtra.existsSync(path.resolve(fixturesFolder("temp"), "mocks", "collections.json"))
).toEqual(true);
});
diff --git a/test/core-e2e-legacy/src/validations.spec.js b/test/core-e2e-legacy/src/validations.spec.js
index 08ffa2e6d..d75163da6 100644
--- a/test/core-e2e-legacy/src/validations.spec.js
+++ b/test/core-e2e-legacy/src/validations.spec.js
@@ -42,7 +42,7 @@ describe("mocks and routes validations", () => {
});
it("should have added an alert about mocks file loading error", () => {
- expect(findAlert("files:mocks", core.alerts).error.message).toEqual(
+ expect(findAlert("files:collections", core.alerts).error.message).toEqual(
expect.stringContaining("File does not export an array")
);
});
@@ -64,7 +64,7 @@ describe("mocks and routes validations", () => {
it("should have added an alert about route variant with duplicated id", () => {
expect(
- findAlert("mocks:loadRoutes:get-user-variant-invalid:variants:1:duplicated", core.alerts)
+ findAlert("mock:routes:load:get-user-variant-invalid:variants:1:duplicated", core.alerts)
.message
).toEqual(
"Route variant with duplicated id '1' detected in route 'get-user-variant-invalid'. It has been ignored"
@@ -73,7 +73,7 @@ describe("mocks and routes validations", () => {
it("should have added an alert about route variant not valid", () => {
expect(
- findAlert("mocks:loadRoutes:get-user-variant-invalid:variants:2:validation", core.alerts)
+ findAlert("mock:routes:load:get-user-variant-invalid:variants:2:validation", core.alerts)
.message
).toEqual(
"Variant with id '2' in route with id 'get-user-variant-invalid' is invalid: /response: type must be object. /response: instanceof must pass \"instanceof\" keyword validation. /response: oneOf must match exactly one schema in oneOf"
@@ -82,7 +82,7 @@ describe("mocks and routes validations", () => {
it("should have added an alert about route duplicated", () => {
expect(
- findAlert("mocks:loadRoutes:get-user-variant-invalid:duplicated", core.alerts).message
+ findAlert("mock:routes:load:get-user-variant-invalid:duplicated", core.alerts).message
).toEqual(
"Route with duplicated id 'get-user-variant-invalid' detected. It has been ignored"
);
@@ -90,51 +90,65 @@ describe("mocks and routes validations", () => {
it("should have added an alert about route invalid", () => {
expect(
- findAlert("mocks:loadRoutes:get-users-invalid:validation", core.alerts).message
+ findAlert("mock:routes:load:get-users-invalid:validation", core.alerts).message
).toEqual(
"Route with id 'get-users-invalid' is invalid: /method: enum must be equal to one of the allowed values. /method: type must be array. /method: oneOf must match exactly one schema in oneOf"
);
});
it("should have added an alert about mock routeVariant not found", () => {
- expect(findAlert("mocks:loadMocks:base:variants", core.alerts).message).toEqual(
- "Mock with id 'base' is invalid: routeVariant with id 'get-users-invalid:success' was not found, use a valid 'routeId:variantId' identifier"
+ expect(findAlert("mock:collections:load:base:variants", core.alerts).message).toEqual(
+ "Collection with id 'base' is invalid: routeVariant with id 'get-users-invalid:success' was not found, use a valid 'routeId:variantId' identifier"
);
});
it("should have added an alert about mock duplicated", () => {
- expect(findAlert("mocks:loadMocks:1:duplicated", core.alerts).message).toEqual(
- "Mock with duplicated id 'base' detected. It has been ignored"
+ expect(findAlert("mock:collections:load:1:duplicated", core.alerts).message).toEqual(
+ "Collection with duplicated id 'base' detected. It has been ignored"
);
});
it("should have added an alert about mock routeVariant not found in mock 2", () => {
- expect(findAlert("mocks:loadMocks:invalid-variant:variants", core.alerts).message).toEqual(
- "Mock with id 'invalid-variant' is invalid: routeVariant with id 'get-user-variant-invalid:2' was not found, use a valid 'routeId:variantId' identifier"
+ expect(
+ findAlert("mock:collections:load:invalid-variant:variants", core.alerts).message
+ ).toEqual(
+ "Collection with id 'invalid-variant' is invalid: routeVariant with id 'get-user-variant-invalid:2' was not found, use a valid 'routeId:variantId' identifier"
);
});
it("should have added an alert about invalid mock 3", () => {
- expect(findAlert("mocks:loadMocks:invalid-mock:validation", core.alerts).message).toEqual(
- "Mock with id 'invalid-mock' is invalid: must have required property 'routesVariants'"
+ expect(
+ findAlert("mock:collections:load:invalid-mock:validation", core.alerts).message
+ ).toEqual(
+ "Collection with id 'invalid-mock' is invalid: must have required property 'routes'"
);
});
- it("should have added an alert about mock with invalid from", () => {
- expect(findAlert("mocks:loadMocks:invalid-from:from", core.alerts).message).toEqual(
- "Mock with invalid 'from' property detected, 'foo' was not found"
+ it("should have added an alert about Collection with invalid from", () => {
+ expect(findAlert("mock:collections:load:invalid-from:from", core.alerts).message).toEqual(
+ "Collection with invalid 'from' property detected, 'foo' was not found"
+ );
+ });
+
+ it("should have added an alert about Collection with duplicated routes", () => {
+ expect(
+ findAlert("mock:collections:load:duplicated-route:variants", core.alerts).message
+ ).toEqual(
+ "Collection with id 'duplicated-route' is invalid: route with id 'get-user' is used more than once in the same collection"
);
});
- it("should have added an alert about mock with duplicated routes", () => {
- expect(findAlert("mocks:loadMocks:duplicated-route:variants", core.alerts).message).toEqual(
- "Mock with id 'duplicated-route' is invalid: route with id 'get-user' is used more than once in the same mock"
+ it("should have added an alert about deprecated routesVariants property", () => {
+ expect(filterAlerts("mock:collections:load", core.alerts)[0].message).toEqual(
+ expect.stringContaining(
+ "Usage of 'collection.routesVariants' property is deprecated. Use 'collection.routes' instead"
+ )
);
});
it("should have added an alert about errors processing mocks", () => {
- expect(filterAlerts("mocks:loadMocks", core.alerts)[0].message).toEqual(
- "Critical errors found while loading mocks: 1"
+ expect(filterAlerts("mock:collections:load", core.alerts)[1].message).toEqual(
+ "Critical errors found while loading collections: 1"
);
});
@@ -167,7 +181,7 @@ describe("mocks and routes validations", () => {
expect(response.status).toEqual(404);
});
- it("should return user 1 at /api/invalid-users/1 when changing to mock with no valid variant", async () => {
+ it("should return user 1 at /api/invalid-users/1 when changing to Collection with no valid variant", async () => {
core.config.namespace("mocks").option("selected").value = "invalid-variant";
const response = await doFetch("/api/invalid-users/1");
expect(response.status).toEqual(200);
diff --git a/test/core-e2e/jest.config.js b/test/core-e2e/jest.config.js
index 4ed3b7ca6..e8b27bf89 100644
--- a/test/core-e2e/jest.config.js
+++ b/test/core-e2e/jest.config.js
@@ -6,7 +6,7 @@ module.exports = {
clearMocks: true,
testMatch: ["/src/**/*.spec.js"],
- // testMatch: ["/src/**/validations.spec.js"],
+ // testMatch: ["/src/**/quick-start-tutorial.spec.js"],
// Indicates whether the coverage information should be collected while executing the test
collectCoverage: false,
diff --git a/test/core-e2e/src/mock-argument.spec.js b/test/core-e2e/src/collection-selected-argument.spec.js
similarity index 75%
rename from test/core-e2e/src/mock-argument.spec.js
rename to test/core-e2e/src/collection-selected-argument.spec.js
index bb51c3b2f..549b001f8 100644
--- a/test/core-e2e/src/mock-argument.spec.js
+++ b/test/core-e2e/src/collection-selected-argument.spec.js
@@ -10,7 +10,7 @@ Unless required by applicable law or agreed to in writing, software distributed
const { mocksRunner, doFetch, waitForServer, removeConfigFile } = require("./support/helpers");
-describe("mock argument", () => {
+describe("collection.selected argument", () => {
const PATH_OPTION = "--files.path=web-tutorial";
let mocks;
@@ -20,7 +20,7 @@ describe("mock argument", () => {
});
describe("when not provided", () => {
- it("should set as current mock the first one found", async () => {
+ it("should set as current collection the first one found", async () => {
mocks = mocksRunner([PATH_OPTION]);
await waitForServer();
const users = await doFetch("/api/users/2");
@@ -29,8 +29,8 @@ describe("mock argument", () => {
});
describe("when provided and exists", () => {
- it("should set current behavior", async () => {
- mocks = mocksRunner([PATH_OPTION, "--mocks.selected=user-real"]);
+ it("should set current collection", async () => {
+ mocks = mocksRunner([PATH_OPTION, "--mock.collections.selected=user-real"]);
await waitForServer();
const users = await doFetch("/api/users/2");
expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
@@ -39,13 +39,15 @@ describe("mock argument", () => {
describe("when provided and does not exist", () => {
it("should print a warning", async () => {
- mocks = mocksRunner([PATH_OPTION, "--mocks.selected=foo"]);
+ mocks = mocksRunner([PATH_OPTION, "--mock.collections.selected=foo"]);
await waitForServer();
- expect(mocks.logs.current).toEqual(expect.stringContaining("Mock 'foo' was not found"));
+ expect(mocks.logs.current).toEqual(
+ expect.stringContaining("Collection 'foo' was not found")
+ );
});
it("should set as current mock the first one found", async () => {
- mocks = mocksRunner([PATH_OPTION, "--mocks.selected=foo"]);
+ mocks = mocksRunner([PATH_OPTION, "--mock.collections.selected=foo2"]);
await waitForServer();
const users = await doFetch("/api/users/2");
expect(users.body).toEqual({ id: 1, name: "John Doe" });
diff --git a/test/core-e2e/src/mock-setting.spec.js b/test/core-e2e/src/collection-selected-setting.spec.js
similarity index 80%
rename from test/core-e2e/src/mock-setting.spec.js
rename to test/core-e2e/src/collection-selected-setting.spec.js
index 26a71acb8..63da25886 100644
--- a/test/core-e2e/src/mock-setting.spec.js
+++ b/test/core-e2e/src/collection-selected-setting.spec.js
@@ -16,14 +16,14 @@ const {
removeConfigFile,
} = require("./support/helpers");
-describe("mock setting", () => {
- let core, changeMock;
+describe("collection.selected setting", () => {
+ let core, changeCollection;
beforeAll(async () => {
core = await startCore("web-tutorial");
await waitForServer();
- changeMock = (name) => {
- core.config.namespace("mocks").option("selected").value = name;
+ changeCollection = (name) => {
+ core.config.namespace("mock").namespace("collections").option("selected").value = name;
};
});
@@ -32,10 +32,10 @@ describe("mock setting", () => {
await core.stop();
});
- describe("mock by default", () => {
- it("should have added an alert about mock was not defined", () => {
- expect(findAlert("mocks:settings", core.alerts).message).toEqual(
- expect.stringContaining("Option 'mock' was not defined")
+ describe("collection by default", () => {
+ it("should have added an alert about collection was not defined", () => {
+ expect(findAlert("mock:collections:selected", core.alerts).message).toEqual(
+ expect.stringContaining("Option 'mock.collections.selected' was not defined")
);
});
@@ -61,13 +61,13 @@ describe("mock setting", () => {
});
});
- describe('when changing mock to "user-2"', () => {
+ describe('when changing collection to "user-2"', () => {
beforeAll(() => {
- changeMock("user-2");
+ changeCollection("user-2");
});
it("should have removed alert", () => {
- expect(findAlert("mocks:settings", core.alerts)).toEqual(undefined);
+ expect(findAlert("mock:collections:selected", core.alerts)).toEqual(undefined);
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -94,7 +94,7 @@ describe("mock setting", () => {
describe('when changing mock to "user-real"', () => {
beforeAll(() => {
- changeMock("user-real");
+ changeCollection("user-real");
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -126,12 +126,12 @@ describe("mock setting", () => {
describe('when changing mock to "foo"', () => {
beforeAll(() => {
- changeMock("foo");
+ changeCollection("foo");
});
it("should have added an alert", () => {
- expect(findAlert("mocks:settings", core.alerts).message).toEqual(
- expect.stringContaining("Mock 'foo' was not found")
+ expect(findAlert("mock:collections:selected", core.alerts).message).toEqual(
+ expect.stringContaining("Collection 'foo' was not found")
);
});
@@ -158,13 +158,13 @@ describe("mock setting", () => {
});
});
- describe('when changing mock again to "user-real"', () => {
+ describe('when changing collection again to "user-real"', () => {
beforeAll(() => {
- changeMock("user-real");
+ changeCollection("user-real");
});
it("should have removed alert", () => {
- expect(findAlert("mocks:settings", core.alerts)).toEqual(undefined);
+ expect(findAlert("mock:collections:selected", core.alerts)).toEqual(undefined);
});
});
});
diff --git a/test/core-e2e/src/custom-router.spec.js b/test/core-e2e/src/custom-router.spec.js
index abc7275ba..b537bf2a1 100644
--- a/test/core-e2e/src/custom-router.spec.js
+++ b/test/core-e2e/src/custom-router.spec.js
@@ -26,7 +26,7 @@ describe("when using custom router", () => {
describe("and registering it before initializating the server", () => {
beforeAll(async () => {
core = new Core();
- core.addRouter("/api/custom", customRouter);
+ core.server.addRouter("/api/custom", customRouter);
await core.init({
config: {
readFile: false,
@@ -62,7 +62,7 @@ describe("when using custom router", () => {
});
it("custom router should stop listening when is removed", async () => {
- await core.removeRouter("/api/custom", customRouter);
+ await core.server.removeRouter("/api/custom", customRouter);
const response = await doFetch("/api/custom");
expect(response.status).toEqual(404);
});
@@ -85,7 +85,7 @@ describe("when using custom router", () => {
});
await core.start();
await waitForServer();
- await core.addRouter("/api/custom", customRouter);
+ await core.server.addRouter("/api/custom", customRouter);
});
afterAll(async () => {
@@ -106,7 +106,7 @@ describe("when using custom router", () => {
});
it("custom router should stop listening when is removed", async () => {
- await core.removeRouter("/api/custom", customRouter);
+ await core.server.removeRouter("/api/custom", customRouter);
const response = await doFetch("/api/custom");
expect(response.status).toEqual(404);
});
diff --git a/test/core-e2e/src/delay-argument.spec.js b/test/core-e2e/src/delay-argument.spec.js
index fd1675144..85d359c38 100644
--- a/test/core-e2e/src/delay-argument.spec.js
+++ b/test/core-e2e/src/delay-argument.spec.js
@@ -20,7 +20,7 @@ describe("delay argument", () => {
let mocks;
beforeAll(async () => {
- mocks = mocksRunner(["--files.path=web-tutorial", "--mocks.delay=1000"]);
+ mocks = mocksRunner(["--files.path=web-tutorial", "--mock.routes.delay=1000"]);
await waitForServer();
});
diff --git a/test/core-e2e/src/delay-setting.spec.js b/test/core-e2e/src/delay-setting.spec.js
index 7a01fbaa3..e2ccc325c 100644
--- a/test/core-e2e/src/delay-setting.spec.js
+++ b/test/core-e2e/src/delay-setting.spec.js
@@ -40,7 +40,7 @@ describe("delay setting", () => {
describe("When delay setting is changed", () => {
it("should respond after defined delay", async () => {
- core.config.namespace("mocks").option("delay").value = 1000;
+ core.config.namespace("mock").namespace("routes").option("delay").value = 1000;
const timeCounter = new TimeCounter();
await doFetch("/api/users");
timeCounter.stop();
@@ -50,7 +50,7 @@ describe("delay setting", () => {
describe("When route variant has delay", () => {
it("should respond after route variant defined delay", async () => {
- core.mocks.useRouteVariant("get-users:delayed");
+ core.mock.useRouteVariant("get-users:delayed");
const timeCounter = new TimeCounter();
await doFetch("/api/users");
timeCounter.stop();
@@ -58,7 +58,7 @@ describe("delay setting", () => {
});
it("should respond with same delay after setting delay to zero", async () => {
- core.config.namespace("mocks").option("delay").value = 0;
+ core.config.namespace("mock").namespace("routes").option("delay").value = 0;
const timeCounter = new TimeCounter();
await doFetch("/api/users");
timeCounter.stop();
@@ -66,7 +66,7 @@ describe("delay setting", () => {
});
it("should respond with same delay after setting delay to 4000", async () => {
- core.config.namespace("mocks").option("delay").value = 4000;
+ core.config.namespace("mock").namespace("routes").option("delay").value = 4000;
const timeCounter = new TimeCounter();
await doFetch("/api/users");
timeCounter.stop();
@@ -83,7 +83,7 @@ describe("delay setting", () => {
});
it("should respond with same delay after setting delay to zero", async () => {
- core.config.namespace("mocks").option("delay").value = 0;
+ core.config.namespace("mock").namespace("routes").option("delay").value = 0;
const timeCounter = new TimeCounter();
await doFetch("/api/users/1");
timeCounter.stop();
@@ -93,7 +93,7 @@ describe("delay setting", () => {
describe("When route has delay and also route variant", () => {
it("should respond after route variant defined delay", async () => {
- core.config.namespace("mocks").option("selected").value = "user-2";
+ core.config.namespace("mock").namespace("collections").option("selected").value = "user-2";
const timeCounter = new TimeCounter();
await doFetch("/api/users/1");
timeCounter.stop();
@@ -103,11 +103,11 @@ describe("delay setting", () => {
describe("When route has delay and route variant has zero delay", () => {
afterEach(() => {
- core.mocks.restoreRoutesVariants();
+ core.mock.restoreRouteVariants();
});
it("should respond with no delay", async () => {
- core.mocks.useRouteVariant("get-user:zero-delay");
+ core.mock.useRouteVariant("get-user:zero-delay");
const timeCounter = new TimeCounter();
await doFetch("/api/users/1");
timeCounter.stop();
@@ -115,30 +115,30 @@ describe("delay setting", () => {
});
it("should have zero delay in plain route variant", async () => {
- expect(core.mocks.plainRoutesVariants[2]).toEqual({
- handler: "json",
+ expect(core.mock.routes.plainVariants[2]).toEqual({
+ type: "json",
id: "get-user:zero-delay",
delay: 0,
- response: {
+ preview: {
status: 200,
body: {
id: 1,
name: "John Doe",
},
},
- routeId: "get-user",
+ route: "get-user",
});
});
});
describe("When route has delay and route variant has null delay", () => {
afterEach(() => {
- core.mocks.restoreRoutesVariants();
+ core.mock.restoreRouteVariants();
});
it("should respond with global server delay", async () => {
- core.config.namespace("mocks").option("delay").value = 3000;
- core.mocks.useRouteVariant("get-user:null-delay");
+ core.config.namespace("mock").namespace("routes").option("delay").value = 3000;
+ core.mock.useRouteVariant("get-user:null-delay");
const timeCounter = new TimeCounter();
await doFetch("/api/users/1");
timeCounter.stop();
@@ -146,18 +146,18 @@ describe("delay setting", () => {
});
it("should have null delay in plain route variant", async () => {
- expect(core.mocks.plainRoutesVariants[3]).toEqual({
- handler: "json",
+ expect(core.mock.routes.plainVariants[3]).toEqual({
+ type: "json",
id: "get-user:null-delay",
delay: null,
- response: {
+ preview: {
status: 200,
body: {
id: 1,
name: "John Doe",
},
},
- routeId: "get-user",
+ route: "get-user",
});
});
});
diff --git a/test/core-e2e/src/events.spec.js b/test/core-e2e/src/events.spec.js
index abc8f157a..c5f6b1706 100644
--- a/test/core-e2e/src/events.spec.js
+++ b/test/core-e2e/src/events.spec.js
@@ -28,11 +28,11 @@ describe("events", () => {
beforeAll(async () => {
sandbox = sinon.createSandbox();
spies = {
- onChangeMocks: sandbox.spy(),
+ onChangeMock: sandbox.spy(),
onChangeSettings: sandbox.spy(),
onChangeAlerts: sandbox.spy(),
};
- core = await startCore("web-tutorial", { mocks: { selected: "base" } });
+ core = await startCore("web-tutorial", { mock: { collections: { selected: "base" } } });
await waitForServer();
});
@@ -71,22 +71,42 @@ describe("events", () => {
});
});
- describe("When mock is changed", () => {
+ describe("When routes or collections are changed", () => {
let option, removeSpy;
it("should have emitted event", async () => {
option = core.config.namespace("files").option("path");
- removeSpy = core.onChangeMocks(spies.onChangeMocks);
+ removeSpy = core.mock.onChange(spies.onChangeMock);
option.value = fixturesFolder("web-tutorial-modified");
await waitForServerUrl("/api/new-users");
- expect(spies.onChangeMocks.callCount).toEqual(2);
+ expect(spies.onChangeMock.callCount).toEqual(2);
});
it("should not execute callback when event listener is removed", async () => {
removeSpy();
option.value = fixturesFolder("web-tutorial");
await wait(5000);
- expect(spies.onChangeMocks.callCount).toEqual(2);
+ expect(spies.onChangeMock.callCount).toEqual(2);
+ });
+ });
+
+ describe("When delay is changed", () => {
+ let option, removeSpy;
+
+ it("should have emitted event", async () => {
+ spies.onChangeMock.resetHistory();
+ option = core.config.namespace("mock").namespace("routes").option("delay");
+ removeSpy = core.mock.onChange(spies.onChangeMock);
+ option.value = 1000;
+ await wait(1000);
+ expect(spies.onChangeMock.callCount).toEqual(1);
+ });
+
+ it("should not execute callback when event listener is removed", async () => {
+ removeSpy();
+ option.value = 0;
+ await wait(1000);
+ expect(spies.onChangeMock.callCount).toEqual(1);
});
});
@@ -94,8 +114,8 @@ describe("events", () => {
let option, removeSpy;
it("should have emitted event", async () => {
- option = core.config.namespace("mocks").option("selected");
- removeSpy = core.onChangeAlerts(spies.onChangeAlerts);
+ option = core.config.namespace("mock").namespace("collections").option("selected");
+ removeSpy = core.alertsApi.onChange(spies.onChangeAlerts);
option.value = "unexistant";
await wait(500);
expect(spies.onChangeAlerts.callCount).toEqual(1);
diff --git a/test/core-e2e/src/files-disabled.spec.js b/test/core-e2e/src/files-disabled.spec.js
new file mode 100644
index 000000000..5540d943d
--- /dev/null
+++ b/test/core-e2e/src/files-disabled.spec.js
@@ -0,0 +1,54 @@
+/*
+Copyright 2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const path = require("path");
+const fsExtra = require("fs-extra");
+const { mocksRunner, waitForServer, fixturesFolder } = require("./support/helpers");
+
+const configFile = path.resolve(fixturesFolder("temp"), "mocks.config.js");
+const customStarter = path.resolve(fixturesFolder("temp"), "starter");
+
+describe("when files and config file are disabled", () => {
+ let mocks;
+
+ describe("When inited", () => {
+ beforeAll(async () => {
+ await fsExtra.remove(fixturesFolder("temp"));
+ await fsExtra.ensureDir(fixturesFolder("temp"));
+ await fsExtra.copy(fixturesFolder("starter"), customStarter);
+ mocks = mocksRunner([], {
+ customBinary: customStarter,
+ cwd: fixturesFolder("temp"),
+ env: {
+ MOCKS_FILES_ENABLED: "0",
+ MOCKS_CONFIG_READ_FILE: "false",
+ },
+ });
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ await mocks.kill();
+ await fsExtra.remove(fixturesFolder("temp"));
+ });
+
+ describe("when started", () => {
+ it("should have not created the mocks scaffold", async () => {
+ expect(
+ fsExtra.existsSync(path.resolve(fixturesFolder("temp"), "mocks", "collections.json"))
+ ).toEqual(false);
+ });
+
+ it("should have not created the config file", async () => {
+ expect(fsExtra.existsSync(configFile)).toEqual(false);
+ });
+ });
+ });
+});
diff --git a/test/core-e2e/src/files-error.spec.js b/test/core-e2e/src/files-error.spec.js
index 7a89539b7..40530920e 100644
--- a/test/core-e2e/src/files-error.spec.js
+++ b/test/core-e2e/src/files-error.spec.js
@@ -25,24 +25,26 @@ describe("when there is an error loading files", () => {
});
it("should have two routes", async () => {
- expect(core.mocks.plainRoutes.length).toEqual(2);
+ expect(core.mock.routes.plain.length).toEqual(2);
});
it("should have four route variants", async () => {
- expect(core.mocks.plainRoutesVariants.length).toEqual(5);
+ expect(core.mock.routes.plainVariants.length).toEqual(5);
});
- it("should have no mocks", async () => {
- expect(core.mocks.plainMocks.length).toEqual(0);
+ it("should have no collections", async () => {
+ expect(core.mock.collections.plain.length).toEqual(0);
});
it("should have added an alert about not mock found", async () => {
- expect(findAlert("mocks:empty", core.alerts).message).toEqual("No mocks found");
+ expect(findAlert("mock:collections:empty", core.alerts).message).toEqual(
+ "No collections found"
+ );
});
- it("should have added an alert about error loading mocks", async () => {
- expect(findAlert("files:mocks", core.alerts).message).toEqual(
- expect.stringContaining("Error loading mocks from file")
+ it("should have added an alert about error loading collections", async () => {
+ expect(findAlert("files:collections", core.alerts).message).toEqual(
+ expect.stringContaining("Error loading collections from file")
);
});
});
@@ -58,15 +60,15 @@ describe("when there is an error loading files", () => {
});
it("should have three mocks", async () => {
- expect(core.mocks.plainMocks.length).toEqual(3);
+ expect(core.mock.collections.plain.length).toEqual(3);
});
it("should have zero routes", async () => {
- expect(core.mocks.plainRoutes.length).toEqual(0);
+ expect(core.mock.routes.plain.length).toEqual(0);
});
it("should have zero route variants", async () => {
- expect(core.mocks.plainRoutesVariants.length).toEqual(0);
+ expect(core.mock.routes.plainVariants.length).toEqual(0);
});
it("should have added an alert about error loading routes", async () => {
@@ -75,25 +77,25 @@ describe("when there is an error loading files", () => {
);
});
- it("mocks should not have routes variants", () => {
- expect(core.mocks.plainMocks).toEqual([
+ it("collections should not have routes", () => {
+ expect(core.mock.collections.plain).toEqual([
{
id: "base",
from: null,
- routesVariants: ["get-users:success", "get-user:1"],
- appliedRoutesVariants: [],
+ definedRoutes: ["get-users:success", "get-user:1"],
+ routes: [],
},
{
id: "user-2",
from: "base",
- routesVariants: ["get-user:2"],
- appliedRoutesVariants: [],
+ definedRoutes: ["get-user:2"],
+ routes: [],
},
{
id: "user-real",
from: "base",
- routesVariants: ["get-user:real"],
- appliedRoutesVariants: [],
+ definedRoutes: ["get-user:real"],
+ routes: [],
},
]);
});
diff --git a/test/core-e2e/src/fixtures/config-file-no-path/mocks.config.js b/test/core-e2e/src/fixtures/config-file-no-path/mocks.config.js
index e1c7a6958..9368ece5d 100644
--- a/test/core-e2e/src/fixtures/config-file-no-path/mocks.config.js
+++ b/test/core-e2e/src/fixtures/config-file-no-path/mocks.config.js
@@ -2,8 +2,10 @@ const path = require("path");
module.exports = {
log: "silly",
- mocks: {
- selected: "user-real",
+ mock: {
+ collections: {
+ selected: "user-real",
+ }
},
files: {
watch: false,
diff --git a/test/core-e2e/src/fixtures/config-file-with-plugins/TraceMocksPlugin.js b/test/core-e2e/src/fixtures/config-file-with-plugins/TraceMocksPlugin.js
index ede2a6e7e..5f6f3e699 100644
--- a/test/core-e2e/src/fixtures/config-file-with-plugins/TraceMocksPlugin.js
+++ b/test/core-e2e/src/fixtures/config-file-with-plugins/TraceMocksPlugin.js
@@ -3,7 +3,7 @@ class Plugin {
return "trace-mocks";
}
- constructor({ mocks, config, logger }) {
+ constructor({ mock, config, logger }) {
this._traceMocks = config.addOption({
name: "traceMocks",
type: "boolean",
@@ -12,8 +12,8 @@ class Plugin {
});
this._traceMocks.onChange(this._onChangeTraceMocks.bind(this));
- this._mocks = mocks;
- this._onChangeMocks = this._onChangeMocks.bind(this);
+ this._mock = mock;
+ this._onChangeMock = this._onChangeMock.bind(this);
this._logger = logger;
}
@@ -21,15 +21,15 @@ class Plugin {
return "trace-mocks";
}
- init({ onChangeMocks, logger }) {
+ init({ mock, logger }) {
this._enabled = this._traceMocks.value;
- this._removeChangeMocksListener = onChangeMocks(this._onChangeMocks);
+ this._removeChangeMockListener = mock.onChange(this._onChangeMock);
logger.debug(`traceMocks initial value is ${this._traceMocks.value}`);
}
traceMocks() {
if (this._enabled && this._started) {
- this._logger.info(`There are ${this._mocks.plainMocks.length} mocks available`);
+ this._logger.info(`There are ${this._mock.collections.plain.length} mocks available`);
}
}
@@ -48,7 +48,7 @@ class Plugin {
this._enabled = this._traceMocks.value;
}
- _onChangeMocks() {
+ _onChangeMock() {
this.traceMocks();
}
}
diff --git a/test/core-e2e/src/fixtures/config-file-with-plugins/TraceRoutesPlugin.js b/test/core-e2e/src/fixtures/config-file-with-plugins/TraceRoutesPlugin.js
index 28b4d6fd2..8fdc6d7df 100644
--- a/test/core-e2e/src/fixtures/config-file-with-plugins/TraceRoutesPlugin.js
+++ b/test/core-e2e/src/fixtures/config-file-with-plugins/TraceRoutesPlugin.js
@@ -3,7 +3,7 @@ class Plugin {
return "trace-routes";
}
- constructor({ mocks, config, logger }) {
+ constructor({ mock, config, logger }) {
this._traceRoutes = config.addOption({
name: "traceRoutes",
type: "boolean",
@@ -12,8 +12,8 @@ class Plugin {
});
this._traceRoutes.onChange(this._onChangeTraceRoutes.bind(this));
- this._mocks = mocks;
- this._onChangeMocks = this._onChangeMocks.bind(this);
+ this._mock = mock;
+ this._onChangeMock = this._onChangeMock.bind(this);
this._logger = logger;
}
@@ -21,15 +21,15 @@ class Plugin {
return "trace-routes";
}
- init({ onChangeMocks, logger }) {
+ init({ mock, logger }) {
this._enabled = this._traceRoutes.value;
- this._removeChangeMocksListener = onChangeMocks(this._onChangeMocks);
+ this._removeChangeMocksListener = mock.onChange(this._onChangeMock);
logger.debug(`traceRoutes initial value is ${this._traceRoutes.value}`);
}
traceRoutes() {
if (this._enabled && this._started) {
- this._logger.info(`There are ${this._mocks.plainRoutes.length} routes available`);
+ this._logger.info(`There are ${this._mock.routes.plain.length} routes available`);
}
}
@@ -48,7 +48,7 @@ class Plugin {
this._enabled = this._traceRoutes.value;
}
- _onChangeMocks() {
+ _onChangeMock() {
this.traceRoutes();
}
}
diff --git a/test/core-e2e/src/fixtures/config-file-with-plugins/mocks-server-with-plugins.config.js b/test/core-e2e/src/fixtures/config-file-with-plugins/mocks-server-with-plugins.config.js
index 46ca0bc97..47a1f8d4f 100644
--- a/test/core-e2e/src/fixtures/config-file-with-plugins/mocks-server-with-plugins.config.js
+++ b/test/core-e2e/src/fixtures/config-file-with-plugins/mocks-server-with-plugins.config.js
@@ -9,7 +9,9 @@ module.exports = {
plugins: {
register: [TraceRoutesPlugin],
},
- mocks: {
- selected: "user-2",
+ mock: {
+ collections: {
+ selected: "user-2",
+ }
},
};
diff --git a/packages/core/src/scaffold/mocks/mocks.json b/test/core-e2e/src/fixtures/config-file-with-plugins/mocks/collections.json
similarity index 100%
rename from packages/core/src/scaffold/mocks/mocks.json
rename to test/core-e2e/src/fixtures/config-file-with-plugins/mocks/collections.json
diff --git a/test/core-e2e/src/fixtures/config-file-with-plugins/mocks/mocks.json b/test/core-e2e/src/fixtures/config-file-with-plugins/mocks/mocks.json
deleted file mode 100644
index 04f0b6fc5..000000000
--- a/test/core-e2e/src/fixtures/config-file-with-plugins/mocks/mocks.json
+++ /dev/null
@@ -1,16 +0,0 @@
-[
- {
- "id": "base",
- "routesVariants": ["add-headers:enabled", "get-users:success", "get-user:success"]
- },
- {
- "id": "no-headers",
- "from": "base",
- "routesVariants": ["add-headers:disabled"]
- },
- {
- "id": "user-real",
- "from": "no-headers",
- "routesVariants": ["get-user:real"]
- }
-]
diff --git a/test/core-e2e/src/fixtures/config-file-with-plugins/mocks/routes/middlewares.js b/test/core-e2e/src/fixtures/config-file-with-plugins/mocks/routes/middlewares.js
index 65704bfd0..73124f58d 100644
--- a/test/core-e2e/src/fixtures/config-file-with-plugins/mocks/routes/middlewares.js
+++ b/test/core-e2e/src/fixtures/config-file-with-plugins/mocks/routes/middlewares.js
@@ -10,8 +10,8 @@ module.exports = [
variants: [
{
id: "enabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (_req, res, next, mocksServer) => {
res.set("x-mocks-server-example", "some-value");
mocksServer.tracer.info(
@@ -23,8 +23,8 @@ module.exports = [
},
{
id: "disabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (_req, _res, next) => next(),
},
},
diff --git a/test/core-e2e/src/fixtures/config-file-with-plugins/mocks/routes/users.js b/test/core-e2e/src/fixtures/config-file-with-plugins/mocks/routes/users.js
index f83b063a9..b2d1f0a27 100644
--- a/test/core-e2e/src/fixtures/config-file-with-plugins/mocks/routes/users.js
+++ b/test/core-e2e/src/fixtures/config-file-with-plugins/mocks/routes/users.js
@@ -22,16 +22,16 @@ module.exports = [
variants: [
{
id: "success", // id of the variant
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200, // status to send
body: USERS, // body to send
},
},
{
id: "error", // id of the variant
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 400, // status to send
body: {
// body to send
@@ -48,16 +48,16 @@ module.exports = [
variants: [
{
id: "success", // id of the variant
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200, // status to send
body: USERS[0], // body to send
},
},
{
id: "real", // id of the variant
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware:(req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
diff --git a/test/core-e2e/src/fixtures/config-file-with-routes-handler/mocks.config.js b/test/core-e2e/src/fixtures/config-file-with-routes-handler/mocks.config.js
index 6fc50863b..ef19a8d12 100644
--- a/test/core-e2e/src/fixtures/config-file-with-routes-handler/mocks.config.js
+++ b/test/core-e2e/src/fixtures/config-file-with-routes-handler/mocks.config.js
@@ -3,9 +3,13 @@ const CustomRoutesHandler = require("./CustomRoutesHandler");
module.exports = {
log: "silly",
- routesHandlers: [CustomRoutesHandler],
- mocks: {
- selected: "custom-users",
+ variantHandlers: {
+ register: [CustomRoutesHandler],
+ },
+ mock: {
+ collections: {
+ selected: "custom-users",
+ }
},
files: {
path: path.resolve(__dirname, "..", "custom-routes-handler"),
diff --git a/test/core-e2e/src/fixtures/config-file/mocks.config.js b/test/core-e2e/src/fixtures/config-file/mocks.config.js
index 63fadcf32..5ea4c01f1 100644
--- a/test/core-e2e/src/fixtures/config-file/mocks.config.js
+++ b/test/core-e2e/src/fixtures/config-file/mocks.config.js
@@ -2,8 +2,10 @@ const path = require("path");
module.exports = {
log: "silly",
- mocks: {
- selected: "user-2",
+ mock: {
+ collections: {
+ selected: "user-2",
+ }
},
files: {
path: path.resolve(__dirname, "..", "temp"),
diff --git a/test/core-e2e/src/fixtures/custom-routes-handler/mocks.js b/test/core-e2e/src/fixtures/custom-routes-handler/collections.js
similarity index 87%
rename from test/core-e2e/src/fixtures/custom-routes-handler/mocks.js
rename to test/core-e2e/src/fixtures/custom-routes-handler/collections.js
index fedbddfde..46a81bbb1 100644
--- a/test/core-e2e/src/fixtures/custom-routes-handler/mocks.js
+++ b/test/core-e2e/src/fixtures/custom-routes-handler/collections.js
@@ -11,11 +11,11 @@ Unless required by applicable law or agreed to in writing, software distributed
module.exports = [
{
id: "base",
- routesVariants: ["get-users:success"],
+ routes: ["get-users:success"],
},
{
id: "custom-users",
from: "base",
- routesVariants: ["get-users:custom-success"],
+ routes: ["get-users:custom-success"],
},
];
diff --git a/test/core-e2e/src/fixtures/custom-routes-handler/routes/users.js b/test/core-e2e/src/fixtures/custom-routes-handler/routes/users.js
index 77261961b..b1868423b 100644
--- a/test/core-e2e/src/fixtures/custom-routes-handler/routes/users.js
+++ b/test/core-e2e/src/fixtures/custom-routes-handler/routes/users.js
@@ -18,16 +18,16 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS,
},
},
{
id: "custom-success",
- handler: "custom",
- response: {
+ type: "custom",
+ options: {
status: 200,
body: USERS,
},
diff --git a/test/core-e2e/src/fixtures/multi-methods/mocks.js b/test/core-e2e/src/fixtures/delays/collections.js
similarity index 87%
rename from test/core-e2e/src/fixtures/multi-methods/mocks.js
rename to test/core-e2e/src/fixtures/delays/collections.js
index e12b01264..032d309ed 100644
--- a/test/core-e2e/src/fixtures/multi-methods/mocks.js
+++ b/test/core-e2e/src/fixtures/delays/collections.js
@@ -11,11 +11,11 @@ Unless required by applicable law or agreed to in writing, software distributed
module.exports = [
{
id: "base",
- routesVariants: ["get-users:success", "get-user:1"],
+ routes: ["get-users:success", "get-user:1"],
},
{
id: "user-2",
from: "base",
- routesVariants: ["get-user:2"],
+ routes: ["get-user:2"],
},
];
diff --git a/test/core-e2e/src/fixtures/delays/routes/user.js b/test/core-e2e/src/fixtures/delays/routes/user.js
index a841c0e30..d8425d842 100644
--- a/test/core-e2e/src/fixtures/delays/routes/user.js
+++ b/test/core-e2e/src/fixtures/delays/routes/user.js
@@ -19,35 +19,35 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- handler: "json",
+ type: "json",
delay: 2000,
- response: {
+ options: {
status: 200,
body: USERS[1],
},
},
{
id: "zero-delay",
- handler: "json",
+ type: "json",
delay: 0,
- response: {
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "null-delay",
- handler: "json",
+ type: "json",
delay: null,
- response: {
+ options: {
status: 200,
body: USERS[0],
},
diff --git a/test/core-e2e/src/fixtures/delays/routes/users.js b/test/core-e2e/src/fixtures/delays/routes/users.js
index 54d4286e4..ebef3d166 100644
--- a/test/core-e2e/src/fixtures/delays/routes/users.js
+++ b/test/core-e2e/src/fixtures/delays/routes/users.js
@@ -18,17 +18,17 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS,
},
},
{
id: "delayed",
- handler: "json",
+ type: "json",
delay: 2000,
- response: {
+ options: {
status: 200,
body: USERS,
},
diff --git a/test/core-e2e/src/fixtures/esm-config/mocks.config.js b/test/core-e2e/src/fixtures/esm-config/mocks.config.js
index b1cb00070..c126f3857 100644
--- a/test/core-e2e/src/fixtures/esm-config/mocks.config.js
+++ b/test/core-e2e/src/fixtures/esm-config/mocks.config.js
@@ -2,8 +2,10 @@ const path = require("path");
module.exports = {
log: "silly",
- mocks: {
- selected: "user-real",
+ mock: {
+ collections: {
+ selected: "user-real",
+ }
},
files: {
babelRegister: {
diff --git a/test/core-e2e/src/fixtures/esm-modified/mocks.js b/test/core-e2e/src/fixtures/esm-modified/collections.js
similarity index 100%
rename from test/core-e2e/src/fixtures/esm-modified/mocks.js
rename to test/core-e2e/src/fixtures/esm-modified/collections.js
diff --git a/test/core-e2e/src/fixtures/esm-modified/routes/middlewares.es b/test/core-e2e/src/fixtures/esm-modified/routes/middlewares.es
index 3c0798fe9..5e6b334b8 100644
--- a/test/core-e2e/src/fixtures/esm-modified/routes/middlewares.es
+++ b/test/core-e2e/src/fixtures/esm-modified/routes/middlewares.es
@@ -10,8 +10,8 @@ const middlewares = [
variants: [
{
id: "enabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res, next, mocksServer) => {
res.set("x-mocks-server-example", "custom-header");
mocksServer.tracer.info(
@@ -23,8 +23,8 @@ const middlewares = [
},
{
id: "disabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res, next) => next(),
}
},
diff --git a/test/core-e2e/src/fixtures/esm-modified/routes/users.es b/test/core-e2e/src/fixtures/esm-modified/routes/users.es
index 44dce4e23..dd34c6bfd 100644
--- a/test/core-e2e/src/fixtures/esm-modified/routes/users.es
+++ b/test/core-e2e/src/fixtures/esm-modified/routes/users.es
@@ -13,16 +13,16 @@ const routes = [
variants: [
{
id: "success", // id of the variant
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200, // status to send
body: USERS, // body to send
},
},
{
id: "error", // id of the variant
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 400, // status to send
body: {
// body to send
@@ -39,16 +39,16 @@ const routes = [
variants: [
{
id: "success", // id of the variant
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200, // status to send
body: USERS[0], // body to send
},
},
{
id: "real", // id of the variant
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
@@ -73,8 +73,8 @@ const routes = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: [
...USERS,
diff --git a/test/core-e2e/src/fixtures/esm/mocks.es b/test/core-e2e/src/fixtures/esm/collections.es
similarity index 100%
rename from test/core-e2e/src/fixtures/esm/mocks.es
rename to test/core-e2e/src/fixtures/esm/collections.es
diff --git a/test/core-e2e/src/fixtures/esm/routes/middlewares.es b/test/core-e2e/src/fixtures/esm/routes/middlewares.es
index 3c0798fe9..5e6b334b8 100644
--- a/test/core-e2e/src/fixtures/esm/routes/middlewares.es
+++ b/test/core-e2e/src/fixtures/esm/routes/middlewares.es
@@ -10,8 +10,8 @@ const middlewares = [
variants: [
{
id: "enabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res, next, mocksServer) => {
res.set("x-mocks-server-example", "custom-header");
mocksServer.tracer.info(
@@ -23,8 +23,8 @@ const middlewares = [
},
{
id: "disabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res, next) => next(),
}
},
diff --git a/test/core-e2e/src/fixtures/esm/routes/users.es b/test/core-e2e/src/fixtures/esm/routes/users.es
index 39d718027..342bbc2da 100644
--- a/test/core-e2e/src/fixtures/esm/routes/users.es
+++ b/test/core-e2e/src/fixtures/esm/routes/users.es
@@ -13,16 +13,16 @@ const routes = [
variants: [
{
id: "success", // id of the variant
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200, // status to send
body: USERS, // body to send
},
},
{
id: "error", // id of the variant
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 400, // status to send
body: {
// body to send
@@ -39,16 +39,16 @@ const routes = [
variants: [
{
id: "success", // id of the variant
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200, // status to send
body: USERS[0], // body to send
},
},
{
id: "real", // id of the variant
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
diff --git a/test/core-e2e/src/fixtures/files-error-mock/mocks.js b/test/core-e2e/src/fixtures/files-error-mock/collections.js
similarity index 100%
rename from test/core-e2e/src/fixtures/files-error-mock/mocks.js
rename to test/core-e2e/src/fixtures/files-error-mock/collections.js
diff --git a/test/core-e2e/src/fixtures/files-error-mock/routes/user.js b/test/core-e2e/src/fixtures/files-error-mock/routes/user.js
index c9b2ac50c..531a3f880 100644
--- a/test/core-e2e/src/fixtures/files-error-mock/routes/user.js
+++ b/test/core-e2e/src/fixtures/files-error-mock/routes/user.js
@@ -18,24 +18,24 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[1],
},
},
{
id: "real",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
diff --git a/test/core-e2e/src/fixtures/files-error-mock/routes/users.js b/test/core-e2e/src/fixtures/files-error-mock/routes/users.js
index f406dac80..a49f7e3d6 100644
--- a/test/core-e2e/src/fixtures/files-error-mock/routes/users.js
+++ b/test/core-e2e/src/fixtures/files-error-mock/routes/users.js
@@ -18,16 +18,16 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS,
},
},
{
id: "error",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 403,
body: {
message: "Bad data",
diff --git a/test/core-e2e/src/fixtures/web-tutorial/mocks.js b/test/core-e2e/src/fixtures/files-error-routes/collections.js
similarity index 84%
rename from test/core-e2e/src/fixtures/web-tutorial/mocks.js
rename to test/core-e2e/src/fixtures/files-error-routes/collections.js
index 82511e694..8af8046c4 100644
--- a/test/core-e2e/src/fixtures/web-tutorial/mocks.js
+++ b/test/core-e2e/src/fixtures/files-error-routes/collections.js
@@ -11,16 +11,16 @@ Unless required by applicable law or agreed to in writing, software distributed
module.exports = [
{
id: "base",
- routesVariants: ["get-users:success", "get-user:1"],
+ routes: ["get-users:success", "get-user:1"],
},
{
id: "user-2",
from: "base",
- routesVariants: ["get-user:2"],
+ routes: ["get-user:2"],
},
{
id: "user-real",
from: "base",
- routesVariants: ["get-user:real"],
+ routes: ["get-user:real"],
},
];
diff --git a/test/core-e2e/src/fixtures/files-error-routes/routes/user.js b/test/core-e2e/src/fixtures/files-error-routes/routes/user.js
index c9b2ac50c..531a3f880 100644
--- a/test/core-e2e/src/fixtures/files-error-routes/routes/user.js
+++ b/test/core-e2e/src/fixtures/files-error-routes/routes/user.js
@@ -18,24 +18,24 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[1],
},
},
{
id: "real",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
diff --git a/test/core-e2e/src/fixtures/json-files/mocks.json b/test/core-e2e/src/fixtures/json-files/collections.json
similarity index 100%
rename from test/core-e2e/src/fixtures/json-files/mocks.json
rename to test/core-e2e/src/fixtures/json-files/collections.json
diff --git a/test/core-e2e/src/fixtures/json-files/routes/users.json b/test/core-e2e/src/fixtures/json-files/routes/users.json
index fdd8e4715..2e8865ecc 100644
--- a/test/core-e2e/src/fixtures/json-files/routes/users.json
+++ b/test/core-e2e/src/fixtures/json-files/routes/users.json
@@ -6,8 +6,8 @@
"variants": [
{
"id": "success",
- "handler": "json",
- "response": {
+ "type": "json",
+ "options": {
"status": 200,
"body": [
{
@@ -23,8 +23,8 @@
},
{
"id": "error",
- "handler": "json",
- "response": {
+ "type": "json",
+ "options": {
"status": 403,
"body": {
"message": "Bad data"
@@ -40,8 +40,8 @@
"variants": [
{
"id": "1",
- "handler": "json",
- "response": {
+ "type": "json",
+ "options": {
"status": 200,
"body": {
"id": 1,
@@ -51,8 +51,8 @@
},
{
"id": "2",
- "handler": "json",
- "response": {
+ "type": "json",
+ "options": {
"status": 200,
"body": {
"id": 2,
diff --git a/test/core-e2e/src/fixtures/files-error-routes/mocks.js b/test/core-e2e/src/fixtures/middleware-route/collections.js
similarity index 84%
rename from test/core-e2e/src/fixtures/files-error-routes/mocks.js
rename to test/core-e2e/src/fixtures/middleware-route/collections.js
index 82511e694..bc50dfd33 100644
--- a/test/core-e2e/src/fixtures/files-error-routes/mocks.js
+++ b/test/core-e2e/src/fixtures/middleware-route/collections.js
@@ -11,16 +11,16 @@ Unless required by applicable law or agreed to in writing, software distributed
module.exports = [
{
id: "base",
- routesVariants: ["get-users:success", "get-user:1"],
+ routes: ["tracer:enabled", "get-users:success", "get-user:1"],
},
{
id: "user-2",
from: "base",
- routesVariants: ["get-user:2"],
+ routes: ["get-user:2"],
},
{
id: "user-real",
from: "base",
- routesVariants: ["get-user:real"],
+ routes: ["get-user:real"],
},
];
diff --git a/test/core-e2e/src/fixtures/middleware-route/mocks.js b/test/core-e2e/src/fixtures/middleware-route/mocks.js
deleted file mode 100644
index 86860d90d..000000000
--- a/test/core-e2e/src/fixtures/middleware-route/mocks.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-Copyright 2021 Javier Brea
-
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-*/
-
-module.exports = [
- {
- id: "base",
- routesVariants: ["tracer:enabled", "get-users:success", "get-user:1"],
- },
- {
- id: "user-2",
- from: "base",
- routesVariants: ["get-user:2"],
- },
- {
- id: "user-real",
- from: "base",
- routesVariants: ["get-user:real"],
- },
-];
diff --git a/test/core-e2e/src/fixtures/middleware-route/routes/tracer.js b/test/core-e2e/src/fixtures/middleware-route/routes/tracer.js
index 788ca9893..71621f545 100644
--- a/test/core-e2e/src/fixtures/middleware-route/routes/tracer.js
+++ b/test/core-e2e/src/fixtures/middleware-route/routes/tracer.js
@@ -18,8 +18,8 @@ module.exports = [
variants: [
{
id: "enabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, _res, next, core) => {
core.tracer.info(
`Middleware in request ${req.query.req} => ${req.method} => ${req.url}`
@@ -30,8 +30,8 @@ module.exports = [
},
{
id: "disabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware:(_req, _res, next) => {
next();
},
diff --git a/test/core-e2e/src/fixtures/middleware-route/routes/user.js b/test/core-e2e/src/fixtures/middleware-route/routes/user.js
index c9b2ac50c..531a3f880 100644
--- a/test/core-e2e/src/fixtures/middleware-route/routes/user.js
+++ b/test/core-e2e/src/fixtures/middleware-route/routes/user.js
@@ -18,24 +18,24 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[1],
},
},
{
id: "real",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
diff --git a/test/core-e2e/src/fixtures/middleware-route/routes/users.js b/test/core-e2e/src/fixtures/middleware-route/routes/users.js
index f406dac80..a49f7e3d6 100644
--- a/test/core-e2e/src/fixtures/middleware-route/routes/users.js
+++ b/test/core-e2e/src/fixtures/middleware-route/routes/users.js
@@ -18,16 +18,16 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS,
},
},
{
id: "error",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 403,
body: {
message: "Bad data",
diff --git a/test/core-e2e/src/fixtures/delays/mocks.js b/test/core-e2e/src/fixtures/multi-methods/collections.js
similarity index 87%
rename from test/core-e2e/src/fixtures/delays/mocks.js
rename to test/core-e2e/src/fixtures/multi-methods/collections.js
index e12b01264..032d309ed 100644
--- a/test/core-e2e/src/fixtures/delays/mocks.js
+++ b/test/core-e2e/src/fixtures/multi-methods/collections.js
@@ -11,11 +11,11 @@ Unless required by applicable law or agreed to in writing, software distributed
module.exports = [
{
id: "base",
- routesVariants: ["get-users:success", "get-user:1"],
+ routes: ["get-users:success", "get-user:1"],
},
{
id: "user-2",
from: "base",
- routesVariants: ["get-user:2"],
+ routes: ["get-user:2"],
},
];
diff --git a/test/core-e2e/src/fixtures/multi-methods/routes/user.js b/test/core-e2e/src/fixtures/multi-methods/routes/user.js
index e9420db21..c56f26349 100644
--- a/test/core-e2e/src/fixtures/multi-methods/routes/user.js
+++ b/test/core-e2e/src/fixtures/multi-methods/routes/user.js
@@ -18,16 +18,16 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[1],
},
diff --git a/test/core-e2e/src/fixtures/multi-methods/routes/users.js b/test/core-e2e/src/fixtures/multi-methods/routes/users.js
index f406dac80..a49f7e3d6 100644
--- a/test/core-e2e/src/fixtures/multi-methods/routes/users.js
+++ b/test/core-e2e/src/fixtures/multi-methods/routes/users.js
@@ -18,16 +18,16 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS,
},
},
{
id: "error",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 403,
body: {
message: "Bad data",
diff --git a/test/core-e2e/src/fixtures/quick-start-modified/collections.json b/test/core-e2e/src/fixtures/quick-start-modified/collections.json
new file mode 100644
index 000000000..49d6cb99b
--- /dev/null
+++ b/test/core-e2e/src/fixtures/quick-start-modified/collections.json
@@ -0,0 +1,26 @@
+[
+ {
+ "id": "base",
+ "routes": ["add-headers:enabled", "get-users:success", "get-user:success"]
+ },
+ {
+ "id": "no-headers",
+ "from": "base",
+ "routes": ["add-headers:disabled"]
+ },
+ {
+ "id": "all-users",
+ "from": "base",
+ "routes": ["get-users:all", "get-user:id-3"]
+ },
+ {
+ "id": "user-real",
+ "from": "no-headers",
+ "routes": ["get-user:real"]
+ },
+ {
+ "id": "all-users-user-2",
+ "from": "all-users",
+ "routes": ["get-user:id-2"]
+ }
+]
diff --git a/test/core-e2e/src/fixtures/quick-start-modified/routes/common.js b/test/core-e2e/src/fixtures/quick-start-modified/routes/common.js
new file mode 100644
index 000000000..e5d2b63ce
--- /dev/null
+++ b/test/core-e2e/src/fixtures/quick-start-modified/routes/common.js
@@ -0,0 +1,32 @@
+// Use this file only as a guide for first steps using middleware variants. You can delete it when you have understood the concepts.
+// For a detailed explanation about using middlewares, visit:
+// https://mocks-server.org/docs/usage/variants/middlewares
+
+module.exports = [
+ {
+ id: "add-headers", //route id
+ url: "*", // url in express format
+ method: ["GET", "POST", "PUT", "PATCH"], // HTTP methods
+ variants: [
+ {
+ id: "enabled", // variant id
+ handler: "middleware", // variant handler id
+ options: {
+ // Express middleware to execute
+ middleware: (_req, res, next, core) => {
+ res.set("x-mocks-server-example", "some-value");
+ core.logger.info("Custom header added by route variant middleware");
+ next();
+ },
+ },
+ },
+ {
+ id: "disabled", // variant id
+ handler: "middleware", // variant handler id
+ options: {
+ middleware: (_req, _res, next) => next(), // Express middleware to execute
+ },
+ },
+ ],
+ },
+];
diff --git a/test/core-e2e/src/fixtures/quick-start-modified/routes/users.js b/test/core-e2e/src/fixtures/quick-start-modified/routes/users.js
new file mode 100644
index 000000000..f5ecaefda
--- /dev/null
+++ b/test/core-e2e/src/fixtures/quick-start-modified/routes/users.js
@@ -0,0 +1,115 @@
+// Use this file only as a guide for first steps using routes. Delete it when you have added your own route files.
+// For a detailed explanation regarding each routes property, visit:
+// https://mocks-server.org/docs/usage/routes
+
+// users data
+const USERS = [
+ {
+ id: 1,
+ name: "John Doe",
+ },
+ {
+ id: 2,
+ name: "Jane Doe",
+ },
+];
+
+const ALL_USERS = [
+ ...USERS,
+ {
+ id: 3,
+ name: "Tommy",
+ },
+ {
+ id: 4,
+ name: "Timmy",
+ },
+];
+
+module.exports = [
+ {
+ id: "get-users", // route id
+ url: "/api/users", // url in express format
+ method: "GET", // HTTP method
+ variants: [
+ {
+ id: "success", // variant id
+ type: "json", // variant handler id
+ options: {
+ status: 200, // status to send
+ body: USERS, // body to send
+ },
+ },
+ {
+ id: "all", // variant id
+ type: "json", // variant handler id
+ options: {
+ status: 200, // status to send
+ body: ALL_USERS, // body to send
+ },
+ },
+ {
+ id: "error", // variant id
+ type: "json", // variant handler id
+ options: {
+ status: 400, // status to send
+ // body to send
+ body: {
+ message: "Error",
+ },
+ },
+ },
+ ],
+ },
+ {
+ id: "get-user", // route id
+ url: "/api/users/:id", // url in express format
+ method: "GET", // HTTP method
+ variants: [
+ {
+ id: "success", // variant id
+ type: "json", // variant handler id
+ options: {
+ status: 200, // status to send
+ body: USERS[0], // body to send
+ },
+ },
+ {
+ id: "id-3", // variant id
+ type: "json", // variant handler id
+ options: {
+ status: 200, // status to send
+ body: ALL_USERS[2], // body to send
+ },
+ },
+ {
+ id: "real", // variant id
+ type: "middleware", // variant handler id
+ options: {
+ // Express middleware to execute
+ middleware: (req, res) => {
+ const userId = req.params.id;
+ const user = USERS.find((userData) => userData.id === Number(userId));
+ if (user) {
+ res.status(200);
+ res.send(user);
+ } else {
+ res.status(404);
+ res.send({
+ message: "User not found",
+ });
+ }
+ },
+ },
+ },
+ {
+ id: "id-2", // id of the variant
+ type: "json", // variant type
+ options: {
+ status: 200, // status to send
+ body: ALL_USERS[1], // body to send
+ },
+ }
+ ],
+ },
+];
diff --git a/test/core-e2e/src/fixtures/typescript-config/mocks.config.js b/test/core-e2e/src/fixtures/typescript-config/mocks.config.js
index 2976a73f8..a99f11afa 100644
--- a/test/core-e2e/src/fixtures/typescript-config/mocks.config.js
+++ b/test/core-e2e/src/fixtures/typescript-config/mocks.config.js
@@ -1,8 +1,11 @@
const path = require("path");
module.exports = {
- // mock to use on start
- mocks: { selected: "user-real" },
+ mock: {
+ collections: {
+ selected: "user-real",
+ }
+ },
log: "silly",
files: {
path: path.resolve(__dirname, "..", "typescript"),
diff --git a/test/core-e2e/src/fixtures/typescript-custom-config/mocks.config.js b/test/core-e2e/src/fixtures/typescript-custom-config/mocks.config.js
index 19ac52227..9a47b1305 100644
--- a/test/core-e2e/src/fixtures/typescript-custom-config/mocks.config.js
+++ b/test/core-e2e/src/fixtures/typescript-custom-config/mocks.config.js
@@ -2,8 +2,10 @@ const path = require("path");
module.exports = {
log: "silly",
- mocks: {
- selected: "user-real",
+ mock: {
+ collections: {
+ selected: "user-real",
+ }
},
files: {
path: path.resolve(__dirname, "..", "typescript-imports"),
diff --git a/test/core-e2e/src/fixtures/typescript-imports/mocks.json b/test/core-e2e/src/fixtures/typescript-imports/collections.json
similarity index 100%
rename from test/core-e2e/src/fixtures/typescript-imports/mocks.json
rename to test/core-e2e/src/fixtures/typescript-imports/collections.json
diff --git a/test/core-e2e/src/fixtures/typescript/mocks.ts b/test/core-e2e/src/fixtures/typescript/collections.ts
similarity index 100%
rename from test/core-e2e/src/fixtures/typescript/mocks.ts
rename to test/core-e2e/src/fixtures/typescript/collections.ts
diff --git a/test/core-e2e/src/fixtures/typescript/routes/books.json b/test/core-e2e/src/fixtures/typescript/routes/books.json
index a202a6003..b0199c047 100644
--- a/test/core-e2e/src/fixtures/typescript/routes/books.json
+++ b/test/core-e2e/src/fixtures/typescript/routes/books.json
@@ -6,8 +6,8 @@
"variants": [
{
"id": "success",
- "handler": "json",
- "response": {
+ "type": "json",
+ "options": {
"status": 200,
"body": [
{
diff --git a/test/core-e2e/src/fixtures/typescript/routes/middlewares.ts b/test/core-e2e/src/fixtures/typescript/routes/middlewares.ts
index 076834986..ec48e5263 100644
--- a/test/core-e2e/src/fixtures/typescript/routes/middlewares.ts
+++ b/test/core-e2e/src/fixtures/typescript/routes/middlewares.ts
@@ -18,15 +18,15 @@ const middlewares = [
variants: [
{
id: "enabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware
},
},
{
id: "disabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res, next) => next(),
}
},
diff --git a/test/core-e2e/src/fixtures/typescript/routes/users.ts b/test/core-e2e/src/fixtures/typescript/routes/users.ts
index 39d718027..342bbc2da 100644
--- a/test/core-e2e/src/fixtures/typescript/routes/users.ts
+++ b/test/core-e2e/src/fixtures/typescript/routes/users.ts
@@ -13,16 +13,16 @@ const routes = [
variants: [
{
id: "success", // id of the variant
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200, // status to send
body: USERS, // body to send
},
},
{
id: "error", // id of the variant
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 400, // status to send
body: {
// body to send
@@ -39,16 +39,16 @@ const routes = [
variants: [
{
id: "success", // id of the variant
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200, // status to send
body: USERS[0], // body to send
},
},
{
id: "real", // id of the variant
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
diff --git a/test/core-e2e/src/fixtures/validation-not-array/mocks.js b/test/core-e2e/src/fixtures/validation-not-array/collections.js
similarity index 100%
rename from test/core-e2e/src/fixtures/validation-not-array/mocks.js
rename to test/core-e2e/src/fixtures/validation-not-array/collections.js
diff --git a/test/core-e2e/src/fixtures/validation-not-array/routes/routes-valid.js b/test/core-e2e/src/fixtures/validation-not-array/routes/routes-valid.js
index 2032dedc0..d5a3b1dfb 100644
--- a/test/core-e2e/src/fixtures/validation-not-array/routes/routes-valid.js
+++ b/test/core-e2e/src/fixtures/validation-not-array/routes/routes-valid.js
@@ -6,8 +6,8 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: {},
},
diff --git a/test/core-e2e/src/fixtures/validations/mocks.js b/test/core-e2e/src/fixtures/validations/collections.js
similarity index 50%
rename from test/core-e2e/src/fixtures/validations/mocks.js
rename to test/core-e2e/src/fixtures/validations/collections.js
index aa4d19788..11d1bc134 100644
--- a/test/core-e2e/src/fixtures/validations/mocks.js
+++ b/test/core-e2e/src/fixtures/validations/collections.js
@@ -1,16 +1,16 @@
module.exports = [
{
id: "base",
- routesVariants: ["get-users-invalid:success", "get-user-variant-invalid:1", "get-user:2"],
+ routes: ["get-users-invalid:success", "get-user-variant-invalid:1", "get-user:2"],
},
{
id: "base",
- routesVariants: [],
+ routes: [],
},
{
id: "invalid-variant",
from: "base",
- routesVariants: ["get-user-variant-invalid:2"],
+ routes: ["get-user-variant-invalid:2"],
},
{
id: "invalid-mock",
@@ -18,11 +18,11 @@ module.exports = [
{
id: "invalid-from",
from: "foo",
- routesVariants: ["get-user:2"],
+ routes: ["get-user:2"],
},
{
id: "duplicated-route",
from: "base",
- routesVariants: ["get-user:2", "get-user:1"],
+ routes: ["get-user:2", "get-user:1"],
},
];
diff --git a/test/core-e2e/src/fixtures/validations/routes/users.js b/test/core-e2e/src/fixtures/validations/routes/users.js
index 250c33343..e4fc43880 100644
--- a/test/core-e2e/src/fixtures/validations/routes/users.js
+++ b/test/core-e2e/src/fixtures/validations/routes/users.js
@@ -27,16 +27,16 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[1],
},
@@ -50,24 +50,24 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- handler: "json",
- response: null,
+ type: "json",
+ options: null,
},
],
},
@@ -78,8 +78,8 @@ module.exports = [
variants: [
{
id: "2",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[1],
},
diff --git a/test/core-e2e/src/fixtures/web-tutorial-modified/mocks.js b/test/core-e2e/src/fixtures/web-tutorial-modified/collections.js
similarity index 79%
rename from test/core-e2e/src/fixtures/web-tutorial-modified/mocks.js
rename to test/core-e2e/src/fixtures/web-tutorial-modified/collections.js
index 0141b77f9..937139d37 100644
--- a/test/core-e2e/src/fixtures/web-tutorial-modified/mocks.js
+++ b/test/core-e2e/src/fixtures/web-tutorial-modified/collections.js
@@ -11,21 +11,21 @@ Unless required by applicable law or agreed to in writing, software distributed
module.exports = [
{
id: "base",
- routesVariants: ["get-users:success", "get-user:1", "get-users-new:success"],
+ routes: ["get-users:success", "get-user:1", "get-users-new:success"],
},
{
id: "user-2",
from: "base",
- routesVariants: ["get-user:2"],
+ routes: ["get-user:2"],
},
{
id: "user-real",
from: "base",
- routesVariants: ["get-user:real"],
+ routes: ["get-user:real"],
},
{
id: "users-error",
from: "base",
- routesVariants: ["get-users:error"],
+ routes: ["get-users:error"],
},
];
diff --git a/test/core-e2e/src/fixtures/web-tutorial-modified/routes/user.js b/test/core-e2e/src/fixtures/web-tutorial-modified/routes/user.js
index c9b2ac50c..531a3f880 100644
--- a/test/core-e2e/src/fixtures/web-tutorial-modified/routes/user.js
+++ b/test/core-e2e/src/fixtures/web-tutorial-modified/routes/user.js
@@ -18,24 +18,24 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[1],
},
},
{
id: "real",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
diff --git a/test/core-e2e/src/fixtures/web-tutorial-modified/routes/users.js b/test/core-e2e/src/fixtures/web-tutorial-modified/routes/users.js
index 6275e2c85..5189c67ae 100644
--- a/test/core-e2e/src/fixtures/web-tutorial-modified/routes/users.js
+++ b/test/core-e2e/src/fixtures/web-tutorial-modified/routes/users.js
@@ -18,8 +18,8 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
headers: {
"x-custom-header": "foo-header",
"x-another-header": "another-header",
@@ -30,8 +30,8 @@ module.exports = [
},
{
id: "error",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 403,
body: {
message: "Bad data",
@@ -47,8 +47,8 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: [
...USERS,
diff --git a/test/core-e2e/src/fixtures/web-tutorial/collections.js b/test/core-e2e/src/fixtures/web-tutorial/collections.js
new file mode 100644
index 000000000..8af8046c4
--- /dev/null
+++ b/test/core-e2e/src/fixtures/web-tutorial/collections.js
@@ -0,0 +1,26 @@
+/*
+Copyright 2021 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+module.exports = [
+ {
+ id: "base",
+ routes: ["get-users:success", "get-user:1"],
+ },
+ {
+ id: "user-2",
+ from: "base",
+ routes: ["get-user:2"],
+ },
+ {
+ id: "user-real",
+ from: "base",
+ routes: ["get-user:real"],
+ },
+];
diff --git a/test/core-e2e/src/fixtures/web-tutorial/routes/user.js b/test/core-e2e/src/fixtures/web-tutorial/routes/user.js
index 11830e672..9d1a13c42 100644
--- a/test/core-e2e/src/fixtures/web-tutorial/routes/user.js
+++ b/test/core-e2e/src/fixtures/web-tutorial/routes/user.js
@@ -18,24 +18,24 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[1],
},
},
{
id: "real",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
diff --git a/test/core-e2e/src/fixtures/web-tutorial/routes/users.js b/test/core-e2e/src/fixtures/web-tutorial/routes/users.js
index f406dac80..a49f7e3d6 100644
--- a/test/core-e2e/src/fixtures/web-tutorial/routes/users.js
+++ b/test/core-e2e/src/fixtures/web-tutorial/routes/users.js
@@ -18,16 +18,16 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS,
},
},
{
id: "error",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 403,
body: {
message: "Bad data",
diff --git a/test/core-e2e/src/json-files.spec.js b/test/core-e2e/src/json-files.spec.js
index f9b5f7f0d..1d709f099 100644
--- a/test/core-e2e/src/json-files.spec.js
+++ b/test/core-e2e/src/json-files.spec.js
@@ -17,13 +17,13 @@ const {
} = require("./support/helpers");
describe("json files", () => {
- let core, changeMock;
+ let core, changeCollection;
beforeAll(async () => {
core = await startCore("json-files");
await waitForServer();
- changeMock = (name) => {
- core.config.namespace("mocks").option("selected").value = name;
+ changeCollection = (name) => {
+ core.config.namespace("mock").namespace("collections").option("selected").value = name;
};
});
@@ -32,10 +32,10 @@ describe("json files", () => {
await core.stop();
});
- describe("mock by default", () => {
- it("should have added an alert about mock was not defined", () => {
- expect(findAlert("mocks:settings", core.alerts).message).toEqual(
- expect.stringContaining("Option 'mock' was not defined")
+ describe("collection by default", () => {
+ it("should have added an alert about collection was not defined", () => {
+ expect(findAlert("mock:collections:selected", core.alerts).message).toEqual(
+ expect.stringContaining("Option 'mock.collections.selected' was not defined")
);
});
@@ -61,16 +61,16 @@ describe("json files", () => {
});
});
- describe('when changing mock to "user-2"', () => {
+ describe('when changing collection to "user-2"', () => {
beforeAll(() => {
- changeMock("user-2");
+ changeCollection("user-2");
});
it("should have removed alert", () => {
- expect(findAlert("mocks:settings", core.alerts)).toEqual(undefined);
+ expect(findAlert("mock:collections:selected", core.alerts)).toEqual(undefined);
});
- it("should serve users collection mock under the /api/users path", async () => {
+ it("should serve users collection under the /api/users path", async () => {
const users = await doFetch("/api/users");
expect(users.status).toEqual(200);
expect(users.body).toEqual([
@@ -92,18 +92,18 @@ describe("json files", () => {
});
});
- describe('when changing mock to "foo"', () => {
+ describe('when changing collection to "foo"', () => {
beforeAll(() => {
- changeMock("foo");
+ changeCollection("foo");
});
it("should have added an alert", () => {
- expect(findAlert("mocks:settings", core.alerts).message).toEqual(
- expect.stringContaining("Mock 'foo' was not found")
+ expect(findAlert("mock:collections:selected", core.alerts).message).toEqual(
+ expect.stringContaining("Collection 'foo' was not found")
);
});
- // if mock not exists, it uses the first one found
+ // if collection not exists, it uses the first one found
it("should serve users under the /api/users path", async () => {
const users = await doFetch("/api/users");
expect(users.status).toEqual(200);
diff --git a/test/core-e2e/src/load-mocks-and-routes.spec.js b/test/core-e2e/src/load-collections-and-routes.spec.js
similarity index 64%
rename from test/core-e2e/src/load-mocks-and-routes.spec.js
rename to test/core-e2e/src/load-collections-and-routes.spec.js
index aaef20f24..a0ded0860 100644
--- a/test/core-e2e/src/load-mocks-and-routes.spec.js
+++ b/test/core-e2e/src/load-collections-and-routes.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2021 Javier Brea
+Copyright 2021-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -16,22 +16,27 @@ const {
removeConfigFile,
} = require("./support/helpers");
-describe("loadMocks and loadRoutes methods", () => {
- let core, changeMockAndWait;
+describe("loadCollections and loadRoutes methods", () => {
+ let core, changeMockAndWait, waitUntilCollectionChanged;
beforeAll(async () => {
core = await startCore();
- changeMockAndWait = async (mockName) => {
- core.config.namespace("mocks").option("selected").value = mockName;
+ waitUntilCollectionChanged = async (collectionId) => {
await new Promise((resolve) => {
const interval = setInterval(() => {
- if (core.mocks.current === mockName) {
+ if (core.mock.collections.selected === collectionId) {
clearInterval(interval);
resolve();
}
}, 200);
});
};
+
+ changeMockAndWait = async (collectionId) => {
+ core.config.namespace("mock").namespace("collections").option("selected").value =
+ collectionId;
+ await waitUntilCollectionChanged(collectionId);
+ };
await waitForServer();
});
@@ -50,9 +55,10 @@ describe("loadMocks and loadRoutes methods", () => {
});
});
- describe("When routes and mocks are loaded using core methods", () => {
- it("should have loaded new mocks and routes", async () => {
- core.loadRoutes([
+ describe("When routes and collections are loaded using core methods", () => {
+ it("should have loaded new collections and routes", async () => {
+ const { loadRoutes, loadCollections } = core.mock.createLoaders();
+ loadRoutes([
{
id: "get-books",
url: "/api/books",
@@ -60,14 +66,16 @@ describe("loadMocks and loadRoutes methods", () => {
variants: [
{
id: "success",
- response: {
+ type: "json",
+ options: {
status: 200,
body: [{ id: 1, title: "1984" }],
},
},
{
id: "error",
- response: {
+ type: "json",
+ options: {
status: 403,
body: {
message: "Bad data",
@@ -83,14 +91,24 @@ describe("loadMocks and loadRoutes methods", () => {
variants: [
{
id: "success",
- response: {
+ type: "json",
+ options: {
status: 200,
body: [{ id: 1, name: "George Orwell" }],
},
},
+ {
+ id: "bradbury",
+ type: "json",
+ options: {
+ status: 200,
+ body: [{ id: 1, name: "Ray Bradbury" }],
+ },
+ },
{
id: "error",
- response: {
+ type: "json",
+ options: {
status: 403,
body: {
message: "Bad data",
@@ -100,19 +118,25 @@ describe("loadMocks and loadRoutes methods", () => {
],
},
]);
- core.loadMocks([
+ loadCollections([
{
id: "users-and-library",
from: "base",
- routesVariants: ["get-books:success", "get-authors:success"],
+ routes: ["get-books:success", "get-authors:success"],
},
{
id: "authors-error",
from: "users-and-library",
- routesVariants: ["get-authors:error"],
+ routes: ["get-authors:error"],
+ },
+ {
+ id: "bradbury",
+ from: "users-and-library",
+ routes: ["get-authors:bradbury"],
},
]);
- core.config.namespace("mocks").option("selected").value = "users-and-library";
+ core.config.namespace("mock").namespace("collections").option("selected").value =
+ "users-and-library";
await waitForServerUrl("/api/books");
const books = await doFetch("/api/books");
@@ -128,7 +152,15 @@ describe("loadMocks and loadRoutes methods", () => {
]);
});
- it("should be able to change to a new mock", async () => {
+ it("should be able to change collection using select method", async () => {
+ core.mock.collections.select("bradbury");
+ await waitUntilCollectionChanged("bradbury");
+
+ const authors = await doFetch("/api/authors");
+ expect(authors.body).toEqual([{ id: 1, name: "Ray Bradbury" }]);
+ });
+
+ it("should be able to change to a new collection", async () => {
await changeMockAndWait("authors-error");
const books = await doFetch("/api/books");
expect(books.body).toEqual([{ id: 1, title: "1984" }]);
@@ -143,7 +175,7 @@ describe("loadMocks and loadRoutes methods", () => {
expect(authors.status).toEqual(403);
});
- it("should keep mocks loaded from files", async () => {
+ it("should keep collections loaded from files", async () => {
await changeMockAndWait("base");
const users = await doFetch("/api/users");
expect(users.body).toEqual([
diff --git a/test/core-e2e/src/multi-methods.spec.js b/test/core-e2e/src/multi-methods.spec.js
index 28755ab96..fcb748b3f 100644
--- a/test/core-e2e/src/multi-methods.spec.js
+++ b/test/core-e2e/src/multi-methods.spec.js
@@ -28,41 +28,41 @@ describe("when method is defined as array", () => {
await core.stop();
});
- describe("plain mocks and routes", () => {
+ describe("plain collections and routes", () => {
describe("amounts", () => {
- it("should have two mocks", async () => {
- expect(core.mocks.plainMocks.length).toEqual(2);
+ it("should have two collections", async () => {
+ expect(core.mock.collections.plain.length).toEqual(2);
});
it("should have two routes", async () => {
- expect(core.mocks.plainRoutes.length).toEqual(2);
+ expect(core.mock.routes.plain.length).toEqual(2);
});
it("should have four route variants", async () => {
- expect(core.mocks.plainRoutesVariants.length).toEqual(4);
+ expect(core.mock.routes.plainVariants.length).toEqual(4);
});
});
- describe("plainMocks", () => {
- it("should return plain mocks", async () => {
- expect(core.mocks.plainMocks).toEqual([
+ describe("collections.plain", () => {
+ it("should return plain collections", async () => {
+ expect(core.mock.collections.plain).toEqual([
{
id: "base",
from: null,
- routesVariants: ["get-users:success", "get-user:1"],
- appliedRoutesVariants: ["get-users:success", "get-user:1"],
+ definedRoutes: ["get-users:success", "get-user:1"],
+ routes: ["get-users:success", "get-user:1"],
},
{
id: "user-2",
from: "base",
- routesVariants: ["get-user:2"],
- appliedRoutesVariants: ["get-users:success", "get-user:2"],
+ definedRoutes: ["get-user:2"],
+ routes: ["get-users:success", "get-user:2"],
},
]);
});
it("should return plain routes", async () => {
- expect(core.mocks.plainRoutes).toEqual([
+ expect(core.mock.routes.plain).toEqual([
{
id: "get-user",
url: "/api/users/:id",
@@ -81,12 +81,12 @@ describe("when method is defined as array", () => {
});
it("should return plain routesVariants", async () => {
- expect(core.mocks.plainRoutesVariants).toEqual([
+ expect(core.mock.routes.plainVariants).toEqual([
{
id: "get-user:1",
- routeId: "get-user",
- handler: "json",
- response: {
+ route: "get-user",
+ type: "json",
+ preview: {
body: {
id: 1,
name: "John Doe",
@@ -97,9 +97,9 @@ describe("when method is defined as array", () => {
},
{
id: "get-user:2",
- routeId: "get-user",
- handler: "json",
- response: {
+ route: "get-user",
+ type: "json",
+ preview: {
body: {
id: 2,
name: "Jane Doe",
@@ -110,9 +110,9 @@ describe("when method is defined as array", () => {
},
{
id: "get-users:success",
- routeId: "get-users",
- handler: "json",
- response: {
+ route: "get-users",
+ type: "json",
+ preview: {
body: [
{
id: 1,
@@ -129,9 +129,9 @@ describe("when method is defined as array", () => {
},
{
id: "get-users:error",
- routeId: "get-users",
- handler: "json",
- response: {
+ route: "get-users",
+ type: "json",
+ preview: {
body: {
message: "Bad data",
},
@@ -185,7 +185,7 @@ describe("when method is defined as array", () => {
describe('when using route variant "get-user:2"', () => {
it("should serve users under the /api/users path", async () => {
- core.mocks.useRouteVariant("get-user:2");
+ core.mock.useRouteVariant("get-user:2");
const users = await doFetch("/api/users?req=10");
expect(users.status).toEqual(200);
expect(users.body).toEqual([
diff --git a/test/core-e2e/src/path-argument.spec.js b/test/core-e2e/src/path-argument.spec.js
index c2e2720a0..78bae1482 100644
--- a/test/core-e2e/src/path-argument.spec.js
+++ b/test/core-e2e/src/path-argument.spec.js
@@ -36,7 +36,9 @@ describe("path argument", () => {
});
it("should print a warning about creating folder", async () => {
- expect(mocks.logs.current).toEqual(expect.stringContaining("Mocks folder was not found"));
+ expect(mocks.logs.current).toEqual(
+ expect.stringContaining("Mocks Server folder was not found")
+ );
});
it("should have created a mocks folder", async () => {
@@ -45,7 +47,9 @@ describe("path argument", () => {
it("should have created scaffold folder", async () => {
expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "routes"))).toEqual(true);
- expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "mocks.json"))).toEqual(true);
+ expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "collections.json"))).toEqual(
+ true
+ );
});
});
diff --git a/test/core-e2e/src/path-not-exists.spec.js b/test/core-e2e/src/path-not-exists.spec.js
index f7571f1dc..9b9724218 100644
--- a/test/core-e2e/src/path-not-exists.spec.js
+++ b/test/core-e2e/src/path-not-exists.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2021 Javier Brea
+Copyright 2021-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -27,7 +27,7 @@ describe("when path not exists", () => {
await fsExtra.remove(fixturesFolder(FOLDER));
core = await startCore(FOLDER);
changeMock = (name) => {
- core.config.namespace("mocks").option("selected").value = name;
+ core.config.namespace("mock").namespace("collections").option("selected").value = name;
};
await waitForServer();
});
@@ -45,25 +45,27 @@ describe("when path not exists", () => {
it("should have created scaffold folder", async () => {
expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "routes"))).toEqual(true);
- expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "mocks.json"))).toEqual(true);
+ expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "collections.json"))).toEqual(
+ true
+ );
});
it("should have added an alert about folder not found", async () => {
- expect(findAlert("scaffold:mocks", core.alerts).message).toEqual(
- expect.stringContaining("Mocks folder was not found")
+ expect(findAlert("scaffold:folder", core.alerts).message).toEqual(
+ expect.stringContaining("Mocks Server folder was not found")
);
});
- it("should have three mocks", async () => {
- expect(core.mocks.plainMocks.length).toEqual(3);
+ it("should have four collections", async () => {
+ expect(core.mock.collections.plain.length).toEqual(4);
});
it("should have three routes", async () => {
- expect(core.mocks.plainRoutes.length).toEqual(3);
+ expect(core.mock.routes.plain.length).toEqual(3);
});
- it("should have six routes", async () => {
- expect(core.mocks.plainRoutesVariants.length).toEqual(6);
+ it("should have 8 variants", async () => {
+ expect(core.mock.routes.plainVariants.length).toEqual(8);
});
});
diff --git a/test/core-e2e/src/plain-mocks-and-routes.spec.js b/test/core-e2e/src/plain-mocks-and-routes.spec.js
index 14f32aad1..a138c9a86 100644
--- a/test/core-e2e/src/plain-mocks-and-routes.spec.js
+++ b/test/core-e2e/src/plain-mocks-and-routes.spec.js
@@ -24,45 +24,45 @@ describe("mocks and routes", () => {
});
describe("amounts", () => {
- it("should have three mocks", async () => {
- expect(core.mocks.plainMocks.length).toEqual(3);
+ it("should have three collections", async () => {
+ expect(core.mock.collections.plain.length).toEqual(3);
});
it("should have two routes", async () => {
- expect(core.mocks.plainRoutes.length).toEqual(2);
+ expect(core.mock.routes.plain.length).toEqual(2);
});
it("should have five route variants", async () => {
- expect(core.mocks.plainRoutesVariants.length).toEqual(5);
+ expect(core.mock.routes.plainVariants.length).toEqual(5);
});
});
- describe("plainMocks", () => {
- it("should return plain mocks", async () => {
- expect(core.mocks.plainMocks).toEqual([
+ describe("collections.plain", () => {
+ it("should return plain collections", async () => {
+ expect(core.mock.collections.plain).toEqual([
{
id: "base",
from: null,
- routesVariants: ["get-users:success", "get-user:1"],
- appliedRoutesVariants: ["get-users:success", "get-user:1"],
+ definedRoutes: ["get-users:success", "get-user:1"],
+ routes: ["get-users:success", "get-user:1"],
},
{
id: "user-2",
from: "base",
- routesVariants: ["get-user:2"],
- appliedRoutesVariants: ["get-users:success", "get-user:2"],
+ definedRoutes: ["get-user:2"],
+ routes: ["get-users:success", "get-user:2"],
},
{
id: "user-real",
from: "base",
- routesVariants: ["get-user:real"],
- appliedRoutesVariants: ["get-users:success", "get-user:real"],
+ definedRoutes: ["get-user:real"],
+ routes: ["get-users:success", "get-user:real"],
},
]);
});
it("should return plain routes", async () => {
- expect(core.mocks.plainRoutes).toEqual([
+ expect(core.mock.routes.plain).toEqual([
{
id: "get-user",
url: "/api/users/:id",
@@ -81,12 +81,12 @@ describe("mocks and routes", () => {
});
it("should return plain routesVariants", async () => {
- expect(core.mocks.plainRoutesVariants).toEqual([
+ expect(core.mock.routes.plainVariants).toEqual([
{
id: "get-user:1",
- routeId: "get-user",
- handler: "json",
- response: {
+ route: "get-user",
+ type: "json",
+ preview: {
body: {
id: 1,
name: "John Doe",
@@ -97,9 +97,9 @@ describe("mocks and routes", () => {
},
{
id: "get-user:2",
- routeId: "get-user",
- handler: "json",
- response: {
+ route: "get-user",
+ type: "json",
+ preview: {
body: {
id: 2,
name: "Jane Doe",
@@ -110,16 +110,16 @@ describe("mocks and routes", () => {
},
{
id: "get-user:real",
- routeId: "get-user",
- handler: "middleware",
- response: null,
+ route: "get-user",
+ type: "middleware",
+ preview: null,
delay: null,
},
{
id: "get-users:success",
- routeId: "get-users",
- handler: "json",
- response: {
+ route: "get-users",
+ type: "json",
+ preview: {
body: [
{
id: 1,
@@ -136,9 +136,9 @@ describe("mocks and routes", () => {
},
{
id: "get-users:error",
- routeId: "get-users",
- handler: "json",
- response: {
+ route: "get-users",
+ type: "json",
+ preview: {
body: {
message: "Bad data",
},
diff --git a/test/core-e2e/src/plugin-load-collections-and-routes.spec.js b/test/core-e2e/src/plugin-load-collections-and-routes.spec.js
new file mode 100644
index 000000000..7249940b3
--- /dev/null
+++ b/test/core-e2e/src/plugin-load-collections-and-routes.spec.js
@@ -0,0 +1,172 @@
+/*
+Copyright 2021-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const {
+ startCore,
+ doFetch,
+ waitForServer,
+ waitForServerUrl,
+ removeConfigFile,
+} = require("./support/helpers");
+
+describe("loadCollections and loadRoutes methods", () => {
+ let core, changeMockAndWait;
+
+ beforeAll(async () => {
+ class Plugin {
+ static get id() {
+ return "test-plugin";
+ }
+ register({ mock }) {
+ this._mock = mock;
+ }
+ start() {
+ const { loadRoutes, loadCollections } = this._mock.createLoaders();
+ loadRoutes([
+ {
+ id: "get-books",
+ url: "/api/books",
+ method: "GET",
+ variants: [
+ {
+ id: "success",
+ handler: "json",
+ response: {
+ status: 200,
+ body: [{ id: 1, title: "1984" }],
+ },
+ },
+ {
+ id: "error",
+ handler: "json",
+ response: {
+ status: 403,
+ body: {
+ message: "Bad data",
+ },
+ },
+ },
+ ],
+ },
+ {
+ id: "get-authors",
+ url: "/api/authors",
+ method: "GET",
+ variants: [
+ {
+ id: "success",
+ handler: "json",
+ response: {
+ status: 200,
+ body: [{ id: 1, name: "George Orwell" }],
+ },
+ },
+ {
+ id: "error",
+ handler: "json",
+ response: {
+ status: 403,
+ body: {
+ message: "Bad data",
+ },
+ },
+ },
+ ],
+ },
+ ]);
+ loadCollections([
+ {
+ id: "users-and-library",
+ from: "base",
+ routes: ["get-books:success", "get-authors:success"],
+ },
+ {
+ id: "authors-error",
+ from: "users-and-library",
+ routes: ["get-authors:error"],
+ },
+ ]);
+ }
+ }
+
+ core = await startCore(null, { plugins: { register: [Plugin] } });
+ changeMockAndWait = async (mockName) => {
+ core.config.namespace("mock").namespace("collections").option("selected").value = mockName;
+ await new Promise((resolve) => {
+ const interval = setInterval(() => {
+ if (core.mock.collections.selected === mockName) {
+ clearInterval(interval);
+ resolve();
+ }
+ }, 200);
+ });
+ };
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ removeConfigFile();
+ await core.stop();
+ });
+
+ describe("When started", () => {
+ it("should return users", async () => {
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ });
+
+ it("should have loaded new mocks and routes", async () => {
+ core.config.namespace("mock").namespace("collections").option("selected").value =
+ "users-and-library";
+ await waitForServerUrl("/api/books");
+
+ const books = await doFetch("/api/books");
+ expect(books.body).toEqual([{ id: 1, title: "1984" }]);
+
+ const authors = await doFetch("/api/authors");
+ expect(authors.body).toEqual([{ id: 1, name: "George Orwell" }]);
+
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ });
+
+ it("should be able to change to a new mock", async () => {
+ await changeMockAndWait("authors-error");
+ const books = await doFetch("/api/books");
+ expect(books.body).toEqual([{ id: 1, title: "1984" }]);
+
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+
+ const authors = await doFetch("/api/authors");
+ expect(authors.status).toEqual(403);
+ });
+
+ it("should keep mocks loaded from files", async () => {
+ await changeMockAndWait("base");
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ const authors = await doFetch("/api/authors");
+ expect(authors.status).toEqual(404);
+ });
+ });
+});
diff --git a/test/core-e2e/src/plugins.spec.js b/test/core-e2e/src/plugins.spec.js
index 22f931907..0e257cc88 100644
--- a/test/core-e2e/src/plugins.spec.js
+++ b/test/core-e2e/src/plugins.spec.js
@@ -96,7 +96,8 @@ describe("plugins", () => {
it("should have executed logger in register method", () => {
expect(
- filterLogs(core.logs, "[plugins:test-plugin] Log from register method").length
+ filterLogs(core.logger.globalStore, "[plugins:test-plugin] Log from register method")
+ .length
).toEqual(1);
});
@@ -106,7 +107,8 @@ describe("plugins", () => {
it("should have executed logger in init method", () => {
expect(
- filterLogs(core.logs, "[plugins:test-plugin] Log from init method").length
+ filterLogs(core.logger.globalStore, "[plugins:test-plugin] Log from init method")
+ .length
).toEqual(1);
});
@@ -122,7 +124,8 @@ describe("plugins", () => {
it("should have executed logger in start method", () => {
expect(
- filterLogs(core.logs, "[plugins:test-plugin] Log from start method").length
+ filterLogs(core.logger.globalStore, "[plugins:test-plugin] Log from start method")
+ .length
).toEqual(1);
});
@@ -168,7 +171,8 @@ describe("plugins", () => {
it("should have executed logger in stop method", () => {
expect(
- filterLogs(core.logs, "[plugins:test-plugin] Log from stop method").length
+ filterLogs(core.logger.globalStore, "[plugins:test-plugin] Log from stop method")
+ .length
).toEqual(1);
});
});
@@ -209,11 +213,13 @@ describe("plugins", () => {
// Plugin id is still not available in register method
// It should have been renamed when start alert is received using a different context
context: "plugins:test-plugin:test-register",
+ id: "plugins:test-plugin:test-register",
message: "Warning registering plugin",
error: undefined,
},
{
context: "plugins:test-plugin:test-start",
+ id: "plugins:test-plugin:test-start",
message: "Warning starting plugin",
error: undefined,
},
@@ -230,23 +236,23 @@ describe("plugins", () => {
return "test-plugin";
}
- constructor({ addRouter, alerts, config, logger }) {
+ constructor({ server, alerts, config, logger }) {
logger.info("Log from register method");
- addRouter("/foo-path", customRouter);
+ server.addRouter("/foo-path", customRouter);
alerts.set("test-register", "Warning registering plugin");
registerSpy();
configSpy(config);
}
- init({ onChangeAlerts, onChangeMocks, logger, config }) {
+ init({ alerts, mock, logger, config }) {
logger.info("Log from init method");
initSpy(
config.root.namespace("files").option("path").value,
config.root.namespace("server").option("port").value,
- config.root.namespace("mocks").option("delay").value
+ config.root.namespace("mock").namespace("routes").option("delay").value
);
config.root.option("log").value = "silly";
- onChangeAlerts(changeAlertsSpy);
- onChangeMocks(mocksLoadedSpy);
+ alerts.onChange(changeAlertsSpy);
+ mock.onChange(mocksLoadedSpy);
}
start({ alerts, logger }) {
logger.info("Log from start method");
@@ -267,23 +273,23 @@ describe("plugins", () => {
return "test-plugin";
}
- register({ addRouter, alerts, config, logger }) {
+ register({ server, alerts, config, logger }) {
logger.info("Log from register method");
- addRouter("/foo-path", customRouter);
+ server.addRouter("/foo-path", customRouter);
alerts.set("test-register", "Warning registering plugin");
registerSpy();
configSpy(config);
}
- init({ logger, config, onChangeAlerts, onChangeMocks }) {
+ init({ logger, config, alerts, mock }) {
logger.info("Log from init method");
initSpy(
config.root.namespace("files").option("path").value,
config.root.namespace("server").option("port").value,
- config.root.namespace("mocks").option("delay").value
+ config.root.namespace("mock").namespace("routes").option("delay").value
);
config.root.option("log").value = "silly";
- onChangeAlerts(changeAlertsSpy);
- onChangeMocks(mocksLoadedSpy);
+ alerts.onChange(changeAlertsSpy);
+ mock.onChange(mocksLoadedSpy);
}
start({ alerts, logger }) {
logger.info("Log from start method");
@@ -300,23 +306,23 @@ describe("plugins", () => {
testPlugin(
"created as a Class with register method and without static id",
class Plugin {
- register({ addRouter, alerts, config, logger }) {
+ register({ server, alerts, config, logger }) {
logger.info("Log from register method");
- addRouter("/foo-path", customRouter);
+ server.addRouter("/foo-path", customRouter);
alerts.set("test-register", "Warning registering plugin");
registerSpy();
configSpy(config);
}
- init({ logger, config, onChangeAlerts, onChangeMocks }) {
+ init({ logger, config, alerts, mock }) {
logger.info("Log from init method");
initSpy(
config.root.namespace("files").option("path").value,
config.root.namespace("server").option("port").value,
- config.root.namespace("mocks").option("delay").value
+ config.root.namespace("mock").namespace("routes").option("delay").value
);
config.root.option("log").value = "silly";
- onChangeAlerts(changeAlertsSpy);
- onChangeMocks(mocksLoadedSpy);
+ alerts.onChange(changeAlertsSpy);
+ mock.onChange(mocksLoadedSpy);
}
start({ alerts, logger }) {
logger.info("Log from start method");
@@ -340,8 +346,8 @@ describe("plugins", () => {
return "test-plugin";
}
- register({ addRouter, alerts, config }) {
- addRouter("/foo-path", customRouter);
+ register({ server, alerts, config }) {
+ server.addRouter("/foo-path", customRouter);
alerts.set("test-register", "Warning registering plugin");
registerSpy();
configSpy(config);
diff --git a/test/core-e2e/src/quick-start-tutorial.spec.js b/test/core-e2e/src/quick-start-tutorial.spec.js
new file mode 100644
index 000000000..0584eb648
--- /dev/null
+++ b/test/core-e2e/src/quick-start-tutorial.spec.js
@@ -0,0 +1,229 @@
+/*
+Copyright 2021-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const path = require("path");
+const fsExtra = require("fs-extra");
+const {
+ startCore,
+ doFetch,
+ fixturesFolder,
+ waitForServer,
+ findAlert,
+ removeConfigFile,
+ wait,
+} = require("./support/helpers");
+
+describe("Quick start tutorial", () => {
+ const FOLDER = "unexistant";
+ const quickStartModified = fixturesFolder("quick-start-modified");
+ let core, changeCollection, useRouteVariant, changeFilesPath;
+
+ beforeAll(async () => {
+ await fsExtra.remove(fixturesFolder(FOLDER));
+ core = await startCore(FOLDER);
+ changeCollection = (name) => {
+ core.mock.collections.select(name);
+ };
+ useRouteVariant = (name) => {
+ core.mock.useRouteVariant(name);
+ };
+ changeFilesPath = (folder) => {
+ core.config.namespace("files").option("path").value = folder;
+ };
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ removeConfigFile();
+ await fsExtra.remove(fixturesFolder(FOLDER));
+ await core.stop();
+ });
+
+ describe("when started", () => {
+ it("should have created folder", async () => {
+ expect(fsExtra.existsSync(fixturesFolder(FOLDER))).toEqual(true);
+ });
+
+ it("should have created routes folder", async () => {
+ expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "routes"))).toEqual(true);
+ expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "collections.json"))).toEqual(
+ true
+ );
+ });
+
+ it("should have created config file", async () => {
+ expect(fsExtra.existsSync(path.resolve(fixturesFolder(FOLDER), "collections.json"))).toEqual(
+ true
+ );
+ });
+
+ it("should have added an alert about folder not found", async () => {
+ expect(findAlert("scaffold:folder", core.alerts).message).toEqual(
+ expect.stringContaining("Mocks Server folder was not found")
+ );
+ });
+
+ it("should have four collections", async () => {
+ expect(core.mock.collections.plain.length).toEqual(4);
+ });
+
+ it("should have three routes", async () => {
+ expect(core.mock.routes.plain.length).toEqual(3);
+ });
+
+ it("should have 8 variants", async () => {
+ expect(core.mock.routes.plainVariants.length).toEqual(8);
+ });
+ });
+
+ describe("base mock", () => {
+ it("should serve 2 users under the /api/users path", async () => {
+ const users = await doFetch("/api/users");
+ expect(users.status).toEqual(200);
+ expect(users.headers.get("x-mocks-server-example")).toEqual("some-value");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ });
+
+ it("should serve user 1 under the /api/users/1 path", async () => {
+ const users = await doFetch("/api/users/1");
+ expect(users.headers.get("x-mocks-server-example")).toEqual("some-value");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+
+ it("should serve user 1 under the /api/users/2 path", async () => {
+ const users = await doFetch("/api/users/2");
+ expect(users.headers.get("x-mocks-server-example")).toEqual("some-value");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+ });
+
+ describe("when selecting all-users collection", () => {
+ beforeAll(() => {
+ changeCollection("all-users");
+ });
+
+ it("should serve 4 users under the /api/users path", async () => {
+ const users = await doFetch("/api/users");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ { id: 3, name: "Tommy" },
+ { id: 4, name: "Timmy" },
+ ]);
+ });
+
+ it("should serve user 3 under the /api/users/1 path", async () => {
+ const users = await doFetch("/api/users/1");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual({ id: 3, name: "Tommy" });
+ });
+
+ it("should serve user 3 under the /api/users/2 path", async () => {
+ const users = await doFetch("/api/users/2");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual({ id: 3, name: "Tommy" });
+ });
+ });
+
+ describe("when using get-user:success route variant", () => {
+ beforeAll(() => {
+ useRouteVariant("get-user:success");
+ });
+
+ it("should serve 4 users under the /api/users path", async () => {
+ const users = await doFetch("/api/users");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ { id: 3, name: "Tommy" },
+ { id: 4, name: "Timmy" },
+ ]);
+ });
+
+ it("should serve user 2 under the /api/users/1 path", async () => {
+ const users = await doFetch("/api/users/1");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+
+ it("should serve user 2 under the /api/users/2 path", async () => {
+ const users = await doFetch("/api/users/2");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+ });
+
+ describe("when adding a route variant", () => {
+ beforeAll(async () => {
+ changeFilesPath(quickStartModified);
+ await wait(3000);
+ useRouteVariant("get-user:id-2");
+ });
+
+ it("should serve 4 users under the /api/users path", async () => {
+ const users = await doFetch("/api/users");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ { id: 3, name: "Tommy" },
+ { id: 4, name: "Timmy" },
+ ]);
+ });
+
+ it("should serve user 2 under the /api/users/1 path", async () => {
+ const users = await doFetch("/api/users/1");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
+ });
+
+ it("should serve user 2 under the /api/users/2 path", async () => {
+ const users = await doFetch("/api/users/2");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
+ });
+ });
+
+ describe("when adding a collection", () => {
+ beforeAll(async () => {
+ changeCollection("all-users-user-2");
+ });
+
+ it("should serve 4 users under the /api/users path", async () => {
+ const users = await doFetch("/api/users");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ { id: 3, name: "Tommy" },
+ { id: 4, name: "Timmy" },
+ ]);
+ });
+
+ it("should serve user 2 under the /api/users/1 path", async () => {
+ const users = await doFetch("/api/users/1");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
+ });
+
+ it("should serve user 2 under the /api/users/2 path", async () => {
+ const users = await doFetch("/api/users/2");
+ expect(users.status).toEqual(200);
+ expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
+ });
+ });
+});
diff --git a/test/core-e2e/src/route-handler.spec.js b/test/core-e2e/src/route-handler.spec.js
index 9c061fe9a..fa4aa3274 100644
--- a/test/core-e2e/src/route-handler.spec.js
+++ b/test/core-e2e/src/route-handler.spec.js
@@ -19,15 +19,15 @@ const {
const RouteHandler = require("./fixtures/config-file-with-routes-handler/CustomRoutesHandler");
-describe("when adding route handlers", () => {
+describe("when registering route handlers", () => {
describe("When started", () => {
let core;
beforeAll(async () => {
core = createCore();
- core.addRoutesHandler(RouteHandler);
+ core.variantHandlers.register([RouteHandler]);
await startExistingCore(core, fixturesFolder("custom-routes-handler"), {
- mocks: { selected: "custom-users" },
+ mock: { collections: { selected: "custom-users" } },
});
core.logger.setLevel("debug", { transport: "store" });
});
diff --git a/test/core-e2e/src/route-variants.spec.js b/test/core-e2e/src/route-variants.spec.js
index 7f0965f95..faa4bd73d 100644
--- a/test/core-e2e/src/route-variants.spec.js
+++ b/test/core-e2e/src/route-variants.spec.js
@@ -21,7 +21,7 @@ describe("route variants", () => {
beforeAll(async () => {
core = await startCore("middleware-route", {
- mocks: { selected: "base" },
+ mock: { collections: { selected: "base" } },
});
await waitForServer();
});
@@ -74,7 +74,7 @@ describe("route variants", () => {
describe('when using route variant "get-user:2"', () => {
it("should serve users under the /api/users path", async () => {
- core.mocks.useRouteVariant("get-user:2");
+ core.mock.useRouteVariant("get-user:2");
const users = await doFetch("/api/users?req=4");
expect(users.status).toEqual(200);
expect(users.body).toEqual([
@@ -116,7 +116,7 @@ describe("route variants", () => {
describe('when using route variant "tracer:disabled"', () => {
it("should serve users under the /api/users path", async () => {
- core.mocks.useRouteVariant("tracer:disabled");
+ core.mock.useRouteVariant("tracer:disabled");
const users = await doFetch("/api/users?req=7");
expect(users.status).toEqual(200);
expect(users.body).toEqual([
@@ -130,7 +130,7 @@ describe("route variants", () => {
});
it("should serve user 2 under the /api/users/1 path", async () => {
- core.mocks.useRouteVariant("get-user:2");
+ core.mock.useRouteVariant("get-user:2");
const users = await doFetch("/api/users/1?req=8");
expect(users.status).toEqual(200);
expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
@@ -153,7 +153,7 @@ describe("route variants", () => {
describe('when using route variant "tracer:enabled"', () => {
it("should serve users under the /api/users path", async () => {
- core.mocks.useRouteVariant("tracer:enabled");
+ core.mock.useRouteVariant("tracer:enabled");
const users = await doFetch("/api/users?req=10");
expect(users.status).toEqual(200);
expect(users.body).toEqual([
@@ -195,7 +195,7 @@ describe("route variants", () => {
describe("when restoring route variants", () => {
it("should serve users under the /api/users path", async () => {
- core.mocks.restoreRoutesVariants();
+ core.mock.restoreRouteVariants();
const users = await doFetch("/api/users?req=1");
expect(users.status).toEqual(200);
expect(users.body).toEqual([
@@ -219,7 +219,7 @@ describe("route variants", () => {
describe('when using route variant "get-user:real"', () => {
it("should serve users under the /api/users path", async () => {
- core.mocks.useRouteVariant("get-user:real");
+ core.mock.useRouteVariant("get-user:real");
const users = await doFetch("/api/users");
expect(users.status).toEqual(200);
expect(users.body).toEqual([
@@ -243,7 +243,7 @@ describe("route variants", () => {
describe('when changing mock to "user-2"', () => {
beforeEach(() => {
- core.config.namespace("mocks").option("selected").value = "user-2";
+ core.config.namespace("mock").namespace("collections").option("selected").value = "user-2";
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -270,7 +270,7 @@ describe("route variants", () => {
describe('when using route variant "get-user:real" again', () => {
it("should serve user 1 under the /api/users/1 path", async () => {
- core.mocks.useRouteVariant("get-user:real");
+ core.mock.useRouteVariant("get-user:real");
const users = await doFetch("/api/users/1");
expect(users.status).toEqual(200);
expect(users.body).toEqual({ id: 1, name: "John Doe" });
@@ -285,7 +285,7 @@ describe("route variants", () => {
describe("when restoring route variants again", () => {
it("should serve user 2 under the /api/users/1 path", async () => {
- core.mocks.restoreRoutesVariants();
+ core.mock.restoreRouteVariants();
const users = await doFetch("/api/users/1");
expect(users.status).toEqual(200);
expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
diff --git a/test/core-e2e/src/scaffold.spec.js b/test/core-e2e/src/scaffold.spec.js
index ea9251af6..de23f438e 100644
--- a/test/core-e2e/src/scaffold.spec.js
+++ b/test/core-e2e/src/scaffold.spec.js
@@ -16,6 +16,7 @@ const {
waitForServer,
fixturesFolder,
removeConfigFile,
+ removeNewLines,
} = require("./support/helpers");
const configFile = path.resolve(fixturesFolder("temp"), "mocks.config.js");
@@ -45,7 +46,7 @@ describe("when nor config file nor mocks folder exists", () => {
describe("when started for the first time", () => {
it("should have created the mocks scaffold", async () => {
expect(
- fsExtra.existsSync(path.resolve(fixturesFolder("temp"), "mocks", "mocks.json"))
+ fsExtra.existsSync(path.resolve(fixturesFolder("temp"), "mocks", "collections.json"))
).toEqual(true);
});
@@ -53,9 +54,13 @@ describe("when nor config file nor mocks folder exists", () => {
expect(fsExtra.existsSync(configFile)).toEqual(true);
});
- it("should have base as selected mock in config file", async () => {
- const config = require(configFile);
- expect(config.mocks.selected).toEqual("base");
+ it("should have mock.routes.delay as 0 in config file", async () => {
+ const config = await fsExtra.readFile(configFile, "utf-8");
+ expect(removeNewLines(config)).toEqual(
+ expect.stringContaining(
+ `mock: { routes: { // Global delay to apply to routes //delay: 0, }, collections: { // Selected collection //selected: "base", }, }`
+ )
+ );
});
it("should serve users under the /api/users path", async () => {
@@ -90,9 +95,13 @@ describe("when nor config file nor mocks folder exists", () => {
await waitForServer();
});
- it("should have base as selected mock in config file", async () => {
- const config = require(configFile);
- expect(config.mocks.selected).toEqual("base");
+ it("should have mock.delay as 0 in config file", async () => {
+ const config = await fsExtra.readFile(configFile, "utf-8");
+ expect(removeNewLines(config)).toEqual(
+ expect.stringContaining(
+ `mock: { routes: { // Global delay to apply to routes //delay: 0, }, collections: { // Selected collection //selected: "base", }, }`
+ )
+ );
});
it("should serve users under the /api/users path", async () => {
@@ -144,7 +153,9 @@ describe("when nor config file nor mocks folder exists", () => {
});
it("should have tried to load provided mocks", async () => {
- expect(mocks.logs.all).toEqual(expect.stringContaining("Mock with id 'user-2' is invalid"));
+ expect(mocks.logs.all).toEqual(
+ expect.stringContaining("Collection with id 'user-2' is invalid")
+ );
});
});
@@ -217,7 +228,7 @@ describe("when nor config file nor mocks folder exists", () => {
it("should have created the mocks scaffold", async () => {
expect(
- fsExtra.existsSync(path.resolve(fixturesFolder("temp"), "mocks", "mocks.json"))
+ fsExtra.existsSync(path.resolve(fixturesFolder("temp"), "mocks", "collections.json"))
).toEqual(true);
});
diff --git a/test/core-e2e/src/support/helpers.js b/test/core-e2e/src/support/helpers.js
index eaea72792..e29defcf0 100644
--- a/test/core-e2e/src/support/helpers.js
+++ b/test/core-e2e/src/support/helpers.js
@@ -170,6 +170,10 @@ const removeConfigFile = () => {
}
};
+const removeNewLines = (str) => {
+ return str.replace(/(\r\n|\n|\r)/gm, "");
+};
+
module.exports = {
createCore,
startExistingCore,
@@ -185,4 +189,5 @@ module.exports = {
findAlert,
findTrace,
removeConfigFile,
+ removeNewLines,
};
diff --git a/test/core-e2e/src/validations.spec.js b/test/core-e2e/src/validations.spec.js
index 643f1f8de..06ca52eb9 100644
--- a/test/core-e2e/src/validations.spec.js
+++ b/test/core-e2e/src/validations.spec.js
@@ -38,17 +38,17 @@ describe("mocks and routes validations", () => {
});
it("should have loaded valid routes", () => {
- expect(core.mocks.plainRoutes.length).toEqual(1);
+ expect(core.mock.routes.plain.length).toEqual(1);
});
it("should have added an alert about mocks file loading error", () => {
- expect(findAlert("files:mocks", core.alerts).error.message).toEqual(
+ expect(findAlert("files:collections", core.alerts).error.message).toEqual(
expect.stringContaining("File does not export an array")
);
});
- it("should have not loaded mocks", () => {
- expect(core.mocks.plainMocks.length).toEqual(0);
+ it("should have not loaded collections", () => {
+ expect(core.mock.collections.plain.length).toEqual(0);
});
});
@@ -64,7 +64,7 @@ describe("mocks and routes validations", () => {
it("should have added an alert about route variant with duplicated id", () => {
expect(
- findAlert("mocks:loadRoutes:get-user-variant-invalid:variants:1:duplicated", core.alerts)
+ findAlert("mock:routes:load:get-user-variant-invalid:variants:1:duplicated", core.alerts)
.message
).toEqual(
"Route variant with duplicated id '1' detected in route 'get-user-variant-invalid'. It has been ignored"
@@ -73,16 +73,16 @@ describe("mocks and routes validations", () => {
it("should have added an alert about route variant not valid", () => {
expect(
- findAlert("mocks:loadRoutes:get-user-variant-invalid:variants:2:validation", core.alerts)
+ findAlert("mock:routes:load:get-user-variant-invalid:variants:2:validation", core.alerts)
.message
).toEqual(
- "Variant with id '2' in route with id 'get-user-variant-invalid' is invalid: Invalid 'response' property:: type must be object"
+ "Variant with id '2' in route with id 'get-user-variant-invalid' is invalid: Invalid 'options' property:: type must be object"
);
});
it("should have added an alert about route duplicated", () => {
expect(
- findAlert("mocks:loadRoutes:get-user-variant-invalid:duplicated", core.alerts).message
+ findAlert("mock:routes:load:get-user-variant-invalid:duplicated", core.alerts).message
).toEqual(
"Route with duplicated id 'get-user-variant-invalid' detected. It has been ignored"
);
@@ -90,64 +90,70 @@ describe("mocks and routes validations", () => {
it("should have added an alert about route invalid", () => {
expect(
- findAlert("mocks:loadRoutes:get-users-invalid:validation", core.alerts).message
+ findAlert("mock:routes:load:get-users-invalid:validation", core.alerts).message
).toEqual(
"Route with id 'get-users-invalid' is invalid: /method: enum must be equal to one of the allowed values. /method: type must be array. /method: oneOf must match exactly one schema in oneOf"
);
});
it("should have added an alert about mock routeVariant not found", () => {
- expect(findAlert("mocks:loadMocks:base:variants", core.alerts).message).toEqual(
- "Mock with id 'base' is invalid: routeVariant with id 'get-users-invalid:success' was not found, use a valid 'routeId:variantId' identifier"
+ expect(findAlert("mock:collections:load:base:variants", core.alerts).message).toEqual(
+ "Collection with id 'base' is invalid: routeVariant with id 'get-users-invalid:success' was not found, use a valid 'routeId:variantId' identifier"
);
});
it("should have added an alert about mock duplicated", () => {
- expect(findAlert("mocks:loadMocks:1:duplicated", core.alerts).message).toEqual(
- "Mock with duplicated id 'base' detected. It has been ignored"
+ expect(findAlert("mock:collections:load:1:duplicated", core.alerts).message).toEqual(
+ "Collection with duplicated id 'base' detected. It has been ignored"
);
});
it("should have added an alert about mock routeVariant not found in mock 2", () => {
- expect(findAlert("mocks:loadMocks:invalid-variant:variants", core.alerts).message).toEqual(
- "Mock with id 'invalid-variant' is invalid: routeVariant with id 'get-user-variant-invalid:2' was not found, use a valid 'routeId:variantId' identifier"
+ expect(
+ findAlert("mock:collections:load:invalid-variant:variants", core.alerts).message
+ ).toEqual(
+ "Collection with id 'invalid-variant' is invalid: routeVariant with id 'get-user-variant-invalid:2' was not found, use a valid 'routeId:variantId' identifier"
);
});
it("should have added an alert about invalid mock 3", () => {
- expect(findAlert("mocks:loadMocks:invalid-mock:validation", core.alerts).message).toEqual(
- "Mock with id 'invalid-mock' is invalid: must have required property 'routesVariants'"
+ expect(
+ findAlert("mock:collections:load:invalid-mock:validation", core.alerts).message
+ ).toEqual(
+ "Collection with id 'invalid-mock' is invalid: must have required property 'routes'"
);
});
- it("should have added an alert about mock with invalid from", () => {
- expect(findAlert("mocks:loadMocks:invalid-from:from", core.alerts).message).toEqual(
- "Mock with invalid 'from' property detected, 'foo' was not found"
+ it("should have added an alert about Collection with invalid from", () => {
+ expect(findAlert("mock:collections:load:invalid-from:from", core.alerts).message).toEqual(
+ "Collection with invalid 'from' property detected, 'foo' was not found"
);
});
- it("should have added an alert about mock with duplicated routes", () => {
- expect(findAlert("mocks:loadMocks:duplicated-route:variants", core.alerts).message).toEqual(
- "Mock with id 'duplicated-route' is invalid: route with id 'get-user' is used more than once in the same mock"
+ it("should have added an alert about Collection with duplicated routes", () => {
+ expect(
+ findAlert("mock:collections:load:duplicated-route:variants", core.alerts).message
+ ).toEqual(
+ "Collection with id 'duplicated-route' is invalid: route with id 'get-user' is used more than once in the same collection"
);
});
it("should have added an alert about errors processing mocks", () => {
- expect(filterAlerts("mocks:loadMocks", core.alerts)[0].message).toEqual(
- "Critical errors found while loading mocks: 1"
+ expect(filterAlerts("mock:collections:load", core.alerts)[0].message).toEqual(
+ "Critical errors found while loading collections: 1"
);
});
it("should have not loaded invalid routes", () => {
- expect(core.mocks.plainRoutes.length).toEqual(2);
+ expect(core.mock.routes.plain.length).toEqual(2);
});
it("should have not loaded invalid route variants", () => {
- expect(core.mocks.plainRoutesVariants.length).toEqual(3);
+ expect(core.mock.routes.plainVariants.length).toEqual(3);
});
it("should have not loaded invalid mocks", () => {
- expect(core.mocks.plainMocks.length).toEqual(4);
+ expect(core.mock.collections.plain.length).toEqual(4);
});
it("should return user 2 at /api/users/1", async () => {
@@ -167,8 +173,9 @@ describe("mocks and routes validations", () => {
expect(response.status).toEqual(404);
});
- it("should return user 1 at /api/invalid-users/1 when changing to mock with no valid variant", async () => {
- core.config.namespace("mocks").option("selected").value = "invalid-variant";
+ it("should return user 1 at /api/invalid-users/1 when changing to Collection with no valid variant", async () => {
+ core.config.namespace("mock").namespace("collections").option("selected").value =
+ "invalid-variant";
const response = await doFetch("/api/invalid-users/1");
expect(response.status).toEqual(200);
expect(response.body).toEqual({ id: 1, name: "John Doe" });
diff --git a/test/cypress-commands-e2e/cypress/integration/mocks.js b/test/cypress-commands-e2e/cypress/integration/commands.js
similarity index 87%
rename from test/cypress-commands-e2e/cypress/integration/mocks.js
rename to test/cypress-commands-e2e/cypress/integration/commands.js
index 670aabf5e..8ad4096d1 100644
--- a/test/cypress-commands-e2e/cypress/integration/mocks.js
+++ b/test/cypress-commands-e2e/cypress/integration/commands.js
@@ -24,9 +24,9 @@ describe("Mocks server responses", () => {
});
});
- describe("when mock is changed to custom", () => {
+ describe("when collection is changed to custom", () => {
before(() => {
- cy.mocksSetMock("custom");
+ cy.mocksSetCollection("custom");
cy.visit("/");
});
@@ -62,12 +62,16 @@ describe("Mocks server responses", () => {
});
});
- describe("when settings are changed", () => {
+ describe("when config is changed", () => {
before(() => {
- cy.mocksSetSettings({
- mocks: {
- selected: "standard",
- delay: 0,
+ cy.mocksSetConfig({
+ mock: {
+ collections: {
+ selected: "standard",
+ },
+ routes: {
+ delay: 0,
+ },
},
});
cy.visit("/");
@@ -99,7 +103,7 @@ describe("Mocks server responses", () => {
describe("when route variants are restored", () => {
before(() => {
- cy.mocksRestoreRoutesVariants();
+ cy.mocksRestoreRouteVariants();
cy.visit("/");
});
diff --git a/test/cypress-commands-e2e/mocks/mocks.json b/test/cypress-commands-e2e/mocks/collections.json
similarity index 100%
rename from test/cypress-commands-e2e/mocks/mocks.json
rename to test/cypress-commands-e2e/mocks/collections.json
diff --git a/test/cypress-commands-e2e/package.json b/test/cypress-commands-e2e/package.json
index 453fb5a15..92b3e8f88 100644
--- a/test/cypress-commands-e2e/package.json
+++ b/test/cypress-commands-e2e/package.json
@@ -3,17 +3,17 @@
"scripts": {
"mocks": "mocks-server",
"mocks:ci": "mocks-server --no-plugins.inquirerCli.enabled",
- "mocks:ci:custom-config": "mocks-server --no-plugins.inquirerCli.enabled --server.port=3200 --plugins.adminApi.path=/foo",
+ "mocks:ci:custom-config": "mocks-server --no-plugins.inquirerCli.enabled --server.port=3200 --plugins.adminApi.port=3120",
"build:app": "pnpm -w run nx build cypress-commands-e2e-vanilla-app -- --port=3100",
"build:app:custom-config": "pnpm -w run nx build cypress-commands-e2e-vanilla-app -- --port=3200",
"cypress:install": "cypress install",
"cypress:verify": "cypress verify",
"cypress:open": "cypress open",
"cypress:run": "cypress run",
- "cypress:run:custom-config": "cross-env CYPRESS_MOCKS_SERVER_BASE_URL=http://127.0.0.1:3200 CYPRESS_MOCKS_SERVER_ADMIN_API_PATH=/foo cypress run",
+ "cypress:run:custom-config": "cross-env CYPRESS_MOCKS_SERVER_ADMIN_API_PORT=3120 cypress run",
"start:app": "pnpm -w run nx start cypress-commands-e2e-vanilla-app",
- "mocks:ci-and-start:app": "start-server-and-test mocks:ci http-get://127.0.0.1:3100/admin/about start:app",
- "mocks:ci:custom-config-and-start:app": "start-server-and-test mocks:ci:custom-config http-get://127.0.0.1:3200/foo/about start:app",
+ "mocks:ci-and-start:app": "start-server-and-test mocks:ci http-get://127.0.0.1:3110/api/about start:app",
+ "mocks:ci:custom-config-and-start:app": "start-server-and-test mocks:ci:custom-config http-get://127.0.0.1:3120/api/about start:app",
"test:app": "start-server-and-test mocks:ci-and-start:app http-get://127.0.0.1:3000 cypress:run",
"test:app:custom-config": "start-server-and-test mocks:ci:custom-config-and-start:app http-get://127.0.0.1:3000 cypress:run:custom-config",
"test:e2e": "npm run build:app && npm run test:app && npm run build:app:custom-config && npm run test:app:custom-config"
diff --git a/test/main-e2e/.gitignore b/test/main-e2e/.gitignore
new file mode 100644
index 000000000..3307228f6
--- /dev/null
+++ b/test/main-e2e/.gitignore
@@ -0,0 +1 @@
+/mocks
\ No newline at end of file
diff --git a/test/main-e2e/src/createServer.spec.js b/test/main-e2e/src/createServer.spec.js
new file mode 100644
index 000000000..e304f6084
--- /dev/null
+++ b/test/main-e2e/src/createServer.spec.js
@@ -0,0 +1,351 @@
+/*
+Copyright 2021-2022 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const { createServer } = require("@mocks-server/main");
+
+const { doFetch, waitForServer, cleanRootScaffold } = require("./support/helpers");
+
+describe("createServer", () => {
+ jest.setTimeout(15000);
+ let server;
+
+ beforeAll(async () => {
+ await cleanRootScaffold();
+ server = createServer({
+ files: {
+ enabled: true,
+ },
+ });
+ await server.start();
+ await waitForServer();
+ });
+
+ afterAll(async () => {
+ await server.stop();
+ });
+
+ describe("When started", () => {
+ it("should serve users collection mock under the /api/users path", async () => {
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ });
+
+ it("should serve user 1 under the /api/users/1 path", async () => {
+ const users = await doFetch("/api/users/1");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+
+ it("should serve user 1 under the /api/users/2 path", async () => {
+ const users = await doFetch("/api/users/2");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+ });
+
+ describe("mocks api", () => {
+ it("should return mocks", async () => {
+ const response = await doFetch("/admin/mocks");
+ expect(response.body).toEqual([
+ {
+ id: "base",
+ from: null,
+ routesVariants: ["add-headers:enabled", "get-users:success", "get-user:success"],
+ appliedRoutesVariants: ["add-headers:enabled", "get-users:success", "get-user:success"],
+ },
+ {
+ id: "no-headers",
+ from: "base",
+ routesVariants: ["add-headers:disabled"],
+ appliedRoutesVariants: ["add-headers:disabled", "get-users:success", "get-user:success"],
+ },
+ {
+ id: "all-users",
+ from: "base",
+ routesVariants: ["get-users:all", "get-user:id-3"],
+ appliedRoutesVariants: ["add-headers:enabled", "get-users:all", "get-user:id-3"],
+ },
+ {
+ id: "user-real",
+ from: "no-headers",
+ routesVariants: ["get-user:real"],
+ appliedRoutesVariants: ["add-headers:disabled", "get-users:success", "get-user:real"],
+ },
+ ]);
+ });
+ });
+
+ describe("routes api", () => {
+ it("should return routes", async () => {
+ const response = await doFetch("/admin/routes");
+ expect(response.body).toEqual([
+ {
+ id: "add-headers",
+ url: "*",
+ method: ["GET", "POST", "PUT", "PATCH"],
+ delay: null,
+ variants: ["add-headers:enabled", "add-headers:disabled"],
+ },
+ {
+ id: "get-users",
+ url: "/api/users",
+ method: "GET",
+ delay: null,
+ variants: ["get-users:success", "get-users:all", "get-users:error"],
+ },
+ {
+ id: "get-user",
+ url: "/api/users/:id",
+ method: "GET",
+ delay: null,
+ variants: ["get-user:success", "get-user:id-3", "get-user:real"],
+ },
+ ]);
+ });
+ });
+
+ describe("routes variants api", () => {
+ it("should return routes variants", async () => {
+ const response = await doFetch("/admin/routes-variants");
+ expect(response.body).toEqual([
+ {
+ id: "add-headers:enabled",
+ routeId: "add-headers",
+ handler: "middleware",
+ response: null,
+ delay: null,
+ },
+ {
+ id: "add-headers:disabled",
+ routeId: "add-headers",
+ handler: "middleware",
+ response: null,
+ delay: null,
+ },
+ {
+ id: "get-users:success",
+ routeId: "get-users",
+ handler: "json",
+ response: {
+ body: [
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ],
+ status: 200,
+ },
+ delay: null,
+ },
+ {
+ id: "get-users:all",
+ routeId: "get-users",
+ handler: "json",
+ response: {
+ body: [
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ { id: 3, name: "Tommy" },
+ { id: 4, name: "Timmy" },
+ ],
+ status: 200,
+ },
+ delay: null,
+ },
+ {
+ id: "get-users:error",
+ routeId: "get-users",
+ handler: "json",
+ response: { body: { message: "Error" }, status: 400 },
+ delay: null,
+ },
+ {
+ id: "get-user:success",
+ routeId: "get-user",
+ handler: "json",
+ response: { body: { id: 1, name: "John Doe" }, status: 200 },
+ delay: null,
+ },
+ {
+ id: "get-user:id-3",
+ routeId: "get-user",
+ handler: "json",
+ response: { body: { id: 3, name: "Tommy" }, status: 200 },
+ delay: null,
+ },
+ {
+ id: "get-user:real",
+ routeId: "get-user",
+ handler: "middleware",
+ response: null,
+ delay: null,
+ },
+ ]);
+ });
+ });
+
+ describe('When changing current collection to "user-real"', () => {
+ beforeAll(() => {
+ server.mock.collections.select("user-real");
+ });
+
+ it("should serve users collection mock under the /api/users path", async () => {
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ });
+
+ it("should serve user 1 under the /api/users/1 path", async () => {
+ const users = await doFetch("/api/users/1");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+
+ it("should serve user 2 under the /api/users/2 path", async () => {
+ const users = await doFetch("/api/users/2");
+ expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
+ });
+
+ it("should return not found for /api/users/3 path", async () => {
+ const usersResponse = await doFetch("/api/users/3");
+ expect(usersResponse.status).toEqual(404);
+ });
+ });
+
+ describe("When setting custom route variant", () => {
+ beforeAll(() => {
+ server.mock.useRouteVariant("get-user:success");
+ });
+
+ it("should serve users collection mock under the /api/users path", async () => {
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ });
+
+ it("should serve user 1 under the /api/users/1 path", async () => {
+ const users = await doFetch("/api/users/1");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+
+ it("should serve user 1 under the /api/users/2 path", async () => {
+ const users = await doFetch("/api/users/2");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+
+ it("should return user 2 for /api/users/3 path", async () => {
+ const users = await doFetch("/api/users/3");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+ });
+
+ describe("When restoring route variants", () => {
+ beforeAll(() => {
+ server.mock.restoreRouteVariants();
+ });
+
+ it("should serve users collection mock under the /api/users path", async () => {
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ });
+
+ it("should serve user 1 under the /api/users/1 path", async () => {
+ const users = await doFetch("/api/users/1");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+
+ it("should serve user 2 under the /api/users/2 path", async () => {
+ const users = await doFetch("/api/users/2");
+ expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
+ });
+
+ it("should return not found for /api/users/3 path", async () => {
+ const usersResponse = await doFetch("/api/users/3");
+ expect(usersResponse.status).toEqual(404);
+ });
+ });
+
+ describe("when using api to change current mock", () => {
+ beforeAll(async () => {
+ await doFetch("/admin/settings", {
+ method: "PATCH",
+ body: {
+ mocks: {
+ selected: "base",
+ },
+ },
+ });
+ });
+
+ it("should return new mock when getting settings", async () => {
+ const settingsResponse = await doFetch("/admin/settings");
+ expect(settingsResponse.body.mocks.selected).toEqual("base");
+ });
+
+ it("should serve user 1 under the /api/users/2 path", async () => {
+ const users = await doFetch("/api/users/2");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+ });
+
+ describe("when using api to set route variant", () => {
+ beforeAll(async () => {
+ await doFetch("/admin/mock-custom-routes-variants", {
+ method: "POST",
+ body: {
+ id: "get-user:real",
+ },
+ });
+ });
+
+ it("should return custom route variant in API", async () => {
+ const response = await doFetch("/admin/mock-custom-routes-variants");
+ expect(response.body).toEqual(["get-user:real"]);
+ });
+
+ it("should serve user 1 under the /api/users/1 path", async () => {
+ const users = await doFetch("/api/users/1");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+
+ it("should serve user 2 under the /api/users/2 path", async () => {
+ const users = await doFetch("/api/users/2");
+ expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
+ });
+
+ it("should return not found for /api/users/3 path", async () => {
+ const usersResponse = await doFetch("/api/users/3");
+ expect(usersResponse.status).toEqual(404);
+ });
+ });
+
+ describe("when using api to restore routes variants", () => {
+ beforeAll(async () => {
+ await doFetch("/admin/mock-custom-routes-variants", {
+ method: "DELETE",
+ });
+ });
+
+ it("should return custom route variants in API", async () => {
+ const response = await doFetch("/admin/mock-custom-routes-variants");
+ expect(response.body).toEqual([]);
+ });
+
+ it("should serve user 1 under the /api/users/2 path", async () => {
+ const users = await doFetch("/api/users/1");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ });
+ });
+});
diff --git a/test/main-e2e/src/fixtures/proxy/mocks.config.js b/test/main-e2e/src/fixtures/proxy/mocks.config.js
index e836bf2d9..df55944e9 100644
--- a/test/main-e2e/src/fixtures/proxy/mocks.config.js
+++ b/test/main-e2e/src/fixtures/proxy/mocks.config.js
@@ -1,5 +1,7 @@
module.exports = {
- mocks: {
- selected: "base",
+ mock: {
+ collections: {
+ selected: "base",
+ },
},
};
diff --git a/test/main-e2e/src/fixtures/proxy/mocks/collections.js b/test/main-e2e/src/fixtures/proxy/mocks/collections.js
new file mode 100644
index 000000000..31f5ea86a
--- /dev/null
+++ b/test/main-e2e/src/fixtures/proxy/mocks/collections.js
@@ -0,0 +1,10 @@
+module.exports = [
+ {
+ id: "base",
+ routes: ["proxy-all:enabled"],
+ },
+ {
+ id: "proxy-disabled",
+ routes: ["proxy-all:disabled"],
+ },
+];
diff --git a/test/main-e2e/src/fixtures/proxy/mocks/mocks.js b/test/main-e2e/src/fixtures/proxy/mocks/mocks.js
deleted file mode 100644
index 92dd8d8bb..000000000
--- a/test/main-e2e/src/fixtures/proxy/mocks/mocks.js
+++ /dev/null
@@ -1,10 +0,0 @@
-module.exports = [
- {
- id: "base",
- routesVariants: ["proxy-all:enabled"],
- },
- {
- id: "proxy-disabled",
- routesVariants: ["proxy-all:disabled"],
- },
-];
diff --git a/test/main-e2e/src/fixtures/proxy/mocks/routes/proxy.js b/test/main-e2e/src/fixtures/proxy/mocks/routes/proxy.js
index b22d21351..a7bb9779e 100644
--- a/test/main-e2e/src/fixtures/proxy/mocks/routes/proxy.js
+++ b/test/main-e2e/src/fixtures/proxy/mocks/routes/proxy.js
@@ -6,16 +6,16 @@ module.exports = [
variants: [
{
id: "enabled",
- handler: "proxy-v4",
- response: {
+ type: "proxy-v4",
+ options: {
host: "http://127.0.0.1:3200",
options: {},
},
},
{
id: "disabled",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (_req, _res, next) => next(),
},
},
diff --git a/test/main-e2e/src/proxy.spec.js b/test/main-e2e/src/proxy.spec.js
index 0154122e3..0b192e5e9 100644
--- a/test/main-e2e/src/proxy.spec.js
+++ b/test/main-e2e/src/proxy.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2021-present Javier Brea
+Copyright 2021-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -21,7 +21,7 @@ describe("scaffold", () => {
let mocks, host;
beforeAll(async () => {
- host = mocksRunner(["--server.port=3200"]);
+ host = mocksRunner(["--server.port=3200", "--plugins.adminApi.port=3210"]);
mocks = mocksRunner(["--server.port=3100"], { cwd: fixturesFolder("proxy") });
await waitForServerAndCli();
await waitForServerAndCli(3200);
@@ -34,11 +34,10 @@ describe("scaffold", () => {
describe("When started", () => {
it("should have 2 mocks available", async () => {
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Mocks: 2"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Collections: 2"));
});
it("should not display alerts", async () => {
- console.log(mocks.currentScreen);
expect(mocks.currentScreen).toEqual(expect.not.stringContaining("ALERTS"));
});
@@ -125,7 +124,7 @@ describe("scaffold", () => {
await mocks.pressEnter();
await mocks.cursorDown(1);
const newScreen = await mocks.pressEnter();
- expect(newScreen).toEqual(expect.stringContaining("Current mock: proxy-disabled"));
+ expect(newScreen).toEqual(expect.stringContaining("Current collection: proxy-disabled"));
});
it("should return not found for /api/users path", async () => {
@@ -147,7 +146,7 @@ describe("scaffold", () => {
const newScreen = await mocks.pressEnter();
expect(newScreen).toEqual(
expect.stringContaining(
- "Current mock: proxy-disabled (custom variants: proxy-all:enabled)"
+ "Current collection: proxy-disabled (custom variants: proxy-all:enabled)"
)
);
});
@@ -175,7 +174,9 @@ describe("scaffold", () => {
it("should not display custom route variant in CLI", async () => {
await wait(500);
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Current mock: proxy-disabled"));
+ expect(mocks.currentScreen).toEqual(
+ expect.stringContaining("Current collection: proxy-disabled")
+ );
expect(mocks.currentScreen).toEqual(expect.not.stringContaining("(custom variants:"));
});
@@ -209,7 +210,7 @@ describe("scaffold", () => {
it("should display new mock in CLI", async () => {
await wait(500);
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Current mock: base"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Current collection: base"));
});
});
});
diff --git a/test/main-e2e/src/scaffold.spec.js b/test/main-e2e/src/scaffold.spec.js
index e81013d85..cda54e25e 100644
--- a/test/main-e2e/src/scaffold.spec.js
+++ b/test/main-e2e/src/scaffold.spec.js
@@ -1,5 +1,5 @@
/*
-Copyright 2021-present Javier Brea
+Copyright 2021-2022 Javier Brea
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
@@ -31,8 +31,8 @@ describe("scaffold", () => {
});
describe("When started", () => {
- it("should have 3 mocks available", async () => {
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Mocks: 3"));
+ it("should have 4 mocks available", async () => {
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Collections: 4"));
});
it("should not display behaviors", async () => {
@@ -74,6 +74,12 @@ describe("scaffold", () => {
routesVariants: ["add-headers:disabled"],
appliedRoutesVariants: ["add-headers:disabled", "get-users:success", "get-user:success"],
},
+ {
+ id: "all-users",
+ from: "base",
+ routesVariants: ["get-users:all", "get-user:id-3"],
+ appliedRoutesVariants: ["add-headers:enabled", "get-users:all", "get-user:id-3"],
+ },
{
id: "user-real",
from: "no-headers",
@@ -91,23 +97,23 @@ describe("scaffold", () => {
{
id: "add-headers",
url: "*",
+ method: ["GET", "POST", "PUT", "PATCH"],
delay: null,
- method: "GET",
variants: ["add-headers:enabled", "add-headers:disabled"],
},
{
id: "get-users",
url: "/api/users",
- delay: null,
method: "GET",
- variants: ["get-users:success", "get-users:error"],
+ delay: null,
+ variants: ["get-users:success", "get-users:all", "get-users:error"],
},
{
id: "get-user",
url: "/api/users/:id",
- delay: null,
method: "GET",
- variants: ["get-user:success", "get-user:real"],
+ delay: null,
+ variants: ["get-user:success", "get-user:id-3", "get-user:real"],
},
]);
});
@@ -144,6 +150,21 @@ describe("scaffold", () => {
},
delay: null,
},
+ {
+ id: "get-users:all",
+ routeId: "get-users",
+ handler: "json",
+ response: {
+ body: [
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ { id: 3, name: "Tommy" },
+ { id: 4, name: "Timmy" },
+ ],
+ status: 200,
+ },
+ delay: null,
+ },
{
id: "get-users:error",
routeId: "get-users",
@@ -158,6 +179,13 @@ describe("scaffold", () => {
response: { body: { id: 1, name: "John Doe" }, status: 200 },
delay: null,
},
+ {
+ id: "get-user:id-3",
+ routeId: "get-user",
+ handler: "json",
+ response: { body: { id: 3, name: "Tommy" }, status: 200 },
+ delay: null,
+ },
{
id: "get-user:real",
routeId: "get-user",
@@ -169,12 +197,12 @@ describe("scaffold", () => {
});
});
- describe('When changing current mock to "user-real"', () => {
+ describe('When changing current collection to "user-real"', () => {
it("should display new selected mock", async () => {
await mocks.pressEnter();
- await mocks.cursorDown(2);
+ await mocks.cursorDown(3);
const newScreen = await mocks.pressEnter();
- expect(newScreen).toEqual(expect.stringContaining("Current mock: user-real"));
+ expect(newScreen).toEqual(expect.stringContaining("Current collection: user-real"));
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -205,10 +233,12 @@ describe("scaffold", () => {
it("should display custom route variant", async () => {
await mocks.cursorDown();
await mocks.pressEnter();
- await mocks.cursorDown(4);
+ await mocks.cursorDown(5);
const newScreen = await mocks.pressEnter();
expect(newScreen).toEqual(
- expect.stringContaining("Current mock: user-real (custom variants: get-user:success)")
+ expect.stringContaining(
+ "Current collection: user-real (custom variants: get-user:success)"
+ )
);
});
@@ -240,7 +270,7 @@ describe("scaffold", () => {
it("should display mock", async () => {
await mocks.cursorDown(2);
const newScreen = await mocks.pressEnter();
- expect(newScreen).toEqual(expect.stringContaining("Current mock: user-real"));
+ expect(newScreen).toEqual(expect.stringContaining("Current collection: user-real"));
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -291,7 +321,7 @@ describe("scaffold", () => {
it("should display new mock in CLI", async () => {
await wait(500);
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Current mock: base"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Current collection: base"));
});
});
@@ -308,7 +338,7 @@ describe("scaffold", () => {
it("should display custom route variant in CLI", async () => {
await wait(500);
expect(mocks.currentScreen).toEqual(
- expect.stringContaining("Current mock: base (custom variants: get-user:real)")
+ expect.stringContaining("Current collection: base (custom variants: get-user:real)")
);
});
@@ -342,7 +372,7 @@ describe("scaffold", () => {
it("should not display custom route variant in CLI", async () => {
await wait(500);
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Current mock: base"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Current collection: base"));
expect(mocks.currentScreen).toEqual(expect.not.stringContaining("(custom variants:"));
});
diff --git a/test/main-e2e/src/support/helpers.js b/test/main-e2e/src/support/helpers.js
index e396aefb8..6dc466a52 100644
--- a/test/main-e2e/src/support/helpers.js
+++ b/test/main-e2e/src/support/helpers.js
@@ -27,6 +27,7 @@ const defaultRequestOptions = {
},
};
+const rootFolder = path.resolve(__dirname, "..", "..");
const baseFixturesFolder = path.resolve(__dirname, "..", "fixtures");
const fixturesFolder = (folderName) => {
@@ -44,6 +45,10 @@ const cleanScaffold = async () => {
await fsExtra.remove(path.resolve(scaffoldFolder, "mocks.config.js"));
};
+const cleanRootScaffold = async () => {
+ await fsExtra.remove(path.resolve(rootFolder, "mocks"));
+};
+
const serverUrl = (port) => {
return `http://127.0.0.1:${port || SERVER_PORT}`;
};
@@ -131,4 +136,5 @@ module.exports = {
waitForServerAndCli,
fixturesFolder,
cleanScaffold,
+ cleanRootScaffold,
};
diff --git a/test/plugin-admin-api-swagger-e2e/.eslintrc.json b/test/plugin-admin-api-swagger-e2e/.eslintrc.json
new file mode 100644
index 000000000..dcfd5648b
--- /dev/null
+++ b/test/plugin-admin-api-swagger-e2e/.eslintrc.json
@@ -0,0 +1,11 @@
+{
+ "env": {
+ "browser": true,
+ "es6": true
+ },
+ "parser": "@babel/eslint-parser",
+ "parserOptions": {
+ "sourceType": "module",
+ "requireConfigFile" : false
+ }
+}
diff --git a/test/plugin-admin-api-swagger-e2e/.gitignore b/test/plugin-admin-api-swagger-e2e/.gitignore
new file mode 100644
index 000000000..d621a98c0
--- /dev/null
+++ b/test/plugin-admin-api-swagger-e2e/.gitignore
@@ -0,0 +1,28 @@
+# See https://help.github.com/ignore-files/ for more about ignoring files.
+
+#environment variables
+/.env
+
+# dependencies
+/node_modules
+/cypress/fixtures
+/cypress/screenshots
+
+# tests
+/coverage
+/dist
+
+# misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# ides
+.idea
+.vs
diff --git a/test/plugin-admin-api-swagger-e2e/cypress.json b/test/plugin-admin-api-swagger-e2e/cypress.json
new file mode 100644
index 000000000..704786d0b
--- /dev/null
+++ b/test/plugin-admin-api-swagger-e2e/cypress.json
@@ -0,0 +1,4 @@
+{
+ "baseUrl": "http://127.0.0.1:3110",
+ "video": false
+}
diff --git a/test/plugin-admin-api-swagger-e2e/cypress/integration/swagger.js b/test/plugin-admin-api-swagger-e2e/cypress/integration/swagger.js
new file mode 100644
index 000000000..e404f8e40
--- /dev/null
+++ b/test/plugin-admin-api-swagger-e2e/cypress/integration/swagger.js
@@ -0,0 +1,121 @@
+function operationSelectors(operationId) {
+ const container = `#${operationId}`;
+ const tryButton = `${container} .try-out`;
+ const responses = `${container} .responses-table .response`;
+ const execute = `${container} button.execute`;
+ const liveResponses = `${container} .live-responses-table`;
+ const liveResponseBody = `${liveResponses} tr.response code`;
+ const liveResponseStatus = `${liveResponses} tr.response td.response-col_status`;
+
+ return {
+ container,
+ tryButton,
+ execute,
+ responses,
+ liveResponses,
+ liveResponseStatus,
+ liveResponseBody,
+ };
+}
+
+describe("About section", () => {
+ const SELECTORS = {
+ TITLE: "h2.title",
+ GET_CONFIG: "operations-config-get_config",
+ GET_ALERTS: "operations-alerts-get_alerts",
+ GET_ROUTES: "operations-mock-get_mock_routes",
+ GET_VARIANTS: "operations-mock-get_mock_variants",
+ GET_COLLECTIONS: "operations-mock-get_mock_collections",
+ GET_CUSTOM_ROUTE_VARIANTS: "operations-mock-get_mock_custom_route_variants",
+ };
+
+ function runOperationAndExpect({ operation, status: statusCode, body }) {
+ const selectors = operationSelectors(operation);
+ cy.get(selectors.container).should("be.visible");
+ cy.get(selectors.container).click();
+ cy.get(selectors.tryButton).click();
+ cy.get(selectors.execute).click();
+ cy.get(selectors.liveResponses).should("be.visible");
+ cy.get(selectors.liveResponseStatus).should("have.text", statusCode);
+ cy.get(selectors.liveResponseBody).should("contain.text", body);
+ }
+
+ before(() => {
+ cy.visit("/");
+ });
+
+ it("should display current core version", () => {
+ cy.get(SELECTORS.TITLE).should("contain.text", "Mocks Server admin API");
+ });
+
+ describe("get config operation", () => {
+ const selectors = operationSelectors(SELECTORS.GET_CONFIG);
+
+ it("should be visible", () => {
+ cy.get(selectors.container).should("be.visible");
+ });
+
+ it("should display operation responses when clicked", () => {
+ cy.get(selectors.container).click();
+ cy.get(selectors.responses).should("be.visible");
+ });
+
+ it("should display operation result when try button and execute are clicked", () => {
+ cy.get(selectors.tryButton).click();
+ cy.get(selectors.execute).click();
+ cy.get(selectors.liveResponses).should("be.visible");
+ cy.get(selectors.liveResponseStatus).should("have.text", "200");
+ cy.get(selectors.liveResponseBody).should("contain.text", '"port": 3110');
+ });
+ });
+
+ describe("get alerts operation", () => {
+ it("should display operation result when executed", () => {
+ runOperationAndExpect({
+ operation: SELECTORS.GET_ALERTS,
+ status: 200,
+ body: "Option 'mock.collections.selected' was not defined",
+ });
+ });
+ });
+
+ describe("get routes operation", () => {
+ it("should display operation result when executed", () => {
+ runOperationAndExpect({
+ operation: SELECTORS.GET_ROUTES,
+ status: 200,
+ body: '"id": "get-user"',
+ });
+ });
+ });
+
+ describe("get variants operation", () => {
+ it("should display operation result when executed", () => {
+ runOperationAndExpect({
+ operation: SELECTORS.GET_VARIANTS,
+ status: 200,
+ body: '"route": "get-user"',
+ });
+ });
+ });
+
+ describe("get collections operation", () => {
+ it("should display operation result when executed", () => {
+ runOperationAndExpect({
+ operation: SELECTORS.GET_COLLECTIONS,
+ status: 200,
+ body: '"routes": [',
+ });
+ });
+ });
+
+ describe("get custom route variants operation", () => {
+ it("should display operation result when executed", () => {
+ runOperationAndExpect({
+ operation: SELECTORS.GET_CUSTOM_ROUTE_VARIANTS,
+ status: 200,
+ body: "[]",
+ });
+ });
+ });
+});
diff --git a/test/plugin-admin-api-swagger-e2e/cypress/plugins/index.js b/test/plugin-admin-api-swagger-e2e/cypress/plugins/index.js
new file mode 100644
index 000000000..feee699ee
--- /dev/null
+++ b/test/plugin-admin-api-swagger-e2e/cypress/plugins/index.js
@@ -0,0 +1,4 @@
+module.exports = (on, config) => {
+ require("cypress-fail-fast/plugin")(on, config);
+ return config;
+};
diff --git a/test/plugin-admin-api-swagger-e2e/cypress/support/commands.js b/test/plugin-admin-api-swagger-e2e/cypress/support/commands.js
new file mode 100644
index 000000000..56513b4bb
--- /dev/null
+++ b/test/plugin-admin-api-swagger-e2e/cypress/support/commands.js
@@ -0,0 +1,2 @@
+import "@testing-library/cypress/add-commands";
+import "cypress-fail-fast";
diff --git a/test/plugin-admin-api-swagger-e2e/cypress/support/index.js b/test/plugin-admin-api-swagger-e2e/cypress/support/index.js
new file mode 100644
index 000000000..3cb55dcf9
--- /dev/null
+++ b/test/plugin-admin-api-swagger-e2e/cypress/support/index.js
@@ -0,0 +1,7 @@
+import "./commands";
+
+Cypress.on("uncaught:exception", () => {
+ // returning false here prevents Cypress from
+ // failing the test
+ return false;
+});
diff --git a/test/plugin-admin-api-swagger-e2e/package.json b/test/plugin-admin-api-swagger-e2e/package.json
new file mode 100644
index 000000000..61ede77e7
--- /dev/null
+++ b/test/plugin-admin-api-swagger-e2e/package.json
@@ -0,0 +1,13 @@
+{
+ "private": true,
+ "scripts": {
+ "mocks:ci": "pnpm -w run nx start admin-api-client-unit-mocks",
+ "test": "cypress run",
+ "test:e2e": "start-server-and-test mocks:ci http-get://127.0.0.1:3110/api/about test",
+ "cypress:open": "cypress open",
+ "cypress:run": "cypress run"
+ },
+ "dependencies": {
+ "@mocks-server/main": "workspace:*"
+ }
+}
diff --git a/test/plugin-admin-api-swagger-e2e/project.json b/test/plugin-admin-api-swagger-e2e/project.json
new file mode 100644
index 000000000..e394a8098
--- /dev/null
+++ b/test/plugin-admin-api-swagger-e2e/project.json
@@ -0,0 +1,8 @@
+{
+ "root": "test/plugin-admin-api-swagger-e2e",
+ "projectType": "application",
+ "implicitDependencies": [
+ "admin-api-client-unit-mocks"
+ ],
+ "tags": ["type:test"]
+}
diff --git a/test/plugin-inquirer-cli-e2e/jest.config.js b/test/plugin-inquirer-cli-e2e/jest.config.js
index 1d50cde9e..9bfddfe33 100644
--- a/test/plugin-inquirer-cli-e2e/jest.config.js
+++ b/test/plugin-inquirer-cli-e2e/jest.config.js
@@ -6,7 +6,7 @@ module.exports = {
clearMocks: true,
testMatch: ["/src/**/*.spec.js"],
- // testMatch: ["/src/**/interactive-cli.spec.js"],
+ // testMatch: ["/src/**/files-watch.spec.js"],
// Indicates whether the coverage information should be collected while executing the test
collectCoverage: false,
diff --git a/test/plugin-inquirer-cli-e2e/src/main/arguments-legacy.spec.js b/test/plugin-inquirer-cli-e2e/src/main/arguments-legacy.spec.js
new file mode 100644
index 000000000..f8acb64be
--- /dev/null
+++ b/test/plugin-inquirer-cli-e2e/src/main/arguments-legacy.spec.js
@@ -0,0 +1,119 @@
+/*
+Copyright 2019 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+const { mocksRunner, doFetch, waitForServerAndCli, TimeCounter } = require("./support/helpers");
+
+describe("command line arguments", () => {
+ let mocks;
+
+ afterEach(async () => {
+ await mocks.kill();
+ });
+
+ describe("path option", () => {
+ it("should set mocks folder", async () => {
+ expect.assertions(2);
+ mocks = mocksRunner(["--files.path=web-tutorial"]);
+ await waitForServerAndCli();
+ const users = await doFetch("/api/users");
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Collections: 3"));
+ });
+ });
+
+ describe("mock option", () => {
+ describe("when not provided", () => {
+ it("should set as current mock the first one found", async () => {
+ expect.assertions(2);
+ mocks = mocksRunner(["--files.path=web-tutorial"]);
+ await waitForServerAndCli();
+ const users = await doFetch("/api/users/2");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Current collection: base"));
+ });
+ });
+
+ describe("when provided and exists", () => {
+ it("should set current mock", async () => {
+ expect.assertions(2);
+ mocks = mocksRunner(["--files.path=web-tutorial", "--mocks.selected=user-2"]);
+ await waitForServerAndCli();
+ const users = await doFetch("/api/users/2");
+ expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Current collection: user-2"));
+ });
+ });
+
+ describe("when provided and does not exist", () => {
+ it("should display an alert", async () => {
+ mocks = mocksRunner(["--files.path=web-tutorial", "--mocks.selected=foo"]);
+ await waitForServerAndCli();
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("ALERTS"));
+ expect(mocks.currentScreen).toEqual(
+ expect.stringContaining("Collection 'foo' was not found")
+ );
+ });
+
+ it("should set as current behavior the first one found", async () => {
+ expect.assertions(3);
+ mocks = mocksRunner(["--files.path=web-tutorial", "--mocks.selected=foo"]);
+ await waitForServerAndCli();
+ const users = await doFetch("/api/users/2");
+ expect(users.body).toEqual({ id: 1, name: "John Doe" });
+ expect(mocks.currentScreen).toEqual(
+ expect.stringContaining("Selecting the first one found")
+ );
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Current collection: base"));
+ });
+ });
+ });
+
+ describe("delay legacy option", () => {
+ it("should set delay", async () => {
+ expect.assertions(3);
+ mocks = mocksRunner(["--files.path=web-tutorial", "--mocks.delay=2000"]);
+ await waitForServerAndCli();
+ const timeCounter = new TimeCounter();
+ const users = await doFetch("/api/users");
+ timeCounter.stop();
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Delay: 2000"));
+ expect(timeCounter.total).toBeGreaterThan(1999);
+ }, 10000);
+ });
+
+ describe("log option", () => {
+ it("should set log level", async () => {
+ mocks = mocksRunner(["--files.path=web-tutorial", "--log=debug"]);
+ await waitForServerAndCli();
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Log level: debug"));
+ });
+ });
+
+ describe("emojis option", () => {
+ it("should print emojis by default", async () => {
+ mocks = mocksRunner(["--files.path=web-tutorial"]);
+ await waitForServerAndCli();
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("↕️"));
+ });
+
+ it("should disable emojis when --no-plugins.inquirerCli.emojis argument is received", async () => {
+ mocks = mocksRunner(["--files.path=web-tutorial", "--no-plugins.inquirerCli.emojis"]);
+ await waitForServerAndCli();
+ expect(mocks.currentScreen).toEqual(expect.not.stringContaining("↕️"));
+ });
+ });
+});
diff --git a/test/plugin-inquirer-cli-e2e/src/main/arguments.spec.js b/test/plugin-inquirer-cli-e2e/src/main/arguments.spec.js
index 34fa2ef2c..54b4ef103 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/arguments.spec.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/arguments.spec.js
@@ -27,7 +27,7 @@ describe("command line arguments", () => {
{ id: 1, name: "John Doe" },
{ id: 2, name: "Jane Doe" },
]);
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Mocks: 3"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Collections: 3"));
});
});
@@ -39,37 +39,41 @@ describe("command line arguments", () => {
await waitForServerAndCli();
const users = await doFetch("/api/users/2");
expect(users.body).toEqual({ id: 1, name: "John Doe" });
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Current mock: base"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Current collection: base"));
});
});
describe("when provided and exists", () => {
it("should set current mock", async () => {
expect.assertions(2);
- mocks = mocksRunner(["--files.path=web-tutorial", "--mocks.selected=user-2"]);
+ mocks = mocksRunner(["--files.path=web-tutorial", "--mock.collections.selected=user-2"]);
await waitForServerAndCli();
const users = await doFetch("/api/users/2");
expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Current mock: user-2"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Current collection: user-2"));
});
});
describe("when provided and does not exist", () => {
it("should display an alert", async () => {
- mocks = mocksRunner(["--files.path=web-tutorial", "--mocks.selected=foo"]);
+ mocks = mocksRunner(["--files.path=web-tutorial", "--mock.collections.selected=foo"]);
await waitForServerAndCli();
expect(mocks.currentScreen).toEqual(expect.stringContaining("ALERTS"));
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Mock 'foo' was not found"));
+ expect(mocks.currentScreen).toEqual(
+ expect.stringContaining("Collection 'foo' was not found")
+ );
});
it("should set as current behavior the first one found", async () => {
expect.assertions(3);
- mocks = mocksRunner(["--files.path=web-tutorial", "--mocks.selected=foo"]);
+ mocks = mocksRunner(["--files.path=web-tutorial", "--mock.collections.selected=foo"]);
await waitForServerAndCli();
const users = await doFetch("/api/users/2");
expect(users.body).toEqual({ id: 1, name: "John Doe" });
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Using the first one found"));
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Current mock: base"));
+ expect(mocks.currentScreen).toEqual(
+ expect.stringContaining("Selecting the first one found")
+ );
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Current collection: base"));
});
});
});
@@ -77,7 +81,7 @@ describe("command line arguments", () => {
describe("delay option", () => {
it("should set delay", async () => {
expect.assertions(3);
- mocks = mocksRunner(["--files.path=web-tutorial", "--mocks.delay=2000"]);
+ mocks = mocksRunner(["--files.path=web-tutorial", "--mock.routes.delay=2000"]);
await waitForServerAndCli();
const timeCounter = new TimeCounter();
const users = await doFetch("/api/users");
diff --git a/test/plugin-inquirer-cli-e2e/src/main/disabled.spec.js b/test/plugin-inquirer-cli-e2e/src/main/disabled.spec.js
index 3b25f3eb3..ec8143bd5 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/disabled.spec.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/disabled.spec.js
@@ -38,9 +38,9 @@ describe("command line arguments with cli disabled", () => {
});
});
- describe("behavior option", () => {
+ describe("collection option", () => {
describe("when not provided", () => {
- it("should set as current behavior the first one found", async () => {
+ it("should set as current collection the first one found", async () => {
mocks = mocksRunner(["--files.path=web-tutorial", "--no-plugins.inquirerCli.enabled"]);
await waitForServer();
const users = await doFetch("/api/users/2");
@@ -48,8 +48,8 @@ describe("command line arguments with cli disabled", () => {
});
});
- describe("when provided and exists", () => {
- it("should set current behavior", async () => {
+ describe("when legacy is provided and exists", () => {
+ it("should set current collection", async () => {
mocks = mocksRunner([
"--files.path=web-tutorial",
"--no-plugins.inquirerCli.enabled",
@@ -60,9 +60,22 @@ describe("command line arguments with cli disabled", () => {
expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
});
});
+
+ describe("when is provided and exists", () => {
+ it("should set current collection", async () => {
+ mocks = mocksRunner([
+ "--files.path=web-tutorial",
+ "--no-plugins.inquirerCli.enabled",
+ "--mock.collections.selected=user-2",
+ ]);
+ await waitForServer();
+ const users = await doFetch("/api/users/2");
+ expect(users.body).toEqual({ id: 2, name: "Jane Doe" });
+ });
+ });
});
- describe("delay option", () => {
+ describe("legacy delay option", () => {
it("should set delay", async () => {
expect.assertions(2);
mocks = mocksRunner([
@@ -81,4 +94,24 @@ describe("command line arguments with cli disabled", () => {
expect(timeCounter.total).toBeGreaterThan(1999);
});
});
+
+ describe("legacy option", () => {
+ it("should set delay", async () => {
+ expect.assertions(2);
+ mocks = mocksRunner([
+ "--files.path=web-tutorial",
+ "--no-plugins.inquirerCli.enabled",
+ "--mock.routes.delay=2000",
+ ]);
+ await waitForServer();
+ const timeCounter = new TimeCounter();
+ const users = await doFetch("/api/users");
+ timeCounter.stop();
+ expect(users.body).toEqual([
+ { id: 1, name: "John Doe" },
+ { id: 2, name: "Jane Doe" },
+ ]);
+ expect(timeCounter.total).toBeGreaterThan(1999);
+ });
+ });
});
diff --git a/test/plugin-inquirer-cli-e2e/src/main/files-watch.spec.js b/test/plugin-inquirer-cli-e2e/src/main/files-watch.spec.js
index 8c437753a..cb06f15eb 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/files-watch.spec.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/files-watch.spec.js
@@ -35,11 +35,11 @@ describe("files watcher", () => {
describe("When started", () => {
it("should display available mocks in CLI", async () => {
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Mocks: 3"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Collections: 3"));
});
it("should display current mock in CLI", async () => {
- expect(mocks.logs).toEqual(expect.stringContaining("Current mock: base"));
+ expect(mocks.logs).toEqual(expect.stringContaining("Current collection: base"));
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -69,7 +69,7 @@ describe("files watcher", () => {
describe("without changing current mock", () => {
it("should display available mocks in CLI", async () => {
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Mocks: 4"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Collections: 4"));
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -91,19 +91,19 @@ describe("files watcher", () => {
});
});
- describe('When changing current mock to "user-2"', () => {
+ describe('When changing current collection to "user-2"', () => {
beforeAll(async () => {
await mocks.pressEnter();
await mocks.cursorDown();
await mocks.pressEnter();
});
- it("should display current mock in CLI", async () => {
+ it("should display current collection in CLI", async () => {
await wait(500);
- expect(mocks.logs).toEqual(expect.stringContaining("Current mock: user-2"));
+ expect(mocks.logs).toEqual(expect.stringContaining("Current collection: user-2"));
});
- it("should serve users collection mock under the /api/users path", async () => {
+ it("should serve users collection under the /api/users path", async () => {
const users = await doFetch("/api/users");
expect(users.body).toEqual([
{ id: 1, name: "John Doe modified" },
@@ -131,7 +131,7 @@ describe("files watcher", () => {
it("should display current behavior in CLI", async () => {
await wait(500);
- expect(mocks.logs).toEqual(expect.stringContaining("Current mock: user-real"));
+ expect(mocks.logs).toEqual(expect.stringContaining("Current collection: user-real"));
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -157,25 +157,27 @@ describe("files watcher", () => {
describe("When files are modified and contain an error", () => {
beforeAll(async () => {
fsExtra.copySync(fixturesFolder("files-error-mock"), fixturesFolder("temp"));
- await wait(2000);
+ await wait(3000);
});
it("should display an error", async () => {
expect(mocks.currentScreen).toEqual(
- expect.stringContaining("Error: [files:mocks:error] Error loading mocks from file")
+ expect.stringContaining(
+ "Error: [files:collections:error] Error loading collections from file"
+ )
);
expect(mocks.currentScreen).toEqual(
expect.stringContaining(
- `${pathJoin("main", "fixtures", "temp", "mocks.js")}: foo is not defined`
+ `${pathJoin("main", "fixtures", "temp", "collections.js")}: foo is not defined`
)
);
expect(mocks.currentScreen).toEqual(
- expect.stringContaining(`${pathJoin("main", "fixtures", "temp", "mocks.js")}:11:18`)
+ expect.stringContaining(`${pathJoin("main", "fixtures", "temp", "collections.js")}:11:18`)
);
});
it("should have no mocks available", async () => {
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Mocks: 0"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Collections: 0"));
});
it("should not serve users collection mock under the /api/users path", async () => {
@@ -210,7 +212,7 @@ describe("files watcher", () => {
expect.assertions(2);
expect(mocks.currentScreen).toEqual(expect.not.stringContaining("ALERTS"));
expect(mocks.currentScreen).toEqual(
- expect.stringContaining("Error loading mocks from file")
+ expect.stringContaining("Error loading collections from file")
);
});
@@ -220,7 +222,9 @@ describe("files watcher", () => {
await wait(2000);
expect(mocks.currentScreen).toEqual(expect.not.stringContaining("Displaying logs"));
expect(mocks.currentScreen).toEqual(
- expect.stringContaining("Error: [files:mocks:error] Error loading mocks from file")
+ expect.stringContaining(
+ "Error: [files:collections:error] Error loading collections from file"
+ )
);
expect(mocks.currentScreen).toEqual(expect.stringContaining("ALERTS"));
});
diff --git a/test/plugin-inquirer-cli-e2e/src/main/fixtures/files-error-mock/mocks.js b/test/plugin-inquirer-cli-e2e/src/main/fixtures/files-error-mock/collections.js
similarity index 100%
rename from test/plugin-inquirer-cli-e2e/src/main/fixtures/files-error-mock/mocks.js
rename to test/plugin-inquirer-cli-e2e/src/main/fixtures/files-error-mock/collections.js
diff --git a/test/plugin-inquirer-cli-e2e/src/main/fixtures/files-error-mock/routes/user.js b/test/plugin-inquirer-cli-e2e/src/main/fixtures/files-error-mock/routes/user.js
index bdf33726f..23a7e4896 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/fixtures/files-error-mock/routes/user.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/fixtures/files-error-mock/routes/user.js
@@ -18,24 +18,24 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[1],
},
},
{
id: "real",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
diff --git a/test/plugin-inquirer-cli-e2e/src/main/fixtures/files-error-mock/routes/users.js b/test/plugin-inquirer-cli-e2e/src/main/fixtures/files-error-mock/routes/users.js
index f406dac80..a49f7e3d6 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/fixtures/files-error-mock/routes/users.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/fixtures/files-error-mock/routes/users.js
@@ -18,16 +18,16 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS,
},
},
{
id: "error",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 403,
body: {
message: "Bad data",
diff --git a/test/plugin-inquirer-cli-e2e/src/main/fixtures/mocks.config.js b/test/plugin-inquirer-cli-e2e/src/main/fixtures/mocks.config.js
index 590a5e40c..4fa0958c4 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/fixtures/mocks.config.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/fixtures/mocks.config.js
@@ -11,6 +11,10 @@ module.exports = {
// Allow unknown arguments
//allowUnknownArguments: false,
},
+ variantHandlers: {
+ // Variant Handlers to be registered
+ //register: [],
+ },
plugins: {
// Plugins to be registered
//register: [null],
@@ -19,11 +23,15 @@ module.exports = {
//enabled: true,
},
},
- mocks: {
+ mock: {
// Selected mock
- selected: "base",
- // Global delay to apply to routes
- //delay: 0,
+ collections: {
+ //selected: "base",
+ },
+ routes: {
+ // Global delay to apply to routes
+ //delay: 0,
+ },
},
server: {
// Port number for the server to be listening at
diff --git a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/mocks.js b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/collections.js
similarity index 79%
rename from test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/mocks.js
rename to test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/collections.js
index 0141b77f9..937139d37 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/mocks.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/collections.js
@@ -11,21 +11,21 @@ Unless required by applicable law or agreed to in writing, software distributed
module.exports = [
{
id: "base",
- routesVariants: ["get-users:success", "get-user:1", "get-users-new:success"],
+ routes: ["get-users:success", "get-user:1", "get-users-new:success"],
},
{
id: "user-2",
from: "base",
- routesVariants: ["get-user:2"],
+ routes: ["get-user:2"],
},
{
id: "user-real",
from: "base",
- routesVariants: ["get-user:real"],
+ routes: ["get-user:real"],
},
{
id: "users-error",
from: "base",
- routesVariants: ["get-users:error"],
+ routes: ["get-users:error"],
},
];
diff --git a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/routes/user.js b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/routes/user.js
index bdf33726f..23a7e4896 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/routes/user.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/routes/user.js
@@ -18,24 +18,24 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[1],
},
},
{
id: "real",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
diff --git a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/routes/users.js b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/routes/users.js
index d67bede8a..e1f358b7b 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/routes/users.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial-modified/routes/users.js
@@ -18,8 +18,8 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
headers: {
"x-custom-header": "foo-header",
"x-another-header": "another-header",
@@ -30,8 +30,8 @@ module.exports = [
},
{
id: "error",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 403,
body: {
message: "Bad data",
@@ -47,8 +47,8 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: [
...USERS,
diff --git a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/collections.js b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/collections.js
new file mode 100644
index 000000000..8af8046c4
--- /dev/null
+++ b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/collections.js
@@ -0,0 +1,26 @@
+/*
+Copyright 2021 Javier Brea
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+*/
+
+module.exports = [
+ {
+ id: "base",
+ routes: ["get-users:success", "get-user:1"],
+ },
+ {
+ id: "user-2",
+ from: "base",
+ routes: ["get-user:2"],
+ },
+ {
+ id: "user-real",
+ from: "base",
+ routes: ["get-user:real"],
+ },
+];
diff --git a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/mocks.js b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/mocks.js
deleted file mode 100644
index 82511e694..000000000
--- a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/mocks.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-Copyright 2021 Javier Brea
-
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-*/
-
-module.exports = [
- {
- id: "base",
- routesVariants: ["get-users:success", "get-user:1"],
- },
- {
- id: "user-2",
- from: "base",
- routesVariants: ["get-user:2"],
- },
- {
- id: "user-real",
- from: "base",
- routesVariants: ["get-user:real"],
- },
-];
diff --git a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/routes/user.js b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/routes/user.js
index bdf33726f..23a7e4896 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/routes/user.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/routes/user.js
@@ -18,24 +18,24 @@ module.exports = [
variants: [
{
id: "1",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[0],
},
},
{
id: "2",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS[1],
},
},
{
id: "real",
- handler: "middleware",
- response: {
+ type: "middleware",
+ options: {
middleware: (req, res) => {
const userId = req.params.id;
const user = USERS.find((userData) => userData.id === Number(userId));
diff --git a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/routes/users.js b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/routes/users.js
index f406dac80..a49f7e3d6 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/routes/users.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/fixtures/web-tutorial/routes/users.js
@@ -18,16 +18,16 @@ module.exports = [
variants: [
{
id: "success",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 200,
body: USERS,
},
},
{
id: "error",
- handler: "json",
- response: {
+ type: "json",
+ options: {
status: 403,
body: {
message: "Bad data",
diff --git a/test/plugin-inquirer-cli-e2e/src/main/interactive-cli.spec.js b/test/plugin-inquirer-cli-e2e/src/main/interactive-cli.spec.js
index 4237df463..93ed9a365 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/interactive-cli.spec.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/interactive-cli.spec.js
@@ -21,7 +21,7 @@ describe("interactive CLI", () => {
let mocks;
beforeAll(async () => {
- mocks = mocksRunner(["--files.path=web-tutorial", "--mocks.selected=foo"]);
+ mocks = mocksRunner(["--files.path=web-tutorial", "--mock.collections.selected=foo"]);
await waitForServerAndCli();
});
@@ -31,16 +31,18 @@ describe("interactive CLI", () => {
describe("When started", () => {
it("should display an alert because chosen mock does not exist", async () => {
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Mock 'foo' was not found."));
+ expect(mocks.currentScreen).toEqual(
+ expect.stringContaining("Collection 'foo' was not found.")
+ );
expect(mocks.currentScreen).toEqual(expect.stringContaining("ALERTS"));
});
it("should have loaded first mock", async () => {
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Current mock: base"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Current collection: base"));
});
it("should have 3 mocks available", async () => {
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Mocks: 3"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Collections: 3"));
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -67,7 +69,7 @@ describe("interactive CLI", () => {
await mocks.pressEnter();
await mocks.cursorDown(2);
const newScreen = await mocks.pressEnter();
- expect(newScreen).toEqual(expect.stringContaining("Current mock: user-real"));
+ expect(newScreen).toEqual(expect.stringContaining("Current collection: user-real"));
});
it("should have removed alert", async () => {
@@ -118,7 +120,7 @@ describe("interactive CLI", () => {
await wait(1000);
expect(mocks.currentScreen).toEqual(expect.stringContaining("Displaying logs"));
expect(mocks.currentScreen).toEqual(
- expect.stringContaining("[verbose][mocks:routes:get-users:success] Sending response")
+ expect.stringContaining("[verbose][mock:routes:get-users:success] Sending response")
);
await mocks.pressEnter();
});
diff --git a/test/plugin-inquirer-cli-e2e/src/main/no-mocks.spec.js b/test/plugin-inquirer-cli-e2e/src/main/no-mocks.spec.js
index 134deea81..028b3b686 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/no-mocks.spec.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/no-mocks.spec.js
@@ -18,24 +18,24 @@ describe("with no behaviors", () => {
});
it("should display alerts", async () => {
- mocks = mocksRunner(["--files.path=no-mocks", "--mocks.selected=foo"]);
+ mocks = mocksRunner(["--files.path=no-mocks", "--mock.collections.selected=foo"]);
await waitForServerAndCli();
expect(mocks.currentScreen).toEqual(expect.stringContaining("ALERTS"));
expect(mocks.currentScreen).toEqual(
- expect.stringContaining("Warning: [mocks:empty] No mocks found")
+ expect.stringContaining("Warning: [mock:collections:empty] No collections found")
);
});
it("should print a dash as current behavior", async () => {
mocks = mocksRunner(["--files.path=no-mocks"]);
await waitForServerAndCli();
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Current mock: -"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Current collection: -"));
});
it("should print mocks as 0", async () => {
mocks = mocksRunner(["--files.path=no-mocks"]);
await waitForServerAndCli();
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Mocks: 0"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Collections: 0"));
});
it("should print current routes as 0", async () => {
diff --git a/test/plugin-inquirer-cli-e2e/src/main/web-tutorial.spec.js b/test/plugin-inquirer-cli-e2e/src/main/web-tutorial.spec.js
index f85e850d5..29d355ef0 100644
--- a/test/plugin-inquirer-cli-e2e/src/main/web-tutorial.spec.js
+++ b/test/plugin-inquirer-cli-e2e/src/main/web-tutorial.spec.js
@@ -25,7 +25,7 @@ describe("web tutorial", () => {
describe("When started", () => {
it("should have 3 mocks available", async () => {
- expect(mocks.currentScreen).toEqual(expect.stringContaining("Mocks: 3"));
+ expect(mocks.currentScreen).toEqual(expect.stringContaining("Collections: 3"));
});
it("should not display behaviors", async () => {
@@ -56,7 +56,7 @@ describe("web tutorial", () => {
await mocks.pressEnter();
await mocks.cursorDown();
const newScreen = await mocks.pressEnter();
- expect(newScreen).toEqual(expect.stringContaining("Current mock: user-2"));
+ expect(newScreen).toEqual(expect.stringContaining("Current collection: user-2"));
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -83,7 +83,7 @@ describe("web tutorial", () => {
await mocks.pressEnter();
await mocks.cursorDown(2);
const newScreen = await mocks.pressEnter();
- expect(newScreen).toEqual(expect.stringContaining("Current mock: user-real"));
+ expect(newScreen).toEqual(expect.stringContaining("Current collection: user-real"));
});
it("should serve users collection mock under the /api/users path", async () => {
@@ -117,7 +117,7 @@ describe("web tutorial", () => {
await mocks.cursorDown();
const newScreen = await mocks.pressEnter();
expect(newScreen).toEqual(
- expect.stringContaining("Current mock: user-real (custom variants: get-user:2)")
+ expect.stringContaining("Current collection: user-real (custom variants: get-user:2)")
);
});
@@ -150,7 +150,7 @@ describe("web tutorial", () => {
await mocks.cursorDown(2);
await mocks.pressEnter();
const newScreen = await mocks.pressEnter();
- expect(newScreen).toEqual(expect.stringContaining("Current mock: user-real"));
+ expect(newScreen).toEqual(expect.stringContaining("Current collection: user-real"));
});
it("should serve users collection mock under the /api/users path", async () => {
diff --git a/workspace.json b/workspace.json
index ea9935f71..7a766e6fe 100644
--- a/workspace.json
+++ b/workspace.json
@@ -28,6 +28,7 @@
"main-e2e": "test/main-e2e",
"nested-collections": "packages/nested-collections",
"plugin-admin-api": "packages/plugin-admin-api",
+ "plugin-admin-api-swagger-e2e": "test/plugin-admin-api-swagger-e2e",
"plugin-inquirer-cli": "packages/plugin-inquirer-cli",
"plugin-inquirer-cli-e2e": "test/plugin-inquirer-cli-e2e",
"plugin-proxy": "packages/plugin-proxy"