Required Field Missing Error on Apex Trigger Test in Salesforce - testing

I am failing my apex code test with the following error:
"System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Opportunity__c]: [Opportunity__c]
Stack Trace: Class.Integromat_GetAuroraArrayInfoTest.testTrigger: line 68, column 1"
Arrays_from_Aurora__c is a Child Relationship to Opportunity. Opportunity__c exists both as an opportunity field as well as an Arrays_from_Aurora__c field.
How do I fix this? Thank You!
Here is my test:
#isTest
public class Integromat_GetAuroraArrayInfoTest {
static SObject mock(String sobjectName) {
SObjectType t = Schema.getGlobalDescribe().get(sobjectName);
SObject o = t.newSobject();
Map<String, Schema.SObjectField> m = t.getDescribe().fields.getMap();
for (String fieldName : m.keySet()) {
DescribeFieldResult f = m.get(fieldName).getDescribe();
if (!f.isNillable() && f.isCreateable() && !f.isDefaultedOnCreate()) {
if (f.getType() == DisplayType.Boolean) {
o.put(f.getName(), false);
}
else if (f.getType() == DisplayType.Currency) {
o.put(f.getName(), 0);
}
else if (f.getType() == DisplayType.Date) {
o.put(f.getName(), Date.today());
}
else if (f.getType() == DisplayType.DateTime) {
o.put(f.getName(), System.now());
}
else if (f.getType() == DisplayType.Double) {
o.put(f.getName(), 0.0);
}
else if (f.getType() == DisplayType.Email) {
o.put(f.getName(), 'foo#foo.com');
}
else if (f.getType() == DisplayType.Integer) {
o.put(f.getName(), 0);
}
else if (f.getType() == DisplayType.Percent) {
o.put(f.getName(), 0);
}
else if (f.getType() == DisplayType.Phone) {
o.put(f.getName(), '555-555-1212');
}
else if (f.getType() == DisplayType.String) {
o.put(f.getName(), 'TEST');
}
else if (f.getType() == DisplayType.TextArea) {
o.put(f.getName(), 'TEST');
}
else if (f.getType() == DisplayType.Time) {
o.put(f.getName(), System.now().time());
}
else if (f.getType() == DisplayType.URL) {
o.put(f.getName(), 'http://example.com');
}
else if (f.getType() == DisplayType.PickList) {
o.put(f.getName(), f.getPicklistValues()[0].getValue());
}
}
}
return o;
}
#isTest static void testTrigger() {
SObject o = mock('Arrays_from_Aurora__c');
Test.startTest();
insert o;
update o;
delete o;
Test.stopTest();
System.assertEquals(200, Webhook.response.getStatusCode());
}}

The error message tells you exactly what's wrong. There's a required field called Opportunity__c on the object Arrays_from_Aurora__c, and your code is not populating it.
The data mocking framework you are using doesn't populate relationship fields at all. It's not going to work for the majority of Salesforce data models for that reason. You'll need to either manually construct all of the data required, or use a more sophisticated mocking framework that allows you to construct relationships between records.

Related

How to detect postProcess PrestaShop 1.6 EDIT/ADD/DELETE mode?

How to detect postProcess PrestaShop 1.6 EDIT/ADD/DELETE mode?
I have code, something like this (detect edit not working...):
detect add - is ok
detect delete - is ok
<?php
public function postProcess()
{
if (Tools::isSubmit('deletems_admin_delivery_manager') && Tools::getValue('id_ms_admin_delivery_manager') != '')
{
$this->errors[] = Tools::displayError('DETECT DELETE');
} elseif (Tools::isSubmit('submitAdminDeliveryManager')) {
if (!$id_ms_admin_delivery_manager = Tools::getValue('id_ms_admin_delivery_manager')) {
$this->errors[] = Tools::displayError('DETECT ADD');
// this not working...
} elseif($id_ms_admin_delivery_manager = Tools::getValue('id_ms_admin_delivery_manager')) {
$this->errors[] = Tools::displayError('DETECT EDIT - NOT WORKING');
}
}
}
Replace = by == in your last condition.
Of course, you don't really need the third condition:
$obj = $this->loadObject(true);
if (Tools::isSubmit('deletems_admin_delivery_manager') && $obj->id)
{
$this->errors[] = Tools::displayError('DETECT DELETE');
} elseif (Tools::isSubmit('submitAdminDeliveryManager')) {
if (#$obj->id) {
$this->errors[] = Tools::displayError('DETECT EDIT');
} else {
$this->errors[] = Tools::displayError('DETECT ADD');
}
}
UPDATE:
also you can use the Prestashop methods:
public function processDelete()
{
//Delete
}
public function processSave()
{
//Add or Update
}
public function processAdd()
{
//Add
}
public function processUpdate()
{
//Update
}

How to move the snap position from center to left of RecycleView using SnapHelper?

I have an RecycleView that contains ImageViews and my question is how can i move the snap to be on the left side of the RecycleView instead of the center?
When i move the ImageViews they get snapped in the center and I can move them to the left or right inside that "snap window" by overriding the CalculateDistanceToFinalSnap method. I think I would now need to move that "snap window" to the left side of the RecycleView but I don't know how, or maybe there is another way, please help.
Here is a image of my problem, maybe it will help you to understand more clearly:
image
#Jessie Zhang -MSFT's solution works for me. The code was a little oddly formatted and I had some difficulty bringing it over. Here is the same solution (for a horizontal snap only) in Kotlin.
class StartSnapHelper: LinearSnapHelper() {
override fun calculateDistanceToFinalSnap(layoutManager: RecyclerView.LayoutManager, targetView: View): IntArray? {
return if (layoutManager.canScrollHorizontally()) {
val outer = mutableListOf<Int>()
outer.add(distanceToStart(targetView, getHorizontalHelper(layoutManager)))
outer.add(0)
outer.toIntArray()
} else {
super.calculateDistanceToFinalSnap(layoutManager, targetView)
}
}
override fun findSnapView(layoutManager: RecyclerView.LayoutManager?): View? {
return if (layoutManager is LinearLayoutManager) {
if (layoutManager.canScrollHorizontally()) {
getStartView(layoutManager, getHorizontalHelper(layoutManager))
} else {
super.findSnapView(layoutManager)
}
} else {
super.findSnapView(layoutManager)
}
}
private fun distanceToStart(targetView: View, helper: OrientationHelper): Int {
return helper.getDecoratedStart(targetView) - helper.startAfterPadding
}
private fun getStartView(layoutManager: RecyclerView.LayoutManager, orientationHelper: OrientationHelper): View? {
val firstChild = (layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
val isLastItem = (layoutManager.findLastCompletelyVisibleItemPosition() == layoutManager.itemCount - 1)
if (firstChild == RecyclerView.NO_POSITION || isLastItem) {
return null
}
val child = layoutManager.findViewByPosition(firstChild)
return if (orientationHelper.getDecoratedEnd(child) >= orientationHelper.getDecoratedMeasurement(child) / 2
&& orientationHelper.getDecoratedEnd(child) > 0) {
child;
} else {
if (layoutManager.findFirstCompletelyVisibleItemPosition() == layoutManager.itemCount -1) {
null
} else {
layoutManager.findViewByPosition(firstChild + 1)
}
}
}
private fun getHorizontalHelper(layoutManager: RecyclerView.LayoutManager): OrientationHelper {
return OrientationHelper.createHorizontalHelper(layoutManager)
}
}
I have achieved this function ,we juse need to create a class and extent class LinearSnapHelper and override method CalculateDistanceToFinalSnap and FindSnapView. You can check out the full demo here .
The main code is as follows:
public class StartSnapHelper: LinearSnapHelper
{
private OrientationHelper mVerticalHelper, mHorizontalHelper;
public StartSnapHelper()
{
}
public override void AttachToRecyclerView(RecyclerView recyclerView)
{
base.AttachToRecyclerView(recyclerView);
}
public override int[] CalculateDistanceToFinalSnap(RecyclerView.LayoutManager layoutManager, View targetView)
{
//return base.CalculateDistanceToFinalSnap(layoutManager, targetView);
int[] outer = new int[2];
if (layoutManager.CanScrollHorizontally())
{
outer[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager));
} else {
outer[0] = 0;
}
if (layoutManager.CanScrollVertically()) {
outer[1] = distanceToStart(targetView, getVerticalHelper(layoutManager));
} else {
outer[1] = 0;
}
return outer;
}
private int distanceToStart(View targetView, OrientationHelper helper)
{
return helper.GetDecoratedStart(targetView) - helper.StartAfterPadding;
}
public override View FindSnapView(RecyclerView.LayoutManager layoutManager)
{
if (layoutManager is LinearLayoutManager) {
if (layoutManager.CanScrollHorizontally())
{
return getStartView(layoutManager, getHorizontalHelper(layoutManager));
}
else
{
return getStartView(layoutManager, getVerticalHelper(layoutManager));
}
}
return base.FindSnapView(layoutManager);
}
private View getStartView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper)
{
if (layoutManager is LinearLayoutManager) {
int firstChild = ((LinearLayoutManager)layoutManager).FindFirstVisibleItemPosition();
bool isLastItem = ((LinearLayoutManager)layoutManager)
.FindLastCompletelyVisibleItemPosition()
== layoutManager.ItemCount - 1;
if (firstChild == RecyclerView.NoPosition || isLastItem)
{
return null;
}
View child = layoutManager.FindViewByPosition(firstChild);
if (helper.GetDecoratedEnd(child) >= helper.GetDecoratedMeasurement(child) / 2
&& helper.GetDecoratedEnd(child) > 0)
{
return child;
}
else
{
if (((LinearLayoutManager)layoutManager).FindLastCompletelyVisibleItemPosition()
== layoutManager.ItemCount - 1)
{
return null;
}
else
{
return layoutManager.FindViewByPosition(firstChild + 1);
}
}
}
return base.FindSnapView(layoutManager);
}
private OrientationHelper getVerticalHelper(RecyclerView.LayoutManager layoutManager)
{
if (mVerticalHelper == null)
{
mVerticalHelper = OrientationHelper.CreateVerticalHelper(layoutManager);
}
return mVerticalHelper;
}
private OrientationHelper getHorizontalHelper(RecyclerView.LayoutManager layoutManager)
{
if (mHorizontalHelper == null)
{
mHorizontalHelper = OrientationHelper.CreateHorizontalHelper(layoutManager);
}
return mHorizontalHelper;
}
}
And use like this:
SnapHelper snapHelperStart = new StartSnapHelper();
snapHelperStart.AttachToRecyclerView(recyclerView);

createUrl doesn't work correctly within extended CBaseUrlRule class

I made my own class that extends CBaseUrlRule to manage some sort of pages on site. Result class code is
class HotelUrlRule extends CBaseUrlRule {
public function parseUrl($manager,$request,$pathInfo,$rawPathInfo) {
if(isset($_GET['id'])) {
if (($_GET['id'] != 0) && ($pathInfo == 'hotel')) {
return 'hotel/index';
}
}
return false;
}
public function createUrl($manager,$route,$params,$ampersand) {
if ($route == 'hotel/index') {
Yii::import('application.controllers.SearchController');
$searcher = new SearchController($this, NULL);
$hotelRaw = $searcher->actionGetHotelInformation($_GET['id']);
$hotelRaw = $hotelRaw['GetHotelInformationResult'];
$hotelName = $hotelRaw['Name'];
$hotelName = preg_replace('%(\s)%', '-', $hotelName);
return 'hotel/' . $hotelName;
}
return false;
}
}
The condition in parseUrl ($_GET['id'] != 0) && ($pathInfo == 'hotel') returns 'true' and the condition in createUrl ($route == 'hotel/index') returns 'false'. Var_dump of $route is 'admin/auth'.
Why is it so? Any guesses?

How to write a custom FindElement routine in Selenium?

I'm trying to figure out how to write a custom FindElement routine in Selenium 2.0 WebDriver. The idea would be something like this:
driver.FindElement(By.Method( (ISearchContext) => {
/* examine search context logic here... */ }));
The anonymous method would examine the ISearchContext and return True if it matches; False otherwise.
I'm digging through the Selenium code, and getting a bit lost. It looks like the actual By.* logic is carried out server-side, not client side. That seems to be complicating matters.
Any suggestions?
I do a multi-staged search. I have a method that performs a try catch and then a method that gets the element. In theory you could do a try catch until instead of this way but I like this way better because of my setup.
public bool CheckUntil(IWebDriver driver, string selectorType, string selectorInfo)
{
int Timer = 160;
bool itemFound = false;
for (int i = 0; i < Timer; i++)
if(itemFound)
{
i = 0
}
else
{
Thread.Sleep(500);
if(selectorType.ToLower() == "id" && TryCatch(driver, selectorType, selectorInfo))
{
if(driver.FindElement(By.Id(selectorInfo).Displayed)
{
itemFound = true;
}
}
else if(selectorType.ToLower() == "tagname" && TryCatch(driver, selectorType, selectorInfo))
{
if(driver.FindElement(By.TagName(selectorInfo).Displayed)
{
itemFound = true;
}
}
}
return itemFound;
}
Here's my try catch method you can add as many different types as you want id, cssselector, xpath, tagname, classname, etc.
public bool TryCatch(IWebDriver driver, string selectorType, string selectorInfo)
{
bool ElementFound = false;
try
{
switch(selectorType)
{
case "id":
driver.FindElement(By.Id(selectorInfo);
break;
case "tagname":
driver.FindElement(By.TagName(selectorInfo);
break;
}
ElementFound = truel
}
catch
{
ElementFound = false;
}
return ElementFound;
}
Ok, I figured out how to do this. I'm leveraging driver.ExecuteScript() to run custom js on the webdriver. It looks a bit like this:
function elementFound(elem) {
var nodeType = navigator.appName == ""Microsoft Internet
Explorer"" ? document.ELEMENT_NODE : Node.ELEMENT_NODE;
if(elem.nodeType == nodeType)
{
/* Element identification logic here */
}
else { return false; }
}
function traverseElement(elem) {
if (elementFound(elem) == true) {
return elem;
}
else {
for (var i = 0; i < elem.childNodes.length; i++) {
var ret = traverseElement(elem.childNodes[i]);
if(ret != null) { return ret; }
}
}
}
return traverseElement(document);

Exporting a non public Type through public API

I am trying to follow Trees tutorial at: http://cslibrary.stanford.edu/110/BinaryTrees.html
Here is the code I have written so far:
package trees.bst;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/**
*
* #author sachin
*/
public class BinarySearchTree {
Node root = null;
class Node {
Node left = null;
Node right = null;
int data = 0;
public Node(int data) {
this.left = null;
this.right = null;
this.data = data;
}
}
public void insert(int data) {
root = insert(data, root);
}
public boolean lookup(int data) {
return lookup(data, root);
}
public void buildTree(int numNodes) {
for (int i = 0; i < numNodes; i++) {
int num = (int) (Math.random() * 10);
System.out.println("Inserting number:" + num);
insert(num);
}
}
public int size() {
return size(root);
}
public int maxDepth() {
return maxDepth(root);
}
public int minValue() {
return minValue(root);
}
public int maxValue() {
return maxValue(root);
}
public void printTree() { //inorder traversal
System.out.println("inorder traversal:");
printTree(root);
System.out.println("\n--------------");
}
public void printPostorder() { //inorder traversal
System.out.println("printPostorder traversal:");
printPostorder(root);
System.out.println("\n--------------");
}
public int buildTreeFromOutputString(String op) {
root = null;
int i = 0;
StringTokenizer st = new StringTokenizer(op);
while (st.hasMoreTokens()) {
String stNum = st.nextToken();
int num = Integer.parseInt(stNum);
System.out.println("buildTreeFromOutputString: Inserting number:" + num);
insert(num);
i++;
}
return i;
}
public boolean hasPathSum(int pathsum) {
return hasPathSum(pathsum, root);
}
public void mirror() {
mirror(root);
}
public void doubleTree() {
doubleTree(root);
}
public boolean sameTree(BinarySearchTree bst) { //is this tree same as another given tree?
return sameTree(this.root, bst.getRoot());
}
public void printPaths() {
if (root == null) {
System.out.println("print path sum: tree is empty");
}
List pathSoFar = new ArrayList();
printPaths(root, pathSoFar);
}
///-------------------------------------------Public helper functions
public Node getRoot() {
return root;
}
//Exporting a non public Type through public API
///-------------------------------------------Helper Functions
private boolean isLeaf(Node node) {
if (node == null) {
return false;
}
if (node.left == null && node.right == null) {
return true;
}
return false;
}
///-----------------------------------------------------------
private boolean sameTree(Node n1, Node n2) {
if ((n1 == null && n2 == null)) {
return true;
} else {
if ((n1 == null || n2 == null)) {
return false;
} else {
if ((n1.data == n2.data)) {
return (sameTree(n1.left, n2.left) && sameTree(n1.right, n2.right));
}
}
}
return false;
}
private void doubleTree(Node node) {
//create a copy
//bypass the copy to continue looping
if (node == null) {
return;
}
Node copyNode = new Node(node.data);
Node temp = node.left;
node.left = copyNode;
copyNode.left = temp;
doubleTree(copyNode.left);
doubleTree(node.right);
}
private void mirror(Node node) {
if (node == null) {
return;
}
Node temp = node.left;
node.left = node.right;
node.right = temp;
mirror(node.left);
mirror(node.right);
}
private void printPaths(Node node, List pathSoFar) {
if (node == null) {
return;
}
pathSoFar.add(node.data);
if (isLeaf(node)) {
System.out.println("path in tree:" + pathSoFar);
pathSoFar.remove(pathSoFar.lastIndexOf(node.data)); //only the current node, a node.data may be duplicated
return;
} else {
printPaths(node.left, pathSoFar);
printPaths(node.right, pathSoFar);
}
}
private boolean hasPathSum(int pathsum, Node node) {
if (node == null) {
return false;
}
int val = pathsum - node.data;
boolean ret = false;
if (val == 0 && isLeaf(node)) {
ret = true;
} else if (val == 0 && !isLeaf(node)) {
ret = false;
} else if (val != 0 && isLeaf(node)) {
ret = false;
} else if (val != 0 && !isLeaf(node)) {
//recurse further
ret = hasPathSum(val, node.left) || hasPathSum(val, node.right);
}
return ret;
}
private void printPostorder(Node node) { //inorder traversal
if (node == null) {
return;
}
printPostorder(node.left);
printPostorder(node.right);
System.out.print(" " + node.data);
}
private void printTree(Node node) { //inorder traversal
if (node == null) {
return;
}
printTree(node.left);
System.out.print(" " + node.data);
printTree(node.right);
}
private int minValue(Node node) {
if (node == null) {
//error case: this is not supported
return -1;
}
if (node.left == null) {
return node.data;
} else {
return minValue(node.left);
}
}
private int maxValue(Node node) {
if (node == null) {
//error case: this is not supported
return -1;
}
if (node.right == null) {
return node.data;
} else {
return maxValue(node.right);
}
}
private int maxDepth(Node node) {
if (node == null || (node.left == null && node.right == null)) {
return 0;
}
int ldepth = 1 + maxDepth(node.left);
int rdepth = 1 + maxDepth(node.right);
if (ldepth > rdepth) {
return ldepth;
} else {
return rdepth;
}
}
private int size(Node node) {
if (node == null) {
return 0;
}
return 1 + size(node.left) + size(node.right);
}
private Node insert(int data, Node node) {
if (node == null) {
node = new Node(data);
} else if (data <= node.data) {
node.left = insert(data, node.left);
} else {
node.right = insert(data, node.right);
}
//control should never reach here;
return node;
}
private boolean lookup(int data, Node node) {
if (node == null) {
return false;
}
if (node.data == data) {
return true;
}
if (data < node.data) {
return lookup(data, node.left);
} else {
return lookup(data, node.right);
}
}
public static void main(String[] args) {
BinarySearchTree bst = new BinarySearchTree();
int treesize = 5;
bst.buildTree(treesize);
//treesize = bst.buildTreeFromOutputString("4 4 4 6 7");
treesize = bst.buildTreeFromOutputString("3 4 6 3 6");
//treesize = bst.buildTreeFromOutputString("10");
for (int i = 0; i < treesize; i++) {
System.out.println("Searching:" + i + " found:" + bst.lookup(i));
}
System.out.println("tree size:" + bst.size());
System.out.println("maxDepth :" + bst.maxDepth());
System.out.println("minvalue :" + bst.minValue());
System.out.println("maxvalue :" + bst.maxValue());
bst.printTree();
bst.printPostorder();
int pathSum = 10;
System.out.println("hasPathSum " + pathSum + ":" + bst.hasPathSum(pathSum));
pathSum = 6;
System.out.println("hasPathSum " + pathSum + ":" + bst.hasPathSum(pathSum));
pathSum = 19;
System.out.println("hasPathSum " + pathSum + ":" + bst.hasPathSum(pathSum));
bst.printPaths();
bst.printTree();
//bst.mirror();
System.out.println("Tree after mirror function:");
bst.printTree();
//bst.doubleTree();
System.out.println("Tree after double function:");
bst.printTree();
System.out.println("tree size:" + bst.size());
System.out.println("Same tree:" + bst.sameTree(bst));
BinarySearchTree bst2 = new BinarySearchTree();
bst2.buildTree(treesize);
treesize = bst2.buildTreeFromOutputString("3 4 6 3 6");
bst2.printTree();
System.out.println("Same tree:" + bst.sameTree(bst2));
System.out.println("---");
}
}
Now the problem is that netbeans shows Warning: Exporting a non public Type through public API for function getRoot().
I write this function to get root of tree to be used in sameTree() function, to help comparison of "this" with given tree.
Perhaps this is a OOP design issue... How should I restructure the above code that I do not get this warning and what is the concept I am missing here?
The issue here is that some code might call getRoot() but won't be able to use it's return value since you only gave package access to the Node class.
Make Node a top level class with its own file, or at least make it public
I don't really understand why you even created the getRoot() method. As long as you are inside your class you can even access private fields from any other object of the same class.
So you can change
public boolean sameTree(BinarySearchTree bst) { //is this tree same as another given tree?
return sameTree(this.root, bst.getRoot());
}
to
public boolean sameTree(BinarySearchTree bst) { //is this tree same as another given tree?
return sameTree(this.root, bst.root);
}
I would also add a "short path" for the case you pass the same instance to this method:
public boolean sameTree(BinarySearchTree bst) { //is this tree same as another given tree?
if (this == bst) {
return true;
}
return sameTree(this.root, bst.root);
}