Codeception Cest Mockery - codeception

public function tryRegister(FunctionalTester $I){
//arrange
$I->disableEvents();
$user = $I->factory()->instance(User::class);
$new_password = str_random(10);
// prevent validation error on captcha
\NoCaptcha::shouldReceive('verifyResponse')
->once()
->andReturn(true);
// provide hidden input for your 'required' validation
\NoCaptcha::shouldReceive('display')
->zeroOrMoreTimes()
->andReturn('<input type="hidden" name="g-recaptcha-response" alue="1" />');
//act
$I->amOnPage(route('auth.register'));
$I->fillField("username",$user->username);
$I->fillField("name",$user->name);
$I->fillField("email",$user->email);
$I->fillField("password",$new_password);
$I->fillField("password_confirmation",$new_password);
$I->click('Register');
$I->seeCurrentRouteIs('auth.login');
//$I->seeEventTriggered(UserRegistered::class);
//assert
$registered_user = \UserRepo::findByField('email',$user->email)->first();
$I->assertFalse(\Auth::check());
$I->assertTrue($user->name == $registered_user->name);
$I->assertTrue($user->username == $registered_user->username);
$I->assertTrue($user->email == $registered_user->email);
$I->assertTrue(\Hash::check($new_password,$registered_user->password));
}
I have this functional test I want to run but, it's failing because of the recapcha embedded into the page. My mocked objects don't seem to have any affect. Am I going about this in the wrong fashion?

Looks like you have to use haveBinding
$I->haveBinding('captcha',function(){
$no_captcha = \Mockery::mock(Anhskohbo\NoCaptcha\NoCaptcha::class);
// prevent validation error on captcha
$no_captcha->shouldReceive('verifyResponse')
->andReturn(true);
// provide hidden input for your 'required' validation
$no_captcha->shouldReceive('display')
->zeroOrMoreTimes()
->andReturn('<input type="hidden" name="g-recaptcha-response" value="1" />');
return $no_captcha;
});

Related

Paypal Php Sdk - NotifyUrl is not a fully qualified URL Error

I have this code
$product_info = array();
if(isset($cms['site']['url_data']['product_id'])){
$product_info = $cms['class']['product']->get($cms['site']['url_data']['product_id']);
}
if(!isset($product_info['id'])){
/*
echo 'No product info.';
exit();
*/
header_url(SITE_URL.'?subpage=user_subscription#xl_xr_page_my%20account');
}
$fee = $product_info['yearly_price_end'] / 100 * $product_info['fee'];
$yearly_price_end = $product_info['yearly_price_end'] + $fee;
$fee = ($product_info['setup_price_end'] / 100) * $product_info['fee'];
$setup_price_end = $product_info['setup_price_end'] + $fee;
if(isset($_SESSION['discountcode_amount'])){
$setup_price_end = $setup_price_end - $_SESSION['discountcode_amount'];
unset($_SESSION['discountcode_amount']);
}
$error = false;
$plan_id = '';
$approvalUrl = '';
$ReturnUrl = SITE_URL.'payment/?payment_type=paypal&payment_page=process_agreement';
$CancelUrl = SITE_URL.'payment/?payment_type=paypal&payment_page=cancel_agreement';
$now = $cms['date'];
$now->modify('+5 minutes');
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
$cms['options']['plugin_paypal_clientid'], // ClientID
$cms['options']['plugin_paypal_clientsecret'] // ClientSecret
)
);
use PayPal\Api\ChargeModel;
use PayPal\Api\Currency;
use PayPal\Api\MerchantPreferences;
use PayPal\Api\PaymentDefinition;
use PayPal\Api\Plan;
use PayPal\Api\Patch;
use PayPal\Api\PatchRequest;
use PayPal\Common\PayPalModel;
use PayPal\Api\Agreement;
use PayPal\Api\Payer;
use PayPal\Api\ShippingAddress;
// Create a new instance of Plan object
$plan = new Plan();
// # Basic Information
// Fill up the basic information that is required for the plan
$plan->setName($product_info['name'])
->setDescription($product_info['desc_text'])
->setType('fixed');
// # Payment definitions for this billing plan.
$paymentDefinition = new PaymentDefinition();
// The possible values for such setters are mentioned in the setter method documentation.
// Just open the class file. e.g. lib/PayPal/Api/PaymentDefinition.php and look for setFrequency method.
// You should be able to see the acceptable values in the comments.
$setFrequency = 'Year';
//$setFrequency = 'Day';
$paymentDefinition->setName('Regular Payments')
->setType('REGULAR')
->setFrequency($setFrequency)
->setFrequencyInterval("1")
->setCycles("999")
->setAmount(new Currency(array('value' => $yearly_price_end, 'currency' => $cms['session']['client']['currency']['iso_code'])));
// Charge Models
$chargeModel = new ChargeModel();
$chargeModel->setType('SHIPPING')
->setAmount(new Currency(array('value' => 0, 'currency' => $cms['session']['client']['currency']['iso_code'])));
$paymentDefinition->setChargeModels(array($chargeModel));
$merchantPreferences = new MerchantPreferences();
// ReturnURL and CancelURL are not required and used when creating billing agreement with payment_method as "credit_card".
// However, it is generally a good idea to set these values, in case you plan to create billing agreements which accepts "paypal" as payment_method.
// This will keep your plan compatible with both the possible scenarios on how it is being used in agreement.
$merchantPreferences->setReturnUrl($ReturnUrl)
->setCancelUrl($CancelUrl)
->setAutoBillAmount("yes")
->setInitialFailAmountAction("CONTINUE")
->setMaxFailAttempts("0")
->setSetupFee(new Currency(array('value' => $setup_price_end, 'currency' => $cms['session']['client']['currency']['iso_code'])));
$plan->setPaymentDefinitions(array($paymentDefinition));
$plan->setMerchantPreferences($merchantPreferences);
// ### Create Plan
try {
$output = $plan->create($apiContext);
} catch (Exception $ex){
die($ex);
}
echo $output->getId().'<br />';
echo $output.'<br />';
Been working with paypal php sdk for some days now and my code stop working.
So i went back to basic and i am still getting the same damn error.
I am trying to create a plan for subscription but getting the following error:
"NotifyUrl is not a fully qualified URL"
I have no idea how to fix this as i dont use NotfifyUrl in my code?
Could be really nice if anyone had an idea how to fix this problem :)
Thanks
PayPal did a update to their API last night which has caused problem within their SDK.
They are sending back null values in their responses.
I MUST stress the error is not on sending the request to PayPal, but on processing their response.
BUG Report : https://github.com/paypal/PayPal-PHP-SDK/issues/1151
Pull Request : https://github.com/paypal/PayPal-PHP-SDK/pull/1152
Hope this helps, but their current SDK is throwing exceptions.
Use below simple fix.
Replace below function in vendor\paypal\rest-api-sdk-php\lib\PayPal\Api\MerchantPreferences.php
public function setNotifyUrl($notify_url)
{
if(!empty($notify_url)){
UrlValidator::validate($notify_url, "NotifyUrl");
}
$this->notify_url = $notify_url;
return $this;
}
If you get the same error for return_url/cancel_url, add the if condition as above.
Note: This is not a permanent solution, you can use this until getting the update from PayPal.
From the GitHub repo for the PayPal PHP SDK, I see that the error you mentioned is thrown when MerchantPreferences is not given a valid NotifyUrl. I see you're setting the CancelUrl and ReturnUrl, but not the NotifyUrl. You may simply need to set that as well, i.e.:
$NotifyUrl = (some url goes here)
$obj->setNotifyUrl($NotifyUrl);
Reason behind it!
error comes from.
vendor\paypal\rest-api-sdk-php\lib\PayPal\Validation\UrlValidator.php
line.
if (filter_var($url, FILTER_VALIDATE_URL) === false) {
throw new \InvalidArgumentException("$urlName is not a fully qualified URL");
}
FILTER_VALIDATE_URL: according to this php function.
INVALID URL: "http://cat_n.domain.net.in/"; // IT CONTAIN _ UNDERSCORE.
VALID URL: "http://cat-n.domain.net.in/"; it separated with - dash
here you can dump your url.
vendor\paypal\rest-api-sdk-php\lib\PayPal\Validation\UrlValidator.php
public static function validate($url, $urlName = null)
{
var_dump($url);
}
And then check this here: https://www.w3schools.com/PHP/phptryit.asp?filename=tryphp_func_validate_url
you can check here what character will reason for invalid.

Passing variables to fpdf

I have a problem with passing variables to fpdf. First script is getting post text sent to filtering class, the class is returning filtered POST-s as a 2 element array. First script looks like this:
include('service.php');
include('pdf.php');
$pdf_filter = new Pdf_filter;
$filter = $pdf_filter->pdfFilter();
var_dump($filter);
extract($filter);
I'm extracting $filter array to get variables from it (filtering script is creating variables of the POST that are sent and I can echo them so I don't know if this is even necessary).
The second script looks like this:
require('E:\Xampp\php\fpdf181\fpdf.php');
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',12);
$pdf->Cell(195,5, $tytul, 0,1,'C');
$pdf->Cell(195,5, $petycja, 0,1,'C');
$pdf->Output();
and I'm getting this error:
Notice: Undefined variable: tytul in E:\Xampp\htdocs\php\bazy_danych\obiektowe\my\pdf.php on line 10
Notice: Undefined variable: petycja in E:\Xampp\htdocs\php\bazy_danych\obiektowe\my\pdf.php on line 11
Fatal error: Uncaught exception 'Exception' with message 'FPDF error: Some data has already been output, can't send PDF file' in E:\Xampp\php\fpdf181\fpdf.php:271
Stack trace: #0 E:\Xampp\php\fpdf181\fpdf.php(1063): FPDF->Error('Some data has a...')
#1 E:\Xampp\php\fpdf181\fpdf.php(999): FPDF->_checkoutput()
#2 E:\Xampp\htdocs\php\bazy_danych\obiektowe\my\pdf.php(12): FPDF->Output()
#3 E:\Xampp\htdocs\php\bazy_danych\obiektowe\my\test.php(3): include('E:\\Xampp\\htdocs...')
#4 {main} thrown in E:\Xampp\php\fpdf181\fpdf.php on line 271
How should I pass the variables? Interesting: it works if I use the unfiltered $_POST with the following code:
require('E:\Xampp\php\fpdf181\fpdf.php');
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',12);
$pdf->Cell(195,5, $_POST['tytul'], 0,1,'C');
$pdf->Cell(195,5, $_POST['petycja'], 0,1,'C');
$pdf->Output();
EDIT: I will post the initial form and filtering function:
Form:
<form action="test.php" method="POST">
Wpisz tytuł petycji (35 znaków):<br>
<input type="text" name="tytul" maxlength="35" size="35" placeholder="Tytuł petycji" required><br>
Wpisz treść petycji (500 znaków):<br>
<textarea name="petycja" maxlength="500" rows="4" cols="50" placeholder="Treść petycji" required></textarea><br>
<input type="submit" value="Napisz petycje">
</form>
Filtering function:
class Pdf_filter{
protected $title;
protected $text;
public function pdfFilter(){
if (isset($_POST)){
foreach ($_POST as $key => $val) {
$filterVal = strip_tags($val);
$filterVal = htmlspecialchars($filterVal);
$filterVal = stripslashes($filterVal);
$filterVal = str_replace("\\", "", $filterVal);
$filter = array($key => $filterVal);
foreach ($filter as $key => $val) {
echo "[$$key]";
echo "$val<br>";
${$key} = $val;
}
}
if(!preg_match("/^[\sa-zA-ZĄĆĘŁŃÓŚŹŻąćęłńóśźż0-9-_,.:\'?()]+$/", $tytul)){
echo "Niedozwolone znaki $tytul!";
exit();
}
elseif(!preg_match("/^[\sa-zA-ZĄĆĘŁŃÓŚŹŻąćęłńóśźż0-9-_,.:\'?()]+$/", $petycja)){
echo "Niedozwolone znaki $petycja!";
exit();
}
else{
return $filter = array('tytul'=>$tytul,'petycja'=>$petycja);
}
}
else{
echo "Proszę wypełnić wszytskie pola!";
}
}
}
Well I am dumb. The problem was related with class variables. Code that happened to work for me:
class Pdf extends FPDF{
protected $filter;
protected $tytul;
protected $petycja;
public function __construct($filter){
$this->filter = extract($filter);
$this->tytul = $tytul;
$this->petycja = $petycja;
}
public function tytul(){
return $this->tytul;
}
public function petycja(){
return $this->petycja;
}
public function dokument(){
parent::__construct();
$this->AddPage();
$this->SetFont('Arial','B',15);
$this->Cell(195,5, $this->tytul, 0,1,'C');
$this->Cell(195,5, $this->petycja, 0,1,'C');
$this->Output();
}
}
Now I need to think of a way to display polish symbols in fpdf and line breaks (but that maybe done with text editor isntead of just textbox).

whmcs server-side pagination

I'm working with WHMCS and I notice that list views are not working well.
That's because in the clientarea's list views I have tousans thousands of records to display and the DataTables is crashing.
Is there a way to paginate from the server-side? I will appreciate any idea.
Here is an idea: let' say you are viewing the Domains list page, you can use ClientAreaPage hook to create a variable to load a "paged" copy of domains:
add_hook( 'ClientAreaPage', 1, function( $vars )
{
$myVars = array();
if (App::getCurrentFilename() == 'clientarea' && isset($_GET['action']) && $_GET['action'] == 'domains') {
$domains2 = array();
foreach($vars['domains'] as $k => $domain) {
if ($k < 3) {//your code to handle pagination
$domains2[] = $domain;
}
}
$myVars['domains2'] = $domains2;
$myVars['currentpage'] = 1;
}
return $myVars;
});
In clientareadomains.tpl (template file), you need to change $domains to $domains2:
{foreach key=num item=domain from=$domains2}
Of course, it is not simple task, you need to handle pagination in the hook and the tpl files.
Hope it helps.

How To Validate a Devexpress Textbox inside an Devexpress Gridview in Javasacript

i am not able to figure out why the focusout validation that uses the assigned regex is not working in the devex textbox. when i am using the textbox out of the grid it starts working as required. Kindly suggest the solution.
#Html.DevExpress().GridView(settings =>
{
settings.Columns.Add(column =>
{
column.FieldName = "InYear";
column.Caption = "In Year";
column.Width = 100;
column.ColumnType = MVCxGridViewColumnType.TextBox;
column.SortOrder = DevExpress.Data.ColumnSortOrder.Ascending; // Default
column.SortIndex = 1;
column.CellStyle.HorizontalAlign = HorizontalAlign.Left;
var txtProperties = column.PropertiesEdit as TextBoxProperties;
txtProperties.Width = Unit.Percentage(100);
txtProperties.MaxLength = 4;
txtProperties.DisplayFormatInEditMode = true;
txtProperties.ValidationSettings.RequiredField.IsRequired = true;
txtProperties.ValidationSettings.ValidateOnLeave = true;
txtProperties.ValidationSettings.RegularExpression.ValidationExpression = #"\d{4}";
txtProperties.ValidationSettings.RegularExpression.ErrorText = "Expected format is: YYYY";
txtProperties.ClientSideEvents.ValueChanged = String.Format("function (s, e) {{ OnValueChanged(s, e, '{0}', {1}); }}", "InYear", "0");
column.SetDataItemTemplateContent(c =>
{
if (!(bool)DataBinder.Eval(c.DataItem, "ReadOnly"))
{
Html.DevExpress().TextBox(txtSettings =>
{
txtSettings.Name = "txtInYear_" + c.KeyValue.ToString();
txtSettings.Width = Unit.Percentage(100);
txtSettings.Properties.MaxLength = 4;
txtSettings.Properties.DisplayFormatInEditMode = true;
txtSettings.Properties.ValidationSettings.ValidateOnLeave = true;
txtSettings.Properties.ValidationSettings.ValidationGroup = c.KeyValue.ToString();
txtSettings.Properties.ValidationSettings.RegularExpression.ValidationExpression = #"[0-9]{4}";
txtSettings.Properties.ValidationSettings.RegularExpression.ErrorText = "Expected format is: YYYY";
txtSettings.Properties.ClientSideEvents.ValueChanged = String.Format("function (s, e) {{ OnValueChanged(s, e, '{0}', {1}); }}", c.Column.FieldName, c.KeyValue);
}).Bind(DataBinder.Eval(c.DataItem, c.Column.FieldName)).Render();
}
else
Html.DevExpress().Label(lblSettings =>
{
lblSettings.Name = "lblInYear_" + c.KeyValue.ToString();
lblSettings.Width = Unit.Percentage(100);
}).Bind(DataBinder.Eval(c.DataItem, c.Column.FieldName).ToString()).Render();
});
});
}).Bind(Model).GetHtml()
EDIT : I am using a button out of the gridview to trigger the update command. How can i trigger only validate event of the EditRow. Please view attached image.
Thanks in advance
When do you need to validate the TextBox? In browser mode or when editing? Currently your TextBox is required when you edit a row. Try to set the IsRequired property for your TextBox in the template as well.
txtSettings.Properties.ValidationSettings.RequiredField.IsRequired = true;
It should work.
Go through this thread - MVC GridView - Client validation in default EditForm.
In case if you are working with ajax form then i suggest you use
built-in validation instead:GridView - How to use Microsoft
validation with an AJAX form to validate the Model properties on the
client side.
More References:
GridView - How to enable the client-side validation in the Edit Form
How to correctly enable Model, Unobtrusive or jQuery Client validation
Client Validation in MVC3 with Gridview Template Form
After a long struggle i got the following answer :
Assign a validation group property to the nested controls as below
txtSettings.Properties.ValidationSettings.ValidationGroup = c.KeyValue.ToString();
Iterate through the keyvalues on client side and call the devexpress validate function ASPxClientEdit.ValidateEditorsInContainer as following, i represent validation group name
var isValid =!ASPxClientEdit.ValidateEditorsInContainer(GridName.GetMainElement(), i)
My approach might not be the best but it helped me a lot, i think this would also be helpful for others having the same issue.
Thanks.....

Use of SPStatefulLongOperation

Can someone give me an example of the use of SPStatefulLongOperation? It's very poorly documented.
Here's an example of code I've just used. It applies a ThmxTheme (selectedTheme) to all SPWebs in an SPSite (site).
SPStatefulLongOperation.Begin(
"Applying theme to sites.",
"<span id='trailingSpan'></span>",
(op) =>
{
op.Run((opState) =>
{
for (int i = 0; i < site.AllWebs.Count; i++)
{
// Update status.
opState.Status = String.Format(
"<script type='text/javascript'>document.all.item('trailingSpan').innerText = '{0} ({1} of {2})';</script>",
site.AllWebs[i].Title,
i + 1,
site.AllWebs.Count);
// Set the theme.
selectedTheme.ApplyTo(site.AllWebs[i], true);
}
});
op.End(System.Web.HttpContext.Current.Request.UrlReferrer.ToString());
});
Note that the current value of opState.State is appended to the client's HTML (via HttpContext.Current.Response.Write and .Flush) every second. Thus you don't want to send any status message directly; you want to send some JavaScript that will update an existing status element on the page. (Here, the trailingSpan element.)