Objectify Ref<> with #Load is not working with ofy().load().group() - google-app-engine

I have a problem Ref<> usage with #Load. Basically I made a copy paste from Objectify website to test #Load annotation with Load Groups.
#Entity
public static class Thing {
public static class Partial {}
public static class Everything extends Partial {}
public static class Stopper {}
#Id Long id;
#Load(Partial.class) Ref<Other> withPartial;
#Load(Everything.class) Ref<Other> withEveryhthing;
#Load(unless=Stopper.class) Ref<Other> unlessStopper;
public Ref<Other> getWithPartial() {
return withPartial;
}
public void setWithPartial(Ref<Other> withPartial) {
this.withPartial = withPartial;
}
public Ref<Other> getWithEveryhthing() {
return withEveryhthing;
}
public void setWithEveryhthing(Ref<Other> withEveryhthing) {
this.withEveryhthing = withEveryhthing;
}
public Ref<Other> getUnlessStopper() {
return unlessStopper;
}
public void setUnlessStopper(Ref<Other> unlessStopper) {
this.unlessStopper = unlessStopper;
}
}
Then I wrote the following code.
Other other = new Other();
Key<Other> otherKey = ofy().save().entity(other).now();
Thing thing = new Thing();
thing.setWithPartial(Ref.create(otherKey));
Key<Thing> thingKey = ofy().save().entity(thing).now();
Thing t = ofy().load().key(thingKey).now();
System.out.println("Is loaded: " + t.getWithPartial().isLoaded());
Without writing ofy().load().group(Partial.class).key(thingKey).now(); other entity still loads into session. However in documentation it needs group class to be loaded.

The isLoaded() method tests whether the entity is in the session cache. Since you just save()d the entity, it's already in the session cache.
If you want to test the behavior of load groups, you need to ofy().clear() the cache.

Related

How do i write test class for below apex code

Please help me in writing test class for below apex code,i wrote a test class which shows only 66% coverage,i am looking for 100%
public class PickListHandler {
#AuraEnabled
public static List<String> getLevel1(string strName) {
List<String> tempLst = new List<String>
for(AggregateResult ar : [select Level_1__c,COUNT(id) from Case_Type_Data__c group by Level_1__c])
{
tempLst.add('Level 1 data is'+ar.get('Level_1__c'));
return tempLst;
}
}
}
Here is test class
#isTest
public class testGetLevel1 {
static testMethod void testGetLevel1() {
List<String> s = PickListHandler.getLevel1('test');
//System.assert(....);
}
}
You need need to create test data for the object Case_Type_Data__c. If you don't create data, the logic inside for loop will not execute.

MappingException: Ambiguous field mapping detected

Using Spring boot 1.5.6.RELEASE.
I have the following mongo document base class:
#Document(collection="validation_commercial")
public abstract class Tier {
#Id
private String id;
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private Date created;
#Field("tran")
private Tran tran;
public Tier() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Tran getTran() {
return tran;
}
public void setTran(Tran tran) {
this.tran = tran;
}
}
which is then extended:
public class Tier1 extends Tier {
#Field("tier1")
private Tier1Programs tier1;
public Tier1() {
this.tier1 = new Tier1Programs();
}
public Tier1Programs getTier1() {
return tier1;
}
public void setTier1(Tier1Programs tier1) {
this.tier1 = tier1;
}
}
which in turn is extended:
public class Tier2 extends Tier1 {
#Field("tier2")
private Tier2Programs tier2;
public Tier2() {
this.tier2 = new Tier2Programs();
}
public Tier2Programs getTier2() {
return tier2;
}
public void setTier2(Tier2Programs tier2) {
this.tier2 = tier2;
}
}
There is a Tier1 Supervisor (Spring Boot Application) that uses the Tier1 class within the MongoRepository interface:
public interface Tier1Repository extends MongoRepository<Tier1,String>{}
for retrieving and saving - no issue.
I then have a Tier2 Supervisor (Spring Boot Application) that uses a Tier1 Repository (for retrieving the Tier1 document and a Tier2 Repository for saving the Tier2 document:
#Repository("tier1Repository")
public interface Tier1Repository extends MongoRepository<Tier1,String>{}
#Repository("tier2Repository")
public interface Tier2Repository extends MongoRepository<Tier2,String>{}
My service is:
#Service
public class TierService {
#Qualifier("tier1Repository")
#Autowired
private final Tier1Repository tier1Repository;
#Qualifier("tier2Repository")
#Autowired
private final Tier2Repository tier2Repository;
public TierService(#Qualifier("tier1Repository") Tier1Repository tier1Repository, #Qualifier("tier2Repository") Tier2Repository tier2Repository) {
this.tier1Repository = tier1Repository;
this.tier2Repository = tier2Repository;
}
public Tier1 findOne(String id) {
return tier1Repository.findOne(id);
}
public void SaveTier(Tier2 tier) {
tier2Repository.save(tier);
}
public Tier1Repository getTier1Repository() {
return tier1Repository;
}
public Tier2Repository getTier2Repository() {
return tier2Repository;
}
}
and finally the app:
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class})
#Configuration
#ComponentScan(basePackages = {"com.k12commercial.tier2supervisor"})
#ImportResource("classpath:application-context.xml")
public class Application implements CommandLineRunner {
#Autowired
private IReceiver raBidNetPriceReceiver;
#Autowired
private UdyDataSourceFactory udyDSRegistry;
public static void main(String[] args) throws InterruptedException {
try {
SpringApplication.run(Application.class, args);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void run(String... args) throws Exception {
raBidNetPriceReceiver.processTierMessages();
exit(0);
}
}
When I run the Tier2 Supervisor from the command line I get the following error:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'tierService' defined in URL
[jar:file:/opt/java-commandline/tier2supervisor-1.0.jar!/BOOT-INF/classes!/com/k12commercial/tier2supervisor/service/TierService.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tier2Repository': Invocation of init method failed; nested exception is org.springframework.data.mapping.model.MappingException: Ambiguous field mapping detected! Both private final java.lang.reflect.Type org.springframework.data.util.TypeDiscoverer.type and private final java.lang.Class org.springframework.data.util.ClassTypeInformation.type map to the same field name type! Disambiguate using #Field annotation!
I am not sure if the issue is Tier2 extending Tier1 (did try putting #Document tag above Tier1 and Tier2 with no change). I think I have marked the relevant fields so don't understand the need to disambiguate. I thought the issue was having 2 repositories (Spring Boot not knowing which one to DI) so removed the Tier1Repository - didn't work. Tried better qualifying the repositories but still got the same error. I made Tier1 and Tier2 #Transient and that got rid of the message but also removed the tier1 section in the mongo document - so wrong correction.
Thinking it is an annotation fix but not seeing it...
Please advise - thank you.
Sorry for the delay (I got pulled away to work on something else) and thank you to those who responded.
The issue was I had a MongoTemplate in my Tier level programs e.g.Tier2Programs (sub library) which Spring Boot was trying to autowire.
By moving the Mongo (CRUD) requirements to the supervisor level (I also replaced the Repositories with one MongoTemplate to simplify) I removed the ambiguity. (I also removed the Service class).
The code is contained with the RaBidNetReciever class
#Component
public class RaBidNetPriceReceiver extends BaseReceiver implements IReceiver, ApplicationEventPublisherAware {
private static final Logger LOGGER = LoggerFactory.getLogger(RaBidNetPriceReceiver.class);
private final RabbitTemplate raBidNetPriceRabbitTemplate;
public RaBidNetPriceReceiver(MongoTemplate mongoTemplate, RabbitTemplate raBidNetPriceRabbitTemplate) {
super(mongoTemplate);
this.raBidNetPriceRabbitTemplate = raBidNetPriceRabbitTemplate;
}
#Transactional
public void processTierMessages() {
try {
while (true) {
gson = getGsonBuilder().create();
byte[] body = (byte[]) raBidNetPriceRabbitTemplate.receiveAndConvert();
if (body == null) {
setFinished(true);
break;
}
tier1Message = gson.fromJson(new String(body), Tier1Message.class);
// document a 'Tier1' type so retrieve Tier1 first...
Tier1 tier1 = mongoTemplate.findById(tier1Message.getId(), Tier1.class);
Tier2Message tier2Message = new Tier2Message(tier1Message.getTran(), tier1Message.getId());
Tier2Process tierProcess = getTierProcess(tier2Message.getTran().getK12ArchitectureId());
Tier2 tier2 = new Tier2();
tier2.setId(tier1.getId());
tier2.setTier1Programs(tier1.getTier1Programs());
tier2.setCreated(tier1.getCreated());
tier2.setTran(tier1.getTran());
tierProcess.setTier(tier2);
tier2 = tier2.getTier2Programs().getRaBidNetPriceProgram().process(tierProcess);
mongoTemplate.save(tier2);
if (tier2.getTier2Programs().getRaBidNetPriceProgram().isFinished()) {
// publish event
publisher.publishEvent(new ProgramEvent(this, "FINISHED", tier2Message));
}
}
} catch (Exception e) {
LOGGER.error("id: " + tier1Message.getId() + " " + e.getMessage());
}
}
#Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}
Thank you,

testng how to dynamically set groups from Factory?

Before I setup a test class like the code below:
1. the Factory and test Dataprovider both used excel as the dataprovider.
2. In the Factory dataprovider table, it has a list of url
3. Each time, it will find one of the url in the factory dataprovider table, and run the test in each test methods..
public class Test {
WebDriver driver;
private String hostName;
private String url;
#Factory(dataProvider = "xxxx global variables", dataProviderClass = xxxx.class)
public GetVariables(String hostName, String url) {
this.hostName = hostName;
this.url = url;
}
#BeforeMethod
#Parameters("browser")
public void start(String browser) throws Exception {
driver = new FirefoxDriver();
driver.get(url);
Thread.sleep(1000);
}
#Test(priority = 10, dataProvider = "dataprovider Test A", dataProviderClass = xxx.class)
public void TestA(Variable1,
Variable2,Variable3) throws Exception {
some test here...
}
#Test(priority = 20, dataProvider = "dataprovider Test B", dataProviderClass = xxx.class)
public void TestB(Variable1,
Variable2,Variable3)
throws Exception {
some test here...
}
#AfterMethod
public void tearDown() {
driver.quit();
}
Now I want to dynamically assign different group for each test for different url. I am thinking add a variable 'flag' in the #Factory dataprovider:
#Factory(dataProvider = "xxxx global variables", dataProviderClass = xxxx.class)
public GetVariables(String hostName, String url, String flag) {
this.hostName = hostName;
this.url = url;
this.flag = flag;
}
That when flag.equals("A"), it will only run test cases in test groups={"A"}.
When flag.equals("B"), it will only run test cases in test groups ={"B"},
When flag.equals("A,B"), it will only run test cases in test groups ={"A","B"}
Is there any way I can do that?
Thank you!
TestNG groups provides "flexibility in how you partition your tests" but it isn't for conditional test sets. For that you simply use plain old Java.
You can use inheritance or composition (I recommend the latter, see Item 16: Favor composition over inheritance from Effective Java).
Either way the general idea is the same: use a Factory to create your test class instances dynamically creating the appropriate class type with the appropriate test annotations and/or methods that you want to run.
Examples:
Inheritance
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class DemoTest {
#Factory
public static Object[] createTests() {
return new Object[]{
new FlavorATest(),
new FlavorBTest(),
new FlavorABTest()
};
}
/**
* Base test class with code for both A-tests and B-tests.
*
* Note that none of these test methods are annotated as tests so that
* subclasses may pick which ones to annotate.
*/
public static abstract class BaseTest {
protected void testA() {
// test something specific to flavor A
}
protected void testB() {
// test something specific to flavor B
}
}
// extend base but only annotate A-tests
public static class FlavorATest extends BaseTest {
#Test
#Override
public void testA() {
super.testA();
}
}
// extend base but only annotate B-tests
public static class FlavorBTest extends BaseTest {
#Test
#Override
public void testB() {
super.testB();
}
}
// extend base and annotate both A-tests and B-tests
public static class FlavorABTest extends BaseTest {
#Test
#Override
public void testA() {
super.testA();
}
#Test
#Override
public void testB() {
super.testB();
}
}
}
Composition
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class DemoTest {
#Factory
public static Object[] createTests() {
return new Object[]{
new FlavorATest(),
new FlavorBTest(),
new FlavorABTest()
};
}
private static void testA() {
// test something specific to flavor A
}
private static void testB() {
// test something specific to flavor B
}
// only create A-test methods and delegate to shared code above
public static class FlavorATest {
#Test
public void testA() {
DemoTest.testA();
}
}
// only create B-test methods and delegate to shared code above
public static class FlavorBTest {
#Test
public void testB() {
DemoTest.testB();
}
}
// create A-test and B-test methods and delegate to shared code above
public static class FlavorABTest {
#Test
public void testA() {
DemoTest.testA();
}
#Test
public void testB() {
DemoTest.testB();
}
}
}
Your factory methods won't be as simple as you'll need to use your "flag" from your test data to switch off of and create instances of the appropriate test classes.

how to use selenium with fitnesse

I am creating a small test. In Code behind I have two classes. Pages, LoginPage.
The first part is running. I dont know how to integrate with second part. Currently I am able to open the browser. Also I am trying to use the Page obect model pattern .
Fitnesse code
!|import|
|TestFramework|
!|script|Pages|
|Goto||https://gmail.com|
|LoginPage|CheckRequiredElementsPresent|Pass|
Fixtures
public class Pages
{
string url;
private LoginPage loginPage;
public static void Goto(string url)
{
Browser.Goto(url);
}
}
public class LoginPage
{
static string PageTitle;
[FindsBy(How = How.Id, Using = "TextUsername")]
private static IWebElement username;
[FindsBy(How = How.Id, Using = "TextPassword")]
private static IWebElement password;
[FindsBy(How = How.Id, Using = "_ButtonLogin")]
private static IWebElement submit;
public string IsAtLoginPage()
{
return "";
}
public string CheckRequiredElementsPresent()
{
if (username != null && password != null && submit != null)
{
return "Pass";
}
return "Fail";
}
}
}
You need to do something like below:
Fitnesse Code
!|import|
|TestFramework|
!|script|Pages|
|Goto||https://gmail.com|
|check Required Element|Pass|
You need to call your second class from your Pages class, please see the code changes & fitnesse fixture changes that I've made.
Fixtures
public class Pages
{
string url;
private LoginPage loginPage;
public static void Goto(string url)
{
Browser.Goto(url);
}
// This is what you need to do to refer method of second class.
// This method will be called after Goto method in sequence.
public boolean checkRequiredElement(){
return loginPage.CheckRequiredElementsPresent()
}
}

Request Factory GWT editor change isn't persisting related JDO entities

I'm using (and new to) RequestFactory in GWT 2.5, with JDO entities with a one-to-many relationship, on AppEngine datastore. I've just started using the GWT RequestFactoryEditorDriver to display/edit my objects.
The Driver traverses my objects fine, and displays them correctly. However, when I try to edit a value on the "related" objects, the change doesn't get persisted to the datastore.
When I change b.name on my UI and click "save", I notice only A's persist() call is called. B's persist() is never called. How do I make the editorDriver fire on both ARequest as well as BRequest request contexts? (since what I want is for B's InstanceRequest<AProxy,Void> persist() to be called when my edits are to B objects only.)
Also, AFAICT, if I have an editor on BProxy, any object b that is being shown by the editor (and following the Editor Contract) should automatically be "context.edit(b)"ed by the Driver to make it mutable. However, in my case "context" is an ARequest, not a BRequest.
Do I have to make a ValueAwareEditor like mentioned here: GWT Editor framework
and create a fresh BRequest inside the flush() call and fire it, so that changes to B separately persist in a BRequest before the ARequest is fired?
editorDriver.getPaths() gives me:
"bs"
Also, the driver definitely sees the change to B's property, as editorDriver.isChanged() returns true before I fire() the context.
There are no errors on my client-side or server-side logs, and the Annotation Processor runs with no warnings.
Here's how I setup my driver:
editorDriver = GWT.create(Driver.class);
editorDriver.initialize(rf, view.getAEditor());
final ARequest aRequest = rf.ARequest();
final Request<List<AProxy>> aRequest = aRequest.findAByUser(loginInfo.getUserId());
String[] paths = editorDriver.getPaths();
aRequest.with(paths).fire(new Receiver<List<AProxy>>() {
#Override
public void onSuccess(List<AProxy> response) {
AProxy a = response.get(0);
ARequest aRequest2 = rf.aRequest();
editorDriver.edit(a, aRequest2);
aRequest2.persist().using(a);
}
});
This is how my entities look:
public abstract class PersistentEntity {
public Void persist() {
PersistenceManager pm = getPersistenceManager();
try {
pm.makePersistent(this);
} finally {
pm.close();
}
return null;
}
public Void remove() {
PersistenceManager pm = getPersistenceManager();
try {
pm.deletePersistent(this);
} finally {
pm.close();
}
return null;
}
}
#PersistenceCapable(identityType = IdentityType.APPLICATION)
#Version(strategy=VersionStrategy.VERSION_NUMBER, column="VERSION",
extensions={#Extension(vendorName="datanucleus", key="field-name", value="version")})
public class A extends PersistentEntity {
... (Id, version omitted for brevity)
#Persistent
private String name;
#Persistent
private List<B> bs;
public String getName() {
return name;
}
...
public void setName(String name) {
this.name = name;
}
public List<B> getBs() {
return bs;
}
public void setBs(List<B> bs) {
this.bs = bs;
}
}
... (same annotations as above omitted for brevity)
public class B extends PersistentEntity {
... (Id, version omitted for brevity)
#Persistent
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Here are the proxies:
#ProxyFor(A.class)
public interface AProxy extends EntityProxy {
String getName();
List<BProxy> getBs();
void setName(String name);
void setBs(List<BProxy> bs);
}
#ProxyFor(B.class)
public interface BProxy extends EntityProxy {
String getName();
void setName(String name);
}
Here are my service stubs:
#Service(A.class)
public interface ARequest extends RequestContext {
Request<List<A>> findAByUser(String userId);
InstanceRequest<AProxy, Void> persist();
InstanceRequest<AProxy, Void> remove();
}
#Service(B.class)
public interface BRequest extends RequestContext {
Request<List<A>> findB(String key);
InstanceRequest<BProxy, Void> persist();
InstanceRequest<BProxy, Void> remove();
}
Edit:
I've now changed my ARequest interface and service implementation to support a "saveAndReturn" method, so that I can recursively "persist" "a" on the server side:
Request<UserSandboxProxy> saveAndReturn(AProxy aProxy);
I find now that when I "flush" my RequestFactoryEditorDriver, the client-side context object has my new "b.name" value. However, if I call "context.fire()" and inspect my "saveAndReturn" method on the server side, the resulting server-side object "a", just before I "persist" it, doesn't contain the change to "b.name" on any item of the List.
Why could this be happening? How do I debug why this client-information doesn't go across the wire, to the server?
Options I've considered, tried and ruled out:
1) Ensuring the APT has been run, and there are no warnings/errors on Proxy or Service interfaces
2) Ensuring that my proxies does have a valid setter in AProxy for the List
You have to use a session-per-request pattern for RequestFactory to work properly. More details here: https://code.google.com/p/google-web-toolkit/issues/detail?id=7827

Resources