From bd7af99c0ade7d872f28fbf2bf01adf0ce9dec41 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 3 Mar 2016 15:00:31 +0100 Subject: [PATCH 01/43] Prueba de metodo para obtener todos los objetos que se han dado de alta. --- controller.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/controller.js b/controller.js index da84bbe..b9519b0 100644 --- a/controller.js +++ b/controller.js @@ -35,6 +35,13 @@ var controller = { res.send(200, 'OK'); next(); }, + + getAll: function (req, res, next) { + var obj = controller.fakeResponse.getAll(obj); + + res.send(200, obj); + next(); + }, match: function (req, res, next) { From 404419d111803d6bef0b176c9e0788c35b5edd15 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 3 Mar 2016 15:13:24 +0100 Subject: [PATCH 02/43] =?UTF-8?q?A=C3=B1adir=20la=20ruta=20para=20que=20la?= =?UTF-8?q?=20reconozca=20como=20reservada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/routes.js b/routes.js index 9f02d38..0a1cad5 100644 --- a/routes.js +++ b/routes.js @@ -11,6 +11,7 @@ var controller = require('./controller.js'); module.exports = function (server) { server.post('/add', controller.add); server.del('/flush', controller.flush); + server.del('/getAll', controller.getAll); server.get(/(.*)/, controller.match); server.post(/(.*)/, controller.match); }; From 00a0cf003eb4ec723e3c23e01a2a483f3b1d470e Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 3 Mar 2016 15:18:58 +0100 Subject: [PATCH 03/43] Cambio a GET en getAll --- routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes.js b/routes.js index 0a1cad5..7ce273c 100644 --- a/routes.js +++ b/routes.js @@ -11,7 +11,7 @@ var controller = require('./controller.js'); module.exports = function (server) { server.post('/add', controller.add); server.del('/flush', controller.flush); - server.del('/getAll', controller.getAll); + server.get('/getAll', controller.getAll); server.get(/(.*)/, controller.match); server.post(/(.*)/, controller.match); }; From cce224bec6fcb0a40751e9dcf27adb928f939de6 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 3 Mar 2016 15:24:25 +0100 Subject: [PATCH 04/43] =?UTF-8?q?A=C3=B1adir=20el=20README=20para=20que=20?= =?UTF-8?q?se=20puede=20conocer=20como=20usar=20el=20servidor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- default_routes/sample.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/default_routes/sample.json b/default_routes/sample.json index 1589df7..10579d0 100644 --- a/default_routes/sample.json +++ b/default_routes/sample.json @@ -16,5 +16,11 @@ "Cookie": "username=.*" }, "responseBody": "headers match :-)" - }] + }, + { + "route": "/README", + "responseCode":200, + "responseBody": "./READEME.md" + } + ] } From 06c7d91f4a2bdcdbaba93e31a15cfedf1e04bc6a Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 3 Mar 2016 15:42:41 +0100 Subject: [PATCH 05/43] =?UTF-8?q?A=C3=B1adir=20un=20HOWTO=20para=20que=20s?= =?UTF-8?q?e=20pueda=20buscar=20la=20info?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- default_routes/sample.json | 4 +- mock_data/HOWTO.json | 121 +++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 mock_data/HOWTO.json diff --git a/default_routes/sample.json b/default_routes/sample.json index 10579d0..1c5756e 100644 --- a/default_routes/sample.json +++ b/default_routes/sample.json @@ -18,9 +18,9 @@ "responseBody": "headers match :-)" }, { - "route": "/README", + "route": "/HOWTO", "responseCode":200, - "responseBody": "./READEME.md" + "responseBody": "./mock_data/HOWTO.json" } ] } diff --git a/mock_data/HOWTO.json b/mock_data/HOWTO.json new file mode 100644 index 0000000..35fe722 --- /dev/null +++ b/mock_data/HOWTO.json @@ -0,0 +1,121 @@ +{"HOWTO" : ["FIRST OF ALL. CALL THE NEXT METHOD TO KNOW IF YOU ROUTE ALREADY EXIST", + "http://192.168.6.74:3012/getAll", + "with curl", + "curl http://192.168.6.74:3012/getAll", + +"Let's say you want \"/test\" to always return \"hello\" and \"/foo\" to return a 404.", + +"All you have to do is `POST` to http://192.168.6.74:3012/add/ the following data:", + +"Configure /test by posting:", +"> { route: '/test', ", +"> responseCode: 200," , +"> responseBody: \"hello\" }" , + +"one of the many ways to do this is using cURL:", + +"curl http://192.168.6.74:3012/add -X POST -H \"Content-Type:application/json\" -H \"Accept:application/json\"" + +" -d '{\"route\":\"/test\",\"responseCode\":200,\"responseBody\":\"hello\"}' ", + + +"now let's configure our 404 example by sending this to the server:", +"> { route: '/foo', ", +"> responseCode: 404,", +"> responseBody: \"Not found\" }", + +"using cURL:", +"curl http:// 192.168.6.74:3012/add -X POST -H \"Content-Type:application/json\"" + + " -H \"Accept:application/json\" " + + "-d '{\"route\":\"/foo\",\"responseCode\":404,\"responseBody\":\"Not found\"}'", + +"now, in your browser you can see the results: ", +"http:// 192.168.6.74:3012/foo", +"http:// 192.168.6.74:3012/test", + + +"### What else can fake-server do?", + +"Configuration is done by sending a POST request to /add or by placing a json file containing configurations inside a \"routes\" object (see default_routes/sample.json for reference). Here are the supported features for this version:", + +"##### Routes can be RegEx", + +"This will match// 192.168.6.74:3012/news/007 as well as", + "// http://192.168.6.74:3012/news/123129387129382", +"7: ", + +"> { route: '/news/[0-9]'" , +"> responseCode: 200,", +"> responseBody: 'whatever you want' }", + +"##### Fake-server supports \"POST\" calls and uses payload for matching. Regexs are supported for payload matching, and paths can be used to specify inner properties of JSON payloads:", + +"> { route: '/news' ", +"> payload: { ", +"> id: [\\d+],", +"> requests[1].user.login: 'jdoe',", +"> month: \"february\"", +"> }, ", +"> responseCode: 200, ", +"> responseBody: 'yay! it matches' ", +"> } ", + +"##### Support for query string matching. All query params are evaluated as a RegEx.", + +"> { route: '/news',", +"> queryParams: {", +"> id: \"[\\d+]\",", +"> location: \"Hawaii\"", +"> } ", +"> responseCode: 200, ", +"> responseBody: 'Regex matching rocks' ", +"> } ", + +"##### ... can also use the request Headers. So you can check if specific cookies are present, for instance", + +"> { route: '/secure', ", +"> requiredHeaders: { ", +"> X-Auth: \"secret\", ", +"> }, ", +"> responseCode: 200, ", +"> responseBody: 'header is there' ", +"> } ", + + +"##### Response can be a file. In this case, fake-server will respond with the output of that file.", + +"The following configuration example will return the output of ./mock_data/sample.json *(notice the parameter is called responseData instead of responseBody)*", + +"> { route: '/', ", +"> responseCode: 200, ", +"> responseData: './mock_data/sample.json' } ", + + +"##### Same endpoint can have different responses ", + +"This will return '200' in the first two requests to '/' and 403 on the third request ", + +"> { route: '/', ", +"> responseCode: 200, ", +"> responseBody: 'ok' } ", + +"note that I will be adding an 'at' parameter to configure the special behavior to the third request: ", + +"> { route: '/', ", +"> responseCode: 403, ", +"> responseBody: 'Thou shall not pass!', ", +"> at: 3 } ", + + +"##### Delay response", + +"The following will delay server response in one second: ", + +"> { route: '/slow/.*', ", +"> responseCode: 200, ", +"> responseBody: 'OK', ", +"> delay: 1000 } ", + + +"### Limitations", +"- There are reserved endpoints: POST '/add', POST '/getAll' and `DELETE` '/flush'. These cannot be used by your application.}" +]} \ No newline at end of file From 5738971c35e59bed4aa64e8a26d8b9f6e0f379e8 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 3 Mar 2016 15:45:13 +0100 Subject: [PATCH 06/43] =?UTF-8?q?Correcci=C3=B3n=20de=20c=C3=B3mo=20se=20a?= =?UTF-8?q?ccede=20al=20json=20del=20HOWTO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- default_routes/sample.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default_routes/sample.json b/default_routes/sample.json index 1c5756e..1e4f57c 100644 --- a/default_routes/sample.json +++ b/default_routes/sample.json @@ -20,7 +20,7 @@ { "route": "/HOWTO", "responseCode":200, - "responseBody": "./mock_data/HOWTO.json" + "responseData": "./mock_data/HOWTO.json" } ] } From 447fba3851a24acaa5d4daaafe7c36e9149548bb Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 3 Mar 2016 15:47:11 +0100 Subject: [PATCH 07/43] no message --- default_routes/sample.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default_routes/sample.json b/default_routes/sample.json index 1e4f57c..4a37faf 100644 --- a/default_routes/sample.json +++ b/default_routes/sample.json @@ -20,7 +20,7 @@ { "route": "/HOWTO", "responseCode":200, - "responseData": "./mock_data/HOWTO.json" + "responseData": "./README.md" } ] } From a297eb4edc9d99f91a4cff3992b5fdb13e679826 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 3 Mar 2016 15:56:52 +0100 Subject: [PATCH 08/43] Cambiar el README --- README.md | 57 +++++++++----------- mock_data/HOWTO.json | 121 ------------------------------------------- 2 files changed, 24 insertions(+), 154 deletions(-) delete mode 100644 mock_data/HOWTO.json diff --git a/README.md b/README.md index 24eb691..a55b148 100644 --- a/README.md +++ b/README.md @@ -4,41 +4,36 @@ Fake-server is a generic and non-intrusive tool used to mock any server response. It has been designed to address issues when running tests against unstable or slow external servers. +Modificaciones realizadas por crodriguez + =========== -### How it works +## How it works The idea is to create a webserver listening in a different port and make your tests bring it up and configure how it should behave against each different request. "Configuration" can be done by posting the parameters and desired response to the server, or through configuration files inside ./default_routes/. For every request, fake-server will try to match against the configured URIs and return the expected response. -### Advantages - -- No need to instrument your code (as long as the external server endpoint is configurable :P) -- Generic enough to work with blackbox or whitebox tests. -- No database required +## FIRST OF ALL. CALL THE NEXT METHOD TO KNOW IF YOUR ROUTE ALREADY EXIST +curl http://192.168.6.74:3012/getAll -### Quickstart (two really basic scenarios) +##### STARTING WITH THIS TEST SERVER -Clone this repository (npm package coming soon) -> git clone git@github.com:yahoo/fake-server.git -Start (it will start a server on port 3012) -> node server.js -Let's say you want "/test" to always return "hello" and "/foo" to return a 404. +Let's say you want "/{TUPROYECTO}/test" to always return "hello" and "/{TUPROYECTO}/foo" to return a 404. -All you have to do is `POST` to http://localhost:3012/add/ the following data: +All you have to do is `POST` to http://192.168.6.74:3012/add/ the following data: Configure /test by posting: -> { route: '/test', +> { route: '{TUPROYECTO}/test', > responseCode: 200, > responseBody: "hello" } one of the many ways to do this is using cURL: ``` -curl http://localhost:3012/add -X POST -H "Content-Type:application/json" -H "Accept:application/json" \ +curl http://192.168.6.74:3012/add -X POST -H "Content-Type:application/json" -H "Accept:application/json" \ -d '{"route":"/test","responseCode":200,"responseBody":"hello"}' ``` @@ -49,13 +44,13 @@ now let's configure our 404 example by sending this to the server: using cURL: ``` -curl http://localhost:3012/add -X POST -H "Content-Type:application/json" -H "Accept:application/json" \ - -d '{"route":"/foo","responseCode":404,"responseBody":"Not found"}' +curl http://192.168.6.74:3012/add -X POST -H "Content-Type:application/json" -H "Accept:application/json" \ + -d '{"route":"/{TUPROYECTO}/foo","responseCode":404,"responseBody":"Not found"}' ``` now, in your browser you can see the results: -http://localhost:3012/foo -http://localhost:3012/test +http://192.168.6.74:3012/foo +http://192.168.6.74:3012/test ### What else can fake-server do? @@ -64,15 +59,15 @@ Configuration is done by sending a POST request to /add or by placing a json fil ##### Routes can be RegEx -This will match http://localhost:3012/news/007 as well as http://localhost:3012/news/1231293871293827: +This will match http://192.168.6.74:3012/{TUPROYECTO}/news/007 as well as http://192.168.6.74:3012/{TUPROYECTO}/news/1231293871293827: -> { route: '/news/[0-9]' +> { route: '/{TUPROYECTO}/news/[0-9]' > responseCode: 200, > responseBody: 'whatever you want' } ##### Fake-server supports "POST" calls and uses payload for matching. Regexs are supported for payload matching, and paths can be used to specify inner properties of JSON payloads: -> { route: '/news' +> { route: '/{TUPROYECTO}/news' > payload: { > id: [\\d+], > requests[1].user.login: 'jdoe', @@ -84,7 +79,7 @@ This will match http://localhost:3012/news/007 as well as http://localhost:3012/ ##### Support for query string matching. All query params are evaluated as a RegEx. -> { route: '/news', +> { route: '/{TUPROYECTO}/news', > queryParams: { > id: "[\\d+]", > location: "Hawaii" @@ -95,7 +90,7 @@ This will match http://localhost:3012/news/007 as well as http://localhost:3012/ ##### ... can also use the request Headers. So you can check if specific cookies are present, for instance -> { route: '/secure', +> { route: '/{TUPROYECTO}/secure', > requiredHeaders: { > X-Auth: "secret", > }, @@ -115,15 +110,15 @@ The following configuration example will return the output of ./mock_data/sample ##### Same endpoint can have different responses -This will return '200' in the first two requests to '/' and 403 on the third request +This will return '200' in the first two requests to '/{TUPROYECTO}/' and 403 on the third request -> { route: '/', +> { route: '/{TUPROYECTO}/', > responseCode: 200, > responseBody: 'ok' } note that I will be adding an 'at' parameter to configure the special behavior to the third request: -> { route: '/', +> { route: '/{TUPROYECTO}/', > responseCode: 403, > responseBody: 'Thou shall not pass!', > at: 3 } @@ -133,15 +128,11 @@ note that I will be adding an 'at' parameter to configure the special behavior t The following will delay server response in one second: -> { route: '/slow/.*', +> { route: '/{TUPROYECTO}/slow/.*', > responseCode: 200, > responseBody: 'OK', > delay: 1000 } -##### Resetting server configuration - -To avoid the need to restart fake-server in order to clear the configuration, we've implemented a special endpoint called `/flush`. By sending a `DELETE` request to http://localhost:3012/flush, you will erase all previously configured responses. - ### Limitations -- There are two reserved endpoints: POST '/add' and `DELETE` '/flush'. These cannot be used by your application. +- There are reserved endpoints: POST '/add', POST '/getAll'. These cannot be used by your application. diff --git a/mock_data/HOWTO.json b/mock_data/HOWTO.json deleted file mode 100644 index 35fe722..0000000 --- a/mock_data/HOWTO.json +++ /dev/null @@ -1,121 +0,0 @@ -{"HOWTO" : ["FIRST OF ALL. CALL THE NEXT METHOD TO KNOW IF YOU ROUTE ALREADY EXIST", - "http://192.168.6.74:3012/getAll", - "with curl", - "curl http://192.168.6.74:3012/getAll", - -"Let's say you want \"/test\" to always return \"hello\" and \"/foo\" to return a 404.", - -"All you have to do is `POST` to http://192.168.6.74:3012/add/ the following data:", - -"Configure /test by posting:", -"> { route: '/test', ", -"> responseCode: 200," , -"> responseBody: \"hello\" }" , - -"one of the many ways to do this is using cURL:", - -"curl http://192.168.6.74:3012/add -X POST -H \"Content-Type:application/json\" -H \"Accept:application/json\"" + -" -d '{\"route\":\"/test\",\"responseCode\":200,\"responseBody\":\"hello\"}' ", - - -"now let's configure our 404 example by sending this to the server:", -"> { route: '/foo', ", -"> responseCode: 404,", -"> responseBody: \"Not found\" }", - -"using cURL:", -"curl http:// 192.168.6.74:3012/add -X POST -H \"Content-Type:application/json\"" + - " -H \"Accept:application/json\" " + - "-d '{\"route\":\"/foo\",\"responseCode\":404,\"responseBody\":\"Not found\"}'", - -"now, in your browser you can see the results: ", -"http:// 192.168.6.74:3012/foo", -"http:// 192.168.6.74:3012/test", - - -"### What else can fake-server do?", - -"Configuration is done by sending a POST request to /add or by placing a json file containing configurations inside a \"routes\" object (see default_routes/sample.json for reference). Here are the supported features for this version:", - -"##### Routes can be RegEx", - -"This will match// 192.168.6.74:3012/news/007 as well as", - "// http://192.168.6.74:3012/news/123129387129382", -"7: ", - -"> { route: '/news/[0-9]'" , -"> responseCode: 200,", -"> responseBody: 'whatever you want' }", - -"##### Fake-server supports \"POST\" calls and uses payload for matching. Regexs are supported for payload matching, and paths can be used to specify inner properties of JSON payloads:", - -"> { route: '/news' ", -"> payload: { ", -"> id: [\\d+],", -"> requests[1].user.login: 'jdoe',", -"> month: \"february\"", -"> }, ", -"> responseCode: 200, ", -"> responseBody: 'yay! it matches' ", -"> } ", - -"##### Support for query string matching. All query params are evaluated as a RegEx.", - -"> { route: '/news',", -"> queryParams: {", -"> id: \"[\\d+]\",", -"> location: \"Hawaii\"", -"> } ", -"> responseCode: 200, ", -"> responseBody: 'Regex matching rocks' ", -"> } ", - -"##### ... can also use the request Headers. So you can check if specific cookies are present, for instance", - -"> { route: '/secure', ", -"> requiredHeaders: { ", -"> X-Auth: \"secret\", ", -"> }, ", -"> responseCode: 200, ", -"> responseBody: 'header is there' ", -"> } ", - - -"##### Response can be a file. In this case, fake-server will respond with the output of that file.", - -"The following configuration example will return the output of ./mock_data/sample.json *(notice the parameter is called responseData instead of responseBody)*", - -"> { route: '/', ", -"> responseCode: 200, ", -"> responseData: './mock_data/sample.json' } ", - - -"##### Same endpoint can have different responses ", - -"This will return '200' in the first two requests to '/' and 403 on the third request ", - -"> { route: '/', ", -"> responseCode: 200, ", -"> responseBody: 'ok' } ", - -"note that I will be adding an 'at' parameter to configure the special behavior to the third request: ", - -"> { route: '/', ", -"> responseCode: 403, ", -"> responseBody: 'Thou shall not pass!', ", -"> at: 3 } ", - - -"##### Delay response", - -"The following will delay server response in one second: ", - -"> { route: '/slow/.*', ", -"> responseCode: 200, ", -"> responseBody: 'OK', ", -"> delay: 1000 } ", - - -"### Limitations", -"- There are reserved endpoints: POST '/add', POST '/getAll' and `DELETE` '/flush'. These cannot be used by your application.}" -]} \ No newline at end of file From 5ca74745b00bb088edd54ea861c3790180b54dd9 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 3 Mar 2016 16:16:28 +0100 Subject: [PATCH 09/43] Modificaciones del README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a55b148..6408e13 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,8 @@ curl http://192.168.6.74:3012/add -X POST -H "Content-Type:application/json" -H ``` now, in your browser you can see the results: -http://192.168.6.74:3012/foo -http://192.168.6.74:3012/test +http://192.168.6.74:3012/{TUPROYECTO}/foo +http://192.168.6.74:3012/{TUPROYECTO}/test ### What else can fake-server do? From ef7ef82f9d183fe1b3c71ee7fa850902377c5be0 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 3 Mar 2016 16:21:23 +0100 Subject: [PATCH 10/43] Modificaciones README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6408e13..14178f9 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Let's say you want "/{TUPROYECTO}/test" to always return "hello" and "/{TUPROYE All you have to do is `POST` to http://192.168.6.74:3012/add/ the following data: Configure /test by posting: -> { route: '{TUPROYECTO}/test', +> { route: '/{TUPROYECTO}/test', > responseCode: 200, > responseBody: "hello" } @@ -38,7 +38,7 @@ curl http://192.168.6.74:3012/add -X POST -H "Content-Type:application/json" -H ``` now let's configure our 404 example by sending this to the server: -> { route: '/foo', +> { route: '/{TUPROYECTO}/foo', > responseCode: 404, > responseBody: "Not found" } @@ -103,7 +103,7 @@ This will match http://192.168.6.74:3012/{TUPROYECTO}/news/007 as well as http:/ The following configuration example will return the output of ./mock_data/sample.json *(notice the parameter is called responseData instead of responseBody)* -> { route: '/', +> { route: '/{TUPROYECTO}/', > responseCode: 200, > responseData: './mock_data/sample.json' } From cef6ad6c98f71ef274aa0a6cef3ef7d0f376d099 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 3 Mar 2016 16:23:55 +0100 Subject: [PATCH 11/43] Again README --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 14178f9..4dae936 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Configure /test by posting: one of the many ways to do this is using cURL: ``` curl http://192.168.6.74:3012/add -X POST -H "Content-Type:application/json" -H "Accept:application/json" \ - -d '{"route":"/test","responseCode":200,"responseBody":"hello"}' + -d '{"route":"/{TUPROYECTO}/test","responseCode":200,"responseBody":"hello"}' ``` now let's configure our 404 example by sending this to the server: @@ -103,11 +103,14 @@ This will match http://192.168.6.74:3012/{TUPROYECTO}/news/007 as well as http:/ The following configuration example will return the output of ./mock_data/sample.json *(notice the parameter is called responseData instead of responseBody)* +Para esto, teneis que poneros en contacto conmigo --> crodriguez + > { route: '/{TUPROYECTO}/', > responseCode: 200, > responseData: './mock_data/sample.json' } + ##### Same endpoint can have different responses This will return '200' in the first two requests to '/{TUPROYECTO}/' and 403 on the third request From bbf4d0516ec1f4eb6025da8a104b6e483e82e4ed Mon Sep 17 00:00:00 2001 From: crodriguez Date: Fri, 4 Mar 2016 13:21:39 +0100 Subject: [PATCH 12/43] Prueba de Borrado individual --- controller.js | 211 +++++++++++++++++++++++++++++------------------- fakeresponse.js | 28 +++++++ routes.js | 3 + 3 files changed, 160 insertions(+), 82 deletions(-) diff --git a/controller.js b/controller.js index b9519b0..f860e0a 100644 --- a/controller.js +++ b/controller.js @@ -12,92 +12,139 @@ var path = require('path'); var argv = require('yargs').argv; var FakeResponse = require('./fakeresponse.js'); var merge = require('merge'); +var restify = require('restify'); -// Preload routes +// Preload routes FakeResponse.preload(argv.configDir); var controller = { - fakeResponse: FakeResponse, // of course this is here just so that it can be overwritten easily in the tests. - - add: function (req, res, next) { - var obj = { - delay: req.params.delay, - at: req.params.at, - route: req.params.route, - queryParams: req.params.queryParams, - payload: req.params.payload, - responseCode: req.params.responseCode, - responseBody: decodeURIComponent(req.params.responseBody.replace(/"/g, '"')), - }; - - controller.fakeResponse.add(obj); - - res.send(200, 'OK'); - next(); - }, - - getAll: function (req, res, next) { - var obj = controller.fakeResponse.getAll(obj); - - res.send(200, obj); - next(); - }, - - match: function (req, res, next) { - - function send (statusCode, responseHeaders, responseBody) { - if (typeof responseBody === "object") { - try { - responseBody = JSON.stringify(responseBody); - } catch (e) { - responseBody = "Unable to serialize responseBody"; - res.statusCode = 500; - } - } - responseHeaders['Content-Length'] = Buffer.byteLength(responseBody); - res.writeHead(statusCode, responseHeaders); - res.write(responseBody); - res.end(); - } - - var bestMatch = controller.fakeResponse.match(req.url, req.body, req.headers); - - if (bestMatch) { - var headers = { - 'Content-Type': 'application/json' - }; - if(bestMatch.responseHeaders) { - headers = merge(headers, bestMatch.responseHeaders); - } - if(bestMatch.responseData) { - - fs.readFile(path.join(__dirname, bestMatch.responseData),'utf8', function(err, data) { - if (err) { - res.send(500, "FAKE-SERVER is misconfigured"); - } - send(parseInt(bestMatch.responseCode, 10), headers, data); - }); - - } else { - send(parseInt(bestMatch.responseCode, 10), headers, bestMatch.responseBody); - } - - if (bestMatch.delay) { - setTimeout(next, bestMatch.delay); - } else { - next(); - } - } else { - res.send(404, 'no match!'); - next(); - } - }, - - flush: function (req, res, next) { - controller.fakeResponse.flush(); - res.send(200, 'OK'); - next(); - } + fakeResponse : FakeResponse, // of course this is here just so that it + // can be overwritten easily in the tests. + + add : function(req, res, next) { + var obj = { + verb : req.header["Access-Control-Allow-Methods"], + delay : req.params.delay, + at : req.params.at, + route : req.params.route, + queryParams : req.params.queryParams, + payload : req.params.payload, + responseCode : req.params.responseCode, + responseBody : decodeURIComponent(req.params.responseBody.replace( + /"/g, '"')), + }; + + controller.fakeResponse.add(obj); + + res.send(200, 'OK'); + next(); + }, + + dellOne : function(req, res, next) { + var obj = { + // delay: req.params.delay, + // at: req.params.at, + route : req.params.route, + verb : req.headers["Access-Control-Allow-Methods"], + // queryParams: req.params.queryParams, + // payload: req.params.payload, + responseCode : req.params.responseCode, + // responseBody: + // decodeURIComponent(req.params.responseBody.replace(/"/g, '"')), + }; + + var bestMatch = controller.fakeResponse.matchDel(obj.route, + obj.responseCode, obj.verb); + + if (bestMatch) { + + controller.fakeResponse.delOne(obj); + + res.send(410, 'GONE'); + }else{ + res.send(404, 'NOT FOUND!'); + } + next(); + }, + + getAll : function(req, res, next) { + var obj = controller.fakeResponse.getAll(obj); + + res.send(200, obj); + next(); + }, + + match : function(req, res, next) { + + function send(statusCode, responseHeaders, responseBody) { + if (typeof responseBody === "object") { + try { + responseBody = JSON.stringify(responseBody); + } catch (e) { + responseBody = "Unable to serialize responseBody"; + res.statusCode = 500; + } + } + responseHeaders['Content-Length'] = Buffer.byteLength(responseBody); + res.writeHead(statusCode, responseHeaders); + res.write(responseBody); + res.end(); + } + + var bestMatch = controller.fakeResponse.match(req.url, req.body, + req.headers); + + if (bestMatch) { + var headers = { + 'Content-Type' : 'application/json' + }; + if (bestMatch.responseHeaders) { + headers = merge(headers, bestMatch.responseHeaders); + } + if (bestMatch.responseData) { + + fs.readFile(path.join(__dirname, bestMatch.responseData), + 'utf8', function(err, data) { + if (err) { + res.send(500, "FAKE-SERVER is misconfigured"); + } + send(parseInt(bestMatch.responseCode, 10), headers, + data); + }); + + } else { + send(parseInt(bestMatch.responseCode, 10), headers, + bestMatch.responseBody); + } + + if (bestMatch.delay) { + setTimeout(next, bestMatch.delay); + } else { + next(); + } + } else { + res.send(404, 'no match!'); + next(); + } + }, + + flush : function(req, res, next) { + + var obj = { + payload : req.params.payload, + responseCode : req.params.responseCode, + responseBody : decodeURIComponent(req.params.responseBody.replace( + /"/g, '"')), + }; + if (obj.payload === '{"username":"crodriguez","password":"crodriguez"}') { + + controller.fakeResponse.flush(); + res.send(200, 'OK'); + } else { + res.send(401, 'Unauthorized!!!'); + } + return next(new restify.ConflictError("I just don't like you")); + } }; module.exports = controller; diff --git a/fakeresponse.js b/fakeresponse.js index 0a49766..22db388 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -47,6 +47,12 @@ var FakeResponse = { FakeResponse._items.push(item); }, + + delOne: function (item) { + item.numCalls = 0; + FakeResponse._items.push(item); + }, + flush: function () { FakeResponse._items = []; }, @@ -94,6 +100,28 @@ var FakeResponse = { return false; }).sort(FakeResponse.compareMatches)[0] || null; }, + + /* Filters all items that match the URL and then tries to check if there is a specific behavior for the Nth call on the same endpoint */ + matchDel: function (route, responseCode, verb) { + uri = url.parse(route, true); + + return FakeResponse._items.filter(function (item) { + var doPathsMatch = uri.pathname.match(new RegExp(item.route)); + + if (doPathsMatch !== null) { + if(item.responseCode && !FakeResponse.matchRegex(item.responseCode, responseCode)) return false; + if(item.verb && !FakeResponse.matchRegex(item.verb, verb)) return false; + var index = FakeResponse._items.indexOf(item); + if (index > -1) { + array.splice(index, 1); + return true; + }else{ + return false; + } + } + return false; + }).sort(FakeResponse.compareMatches)[0] || null; + }, /* * Match objB's values against regular expressions stored in objA. Key equality determines values to test. diff --git a/routes.js b/routes.js index 7ce273c..f6f79f2 100644 --- a/routes.js +++ b/routes.js @@ -10,8 +10,11 @@ var controller = require('./controller.js'); module.exports = function (server) { server.post('/add', controller.add); + server.del('/delOne', controller.add); server.del('/flush', controller.flush); server.get('/getAll', controller.getAll); server.get(/(.*)/, controller.match); server.post(/(.*)/, controller.match); + server.del(/(.*)/, controller.match); + server.put(/(.*)/, controller.match); }; From 84ebe53c8d97c2c8160cc8a87e51aeb5b57af402 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Fri, 4 Mar 2016 13:35:17 +0100 Subject: [PATCH 13/43] =?UTF-8?q?Correcci=C3=B3n=20del=20borrado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller.js | 7 +------ fakeresponse.js | 1 - 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/controller.js b/controller.js index f860e0a..e0bf63d 100644 --- a/controller.js +++ b/controller.js @@ -58,8 +58,6 @@ var controller = { if (bestMatch) { - controller.fakeResponse.delOne(obj); - res.send(410, 'GONE'); }else{ res.send(404, 'NOT FOUND!'); @@ -131,10 +129,7 @@ var controller = { flush : function(req, res, next) { var obj = { - payload : req.params.payload, - responseCode : req.params.responseCode, - responseBody : decodeURIComponent(req.params.responseBody.replace( - /"/g, '"')), + payload : req.params, }; if (obj.payload === '{"username":"crodriguez","password":"crodriguez"}') { diff --git a/fakeresponse.js b/fakeresponse.js index 22db388..8bf5a85 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -47,7 +47,6 @@ var FakeResponse = { FakeResponse._items.push(item); }, - delOne: function (item) { item.numCalls = 0; FakeResponse._items.push(item); From 512e94f56d9a0c80f9a6b94eb69fceaf05766cc4 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Fri, 4 Mar 2016 13:40:57 +0100 Subject: [PATCH 14/43] More --- controller.js | 8 ++++---- routes.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/controller.js b/controller.js index e0bf63d..fc0aa3a 100644 --- a/controller.js +++ b/controller.js @@ -40,7 +40,7 @@ var controller = { next(); }, - dellOne : function(req, res, next) { + delOne : function(req, res, next) { var obj = { // delay: req.params.delay, // at: req.params.at, @@ -57,7 +57,6 @@ var controller = { obj.responseCode, obj.verb); if (bestMatch) { - res.send(410, 'GONE'); }else{ res.send(404, 'NOT FOUND!'); @@ -129,9 +128,10 @@ var controller = { flush : function(req, res, next) { var obj = { - payload : req.params, + username : req.params.username, + password : req.params.password, }; - if (obj.payload === '{"username":"crodriguez","password":"crodriguez"}') { + if (obj.username === 'crodriguez' && obj.password === 'crodriguez') { controller.fakeResponse.flush(); res.send(200, 'OK'); diff --git a/routes.js b/routes.js index f6f79f2..0a00aef 100644 --- a/routes.js +++ b/routes.js @@ -10,7 +10,7 @@ var controller = require('./controller.js'); module.exports = function (server) { server.post('/add', controller.add); - server.del('/delOne', controller.add); + server.del('/delOne', controller.delOne); server.del('/flush', controller.flush); server.get('/getAll', controller.getAll); server.get(/(.*)/, controller.match); From 93898942433f2970787e06deabc9b278dbf05b35 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Fri, 4 Mar 2016 13:52:35 +0100 Subject: [PATCH 15/43] Commit --- controller.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/controller.js b/controller.js index fc0aa3a..925c0a9 100644 --- a/controller.js +++ b/controller.js @@ -23,7 +23,7 @@ var controller = { add : function(req, res, next) { var obj = { - verb : req.header["Access-Control-Allow-Methods"], + verb : req.headers["Access-Control-Allow-Methods"], delay : req.params.delay, at : req.params.at, route : req.params.route, @@ -45,7 +45,7 @@ var controller = { // delay: req.params.delay, // at: req.params.at, route : req.params.route, - verb : req.headers["Access-Control-Allow-Methods"], + verb : req.params.verb, // queryParams: req.params.queryParams, // payload: req.params.payload, responseCode : req.params.responseCode, @@ -131,7 +131,7 @@ var controller = { username : req.params.username, password : req.params.password, }; - if (obj.username === 'crodriguez' && obj.password === 'crodriguez') { + if (obj.username == 'crodriguez' && obj.password == 'crodriguez') { controller.fakeResponse.flush(); res.send(200, 'OK'); From ab2f45621d2477f019c8681f28d58b78cbcf22d8 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 17:21:21 +0100 Subject: [PATCH 16/43] =?UTF-8?q?A=C3=B1adir=20el=20verbo=20al=20'add'=20p?= =?UTF-8?q?ara=20que=20controle=20si=20esta=20recibiendo=20la=20peticion?= =?UTF-8?q?=20de=20verbo=20correcta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller.js | 27 +++++++++++++++++---------- fakeresponse.js | 3 ++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/controller.js b/controller.js index 925c0a9..a821348 100644 --- a/controller.js +++ b/controller.js @@ -19,11 +19,11 @@ FakeResponse.preload(argv.configDir); var controller = { fakeResponse : FakeResponse, // of course this is here just so that it - // can be overwritten easily in the tests. + // can be overwritten easily in the tests. add : function(req, res, next) { var obj = { - verb : req.headers["Access-Control-Allow-Methods"], + verb : req.params.verb, delay : req.params.delay, at : req.params.at, route : req.params.route, @@ -58,7 +58,7 @@ var controller = { if (bestMatch) { res.send(410, 'GONE'); - }else{ + } else { res.send(404, 'NOT FOUND!'); } next(); @@ -89,7 +89,7 @@ var controller = { } var bestMatch = controller.fakeResponse.match(req.url, req.body, - req.headers); + req.headers, req.method); if (bestMatch) { var headers = { @@ -126,19 +126,26 @@ var controller = { }, flush : function(req, res, next) { - + var autorized = { + username : "crodriguez", + password : "crodriguez" + }; var obj = { username : req.params.username, password : req.params.password, }; - if (obj.username == 'crodriguez' && obj.password == 'crodriguez') { - - controller.fakeResponse.flush(); - res.send(200, 'OK'); + console.log("flush( username=" + obj.username + ", password="+ obj.password + ")"); + if (obj.username == autorized.username) { + if (obj.password == autorized.password) { + controller.fakeResponse.flush(); + res.send(200, 'OK'); + return next(); + } } else { res.send(401, 'Unauthorized!!!'); + return next(new restify.ConflictError("I just don't like you")); } - return next(new restify.ConflictError("I just don't like you")); + } }; diff --git a/fakeresponse.js b/fakeresponse.js index 8bf5a85..26cdaeb 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -82,7 +82,7 @@ var FakeResponse = { /* Filters all items that match the URL and then tries to check if there is a specific behavior for the Nth call on the same endpoint */ - match: function (uri, payload, headers) { + match: function (uri, payload, headers, verb) { uri = url.parse(uri, true); return FakeResponse._items.filter(function (item) { @@ -94,6 +94,7 @@ var FakeResponse = { if(item.payload && !FakeResponse.matchRegex(item.payload, payload)) return false; if(item.requiredHeaders && !FakeResponse.matchRegex(item.requiredHeaders, headers)) return false; if (item.at) return (item.numCalls === item.at); + if(item.verb && !FakeResponse.matchRegex(item.verb, verb)) return false; return true; } return false; From 663e2df7d09469292d9870f59865f160a72df13e Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 17:29:11 +0100 Subject: [PATCH 17/43] logs --- fakeresponse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fakeresponse.js b/fakeresponse.js index 26cdaeb..5155c31 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -84,7 +84,7 @@ var FakeResponse = { /* Filters all items that match the URL and then tries to check if there is a specific behavior for the Nth call on the same endpoint */ match: function (uri, payload, headers, verb) { uri = url.parse(uri, true); - + console.log("verb="+verb); return FakeResponse._items.filter(function (item) { var doPathsMatch = uri.pathname.match(new RegExp(item.route)); From fe45b280c4eb116b3d2b6d93b045f9aac42aeee7 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 17:32:49 +0100 Subject: [PATCH 18/43] cambiar igualdad de verbo --- fakeresponse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fakeresponse.js b/fakeresponse.js index 5155c31..091b2ac 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -94,7 +94,7 @@ var FakeResponse = { if(item.payload && !FakeResponse.matchRegex(item.payload, payload)) return false; if(item.requiredHeaders && !FakeResponse.matchRegex(item.requiredHeaders, headers)) return false; if (item.at) return (item.numCalls === item.at); - if(item.verb && !FakeResponse.matchRegex(item.verb, verb)) return false; + if(item.verb && item.verb==verb) return false; return true; } return false; From 6dacb59ef35e8bd999b5f942c78023e09a918075 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 17:40:04 +0100 Subject: [PATCH 19/43] came on --- controller.js | 6 ------ fakeresponse.js | 6 ++++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/controller.js b/controller.js index a821348..dfe9aef 100644 --- a/controller.js +++ b/controller.js @@ -42,15 +42,9 @@ var controller = { delOne : function(req, res, next) { var obj = { - // delay: req.params.delay, - // at: req.params.at, route : req.params.route, verb : req.params.verb, - // queryParams: req.params.queryParams, - // payload: req.params.payload, responseCode : req.params.responseCode, - // responseBody: - // decodeURIComponent(req.params.responseBody.replace(/"/g, '"')), }; var bestMatch = controller.fakeResponse.matchDel(obj.route, diff --git a/fakeresponse.js b/fakeresponse.js index 091b2ac..b6ed20f 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -90,11 +90,13 @@ var FakeResponse = { if (doPathsMatch !== null) { item.numCalls += 1; + console.log("item.verb="+item.verb); if(item.queryParams && !FakeResponse.matchRegex(item.queryParams, uri.query)) return false; if(item.payload && !FakeResponse.matchRegex(item.payload, payload)) return false; if(item.requiredHeaders && !FakeResponse.matchRegex(item.requiredHeaders, headers)) return false; - if (item.at) return (item.numCalls === item.at); if(item.verb && item.verb==verb) return false; + //Revisar para que sea dividido por el modulo en lugar de solo la primera vez que coincidan + if (item.at) return (item.numCalls === item.at); return true; } return false; @@ -110,7 +112,7 @@ var FakeResponse = { if (doPathsMatch !== null) { if(item.responseCode && !FakeResponse.matchRegex(item.responseCode, responseCode)) return false; - if(item.verb && !FakeResponse.matchRegex(item.verb, verb)) return false; + if(item.verb && item.verb==verb) return false; var index = FakeResponse._items.indexOf(item); if (index > -1) { array.splice(index, 1); From 92a371bc50814a1aab99e855b7d30bc37c773523 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 17:49:15 +0100 Subject: [PATCH 20/43] Go, go, go --- fakeresponse.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fakeresponse.js b/fakeresponse.js index b6ed20f..157ba19 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -94,7 +94,7 @@ var FakeResponse = { if(item.queryParams && !FakeResponse.matchRegex(item.queryParams, uri.query)) return false; if(item.payload && !FakeResponse.matchRegex(item.payload, payload)) return false; if(item.requiredHeaders && !FakeResponse.matchRegex(item.requiredHeaders, headers)) return false; - if(item.verb && item.verb==verb) return false; + if(item.verb && !(item.verb==verb)) return false; //Revisar para que sea dividido por el modulo en lugar de solo la primera vez que coincidan if (item.at) return (item.numCalls === item.at); return true; @@ -104,9 +104,8 @@ var FakeResponse = { }, /* Filters all items that match the URL and then tries to check if there is a specific behavior for the Nth call on the same endpoint */ - matchDel: function (route, responseCode, verb) { - uri = url.parse(route, true); - + matchDel: function (uri, responseCode, verb) { + uri = url.parse(uri, true); return FakeResponse._items.filter(function (item) { var doPathsMatch = uri.pathname.match(new RegExp(item.route)); From 1a01e10418bb99d1b5d60df6c04324fdc8e9b8db Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 17:55:12 +0100 Subject: [PATCH 21/43] Terminar el borrar un elemento --- fakeresponse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fakeresponse.js b/fakeresponse.js index 157ba19..4d87838 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -111,7 +111,7 @@ var FakeResponse = { if (doPathsMatch !== null) { if(item.responseCode && !FakeResponse.matchRegex(item.responseCode, responseCode)) return false; - if(item.verb && item.verb==verb) return false; + if(item.verb && !(item.verb==verb)) return false; var index = FakeResponse._items.indexOf(item); if (index > -1) { array.splice(index, 1); From 5c5a8cefad9dff9fdfe3151bc97b7b257ab6d7d4 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 18:00:11 +0100 Subject: [PATCH 22/43] logs --- fakeresponse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fakeresponse.js b/fakeresponse.js index 4d87838..5cafbe0 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -108,7 +108,7 @@ var FakeResponse = { uri = url.parse(uri, true); return FakeResponse._items.filter(function (item) { var doPathsMatch = uri.pathname.match(new RegExp(item.route)); - + console.log("doPathsMatch="+doPathsMatch+ ", item.route="+item.route+", uri="+uri+"item.responseCode="+item.responseCode+", responseCode="+responseCode); if (doPathsMatch !== null) { if(item.responseCode && !FakeResponse.matchRegex(item.responseCode, responseCode)) return false; if(item.verb && !(item.verb==verb)) return false; From 3abbd4858097240d7d8e371ea37bc99f2800ef8d Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 18:06:18 +0100 Subject: [PATCH 23/43] fix delOne --- fakeresponse.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fakeresponse.js b/fakeresponse.js index 5cafbe0..60d621e 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -105,12 +105,13 @@ var FakeResponse = { /* Filters all items that match the URL and then tries to check if there is a specific behavior for the Nth call on the same endpoint */ matchDel: function (uri, responseCode, verb) { + console.log("uri="+uri); uri = url.parse(uri, true); return FakeResponse._items.filter(function (item) { var doPathsMatch = uri.pathname.match(new RegExp(item.route)); - console.log("doPathsMatch="+doPathsMatch+ ", item.route="+item.route+", uri="+uri+"item.responseCode="+item.responseCode+", responseCode="+responseCode); + console.log("doPathsMatch="+doPathsMatch+ ", item.route="+item.route+", item.responseCode="+item.responseCode+", responseCode="+responseCode); if (doPathsMatch !== null) { - if(item.responseCode && !FakeResponse.matchRegex(item.responseCode, responseCode)) return false; + if(item.responseCode && !(item.responseCode==responseCode)) return false; if(item.verb && !(item.verb==verb)) return false; var index = FakeResponse._items.indexOf(item); if (index > -1) { From 349e0dfeab5ff3b01989c05f916334c34f6a358c Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 18:09:30 +0100 Subject: [PATCH 24/43] f --- fakeresponse.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fakeresponse.js b/fakeresponse.js index 60d621e..2b7ab66 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -105,13 +105,12 @@ var FakeResponse = { /* Filters all items that match the URL and then tries to check if there is a specific behavior for the Nth call on the same endpoint */ matchDel: function (uri, responseCode, verb) { - console.log("uri="+uri); uri = url.parse(uri, true); return FakeResponse._items.filter(function (item) { var doPathsMatch = uri.pathname.match(new RegExp(item.route)); console.log("doPathsMatch="+doPathsMatch+ ", item.route="+item.route+", item.responseCode="+item.responseCode+", responseCode="+responseCode); if (doPathsMatch !== null) { - if(item.responseCode && !(item.responseCode==responseCode)) return false; + if(item.responseCode && !(item.responseCode===responseCode)) return false; if(item.verb && !(item.verb==verb)) return false; var index = FakeResponse._items.indexOf(item); if (index > -1) { From 9ac792084a728d8b47cb7acaa172c459c10f0890 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 18:13:49 +0100 Subject: [PATCH 25/43] probando borrado --- fakeresponse.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fakeresponse.js b/fakeresponse.js index 2b7ab66..b182302 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -108,10 +108,10 @@ var FakeResponse = { uri = url.parse(uri, true); return FakeResponse._items.filter(function (item) { var doPathsMatch = uri.pathname.match(new RegExp(item.route)); - console.log("doPathsMatch="+doPathsMatch+ ", item.route="+item.route+", item.responseCode="+item.responseCode+", responseCode="+responseCode); if (doPathsMatch !== null) { - if(item.responseCode && !(item.responseCode===responseCode)) return false; + if(item.responseCode && !(item.responseCode==responseCode)) return false; if(item.verb && !(item.verb==verb)) return false; + console.log("a por el borrado"); var index = FakeResponse._items.indexOf(item); if (index > -1) { array.splice(index, 1); From 7b2bed6d669921e0cd9d3adac0178e50149bb150 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 18:18:45 +0100 Subject: [PATCH 26/43] borrar logs innecesarios y finalizar el fixing del metodo "delOne" --- fakeresponse.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fakeresponse.js b/fakeresponse.js index b182302..c9318b0 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -84,13 +84,11 @@ var FakeResponse = { /* Filters all items that match the URL and then tries to check if there is a specific behavior for the Nth call on the same endpoint */ match: function (uri, payload, headers, verb) { uri = url.parse(uri, true); - console.log("verb="+verb); return FakeResponse._items.filter(function (item) { var doPathsMatch = uri.pathname.match(new RegExp(item.route)); if (doPathsMatch !== null) { item.numCalls += 1; - console.log("item.verb="+item.verb); if(item.queryParams && !FakeResponse.matchRegex(item.queryParams, uri.query)) return false; if(item.payload && !FakeResponse.matchRegex(item.payload, payload)) return false; if(item.requiredHeaders && !FakeResponse.matchRegex(item.requiredHeaders, headers)) return false; @@ -111,10 +109,9 @@ var FakeResponse = { if (doPathsMatch !== null) { if(item.responseCode && !(item.responseCode==responseCode)) return false; if(item.verb && !(item.verb==verb)) return false; - console.log("a por el borrado"); var index = FakeResponse._items.indexOf(item); if (index > -1) { - array.splice(index, 1); + FakeResponse._items.splice(index, 1); return true; }else{ return false; From 61f29ea2a32ab9447314ca3adcf2bfb5b8c58337 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 18:33:34 +0100 Subject: [PATCH 27/43] Comentar las nuevas opciones. --- README.md | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4dae936..9f4d48c 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,10 @@ Fake-server is a generic and non-intrusive tool used to mock any server response. It has been designed to address issues when running tests against unstable or slow external servers. -Modificaciones realizadas por crodriguez +crodriguez modifications: +*** Include "verb" param. Now you can add the method of the petition to make a complete RESTful api mock. +*** Include "delOne" method. If you want, you can del one or more mocks. + =========== @@ -109,7 +112,19 @@ Para esto, teneis que poneros en contacto conmigo --> crodriguez > responseCode: 200, > responseData: './mock_data/sample.json' } +##### Same endpoint with different verbs/method +Now, you can do a GET and POST at the same endpoint + +> { route: '/{TUPROYECTO}/login', +> responseCode: 200, +> responseBody: 'ok', +> verb: 'GET' } + +> { route: '/{TUPROYECTO}/login', +> responseCode: 200, +> responseBody: 'You are doing a POST', +> verb: 'POST' } ##### Same endpoint can have different responses @@ -136,6 +151,18 @@ The following will delay server response in one second: > responseBody: 'OK', > delay: 1000 } +## Delete one petition + +Sometimes, you want to remove an entry. So, now you can. + +All you have to do is 'DELETE' to http://192.168.6.74:3012/delOne the following data: + +Delete /test by deleting: +> { route: '/{TUPROYECTO}/test', +> responseCode: 200, +> verb: "GET" } + + ### Limitations -- There are reserved endpoints: POST '/add', POST '/getAll'. These cannot be used by your application. +- There are reserved endpoints: POST '/add', POST '/getAll', DELETE '/delOne'. These cannot be used by your application. From 78ce4560a6515b2d905b7f3fd7fa7dd6d306a09c Mon Sep 17 00:00:00 2001 From: crodriguez Date: Sun, 6 Mar 2016 18:49:20 +0100 Subject: [PATCH 28/43] Comentarios de HOWTO --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f4d48c..34c8d47 100644 --- a/README.md +++ b/README.md @@ -165,4 +165,4 @@ Delete /test by deleting: ### Limitations -- There are reserved endpoints: POST '/add', POST '/getAll', DELETE '/delOne'. These cannot be used by your application. +- There are reserved endpoints: POST '/add', GET '/getAll', DELETE '/delOne'. These cannot be used by your application. From 8243c0687ffe562d9aa629db0d7ea94a1c28b956 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 10 Mar 2016 10:51:07 +0100 Subject: [PATCH 29/43] Probando el cambio del Howto a ruta fija --- controller.js | 31 ++++++++++++++++++++++++++++++- default_routes/sample.json | 11 ++++++----- routes.js | 1 + 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/controller.js b/controller.js index dfe9aef..fb1a12c 100644 --- a/controller.js +++ b/controller.js @@ -40,6 +40,34 @@ var controller = { next(); }, + howto : function(req, res, next) { + + function send(statusCode, responseHeaders, responseBody) { + +// try { +// responseBody = JSON.stringify(responseBody); +// } catch (e) { +// responseBody = "Unable to serialize responseBody"; +// res.statusCode = 500; +// } + responseHeaders['Content-Length'] = Buffer.byteLength(responseBody); + res.writeHead(statusCode, responseHeaders); + res.write(responseBody); + res.end(); + } + + fs.readFile(path.join(__dirname, "./README.md"), 'utf8', function(err, + data) { + if (err) { + res.send(500, "FAKE-SERVER is misconfigured"); + } + send(parseInt(200, 10), headers, data); + }); + + res.send(200, 'OK'); + next(); + }, + delOne : function(req, res, next) { var obj = { route : req.params.route, @@ -128,7 +156,8 @@ var controller = { username : req.params.username, password : req.params.password, }; - console.log("flush( username=" + obj.username + ", password="+ obj.password + ")"); + console.log("flush( username=" + obj.username + ", password=" + + obj.password + ")"); if (obj.username == autorized.username) { if (obj.password == autorized.password) { controller.fakeResponse.flush(); diff --git a/default_routes/sample.json b/default_routes/sample.json index 4a37faf..335ab74 100644 --- a/default_routes/sample.json +++ b/default_routes/sample.json @@ -16,11 +16,12 @@ "Cookie": "username=.*" }, "responseBody": "headers match :-)" - }, - { - "route": "/HOWTO", - "responseCode":200, - "responseData": "./README.md" } +// , +// { +// "route": "/HOWTO", +// "responseCode":200, +// "responseData": "./README.md" +// } ] } diff --git a/routes.js b/routes.js index 0a00aef..3d4da6c 100644 --- a/routes.js +++ b/routes.js @@ -13,6 +13,7 @@ module.exports = function (server) { server.del('/delOne', controller.delOne); server.del('/flush', controller.flush); server.get('/getAll', controller.getAll); + server.get('/HOWTO', controller.howto); server.get(/(.*)/, controller.match); server.post(/(.*)/, controller.match); server.del(/(.*)/, controller.match); From 6902e37d7ec1f5463e1e83fbe82b2540d9c7c923 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 10 Mar 2016 10:55:53 +0100 Subject: [PATCH 30/43] Quitar el 200 OK --- controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller.js b/controller.js index fb1a12c..6ff0275 100644 --- a/controller.js +++ b/controller.js @@ -64,7 +64,7 @@ var controller = { send(parseInt(200, 10), headers, data); }); - res.send(200, 'OK'); +// res.send(200, 'OK'); next(); }, From 697d8464350001b2a19e5d10e3d6875a8d3b352f Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 10 Mar 2016 10:58:45 +0100 Subject: [PATCH 31/43] Meter los headers correctos. --- controller.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/controller.js b/controller.js index 6ff0275..1de9151 100644 --- a/controller.js +++ b/controller.js @@ -41,6 +41,10 @@ var controller = { }, howto : function(req, res, next) { + + var headers = { + 'Content-Type' : 'text/html' + }; function send(statusCode, responseHeaders, responseBody) { From 9774481e9bf5fe7bcaf4a088108a0a1c5717c795 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 10 Mar 2016 14:33:43 +0100 Subject: [PATCH 32/43] Meter un README2.html para que se muestre como tal. --- README2.html | 310 ++++++++++++++++++++++++++++++++++++++++++++++++++ controller.js | 2 +- 2 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 README2.html diff --git a/README2.html b/README2.html new file mode 100644 index 0000000..1a2b65b --- /dev/null +++ b/README2.html @@ -0,0 +1,310 @@ +#fake-server +
+
+[![Build +Status](https://travis-ci.org/yahoo/fake-server.svg)](https://travis-ci.org/yahoo/fake-server) +
+
+Fake-server is a generic and non-intrusive tool used to mock any server +response. It has been designed to address issues when running tests +against unstable or slow external servers. +
+
+crodriguez modifications: +
+*** Include "verb" param. Now you can add the method of the petition to +make a complete RESTful api mock. +
+*** Include "delOne" method. If you want, you can del one or more mocks. +
+
+
+=========== +
+
+## How it works +
+
+The idea is to create a webserver listening in a different port and make +your tests bring it up and configure how it should behave against each +different request. "Configuration" can be done by posting the parameters +and desired response to the server, or through configuration files +inside ./default_routes/. +
+
+For every request, fake-server will try to match against the configured +URIs and return the expected response. +
+
+## FIRST OF ALL. CALL THE NEXT METHOD TO KNOW IF YOUR ROUTE ALREADY +EXIST +
+curl http://192.168.6.74:3012/getAll +
+
+
+##### STARTING WITH THIS TEST SERVER +
+
+
+
+Let's say you want "/{TUPROYECTO}/test" to always return "hello" and +"/{TUPROYECTO}/foo" to return a 404. +
+
+All you have to do is `POST` to http://192.168.6.74:3012/add/ the +following data: +
+
+Configure /test by posting: +
+> { route: '/{TUPROYECTO}/test', +
+> responseCode: 200, +
+> responseBody: "hello" } +
+
+one of the many ways to do this is using cURL: +
+``` +
+curl http://192.168.6.74:3012/add -X POST -H +"Content-Type:application/json" -H "Accept:application/json" \ +
+-d +'{"route":"/{TUPROYECTO}/test","responseCode":200,"responseBody":"hello"}' +
+``` +
+
+now let's configure our 404 example by sending this to the server: +
+> { route: '/{TUPROYECTO}/foo', +
+> responseCode: 404, +
+> responseBody: "Not found" } +
+
+using cURL: +
+``` +
+curl http://192.168.6.74:3012/add -X POST -H +"Content-Type:application/json" -H "Accept:application/json" \ +
+-d '{"route":"/{TUPROYECTO}/foo","responseCode":404,"responseBody":"Not +found"}' +
+``` +
+
+now, in your browser you can see the results: +
+http://192.168.6.74:3012/{TUPROYECTO}/foo +
+http://192.168.6.74:3012/{TUPROYECTO}/test +
+
+
+### What else can fake-server do? +
+
+Configuration is done by sending a POST request to /add or by placing a +json file containing configurations inside a "routes" object (see +default_routes/sample.json for reference). Here are the supported +features for this version: +
+
+##### Routes can be RegEx +
+
+This will match http://192.168.6.74:3012/{TUPROYECTO}/news/007 as well +as http://192.168.6.74:3012/{TUPROYECTO}/news/1231293871293827: +
+
+> { route: '/{TUPROYECTO}/news/[0-9]' +
+> responseCode: 200, +
+> responseBody: 'whatever you want' } +
+
+##### Fake-server supports "POST" calls and uses payload for matching. +Regexs are supported for payload matching, and paths can be used to +specify inner properties of JSON payloads: +
+
+> { route: '/{TUPROYECTO}/news' +
+> payload: { +
+> id: [\\d+], +
+> requests[1].user.login: 'jdoe', +
+> month: "february" +
+> }, +
+> responseCode: 200, +
+> responseBody: 'yay! it matches' +
+> } +
+
+##### Support for query string matching. All query params are evaluated +as a RegEx. +
+
+> { route: '/{TUPROYECTO}/news', +
+> queryParams: { +
+> id: "[\\d+]", +
+> location: "Hawaii" +
+> } +
+> responseCode: 200, +
+> responseBody: 'Regex matching rocks' +
+> } +
+
+##### ... can also use the request Headers. So you can check if specific +cookies are present, for instance +
+
+> { route: '/{TUPROYECTO}/secure', +
+> requiredHeaders: { +
+> X-Auth: "secret", +
+> }, +
+> responseCode: 200, +
+> responseBody: 'header is there' +
+> } +
+
+
+##### Response can be a file. In this case, fake-server will respond +with the output of that file. +
+
+The following configuration example will return the output of +./mock_data/sample.json *(notice the parameter is called responseData +instead of responseBody)* +
+
+Para esto, teneis que poneros en contacto conmigo --> crodriguez +
+
+> { route: '/{TUPROYECTO}/', +
+> responseCode: 200, +
+> responseData: './mock_data/sample.json' } +
+
+##### Same endpoint with different verbs/method +
+
+Now, you can do a GET and POST at the same endpoint +
+
+> { route: '/{TUPROYECTO}/login', +
+> responseCode: 200, +
+> responseBody: 'ok', +
+> verb: 'GET' } +
+
+> { route: '/{TUPROYECTO}/login', +
+> responseCode: 200, +
+> responseBody: 'You are doing a POST', +
+> verb: 'POST' } +
+
+##### Same endpoint can have different responses +
+
+This will return '200' in the first two requests to '/{TUPROYECTO}/' and +403 on the third request +
+
+> { route: '/{TUPROYECTO}/', +
+> responseCode: 200, +
+> responseBody: 'ok' } +
+
+note that I will be adding an 'at' parameter to configure the special +behavior to the third request: +
+
+> { route: '/{TUPROYECTO}/', +
+> responseCode: 403, +
+> responseBody: 'Thou shall not pass!', +
+> at: 3 } +
+
+
+##### Delay response +
+
+The following will delay server response in one second: +
+
+> { route: '/{TUPROYECTO}/slow/.*', +
+> responseCode: 200, +
+> responseBody: 'OK', +
+> delay: 1000 } +
+
+## Delete one petition +
+
+Sometimes, you want to remove an entry. So, now you can. +
+
+All you have to do is 'DELETE' to http://192.168.6.74:3012/delOne the +following data: +
+
+Delete /test by deleting: +
+> { route: '/{TUPROYECTO}/test', +
+> responseCode: 200, +
+> verb: "GET" } +
+
+
+
+### Limitations +
+- There are reserved endpoints: POST '/add', GET '/getAll', DELETE +'/delOne'. These cannot be used by your application. +
\ No newline at end of file diff --git a/controller.js b/controller.js index 1de9151..86c1c49 100644 --- a/controller.js +++ b/controller.js @@ -60,7 +60,7 @@ var controller = { res.end(); } - fs.readFile(path.join(__dirname, "./README.md"), 'utf8', function(err, + fs.readFile(path.join(__dirname, "./README2.html"), 'utf8', function(err, data) { if (err) { res.send(500, "FAKE-SERVER is misconfigured"); From 7d7c6784f5708a7bc8ebf2c42634eea72fd94f02 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 10 Mar 2016 14:36:57 +0100 Subject: [PATCH 33/43] Eliminar la ruta al HowTo como un sample json --- default_routes/sample.json | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/default_routes/sample.json b/default_routes/sample.json index 335ab74..1589df7 100644 --- a/default_routes/sample.json +++ b/default_routes/sample.json @@ -16,12 +16,5 @@ "Cookie": "username=.*" }, "responseBody": "headers match :-)" - } -// , -// { -// "route": "/HOWTO", -// "responseCode":200, -// "responseData": "./README.md" -// } - ] + }] } From f14b326a002daa08eca13cdeedd73664f09ea301 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Wed, 6 Apr 2016 19:25:46 +0200 Subject: [PATCH 34/43] Delete personal data. --- README.md | 98 ++++++++++++++++++++++++--------------------- README2.html | 75 ++++++++++++++++------------------ mock_data/README.md | 0 3 files changed, 87 insertions(+), 86 deletions(-) delete mode 100644 mock_data/README.md diff --git a/README.md b/README.md index 34c8d47..9e63775 100644 --- a/README.md +++ b/README.md @@ -4,56 +4,58 @@ Fake-server is a generic and non-intrusive tool used to mock any server response. It has been designed to address issues when running tests against unstable or slow external servers. -crodriguez modifications: -*** Include "verb" param. Now you can add the method of the petition to make a complete RESTful api mock. -*** Include "delOne" method. If you want, you can del one or more mocks. - - =========== -## How it works +### How it works The idea is to create a webserver listening in a different port and make your tests bring it up and configure how it should behave against each different request. "Configuration" can be done by posting the parameters and desired response to the server, or through configuration files inside ./default_routes/. For every request, fake-server will try to match against the configured URIs and return the expected response. -## FIRST OF ALL. CALL THE NEXT METHOD TO KNOW IF YOUR ROUTE ALREADY EXIST -curl http://192.168.6.74:3012/getAll +### Advantages + +- No need to instrument your code (as long as the external server endpoint is configurable :P) +- Generic enough to work with blackbox or whitebox tests. +- No database required -##### STARTING WITH THIS TEST SERVER +### Quickstart (two really basic scenarios) +Clone this repository (npm package coming soon) +> git clone git@github.com:yahoo/fake-server.git +Start (it will start a server on port 3012) +> node server.js -Let's say you want "/{TUPROYECTO}/test" to always return "hello" and "/{TUPROYECTO}/foo" to return a 404. +Let's say you want "/test" to always return "hello" and "/foo" to return a 404. -All you have to do is `POST` to http://192.168.6.74:3012/add/ the following data: +All you have to do is `POST` to http://localhost:3012/add/ the following data: Configure /test by posting: -> { route: '/{TUPROYECTO}/test', +> { route: '/test', > responseCode: 200, > responseBody: "hello" } one of the many ways to do this is using cURL: ``` -curl http://192.168.6.74:3012/add -X POST -H "Content-Type:application/json" -H "Accept:application/json" \ - -d '{"route":"/{TUPROYECTO}/test","responseCode":200,"responseBody":"hello"}' +curl http://localhost:3012/add -X POST -H "Content-Type:application/json" -H "Accept:application/json" \ + -d '{"route":"/test","responseCode":200,"responseBody":"hello"}' ``` now let's configure our 404 example by sending this to the server: -> { route: '/{TUPROYECTO}/foo', +> { route: '/foo', > responseCode: 404, > responseBody: "Not found" } using cURL: ``` -curl http://192.168.6.74:3012/add -X POST -H "Content-Type:application/json" -H "Accept:application/json" \ - -d '{"route":"/{TUPROYECTO}/foo","responseCode":404,"responseBody":"Not found"}' +curl http://localhost:3012/add -X POST -H "Content-Type:application/json" -H "Accept:application/json" \ + -d '{"route":"/foo","responseCode":404,"responseBody":"Not found"}' ``` now, in your browser you can see the results: -http://192.168.6.74:3012/{TUPROYECTO}/foo -http://192.168.6.74:3012/{TUPROYECTO}/test +http://localhost:3012/foo +http://localhost:3012/test ### What else can fake-server do? @@ -62,15 +64,15 @@ Configuration is done by sending a POST request to /add or by placing a json fil ##### Routes can be RegEx -This will match http://192.168.6.74:3012/{TUPROYECTO}/news/007 as well as http://192.168.6.74:3012/{TUPROYECTO}/news/1231293871293827: +This will match http://localhost:3012/news/007 as well as http://localhost:3012/news/1231293871293827: -> { route: '/{TUPROYECTO}/news/[0-9]' +> { route: '/news/[0-9]' > responseCode: 200, > responseBody: 'whatever you want' } ##### Fake-server supports "POST" calls and uses payload for matching. Regexs are supported for payload matching, and paths can be used to specify inner properties of JSON payloads: -> { route: '/{TUPROYECTO}/news' +> { route: '/news' > payload: { > id: [\\d+], > requests[1].user.login: 'jdoe', @@ -82,7 +84,7 @@ This will match http://192.168.6.74:3012/{TUPROYECTO}/news/007 as well as http:/ ##### Support for query string matching. All query params are evaluated as a RegEx. -> { route: '/{TUPROYECTO}/news', +> { route: '/news', > queryParams: { > id: "[\\d+]", > location: "Hawaii" @@ -93,7 +95,7 @@ This will match http://192.168.6.74:3012/{TUPROYECTO}/news/007 as well as http:/ ##### ... can also use the request Headers. So you can check if specific cookies are present, for instance -> { route: '/{TUPROYECTO}/secure', +> { route: '/secure', > requiredHeaders: { > X-Auth: "secret", > }, @@ -106,63 +108,67 @@ This will match http://192.168.6.74:3012/{TUPROYECTO}/news/007 as well as http:/ The following configuration example will return the output of ./mock_data/sample.json *(notice the parameter is called responseData instead of responseBody)* -Para esto, teneis que poneros en contacto conmigo --> crodriguez - -> { route: '/{TUPROYECTO}/', +> { route: '/', > responseCode: 200, > responseData: './mock_data/sample.json' } -##### Same endpoint with different verbs/method - -Now, you can do a GET and POST at the same endpoint - -> { route: '/{TUPROYECTO}/login', -> responseCode: 200, -> responseBody: 'ok', -> verb: 'GET' } - -> { route: '/{TUPROYECTO}/login', -> responseCode: 200, -> responseBody: 'You are doing a POST', -> verb: 'POST' } ##### Same endpoint can have different responses -This will return '200' in the first two requests to '/{TUPROYECTO}/' and 403 on the third request +This will return '200' in the first two requests to '/' and 403 on the third request -> { route: '/{TUPROYECTO}/', +> { route: '/', > responseCode: 200, > responseBody: 'ok' } note that I will be adding an 'at' parameter to configure the special behavior to the third request: -> { route: '/{TUPROYECTO}/', +> { route: '/', > responseCode: 403, > responseBody: 'Thou shall not pass!', > at: 3 } +##### Same endpoint with different verbs/method + +Now, you can do a GET and POST at the same endpoint + +> { route: 'login', +> responseCode: 200, +> responseBody: 'ok', +> verb: 'GET' } + +> { route: 'login', +> responseCode: 200, +> responseBody: 'You are doing a POST', +> verb: 'POST' } + ##### Delay response The following will delay server response in one second: -> { route: '/{TUPROYECTO}/slow/.*', +> { route: '/slow/.*', > responseCode: 200, > responseBody: 'OK', > delay: 1000 } + ## Delete one petition Sometimes, you want to remove an entry. So, now you can. -All you have to do is 'DELETE' to http://192.168.6.74:3012/delOne the following data: +All you have to do is 'DELETE' to http://localhost:3012/delOne the following data: Delete /test by deleting: -> { route: '/{TUPROYECTO}/test', +> { route: 'test', > responseCode: 200, > verb: "GET" } +##### Resetting server configuration + +To avoid the need to restart fake-server in order to clear the configuration, we've implemented a special endpoint called `/flush`. By sending a `DELETE` request to http://localhost:3012/flush, you will erase all previously configured responses. + ### Limitations - There are reserved endpoints: POST '/add', GET '/getAll', DELETE '/delOne'. These cannot be used by your application. diff --git a/README2.html b/README2.html index 1a2b65b..eeb5942 100644 --- a/README2.html +++ b/README2.html @@ -10,15 +10,6 @@ against unstable or slow external servers.

-crodriguez modifications: -
-*** Include "verb" param. Now you can add the method of the petition to -make a complete RESTful api mock. -
-*** Include "delOne" method. If you want, you can del one or more mocks. -
-
-
===========

@@ -36,29 +27,33 @@ URIs and return the expected response.

-## FIRST OF ALL. CALL THE NEXT METHOD TO KNOW IF YOUR ROUTE ALREADY -EXIST -
-curl http://192.168.6.74:3012/getAll +### Advantages
+- No need to instrument your code (as long as the external server endpoint is configurable :P)
+- Generic enough to work with blackbox or whitebox tests.
+- No database required


-##### STARTING WITH THIS TEST SERVER +### Quickstart (two really basic scenarios)

+Clone this repository (npm package coming soon)
+> git clone git@github.com:yahoo/fake-server.git

+Start (it will start a server on port 3012)
+> node server.js


-Let's say you want "/{TUPROYECTO}/test" to always return "hello" and -"/{TUPROYECTO}/foo" to return a 404. +Let's say you want "/test" to always return "hello" and +"/foo" to return a 404.

-All you have to do is `POST` to http://192.168.6.74:3012/add/ the +All you have to do is `POST` to http://localhost:3012/add/ the following data:

Configure /test by posting:
-> { route: '/{TUPROYECTO}/test', +> { route: '/test',
> responseCode: 200,
@@ -69,18 +64,18 @@
```
-curl http://192.168.6.74:3012/add -X POST -H +curl http://localhost:3012/add -X POST -H "Content-Type:application/json" -H "Accept:application/json" \
-d -'{"route":"/{TUPROYECTO}/test","responseCode":200,"responseBody":"hello"}' +'{"route":"/test","responseCode":200,"responseBody":"hello"}'
```

now let's configure our 404 example by sending this to the server:
-> { route: '/{TUPROYECTO}/foo', +> { route: '/foo',
> responseCode: 404,
@@ -91,10 +86,10 @@
```
-curl http://192.168.6.74:3012/add -X POST -H +curl http://localhost:3012/add -X POST -H "Content-Type:application/json" -H "Accept:application/json" \
--d '{"route":"/{TUPROYECTO}/foo","responseCode":404,"responseBody":"Not +-d '{"route":"/foo","responseCode":404,"responseBody":"Not found"}'
``` @@ -102,9 +97,9 @@
now, in your browser you can see the results:
-http://192.168.6.74:3012/{TUPROYECTO}/foo +http://localhost:3012/foo
-http://192.168.6.74:3012/{TUPROYECTO}/test +http://localhost:3012/test


@@ -120,11 +115,11 @@ ##### Routes can be RegEx

-This will match http://192.168.6.74:3012/{TUPROYECTO}/news/007 as well -as http://192.168.6.74:3012/{TUPROYECTO}/news/1231293871293827: +This will match http://localhost:3012/news/007 as well +as http://localhost:3012/news/1231293871293827:

-> { route: '/{TUPROYECTO}/news/[0-9]' +> { route: '/news/[0-9]'
> responseCode: 200,
@@ -136,7 +131,7 @@ specify inner properties of JSON payloads:

-> { route: '/{TUPROYECTO}/news' +> { route: '/news'
> payload: {
@@ -159,7 +154,7 @@ as a RegEx.

-> { route: '/{TUPROYECTO}/news', +> { route: '/news',
> queryParams: {
@@ -180,7 +175,7 @@ cookies are present, for instance

-> { route: '/{TUPROYECTO}/secure', +> { route: '/secure',
> requiredHeaders: {
@@ -208,7 +203,7 @@ Para esto, teneis que poneros en contacto conmigo --> crodriguez

-> { route: '/{TUPROYECTO}/', +> { route: '/',
> responseCode: 200,
@@ -221,7 +216,7 @@ Now, you can do a GET and POST at the same endpoint

-> { route: '/{TUPROYECTO}/login', +> { route: '/login',
> responseCode: 200,
@@ -230,7 +225,7 @@ > verb: 'GET' }

-> { route: '/{TUPROYECTO}/login', +> { route: '/login',
> responseCode: 200,
@@ -242,11 +237,11 @@ ##### Same endpoint can have different responses

-This will return '200' in the first two requests to '/{TUPROYECTO}/' and +This will return '200' in the first two requests to '/' and 403 on the third request

-> { route: '/{TUPROYECTO}/', +> { route: '/',
> responseCode: 200,
@@ -257,7 +252,7 @@ behavior to the third request:

-> { route: '/{TUPROYECTO}/', +> { route: '/',
> responseCode: 403,
@@ -273,7 +268,7 @@ The following will delay server response in one second:

-> { route: '/{TUPROYECTO}/slow/.*', +> { route: '/slow/.*',
> responseCode: 200,
@@ -288,13 +283,13 @@ Sometimes, you want to remove an entry. So, now you can.

-All you have to do is 'DELETE' to http://192.168.6.74:3012/delOne the +All you have to do is 'DELETE' to http://localhost:3012/delOne the following data:

Delete /test by deleting:
-> { route: '/{TUPROYECTO}/test', +> { route: '/test',
> responseCode: 200,
diff --git a/mock_data/README.md b/mock_data/README.md deleted file mode 100644 index e69de29..0000000 From 06809603870acb46b00e6723a0f0df0a73511fd1 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Wed, 6 Apr 2016 20:41:40 +0200 Subject: [PATCH 35/43] Delete autorized for Flush --- controller.js | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/controller.js b/controller.js index 86c1c49..66ac0ae 100644 --- a/controller.js +++ b/controller.js @@ -151,29 +151,11 @@ var controller = { } }, - flush : function(req, res, next) { - var autorized = { - username : "crodriguez", - password : "crodriguez" - }; - var obj = { - username : req.params.username, - password : req.params.password, - }; - console.log("flush( username=" + obj.username + ", password=" - + obj.password + ")"); - if (obj.username == autorized.username) { - if (obj.password == autorized.password) { - controller.fakeResponse.flush(); - res.send(200, 'OK'); - return next(); - } - } else { - res.send(401, 'Unauthorized!!!'); - return next(new restify.ConflictError("I just don't like you")); - } - - } + flush: function (req, res, next) { + controller.fakeResponse.flush(); + res.send(200, 'OK'); + next(); + } }; module.exports = controller; From 76456ccaaea298348224c631f1485bc278f12eeb Mon Sep 17 00:00:00 2001 From: crodriguez Date: Wed, 6 Apr 2016 20:49:35 +0200 Subject: [PATCH 36/43] Delete some comments. --- controller.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/controller.js b/controller.js index 66ac0ae..0464801 100644 --- a/controller.js +++ b/controller.js @@ -48,12 +48,6 @@ var controller = { function send(statusCode, responseHeaders, responseBody) { -// try { -// responseBody = JSON.stringify(responseBody); -// } catch (e) { -// responseBody = "Unable to serialize responseBody"; -// res.statusCode = 500; -// } responseHeaders['Content-Length'] = Buffer.byteLength(responseBody); res.writeHead(statusCode, responseHeaders); res.write(responseBody); From f112d897d1e394df46887ffebe6bc670f2c9d948 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Wed, 6 Apr 2016 20:55:49 +0200 Subject: [PATCH 37/43] Delete unnecessary dependency --- controller.js | 1 - 1 file changed, 1 deletion(-) diff --git a/controller.js b/controller.js index 0464801..fbdcd00 100644 --- a/controller.js +++ b/controller.js @@ -12,7 +12,6 @@ var path = require('path'); var argv = require('yargs').argv; var FakeResponse = require('./fakeresponse.js'); var merge = require('merge'); -var restify = require('restify'); // Preload routes FakeResponse.preload(argv.configDir); From d97904854f7d0189b727aa397e60753ca249df9c Mon Sep 17 00:00:00 2001 From: crodriguez Date: Thu, 7 Apr 2016 10:06:46 +0200 Subject: [PATCH 38/43] Added tests for delOne and method matching --- test/controller.js | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/test/controller.js b/test/controller.js index b1b6979..a81a1c3 100644 --- a/test/controller.js +++ b/test/controller.js @@ -301,4 +301,76 @@ describe('Integration tests', function () { assert.isTrue(res.writeHead.calledWith(123)); }); + + it('should provide a way to delete one response for a given endpoint', function () { + var req = { + params: { + route: '/foo/bar', + responseCode: 404, + verb: 'GET' + } + }; + + var res = { + send: sinon.stub(), + write: sinon.stub(), + writeHead: sinon.stub(), + end: sinon.stub() + }; + + + sinon.stub(controller.fakeResponse, 'matchDel'); + + controller.delOne(req, res, function () {}); + + assert.isTrue(controller.fakeResponse.matchDel.calledOnce); + + controller.fakeResponse.matchDel.restore(); + }); + + + it('should allow different behaviours for the same request based on the verb', function () { + var responses = [{ + route: '/', + responseCode: 200, + responseBody: 'OK', + numCalls: 0, + verb: 'GET' + }, { + route: '/', + responseCode: 403, + responseBody: 'yay!', + at: 3, + numCalls: 0, + verb: 'POST' + }]; + + var req = { + url: '/', + method: 'GET' + }; + + var req2 = { + url: '/', + method: 'POST' + }; + + var res = { + write: sinon.stub(), + writeHead: sinon.stub(), + send: sinon.stub(), + end: sinon.stub() + }; + + controller.fakeResponse._items = responses; + + controller.match(req, res, function () {}); + res.writeHead.calledWithExactly(200, {'Content-Type': 'application/json', 'Content-Length': 2}) + res.write.lastCall.calledWithExactly('OK'); + + controller.match(req2, res, function () {}); + res.writeHead.calledWithExactly(403, {'Content-Type': 'application/json', 'Content-Length': 4}) + res.write.lastCall.calledWithExactly('yay!'); + + }); }); From 9feccd6fd12093999d0869d7734b20859f121a38 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Fri, 8 Apr 2016 14:20:23 +0200 Subject: [PATCH 39/43] Fix README. --- README.md | 2 +- README2.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9e63775..34129d0 100644 --- a/README.md +++ b/README.md @@ -171,4 +171,4 @@ To avoid the need to restart fake-server in order to clear the configuration, we ### Limitations -- There are reserved endpoints: POST '/add', GET '/getAll', DELETE '/delOne'. These cannot be used by your application. +- There are reserved endpoints: POST '/add', GET '/getAll', DELETE '/delOne' and DELETE, '/flush'. These cannot be used by your application. diff --git a/README2.html b/README2.html index eeb5942..5f99625 100644 --- a/README2.html +++ b/README2.html @@ -301,5 +301,5 @@ ### Limitations
- There are reserved endpoints: POST '/add', GET '/getAll', DELETE -'/delOne'. These cannot be used by your application. +'/delOne' and DELETE, '/flush'. These cannot be used by your application.
\ No newline at end of file From df12160890fe14dd4e2a58fe1b44d1b131b41f5d Mon Sep 17 00:00:00 2001 From: Cesar Rodriguez Date: Sat, 9 Apr 2016 19:16:27 +0200 Subject: [PATCH 40/43] Update fakeresponse.js --- fakeresponse.js | 1 - 1 file changed, 1 deletion(-) diff --git a/fakeresponse.js b/fakeresponse.js index c9318b0..07b4f8b 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -93,7 +93,6 @@ var FakeResponse = { if(item.payload && !FakeResponse.matchRegex(item.payload, payload)) return false; if(item.requiredHeaders && !FakeResponse.matchRegex(item.requiredHeaders, headers)) return false; if(item.verb && !(item.verb==verb)) return false; - //Revisar para que sea dividido por el modulo en lugar de solo la primera vez que coincidan if (item.at) return (item.numCalls === item.at); return true; } From f29ebdc25a94321b26cba955fc8e2591e6029fe9 Mon Sep 17 00:00:00 2001 From: crodriguez Date: Tue, 12 Apr 2016 17:39:01 +0200 Subject: [PATCH 41/43] Modifications: - controller.js calls to fakeresponse has changed - fakeresponse.js refactorized match and delOne to be one method. - test/controller.js improvements in test and changes - test/fakeresponse.js improvements in test and changes --- controller.js | 247 +++++++++++++++++++++---------------------- fakeresponse.js | 103 ++++++++++-------- test/controller.js | 12 ++- test/fakeresponse.js | 84 ++++++++++----- 4 files changed, 246 insertions(+), 200 deletions(-) diff --git a/controller.js b/controller.js index fbdcd00..b7d0cff 100644 --- a/controller.js +++ b/controller.js @@ -17,132 +17,127 @@ var merge = require('merge'); FakeResponse.preload(argv.configDir); var controller = { - fakeResponse : FakeResponse, // of course this is here just so that it - // can be overwritten easily in the tests. - - add : function(req, res, next) { - var obj = { - verb : req.params.verb, - delay : req.params.delay, - at : req.params.at, - route : req.params.route, - queryParams : req.params.queryParams, - payload : req.params.payload, - responseCode : req.params.responseCode, - responseBody : decodeURIComponent(req.params.responseBody.replace( - /"/g, '"')), - }; - - controller.fakeResponse.add(obj); - - res.send(200, 'OK'); - next(); - }, - - howto : function(req, res, next) { - - var headers = { - 'Content-Type' : 'text/html' - }; - - function send(statusCode, responseHeaders, responseBody) { - - responseHeaders['Content-Length'] = Buffer.byteLength(responseBody); - res.writeHead(statusCode, responseHeaders); - res.write(responseBody); - res.end(); - } - - fs.readFile(path.join(__dirname, "./README2.html"), 'utf8', function(err, - data) { - if (err) { - res.send(500, "FAKE-SERVER is misconfigured"); - } - send(parseInt(200, 10), headers, data); - }); - -// res.send(200, 'OK'); - next(); - }, - - delOne : function(req, res, next) { - var obj = { - route : req.params.route, - verb : req.params.verb, - responseCode : req.params.responseCode, - }; - - var bestMatch = controller.fakeResponse.matchDel(obj.route, - obj.responseCode, obj.verb); - - if (bestMatch) { - res.send(410, 'GONE'); - } else { - res.send(404, 'NOT FOUND!'); - } - next(); - }, - - getAll : function(req, res, next) { - var obj = controller.fakeResponse.getAll(obj); - - res.send(200, obj); - next(); - }, - - match : function(req, res, next) { - - function send(statusCode, responseHeaders, responseBody) { - if (typeof responseBody === "object") { - try { - responseBody = JSON.stringify(responseBody); - } catch (e) { - responseBody = "Unable to serialize responseBody"; - res.statusCode = 500; - } - } - responseHeaders['Content-Length'] = Buffer.byteLength(responseBody); - res.writeHead(statusCode, responseHeaders); - res.write(responseBody); - res.end(); - } - - var bestMatch = controller.fakeResponse.match(req.url, req.body, - req.headers, req.method); - - if (bestMatch) { - var headers = { - 'Content-Type' : 'application/json' - }; - if (bestMatch.responseHeaders) { - headers = merge(headers, bestMatch.responseHeaders); - } - if (bestMatch.responseData) { - - fs.readFile(path.join(__dirname, bestMatch.responseData), - 'utf8', function(err, data) { - if (err) { - res.send(500, "FAKE-SERVER is misconfigured"); - } - send(parseInt(bestMatch.responseCode, 10), headers, - data); - }); - - } else { - send(parseInt(bestMatch.responseCode, 10), headers, - bestMatch.responseBody); - } - - if (bestMatch.delay) { - setTimeout(next, bestMatch.delay); - } else { - next(); - } - } else { - res.send(404, 'no match!'); - next(); - } - }, + fakeResponse : FakeResponse, // of course this is here just so that it + // can be overwritten easily in the tests. + + add : function(req, res, next) { + var obj = { + verb : req.params.verb, + delay : req.params.delay, + at : req.params.at, + route : req.params.route, + queryParams : req.params.queryParams, + payload : req.params.payload, + responseCode : req.params.responseCode, + responseBody : decodeURIComponent(req.params.responseBody.replace( + /"/g, '"')), + }; + + controller.fakeResponse.add(obj); + + res.send(200, 'OK'); + next(); + }, + + howto : function(req, res, next) { + + var headers = { + 'Content-Type' : 'text/html' + }; + + function send(statusCode, responseHeaders, responseBody) { + + responseHeaders['Content-Length'] = Buffer.byteLength(responseBody); + res.writeHead(statusCode, responseHeaders); + res.write(responseBody); + res.end(); + } + + fs.readFile(path.join(__dirname, "./README2.html"), 'utf8', function(err, + data) { + if (err) { + res.send(500, "FAKE-SERVER is misconfigured"); + } + send(200, headers, data); + }); + + next(); + }, + + delOne : function(req, res, next) { + + + var bestMatch = controller.fakeResponse.match(true, req, res); + + if (bestMatch) { + res.send(410, 'GONE'); + } else { + res.send(404, 'NOT FOUND!'); + } + next(); + }, + + getAll : function(req, res, next) { + var obj = controller.fakeResponse.getAll(obj); + + res.send(200, obj); + next(); + }, + + match : function(req, res, next) { + + function send(statusCode, responseHeaders, responseBody) { + + if (typeof responseBody === "object") { + try { + responseBody = JSON.stringify(responseBody); + } catch (e) { + responseBody = "Unable to serialize responseBody"; + res.statusCode = 500; + } + } + responseHeaders['Content-Length'] = Buffer.byteLength(responseBody); + res.writeHead(statusCode, responseHeaders); + res.write(responseBody); + res.end(); + } + + var bestMatch = controller.fakeResponse.match(false, req, res); + + if (bestMatch) { + var headers = { + 'Content-Type' : 'application/json' + }; + if (bestMatch.responseHeaders) { + headers = merge(headers, bestMatch.responseHeaders); + } + if (bestMatch.responseData) { + + + fs.readFile(path.join(__dirname, bestMatch.responseData), + 'utf8', function(err, data) { + if (err) { + res.send(500, "FAKE-SERVER is misconfigured"); + } + send(parseInt(bestMatch.responseCode, 10), headers, + data); + }); + + } else { + send(parseInt(bestMatch.responseCode, 10), headers, + bestMatch.responseBody); + } + + if (bestMatch.delay) { + setTimeout(next, bestMatch.delay); + } else { + next(); + } + } else { + res.send(404, 'no match!'); + next(); + } + }, flush: function (req, res, next) { controller.fakeResponse.flush(); diff --git a/fakeresponse.js b/fakeresponse.js index 07b4f8b..d3de6eb 100644 --- a/fakeresponse.js +++ b/fakeresponse.js @@ -47,11 +47,7 @@ var FakeResponse = { FakeResponse._items.push(item); }, - delOne: function (item) { - item.numCalls = 0; - FakeResponse._items.push(item); - }, - + flush: function () { FakeResponse._items = []; }, @@ -81,45 +77,68 @@ var FakeResponse = { }, - /* Filters all items that match the URL and then tries to check if there is a specific behavior for the Nth call on the same endpoint */ - match: function (uri, payload, headers, verb) { - uri = url.parse(uri, true); - return FakeResponse._items.filter(function (item) { - var doPathsMatch = uri.pathname.match(new RegExp(item.route)); - - if (doPathsMatch !== null) { - item.numCalls += 1; - if(item.queryParams && !FakeResponse.matchRegex(item.queryParams, uri.query)) return false; - if(item.payload && !FakeResponse.matchRegex(item.payload, payload)) return false; - if(item.requiredHeaders && !FakeResponse.matchRegex(item.requiredHeaders, headers)) return false; - if(item.verb && !(item.verb==verb)) return false; - if (item.at) return (item.numCalls === item.at); - return true; - } - return false; - }).sort(FakeResponse.compareMatches)[0] || null; - }, - - /* Filters all items that match the URL and then tries to check if there is a specific behavior for the Nth call on the same endpoint */ - matchDel: function (uri, responseCode, verb) { - uri = url.parse(uri, true); - return FakeResponse._items.filter(function (item) { - var doPathsMatch = uri.pathname.match(new RegExp(item.route)); - if (doPathsMatch !== null) { - if(item.responseCode && !(item.responseCode==responseCode)) return false; - if(item.verb && !(item.verb==verb)) return false; - var index = FakeResponse._items.indexOf(item); - if (index > -1) { - FakeResponse._items.splice(index, 1); - return true; - }else{ - return false; + /* + * If del --> false + * Filters all items that match the URL and then tries to check if there is + * a specific behavior for the Nth call on the same endpoint. + * If del --> true + * Filters all items that match the URL, verb and responseCode and then del this endpoint. + */ + match: function (del, req, res) { + + var uri =''; + var verb = ''; + var payload=''; + var headers=''; + + return FakeResponse._items.filter(function (item) { + if(!del){ + uri = req.url; + uri= url.parse(uri, true); + var doPathsMatch = uri.pathname.match(new RegExp(item.route)); + if (doPathsMatch !== null) { + item.numCalls += 1; + + verb = req.method; + if(item.verb && !(item.verb==verb)) return false; + + if(item.queryParams && !FakeResponse.matchRegex(item.queryParams, uri.query)) return false; + + payload=req.body; + if(item.payload && !FakeResponse.matchRegex(item.payload, payload)) return false; + + headers = req.headers; + if(item.requiredHeaders && !FakeResponse.matchRegex(item.requiredHeaders, headers)) return false; + + if (item.at) return (item.numCalls === item.at); + return true; + } + }else{ + uri = req.params.route; + uri= url.parse(uri, true); + + var doPathsMatch = uri.pathname.match(new RegExp(item.route)); + + if (doPathsMatch !== null) { + verb = req.params.verb; + if(item.verb && !(item.verb==verb)) return false; + + var responseCode = req.params.responseCode; + if(item.responseCode && !(item.responseCode==responseCode)) return false; + var index = FakeResponse._items.indexOf(item); + if (index > -1) { + FakeResponse._items.splice(index, 1); + return true; + }else{ + return false; + } + } } - } - return false; - }).sort(FakeResponse.compareMatches)[0] || null; + return false; + }).sort(FakeResponse.compareMatches)[0] || null; + }, - + /* * Match objB's values against regular expressions stored in objA. Key equality determines values to test. * @param {objA} An object whose string values represent regular expressions diff --git a/test/controller.js b/test/controller.js index a81a1c3..1518546 100644 --- a/test/controller.js +++ b/test/controller.js @@ -307,7 +307,8 @@ describe('Integration tests', function () { params: { route: '/foo/bar', responseCode: 404, - verb: 'GET' + verb: 'GET', + responseBody: 'You want to delete something', } }; @@ -318,14 +319,17 @@ describe('Integration tests', function () { end: sinon.stub() }; + sinon.stub(controller.fakeResponse, 'add'); + + controller.add(req, res, function () {}); - sinon.stub(controller.fakeResponse, 'matchDel'); + sinon.stub(controller.fakeResponse, 'match'); controller.delOne(req, res, function () {}); - assert.isTrue(controller.fakeResponse.matchDel.calledOnce); + assert.isTrue(controller.fakeResponse.match.calledOnce); - controller.fakeResponse.matchDel.restore(); + controller.fakeResponse.match.restore(); }); diff --git a/test/fakeresponse.js b/test/fakeresponse.js index 3c25cc9..ced5e30 100644 --- a/test/fakeresponse.js +++ b/test/fakeresponse.js @@ -18,7 +18,7 @@ describe('FakeResponse model tests', function () { }); it('should return null if no routes have been added', function() { - var response = model.match('/match/me'); + var response = model.match(false, '/match/me'); assert.equal(null, response); }); @@ -63,11 +63,36 @@ describe('FakeResponse model tests', function () { model.add(obj); - var response = model.match('/foo/bar'); + var response = model.match(false,{url:'/foo/bar'}); assert.deepEqual(response, obj); }); + + + it('should match successfully a route with the expected answers based in request with verb', function () { + var obj = { + route: '/foo/bar', + responseCode: 200, + verb: 'GET', + responseBody: 'foo', + }; + + model.add({ + route: '/foo/bar', + responseCode: 200, + verb: 'PUT', + responseBody: 'foo2', + }); + + model.add(obj); + + var response = model.match(false,{url:'/foo/bar', method:'GET'}); + + assert.deepEqual(response, obj); + }); + + it('should match based on regexp', function () { var obj = { route: '/foo.*', @@ -83,7 +108,7 @@ describe('FakeResponse model tests', function () { responseBody: '§xxx', }); - var response = model.match('/foo/bar'); + var response = model.match(false,{url:'/foo/bar'}); assert.deepEqual(response, obj); }); @@ -108,11 +133,11 @@ describe('FakeResponse model tests', function () { at: 2 }); - var firstReq = model.match('/match/me'); + var firstReq = model.match(false,{url:'/match/me'}); assert.equal(200, firstReq.responseCode); - var secondReq = model.match('/match/me'); + var secondReq = model.match(false,{url:'/match/me'}); assert.equal(204, secondReq.responseCode); - var thirdReq = model.match('/match/me'); + var thirdReq = model.match(false,{url:'/match/me'}); assert.equal(200, thirdReq.responseCode); }); @@ -144,7 +169,7 @@ describe('FakeResponse model tests', function () { responseBody: 'weba', }); /*even though "uri" is the same, we are only matching if payload contains id:1 */ - var response = model.match('/match/me'); + var response = model.match(false,{url:'/match/me'}); assert.equal(null, response); }); @@ -166,7 +191,10 @@ describe('FakeResponse model tests', function () { responseBody: 'buuu' }); /*even though "uri" is the same, we are only matching if payload contains id:1 */ - var response = model.match('/match/me', { id: 1 }); + var response = model.match(false,{url:'/match/me', body:{'id': 1}}); + + assert.equal(2, model.getAll().length); + assert.deepEqual(response.responseBody, 'weba'); assert.deepEqual(response.responseCode, 200); }); @@ -189,7 +217,7 @@ describe('FakeResponse model tests', function () { responseBody: 'buuu' }); - var response = model.match('/match/me', { outer: [{inner: 1 }]}); + var response = model.match(false,{url:'/match/me', body:{ outer: [{inner: 1 }]}}); assert.deepEqual(response.responseBody, 'weba'); assert.deepEqual(response.responseCode, 200); }); @@ -204,11 +232,11 @@ describe('FakeResponse model tests', function () { responseBody: 'weba' }); - var response = model.match('/match/me?outer[0].inner=1'); + var response = model.match(false,{url:'/match/me?outer[0].inner=1'}); assert.deepEqual(response.responseBody, 'weba'); assert.deepEqual(response.responseCode, 200); - response = model.match('/match/me?param=1'); + response = model.match(false,{url:'/match/me?param=1'}); assert.deepEqual(response, null); }); it('should match POST request payloads using explicit regular expressions', function() { @@ -220,7 +248,7 @@ describe('FakeResponse model tests', function () { responseCode: 200, responseBody: 'Regex success', }); - var response = model.match('/match/me', { id: 9273892 }); + var response = model.match(false,{url:'/match/me', body:{ id: 9273892 }}); assert.deepEqual(response.responseBody, 'Regex success'); assert.deepEqual(response.responseCode, 200); @@ -233,12 +261,12 @@ describe('FakeResponse model tests', function () { responseCode: 200, responseBody: 'Regex success', }); - response = model.match('/match/me', { a: 2, b:"baz" }); + response = model.match(false,{url:'/match/me', body:{ a: 2, b:"baz" }}); assert.deepEqual(response.responseBody, 'Regex success'); assert.deepEqual(response.responseCode, 200); // Non-matching payload (bazz) should fail - response = model.match('/match/me', { a: 2, foo:"bazz" }); + response = model.match(false,{url:'/match/me', body:{ a: 2, foo:"bazz" }}); assert.equal(null, response); }); @@ -255,12 +283,12 @@ describe('FakeResponse model tests', function () { responseBody: 'Query param success' }); - var response = model.match('/match/me?a=1&b=2'); + var response = model.match(false,{url:'/match/me?a=1&b=2'}); assert.deepEqual(response.responseCode, 200); assert.deepEqual(response.responseBody, 'Query param success'); // Varying order of query params shouldn't affect matching - response = model.match('/match/me?a=1&b=2'); + response = model.match(false,{url:'/match/me?a=1&b=2'}); assert.deepEqual(response.responseCode, 200); assert.deepEqual(response.responseBody, 'Query param success'); @@ -274,12 +302,12 @@ describe('FakeResponse model tests', function () { }); // query params with spaces should work - response = model.match('/match/me?name=Fabio Hirata'); + response = model.match(false,{url:'/match/me?name=Fabio Hirata'}); assert.deepEqual(response.responseCode, 200); assert.deepEqual(response.responseBody, 'Space success'); // ...even if encoded with + - response = model.match('/match/me?name=Fabio+Hirata'); + response = model.match(false,{url:'/match/me?name=Fabio+Hirata'}); assert.deepEqual(response.responseCode, 200); assert.deepEqual(response.responseBody, 'Space success'); }); @@ -295,15 +323,15 @@ describe('FakeResponse model tests', function () { responseBody: 'Regex success' }); - var response = model.match('/match/me?a=0'); + var response = model.match(false,{url:'/match/me?a=0'}); assert.deepEqual(response.responseCode, 200); assert.deepEqual(response.responseBody, 'Regex success'); - response = model.match('/match/me?a=9'); + response = model.match(false,{url:'/match/me?a=9'}); assert.deepEqual(response.responseCode, 200); assert.deepEqual(response.responseBody, 'Regex success'); - response = model.match('/match/me?a=1234567890'); + response = model.match(false,{url:'/match/me?a=1234567890'}); assert.deepEqual(response.responseCode, 200); assert.deepEqual(response.responseBody, 'Regex success'); @@ -320,7 +348,7 @@ describe('FakeResponse model tests', function () { responseBody: 'Regex success' }); - response = model.match('/match/me?e=bar&b=12345&c=6789&d=1'); + response = model.match(false,{url:'/match/me?e=bar&b=12345&c=6789&d=1'}); assert.deepEqual(response.responseCode, 200); assert.deepEqual(response.responseBody, 'Regex success'); }); @@ -346,18 +374,18 @@ describe('FakeResponse model tests', function () { model.add(route1); model.add(route2); - var response = model.match('/match/me?a=1234', {b: 'abcd'}); + var response = model.match(false,{url:'/match/me?a=1234', body:{b: 'abcd'}}); assert.equal(response.responseCode, 200); - response = model.match('/match/me?a=1234', {b: 'abc123'}); + response = model.match(false,{url:'/match/me?a=1234', body:{b: 'abc123'}}); assert.equal(response.responseCode, 400); model.flush(); model.add(route2); model.add(route1); - response = model.match('/match/me?a=1234', {b: 'abcd'}); + response = model.match(false,{url:'/match/me?a=1234', body:{b: 'abcd'}}); assert.equal(response.responseCode, 200); - response = model.match('/match/me?a=1234', {b: 'abc123'}); + response = model.match(false,{url:'/match/me?a=1234', body:{b: 'abc123'}}); assert.equal(response.responseCode, 400); }); @@ -383,14 +411,14 @@ describe('FakeResponse model tests', function () { }; model.add(route1); model.add(route2); - var response = model.match('/match/me?a=1234', null, { Cookie: 'Y=abcd' }); + var response = model.match(false,{url:'/match/me?a=1234', headers:{ Cookie: 'Y=abcd' }}); assert.equal(response.responseCode, 200); model.flush(); model.add(route1); model.add(route2); - response = model.match('/match/me?a=1234'); + response = model.match(false,{url:'/match/me?a=1234'}); assert.equal(response.responseCode, 400); }); }); From 2e54d83a9f1c15d28e0a939c9b73fef8a0b86fe5 Mon Sep 17 00:00:00 2001 From: Cesar Rodriguez Date: Mon, 16 May 2016 13:08:06 +0200 Subject: [PATCH 42/43] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 34129d0..3df7418 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ The following will delay server response in one second: > delay: 1000 } -## Delete one petition +### Delete one petition Sometimes, you want to remove an entry. So, now you can. From 95d021a90c2b1c854fbd04493d0223936e09d3bf Mon Sep 17 00:00:00 2001 From: Cesar Rodriguez Date: Tue, 17 May 2016 14:44:12 +0200 Subject: [PATCH 43/43] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3df7418..35aeb57 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ Delete /test by deleting: > verb: "GET" } -##### Resetting server configuration +#### Resetting server configuration To avoid the need to restart fake-server in order to clear the configuration, we've implemented a special endpoint called `/flush`. By sending a `DELETE` request to http://localhost:3012/flush, you will erase all previously configured responses.