UNPKG

unmock-core

Version:

[![npm](https://img.shields.io/npm/v/unmock-core.svg)][npmjs] [![CircleCI](https://circleci.com/gh/unmock/unmock-js.svg?style=svg)](https://circleci.com/gh/unmock/unmock-js) [![codecov](https://codecov.io/gh/unmock/unmock-js/branch/dev/graph/badge.svg)](h

115 lines 5.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const debug_1 = require("debug"); const minimatch = require("minimatch"); const constants_1 = require("../constants"); const dsl_1 = require("../dsl"); const utils_1 = require("./utils"); const validator_1 = require("./validator"); const debugLog = debug_1.default("unmock:state"); class State { constructor() { this.state = {}; } update(stateUpdate) { const { endpoint, method, newState } = stateUpdate.stateInput; debugLog(`Fetching operations for '${method} ${endpoint}'...`); const ops = utils_1.getOperations(stateUpdate); if (ops.error !== undefined) { debugLog(`Couldn't find any matching operations: ${ops.error}`); throw new Error(ops.error); } if (newState.isEmpty) { return; } debugLog(`Found the following operations: ${JSON.stringify(ops.operations, undefined, 1)}`); const mapped = ops.operations.map(op => (Object.assign(Object.assign({}, validator_1.getValidStatesForOperationWithState(op.operation, newState, stateUpdate.dereferencer)), { endpoint: op.endpoint, method: op.method }))); const failed = mapped.every(resp => resp.error !== undefined); if (failed) { const error = utils_1.chooseErrorFromList(mapped.map(resp => resp.error)); throw new Error(error ? error.msg : `Unexpected error while setting state - ${JSON.stringify(newState.state)}`); } mapped .filter(resp => resp.error === undefined) .map(resp => ({ state: dsl_1.DSL.translateTopLevelToOAS(newState.top, resp.responses), endpoint: utils_1.convertEndpointToWildcard(resp.endpoint), method: resp.method, })) .forEach(aug => this.updateStateInternal(aug.endpoint, aug.method, aug.state)); } getState(method, endpoint) { debugLog(`Filtering all saved states that match '${endpoint}'...`); const mostRelevantEndpoint = Object.keys(this.state) .filter((sKey) => minimatch(endpoint, sKey, { nocase: true }) && (this.state[sKey][method] !== undefined || this.state[sKey][constants_1.DEFAULT_STATE_HTTP_METHOD] !== undefined)) .sort((a, b) => { const nA = a.split("*"); const nB = b.split("*"); return nA > nB || (nA === nB && a.indexOf("*") < b.indexOf("*")) ? -1 : 1; }) .shift(); if (mostRelevantEndpoint === undefined) { debugLog(`No states match '${endpoint}'`); return undefined; } debugLog(`Most relevant endpoint is ${mostRelevantEndpoint}`); const matchingMethod = Object.keys(this.state[mostRelevantEndpoint]).includes(method) ? method : constants_1.DEFAULT_STATE_HTTP_METHOD; const relevantState = this.state[mostRelevantEndpoint][matchingMethod]; const { parsed, newState } = dsl_1.DSL.actTopLevelFromOAS(relevantState); this.updateStateFromDSL(newState, mostRelevantEndpoint, matchingMethod); return Object.keys(parsed).length > 0 ? parsed : undefined; } reset() { this.state = {}; } updateStateFromDSL(newState, endpoint, method) { Object.keys(newState).forEach(code => Object.keys(newState[code]).forEach(media => { const state = newState[code][media]; if (state === undefined) { this.deleteStateInternal(endpoint, method, code, media); } else if (Object.keys(state).length > 0) { this.updateStateInternal(endpoint, method, { [code]: { [media]: state }, }); } })); } updateStateInternal(endpoint, method, responses) { if (this.state[endpoint] === undefined) { this.state[endpoint] = {}; } if (this.state[endpoint][method] === undefined) { this.state[endpoint][method] = {}; } this.state[endpoint][method] = Object.assign(Object.assign({}, this.state[endpoint][method]), responses); } deleteStateInternal(endpoint, method, code, mediaType) { if (this.state[endpoint] === undefined || this.state[endpoint][method] === undefined || this.state[endpoint][method][code] === undefined || this.state[endpoint][method][code][mediaType] === undefined) { return; } delete this.state[endpoint][method][code][mediaType]; if (Object.keys(this.state[endpoint][method][code]).length === 0) { delete this.state[endpoint][method][code]; if (Object.keys(this.state[endpoint][method]).length === 0) { delete this.state[endpoint][method]; if (Object.keys(this.state[endpoint]).length === 0) { delete this.state[endpoint]; } } } } } exports.State = State; //# sourceMappingURL=state.js.map