From 229f9d6cd1ee63233aaf405e6d713edb4c7b5c54 Mon Sep 17 00:00:00 2001 From: Giovanni Briggs Date: Tue, 9 Aug 2016 16:25:32 -0700 Subject: [PATCH] Improved test cases and updated docs. Improved test cases and added requirements file for Python middleware. Also added docs on testing. --- .gitignore | 3 +++ docs/backend.rst | 40 ++++++++++++++++++++++++++++------ docs/index.rst | 1 + docs/middleware.rst | 5 +++++ docs/testing.rst | 50 +++++++++++++++++++++++++++++++++++++++++++ package.json | 1 - server.js | 15 +++++++++---- test/requirements.txt | 6 ++++++ test/server.js | 2 +- 9 files changed, 111 insertions(+), 12 deletions(-) create mode 100644 docs/testing.rst create mode 100644 test/requirements.txt diff --git a/.gitignore b/.gitignore index 155bfd4..7e4891b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,9 @@ dist # heroku/foreman env file .env +# GAE app.yaml +app.yaml + # Runtime data pids *.pid diff --git a/docs/backend.rst b/docs/backend.rst index c689bb6..a2ddf73 100644 --- a/docs/backend.rst +++ b/docs/backend.rst @@ -141,6 +141,26 @@ The credit_card endpoint allows us to get more information about a tokenized cre :`. + Environment File ~~~~~~~~~~~~~~~~~~~ An environment file can still be defined to set the values of the different environment variables. Some third party hosting services (such as the Google App Engine) will take all files in your current directory and upload those instead of using a git repository. These types of services don't always provide a way to set environment variables remotely, so the hidden file works in those cases. @@ -296,12 +322,14 @@ The file should be named `.env` and be placed in the same directory as `server.j A sample environment file looks like this: .. code-block:: python - KVASIR_COOKIE_SECRET = YOUR_COOKIE_SECRET - KVASIR_MIDDLEWARE_URI = https://your.middle.ware/ - KVASIR_MIDDLEWARE_SECRET = YOU_MIDDLEWARE_SECRET - KVASIR_CLIENT_ID = YOUR_WEPAY_CLIENT_ID - KVASIR_CLIENT_SECRET = YOUR_WEPAY_CLIENT_SECRET - KVASIR_HTTP_OVERRIDE = TRUE_OR_FALSE + KVASIR_COOKIE_SECRET=YOUR_COOKIE_SECRET + KVASIR_MIDDLEWARE_URI=https://your.middle.ware/ + KVASIR_MIDDLEWARE_SECRET=sup3rs3cr37 + KVASIR_CLIENT_ID=00000 + KVASIR_CLIENT_SECRET=th1s1s4s3cr37 + KVASIR_HTTP_OVERRIDE=false + KVASIR_WEPAY_USE_PRODUCTION=false + KVASIR_MIDDLEWARE_TEST_URI=https://your.test.middleware Generating Secret Keys ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/index.rst b/docs/index.rst index 7453a2d..ac08435 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -75,6 +75,7 @@ Contents backend middleware usecases + testing herokudeploy googleappengine diff --git a/docs/middleware.rst b/docs/middleware.rst index ce33c4e..9c405ce 100644 --- a/docs/middleware.rst +++ b/docs/middleware.rst @@ -41,6 +41,10 @@ Overall, these are the requirements for the middleware: .. note:: Many of the middleware endpoints have names that match endpoints on the Kvasir server (and the WePay API). There is not a 1 to 1 map between all of these different APIs. Middleware endpoints will have *"(middleware)"* in front of all of them in order to separate them from the Kvasir server endpoints. +Testing your Middleware +~~~~~~~~~~~~~~~~~~~~~~~~~~ +After you design your middleware, you will want to run it against our defined test cases which are talked more about in our :ref:`testing section `. + Authorization ~~~~~~~~~~~~~~~~~ Security was a concern when developing the specifications for the middleware. Exposing your database to another application posses some risk. @@ -134,3 +138,4 @@ If you do not have a required field, you will likely need to add it into your da Our development database actually includes the WePay responses as blobs in a column. We pulled out data that we wanted to be able to index and search on (like emails, account_ids, account names and checkout_ids) and gave them dedicated columns. While this increases the size of your database, it does give you all of the information regarding actions completed on your platform. Not all of the information contained in the WePay API responses are completely necessary, but they could become useful at some point. Simply storing the original responses as blobs gives you the opportunity to pull them out and get more detailed information when appropriate. + diff --git a/docs/testing.rst b/docs/testing.rst new file mode 100644 index 0000000..e62ff04 --- /dev/null +++ b/docs/testing.rst @@ -0,0 +1,50 @@ +.. _kvasirtesting: + +Testing Kvasir +================= +Kvasir comes with a direcrory called *test* that contains a set of `Mocha `_ tests that use `Chai's `_ assertion API to make sure that Kvasir's server is performing as expected. + +To achieve this, the *test* directory also contains a sample middleware written in Python that uses a small JSON file as a "database." The JSON file contains a handful of live WePay objects (from the stage environment) that allow you to check to make sure that Kvasir has everything it needs to perform correctly. + + +Running the Tests +------------------------ +There are a couple of configuration options that you have to set in order for the test cases to work the first time: + - KVASIR_MIDDLEWARE_TEST_URI=http://localhost:5000 + * the Python middleware server will run on port 5000 and we want to tell Kvasir to use this URL for running tests + +You can either set this in your `.env` file or via environment variables. + +When you run Kvasir you want to run it as: + >>> npm start -- --test + +This will launch Kvasir in test mode and overwrite the value of KVASIR_MIDDLEWARE_URI with the value on KVASIR_MIDDLEWARE_TEST_URI. It will also override the value of KVASIR_MIDDLEWARE_SECRET with the value provided in the test JSON "database." + +After this is set up, open another terminal window and navigate to the *test* directory and run: + >>> pip install -r requirements.txt + >>> python middleware.py + +The first line will install all required libraries for our middleware to run. The second will actually launch it. + +The middleware loads the JSON file into memory in order to simulate what it would look like if this was actually live. Originally, we wrote only failure test cases, because we couldn't be certain what values would be in every database that tries to integrate with us. It's hard to write a test to successfully query a user based on their email if you don't know what emails you have avaialable. + +Now launch a third terminal and navigate to Kvasir's main source directory and run: + >>> npm test + +This will launch a series of test cases, all of which should succeed. + +These tests are designed to make sure that the server and the middleware: + 1) can communicate with one another + 2) are returning data in the expected format + 3) are returing errors when they are supposed to + +.. note:: + These test cases are not exhaustive. For example, it does not check that http:post:`/preapproval/cancel` actually works, because we can only cancel a preapproval once. + +Testing your Middleware +---------------------------- +While a middleware is readily provided, the KVASIR_MIDDLEWARE_TEST_URI is meant to provide you with the ability to change what URI you are testing against, and thereby what middleware you test against. + +All Kvasir cares about is that the middleware is present and returns data as expected. As you develop your own middleware, you can use the testing cases provided to make sure that your middleware provides the necessary data in the expected format. Build your middleware, and then change the KVASIR_MIDDLEWARE_TEST_URI and you will test against whatever URI you provide. + +None of these tests check that the React components are working properly. That is on the to-do list; however, the React components should behave as expected as long as the data they receive is in the right format. So having test cases that simply check the format of the data that Kvasir sends to the front end allows us to be reasonably confident that your middleware works in all cases with Kvasir. \ No newline at end of file diff --git a/package.json b/package.json index 1cc4df6..843dd6c 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ }, "scripts": { "start": "node server.js", - "start:test": "npm start -- --test", "postinstall": "webpack --config ./webpack.config.js", "bundle": "webpack --config webpack.config.js", "test": "mocha --reporter spec", diff --git a/server.js b/server.js index 8ad3db9..62eeec9 100644 --- a/server.js +++ b/server.js @@ -46,7 +46,8 @@ var app_config = { "certificate": process.env.KVASIR_SSL_CERTIFICATE }, "middleware_test_uri": process.env.KVASIR_MIDDLEWARE_TEST_URI, - "test_mode": argv.test + "test_mode": argv.test, + "wepay_production": process.env.KVASIR_WEPAY_USE_PRODUCTION } @@ -200,8 +201,14 @@ function getWePayData(res, wepay_endpoint, access_token, package) { wepay_settings.access_token = access_token; } + // set wepay settings and chose production or stage var wepay = new WePay(wepay_settings); - wepay.use_staging(); + if (app_config.wepay_production) { + wepay.use_production() + } + else { + wepay.use_staging(); + } winston.info("Making request to wepay: ", wepay_endpoint, package); @@ -497,8 +504,8 @@ verifyConfig(app_config); if (app_config.test_mode){ console.log("Updating config because of test mode."); - app_config.middleware_uri = app_config.middleware_test_uri; - app_config.middleware_secret = require("./test/test.json").secret_key; + app_config.middleware_uri = app_config.middleware_test_uri ? app_config.middleware_test_uri : app_config.middleware_uri; + app_config.middleware_secret = app_config.middleware_test_uri ? require("./test/test.json").secret_key : app_config.middleware_secret; console.log("New config: ", app_config); } diff --git a/test/requirements.txt b/test/requirements.txt new file mode 100644 index 0000000..31e16e1 --- /dev/null +++ b/test/requirements.txt @@ -0,0 +1,6 @@ +Flask==0.10.1 +itsdangerous==0.24 +Jinja2==2.8 +MarkupSafe==0.23 +requests==2.2.1 +Werkzeug==0.11.10 diff --git a/test/server.js b/test/server.js index e82dc57..f06e772 100644 --- a/test/server.js +++ b/test/server.js @@ -360,7 +360,7 @@ describe("server", function() { }); /** - * Check credit card endpoint + * Check credit card * */ describe("credit_card endoint", function(){