The bopf does not generated after cds view activated - cds

I have a CDS view and I would like to generate in addition a BOPF object. The CDS view looks as the following:
#AbapCatalog.sqlViewName: 'ZPOC_CDS_ORDERS'
#AbapCatalog.compiler.compareFilter: true
#AccessControl.authorizationCheck: #NOT_REQUIRED
#EndUserText.label: 'Order for VALEAN POC'
#ObjectModel.compositionRoot: true
#ObjectModel.modelCategory: #BUSINESS_OBJECT
#ObjectModel.semanticKey: ['DraftId', 'DraftItem']
#ObjectModel.representativeKey: 'DraftId'
#ObjectModel.writeActivePersistence: 'ZPOC_ORDERS'
#ObjectModel.createEnabled: true
#ObjectModel.deleteEnabled: true
#ObjectModel.updateEnabled: true
#OData: {
publish: true
}
define view ZPOCCDSORDERS as
select from zpoc_orders
{
key draft_id as DraftId,
key draft_item as DraftItem,
order_id as OrderId,
sales_org as SalesOrg,
sales_dist as SalesDist,
sales_div as SalesDiv,
customer_id as CustomerId,
recipient_id as RecipientId,
po_ref as PoRef,
}
In the transaction /n/BOBF/CONF_UI, I was searching for new generated Z* BOPF object but could not find anything.
What am I doing wrong?

Related

Grails unit testing service with spock mocking functionality

Presently trying to test a Grails service (Experience with Geb functional testing)
Trying to mock the necessary required data that the service will need (e.g. User,etc.) ... no matter how I seem to declare/initialize the domains of interest they all appear as NULL in all my tests methods
I'm trying to set this required information once, so it can be reused through the test methods.
#TestFor(ReminderService)
#Mock([Reminder, User, Subscriptions, Organisation, UserOrganisation, OrganisationRole, Ref, Role, Title])
class ReminderServiceTests extends Specification {
#Shared user, org, userOrg, roleUser, sub, orgRole, ti, refVals, reminder
def mailService
def setup() {
def refSubStatus = new Ref(value: 'Current').save()
def refSubPublic = new Ref(value: 'No').save()
def refSubType = new Ref(value: 'Subscription Taken').save()
def refRemUnit = new Ref(value: 'Month').save()
def refOrgRole = new Ref(value: 'Subscriber').save()
def refRemMethod = new Ref(value: 'email').save()
def refRemTrigger = new Ref(value: 'Subscription Manual Renewal Date').save()
reminder = new Reminder(user: user, active: true, amount: 1, unit:refRemUnit, reminderMethod:refRemMethod, trigger: refRemTrigger, lastRan:null).save()
refVals = [refSubStatus,refSubPublic, refSubType, refRemUnit, refOrgRole, refRemMethod, refRemTrigger]
roleUser = new Role(authority: 'BASIC_USER', roleType:'global').save()
ti = new Title(title: "A random title....", impId: UUID.randomUUID().toString()).save()
sub = new Subscription(name:"A random subscription name",
status:refSubStatus,
identifier:UUID.randomUUID().toString(),
impId:UUID.randomUUID().toString(),
startDate:new LocalDate().minusYears(1).toDate(),
endDate: new LocalDate().plusMonths(1).toDate(),
isPublic: refSubPublic,
type: refSubType,
renewal: new LocalDate().minusMonths(3).toDate()).save()
org = new Organisation(name: "new org", impId: UUID.randomUUID().toString()).save()
orgRole = new OrganisationRole(sub: sub, roleType: refOrgRole, org: org).save()
user = new User(username: 'j_doe', firstname: "John", lastname: "Doe", email: 'example#googlemail.com', defaultDash: org).save()
userOrg = new UserOrganisation(org: org, user: user, formalRole: roleUser, status: 1).save()
mailService = new MailService()
// mockDomain(Ref, refdataValues)
// mockDomain(Title, ti)
// mockDomain(OrganisationRole, orgRole)
// mockDomain(Organisation, org)
// mockDomain(User, user)
// mockDomain(UserOrganisation, userOrg)
// mockDomain(Reminder, reminder)
}
def "Getting subscriptions for a user"() {
when:
def subscriptions = service.getAuthorisedSubsciptionsByUser(user)
then:
subscriptions != null
subscriptions.size() > 0
}
Everything is null, I've tried using mockDomain (See commented out section in setup(), including using setupSpec() something is not quite right)
Have you tried not using #Shared? AS I see it now, you don't need it. Your references are shared throughout the lifecycle of the Spec, but you put your init code in setup, which is called before each spec. That does not seem right. #Shared variables are internally stored in a different instance than the normal variables, so there may be some kind of mixup. Also, you might try to use setupSpec() instead of setup() for #Shared variables.
#TestFor(SomeService)
#Mock([DomainClass])
class SomeServiceSpec extends Specification {
def "test someMethod"() {
given:
def x = new DomainClass(attr1: 'a', attr2: 'b').save(flush: true)
when:
def result = service.someMethod() // returns that saved Domain instance
then:
result instanceof DomainClass
result.attr1 == 'a'
result.attr2 == 'b'
}
}
.save() has proven insufficient in my unit tests, while .save(flush: true) produces the desired results.

How can I unit test a controller using altered default date binding?

How can I simulate the behavior of grails.databinding.dateFormats in a controller spock test?
In my Config.groovy, I added these settings:
grails.databinding.dateFormats = [
'yyyy-MM-dd\'T\'HH:mm:ss.SSSX',
'yyyy-MM-dd\'T\'HH:mm:ssX',
]
What do I have to do to get the unit test framework to bind date properties using one of the specified formats?
My controller looks like:
class MyController {
static responseFormats = ['json']
def get() {
MyCommand command = bindData(new MyCommand(), params)
command.validate()
if (command.hasErrors()) {
...
}
else {
//...do stuff with command object
}
}
#Validateable
class MyCommand {
Long resourceId
Date startDate
Date endDate
static constraints = {
resourceId nullable: false
startDate nullable: false
endDate nullable: false
}
}
}
When I run the application, this code works normally; however, when bindData() is called in the unit test, the 'resourceId' property on the command object is populated, while the date properties are not.

Add or remove an entry from a List type attribute in a DynamoDB table item

I have a very simple class, with a string type primary key and List type attributes. I want to write an API for adding and removing an item from the attribute list, and saving the changes back to DDB.
The simplest solution I can think of is:
Read the list (if it exists)
If it exists, remove or add the item from the List type attribute
Put the modified object back
Is there a cleaner/simpler way to do this via DynamoDB java API?
The accepted answer is incorrect, the correct way of doing this is listed in the DynamoDB UpdateExpression documentation
You need to read the list then get the index of the item you're looking to remove then run REMOVE list[index] as an UpdateExpression
You can use SET operator to add element in the attribute list. But for that you have to retrieve the existing list first then append new element in the list. Suppose you have a attribute named active_user which contain the list of active users.
previous_list = "#a"
query = "SET %s = list_append(%s, :new_user)" % (previous_list, previous_list)
user_table.update_item(
Key={
# primary key
},
UpdateExpression=query,
ExpressionAttributeNames={
'#a': 'active_user',
},
ExpressionAttributeValues={
':new_user': new_user_model
}
)
You can use REMOVE operator to remove or delete an element of the list. But you have to find the index of the element because REMOVE operator removes the given index of the list.
#user_index is the position of the target user in the list
query = "REMOVE active_user[%d]" % (user_index)
user_table.update_item(
Key={
# primary key
},
UpdateExpression=query
)
Here is REMOVE operator doc and SET operator doc.
For those using PynamoDB you can do:
Remove from ListAttribute (list):
obj = Model.get(model_id)
index = obj.list.index(value)
obj.update(
actions=[
Model.list[index].remove()
]
)
Append to ListAttribute(list):
obj = Model.get(model_id)
obj.update(actions=[
Model.list.set(
Model.list.append([value])
)]
)
For anyone else who arrives here and is still stuck using node and DocumentClient. I could not make any sort of ExpressionAtrributeVariables or ExpressionAttributeNames interpolation work, so ended up just using string concatenation.
const AWS = require('aws-sdk');
const dynamo = new AWS.DynamoDB.DocumentClient();
exports.handler = async(event, context) => {
var data = JSON.parse(event.body);
var recordID = data.idOfSomeRecordWithAList
var item = data.someListItemToDelete
// Get the current list
var listParams = {
TableName: 'someTable',
Key: {
'id': recordID
}
}
var records = await dynamo.get(listParams).promise();
var list = records.Item.someList;
// Remove the selected item from the list
var indexToRemove = list.findIndex(i => i === item);
// Note the standard string concatenation here
// I could not get any sort of #value or :value interpolation to work!!
var UpdateExpression = 'REMOVE someList['+indexToRemove+']';
var removeListItemParams = {
TableName: 'someTable',
Key: {
'id': recordID
},
UpdateExpression
}
try {
await dynamo.update(removeListItemParams).promise();
} catch (e) {
// This is helpful if running in Lambda and need to check logs.
console.log(e);
}
}
Also REMOVE is for lists DELETE is for sets (and has a special syntax [1]).
I just read the UpdateItem API thoroughly which talks about deleting set type attributes:
DELETE - Removes the attribute and its value, if no value is specified for DELETE. The data type of the specified value must match the existing value's data type.If a set of values is specified, then those values are subtracted from the old set. For example, if the attribute value was the set [a,b,c] and the DELETE action specifies [a,c], then the final attribute value is [b]. Specifying an empty set is an error.

How to mock springSecurityService in unit tests using grails

I am using Spring security in my grails project. I have installed the spring-security-core plugin and spring-security-ui plugin.
The domain classes I have used for Person and Authority are User and Role respectively
As per project requirements, I have modified my User.groovy class and the code for the same is as below:
class User {
transient springSecurityService
//Mandatory Fields
String employeeId
String firstName
String lastName
String password
String emailId
//Other Fields
String mobileNumber
String address
String city
String zipCode
User manager
static hasMany = [previousPasswords: String]
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static transients = ['springSecurityService']
static constraints = {
employeeId blank: false, unique: true
firstName blank: false
lastName blank: false
password blank: false, password: true, validator: { val, obj ->
if(obj.previousPasswords) {
return !obj.previousPasswords.contains(encode(val.toUpperCase()))
}
return true
}
emailId blank: false, email: true
mobileNumber nullable: true
address nullable: true
city nullable: true
zipCode nullable: true
manager nullable: true
previousPasswords display: false, editable: false
}
static mapping = {
password column: '`password`'
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}
def beforeInsert() {
previousPasswords = [encode(password.toUpperCase())]
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
previousPasswords << encode(password.toUpperCase())
encodePassword()
}
}
protected String encode(String pwd) {
return springSecurityService.encodePassword(pwd)
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
I am trying to write Unit tests to check the constraints for this unit class
One of my test looks as below
void "test if employeeId can be blank or non-unique"() {
given:
def springSecurityService = mockFor(SpringSecurityService,true)
springSecurityService.encodePassword(){String pwd -> return null}
// def springSecurityServiceFactory = mockFor(SpringSecurityService,true)
// def mockSpringSecurityService = Mock(SpringSecurityService)
// mockSpringSecurityService.metaClass.encodePassword = {String password -> return null}
// User.metaClass.encodePassword = { return null }
// User.metaClass.encode = {password -> return null }
// User.metaClass.getSpringSecurityService = { mockSpringSecurityService }
when: 'employeeId is blank'
def user = new User(employeeId: " ")
user.springSecurityService= springSecurityService
then: 'validation fails'
!user.validate()
user.errors.getFieldError("employeeId").codes.contains("nullable")
when: 'employeeId is unique'
user = new User(employeeId: "empId1", firstName: "f_name", lastName: "l_name", password: "password", emailId: "test#hptest.com")
user.springSecurityService= springSecurityService
then: 'validation succeeds'
user.validate()
user.save(flush: true, failOnError: true)
mockForConstraintsTests(User, [user])
when: 'employeeId is non unique'
def user_2 = new User(employeeId: "empId1")
user_2.springSecurityService= springSecurityService
then: 'validation fails'
!user_2.validate()
user_2.errors.getFieldError("employeeId").codes.contains("unique")
}
I have been trying different ways to mock springSecurityService but all seem to fail. Can anyone suggest a way to mock this service.
Currently I am getting this error.
groovy.lang.MissingMethodException: No signature of method: grails.test.GrailsMock.encodePassword() is applicable for argument types: (com.hp.bots.UserSpec$_$spock_feature_0_0_closure1) values: [com.hp.bots.UserSpec$_$spock_feature_0_0_closure1#18324cd]
at com.hp.bots.UserSpec.test if employeeId can be blank or non-unique(UserSpec.groovy:25)
This test also fails if I try to run it as an integration test (without mocking). I am not able to understand where I am going wrong.
I guess if you replace
springSecurityService.encodePassword(){String pwd -> return null}
with
springSecurityService.demand.encodePassword(){String pwd -> return null}
and
user.springSecurityService= springSecurityService.createMock() (grails 2.3.7)
and for user_2
you should be able to get this test running.
you could have a look here for further documentation. http://grails.org/doc/2.3.7/guide/testing.html
I usually mock services by creating a map with the function(s) that will be called. I would only recommend this approach when only one or two simple functions are being called on the service in question, and these calls do not need to be verified/tracked. In your case your given clause might look like this:
def springSecurityService = [encodePassword: { password ->
return password
}]

Grails: How does that the UPDATE function work?

I got rid of the original UPDATE gsp Grails offers.
I put it in the first row of my list.gsp table and change all the values of the table to g:textfield so they can be edited without going to the save.gsp
But now I'm trying to make it work, and I can't.
I added a update button in the last column of the row, of every row.
When I change the values of the g:textfields and click the update button it tells me
Density #ID updated
but the values do not change.
I think I am doing something wrong with def update in the controller.
Here is the code:
def update = {
log.info "Entering Action ${actionUri}"
def densityInstance = Density.get(params.id)
if (densityInstance) {
if(params?.Rcommodity) {
println "${params.Rcommodity}"
}
if (params.version) {
def version = params.version.toLong()
if (densityInstance.version > version) {
densityInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'density.label', default: 'Density')] as Object[], "Another user has updated this Density while you were editing")
render(view: "list", model: [densityInstance: densityInstance])
return
}
}
densityInstance.properties = params
if (!densityInstance.hasErrors() && densityInstance.save(flush: true)) {
flash.message = "${message(code: 'default.updated.message', args: [message(code: 'density.label', default: 'Density'), densityInstance.id])}"
redirect(action: "list", id: densityInstance.id)
}
else {
redirect(action: "list", id: densityInstance.id)
}
}
else {
flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'density.label', default: 'Density'), params.id])}"
redirect(action: "list")
}
}
The Rcommodity is the name of the textfields created, I put a println to see if the value was right, now I don't know how to make the value of the textfield be the one entered, it gives me the same value it had before but it gives me the message saying that it was updated.
The controller is DensityController and the domain is density
Any help would be greatly appreciated. Thanks :D
Looks from the flash message being printed as though the instance is being updated (though the "#ID" bit looks odd - have you replaced the actual id?).
It might be that
densityInstance.properties = params
is not actually be matching any instance properties, so none are actually being changed before the save. Are you sure you've named your gsp input fields to match the names of your Density class fields? Is Rcommodity a property of Density, for example?
Might help to add the form bit of your gsp page, as well as the Density domain class.