Tests with redux async action and axios - redux

I have been learning testing with
mocha
chai
sinon
enzyme
now I am testing a redux async application, and I want to know if the arguments provided to some API calls are correct, how do I do that?
I'm thinking of something like axios.getCall().args to get the arguments provided for the API call and then verify if they are correct but I can't find a command that matches what I am thinking.

I found out how,
first stub the method
axios.post = sinon.stub().returns(Promise.resolve({ data: 'test' }));
then dispatch the async action
store.dispatch(updateTodos(currentState))
.then(() => {
// this line would get the call and then get the argument
let args = axios.post.getCalls()[0].args;
done();
});

Related

Firebase Functions unable to run HelloWorld example with Unity

I try to call the most basic https function from unity, but I always get an internal error.
I deployed the function and it works when called by the browser:
https://us-central1-infinite-space-rpg.cloudfunctions.net/helloWorld
Node.js code:
const functions = require("firebase-functions");
exports.helloWorld = functions.https.onRequest((request, response) => {
functions.logger.info("Hello logs!", {structuredData: true});
response.send("Hello from Firebase!");
});
unity code:
FirebaseFunctions functions = FirebaseFunctions.DefaultInstance;
var func = functions.GetHttpsCallable("helloWorld");
func.CallAsync().ContinueWithOnMainThread((response) =>
{
Debug.Log("result: " + response.Result.Data.ToString());
});
This is the faulted error response I get:
In the firebase dashboard I can see that the function gets called and it also completes without an error.
So the setup should be fine, but the "one or more errors occurred(INTERNAL) does not give any hint on what might be the issue.
Permissions should also be fine, all users can invoke the function.
I really hope that someone has an idea!
also tried the exact sample from firebase with the same error.
https://firebase.google.com/docs/functions/get-started
I`m now stuck with this since 2 days, is there a better place to ask such a specific question, maybe a firebase support forum?

unit testing firebase HttpsFunctions

I am using firebase https function and am running unit tests on them. When calling the https function to be tested, the firebase documentation suggest to simply call it within my test file like this:
toBeTestesFunction()
This is my firebase https function:
export const toBeTestedFunction = https.onRequest(async (req, resp) => {
bla bla bla
}
Now my problem is that onRequest takes a callback which in my case is asynchronous and needs to be awaited. However onRequest return the type HttpsFunction which is of type:
TriggerAnnotated & ((req: Request, resp: Response) => void);
Since it does not return a promise I cannot await it. This makes the content in the function which has a callback that is asynchronous untestable. In the firebase documentation they give an exmaple which seems flawed (https://firebase.google.com/docs/functions/unit-testing?authuser=0#test-background).
Any help is much appreciated
Thanks

Post request redux thunk

I have GET requests and normally when those succeeded I save data in store, but for POST requests I need to know if it succeeded or not, in order to execute some code (show a message and redirect), the docu says you can use an isLoading variable, but it just says if the service is working but not if it succeeded, if I try to create a new success variable in the store, it will be turned on forever after the request and I don't need that either. I tried returning a promise from the action creator and handle response directly inside the component but it looks like the same to call axios there instead of using redux.
My action creator looks like this:
export function createProject(userId, projectName) {
return function (dispatch) {
dispatch({ type: projectsActions.START_CREATE_PROJECT });
return ProjectsService.createProject(userId, projectName).then(() => {
dispatch({ type: projectsActions.SUCCESS_CREATE_PROJECT });
}).catch((error) => {
dispatch({ type: projectsActions.ERROR_CREATE_PROJECT });
throw error;
});
}
}
I understand where your doubts are coming from, it doesn't seem appropriate to have a field on your Redux store only to know the success of a one-time request.
If you only need to make a post request and only care about it's result once, the simplest way to do it is to use state in the component making the request. Component-level state is easily manageable and gets removed from memory when the component is unmounted, but on the other hand you may want to have a single source of truth for your app. You have to make a choice, but your Redux implementation is correct.

Firebase callable + express?

With functions.https.onRequest(app); it was possible to use express right away.
I'm wondering if it's possible to use functions.https.onCall(...) together with express in the same way?
onCall(...) seem to have a different signature but maybe there is still a way to keep using express while working with onCall(...) functions?
No, it's not possible. Callable functions force your endpoint to use a certain path, a certain type of input (JSON via POST) and a certain type of output (also JSON). Express wouldn't really help you out, given the constraints of how callables work. You can read about all the callable protocol details in the documentation. You can see that callables abstract away all of the details of the request and response, which you would normally work with when using Express.
What does work however is using onRequest and calling that... then you can use express like normal and have the simplicity of firebase callable on the client side...
then you can do your authorization like normal. For example with the following middleware:
export const createFirebaseAuth = () => (req: express.Request, res: express.Response, next: express.NextFunction) => {
console.log('Time: ', Date.now());
const token = req.header('Authorization');
if (!token) {
res.status(400);
res.send('Authtoken must be sent with a request');
return;
}
admin
.auth()
.verifyIdToken(token.replace('Bearer ', ''))
.then((v) => {
req.user = v;
next();
})
.catch((error) => {
res.status(401);
res.send(error.message);
res.end();
});
}

redux-saga and firebase - Can't log the user out in a clean way

As a preface, let me mention that I have never used redux-saga or Firebase before today. I'm currently playing around to get a feel for both technologies.
I'm probably just missing a small concept, but I can't seem to get signout to work on my app. I figured that I should probably use call() to manage side effects within a saga, but nothing does the trick.
Here's the saga in question:
export function* deauthenticateUser() {
yield takeLatest(DEAUTHENTICATE_REQUEST, function* () {
try {
yield call(firebase.auth().signOut)
yield put({ type: DEAUTHENTICATE })
}
catch (error) {
yield put({
type: DEAUTHENTICATE_FAILURE,
payload: error,
error: true,
})
}
})
}
I confirmed that calling firebase.auth().signout() directly works, it's only when using call() that I get the error action. Note that there's also no payload when the error gets dispatched.
I checked in Firebase's documentation, and apparently firebase.auth().signout() returns a promise with nothing as it's content. I'm starting to wonder if that wouldn't be the problem, maybe redux-saga does not like having no result in it's promise when using call()?
How would one handle authentication and especially logging out with Firebase and redux-saga?
From a comment from NULL SWEΔT, I had to call yield call([firebase.auth(), firebase.auth().signOut]).
The reason for this is because of JS' context and how this works. More details by reading this and this (read documentation for call([context, fn], ...args)).

Resources