From f2533a0e23096f4220a89db97b18820041145a98 Mon Sep 17 00:00:00 2001 From: tomazahlin Date: Tue, 10 Mar 2015 13:29:45 +0100 Subject: [PATCH 1/7] Updated WebApiContext.php Headers are now sent in the request when sending a request with form data. --- src/Context/WebApiContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Context/WebApiContext.php b/src/Context/WebApiContext.php index f21b24b..c371666 100644 --- a/src/Context/WebApiContext.php +++ b/src/Context/WebApiContext.php @@ -175,7 +175,7 @@ public function iSendARequestWithFormData($method, $url, PyStringNode $body) $fields = array(); parse_str(implode('&', explode("\n", $body)), $fields); - $this->request = $this->getClient()->createRequest($method, $url); + $this->request = $this->getClient()->createRequest($method, $url, array('headers' => $this->getHeaders())); /** @var \GuzzleHttp\Post\PostBodyInterface $requestBody */ $requestBody = $this->request->getBody(); foreach ($fields as $key => $value) { From 8a4b5d31161cf9bd996c6fc37df4475c3e62ffbd Mon Sep 17 00:00:00 2001 From: tomazahlin Date: Tue, 17 Mar 2015 10:44:11 +0100 Subject: [PATCH 2/7] Update WebApiContext.php --- src/Context/WebApiContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Context/WebApiContext.php b/src/Context/WebApiContext.php index c371666..f21b24b 100644 --- a/src/Context/WebApiContext.php +++ b/src/Context/WebApiContext.php @@ -175,7 +175,7 @@ public function iSendARequestWithFormData($method, $url, PyStringNode $body) $fields = array(); parse_str(implode('&', explode("\n", $body)), $fields); - $this->request = $this->getClient()->createRequest($method, $url, array('headers' => $this->getHeaders())); + $this->request = $this->getClient()->createRequest($method, $url); /** @var \GuzzleHttp\Post\PostBodyInterface $requestBody */ $requestBody = $this->request->getBody(); foreach ($fields as $key => $value) { From d88b8a2570b47beac83ab6e5090250623a4fab39 Mon Sep 17 00:00:00 2001 From: tomazahlin Date: Tue, 17 Mar 2015 10:45:47 +0100 Subject: [PATCH 3/7] Fixed headers Fixed (added) headers when sending a request with form data. --- src/Context/WebApiContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Context/WebApiContext.php b/src/Context/WebApiContext.php index f21b24b..c371666 100644 --- a/src/Context/WebApiContext.php +++ b/src/Context/WebApiContext.php @@ -175,7 +175,7 @@ public function iSendARequestWithFormData($method, $url, PyStringNode $body) $fields = array(); parse_str(implode('&', explode("\n", $body)), $fields); - $this->request = $this->getClient()->createRequest($method, $url); + $this->request = $this->getClient()->createRequest($method, $url, array('headers' => $this->getHeaders())); /** @var \GuzzleHttp\Post\PostBodyInterface $requestBody */ $requestBody = $this->request->getBody(); foreach ($fields as $key => $value) { From 86aa0e8478d0fe53bcf1516fa3e63823406fefd7 Mon Sep 17 00:00:00 2001 From: Tomaz Ahlin Date: Wed, 18 Mar 2015 15:27:58 +0100 Subject: [PATCH 4/7] Improved context to handle more cases. --- src/Context/WebApiContext.php | 53 +++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/src/Context/WebApiContext.php b/src/Context/WebApiContext.php index c371666..419ad35 100644 --- a/src/Context/WebApiContext.php +++ b/src/Context/WebApiContext.php @@ -26,29 +26,37 @@ class WebApiContext implements ApiClientAwareContext /** * @var string */ - private $authorization; + protected $authorization; /** * @var ClientInterface */ - private $client; + protected $client; /** * @var array */ - private $headers = array(); + protected $headers = array(); /** * @var \GuzzleHttp\Message\RequestInterface */ - private $request; + protected $request; /** * @var \GuzzleHttp\Message\ResponseInterface */ - private $response; + protected $response; - private $placeHolders = array(); + /** + * @var array + */ + protected $placeHolders = array(); + + /** + * @var array + */ + protected $decodedData = array(); /** * {@inheritdoc} @@ -227,6 +235,39 @@ public function theResponseShouldNotContain($text) Assertions::assertNotRegExp($expectedRegexp, $actual); } + /** + * Checks that response is json and stores the data to array. + * + * @Then /^(?:the )?response should be json$/ + */ + public function theResponseShouldBeJson() + { + $data = json_decode($this->response->getBody()); + + Assertions::assertNotFalse($data); + + $this->decodedData = $data; + } + + /** + * Checks that response is json and stores the data to array. + * + * @param string $key + * @param string $subKeys + * + * @Then /^(?:the )?response should contain "([^"]*)" with "([^"]*)" $/ + */ + public function theResponseShouldContainKey($key, $subKeys) + { + $subKeys = explode(',', $subKeys); + + Assertions::assertContains($key, $this->decodedData); + + foreach ($subKeys as $subKey) { + Assertions::assertContains($subKey, $this->decodedData[$key]); + } + } + /** * Checks that response body contains JSON from PyString. * From 801afb34ffd4369435a0f9c90f88c736759ba02e Mon Sep 17 00:00:00 2001 From: Tomaz Ahlin Date: Wed, 18 Mar 2015 15:50:16 +0100 Subject: [PATCH 5/7] Fixed context with the right assertions. --- src/Context/WebApiContext.php | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/Context/WebApiContext.php b/src/Context/WebApiContext.php index 419ad35..1123a16 100644 --- a/src/Context/WebApiContext.php +++ b/src/Context/WebApiContext.php @@ -20,6 +20,7 @@ * Provides web API description definitions. * * @author Konstantin Kudryashov + * @author Tomaz Ahlin (Improvements only) */ class WebApiContext implements ApiClientAwareContext { @@ -53,11 +54,6 @@ class WebApiContext implements ApiClientAwareContext */ protected $placeHolders = array(); - /** - * @var array - */ - protected $decodedData = array(); - /** * {@inheritdoc} */ @@ -132,7 +128,7 @@ public function iSendARequestWithValues($method, $url, TableNode $post) } $bodyOption = array( - 'body' => json_encode($fields), + 'body' => json_encode($fields), ); $this->request = $this->getClient()->createRequest($method, $url, $bodyOption); if (!empty($this->headers)) { @@ -242,11 +238,8 @@ public function theResponseShouldNotContain($text) */ public function theResponseShouldBeJson() { - $data = json_decode($this->response->getBody()); - + $data = json_decode($this->response->getBody(), true); Assertions::assertNotFalse($data); - - $this->decodedData = $data; } /** @@ -255,16 +248,19 @@ public function theResponseShouldBeJson() * @param string $key * @param string $subKeys * - * @Then /^(?:the )?response should contain "([^"]*)" with "([^"]*)" $/ + * @Then /^(?:the )?response should contain "([^"]*)" with "([^"]*)"$/ */ public function theResponseShouldContainKey($key, $subKeys) { + $data = json_decode($this->response->getBody(), true); + Assertions::assertNotFalse($data); + $subKeys = explode(',', $subKeys); - Assertions::assertContains($key, $this->decodedData); + Assertions::assertArrayHasKey('data', $data); foreach ($subKeys as $subKey) { - Assertions::assertContains($subKey, $this->decodedData[$key]); + Assertions::assertArrayHasKey($subKey, $data[$key]); } } @@ -286,7 +282,7 @@ public function theResponseShouldContainJson(PyStringNode $jsonString) if (null === $etalon) { throw new \RuntimeException( - "Can not convert etalon to json:\n" . $this->replacePlaceHolder($jsonString->getRaw()) + "Can not convert etalon to json:\n" . $this->replacePlaceHolder($jsonString->getRaw()) ); } From a69a2d3acf21c4eca6a66b97951f4cbe89bae1ef Mon Sep 17 00:00:00 2001 From: Tomaz Ahlin Date: Mon, 23 Mar 2015 14:00:29 +0100 Subject: [PATCH 6/7] Fixed parsing of the form data. --- .../chef/cookbooks/default/recipes/default.rb | 117 ++++++++++++++++++ .../templates/default/ssl_vhost.conf.erb | 38 ++++++ .../default/templates/default/vhost.conf.erb | 20 +++ Vagrant/chef/cookbooks/dev/recipes/default.rb | 96 ++++++++++++++ .../dev/templates/default/xdebug.ini.erb | 12 ++ Vagrant/chef/data_bags/dev/config/xdebug.json | 4 + .../dev/vhosts/web-api-extension.dev.json | 9 ++ Vagrantfile | 23 ++++ Vagrantfile.dist | 23 ++++ src/Context/WebApiContext.php | 8 +- 10 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 Vagrant/chef/cookbooks/default/recipes/default.rb create mode 100644 Vagrant/chef/cookbooks/default/templates/default/ssl_vhost.conf.erb create mode 100644 Vagrant/chef/cookbooks/default/templates/default/vhost.conf.erb create mode 100644 Vagrant/chef/cookbooks/dev/recipes/default.rb create mode 100644 Vagrant/chef/cookbooks/dev/templates/default/xdebug.ini.erb create mode 100755 Vagrant/chef/data_bags/dev/config/xdebug.json create mode 100755 Vagrant/chef/data_bags/dev/vhosts/web-api-extension.dev.json create mode 100644 Vagrantfile create mode 100644 Vagrantfile.dist diff --git a/Vagrant/chef/cookbooks/default/recipes/default.rb b/Vagrant/chef/cookbooks/default/recipes/default.rb new file mode 100644 index 0000000..3a8e1eb --- /dev/null +++ b/Vagrant/chef/cookbooks/default/recipes/default.rb @@ -0,0 +1,117 @@ +execute "add dotdeb repo" do + user "root" + not_if "grep 'deb http://packages.dotdeb.org wheezy all' /etc/apt/sources.list" + command "echo 'deb http://packages.dotdeb.org wheezy all' >> /etc/apt/sources.list && echo 'deb-src http://packages.dotdeb.org wheezy all' >> /etc/apt/sources.list" +end + +execute "add dotdeb key" do + user "root" + not_if "apt-key finger | grep 'Key fingerprint = 6572 BBEF 1B5F F28B 28B7 0683 7E3F 0700 89DF 5277'" + command "wget http://www.dotdeb.org/dotdeb.gpg && apt-key add dotdeb.gpg && apt-get update" +end + +# Run apt-get update to create the stamp file +execute "apt-get-update" do + command "apt-get update" + ignore_failure true + not_if do ::File.exists?('/var/lib/apt/periodic/update-success-stamp') end +end + +# For other recipes to call to force an update +execute "apt-get update" do + command "apt-get update" + ignore_failure true + action :nothing +end + +# provides /var/lib/apt/periodic/update-success-stamp on apt-get update +package "update-notifier-common" do + notifies :run, resources(:execute => "apt-get-update"), :immediately +end + +execute "apt-get-update-periodic" do + command "apt-get update" + ignore_failure true + only_if do + File.exists?('/var/lib/apt/periodic/update-success-stamp') && + File.mtime('/var/lib/apt/periodic/update-success-stamp') < Time.now - 86400 + end +end + +# install the software we need +%w( +curl +vim +git +libapache2-mod-php5 +php5-cli +php5-curl +php5-gd +php5-intl +php5-mysql +mysql-server +php5-mcrypt +php5-memcached +php-apc +redis-server +php5-redis +htop +unzip +).each { | pkg | package pkg } + +# upgrade system packages +execute "apt-get-upgrade-system" do + command "apt-get upgrade" + ignore_failure false + only_if do + File.exists?('/var/lib/apt/periodic/update-success-stamp') && + File.mtime('/var/lib/apt/periodic/update-success-stamp') < Time.now - 86400 + end +end + +execute "apache-enable-mod-rewrite" do + user "root" + command "a2enmod rewrite" + notifies :reload, "service[apache2]" +end + +execute "apache-enable-mod-ssl" do + user "root" + command "a2enmod ssl" + notifies :reload, "service[apache2]" +end + +service "apache2" do + supports :restart => true, :reload => true, :status => true + action [ :enable, :start ] +end + +execute "check if date.timezone is Europe/Berlin in /etc/php5/apache2/php.ini?" do + user "root" + not_if "grep '^date.timezone = Europe/Berlin' /etc/php5/apache2/php.ini" + command "sed -i 's/;date.timezone =.*/date.timezone = Europe\\/Berlin/g' /etc/php5/apache2/php.ini" +end + +execute "check if date.timezone is Europe/Berlin in /etc/php5/cli/php.ini?" do + user "root" + not_if "grep '^date.timezone = Europe/Berlin' /etc/php5/cli/php.ini" + command "sed -i 's/;date.timezone =.*/date.timezone = Europe\\/Berlin/g' /etc/php5/cli/php.ini" +end + +execute "check if memory_limit is set to the correct value in /etc/php5/apache2/php.ini?" do + user "root" + not_if "grep 'memory_limit = 256M' /etc/php5/apache2/php.ini" + command "sed -i 's/memory_limit =.*/memory_limit = 256M/g' /etc/php5/apache2/php.ini" +end + +execute "check if memory_limit is set to the correct value /etc/php5/cli/php.ini?" do + user "root" + not_if "grep 'memory_limit = 512M' /etc/php5/cli/php.ini" + command "sed -i 's/memory_limit =.*/memory_limit = 512M/g' /etc/php5/cli/php.ini" +end + +execute "check if max_execution_time is set to the correct value in /etc/php5/apache2/php.ini?" do + user "root" + not_if "grep 'max_execution_time = 60' /etc/php5/apache2/php.ini" + command "sed -i 's/max_execution_time =.*/max_execution_time = 60/g' /etc/php5/apache2/php.ini" +end diff --git a/Vagrant/chef/cookbooks/default/templates/default/ssl_vhost.conf.erb b/Vagrant/chef/cookbooks/default/templates/default/ssl_vhost.conf.erb new file mode 100644 index 0000000..4a4af8c --- /dev/null +++ b/Vagrant/chef/cookbooks/default/templates/default/ssl_vhost.conf.erb @@ -0,0 +1,38 @@ + + ServerName <%= @name %> + <% if @aliases %> + ServerAlias <% @aliases.each do |a| %><%= a %> <% end %> + <% end %> + RewriteEngine On + RewriteRule ^(.*) https://<%= @name %>$1 [R=301,L] + + + + ServerName <%= @name %> + <% if @aliases %> + ServerAlias <% @aliases.each do |a| %><%= a %> <% end %> + <% end %> + DocumentRoot <%= @docroot %> + "> + Options FollowSymLinks + AllowOverride All + Order allow,deny + Allow from all + + + Options FollowSymLinks + AllowOverride None + + + # SSL settings + SSLEngine on + SSLCertificateFile /etc/ssl/certs/<%= @name %>.crt.pem + SSLCertificateKeyFile /etc/ssl/private/<%= @name %>.key.pem + BrowserMatch "MSIE [2-6]" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0 + # MSIE 7 and newer should be able to use keepalive + BrowserMatch "MSIE [7-9]" ssl-unclean-shutdown + + LogLevel info + ErrorLog /var/log/apache2/<%= @name %>-error.log + CustomLog /var/log/apache2/<%= @name %>-access.log combined + \ No newline at end of file diff --git a/Vagrant/chef/cookbooks/default/templates/default/vhost.conf.erb b/Vagrant/chef/cookbooks/default/templates/default/vhost.conf.erb new file mode 100644 index 0000000..c4a440b --- /dev/null +++ b/Vagrant/chef/cookbooks/default/templates/default/vhost.conf.erb @@ -0,0 +1,20 @@ + + ServerName <%= @name %> + <% if @aliases %> + ServerAlias <% @aliases.each do |a| %><%= a %> <% end %> + <% end %> + DocumentRoot <%= @docroot %> + "> + Options FollowSymLinks + AllowOverride All + Order allow,deny + Allow from all + + + Options FollowSymLinks + AllowOverride None + + LogLevel info + ErrorLog /var/log/apache2/<%= @name %>-error.log + CustomLog /var/log/apache2/<%= @name %>-access.log combined + \ No newline at end of file diff --git a/Vagrant/chef/cookbooks/dev/recipes/default.rb b/Vagrant/chef/cookbooks/dev/recipes/default.rb new file mode 100644 index 0000000..e45d344 --- /dev/null +++ b/Vagrant/chef/cookbooks/dev/recipes/default.rb @@ -0,0 +1,96 @@ +include_recipe "default" + +# Install dev only software. +%w( +php5-xdebug +).each { | pkg | package pkg } + +# Change apache user to avoid permission issues. +execute "Change apache user in /etc/apache2/apache2.conf" do + user "root" + not_if "grep '^User vagrant' /etc/apache2/apache2.conf" + command "echo 'User vagrant' >> /etc/apache2/apache2.conf" +end + +execute "Change apache group in /etc/apache2/apache2.conf" do + user "root" + not_if "grep '^Group vagrant' /etc/apache2/apache2.conf" + command "echo 'Group vagrant' >> /etc/apache2/apache2.conf" +end + +execute "Set default server name in /etc/apache2/apache2.conf" do + user "root" + not_if "grep '^ServerName' /etc/apache2/apache2.conf" + command "echo 'ServerName sites.dev' >> /etc/apache2/apache2.conf" +end + +vhosts = [] +begin + vhosts = data_bag("vhosts") +rescue + puts "Vhost data bag is empty" +end +vhosts.each do | name | + vhost = data_bag_item("vhosts", name) + conffile = "/etc/apache2/sites-available/#{vhost['name']}.conf" + if vhost['type'] == "SSL" + execute "Generate certificate" do + user "root" + command "openssl req -x509 -newkey rsa:2048 -keyout /tmp/#{vhost['name']}.key.pem -out /tmp/#{vhost['name']}.crt.pem -days 365 -nodes -subj '/C=DE/ST=Bavaria/L=Munic/CN=#{vhost['name']}' && mv /tmp/#{vhost['name']}.crt.pem /etc/ssl/certs/#{vhost['name']}.crt.pem && mv /tmp/#{vhost['name']}.key.pem /etc/ssl/private/#{vhost['name']}.key.pem" + not_if "test -f /etc/ssl/certs/#{vhost['name']}.crt.pem && test -f /etc/ssl/private/#{vhost['name']}.key.pem" + end + template conffile do + user "root" + mode "0644" + source "ssl_vhost.conf.erb" + cookbook "default" + notifies :reload, "service[apache2]" + variables ({ + :name => vhost['name'], + :aliases => vhost['aliases'], + :docroot => vhost['docroot'] + }) + end + else + template conffile do + user "root" + mode "0644" + source "vhost.conf.erb" + cookbook "default" + notifies :reload, "service[apache2]" + variables ({ + :name => vhost['name'], + :aliases => vhost['aliases'], + :docroot => vhost['docroot'] + }) + end + end + execute "Remove not needed vhosts" do + user "root" + command "cd /etc/apache2/sites-available && rm `ls | grep -v '^#{vhost['name']}.conf$'` && cd /etc/apache2/sites-enabled && rm `ls | grep -v '^#{vhost['name']}.conf$'`" + only_if "ls /etc/apache2/sites-available | grep -v '^#{vhost['name']}.conf$'" + end + execute "Link vhost to enabled sites" do + user "root" + command "ln -s #{conffile} /etc/apache2/sites-enabled/#{vhost['name']}.conf" + not_if "test -L /etc/apache2/sites-enabled/#{vhost['name']}.conf" + end +end + +# Set up Xdebug. +xdebug = data_bag_item("config", "xdebug") + +template "/etc/php5/mods-available/xdebug.ini" do + user "root" + mode "0644" + source "xdebug.ini.erb" + notifies :reload, "service[apache2]" + variables ({ + :hostip => xdebug['hostip'] + }) +end +execute "Activate Xdebug" do + user "root" + command "ln -s /etc/php5/mods-available/xdebug.ini /etc/php5/conf.d/20-xdebug.ini" + not_if "test -L /etc/php5/conf.d/20-xdebug.ini" +end diff --git a/Vagrant/chef/cookbooks/dev/templates/default/xdebug.ini.erb b/Vagrant/chef/cookbooks/dev/templates/default/xdebug.ini.erb new file mode 100644 index 0000000..35a4285 --- /dev/null +++ b/Vagrant/chef/cookbooks/dev/templates/default/xdebug.ini.erb @@ -0,0 +1,12 @@ +zend_extension=/usr/lib/php5/20100525/xdebug.so + +[xdebug] +xdebug.remote_enable=On +xdebug.remote_host="<%= @hostip %>" +xdebug.remote_port=9000 +xdebug.remote_handler="dbgp" +xdebug.cli_color=1 +xdebug.overload_var_dump=0 +xdebug.show_mem_delta=1 +xdebug.trace_format=1 +xdebug.max_nesting_level=250 \ No newline at end of file diff --git a/Vagrant/chef/data_bags/dev/config/xdebug.json b/Vagrant/chef/data_bags/dev/config/xdebug.json new file mode 100755 index 0000000..acc5fea --- /dev/null +++ b/Vagrant/chef/data_bags/dev/config/xdebug.json @@ -0,0 +1,4 @@ +{ + "id": "xdebug", + "hostip": "10.2.254.1" +} \ No newline at end of file diff --git a/Vagrant/chef/data_bags/dev/vhosts/web-api-extension.dev.json b/Vagrant/chef/data_bags/dev/vhosts/web-api-extension.dev.json new file mode 100755 index 0000000..dad24ef --- /dev/null +++ b/Vagrant/chef/data_bags/dev/vhosts/web-api-extension.dev.json @@ -0,0 +1,9 @@ +{ + "id": "web-api-extension", + "type": "SSL", + "name": "web-api-extension.dev", + "aliases": [ + "web-api-extension.dev" + ], + "docroot": "/vagrant/web" +} \ No newline at end of file diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..0d818f9 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,23 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + config.vm.box = "sites" + config.vm.box_url = "file:///Volumes/Jarlssen/98\ Development/41\ Vagrant\ Boxes/sites.jarlssen.de/sites-cheflatest-virtualbox.box" + config.vm.hostname = "web-api-ext-dev" + config.vm.synced_folder ".", "/vagrant", :nfs => true + config.vm.network :private_network, ip: "10.2.254.4" + config.vm.provision :chef_solo do |chef| + chef.cookbooks_path = "Vagrant/chef/cookbooks" + chef.data_bags_path = "Vagrant/chef/data_bags/dev" + # chef debug level, start vagrant like this to debug: + # $ CHEF_LOG_LEVEL=debug vagrant + chef.log_level = ENV['CHEF_LOG'] || "info" + # chef recipes + chef.add_recipe("default") + chef.add_recipe("dev") + end + end diff --git a/Vagrantfile.dist b/Vagrantfile.dist new file mode 100644 index 0000000..5e1edc8 --- /dev/null +++ b/Vagrantfile.dist @@ -0,0 +1,23 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + config.vm.box = "sites" + config.vm.box_url = "file:///Volumes/Jarlssen/98\ Development/41\ Vagrant\ Boxes/sites.jarlssen.de/sites-cheflatest-virtualbox.box" + config.vm.hostname = "web-api-ext-dev" + config.vm.synced_folder ".", "/vagrant", :nfs => true + config.vm.network :private_network, ip: "10.2.254.2" + config.vm.provision :chef_solo do |chef| + chef.cookbooks_path = "Vagrant/chef/cookbooks" + chef.data_bags_path = "Vagrant/chef/data_bags/dev" + # chef debug level, start vagrant like this to debug: + # $ CHEF_LOG_LEVEL=debug vagrant + chef.log_level = ENV['CHEF_LOG'] || "info" + # chef recipes + chef.add_recipe("default") + chef.add_recipe("dev") + end + end diff --git a/src/Context/WebApiContext.php b/src/Context/WebApiContext.php index 1123a16..1b168f0 100644 --- a/src/Context/WebApiContext.php +++ b/src/Context/WebApiContext.php @@ -178,7 +178,13 @@ public function iSendARequestWithFormData($method, $url, PyStringNode $body) $body = $this->replacePlaceHolder(trim($body)); $fields = array(); - parse_str(implode('&', explode("\n", $body)), $fields); + + $dataLines = explode("\n", $body); + foreach($dataLines as $line) { + $line = explode('=', $line); + $fields[$line[0]] = $line[1]; + } + $this->request = $this->getClient()->createRequest($method, $url, array('headers' => $this->getHeaders())); /** @var \GuzzleHttp\Post\PostBodyInterface $requestBody */ $requestBody = $this->request->getBody(); From 2f1325db69be162bded583c9682d7660b405d4c1 Mon Sep 17 00:00:00 2001 From: Tomaz Ahlin Date: Mon, 23 Mar 2015 15:30:47 +0100 Subject: [PATCH 7/7] Added more contexts. --- src/Context/WebApiContext.php | 121 ++++++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 6 deletions(-) diff --git a/src/Context/WebApiContext.php b/src/Context/WebApiContext.php index 1b168f0..c09cce0 100644 --- a/src/Context/WebApiContext.php +++ b/src/Context/WebApiContext.php @@ -185,7 +185,10 @@ public function iSendARequestWithFormData($method, $url, PyStringNode $body) $fields[$line[0]] = $line[1]; } - $this->request = $this->getClient()->createRequest($method, $url, array('headers' => $this->getHeaders())); + $this->request = $this->getClient()->createRequest($method, $url); + if (!empty($this->headers)) { + $this->request->addHeaders($this->headers); + } /** @var \GuzzleHttp\Post\PostBodyInterface $requestBody */ $requestBody = $this->request->getBody(); foreach ($fields as $key => $value) { @@ -249,27 +252,133 @@ public function theResponseShouldBeJson() } /** - * Checks that response is json and stores the data to array. + * Checks that response is json and it contains desired keys. * * @param string $key + * @param string $type * @param string $subKeys * - * @Then /^(?:the )?response should contain "([^"]*)" with "([^"]*)"$/ + * @Then /^(?:the )?response should contain "([^"]*)" with "(at least|exactly)" "([^"]*)"$/ */ - public function theResponseShouldContainKey($key, $subKeys) + public function theResponseShouldContainKeys($key, $type, $subKeys) + { + $this->theResponseShouldContainOneItem($key, $type, $subKeys, false); + } + + /** + * Checks that response is json and it contains desired keys and values. + * + * @param string $key + * @param string $type + * @param string $subKeys + * @param string $subKeyValues + * + * @Then /^(?:the )?response should contain "([^"]*)" with "(at least|exactly)" "([^"]*)" with values "([^"]*)"$/ + */ + public function theResponseShouldContainKeysAndValues($key, $type, $subKeys, $subKeyValues) + { + $this->theResponseShouldContainOneItem($key, $type, $subKeys, true, $subKeyValues); + } + + /** + * Checks that response is json and stores the data to array. + * + * @param string $key + * @param string $type + * @param string $subKeys + * @param boolean $compareValues + * @param string $subKeyValues + */ + private function theResponseShouldContainOneItem($key, $type, $subKeys, $compareValues, $subKeyValues = '') { $data = json_decode($this->response->getBody(), true); Assertions::assertNotFalse($data); - $subKeys = explode(',', $subKeys); + $subKeys = array_map('trim', explode(',', $subKeys)); + $subKeyValues = array_map('trim', explode(',', $subKeyValues)); + + if ($compareValues) { + Assertions::assertEquals(count($subKeyValues), count($subKeys)); + } Assertions::assertArrayHasKey('data', $data); - foreach ($subKeys as $subKey) { + for ($j=0, $c=count($subKeys); $j<$c; $j++) { + $subKey = $subKeys[$j]; + if ($this->isExactType($type)) { + Assertions::assertEquals(count($subKeys), count($data[$key])); + } Assertions::assertArrayHasKey($subKey, $data[$key]); + if ($compareValues) { + Assertions::assertEquals($subKeyValues[$j], $data[$key][$subKey]); + } } } + /** + * Checks that response is json and contains the expected number of items with the desired keys. + * + * @param string $key + * @param integer $n + * @param string $type + * @param string $subKeys + * + * @Then /^(?:the )?response should contain "([^"]*)" with (\d+) items containing "(at least|exactly)" "([^"]*)"$/ + */ + public function theResponseShouldContainItemsWithKeys($key, $n, $type, $subKeys) + { + $this->theResponseShouldContainItems($key, $n, $type, $subKeys, false); + } + + /** + * Checks that response is json and contains the expected number of items with the desired keys. + * + * @param string $key + * @param integer $n + * @param string $type + * @param string $subKeys + * @param boolean $compareValues + * @param string $subKeyValues + */ + private function theResponseShouldContainItems($key, $n, $type, $subKeys, $compareValues, $subKeyValues = '') + { + $data = json_decode($this->response->getBody(), true); + Assertions::assertNotFalse($data); + + $subKeys = array_map('trim', explode(',', $subKeys)); + $subKeyValues = array_map('trim', explode(',', $subKeyValues)); + + if ($compareValues) { + Assertions::assertEquals(count($subKeyValues), count($subKeys)); + } + + Assertions::assertArrayHasKey($key, $data); + Assertions::assertEquals($n, count($data[$key])); + + for ($i=0; $i<$n; $i++) { + for ($j=0, $c=count($subKeys); $j<$c; $j++) { + $subKey = $subKeys[$j]; + Assertions::assertArrayHasKey($i, $data[$key]); + if ($this->isExactType($type)) { + Assertions::assertEquals(count($subKeys), count($data[$key][$i])); + } + Assertions::assertArrayHasKey($subKey, $data[$key][$i]); + if ($compareValues) { + Assertions::assertEquals($subKeyValues[$j], $data[$key][$i][$subKey]); + } + } + } + } + + /** + * @param $type + * @returns boolean + */ + private function isExactType($type) + { + return $type === 'exactly'; + } + /** * Checks that response body contains JSON from PyString. *