Hey folks. I’m trying write a unit test that dispatches an event. The event is dispatched like this in the view ns:

(r/dispatch [:timeline/init (r-dom/dom-node comp) {}])
I need to use dom-node because the event creates a new object (a timeline from the vis js lib, to be more precise: The issue is that I don’t know how to simulate this dom-node in the unit test. I tried to use (.getElementById js/document “app”) and pass it to :timeline/init but it gets nil.

p-himik 2021-04-23T18:20:27.322700Z

If you test in a browser, you can always create a new element. But since this particular event ends up mutating something in the DOM in an explicit way, such a test might affect other tests.

p-himik 2021-04-23T18:22:17.322900Z

Ah, actually, I might be wrong, because by default that element is not inserted: But you might need to insert it into the document if vis-timeline expects it to be there.


To be more specific, the event does this:

(new vis/Timeline
                             (clj->js opts))
where node is something coming from the event parameters (when it’s called from the view, (r-dom/dom-node comp)). This inserts timeline in the document as a child of node.

p-himik 2021-04-23T18:46:58.323500Z

Ideally, you should do it in an effect handler, not an event handler.


Yeah, I considered that. But setting it as an effect wouldn’t solve the original issue of the test, right? I’m not sure I got your previous suggestion.

p-himik 2021-04-23T18:50:40.323900Z

It would allow you test the event handler in isolation, if it does any relevant work apart from calling (new ...).

p-himik 2021-04-23T18:51:01.324100Z

My previous suggestion is to use document.createElement instead of document.getElementById.

p-himik 2021-04-23T18:51:09.324300Z

Only for tests, of course.


Got it. Yeah, the event does other things too. I’ll see what I can do. Thanks.

Mitch 2021-04-23T19:44:05.328500Z

There is some discussion in the #lsp about adding code navigation to re-frame registry and a few questions are popping up. Light testing shows that the two scenarios below work in re-frame, but it is unclear whether they are defined behavior: 1. Is it specified whether you are allowed to register the same id to different kinds? (e.g. Could I register :start as a subscription and a coeffect?) 2. Is it specified whether id's need to be keywords? For example, registering 'a-symbol as an event handler works.



kennytilton 2021-04-23T22:10:24.328600Z

Great idea. That would avoid our situation where our own wrapper tries to launch without the data, then our wrapper gets confused because it did not anticipate this use case. I actually sorted things out before noticing the "new thing" use case, in which no data is expected. So I have to distinguish those two with a payload that includes :create-or-modify indicator in some form. Thx for the simple solution! 🙏

kennytilton 2021-04-23T22:20:25.328800Z

I am humbled, @p-himik and @emccue. Thanks so much for these. I am totally going with a solution in which the modal looks for :team-editor-data or some such, and chained dispatch sees to it that the modal gets one complete delivery when everything is ready for the modal. And it turns out I missed the "new team" use case, in which no http-get of any existing team will be needed. So there will just be a single payload indicating "create" or "edit", and various paths will end by adding that to app db, just as your examples suggest. Bravo #re-frame!

p-himik 2021-04-23T22:30:00.329Z

1. You can. All handler kinds are independent. You can use :start as a subscription ID, an event ID, an effect ID, a coeffect ID - all at the same time. 2. IDs can be anything.