I want to test a catch in my code and want to know how i can trigger an error locally with this:
useEffect(() => {
if (!isOpen)
setShowSuccessConfirmation(false);
}, [isOpen]);
const enableSubmission = currentDocuments.length > 0;
const submitPanel = () => {
const documentIds = currentDocuments.map(doc => doc.documentId);
setIsSubmitting(true);
TradingService.requestRenewal(panelState!.modelCode, documentIds)
.then(() => {
setShowSuccessConfirmation(true);
})
.catch(() => {
setShowErrorModal(true);
setShowSuccessConfirmation(false);
})
.finally(() => {
setIsSubmitting(false);
});
};
Related
I am trying to connect to 3 api's but from one button click essentially - and I want each process to start after the previous has finished. However, currently it just executes the first if statement and does not run the next two.
Is their a different approach I should take?
const syncAccount = () => {
if(!mavenlinkConnected){
getMavenlinkAuthorization()
}
if (!bambooConnected){
authorizeBamboo();
}
if (!maconomyConnected){
authorizeMaconomy();
}
}
Below is the other functions that are in relation to the above code block
useEffect(() => {
if (loading) return;
if (!user) return navigate("/");
fetchUserName();
if(userTokenCode !== null){
authorizeMavenlink();
}
}, [user, loading]);
const authorizeMavenlink = () => {
console.log(uid);
const userRef = doc(db, 'users', uid);
axios({
method: 'post',
url: 'http://localhost:5000/oauth/mavenlink?code='+userTokenCode,
data: {}
})
.then((response) => {
setAccessToken(response.data);
setDoc(userRef, { mavenlinkAccessToken: response.data}, { merge: true });
setMavenlinkConnected(true);
setSuccessAlert(true);
})
.catch((error) => {
console.log(error);
setErrorAlert(true)
});
}
const getMavenlinkAuthorization = () => {
window.open('https://app.mavenlink.com/oauth/authorize?client_id=********&response_type=code&redirect_uri=http://localhost:3000');
window.close();
}
const authorizeBamboo = () => {
// axios({
// method: 'post',
// url: 'http://localhost:5000/oauth/bamboo',
// data: {}
// })
// .then((response) => {
// console.log(response)
// })
// .catch((error) => {
// console.log(error);
// });
console.log('bamboo connected')
setBambooConnected(true);
}
const authorizeMaconomy = () => {
console.log("Maconomy connected")
setMaconomyConnected(true);
}
As you are saying you are calling API's on each if statement
You should mark your function as async and wait for each execution.
Example:-
const syncAccount = async() => {
if(!mavenlinkConnected){
await getMavenlinkAuthorization()
}
if (!bambooConnected){
await authorizeBamboo();
}
if (!maconomyConnected){
await authorizeMaconomy();
}
}
or you use promises
const syncAccount = () => {
if(!mavenlinkConnected){
getMavenlinkAuthorization().then({
if (!bambooConnected){
return authorizeBamboo();
} else {
return Promise.resolve();
}
}).then(() => {
if (!maconomyConnected){
return authorizeMaconomy();
}
}).catch(error => {
//log error
})
}
}
Best of luck! Happy coding...
I'm very confused to chose the better one, can you suggest which one is better choice and why ?
App.js
with abortcontroller
useEffect(() => {
const abortCtrl = new AbortController();
const opts = { signal: abortCtrl.signal };
fetch(URL, opts)
.then((response) => response.json())
.then((data) => setTodo(data))
.catch((error) => console.log(error.message));
return () => abortCtrl.abort();
}, []);
with local variable
useEffect(() => {
let isActive = true;
fetch(URL)
.then((response) => response.json())
.then((data) => {
if (isActive) {
setTodo(data);
}
})
.catch((error) => console.log(error.message));
return () => {
isActive = false;
};
}, []);
here userlist is updating immediately what can be correct code for above logic
I am trying fetch userlist from firestore than traversing that list to find user details from different collection
useEffect(() => {
db.collection("following/" + Credens.uid + "/userFollowing")
.get()
.then((snapshot) => {
followingList = snapshot.docs.map((value, ind) => value.data());
})
.then(() => {
if (followingList.length > 0) {
followingList.map((value, index) => {
db.collection("Postss")
.doc(value.useruid)
.collection("MovieWatched")
.get()
.then((snaps) => {
// let Detail = snap.data()
let movieidList = snaps.docs.map(
(value) => value.data().postMovieId
);
if (movieidList.includes(MovieId) === true) {
setuserList((prev) => [...prev, value.useruid]);
}
});
});
}
})
.then(() => {
console.log(userList);
userList.map((value, index) => {
db.collection("users")
.doc(value)
.get()
.then((snapshot) => {
setfriendsWatchedData((prev) => [
...prev,
{
usersID: value,
userData: snapshot.data(),
},
]);
});
});
});
// return () => {
// cleanup
// }
}, []);
To be sure the state did change, you can use the useEffect() to monitor the changing of that state like:
useEffect(() => {
if (userList) {
// userList.map....
}
}, [userList])
Additional conditions can be specified in the if statement. The hook will run whenever the state changes.
I have a function that looks like the following:
const func = () =>
new Promise((resolve, reject) =>
asyncFunc()
.then(data =>
axios.post('someAPI', {
data
})
)
.then(response => {
asyncFunc1(response.data)
resolve(response.data)
})
.catch(err => reject(err)
);
I have read through the documentation of jest and mocking async functions, but it does not seem to cover the scope of this function. Can someone provide some insight into testing functions of this complexity?
EDIT:
Here is the function and current testing:
export const refreshAuth = () =>
new Promise((resolve, reject) =>
getRefreshToken()
.then(refreshJWT =>
axios.post(`${SomeAPI.auth}/refresh`, {
refreshJWT
})
)
.then((res: AxiosResponse<JWTData>) => {
onSignIn(res.data.accessJWT, res.data.refreshJWT);
resolve(res.data.accessJWT);
})
.catch(err => {
console.error('failed to refresh the access token', err);
reject(err);
})
);
export const onSignIn = (access: string, refresh: string) =>
Promise.all([
SecureStore.setItemAsync(REFRESH_KEY, refresh),
SecureStore.setItemAsync(ACCESS_KEY, access)
]);
export const getRefreshToken = () => SecureStore.getItemAsync(REFRESH_KEY);
And Testing:
describe('OAuth2', () => {
it('Runs all promise chains within refreshAuth()', async done => {
const data = {
data: {
accessJWT: 'token',
refreshJWT: 'refresh'
}
};
const getItemAsync = jest.fn().mockResolvedValue({ refreshToken: 'refresh' });
const mockOnSignIn = jest.fn().mockResolvedValue({});
const mockPostAxios = mockedAxios.post.mockResolvedValue(data);
return OAuth2.refreshAuth().then(() => {
expect(getItemAsync).toHaveBeenCalled();
expect(mockPostAxios).toHaveBeenCalled();
expect(mockOnSignIn).toHaveBeenCalledWith(
data.data.accessJWT,
data.data.refreshJWT
);
});
});
});
I'm trying to do some enzyme/jest unit testing for a asynchronous function in my reactJS component, which gets injected as prop.
My Problem is to test for a value in the then() part of the function and to test for catch() if an error occures.
This is how the function of my component (<CreateAccount />) looks like:
_onSubmit = (event) => {
event.preventDefault()
const { username, password } = this.state
this.props.createUserMutation({
variables: { username, password }
}).then(response => {
const token = response.data.createUser.token
if (token) {
Cookies.set('auth-token', token, { expires: 1 })
}
}).catch(error => {
console.warn(error)
})
}
The first test should check for .catch(error => {}) as data is undefined:
it('_onSubmit() should throw error if data is missing', () => {
const createUserMutation = () => {
return Promise.resolve({})
}
const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
wrapper.update().find(Form).simulate('submit', {
preventDefault: () => {}
})
const state = wrapper.instance().state
expect(wrapper).toThrow() // <-- How to do it correctly?
})
And the second test should check if cookie is set correctly. Here I don't know how to do that? I think I have to mock Cookie
it('_onSubmit() should get token', () => {
const createUserMutation = () => {
return Promise.resolve({
data: {
createUser: { token: 'token' }
}
})
}
const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
wrapper.find(Form).simulate('submit', {
preventDefault: () => {}
})
// How to check for token value and Cookies?
})
What I usually have to do when I want to see if the spy worked on the catch or then, is to add another then() on the test. For example:
it('_onSubmit() should throw error if data is missing', () => {
const createUserMutation = jest.fn(() => Promise.reject(new Error()));
const spy = jest.spyOn(console,"warn");
const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
wrapper.update().find(Form).simulate('submit', {
preventDefault: () => {}
});
return createUserMutation.catch(() => {
expect(wrapper).toMatchSnapshot();
})
.then(() => {
expect(spy).toHaveBeenCalledTimes(1);
});
})
I guess it is somehow related to how NodeJS handles the queues, promises, ticks, etc, internally.
That is the rejected/catch branch. If you want to test the IF path, just use a Promise.resolve and return a promise.then() instead of catch.
Why are you using console.warn for an error? Use console.error instead. You will need to mock it out to a spy as well to test it.
First test:
it('_onSubmit() should throw error if data is missing', (done) => {
const createUserMutation = () => new Promise();
const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
wrapper.update().find(Form).simulate('submit', {
preventDefault: () => {}
})
const state = wrapper.instance().state
createUserMutation.resolve().then(() => {
expect(console.warn).toHaveBeenCalled();
done();
});
})
If you are running this in a mock browser environment and not a real browser then you must mock out Cookies.set.
Second test:
it('_onSubmit() should get token', (done) => {
const createUserMutation = () => new Promise();
const wrapper = shallow(<CreateAccount createUserMutation={createUserMutation} />)
wrapper.find(Form).simulate('submit', {
preventDefault: () => {}
});
jest.spyOn(window.Cookies, 'set');
const response = {
data: {
createUser: { token: 'token' }
}
}
createUserMutation.resolve(response).then(() => {
expect(window.Cookies.set).toHaveBeenCalled();
done();
});
})
afterEach(() => {
// Reset the spies so that they don't leak to other tests
jest.restoreAllMocks();
});