Integrate wepay SDK library to work with codeigniter2.2 - codeigniter

I am working with a application using codeigniter 2.2 but now I am encountering a problem with integrating wepay library wepay.php into codeigniter library. Any help would be appreciated Here is the current library provided by wepay.
I have tried to integrate wepay.php into codeigniter but it gives white screen. I think there is an issue with multiple classes being defined in wepay.php and I dont know how to handle this in codeigniter
Openaccount.php file:
<?php
require './_shared.php';
?>
<h1>WePay Demo App: Open Account</h1>
Back
<br />
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['account_name']) && isset($_POST['account_description'])) {
// WePay sanitizes its own data, but displaying raw POST data on your own site is a XSS security hole.
$name = htmlentities($_POST['account_name']);
$desc = htmlentities($_POST['account_description']);
try {
$wepay = new WePay('STAGE_5cdbb3fa32af0ccaef97328542d5e2a0a7f61263ed2bcd79c9f29c2d5e0d85e6');
$account = $wepay->request('account/create', array(
'name' => $name,
'description' => $desc,
));
echo "Created account $name for '$desc'! View on WePay at $account->account_uri. See all of your accounts here.";
}
catch (WePayException $e) {
// Something went wrong - normally you would log
// this and give your user a more informative message
echo $e->getMessage();
}
}
else {
echo 'Account name and description are both required.';
}
}
?>
<form method="post">
<fieldset>
<legend>Account Info</legend>
<label for="account_name">Account Name:</label><br />
<input type="text" id="account_name" name="account_name" placeholder="Ski Trip Savings"/>
<br /><br />
<label for="account_description">Account Description: </label><br />
<textarea name="account_description" rows="10" cols="40" placeholder="Saving up some dough for our ski trip!"></textarea>
<br /><br />
<input type="submit" value="Open account" />
</fieldset>
</form>
shared.php file:
<?php
require '../wepay.php';
Wepay::useStaging('34218', '7c09762bbe','2014-01-08');
session_start();
?>
Please have a look at the bottom of wepay.php it is multiple classes defined in one class.
wepay.php contents
<?php
class WePay {
/**
* Version number - sent in user agent string
*/
const VERSION = '0.2.1';
/**
* Scope fields
* Passed into Wepay::getAuthorizationUri as array
*/
const SCOPE_MANAGE_ACCOUNTS = 'manage_accounts'; // Open and interact with accounts
const SCOPE_COLLECT_PAYMENTS = 'collect_payments'; // Create and interact with checkouts
const SCOPE_VIEW_USER = 'view_user'; // Get details about authenticated user
const SCOPE_PREAPPROVE_PAYMENTS = 'preapprove_payments'; // Create and interact with preapprovals
const SCOPE_MANAGE_SUBSCRIPTIONS = 'manage_subscriptions'; // Subscriptions
const SCOPE_SEND_MONEY = 'send_money'; // For withdrawals
/**
* Application's client ID
*/
private static $client_id;
/**
* Application's client secret
*/
private static $client_secret;
/**
* API Version
* https://www.wepay.com/developer/reference/versioning
*/
private static $api_version;
/**
* #deprecated Use WePay::getAllScopes() instead.
*/
public static $all_scopes = array(
self::SCOPE_MANAGE_ACCOUNTS,
self::SCOPE_COLLECT_PAYMENTS,
self::SCOPE_PREAPPROVE_PAYMENTS,
self::SCOPE_VIEW_USER,
self::SCOPE_SEND_MONEY,
self::SCOPE_MANAGE_SUBSCRIPTIONS
);
/**
* Determines whether to use WePay's staging or production servers
*/
private static $production = null;
/**
* cURL handle
*/
private static $ch = NULL;
/**
* Authenticated user's access token
*/
private $token;
/**
* Pass WePay::getAllScopes() into getAuthorizationUri if your application desires full access
*/
public static function getAllScopes() {
return array(
self::SCOPE_MANAGE_ACCOUNTS,
self::SCOPE_MANAGE_SUBSCRIPTIONS,
self::SCOPE_COLLECT_PAYMENTS,
self::SCOPE_PREAPPROVE_PAYMENTS,
self::SCOPE_VIEW_USER,
self::SCOPE_SEND_MONEY
);
}
/**
* Generate URI used during oAuth authorization
* Redirect your user to this URI where they can grant your application
* permission to make API calls
* #link https://www.wepay.com/developer/reference/oauth2
* #param array $scope List of scope fields for which your application wants access
* #param string $redirect_uri Where user goes after logging in at WePay (domain must match application settings)
* #param array $options optional user_name,user_email which will be pre-filled on login form, state to be returned in querystring of redirect_uri
* #return string URI to which you must redirect your user to grant access to your application
*/
public static function getAuthorizationUri(array $scope, $redirect_uri, array $options = array()) {
// This does not use WePay::getDomain() because the user authentication
// domain is different than the API call domain
if (self::$production === null) {
throw new RuntimeException('You must initialize the WePay SDK with WePay::useStaging() or WePay::useProduction()');
}
$domain = self::$production ? 'https://www.wepay.com' : 'https://stage.wepay.com';
$uri = $domain . '/v2/oauth2/authorize?';
$uri .= http_build_query(array(
'client_id' => self::$client_id,
'redirect_uri' => $redirect_uri,
'scope' => implode(',', $scope),
'state' => empty($options['state']) ? '' : $options['state'],
'user_name' => empty($options['user_name']) ? '' : $options['user_name'],
'user_email' => empty($options['user_email']) ? '' : $options['user_email'],
), '', '&');
return $uri;
}
private static function getDomain() {
if (self::$production === true) {
return 'https://wepayapi.com/v2/';
}
elseif (self::$production === false) {
return 'https://stage.wepayapi.com/v2/';
}
else {
throw new RuntimeException('You must initialize the WePay SDK with WePay::useStaging() or WePay::useProduction()');
}
}
/**
* Exchange a temporary access code for a (semi-)permanent access token
* #param string $code 'code' field from query string passed to your redirect_uri page
* #param string $redirect_uri Where user went after logging in at WePay (must match value from getAuthorizationUri)
* #return StdClass|false
* user_id
* access_token
* token_type
*/
public static function getToken($code, $redirect_uri) {
$params = (array(
'client_id' => self::$client_id,
'client_secret' => self::$client_secret,
'redirect_uri' => $redirect_uri,
'code' => $code,
'state' => '', // do not hardcode
));
$result = self::make_request('oauth2/token', $params);
return $result;
}
/**
* Configure SDK to run against WePay's production servers
* #param string $client_id Your application's client id
* #param string $client_secret Your application's client secret
* #return void
* #throws RuntimeException
*/
public static function useProduction($client_id, $client_secret, $api_version = null) {
if (self::$production !== null) {
throw new RuntimeException('API mode has already been set.');
}
self::$production = true;
self::$client_id = $client_id;
self::$client_secret = $client_secret;
self::$api_version = $api_version;
}
/**
* Configure SDK to run against WePay's staging servers
* #param string $client_id Your application's client id
* #param string $client_secret Your application's client secret
* #return void
* #throws RuntimeException
*/
public static function useStaging($client_id, $client_secret, $api_version = null) {
if (self::$production !== null) {
throw new RuntimeException('API mode has already been set.');
}
self::$production = false;
self::$client_id = $client_id;
self::$client_secret = $client_secret;
self::$api_version = $api_version;
}
/**
* Returns the current environment.
* #return string "none" (not configured), "production" or "staging".
*/
public static function getEnvironment() {
if(self::$production === null) {
return 'none';
} else if(self::$production) {
return 'production';
} else {
return 'staging';
}
}
/**
* Set Api Version
* https://www.wepay.com/developer/reference/versioning
*
* #param string $version Api Version to send in call request header
*/
public static function setApiVersion($version) {
self::$api_version = $version;
}
/**
* Create a new API session
* #param string $token - access_token returned from WePay::getToken
*/
public function __construct($token) {
if ($token && !is_string($token)) {
throw new InvalidArgumentException('$token must be a string, ' . gettype($token) . ' provided');
}
$this->token = $token;
}
/**
* Clean up cURL handle
*/
public function __destruct() {
if (self::$ch) {
curl_close(self::$ch);
self::$ch = NULL;
}
}
/**
* create the cURL request and execute it
*/
private static function make_request($endpoint, $values, $headers = array())
{
self::$ch = curl_init();
$headers = array_merge(array("Content-Type: application/json"), $headers); // always pass the correct Content-Type header
// send Api Version header
if(!empty(self::$api_version)) {
$headers[] = "Api-Version: " . self::$api_version;
}
curl_setopt(self::$ch, CURLOPT_USERAGENT, 'WePay v2 PHP SDK v' . self::VERSION . ' Client id:' . self::$client_id);
curl_setopt(self::$ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt(self::$ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt(self::$ch, CURLOPT_TIMEOUT, 30); // 30-second timeout, adjust to taste
curl_setopt(self::$ch, CURLOPT_POST, !empty($values)); // WePay's API is not strictly RESTful, so all requests are sent as POST unless there are no request values
$uri = self::getDomain() . $endpoint;
curl_setopt(self::$ch, CURLOPT_URL, $uri);
if (!empty($values)) {
curl_setopt(self::$ch, CURLOPT_POSTFIELDS, json_encode($values));
}
$raw = curl_exec(self::$ch);
if ($errno = curl_errno(self::$ch)) {
// Set up special handling for request timeouts
if ($errno == CURLE_OPERATION_TIMEOUTED) {
throw new WePayServerException("Timeout occurred while trying to connect to WePay");
}
throw new Exception('cURL error while making API call to WePay: ' . curl_error(self::$ch), $errno);
}
$result = json_decode($raw);
$httpCode = curl_getinfo(self::$ch, CURLINFO_HTTP_CODE);
if ($httpCode >= 400) {
if (!isset($result->error_code)) {
throw new WePayServerException("WePay returned an error response with no error_code, please alert api#wepay.com. Original message: $result->error_description", $httpCode, $result, 0);
}
if ($httpCode >= 500) {
throw new WePayServerException($result->error_description, $httpCode, $result, $result->error_code);
}
switch ($result->error) {
case 'invalid_request':
throw new WePayRequestException($result->error_description, $httpCode, $result, $result->error_code);
case 'access_denied':
default:
throw new WePayPermissionException($result->error_description, $httpCode, $result, $result->error_code);
}
}
return $result;
}
/**
* Make API calls against authenticated user
* #param string $endpoint - API call to make (ex. 'user', 'account/find')
* #param array $values - Associative array of values to send in API call
* #return StdClass
* #throws WePayException on failure
* #throws Exception on catastrophic failure (non-WePay-specific cURL errors)
*/
public function request($endpoint, array $values = array()) {
$headers = array();
if ($this->token) { // if we have an access_token, add it to the Authorization header
$headers[] = "Authorization: Bearer $this->token";
}
$result = self::make_request($endpoint, $values, $headers);
return $result;
}
}
/**
* Different problems will have different exception types so you can
* catch and handle them differently.
*
* WePayServerException indicates some sort of 500-level error code and
* was unavoidable from your perspective. You may need to re-run the
* call, or check whether it was received (use a "find" call with your
* reference_id and make a decision based on the response)
*
* WePayRequestException indicates a development error - invalid endpoint,
* erroneous parameter, etc.
*
* WePayPermissionException indicates your authorization token has expired,
* was revoked, or is lacking in scope for the call you made
*/
class WePayException extends Exception {
public function __construct($description = '', $http_code = FALSE, $response = FALSE, $code = 0, $previous = NULL)
{
$this->response = $response;
if (!defined('PHP_VERSION_ID')) {
$version = explode('.', PHP_VERSION);
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
}
if (PHP_VERSION_ID < 50300) {
parent::__construct($description, $code);
} else {
parent::__construct($description, $code, $previous);
}
}
}
class WePayRequestException extends WePayException {}
class WePayPermissionException extends WePayException {}
class WePayServerException extends WePayException {}

Here is the solution to integrate wepay library in codeigniter
Go to application/config/config.php and add the following wepay app credentials at the end
config.php you can also make separate config file but I had included it in CI's config
/*WEPAY config items*/
$config['client_id']='client_id_here';
$config['client_secret']='client_secret_here';
$config['app_version']='2014-01-08'; // this could be different in future
$config['access_token']='access_token_here';
/* End of file config.php */
/* Location: ./application/config/config.php */
create a file name wepay.php in Codeigniter's application/libraries/wepay.php and paste the following contents in wepay.php at line 202 add your app's access token and also remember to remove line 234 of wepay.php as u go live, I added this line of code to stop curl from verifying SSL certificate.
curl_setopt(self::$ch, CURLOPT_SSL_VERIFYPEER, 0);
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class WePay {
/**
* Version number - sent in user agent string
*/
const VERSION = '0.2.1';
/**
* Scope fields
* Passed into Wepay::getAuthorizationUri as array
*/
const SCOPE_MANAGE_ACCOUNTS = 'manage_accounts'; // Open and interact with accounts
const SCOPE_COLLECT_PAYMENTS = 'collect_payments'; // Create and interact with checkouts
const SCOPE_VIEW_USER = 'view_user'; // Get details about authenticated user
const SCOPE_PREAPPROVE_PAYMENTS = 'preapprove_payments'; // Create and interact with preapprovals
const SCOPE_MANAGE_SUBSCRIPTIONS = 'manage_subscriptions'; // Subscriptions
const SCOPE_SEND_MONEY = 'send_money'; // For withdrawals
/**
* Application's client ID
*/
private static $client_id;
/**
* Application's client secret
*/
private static $client_secret;
/**
* API Version
* https://www.wepay.com/developer/reference/versioning
*/
private static $api_version;
/**
* #deprecated Use WePay::getAllScopes() instead.
*/
public static $all_scopes = array(
self::SCOPE_MANAGE_ACCOUNTS,
self::SCOPE_COLLECT_PAYMENTS,
self::SCOPE_PREAPPROVE_PAYMENTS,
self::SCOPE_VIEW_USER,
self::SCOPE_SEND_MONEY,
self::SCOPE_MANAGE_SUBSCRIPTIONS
);
/**
* Determines whether to use WePay's staging or production servers
*/
private static $production = null;
/**
* cURL handle
*/
private static $ch = NULL;
/**
* Authenticated user's access token
*/
private $token;
/**
* Pass WePay::getAllScopes() into getAuthorizationUri if your application desires full access
*/
public static function getAllScopes() {
return array(
self::SCOPE_MANAGE_ACCOUNTS,
self::SCOPE_MANAGE_SUBSCRIPTIONS,
self::SCOPE_COLLECT_PAYMENTS,
self::SCOPE_PREAPPROVE_PAYMENTS,
self::SCOPE_VIEW_USER,
self::SCOPE_SEND_MONEY
);
}
/**
* Generate URI used during oAuth authorization
* Redirect your user to this URI where they can grant your application
* permission to make API calls
* #link https://www.wepay.com/developer/reference/oauth2
* #param array $scope List of scope fields for which your application wants access
* #param string $redirect_uri Where user goes after logging in at WePay (domain must match application settings)
* #param array $options optional user_name,user_email which will be pre-filled on login form, state to be returned in querystring of redirect_uri
* #return string URI to which you must redirect your user to grant access to your application
*/
public static function getAuthorizationUri(array $scope, $redirect_uri, array $options = array()) {
// This does not use WePay::getDomain() because the user authentication
// domain is different than the API call domain
if (self::$production === null) {
throw new RuntimeException('You must initialize the WePay SDK with WePay::useStaging() or WePay::useProduction()');
}
$domain = self::$production ? 'https://www.wepay.com' : 'https://stage.wepay.com';
$uri = $domain . '/v2/oauth2/authorize?';
$uri .= http_build_query(array(
'client_id' => self::$client_id,
'redirect_uri' => $redirect_uri,
'scope' => implode(',', $scope),
'state' => empty($options['state']) ? '' : $options['state'],
'user_name' => empty($options['user_name']) ? '' : $options['user_name'],
'user_email' => empty($options['user_email']) ? '' : $options['user_email'],
), '', '&');
return $uri;
}
private static function getDomain() {
if (self::$production === true) {
return 'https://wepayapi.com/v2/';
}
elseif (self::$production === false) {
return 'https://stage.wepayapi.com/v2/';
}
else {
throw new RuntimeException('You must initialize the WePay SDK with WePay::useStaging() or WePay::useProduction()');
}
}
/**
* Exchange a temporary access code for a (semi-)permanent access token
* #param string $code 'code' field from query string passed to your redirect_uri page
* #param string $redirect_uri Where user went after logging in at WePay (must match value from getAuthorizationUri)
* #return StdClass|false
* user_id
* access_token
* token_type
*/
public static function getToken($code, $redirect_uri) {
$params = (array(
'client_id' => self::$client_id,
'client_secret' => self::$client_secret,
'redirect_uri' => $redirect_uri,
'code' => $code,
'state' => '', // do not hardcode
));
$result = self::make_request('oauth2/token', $params);
return $result;
}
/**
* Configure SDK to run against WePay's production servers
* #param string $client_id Your application's client id
* #param string $client_secret Your application's client secret
* #return void
* #throws RuntimeException
*/
public static function useProduction($client_id, $client_secret, $api_version = null) {
if (self::$production !== null) {
throw new RuntimeException('API mode has already been set.');
}
self::$production = true;
self::$client_id = $client_id;
self::$client_secret = $client_secret;
self::$api_version = $api_version;
}
/**
* Configure SDK to run against WePay's staging servers
* #param string $client_id Your application's client id
* #param string $client_secret Your application's client secret
* #return void
* #throws RuntimeException
*/
public static function useStaging($client_id, $client_secret, $api_version = null) {
if (self::$production !== null) {
throw new RuntimeException('API mode has already been set.');
}
self::$production = false;
self::$client_id = $client_id;
self::$client_secret = $client_secret;
self::$api_version = $api_version;
}
/**
* Returns the current environment.
* #return string "none" (not configured), "production" or "staging".
*/
public static function getEnvironment() {
if(self::$production === null) {
return 'none';
} else if(self::$production) {
return 'production';
} else {
return 'staging';
}
}
/**
* Set Api Version
* https://www.wepay.com/developer/reference/versioning
*
* #param string $version Api Version to send in call request header
*/
public static function setApiVersion($version) {
self::$api_version = $version;
}
/**
* Create a new API session
* #param string $token - access_token returned from WePay::getToken
*/
public function __construct() {
$token='your_application_access_token';
if ($token && !is_string($token)) {
throw new InvalidArgumentException('$token must be a string, ' . gettype($token) . ' provided');
}
$this->token = $token;
}
/**
* Clean up cURL handle
*/
public function __destruct() {
if (self::$ch) {
curl_close(self::$ch);
self::$ch = NULL;
}
}
/**
* create the cURL request and execute it
*/
private static function make_request($endpoint, $values, $headers = array())
{
self::$ch = curl_init();
$headers = array_merge(array("Content-Type: application/json"), $headers); // always pass the correct Content-Type header
// send Api Version header
if(!empty(self::$api_version)) {
$headers[] = "Api-Version: " . self::$api_version;
}
curl_setopt(self::$ch, CURLOPT_USERAGENT, 'WePay v2 PHP SDK v' . self::VERSION . ' Client id:' . self::$client_id);
curl_setopt(self::$ch, CURLOPT_SSL_VERIFYPEER, 0); // Remove this line after testing because this line is to stop curl from using ssl verification
curl_setopt(self::$ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt(self::$ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt(self::$ch, CURLOPT_TIMEOUT, 30); // 30-second timeout, adjust to taste
curl_setopt(self::$ch, CURLOPT_POST, !empty($values)); // WePay's API is not strictly RESTful, so all requests are sent as POST unless there are no request values
$uri = self::getDomain() . $endpoint;
curl_setopt(self::$ch, CURLOPT_URL, $uri);
if (!empty($values)) {
curl_setopt(self::$ch, CURLOPT_POSTFIELDS, json_encode($values));
}
$raw = curl_exec(self::$ch);
if ($errno = curl_errno(self::$ch)) {
// Set up special handling for request timeouts
if ($errno == CURLE_OPERATION_TIMEOUTED) {
throw new WePayServerException("Timeout occurred while trying to connect to WePay");
}
throw new Exception('cURL error while making API call to WePay: ' . curl_error(self::$ch), $errno);
}
$result = json_decode($raw);
$httpCode = curl_getinfo(self::$ch, CURLINFO_HTTP_CODE);
if ($httpCode >= 400) {
if (!isset($result->error_code)) {
throw new WePayServerException("WePay returned an error response with no error_code, please alert api#wepay.com. Original message: $result->error_description", $httpCode, $result, 0);
}
if ($httpCode >= 500) {
throw new WePayServerException($result->error_description, $httpCode, $result, $result->error_code);
}
switch ($result->error) {
case 'invalid_request':
throw new WePayRequestException($result->error_description, $httpCode, $result, $result->error_code);
case 'access_denied':
default:
throw new WePayPermissionException($result->error_description, $httpCode, $result, $result->error_code);
}
}
return $result;
}
/**
* Make API calls against authenticated user
* #param string $endpoint - API call to make (ex. 'user', 'account/find')
* #param array $values - Associative array of values to send in API call
* #return StdClass
* #throws WePayException on failure
* #throws Exception on catastrophic failure (non-WePay-specific cURL errors)
*/
public function request($endpoint, array $values = array()) {
$headers = array();
if ($this->token) { // if we have an access_token, add it to the Authorization header
$headers[] = "Authorization: Bearer $this->token";
}
$result = self::make_request($endpoint, $values, $headers);
return $result;
}
}
/**
* Different problems will have different exception types so you can
* catch and handle them differently.
*
* WePayServerException indicates some sort of 500-level error code and
* was unavoidable from your perspective. You may need to re-run the
* call, or check whether it was received (use a "find" call with your
* reference_id and make a decision based on the response)
*
* WePayRequestException indicates a development error - invalid endpoint,
* erroneous parameter, etc.
*
* WePayPermissionException indicates your authorization token has expired,
* was revoked, or is lacking in scope for the call you made
*/
class WePayException extends Exception {
public function __construct($description = '', $http_code = FALSE, $response = FALSE, $code = 0, $previous = NULL)
{
$this->response = $response;
if (!defined('PHP_VERSION_ID')) {
$version = explode('.', PHP_VERSION);
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
}
if (PHP_VERSION_ID < 50300) {
parent::__construct($description, $code);
} else {
parent::__construct($description, $code, $previous);
}
}
}
class WePayRequestException extends WePayException {}
class WePayPermissionException extends WePayException {}
class WePayServerException extends WePayException {}
Now the final step make a controller, here my controller name is payment here are its contents:
application/controllers/payment.php
After that you can call controller method by adding controller name and method in browser localhost/yourapplication/index.php/payment/test_wepay_response
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Payment extends CI_Controller {
public function __construct()
{
parent::__construct();
if($this->session->userdata('urole') != 'admin'){redirect('admin_login');}
$this->load->library('wePay','wepay');
$this->load->model('admin_model','admin');
}
public function index()
{ echo 'Hi there library loaded';exit;
}
public function test_wepay_response()
{
$client_id=$this->config->item('client_id');
$client_secret= $this->config->item('client_secret');
$client_secret= $this->config->item('app_version');
$this->wepay->useStaging($client_id,$client_secret,$app_version);
//$data = array('account_id' => '12345');
$response =$this->wepay->request('account/find');
print_r($response);exit;
}
}

Related

Why do I get a dirty response from my Laravel API using GuzzleHttp?

In my API, my controllers extend from BaseController and my endpoints send responses using the sendResponse method (this is my BaseController):
class BaseController extends Controller
{
/**
* success response method.
*
* #param mixed $data The data resulting from the transaction
* #param string $message The success message of the transaction
* #param int $status The error code of the transaction, default is 200
*
* #return JsonResponse
*/
public function sendResponse( $data, string $message, int $status = 200 ) : JsonResponse
{
$response = [
'success' => true,
'data' => $data,
'message' => $message,
];
return response()->json( $response, $status );
}
/**
* return error response.
*
* #param string $message The error message
* #param mixed $data The list of errors of the transaction
* #param int $status The error code of the transaction, default is 404
*
* #return JsonResponse
*/
public function sendError( string $message, array $data = [], int $status = 404 ) : JsonResponse
{
$response = [
'success' => false,
'message' => $message,
];
if( !empty( $data ) ){
$response[ 'data' ] = $data;
}
return response()->json( $response, $status );
}
}
For example I can do this:
/**
* Display a listing of the resource.
*
* #return JsonResponse
*/
public function index() : JsonResponse
{
$users = User::all();
return $this->sendResponse( UserResource::collection( $users ), 'success' );
}
Now, in the other side, I have a project that consumes the API using Guzzle, so I have created a class that handles the requests:
namespace App\Models;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
class RequestURL
{
public string $endpoint;
public string $method;
public array $params;
public array $headers;
public mixed $response = null;
/**
* Constructor of the class
*
* #param string $endpoint
* #param string $method
* #param array $params
* #param array $headers
*/
public function __construct( string $endpoint, string $method = 'post', array $params = [], array $headers = [] )
{
$this->endpoint = $endpoint;
$this->method = $method;
$this->params = $params;
$this->headers = $this->makeHeaders( $headers );
$this->send();
}
/**
* Sends the request and expects the response from the api endpoint
*
* #return void
*/
private function send() : void
{
$client = new Client( [ 'base_uri' => config( 'superveci.api' ) ] );
try{
$this->response = $client->request( $this->method, $this->endpoint, [
'json' => $this->params,
'headers' => $this->headers,
'verify' => false,
] );
}
catch( GuzzleException $e ){
// TODO : log the error request
}
}
/**
* Returns the response on the requested url
*
* #return ResponseInterface|null
*/
public function getResponse() : ?ResponseInterface
{
return $this->response;
}
/**
* Returns the body of the response as a json object
*
* #return mixed
*/
public function getBody() : mixed
{
if( isset( $this->response ) ){
return json_decode( substr( (string) $this->getResponse()->getBody()->getContents(), 39 ) );
}
return null;
}
/**
* Returns the data from the response as a json object
*
* #return mixed
*/
public function getData() : mixed
{
return data_get( $this->getBody(), 'data' );
}
/**
* #return int
*/
public function getCode() : int
{
if( $this->response != null ){
return $this->response->getStatusCode();
}
return 401;
}
/**
* Sets the headers of the request up
*
* #param array $headers
*
* #return array
*/
private function makeHeaders( array $headers = [] ) : array
{
$bearer = ( isset( $headers[ 'token' ] ) ) ? $headers[ 'token' ] : request()->cookie( '_token' );
if( $bearer != null ){
$headers[ 'Authorization' ] = 'Bearer ' . $bearer;
}
return array_merge( [ 'Accept' => 'application/json', ], $headers );
}
}
As you can see, in the getBody() method, I wanted to cast the response data as an object, so, the logical thing here was to use json_decode. But for some reason it was returning null, until I found out that the response was dirty and I had to clean the first 39 characters of it, to be able to cast it using:
substr( (string) $this->getResponse()->getBody()->getContents(), 39 )
If I don' t do it, the response I get is similar to this (this is the resulting inspected code from my browser):
<pre hidden="">
{"success":true,"data":{"saludo":"Hello world","despedida":"Good bye cruel world"},"message":"success"}
</pre>
And of course the json_decode fails.
What is going on? Is this normal behavior? will it always be 39 characters?
Thanks

How to get file extension from SwiftAttachment object in Laravel Email Transport

This is Laravel 8. I'm extending Illuminate\Mail\Transport\Transport class to create a custom mail transport in order to utilize the company's custom mail API with Illuminate\Mail\Mailable. I got most of it working, including file attachments, however the Swift_Mime_SimpleMimeEntity and the classes deriving from it contain getBody(), getFilename(), getSize(), and getContentType() but no methods to extract file extension.
<?php
namespace App\CustomMailDriver;
use GuzzleHttp\ClientInterface;
use Illuminate\Mail\Transport\Transport;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Swift_Mime_SimpleMessage;
class CustomTransport extends Transport
{
/**
* Guzzle client instance.
*
* #var \GuzzleHttp\ClientInterface
*/
protected $client;
/**
* API key.
*
* #var string
*/
protected $key;
/**
* The API URL to which to POST emails.
*
* #var string
*/
protected $url;
/**
* Create a new Custom transport instance.
*
* #param \GuzzleHttp\ClientInterface $client
* #param string|null $url
* #param string $key
* #return void
*/
public function __construct(ClientInterface $client, string $url, string $key)
{
$this->key = $key;
$this->client = $client;
$this->url = $url;
}
/**
* {#inheritdoc}
*/
public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null)
{
$this->beforeSendPerformed($message);
$payload = $this->getPayload($message);
try {
// ignore ssl (esp when working in DEV/QA)
$response = Http::withoutVerifying()->withHeaders([
'X-Authorization' => $this->key
])->post($this->url, $payload);
Log::info($response->body());
} catch (\Exception $e) {
Log::error($e->getMessage());
}
$this->sendPerformed($message);
return $this->numberOfRecipients($message);
}
/**
* Get the HTTP payload for sending the message.
*
* #param \Swift_Mime_SimpleMessage $message
* #return array
*/
protected function getPayload(Swift_Mime_SimpleMessage $message): array
{
// to
if (!empty($message->getTo())) {
$payload['payload']['to']['email'] = key($message->getTo());
}
// cc
if (!empty($message->getCc())) {
$payload['payload']['cc']['email'] = key($message->getCc());
}
// bcc
if (!empty($message->getBcc())) {
$payload['payload']['bcc']['email'] = key($message->getBcc());
}
// subject
$payload['payload']['subject'] = $message->getSubject();
// html
$payload['payload']['message']['html'] = $message->getBody();
// message children contains plain text, attachments, etc
$children = $message->getChildren();
if (!empty($children)) {
foreach($children as $child) {
// attachments
if (get_class($child) === 'Swift_Attachment') {
$payload['payload']['attachments'][] = [
'content' => base64_encode($child->getBody()),
'filename' => $child->getFilename(),
];
}
// plain text
if (get_class($child) === 'Swift_MimePart') {
$payload['payload']['message']['text'] = $child->getBody();
}
}
}
return $payload;
}
}
I had to go different route. Instead of searching the extension inside Transport class using Swift_Mime_SimpleMessage, I passed the filename with the original extension to Transport class from Illuminate\Mail\Mailable
public function build()
{
$tempUpload = request()->file('file_attachment');
$filename = $tampUpload->getClientOriginalName() . "." . $tempUpload->getClientOriginalExtension();
return $this->from($this->from_email, $this->from_name)
->subject('subject line')
->attach($tempUpload, ['as' => $filename)
->view('emails.gce.supplier_supplier')
->with($this->data);
}

Returning to route after middleware triggered in Laravel

I am working in Laravel 7 and have a middleware that checks if the user has a current user agreement, if not it redirects to a form that offers the current agreement. When the offer is accepted I need to redirect back to where they were originally going. I think I need to put something in the session so that when my controller stores their acceptance it can redirect back to the original route.
class VerifyAgreement
{
public function handle($request, Closure $next, $agreement)
{
if(UserAgreement::outOfDate($agreement)){
return redirect()->route('agreement.offer', $agreement);
}
return $next($request);
}
}
I think I need to get the current request and pass it to the redirect so the User Agreement controller can capture it somehow and then redirect once the agreement is stored... I am not sure.
class AgreementController extends Controller
{
public function offer(Agreement $agreement)
{
return view('agreement.offer',['agreement' => $agreement]);
}
public function agree(Request $request)
{
$agreement_uuid = App\Agreement::findOrFail($request->agreement)->uuid;
UserAgreement::create(['user_uuid'=>auth()->user()->uuid, 'agreement_uuid'=>$agreement_uuid]);
//redirect something something something
}
}
As mentioned in the comments by #Ruben Danielyan, the Illuminate\Routing\Redirector has some methods that you may find useful
Redirector.php
/**
* Create a new redirect response to the previously intended location.
*
* #param string $default
* #param int $status
* #param array $headers
* #param bool|null $secure
* #return \Illuminate\Http\RedirectResponse
*/
public function intended($default = '/', $status = 302, $headers = [], $secure = null)
{
$path = $this->session->pull('url.intended', $default);
return $this->to($path, $status, $headers, $secure);
}
/**
* Set the intended url.
*
* #param string $url
* #return void
*/
public function setIntendedUrl($url)
{
$this->session->put('url.intended', $url);
}

option to send copy of customer welcome email to another address mail in magento 2

i need to send a copy of welcome email to specific mail.
what i did is i tried to create module to do it programmatically, i created a overrid that handle execute CreatePost.php but it sent before.
<?php
/**
* Copyright © Cinemanext, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Cinemanext\ForceLogin\Controller\Account;
use \Magento\Framework\App\ObjectManager;
/**
* #SuppressWarnings(PHPMD.TooManyFields)
* #SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class CreatePost extends \Magento\Customer\Controller\Account\CreatePost
{
}
this option exist in order mail, you can send copy to specific email.
how i can add same function to welcome mail.
Try below code
<?php
namespace Cinemanext\ForceLogin\Controller\Account;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Customer\Model\CustomerFactory;
use Magento\Customer\Model\AddressFactory;
use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\Escaper;
use Magento\Framework\UrlFactory;
use Magento\Customer\Model\Session;
use Magento\Customer\Model\Registration;
use Magento\Framework\Data\Form\FormKey\Validator;
use Magento\Framework\App\ObjectManager;
class CreatePost extends \Magento\Framework\App\Action\Action
{
/**
* #var \Magento\Store\Model\StoreManagerInterface
*/
protected $storeManager;
/**
* #var \Magento\Customer\Model\CustomerFactory
*/
protected $customerFactory;
/**
* #var \Magento\Customer\Model\AddressFactory
*/
protected $addressFactory;
/**
* #var \Magento\Framework\Message\ManagerInterface
*/
protected $messageManager;
/**
* #var \Magento\Framework\Escaper
*/
protected $escaper;
/**
* #var \Magento\Framework\UrlFactory
*/
protected $urlFactory;
/**
* #var \Magento\Customer\Model\Session
*/
protected $session;
/**
* #var Magento\Framework\Data\Form\FormKey\Validator
*/
private $formKeyValidator;
/**
* #param Context $context
* #param StoreManagerInterface $storeManager
* #param CustomerFactory $customerFactory
* #param AddressFactory $addressFactory
* #param ManagerInterface $messageManager
* #param Escaper $escaper
* #param UrlFactory $urlFactory
* #param Session $session
* #param Validator $formKeyValidator
*/
public function __construct(
Context $context,
StoreManagerInterface $storeManager,
CustomerFactory $customerFactory,
AddressFactory $addressFactory,
ManagerInterface $messageManager,
Escaper $escaper,
UrlFactory $urlFactory,
Session $session,
Validator $formKeyValidator = null
)
{
$this->storeManager = $storeManager;
$this->customerFactory = $customerFactory;
$this->addressFactory = $addressFactory;
$this->messageManager = $messageManager;
$this->escaper = $escaper;
$this->urlModel = $urlFactory->create();
$this->session = $session;
$this->formKeyValidator = $formKeyValidator ?: ObjectManager::getInstance()->get(Validator::class);
// messageManager can also be set via $context
// $this->messageManager = $context->getMessageManager();
parent::__construct($context);
}
/**
* Default customer account page
*
* #return void
*/
public function execute()
{
/** #var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultRedirectFactory->create();
// if ($this->session->isLoggedIn() || !$this->registration->isAllowed()) {
// $resultRedirect->setPath('*/*/');
// return $resultRedirect;
// }
// check if the form is actually posted and has the proper form key
if (!$this->getRequest()->isPost() || !$this->formKeyValidator->validate($this->getRequest())) {
$url = $this->urlModel->getUrl('*/*/create', ['_secure' => true]);
$resultRedirect->setUrl($this->_redirect->error($url));
return $resultRedirect;
}
$websiteId = $this->storeManager->getWebsite()->getWebsiteId();
$firstName = 'John';
$lastName = 'Doe';
$email = 'johndoe4#example.com';
$password = 'Test1234';
// instantiate customer object
$customer = $this->customerFactory->create();
$customer->setWebsiteId($websiteId);
// check if customer is already present
// if customer is already present, then show error message
// else create new customer
if ($customer->loadByEmail($email)->getId()) {
//echo 'Customer with the email ' . $email . ' is already registered.';
$message = __(
'There is already an account with this email address "%1".',
$email
);
// #codingStandardsIgnoreEnd
$this->messageManager->addError($message);
} else {
try {
// prepare customer data
$customer->setEmail($email);
$customer->setFirstname($firstName);
$customer->setLastname($lastName);
// set null to auto-generate password
$customer->setPassword($password);
// set the customer as confirmed
// this is optional
// comment out this line if you want to send confirmation email
// to customer before finalizing his/her account creation
$customer->setForceConfirmed(true);
// save data
$customer->save();
// save customer address
// this is optional
// you can skip saving customer address while creating the customer
$customerAddress = $this->addressFactory->create();
$customerAddress->setCustomerId($customer->getId())
->setFirstname($firstName)
->setLastname($lastName)
->setCountryId('US')
->setRegionId('12') // optional, depends upon Country, e.g. USA
->setRegion('California') // optional, depends upon Country, e.g. USA
->setPostcode('90232')
->setCity('Culver City')
->setTelephone('888-888-8888')
->setFax('999')
->setCompany('XYZ')
->setStreet(array(
'0' => 'Your Customer Address 1', // compulsory
'1' => 'Your Customer Address 2' // optional
))
->setIsDefaultBilling('1')
->setIsDefaultShipping('1')
->setSaveInAddressBook('1');
try {
// save customer address
$customerAddress->save();
} catch (Exception $e) {
$this->messageManager->addException($e, __('We can\'t save the customer address.'));
}
// send welcome email to the customer
$customer->sendNewAccountEmail();
//echo 'Customer with the email ' . $email . ' is successfully created.';
$this->messageManager->addSuccess(
__(
'Customer account with email %1 created successfully.',
$email
)
);
$url = $this->urlModel->getUrl('*/*/create', ['_secure' => true]);
$resultRedirect->setUrl($this->_redirect->success($url));
//$resultRedirect->setPath('*/*/');
return $resultRedirect;
} catch (StateException $e) {
$url = $this->urlModel->getUrl('customer/account/forgotpassword');
// #codingStandardsIgnoreStart
$message = __(
'There is already an account with this email address. If you are sure that it is your email address, click here to get your password and access your account.',
$url
);
// #codingStandardsIgnoreEnd
$this->messageManager->addError($message);
} catch (InputException $e) {
$this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
foreach ($e->getErrors() as $error) {
$this->messageManager->addError($this->escaper->escapeHtml($error->getMessage()));
}
} catch (LocalizedException $e) {
$this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
} catch (\Exception $e) {
$this->messageManager->addException($e, __('We can\'t save the customer.'));
}
}
$this->session->setCustomerFormData($this->getRequest()->getPostValue());
$defaultUrl = $this->urlModel->getUrl('*/*/create', ['_secure' => true]);
$resultRedirect->setUrl($this->_redirect->error($defaultUrl));
return $resultRedirect;
}
}

Laravel testing Failed asserting that two strings are equal

I am very new to testing, but have now found it essential to automate my testing.
I have a test that is working fine up until it gets to the link '/cart' it gets to the link '/cart' no problem, but any other link I try to click afterwards always ends up back at the cart.
here is my error after trying to navigate away from the cart.
Failed asserting that two strings are equal.
--- Expected
+++ Actual
## ##
-'http://ngwenya-mtb.dev/events'
+'http://ngwenya-mtb.dev/cart'
And here is my test script
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase {
//use Illuminate\Foundation\Testing\WithoutMiddleware;
//use DatabaseTransactions;
//use withoutMiddleware;
//use DatabaseMigrations;
/**
*
* A basic functional test example.
* Please choose a unique email address for your new participant
* #return void
*/
public function testNewUserRegistration() {
$this->visit('http://ngwenya-mtb.dev/')
// View Event
->click('View event details')
->seePageIs('/event?id=30')
->click('#enter-race47')
->press('Enter yourself to this race')
->seePageIs('/events/courses/register/addtocart')
//->withSession(['This email is already registered' => 'alert-danger'])
/////////////////////////////////////////////
// Fill the register for for new user
/////////////////////////////////////////////
->type('Bingo', 'first_name')
->type('11111111', 'password')
->type('11111111', 'password_confirmation')
->type(''.substr(md5(time()), 0, 12).'#tesing.com', 'email')
//->check('terms')
->select('Male', 'gender')
->select('1985', 'year')
->select('07', 'month')
->select('21', 'day')
->select('Small', 'shirt_size')
->select('Swaziland ID', 'id_type')
->type('badassnumber', 'id_number')
->select('Swazi', 'nationality')
//Contact details Physical
->type('Dawlish', 'town_physical')
->select('Swaziland', 'country_physical')
->type('864741', 'phone_cell')
//Emergency contact details 1
->type('Simon', 'emergency_contact_1')
->type('Brother', 'emergency_relationship_1')
->type('864741', 'emergency_phone_1');
$this->press('Register');
$this->seePageIs('/cart');
/////////////////////////////////////////////
// Add a new user
/////////////////////////////////////////////
$this->visit('http://ngwenya-mtb.dev/');
$this->click('#events-link')
->seePageIs('/events');
dd($this->response->getContent());exit;
$this->click('#event-30');
$this->seePageIs('/event?id=30');
$this->click('#enter-race48');
$this->press('Enter someone else to this race');
$this->seePageIs('/events/courses/register/addtocart');
}
}
Everything is working fine up until this comment
/////////////////////////////////////////////
// Add a new user
/////////////////////////////////////////////
Here is my Registration controller
<?php
namespace App\Http\Controllers;
use Vinkla\Hashids\HashidsManager;
use Illuminate\Routing\Controller as BaseController;
use Sentinel\FormRequests\RegisterRequest;
use Sentinel\FormRequests\EmailRequest;
use Sentinel\FormRequests\ResetPasswordRequest;
use Sentinel\Repositories\Group\SentinelGroupRepositoryInterface;
use Sentinel\Repositories\User\SentinelUserRepositoryInterface;
use Sentinel\Traits\SentinelRedirectionTrait;
use Sentinel\Traits\SentinelViewfinderTrait;
use Sentry;
use View;
use Request;
use Event;
use Redirect;
use Session;
use Config;
use App\Models\Users;
use Illuminate\Support\Facades\Input;
use Gloudemans\Shoppingcart\Facades\Cart;
class RegistrationController extends BaseController
{
/**
* Traits
*/
use SentinelRedirectionTrait;
use SentinelViewfinderTrait;
/**
* Constructor
*/
public function __construct(
SentinelUserRepositoryInterface $userRepository,
SentinelGroupRepositoryInterface $groupRepository,
HashidsManager $hashids
) {
$this->userRepository = $userRepository;
$this->groupRepository = $groupRepository;
$this->hashids = $hashids;
}
/**
* Show the registration form, if registration is allowed
*
* #return Response
*/
public function registration()
{
// Is this user already signed in? If so redirect to the post login route
if (Sentry::check()) {
return $this->redirectTo('session_store');
}
//If registration is currently disabled, show a message and redirect home.
if (! config('sentinel.registration', false)) {
return $this->redirectTo(['route' => 'home'], ['error' => trans('Sentinel::users.inactive_reg')]);
}
// All clear - show the registration form.
return $this->viewFinder(config('sentinel.view.user_register', 'Sentinel::users.register'));
}
/**
* Process a registration request
*
* #return Response
*/
public function register(RegisterRequest $request)
{
// Gather input
$data = $request->all();
// collect cart items
$email = Input::get('email');
$course_id = Input::get('course_id');
$event_name = Input::get('event_name');
$entry_fee = Input::get('entry_fee');
// check user exists
if (Users::where('email', '=', $email)->exists()) {
// user found
$request->session()->flash('alert-danger', 'Warning: This email is already registered.');
Input::flash();
return View::make('sentinel.users.register')
->with('course_id',$course_id)
->with('event_name',$event_name)
->with('entry_fee',$entry_fee);
}
// Add user and course to cart
if ($course_id) {
$firstUserRowId = Cart::add($course_id, $event_name , 1, $entry_fee, [
'first_name' => Input::get('first_name'),
'last_name' => Input::get('last_name'),
'email' => Input::get('email'),
'no_email' => 0,
'master_user' => 1,
'gender' => Input::get('gender'),
'dob' => Input::get('dob'),
'shirt_size' => Input::get('shirt_size'),
'id_type' => Input::get('id_type'),
'id_number' => Input::get('id_number'),
'nationality' => Input::get('nationality'),
'phone_cell' => Input::get('phone_cell'),
'town_physical' => Input::get('town_physical'),
'country_physical' => Input::get('country_physical'),
'emergency_contact_1' => Input::get('emergency_contact_1'),
'emergency_relationship_1' => Input::get('emergency_relationship_1'),
'emergency_phone_1' => Input::get('emergency_phone_1'),
]);
}
// get email from request
$email = $request->only('email');
foreach ($email as $userModel) {}
// Edit date of birth from request
$year = Input::get('year');
$month = Input::get('month');
$day = Input::get('day');
$dob = $year.'-'.$month.'-'.$day;
$data['dob'] = $dob;
// Attempt Registration
$result = $this->userRepository->store($data);
// Log user in
FunctionsController::loginUser($userModel);
// It worked! Use config to determine where we should go.
return $this->redirectViaResponse('registration_complete', $result);
}
/**
* Activate a new user
*
* #param int $id
* #param string $code
*
* #return Response
*/
public function activate($hash, $code)
{
// Decode the hashid
$id = $this->hashids->decode($hash)[0];
// Attempt the activation
$result = $this->userRepository->activate($id, $code);
// It worked! Use config to determine where we should go.
return $this->redirectViaResponse('registration_activated', $result);
}
/**
* Show the 'Resend Activation' form
*
* #return View
*/
public function resendActivationForm()
{
return $this->viewFinder('Sentinel::users.resend');
}
/**
* Process resend activation request
* #return Response
*/
public function resendActivation(EmailRequest $request)
{
// Resend the activation email
$result = $this->userRepository->resend(['email' => e($request->get('email'))]);
// It worked! Use config to determine where we should go.
return $this->redirectViaResponse('registration_resend', $result);
}
/**
* Display the "Forgot Password" form
*
* #return \Illuminate\View\View
*/
public function forgotPasswordForm()
{
return $this->viewFinder('Sentinel::users.forgot');
}
/**
* Process Forgot Password request
* #return Response
*/
public function sendResetPasswordEmail(EmailRequest $request)
{
// Send Password Reset Email
$result = $this->userRepository->triggerPasswordReset(e($request->get('email')));
// It worked! Use config to determine where we should go.
return $this->redirectViaResponse('registration_reset_triggered', $result);
}
/**
* A user is attempting to reset their password
*
* #param $id
* #param $code
*
* #return Redirect|View
*/
public function passwordResetForm($hash, $code)
{
// Decode the hashid
$id = $this->hashids->decode($hash)[0];
// Validate Reset Code
$result = $this->userRepository->validateResetCode($id, $code);
if (! $result->isSuccessful()) {
return $this->redirectViaResponse('registration_reset_invalid', $result);
}
return $this->viewFinder('Sentinel::users.reset', [
'hash' => $hash,
'code' => $code
]);
}
/**
* Process a password reset form submission
*
* #param $hash
* #param $code
* #return Response
*/
public function resetPassword(ResetPasswordRequest $request, $hash, $code)
{
// Decode the hashid
$id = $this->hashids->decode($hash)[0];
// Gather input data
$data = $request->only('password', 'password_confirmation');
// Change the user's password
$result = $this->userRepository->resetPassword($id, $code, e($data['password']));
// It worked! Use config to determine where we should go.
return $this->redirectViaResponse('registration_reset_complete', $result);
}
}
It seems that when you click and a your link "Register" your redirection fail, so check if you have multiple "Register" links/buttons, and if they are pointing to the right URL
And for easiest debugging, you should make less assertions per Test, you will gain in visibility :)

Resources