NaturalIntelligence/Stubmatic

View on GitHub
lib/RequestResolver.js

Summary

Maintainability
D
2 days
Test Coverage
// @ts-check
var util = require('./util/util');
const resolveParsedRequestExpression = require('./expressions/parsedRequestExpression')

module.exports = class RequestResolver {
    parse(http_request, mappings, dataTables){
        for(var i=0;i<mappings.length;i++){
            var entry = util.clone(mappings[i]);
            var matched = matchAndCapture(entry.request, http_request);
            if(matched){//if nothing matches in current mapping, check for other matching
                entry.request.matches = matched;
                entry.index = i;
    
                //resolve dbset entries
                if(entry["data-table"]){
                    entry["data-table"].name = resolveParsedRequestExpression(entry["data-table"].name, matched);
                    if(entry["data-table"].key){
                        entry["data-table"].key = resolveParsedRequestExpression(entry["data-table"].key, matched);
                    }
                    var result = resolveDBSetKey(entry["data-table"], dataTables);
                    if(result){
                        entry["data-table"].key = result;
                    }else{
                        continue;
                    }
                }
                return entry;
            }
        }
        return null;
    }
}

var props = ["headers","query"];
/**
return undefined if any property of mapping doesn't match with request
**/
function matchAndCapture(mapped_request, http_request){
    var matched = {}, i=0;

    if(Array.isArray(mapped_request.method)){
        if(mapped_request.method.indexOf(http_request.method) === -1) return;
    }else if(mapped_request.method === "*"){
        //do nothing
    }else{
        if(mapped_request.method !== http_request.method)    return;
    }

    if(mapped_request.url){
        var urlmatch = util.getMatches(http_request.url,'^'+mapped_request.url+'$');
        if(urlmatch)    matched['url'] = urlmatch;
        else    return;
    }

    if(mapped_request.post){
         const matches = util.getAllMatches(http_request.post, mapped_request.post);
         matched['post'] = concatAllMatches(matches);
        if(! matched['post']) return;
    }
    
    for (i = 0; i < props.length; i++) {
        if(mapped_request[props[i]]){
            var result = matchParamters(http_request, mapped_request, props[i]);
            if(result)            matched[props[i]] = result;
            else            return;
        }
    }
    
    return matched;
}

function matchParamters(http_request, mapped_request, param_name){
    var clips = [];
    clips[0] = "N/A";
    if( !http_request[param_name]){
        if( mapped_request[param_name] ){
            for(var key in mapped_request[param_name]){
                if(mapped_request[param_name][key] !== '^') return;
            }
            return clips;
        }else{
            return;
        }
    }else{
        for(var key in mapped_request[param_name]){
            var value = http_request[param_name][key];
            
            if(mapped_request[param_name][key] === '^'){
                if(value) return;
            }else if(!value){
                return;
            }else{
                var matches = util.getMatches( value, '^'+mapped_request[param_name][key]+'$' );
                
                if(!matches) return;
                if(matches && matches.length > 1){
                    matches = matches.slice(1);
                    clips = clips.concat(matches);
                }
            }
    
        }
        return clips;
    }
}

function concatAllMatches(matches){
    var match = [];
    for (var i = 0; i < matches.length; i++) {
        match = match.concat(matches[i]);
    }
    return match;
}

//var lastKeyIndex = [];

var resolveDBSetKey = function (table, tables){
    if(table.key){
        var row = tables[table.name].get(table.key);
        if(row){
            return table.key;
        }else if(tables[table.name].get('*')){
            return '*';
        }
    }else{//strategy
        if(table.strategy === 'random'){
            var len = tables[table.name].count();
            var i = Math.floor((Math.random() * len) + 1) - 1;
            return tables[table.name].getHashes()[i];
        }/*else if(config.strategy === 'round-robin'){
            var len = dbsets[config.name].size();
            var lastIndex = lastKeyIndex[config.name];
            if(lastIndex != undefined){
                lastKeyIndex[config.name] = lastIndex == len - 1 ? 0 : lastIndex+1;
            }else{
                lastKeyIndex[config.name] = 0;
            }
            return dbsets[config.name].getHashes()[lastKeyIndex[config.name]];
        }*/
    }
}