Strategy for testing POST to API without changing database - javascript

I'm using jasmine-node to test my API, and it has worked great for my GET routes. Now, however, I need to test some POSTs and I'm not sure how to go about this without changing my database.
One thought I had was to reset whatever value I change at the end of each spec.
Is this reasonable or is there a better way to go about testing POST requests to my API?

Wrap anything that modifies your database into a transaction. You can have your database changes and then rollback after each test.

usually you are supposed to have a test database, so modify that one is not a big issue. also, a general approach would be not to rely on predefined values on the database (i.e, the GET always request the SAME object..) but try with different objects each time. (using predefined objects may hide problems when the data is slighty different..).
in order to implement the second strategy, you can execute a test with a POST with pseudo-random data to create a new object, and use the returned ID to feed the following GET, UPDATE and finally the DELETE tests.

Just make a duplicate processing page/function and send the data to that for debugging. Comment out anything that makes changes to the database.
Alternatively, pass a variable in your call such as "debug" and have an if/else section in your original function for debugging, ignoring the rest of the function.
Another alternative still is to duplicate your database table and name it debug table. It will have the same structure as your original. Send the test data to it instead and it won't change your original database tables.

I'm pretty sure that you've come up with some solution for your problem already.
BUT, if you don't, the Angular $httpBackend will solve your problem. It is a
Fake HTTP backend implementation suitable for unit testing applications that use the $http service.

Related

js / vue app doing CRUD, how can I track what needs updating?

I'm working on a vue app that uses vuex and gets objects from an api. The tables have paging and fetch batches of objects from the api, sometimes including related entities as nested objects. The UI allows some editing via inputs in a table, and adds via modals.
When the user wants to save all changes, I have a problem: how do I know what to patch via the api?
Idea 1: capture every change on every input and mark the object being edited as dirty
Idea 2: make a deep copy of the data after the fetch, and do a deep comparison to find out what's dirty
Idea 3: this is my question: please tell me that idea 3 exists and it's better than 1 or 2!
If the answer isn't idea 3, I'm really hoping it's not idea 1. There are so many inputs to attach change handlers to, and if the user edits something, then re-edits back to its original value, I'll have marked something dirty that really isn't.
The deep copy / deep compare at least isolates the problem to two places in code, but my sense is that there must be a better way. If this is the answer (also hoping not), do I build the deep copy / deep compare myself, or is there a package for it?
It looks like you have the final state on the UI and want to persist it on the server. Instead of sending over the delta - I would just send over the full final state and overwrite whatever there was on server side
So if you have user settings - instead of sending what settings were toggled - just send over the "this is what the new set of settings is"
Heavy stuff needs to be done on the server rather than the client most of the time. So I'll follow the answer given by Asad. You're not supposed to make huge objects diffs, it's 2022 so we need to think about performance.
Of course, it also depends of your app, what this is all about. Maybe your API guy is opposed to it for a specific reason (not only related to performance). Setup a meeting with your team/PO and check what is feasible.
You can always make something on your side too, looping on all inputs should be feasible without manually doing that yourself.
TLDR: this needs to be a discussion in your company with your very specific constrains/limitations. All "reasonable solutions" are already listed and you will probably not be able to go further because those kind of "opinion based" questions are not allowed anyway on SO.

REST API Ajax simultaneously requests

Is it wrong to make multiple ajax simultaneously requests to different endpoints of a REST API that end up modifying the same resource?
Note: each endpoint will modify different properties.
For example, let's assume that one endpoint modifies some properties for an order, like order_date and amount and another endpoint set's the link between the same order and a customer by changing the customer_id value from the orders table (I know that maybe this is not the best example, all these updates can be done with one endpoint).
Thanks in advance!
This is totally a requirements based question. It is generally a bad idea to have a single resource be changed by multiple processes, but this ONLY matters if there is a consistency relationship between the data. Consider some of the following questions:
If one or more of the AJAX calls fails does will that break your application? If it will, then yes, this is a bad idea. Will your application carry on regardless of what data you have at any given time? If so, then no this doesn't matter.
Take some time to figure out what dependencies you have between your data calls and you will get your answer.
what you are describing is not a shared resource even if it is stored in the same object because you are modifying different properties however take great care when using same object. if your requests to the server depends on the properties that are modified by the other request.
in general its not a good idea to use the same object to store data that is modified by more than one asynchronous function even if the properties are different. it makes your code confusing and harder to maintain since you have to manually coordinate your function calls to prevent race condition.
there are better ways to manage your asynchronous code using Promises or Observables
It's a bad idea in general. But if your code is small and you can manage it then you can do it though its not recommended.
In the long run, it will cause you many problems confusion, maintaining code, consistency etc.
And if in any case another developer has to manage your code, It will be more confusing and tough for him.
In programming always keep things flexible and think in long run. Your requirements can change in future , what will you do then? write the whole program again? This is one thing , you also want to avoid.

Waiting for one publish to finish before starting another

I have yet to find a relatively good solution for this. Maybe the community can help?
I'm pulling data into my meteor app from some restful end points. One builds on the other. For example..I hit one end point and get a collection of authors. then I need to hit a second endpoint to pull the books each of the authors have written.
Right now I have two separate publish functions on the server side to get the sets of data, however the second one relies on the data from the first. (My initial foray in my app was simply to do it all in one publish, but this felt like not the best architecture)
Is there any way to subscribe to another publish from within another publish server side? Or, some other method of checking that i can do?
So far the internet and stack overflow have yielded little results. I am aware of the publishComposite packages available.. but they seem relatively heavy handed and don't necessarily seem applicable to what I'm trying to do. Any advice would be greatly appreciated
i suggest a divide and conquer strategy. you have basically 2 questions to answer:
for the collections, am i going to do a client-side or server-side join?
what drives calling the remote service to get the new data?
i think you can build these pieces separately and tie them together with the db and Meteor's reactivity.
e.g. you can start by writing the code that hits the remote REST APIs. i think the strategy there is to make the authors call, get the data, then make the books calls. i would do that in one function, tied together with promises. when the book data returns, write it and the authors data to their respective collections (if you don't already have that data), ensuring the foreign keys are intact. now you can tie that function to a button press, and that part is done for now.
next you can move on to the collections and publishing that data. you'll have to decide, as i mentioned, where to do that join. but do the publish(es) in such a way that, per standard Meteor practice, when the collections update in the db, your client gets the updated data.
at this point, you can test everything is storing correctly and updating reactively when you push the button.
the last piece is to decide what drives the API call, to replace the button push. as i'd mentioned in the comments, perhaps a cron job, but maybe there's something else going on in your app that makes it more natural. the danger of putting in the publish, as i think you already know, is that you could get 50 simultaneous subscribes, and you don't want to hit that REST API 50x.

Can I make Rails' CookieStore use JSON under the hood?

I feel like it should be obvious doing this from reading the documentation, but maybe somebody can save me some time. We are using Ruby's CookieStore, and we want to share the cookie with another server that is part of our website which is using WCF. We're already b64-decoding the cookie and we are able to validate the signature (by means of sharing the secret token), all of that is great... but of course the session object is marshalled as a Ruby object, and it's not clear what is the best way to proceed. We could probably have the WCF application make a call to Ruby and have it unmarshal the object and write it out as JSON, but that seems like it will add an unnecessary layer of complexity to the WCF server.
What I'd really like to do is maybe subclass CookieStore, so that instead of just b64 encoding the session object, it writes the object to JSON and then b64's it. (And does the reverse on the way back in, of course) That way, the session token is completely portable, I don't have to worry about Ruby version mismatches, etc. But I'm having trouble figuring out where to do that. I thought it would be obvious if I pulled up the source for cookie_store.rb, but it's not (at least not to me). Anybody want to point me in the right direction?
(Anticipating a related objection: Why the hell do we have two separate servers that need to be so intimately coordinated that they share the session cookie? The short answer: Deadlines.)
Update: So from reading the code, I found that when the MessageVerifier class gets initialized, it looks to see if there is an option for :serializer, and if not it uses Marshal by default. There is already a class called JSON that fulfills the same contract, so if I could just pass that in, I'd be golden.
Unfortunately, the initialize function for CookieStore very specifically only grabs the :digest option to pass along as the options to MessageVerifier. I don't see an easy way around this... If I could get it to just pass along that :serializer option to the verifier_for call, then achieving what I want would literally be as simple as adding :serializer => JSON to my session_store.rb.
Update 2: A co-worker found this, which appears to be exactly what I want. I haven't gotten it to work yet, though... getting a (bah-dump) stack overflow. Will update once again if I find anything worthy of note, but I think that link solves my problem.

Lift session-valid ajax callback from a static javascript

I am currently implementing a graph visualisation tool using lift on the server side and d3 ( a javascript visualisation framework) for all the visualisation. The problem I have is that in the script I want to get session dependent data from the server.
So basically, my objective is to write lift-valid ajax callbacks in a static js script.
What I have tried so far
If you feel that the best solution is one that I already tried feel free to post a detailed answer telling me how to use it exactly and how it completely solves my problem.
Write the ajax callback in another script using lift and call it from the main script
This solution, which is similar to a hidden text input is probably the more likely to work. However it is not elegant and it would mean that I would have to load a lot of scripts on load, which is not really conveniant.
This seems to be one of the prefered solutions in the lift community as explained in this discussion on the mailing list.
REST interface
Usually what one would do to get data from a javascript function in lift is to create a REST interface. However this interface will not be linked to any session. This is the solution I got from my previous question: Get json data in d3 from lift snippet
Give function as argument of script
Another solution would be to give the ajaxcallback as an argument of the main script called to generate my graph. However I expect to have a lot of callbacks and I don't want to have to mess with the arguments of my script.
Write the whole script in lift and then serve it to the client
This solution can be elegant, however my script is very long and I would really prefer that it remainss static.
What I want
On client side
While reviewing the source code of my webpage I found that the callback for an ajaxSelect is:
<select onchange="liftAjax.lift_ajaxHandler('F966066257023LYKF4=' + encodeURIComponent(this.value), null, null, null)" name="F96606625703QXTSWU" id="node_delete" class="input">
Moreover, there is a variable containing the state of the page in the end of the webpage:
var lift_page = "F96606625700QRXLDO";
So, I am wondering if it is possible to simulate that my ajaxcall is valid using this liftAjax.lift_ajaxHandler function. However I don't know the exact synthax to use.
On server side
Since I "forged" a request on client side, I would now like to get the request on client side and to dispatch it to the correct function. This is where the LiftRules.dispatch object seems the best solution: when it is called, all the session management has been made (the request is authentified and linked to a session), however I don't know how to write the correct piece of code in the append function.
Remark
In lift all names of variables are changed to a random string in order to increase the security, I would like to have the same behavior in my application even if that will probably mean that I will have to "give" the javascript these values. However an array of 15 string values is still a better tradeoff than 15 functions as argument of a javascript function.
Edit
While following my research I found this page : Mapping server functions to client actions which somehow explains the goal of named functions even if it stil didn't lead me to a working solution.
Quick Answer
Rest in Lift does not have to be stateless. If you register your RestHelper with LiftRules.dispatch.append, then it will be handled statefully and Session information will be available through the S object as usual.
Long Answer
Since you seem interested, and it's come up on SO before, here's a more detailed explanation of how server-side functions are registered and called in Lift. If you haven't worked with Lift for some time, look away. What follows should not in any way be used to evaluate Lift or its complexity. This is purely library developer level stuff and a majority of Lift users go about their development blissfully unaware of it.
How it works
When you create stateful callbacks, typically by using the methods within the SHtml object, what you are really doing is registering objects of type S.AFuncHolder within the context of the users session, each with a unique ID. The unique ID that was generated during this process is what you're seeing when you come across a pattern like F96606625700QRXLDO. When data is submitted, via form post, ajax, or whatever, Lift will check the request for these function ids and execute the associated function if they exist. There are several helpers that provide more specific types of AFuncHolder, like S.SFuncHolder (accepts a single string query parameter) and S.BinFuncHolder (parameter is multipart form data) but they all return Any and behind the scenes Lift will collect those return values to create the proper type of response. A JsCmd, for instance, will result in a JavaScriptResponse that executes the command. You can also return a LiftResponse directly.
How to use it
AFuncHolders are registered using the S.fmapFunc method. You'd call it like this
S.fmapFunc(SFuncHolder({ (str: String) =>
doSomethingAwesomeWithAString(str)
}))(id => <input type="text" name={id} value=""/>)
The first parameter is your function, wrapped in the proper *FuncHolder type and the second parameter is a function that takes the generated id and outputs something. The something that gets output is what you will include on the page. It should somehow result in the id being sent to the server as a query parameter so that your function is executed.
Putting it all together
You could use the above to make your own Ajax calls, but when Lift makes an ajax call there are a few other considerations:
1) Most browsers only allow so many simultaneous connections to a given domain. Three seems to be the magic number.
2) AFuncHolders will often close over the scope of the snippet they are contained within and if multiple ajax requests are handled at once, each in its own thread, bad things can happen.
To combat these issues, the liftAjax.lift_ajaxHandler function queues each ajax request, ensuring that only one at a time is sent to the server.
The drawback to this approach is that it can make it difficult to make an Ajax call where the result needs to be passed to a callback. JQuery autocomplete, for instance, provides a callback function when input changes that accepts a list of matches. If you are manually calling LiftAjax.lift_ajaxHandler though, you can provide your own callback functions for success & error and I would recommend that you look at the source of those functions in your browser for more information on how they work.
There's actually more to it, like how Lift restores RequestVars on ajax callbacks (which is where the lift_page comes in, but that's about all I'm prepared to explain over coffee on a Saturday morning :)
Good luck with your app!

Categories

Resources