Categories
discuss

How to test dynamic imports (then and catch) with Jest

So I have been struggling with how to test dynamic imports generally and in this case, especially in jest, I have been reading a lot on the internet but did not find anything concrete, so I thought about bringing the question up to centralize a decent solution.

I have the following methods inside of a class

class MyClass {
   successMethod() {  ...  }

   errorMethod() { ... }

    myMethod() {
        return import('./myFile.js')
           .then(() => this.successMethod())
           .catch(() => this.errorMethod());
    }
}

My question is:

How do you mock both Success and Failing promise cases for this dynamic import using Jest to make sure each method (successMethod and errorMethod) are called when resolving or failing respectively?.

I found jest.doMock helps for mocking the resolved case but did not find a way to make the dynamic import fail by mocking it so the catch case is uncovered.

Note: this is not a react application, this is a Vanilla JS project.

Answer

Prototype methods can be spied or mocked on either MyClass.prototype or class instance. Module mocks and spy functions should be restored for each test in order for them to not affect each other.

let myClass;
beforeEach(() => {
  jest.resetModules();
  jest.restoreAllMocks();
  myClass = new MyClass();
  jest.spyOn(myClass, 'successMethod');
  jest.spyOn(myClass, 'errorMethod');
});

jest.doMock requires to import all affected modules after it was called. In order for dynamic import to result in rejected promise, myFile module should throw an error when evaluated. Since dynamic import returns a promise, tests should be asynchronous.

it('...', async () => {
  jest.mock('./myFile.js', () => 'value');
  await expect(myClass.myMethod()).resolves.toEqual(/* return value from successMethod */);
  expect(myClass.successMethod).toBeCalled();
  expect(myClass.errorMethod).not.toBeCalled();
});

it('...', async () => {
  jest.mock('./myFile.js', () => { throw new Error() });
  await expect(myClass.myMethod()).rejects.toThrow(/* error message from errorMethod */);
  expect(myClass.successMethod).not.toBeCalled();
  expect(myClass.errorMethod).toBeCalled();
});
Categories
discuss

Share or Export External tools without using jar-file

I created custom “run configuration” and used in him “external tools”
my problem is that “external tools” are located locally and other developers of the project will not receive it, how can I add it to the project?

One solution is to export the studio settings, get a jar file, but then each developer will have to manually import this jar file, I want to avoid that.

Answer

Maybe this would help ya
https://intellij-support.jetbrains.com/hc/en-us/community/posts/206187849-Sharing-external-tool-config-via-version-control

There are some “hackish” ways you could probably handle this (via symlinks or junctions), if you just need to run a script, I would recommend using Ant (or even Gradle). Either have Ant do the actual work, or write a simple ant script that wraps and launches the external script (via the or target for example). The script, the ant build, and its “Before Launch” configuration can then all be committed to version control.

Categories
discuss

Add file filters to JavaFx Filechooser in Jython and parametrize them

I created a javaFX chooser file in Jython. It wasn’t easy to port from Java to Jython, but in the end some results came. Now I would like to parameterize the obtained class, taking into account the file filters, so as to be able to use the object for browsing different from the type of filtered files.
I tried to insert a fixed filter:

import sys

from javafx.application import Application
from javafx.stage import FileChooser, Stage

class fileBrowser(Application):

    @classmethod
    def main(cls, args):
        fileBrowser.launch(cls, args)

    def start(self, primaryStage):
        fc = FileChooser()
        filter = FileChooser.ExtensionFilter("All Images", '*.jpg')
        fc.getExtensionFilters().add(
            filter
        )

        f = fc.showOpenDialog(primaryStage)

if __name__ == '__main__':
    fileBrowser.main(sys.argv)

But I have the following error:

Exception in Application start method
Traceback (most recent call last):
  File "provaFileChooser.py", line 28, in <module>
    fileBrowser.main(sys.argv)
  File "provaFileChooser.py", line 15, in main
    fileBrowser.launch(cls, args)
        at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$1(LauncherImpl.java:182)
        at java.lang.Thread.run(Unknown Source)
Caused by: Traceback (most recent call last):
  File "provaFileChooser.py", line 19, in start
    filter = FileChooser.ExtensionFilter("JPG Images", '*.jpg')
TypeError: javafx.stage.FileChooser$ExtensionFilter(): 2nd arg can't be coerced to java.util.List, String[]

        at org.python.core.Py.TypeError(Py.java:236)
        at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java:213)
        at org.python.core.PyReflectedFunction.throwBadArgError(PyReflectedFunction.java:316)
        at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java:325)
java.lang.RuntimeException: java.lang.RuntimeException: Exception in Application start method

I also tried to cast the filter into a list and to insert the filter into a list but the error persists.

What am I doing wrong, and what should I do?
Thanks in advance.

Answer

You can solve your StackTrace using vector to parse the extension types, like this:

import sys

from java.io import File

from javafx.application import Application
from javafx.stage import FileChooser, Stage

class FileBrowser(Application):
    
    # I am a class attribute, Im called using NameClass.me
    # You have to remember this path is different according to SO
    initalDir = File("/home/miolivc/Documents/") # you have to handle this
    extensions = ["*.jpg"]

    @classmethod
    def main(cls, args):
        FileBrowser.launch(cls, args)

    def start(self, primaryStage):

        fc = FileChooser()
        filter = FileChooser.ExtensionFilter("All Images", FileBrowser.extensions)
        fc.getExtensionFilters().add(filter)
        fc.setInitialDirectory(FileBrowser.initalDir)

        choosed = fc.showOpenDialog(primaryStage)

        print("File: " + str(choosed))

if __name__ == '__main__':
    FileBrowser.main(sys.argv)

About using FileBrowser in others parts of your code, you have to understand how JavaFX works, you can use file in Controller class constructor and call this view using Scene class. FileBrowser is extending Application class, this mean that is the root of your app, you should call others from this one.

To understand more about this, I suggest you search about Scene and FXMLLoader.

I tested using Zulu Java FX 11 and Jython 2.7.1

Categories
discuss

Google Play Billing Subscription: new policy for mandatory “Hold”: what needs to be changed in the app UI?

Google will change its policy on the 1st of Nov 2020 : subscription “Hold” will need to be enabled https://android-developers.googleblog.com/2020/06/new-features-to-acquire-and-retain-subscribers.html

At the moment, here is how I query if a user has purchased my subscription or not (there is only 1 subscription in my app) and grant him privileges accordingly:

private void queryPurchase() {
    Purchase.PurchasesResult purchasesResult = mBillingClient.queryPurchases(BillingClient.SkuType.SUBS);
    if (purchasesResult != null) {
        if (purchasesResult.getPurchasesList() != null) {
            if (purchasesResult.getPurchasesList().size() > 0) {
                String purchaseToken = purchasesResult.getPurchasesList().get(0).getPurchaseToken();

                if (purchasesResult.getPurchasesList().get(0).toString().contains("productId":"" + "myID")) {
                    //grant user subscription's privileges
                }
            }
            else {
                //do not grant user subscription's privilege
            }
        }
    }
}

My questions are :

  1. Will this method still properly detect whether or not a subscription is on hold?
  2. Do I need to add anything in terms of UI/messaging specifically related to a Hold status?

Answer

Since the 1st of November several of my apps were changed only on the server side, nothing related to UI/messaging to the user. And since I didn’t get any rejection or warning, I would conclude there was no UI/messaging changes required. It would be great if Google requirements were more clear to avoid such a waste of time!

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..