SPOCK - All #Shared Variables are NULL - unit-testing

Here is my test class:
import grails.test.mixin.*
import spock.lang.Specification
import spock.lang.Unroll
import spock.lang.*
import groovy.util.logging.Slf4j
#Slf4j
#Mock([PromoRule, PromoCode, SecUser])
#TestFor(PromoService)
class PromoServiceSpec extends Specification {
#Shared testUser
#Shared testCode
#Shared testRule
def setup() {
}
#Unroll
def 'valid promo codes - #user, #code'() {
given:
testRule = new PromoRule(
name : "ZTEST",
receiverAmount : 5,
receiverAmountType : PromoRule.AmountType.DOLLARS,
senderAmount : 0,
senderAmountType : PromoRule.AmountType.DOLLARS,
receiverPointsAmount : null,
receiverPointsAmountType : null,
receiverMaxUse : null,
)
testRule.save(flush:true, failOnError:true)
testUser = new SecUser(
id: 1,
version: 0,
accountExpired: false,
accountLocked: false,
age: 9000,
balance: 100,
dateCreated: new Date(),
emailVerified: true,
enabled: true,
firstName: 'Sir',
lastName: 'Buttocks',
lastUpdated: new Date(),
lockedBalance: 0,
username: "1",
staff: false,
displayName: 'sir_buttocks',
usernameChosen: true,
depositMade: true,
depositOfferRecentlySeen: false,
pin: null
)
testUser.save(flush: true, failOnError: true)
testCode = new PromoCode(
rule : testRule,
code : "3",
senderId : 1,
)
testCode.save(flush:true, failOnError:true)
expect:
service.isValidPromoCode(user, code) == value
where:
user | code || value
testUser | testCode || true
}
}
When I run this test, I get the following:
| Failure: valid promo codes - null, null(skillz.PromoServiceSpec)
| Condition not satisfied:
service.isValidPromoCode(user, code) == value
| | | | | |
| false null null | true
skillz.PromoService#20e0e9d5 false
I have tried a ton of different configurations and layouts, all of them either getting me a null pointer exception (to the variable itself) or a null value for the variable.
Doing all the definitions at static variables didn't change anything either, same result as using #Shared.
I've tried mocking these as well, but I always get null exceptions when trying to execute .Mock() for the class...
Thanks!!

I'm not exactly sure what you are trying to achieve here, but the where block is evaluated before (the rest of) the method is first entered, and at that time, your shared variables are null. You'd have to set them earlier, e.g. in a setupSpec (not setup) method.

Related

Invocation with unauthorized signer On Anchor Solana

I'm trying to sign a transaction manually with the anchor framework.
The following is the normal and currently working method to call the program:
await program.value.rpc.sendTweet(topic, content, {
accounts: {
author: wallet.value.publicKey,
tweet: tweet.publicKey,
systemProgram: web3.SystemProgram.programId,
},
signers: [tweet]
})
And this is the struct on the rust side
#[derive(Accounts)]
pub struct SendTweet<'info> {
#[account(init, payer = author, space = Tweet::LEN)]
pub tweet: Account<'info, Tweet>,
#[account(mut)]
pub author: Signer<'info>,
#[account(address = system_program::ID)]
pub system_program: AccountInfo<'info>,
}
Instead I want to be able to manually compile, sign and send the transaction, so I've wrote the following:
const transactionInstruction = new TransactionInstruction({
keys: [
{pubkey: tweet.publicKey, isSigner: false, isWritable: true},
{pubkey: wallet.value.publicKey, isSigner: true, isWritable: true}
],
programId: programId,
data: transactionInstructionAnchor.data
});
{...}
await web3.sendAndConfirmRawTransaction(connection, rawTransaction)
I see that the problem Might be inside the keys of the TransactionInstruction because I'm passing just 2 keys, but in the SendTweet accounts I'm passing 3 values:
accounts: {
author: wallet.value.publicKey,
tweet: tweet.publicKey,
systemProgram: programId, // <--- THIS ONE ?
},
I've tried adding to the keys this:
{
pubkey: web3.SystemProgram.programId,
isWritable: false,
isSigner: false,
},
But it gives me the error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: Cross-program invocation with unauthorized signer or writable account
Anyone knows what I'm doing wrong?
Thankyou

Django-wkhtmltopdf crashes on server

I have an app using django-wkhtmltopdf. It is working locally, but when I run on a VPS I'm getting the following error.
Command '['wkhtmltopdf', '--allow', 'True',
'--enable-local-file-access', '--encoding', 'utf8',
'--javascript-delay', '2000', '--page-height', '465mm',
'--page-width', '297mm', '--quiet', '/tmp/wkhtmltopdffyknjyrk.html',
'-']' returned non-zero exit status 1.
I'm guessing I need to set some permissions on the VPS to allow the temp file to be created (or set a directory for it) but I'm not sure how to do this.
Within settings.py I have
WKHTMLTOPDF_CMD_OPTIONS = {
'quiet': True,
'allow' : '/tmp',
'javascript-delay' : 1000,
'enable-local-file-access' : True,
}
And within the django view I've got:
cmd_options = {
#'window-status' : 'ready',
'javascript-delay': 2000,
'page-height' : '465mm',
'page-width' : '297mm',
'allow' : True,
#'T' : 0, 'R' : 0, 'B' : 0, 'L': 0,
}

Using Spock test how to validate json attributes key-value pairs comes as dynamically inputs

How to write right test, in order to test the below csv data stored in database table. In the input other than item, anything could be optional.
In this, item is key, rest all goes as part of json format typically it looks like this in database {"brand": "Brand6", "category": "Category6", "subcategory": "Sub-Category6"}
Input:
item,category,subcategory,brand,type,feature
TEST-ITEM6,Category6,Sub-Category6,Brand6
TEST-ITEM7,Category7,Sub-Category7,Brand7,TYPE7,FEATURE7
TEST-ITEM8,Category8,Sub-Category8,Brand8,TYPE8,FEATURE8
Test case tried:
def "Case 3a. Verify New 2 records with two more additional fields along with earlier fields to the same tenant"() {
expect:
sql().eachRow("SELECT * FROM item WHERE item IN ('"+item+"')") { row ->
def dbItem = row[0]
def dbAttributes = getJsonToObject(row[1])
def dbCategory = dbAttributes.getAt("category").toString()
def dbSubCategory = dbAttributes.getAt("subcategory").toString()
def dbBrand = dbAttributes.getAt("brand").toString()
def dbType = dbAttributes.getAt("type").toString()
def dbFeature = dbAttributes.getAt("feature").toString()
assert dbItem == item
assert category == dbCategory
assert subcategory == dbSubCategory
assert brand == dbBrand
assert type == dbType
assert feature == dbFeature
}
where:
item << ['TEST-ITEM6', 'TEST-ITEM7', 'TEST-ITEM8']
category << ['Category6','Category7', 'Category8']
subcategory << ['Sub-Category6','Sub-Category7', 'Sub-Category8']
brand << ['Brand6','Brand7', 'Brand8']
type << ['TYPE7', 'TYPE8']
feature << ['FEATURE7', 'FEATURE8']
}
Error:
Condition not satisfied:
type == dbType
| | |
TYPE8| TYPE7
false
1 difference (80% similarity)
TYPE(8)
TYPE(7)
Expected :TYPE7
Actual :TYPE8
In this case I would recommend to use Data Tables as it becomes more readable and resembles your input more closely.
And while type and feature are optional, you need to provide some value for it. It could be null or it could be an empty List or Map (if an Item can have more than one type/feature)
So you where block might look like this:
item | category | subcategory | brand | typeFeatureMap
'TEST-ITEM6' | 'Category6' | 'Sub-Category6' | 'Brand6' | [:] // empty
'TEST-ITEM7' | 'Category7' | 'Sub-Category7' | 'Brand7' | ['TYPE7':'FEATURE7']
'TEST-ITEM8' | 'Category8' | 'Sub-Category8' | 'Brand8' | ['TYPE8':'FEATURE8']
I would also recommend to collect the data and then compare it, so you get around ordering issues.
So bofore your eachRow do something like
def itemFeatures = [:]
In your eachRow do something like
itemFeatures.put(dbAttributes.getAt("type").toString(), dbAttributes.getAt("feature").toString())
And afterwards
itemFeatures == typeFeatureMap
While not answering your question, I would recommend to think about separating the tests from your database if possible.
If you create separate tests for an database abstraction layer and your business logic, you'll be more happy in the long run ;)
For the optional fields you can use the Elvis operator ?: like this (sorry, long code, I modeled your database and two new test cases, one with many optional fields and one failing test):
package de.scrum_master.stackoverflow
import spock.lang.Specification
import spock.lang.Unroll
class DataTableWithOptionalItemsTest extends Specification {
#Unroll
def "Case 3a. Verify record '#item' with possibly optional fields"() {
expect:
testData[item].each { row ->
def dbItem = row["item"]
def dbCategory = row["category"]
def dbSubCategory = row["subcategory"]
def dbBrand = row["brand"]
def dbType = row["type"]
def dbFeature = row["feature"]
assert dbItem == item
assert (category ?: dbCategory) == dbCategory
assert (subcategory ?: dbSubCategory) == dbSubCategory
assert (brand ?: dbBrand) == dbBrand
assert (type ?: dbType) == dbType
assert (feature ?: dbFeature) == dbFeature
}
where:
item | category | subcategory | brand | type | feature
'TEST-ITEM6' | 'Category6' | 'Sub-Category6' | 'Brand6' | null | null
'TEST-ITEM7' | 'Category7' | 'Sub-Category7' | 'Brand7' | 'TYPE7' | 'FEATURE7'
'TEST-ITEM8' | 'Category8' | 'Sub-Category8' | 'Brand8' | 'TYPE8' | 'FEATURE8'
'TEST-ITEM9' | null | null | null | null | null
'TEST-FAIL' | 'CategoryX' | 'Sub-CategoryX' | 'BrandX' | 'TYPEX' | 'FEATUREX'
}
static final testData = [
'TEST-ITEM6': [
[
item : 'TEST-ITEM6',
category : 'Category6',
subcategory: 'Sub-Category6',
brand : 'Brand6',
type : 'dummy',
feature : null
],
[
item : 'TEST-ITEM6',
category : 'Category6',
subcategory: 'Sub-Category6',
brand : 'Brand6',
type : null,
feature : "foo"
]
],
'TEST-ITEM7': [
[
item : 'TEST-ITEM7',
category : 'Category7',
subcategory: 'Sub-Category7',
brand : 'Brand7',
type : 'TYPE7',
feature : 'FEATURE7'
],
[
item : 'TEST-ITEM7',
category : 'Category7',
subcategory: 'Sub-Category7',
brand : 'Brand7',
type : 'TYPE7',
feature : 'FEATURE7'
]
],
'TEST-ITEM8': [
[
item : 'TEST-ITEM8',
category : 'Category8',
subcategory: 'Sub-Category8',
brand : 'Brand8',
type : 'TYPE8',
feature : 'FEATURE8'
],
[
item : 'TEST-ITEM8',
category : 'Category8',
subcategory: 'Sub-Category8',
brand : 'Brand8',
type : 'TYPE8',
feature : 'FEATURE8'
]
],
'TEST-ITEM9': [
[
item : 'TEST-ITEM9',
category : 'Category1',
subcategory: 'Sub-Category1',
brand : 'Brand1',
type : 'TYPE1',
feature : 'FEATURE1'
],
[
item : 'TEST-ITEM9',
category : null,
subcategory: null,
brand : null,
type : null,
feature : null
]
],
'TEST-FAIL' : [
[
item : 'TEST-FAIL',
category : 'CategoryX',
subcategory: 'Sub-CategoryX',
brand : 'BrandY',
type : 'TYPEX',
feature : 'FEATUREX'
]
]
]
}

How to use if condition in Karate

Suppose I have the following Json response
[
{
id: 1,
name: "John",
password: "JohnsPassword54",
},
{
id: 2,
name: "David",
password: "DavidsPassword24",
}
]
Then how can I extract the array with name David to do further validation?
e.g. I want to say if name == David then save the id
Well done :) Mastering Json-Path is key to get the most out of Karate !
Just for the sake of demo, here is another option, using the get keyword to get the first element out of the array returned, as Json-Path wildcard searches always return an array:
* def response =
"""
[
{
id: 1,
name: "John",
password: "JohnsPassword54"
},
{
id: 2,
name: "David",
password: "DavidsPassword24"
}
]
"""
* def userId = get[0] response $[?(#.name == 'David')].id
* match userId == 2
I found the solution in the Json expression evaluation -
def user = $..[?(#.name == 'David')]
Then I can use the following -
def userId = user[0].id

Testing a command object in a service class method that has the command object as part of the method signature

I have a Grails service class that I'm trying to write a Spock test for. The signature of the method is as follows:
def buildErrorJsonArray(AddressInfoCommand addressInfoCmd, PaymentInfoCommand paymentInfoCmd, boolean trsRequest = false)
When I populate the AddressInfoCommand and PaymentInfoCommand command object with invalid data in the test and call validate on it, it's not returning any errors and I'm not sure why. My guess is it's the way I'm mocking the command objects in the test (via mockForConstraintsTests). Here is the part of the test that populates the PaymentInfoCommand:
setup:
service.messageSource = [getMessage: { errors, locale -> return "message" }]
mockForConstraintsTests(AddressInfoCommand)
mockForConstraintsTests(PaymentInfoCommand)
PaymentInfoCommand paymentInfoCommand = new PaymentInfoCommand()
def payment = new Payment()
payment.paymentType = ""
payment.cardAccountNumber = ""
payment.cardExpirationDate = ""
payment.cardSecurityCode = ""
paymentInfoCommand.setPaymentInfoCommand(payment)
paymentInfoCommand.validate()
And here is part of the PaymentInfoCommand:
class PaymentInfoCommand {
String cardType = ""
String cardAccountNumber = ""
String cardExpirationDateYear = ""
String cardExpirationDateMonth = ""
String cardSecurityCode = ""
def messageSource
static constraints = {
cardAccountNumber(nullable: false, blank: false, maxSize: 19, creditCard: true)
cardSecurityCode(nullable: false, blank: false, minSize: 3, maxSize: 4, validator: {val, obj ->
if (!StringUtils.isNumeric(obj.cardSecurityCode)) {
return "paymentInfoCommand.cardSecurityCode.notANumber.error"
}
})
} }
Can anyone see what I'm doing wrong?