Software Testing

In this post I would like to explain what is software testing and different methods, levels of software testing.

What is software testing?

Software Testing is the process of evaluating a system or its components with the intent to find whether it satisfies the specified requirements or not.

Testing is executing a system in order to identify any gaps, errors, or missing requirements in contrary to the actual requirements.

What are the Levels of software testing?

Software products are tested at four levels:
  • Unit testing
  • Integration testing
  • System testing
  • Acceptance testing

Unit testing

  • During unit testing, modules are tested in isolation. If all modules were to be tested together, it may not be easy to determine which module has the error.
  • Unit testing reduces debugging effort several folds. Programmers carry out unit testing immediately after they complete the coding of a module.

Role of Unit Testing

  • Assure minimum quality of units before integration into system
  • Focus attention on relatively small units
  • Testing forces us to read our own code – spend more time reading than writing
  • Automated tests support maintainability and extendibility

Integration testing

After different modules of a system have been coded and unit tested:
  • modules are integrated in steps according to an integration plan
  • partially integrated system is tested at each integration step.

Role of Integration Testing

  • Gain confidence in the integrity of overall system design
  • Ensure proper interaction of components

Integration Testing Strategies

  • Big-bang
  • Top-down
  • Bottom-up
  • Critical-first
  • Function-at-a-time
  • As-delivered
  • Sandwich

System Testing

  • Gain confidence in the integrity of the system as a whole
  • Ensure compliance with functional requirements
  • Ensure compliance with performance requirements

Acceptance Testing

  • Testing performed by the customer or end-user himself
  • to determine whether the system should be accepted or reject

Testing is very important step of software development. We have used unit testing for our project Engelsystem. We are developing new features. Interested Developers can work with us.

Development: https://github.com/fossasia/engelsystem

Issues/Bugs:https://github.com/fossasia/engelsystem/issues

AngularJS structure and directives

Today I am going to tell you how to build a well worked Angular JS structure, as well as to be able to maintain your app’s elements correctly. It’s a basic and most important thing to learn and remember before you start building your own website or app because in the early phases of a project the structure doesn’t matter too much, and many people tend to ignore it, but in the long term it will affect code maintainability. It also helps you to develop it quicker and solve bugs without any additional troubles.

I must admit that I was one of them who  had made this mistake and ignore AngularJS correct structure. The thing is that I had not known how to build Angular JS app correctly before I started coding CommonsNet, and I wanted to start and provide a real outcome as quickly as possible. But unfortunately my mistake has stoped me later. I have realised it this week while implementing a quite simple feature – adding HTML elements dynamically. It turned out that I had a trouble while adding them. I had’t known that it’s better not to manipulate DOM elements in Controllers, but instead do it in directives.

Let me to explain it step by step from lessons I’ve learned while refactoring CommonsNet code structure. Please note that I’m just sharing my experience in building rather a small project and I’m covering only a small part of that subject, so some of these tips may be first – useless if you want to build an extended one, and then – not enough if you want to learn more. I recommend you to find further resources.

AngularJS Structure

First of all please see at AngularJS structure provided below. It’s a very basic structure, but it’ is important to have in mind that you should follow that pattern while developing your own app. If you want to have an order in your files you should seperate them by directories and create different ones like: controllers, directives, services, js and views. This structure makes it very easy for the reader to visualize and conceptualize the concepts you are covering.

AngularJS structure.png

My CommonsNet structure differs a bit because I have one main js directory, and all subdirectories like directives, controllers and services  inside it. I think it’s also an acceptable solution. Imagine that I hadn’t had any directives or services directives’ files before last Wednesday…

Then,  it’s also recommended to put index.html at the root of front-end structure. The index.html file will primarily handle loading in all the libraries and Angular elements.

Next, controllers are main part of AngularJS apps. It always happens that developers when starting out tend to put too much logic in the controllers. It’s a bug. Controllers should never do DOM manipulation or hold DOM selectors, that’s where we use directives and ng-model. Likewise business logic should live in services, not controllers.

Data should also be stored in services, except where it is being bound to the $scope. Services are singletons that persist throughout the lifetime of the application, while controllers are transient between application states. So, if the controller is a coordinator between the view and the model, then the amount of the logic it has should be minimal.

Directives

Take a look at a very basic AngularJS directive. Let’s name this file appInfo.js as well as create an .html file appInfo.html as in example below.

Learn AngularJS 1.X   Codecademy.png

In this example we create a new directive called appInfo. It returns an object with three options – restrict, scope and templateURL

  1. restrict specifies how the directive will be used in the view. The 'E' means it will be used as a new HTML element.
  2. scope specifies that we will pass information into this directive through an attribute named info. The = tells the directive to look for an attribute named info in the <app-info> element, like this: The data in info becomes available to use in the template given by templateURL.
  3. templateUrl specifies the HTML to use in order to display the data in scope.info. Here we use the HTML in js/directives/appInfo.html.

Then we need to build a structure to directive in our appInfo.html

<h2 class="title">{{ info.title }}</h2> 
<p class="developer">{{ info.developer }}</p> 
<p class="price">{{ info.price | currency }}</p>

Of course <h2> and <p> are just examples. You can use here what you only want. The title and developer are controller $scope.elements. Let’s take a look at controller’s content.

$scope.apps = [ 
 { 
 title: 'MOVE', 
 developer: 'MOVE, Inc.', 
 price: 0.99 
 }, 
 { 
 title: 'Shutterbugg', 
 developer: 'Chico Dusty', 
 price: 2.99 
 }, 
]

In index.html we use only  ng-repeat to loop through app element in $scope.apps, and then app-info info=”app”

<div ng-repeat="app in apps">
     <app-info info="app"></app-info>
</div>

That’s it. It’s quite a simple example, but it helps me to refactor my code in CommonsNet project and avoid a long, boring, repetitive work while adding new elements to website. It also helps me to implement a feature I have mentioned above. I’am going to tell more about it in next blog post. Stay tuned!

Resources:

https://scotch.io/tutorials/angularjs-best-practices-directory-structure

https://www.codecademy.com/learn/learn-angularjs.

https://commonsnetblog.wordpress.com/

 

Working with Apache Web Server

In this article, I will examine what apache is how to setup apache for ubuntu or debian and how to view error logs for apache and how to understand what the logs contain which will be useful for web development.

What is Apache?

Apache is the most popular web server on the internet. It is used to serve more than half of all active websites.

It is fast, reliable, and secure. It can be highly customized to meet the needs of many different environments by using extensions and modules.

Installing Apache on Ubuntu and Debian

If you do not already have Apache installed, you can do so now by issuing the following commands:

sudo apt-get update
sudo apt-get install apache2

If you visit your VPS’s IP address in a web browser, you will get the default Apache index page. We get the following output.

your_domain_name_or_ip_address
It works!
This is the default web page for this server.
The web server software is running but no content has been added, yet.

Looking into apache error.log files

In order to effectively manage a web server, it is necessary to get feedback about the activity and performance of the server as well as any problems that may be occuring. The Apache HTTP Server provides very comprehensive and flexible logging capabilities.

Error.log file

The server error log, whose name and location is set by the ErrorLog directive, is the most important log file. This is the place where Apache httpd will send diagnostic information and record any errors that it encounters in processing requests.

It is the first place to look when a problem occurs with starting the server or with the operation of the server, since it will often contain details of what went wrong and how to fix it.

Explanation of log message

There is certain information that is contained in most error log entries. For example, here is a typical message.

[Sat Aug 20 08:09:38.958885 2016] [:error] [pid 1489] [client 127.0.0.1:40810] PHP Notice:  Constant MIN_PASSWORD_LENGTH already defined in /var/www/html/test/engelsystem/config/config.php on line 30, referer: http://localhost/

[Sat Aug 20 08:09:38.958885 2016] The first item in the log entry is the date and time of the message.

[:error] The second entry lists the severity of the error being reported.

[pid 1489] Indicates process Id

[client 127.0.0.1:40810] The fourth entry gives the IP address of the client that generated the error.

Fifth one is error message explaining the error.

Constant MIN_PASSWORD_LENGTH already defined.

File and line number

 /var/www/html/test/engelsystem/config/config.php on line 30

Error logs are easy to understand. Using error logs we can easily figure out the problem in your server or your code and fix it.

For more information about the log files and configuration please visit Apache website Apache provides excellent documentation.

Apache log files were useful for me during web development project Engelsystem. We are developing new features. Interested developers can work with us.

Development: https://github.com/fossasia/engelsystem

Issues/Bugs:https://github.com/fossasia/engelsystem/issues

Importing database with PHP script

In this post I would like to discuss how to import tables to database directly through PHP script.

For our Project Engelsystem we need to import the tables manually by the command line or PHPMYADMIN. Now the user need not worry about the importing table. They are directly imported through the script.

Initially we used to import the tables in a sql file by source command or mysql command.

$ mysql -u root -p

CREATE DATABASE engelsystem;

use engelsystem;

source db/install.sql;

source db/update.sql;

Script to import tables directly through PHP.

function import_tables() {
// get the database variables. 
global $DB_HOST, $DB_PASSWORD, $DB_NAME, $DB_USER;
// file names to import
 $import_install = '../db/install.sql';
 $import_update = '../db/update.sql';
 // command to import both the files.
 $command_install = 'mysql -h' .$DB_HOST .' -u' .$DB_USER .' -p' .$DB_PASSWORD .' ' .$DB_NAME .' < ' .$import_install;
 $command_update = 'mysql -h' .$DB_HOST .' -u' .$DB_USER .' -p' .$DB_PASSWORD .' ' .$DB_NAME .' < ' .$import_update;
 $output = array();
 // execute the command
 exec($command_install, $output, $worked_install);
 exec($command_update, $output, $worked_update);

// test whether they are imported successfully or not
switch ($worked_install && $worked_update) {
 case 0:
 return true;
 case 1:
 return false;
 }
}

Once we execute the above script the tables will be imported automatically. User need not import the tables manually.

In this way we can import tables using script. For more information visit about project please visit here.

Development: https://github.com/fossasia/engelsystem

Issues/Bugs:https://github.com/fossasia/engelsystem/issues

CommonsNet’s main features are ready

Main CommonsNet features are generating a file and  generating a code script. Today I would like to provide you with a simple and short guideline how I have managed to implement them.

Generate a file

Generating a file is the most important feature of our website, and it is not only a condition of its existance but also a basis to find stakeholders – in general people who want to use CommonsNet webiste.  It is the most complicated CommonsNet feature as well even if it is not so difficult as you may think.

To implement this feature a pure JavaScript is used and for now we have chosen the simplest solution to build it, mainly because we need to have a working webiste now to start a real promotion and find many customers.

Important steps here are:

  1. Manually prepare a .fodt file
  2. Get .fodt file and modify it
  3. Generate a pdf file from a ready .fodt file
  4. Write function to download a pdf file.

 

Preparing .fodt file

My mentor Andre Rebentisch has recommended me to use .fodt file because it’s very user-friendly and let you to prepare a file’s structure very easy. Actually that’s it! I have prepared manually in Libre Office a default doc file, and then save it in .fodt extension. .Fodt is a great option because it behaves as .xml file and let you modify this file using any programming language.

So, as I have already mentioned above I have created a simple doc file and prepare the structure. It is very clear and looks like a default Libre Office file. Only thing is that it has .fodt extension which means that you can open it in a code editior like for e.g. Sublime and start modifying easily.

If you open your .fodt file in a Sublime, it looks like this. Isn’t it simply? And above all it helps you to easily manipulate your data using for e.g a JavaScript.

Screen Shot 2016-08-13 at 17.19.06

Screen Shot 2016-08-13 at 17.18.00Get .fodt file to manipulate it

In my AngularJS Wizard Controller I write a function to get data from my .fodt file

$http({
 method: 'GET',
 url: 'http://commonsnet.herokuapp.com/generatefile.fodt',
 }).success(function(data){}) .error(function(){
 alert("error");
 });

It’s very easy code sample and you can find it in many Internet resources. I hope it is understandable to you as well. I have written a function which get a .fodt file and return data. Inside .success I have written my whole code to manipulate a .fodt file.  To use it I have decided to use a simple JavaScript replace method and if-else conditions, and in dependence on user’s inputs in a wizard form create different file’s structures. Let me show you a small section :

result = result.replace("NETWORK_NAME", "The owner provides" + " " + vm.ssid + "network connection")

if ((vm.password !== "") && (typeof vm.password !== "undefined")) {
 result = result.replace("INPUT_PASSWORD", "The owner informs that password is" + " " + vm.password);

}

Generate a pdf file from a ready .fodt file

It is still in progress! I will update it as soon as I manage to successfully implement it!

Write function to save it

To save my ready file I have used save function() and put in my AngularJS Wizard Controller.

$scope.save = function() {}

Generate a code script

We have decided to implement a generating code feature, because we want our users to be able to simply fill a wizard form with all Wifi details, then copy  a generated code  and be able to simply  paste it to their website.

We believe it is a very convenient solution to them because all they need to do it is to go through a form and it is ready. Besides, we have already decided to get rid of a database and use only a JSON file to not complicate our website’s working. So, that’s also the reason why we want to make it as simple as possible.

That’s why I have decided to create a link snd store there all wizard form’s values Undoubtedly it causes to build a very long link, but in the same time I believe that it is a good solution if we don’t use a database. I have also already found some ways to shorten and encrypt the generated link.

In my WizardController AngularJS I have write a function with a condtion

$scope.gotoStep = function(newStep) {
 currentStep = newStep;
 if ( currentStep === 3) {
 var link = "commonsnet.herokuapp.com/#/file?ssid=" + vm.ssid + "&password=" + vm.password + "&security=" + vm.securitytypes + "&standard=" + vm.wifistandards + "&payment=" + vm.paymentfieldyes + "&fee=" + vm.paymentfield + "&timelimit=" + vm.timelimityes + "&limit=" + vm.timelimitfield + "&service=" + vm.serviceyes + "&specialdevices=" + vm.specialdevices + "&devices=" + vm.specialdevicesfield + "&specialsettings=" + vm.specialsettings + "&settings=" + vm.specialsettingsfield + "&acceptterms=" + vm.acceptterms + "&liking=" + vm.socialprofile + "&downloading=" + vm.downloading + "&restrictions=" + vm.country + "&country=" + vm.countries + "&law=" + vm.legalrestrictions
 vm.code = '<a href="' + link + '">CommonsNet</a>'
 }
 }

If my currentStep === 3 (actually it’s a  confirmation.html templateUrl) I create a link (a code) which is available to users to copy and paste to their website.

Then I have also created a new FileController (FileCtrl) which is called when users enter a commonsnet.herokuapp.com/#/file (if they paste in an url a copied generated link)

app.controller('FileCtrl',['$scope', '$routeParams', function ($scope, $routeParams) { $scope.ssid = $routeParams.ssid; $scope.password = $routeParams.password; }])

Finally I have created a .html structure to post data from a wizard from which are all stored in our link. It’s a normal html structure but in order to adjust the html’s content to user’s wizard inputs I have used an Angular ng-if . A little example looks like this:

ng-if="ssid && ssid != 'undefined'

And that’s it. It still needs some improvements and fixing bugs but main features work according to my plan!!!

It’ time to intensively extend the idea of CommonsNet and find stakeholders! Are you interested too? I am sure you are, because CommonsNet is a great tool which helps us to build a transparent Wifi networks!

Feel free to write your comments and suggestion!

Configuring Document Root Apache2 Ubuntu

In this post I will explain how to setup document root for apache server.

Initially the document root is set to /var/www/html by default. We need to change it when we have web applications in /var/www/html/folder.

I will show an example how to configure document root for our project engelsystem. Engelsystem is downloaded to /var/www/html/ . We must make sure to point our apache2 document root to the Engelsystem directory to prevent any user from accessing anything other than the public/ directory for security reasons.

Changing apache2 document root

The default document root is set in the 000-default.conf file that is under /etc/apache2/sites-available folder.

$ cd /etc/apache2/sites-available
$ sudo nano 000-default.conf

While the file is opened change DocumentRoot /var/www/ with your new folder e.g DocumentRoot /var/www/html/engelsystem/public where your index.php file resides

Set the right Apache configuration

The configuration of the /var/www folder is under /etc/apache2/apache2.conf. Edit this file to add the configuration of your new document root.

$ sudo nano/etc/apache2/apache2.conf

Copy the following:

<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

and change the directory path:

<Directory /var/www/html/engelsystem/public>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

Restart Apache

Now we can view the engelsystem at localhost/ or http://[i.p.address]/

$ sudoservice apache2 restart

PayPal Express Checkout in Python

As per the PayPal documentation …

Express Checkout is a fast, easy way for buyers to pay with PayPal. Express Checkout eliminates one of the major causes of checkout abandonment by giving buyers all the transaction details at once, including order details, shipping options, insurance choices, and tax totals.

The basic steps for using express checkout to receive one-time payments are:

  1. Getting the PayPal API credentials.
  2. Making a request to the API with the transaction details to get a token
  3. Using the token to send the users to the PayPal payment page
  4. Capturing the payment and charging the user after the user completes the payment at PayPal.

We will be using PayPal’s Classic NVP (Name-value pair) API for implementing this.

Getting PayPal API Credentials

To begin with, we’ll need API Credentials.
We’ll be using the Signature API credentials which consists of

  • API Username
  • API Password
  • Signature

To obtain these, you can follow the steps at Creating and managing NVP/SOAP API credentials – PayPal Developer.

You’ll be getting two sets of credentials. Sandbox and Live. We’ll just stick to the Sandbox for now.

Now, we need sandbox test accounts for making and receiving payments. Head over to Creating Sandbox Test Accounts – PayPal Developer and create two sandbox test accounts. One would be the facilitator and one would be the buyer.

PayPal NVP Servers

All the API actions will take place by making a request to the PayPal server. PayPal has 4 different NVP servers for 4 different purposes.

  1. https://api-3t.sandbox.paypal.com/nvp – Sandbox “testing” server for use with API signature credentials.
  2. https://api-3t.paypal.com/nvp– PayPal “live” production server for use with API signature credentials.
  3. https://api.sandbox.paypal.com/nvp – Sandbox “testing” server for use with API certificate credentials.
  4. https://api.paypal.com/nvp – PayPal “live” production server for use with API certificate credentials.

We’ll be using the Sandbox “testing” server for use with API signature credentials.

Creating a transaction and obtaining the token

To create a transaction, we’ll need to make a request with all the transaction details. We can use Python requests library to easily make the requests. All requests are POST.

We’ll be calling the SetExpressCheckout method of the NVP API to obtain the token.

import requests  
import urlparse

data = {  
    'USER': credentials['USER'],
    'PWD': credentials['PWD'],
    'SIGNATURE': credentials['SIGNATURE'],
    'SUBJECT': credentials['FACILITATOR_EMAIL'],
    'METHOD': 'SetExpressCheckout',
    'VERSION': 93,
    'PAYMENTREQUEST_0_PAYMENTACTION': 'SALE',
    'PAYMENTREQUEST_0_AMT': 100,
    'PAYMENTREQUEST_0_CURRENCYCODE': 'USD',
    'RETURNURL': 'http://localhost:5000/paypal/return/',
    'CANCELURL': 'http://localhost:5000/paypal/cancel/'
}
response = requests.post('https://api-3t.sandbox.paypal.com/nvp', data=data)  
token = dict(urlparse.parse_qsl(response.text))['TOKEN']

Here,

  • USER represents your Sandbox API Username.
  • PWD represents your Sanbox API Password.
  • SIGNATURE represents your Sandbox Signature.
  • SUBJECT represents the facilitator’s email ID.
  • PAYMENTREQUEST_0_AMT is the total transaction amount.
  • PAYMENTREQUEST_0_CURRENCYCODE is the 3 digit ISO 4217 Currency code.
  • RETURNURL is where the user will be sent to after the transaction
  • CANCELURL is where the user will be sent to if he/she cancels the transaction.

A URL-Encoded, Name-value pair response would be obtained. We can decode that into a dict by using Python’s urlparse modules.

From the response, we’re extracting the TOKEN which we will use to generate the payment URL for the user.

This token has to be retained since we’ll be using it in further steps of the process.

Redirecting the user to PayPal for Approval

With the token we obtained, we can form the payment URL.

https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=<TOKEN>

We’ll have to send the user to that URL. Once the user completes the transaction at PayPal, he/she will be returned to the RETURNURL where we’ll further process the transaction.

Obtaining approved payment details and capturing the payment

Once the user completes the transaction and gets redirected back to RETURNURL, we’ll have to obtain the confirmed payment details from PayPal. For that we can again use the token ID that we obtained before.

We’ll now be making a request to the GetExpressCheckoutDetails method of the API.

import requests  
import urlparse

data = {  
    'USER': credentials['USER'],
    'PWD': credentials['PWD'],
    'SIGNATURE': credentials['SIGNATURE'],
    'SUBJECT': credentials['FACILITATOR_EMAIL'],
    'METHOD': 'GetExpressCheckoutDetails',
    'VERSION': 93,
    'TOKEN': TOKEN
}

response = requests.post('https://api-3t.sandbox.paypal.com/nvp', data=data)  
result = dict(urlparse.parse_qsl(response.text))  
payerID = result['PAYERID']

A URL-Encoded, Name-value pair response would be obtained. We can decode that into a dict by using Python’s urlparse modules.

This will provide us with information about the transaction such as transaction time, transaction amount, charges, transaction mode, etc.

But, we’re more interested in the PAYERID which we’ll need to capture/collect the payment. The money is not transferred to the facilitators account until it is captured/collected. So, be sure to collect it.

To collect it, we’ll be making another request to the DoExpressCheckoutPaymentmethod of the API using the token and the PAYERID.

import requests  
import urlparse

data = {  
    'USER': credentials['USER'],
    'PWD': credentials['PWD'],
    'SIGNATURE': credentials['SIGNATURE'],
    'SUBJECT': credentials['FACILITATOR_EMAIL'],
    'METHOD': 'DoExpressCheckoutPayment',
    'VERSION': 93,
    'TOKEN': TOKEN,
    'PAYERID': payerID,
    'PAYMENTREQUEST_0_PAYMENTACTION': 'SALE',
    'PAYMENTREQUEST_0_AMT': 100,
    'PAYMENTREQUEST_0_CURRENCYCODE': 'USD',
}

response = requests.post('https://api-3t.sandbox.paypal.com/nvp', data=data)  
result = dict(urlparse.parse_qsl(response.text))  
status = result['ACK']

All the details have to be the same as the ones provided while obtaining the token. Once we make the request, we’ll again get a URL-Encoded, Name-value pair response. We can decode that into a dict by using Python’s urlparsemodules.

From the response, ACK (Acknowledgement status) will provide us with the status of the payment.

  • Success — A successful operation.
  • SuccessWithWarning — A successful operation; however, there are messages returned in the response that you should examine.
  • Failure — The operation failed; the response also contains one or more error messages explaining the failure.
  • FailureWithWarning — The operation failed and there are messages returned in the response that you should examine.

And, we have completed the PayPal transaction flow for Express Checkout. These are just the basics and might miss a few stuff. I suggest you go through the following links too for a better understanding of everything:

For Reference:
  1. PayPal Name-Value Pair API Basics – PayPal Developer
  2. How to Create One-Time Payments Using Express Checkout – PayPal Developer

CommonNet – how to set up tests

Setting up tests’ environment wasn’t easy

Have you ever tried to set up your tests’ environment using Protractor on Vagrant?

I must admit that it was a very difficult task for me. I have recently spent almost three days trying to prepare my tests’ environment for CommonsNet project, and read many different resources. Fortunately, I have finally done it, so now I want to share with you my experience and give you some tips how to do it.

Protractor

Firstly, I will explain you why I have decided to use Protractor. It is mainly because Proractor is especially designed for end-to-end testing  AngularJS application. Protractor runs tests against your application running in a real browser, interacting with it as a user would.

Writing tests using Protractor is quite easy because you can find working examples in AngularJS docs. Each sample of AngularJS code is enriched by Protractor’s test. It’s amazing.

Selenium

Selenium is a browser automation library. It is most often used for testing web-applications, and may be used for any task that requires automating interaction with the browser. You can download it from here. You have to choose Selenium for a language you use. I have used Selenium for NodeJS.

Vagrant

You don’t have to necessary use Vagrant to run your tests, but I have implemented it, because I run my local environment on Vagrant and it’s more comfortable for me to use it.

Setting up testing environment

Now I will share with you how to run tests. So first all of, I have created a file called install.sh and put all necessary commends there. I have put there several commands. Please take a look at this file.  It helps you to install all of these necessary dependencies using only one command instead of several ones. 

install

Next, I have prepared provision folder, where I put files to install selenium standalone and chromium driver. You can copy these file from here

Then I have created a simple test case. It’s quite easy at the beginning. You just need two files first – conf. js and next- todo_spec.js  Below, I will provide you with my conf.js As you can see it’s not complicated and really short. It’s a basic configuration file and of course you can adjust it to your needs. You can find many examples of conf.js file in Internet.

conf

And finally a simple test, which I have placed in todo_spec.js file. It’s a ProtracotrJS example available on their website

todo-spec.png

Now, let me to write a step by step todo list now.

  • Install Vagrant in your folder
vagrant up
  • Connect to Vagrant
vagrant ssh
  • Open your Vagrant folder
cd /vagrant 
  • Then run selenium file
sh selenium_install.sh 
  • Next open provision folder
cd provision
  • Install java-jar
DISPLAY=:1 xvfb-run java -jar selenium-server-standalone-2.41.0.jar 

Your selenium server should be up and running

  • Then open a new terminal – remember not to close the first one!
  • Open your CommonsNet repository again
cd CommonsNet
  • Connect to Vagrant again
vagrant ssh
  • Open Vagrant folder again
cd /vagrant
  • Then open tests folder
cd tests
  • And finally run Protractor test
protractor conf.js 

That’s it. You should see a result of your test in a terminal.

 

Integrating Stripe in the Flask web framework

{ Repost from my personal blog @ https://blog.codezero.xyz/integrating-stripe-in-flask }

Stripe is a developer and a user-friendly payment infrastructure provider. Stripe provides easy to use SDKs in different programming languages allowing us to easily collect payments on our website or mobile application.

Flask is a web microframework for Python based on Werkzeug, Jinja 2. Flask makes building web applications in python a breeze.

Make sure you have your Flask app ready. Let’s start with installing the required dependency. The Stripe python SDK. You can get it by running.

pip install stripe

Don’t forget to add the same in your requirements.txt. (if you have one that is.)

Now, head over to Stripe: Register and create a new Stripe account to get your test keys. If you don’t wish to create an account at this time, you can use the following test keys, but you’ll not be able to see the payments in the stripe dashboard.

  • Publishable Key: pk_test_6pRNASCoBOKtIshFeQd4XMUh
  • Secret Key: sk_test_BQokikJOvBiI2HlWgH4olfQ2

We’ll need to set the secret key in the SDK.

import stripe

STRIPE_PUBLISHABLE_KEY = 'pk_test_6pRNASCoBOKtIshFeQd4XMUh'  
STRIPE_SECRET_KEY = 'sk_test_BQokikJOvBiI2HlWgH4olfQ2'

stripe.api_key = STRIPE_SECRET_KEY

Let’s create a page with a form for us to handle the Stripe payment.

<!DOCTYPE html>  
<html>  
<head>  
    <title>Pay now</title>
</head>  
<body>  
    <h4>Pay $250.00 by clicking on the button below.</h4>
    <form action="/payment" method="POST">
        <script src="https://checkout.stripe.com/checkout.js" 
                class="stripe-button"
                data-key="pk_test_6pRNASCoBOKtIshFeQd4XMUh"
                data-description="A payment for the Hello World project"
                data-name="HelloWorld.com"
                data-image="/images/logo/hw_project.png"
                data-amount="25000"></script>
    </form>
</body>  
</html>

We’re using Stripe’s Checkout library to get the payment details from the user and process. Also, keep in mind that the checkout library has to be loaded directly from https://checkout.stripe.com/checkout.js. Downloading it and serving locally will not work.

The script tag, accepts a lot of parameters. A few important ones are,

  • data-key – The Publishable Key.
  • data-amount – The amount to be charged to the user in the lowest denomination of the currency. (For example, 5 USD should be represented as 500 cents)
  • data-name – The name of your site or company that will be displayed to the user.
  • data-image – The path to an image file (maybe a logo) that you’d like to be displayed to the user.

More configuration options can be seen at Stripe: Detailed Checkout Guide.

This script would automatically create a Pay with Card button which would open the stripe Checkout lightbox when clicked by the user.

Once the payment process is completed the following parameters are submitted to the form’s action endpoint (the form inside which this script is located), along with any other elements that were in the form.

  • stripeToken – The ID of the token representing the payment details
  • stripeEmail – The email address the user entered during the Checkout process

Along with the Billing address details and Shipping address details if applicable and enabled

We’ll need to write a Flask method to handle the input that were submitted by Stripe to proceed with the transaction and charge the user.

Let’s add a new Flask route to respond when submitting the form.

@app.route('/payment', methods=['POST'])
def payment_proceed():  
    # Amount in cents
    amount = 25000

    customer = stripe.Customer.create(
        email=request.form['stripeEmail'],
        source=request.form['stripeToken']
    )

    charge = stripe.Charge.create(
        amount=amount,
        currency='usd',
        customer=customer.id,
        description='A payment for the Hello World project'
    )

    return render_template('payment_complete.html')

We’re now creating a new Stripe customer along with the stripeToken as the source parameter. The card details are stored by stripe as a token. And using this token ID, Stripe will be able to retrieve it to make the charge.

We’re creating a charge object with the amount in the lowest denomination of the currency, the currency name, the customer ID, and an optional description. This will charge the customer. On a successful transaction, a charge object would be returned. Else, an exception will be thrown.

For more information regarding the Charge object and the various other APIs available fro consumption in Stripe, checkout the Stripe API Guide.

Creating an API in PHP

One of the key components of my GSoC Project was to have a POST API for the Android App generator.

This was required so that the app generator could be plugged into the server and can be called directly instead of someone manually visiting the webpage and entering his/her details.

It takes in a JSON input and compiles and emails the app to the organizer based on his email address in the input JSON.

The input to the API will look something like this :

{
“email”: [email protected],
“app_name”: “MyApp”,
“endpoint”: “https://open-event-dev.herokuapp.com/api/v2
}

Once the data is sent, on the server I have a php file which intercepts the requests and performs an action based on the request.

<?php
function sendResponse($data) {
    header('Content-type: application/json');
    echo json_encode($data);
    die();
}
/* If the request isn't a POST request then send an error message*/
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
    sendResponse([
        "status"=>"error",
        "code"=>405,
        "message"=>"Method Not Allowed",
    ]);
}
/* Store the input received in a variable named body */
$body = json_decode(file_get_contents('php://input'), true);
/* If the user is nissing any important input parameters, don't process the request */
if (!array_key_exists('email', $body) || !array_key_exists('app_name', $body) || !array_key_exists('endpoint', $body)) {
    sendResponse([
        "status"=>"error",
        "code"=>422,
        "message"=>"Unprocessable entity",
    ]);
}
$uid = mt_rand(1000,9999). "_" .time();  //A random User ID
/* Extracting variables from the body */
$email = escapeshellcmd($body['email']);
$appName = escapeshellcmd($body["app_name"]); 
$endpoint = escapeshellcmd($body["endpoint"]);

/* Run a script based on the input parameters */
exec("sudo python /var/www/html/api/appgenserver.py $email $appName $endpoint");

The code above is pretty much self explanatory.

So basically, first we check for a valid request (GET/POST) and throw an error if it is invalid.

Next up, for a valid request we store the body into a variable and then execute a followup script as per our needs using data from this response.

This PHP file should be located in the public-html (/var/www/data) of the server so as to be accessible from outside of the server.

You can test out this API by calling it directly by prepending the server’s ip address to the name of php file containing this code.

Something like :

domain-name.com/api/api.php

You can also use Postman for Chrome or RESTClient for Firefox for making API calls easily.

Well, that’s it then!

You can easily modify the PHP code provided and modify it to suite your needs for making you own API.

Let me know your thoughts and your queries in the “response” 😉 below.

Until next time.