Reputation: 240
// get submit button and add event listener to it
const submitBtn = document.getElementById("submit");
if(submitBtn){
submitBtn.addEventListener('click', loginFunction)
}
//call back function
function loginFunction(e){
e.preventDefault();
// the data to post
const data = {
email: document.getElementById("email").value,
password: document.getElementById("password").value,
};
// post the data to db via fetch
fetch("https://store-manager-api-app-v2.herokuapp.com/api/v2/auth/login",{
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin':'*',
'Access-Control-Request-Method': '*'
},
method:"POST",
mode: "cors",
body: JSON.stringify(data)
}).then(function(response){return response.json()})
.then(function(response){
localStorage.setItem('token', response.token);
if (response.Message === "User logged in successfully!"){
// redirect to index page
document.getElementById("notify").innerHTML =`<div class="isa_success">
<i class="fa fa-check"></i>
${response.Message}
</div>`;
window.location.assign('../HTML/index.html')
}
else{
let notify = document.getElementById("notify");
notify.innerHTML =`<div class="isa_info">
<i class="fa fa-info-circle"></i>
${response.Message}
</div>`
}
})
}
This is my login.js file that listens to a submit button and then performs a fetch to login the user.
Below is my login.test.js file..this is the test for the login.js, but it ain't working. I've tried changing await Promise.resolve.then()
to jest.UseFakeTimers()
but it ain't working. Anyone have an idea why it is not working, and a possible solution?
describe('login',() => {
let fetchMock;
let assignMock;
beforeEach(() => {
document.body.innerHTML +=`
<div id="notify">
</div>
<form id="signin">
<input type="email" id="email" value="[email protected]">
<input type="password" id="password" value ="test1234">
<input type="submit" id="submit">
</form>`;
fetchMock = jest.spyOn(global,'fetch');
fetchMock.mockImplementation(() =>Promise.resolve ({
json: () => Promise.resolve({Message:"User logged in successfully!"})
}));
assignMock = jest.spyOn(window.location , "assign");
assignMock.mockImplementation(() =>{});
require('../UI/js/login');
});
afterEach(() => {
fetchMock.mockRestore();
assignMock.mockRestore();
jest.resetModules()
});
it('fetch data and change the content of #notify', async function() {
document.getElementById('submit').click();
expect(fetchMock).toHaveBeenCalledTimes(1);
const fetchArgs = fetchMock.mock.calls[0];
expect(fetchArgs[0]).toBe('https://store-manager-api-app-v2.herokuapp.com/api/v2/auth/login');
expect(fetchArgs[1]).toEqual({
method: "POST",
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin':'*',
'Access-Control-Request-Method': '*'
},
mode: "cors",
body: JSON.stringify({
email: '[email protected]',
password: "test1234"
})
});
await Promise.resolve().then();
expect(document.getElementById('notify').innerHTML).toBe(`<div class="isa_success">
<i class="fa fa-check"></i>
User logged in successfully!
</div>`);
expect(assignMock).toHaveBeenCalledTimes(1);
expect(assignMock.mock.calls[0][0]).toBe("../HTML/index.html");
});
});
This is the error i'm getting:
Error: expect(received).toBe(expected) // Object.is equality
Expected: "<div class=\"isa_success\">
<i class=\"fa fa-check\"></i>
User logged in successfully!
</div>"
Received: "
"
Difference:
- Expected
+ Received
- <div class="isa_success">
- <i class="fa fa-check"></i>
- User logged in successfully!
- </div>
+
+ <Click to see difference>
45 | });
46 | await Promise.resolve().then();
> 47 | expect(document.getElementById('notify').innerHTML).toBe(`<div class="isa_success">
| ^
48 | <i class="fa fa-check"></i>
49 | User logged in successfully!
50 | </div>`);
at Object.toBe (__tests__/login.test.js:47:58)
at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
at step (__tests__/login.test.js:3:191)
at __tests__/login.test.js:3:361
Upvotes: 2
Views: 2791
Reputation: 240
The solution was rather easy. I just had to add an await Promise.resolve.then()
line to make it work:
describe('login',() => {
let fetchMock;
let assignMock;
beforeEach(() => {
document.body.innerHTML +=`
<div id="notify">
</div>
<form id="signin">
<input type="email" id="email" value="[email protected]">
<input type="password" id="password" value ="test1234">
<input type="submit" id="submit">
</form>`;
fetchMock = jest.spyOn(global,'fetch');
fetchMock.mockImplementation(() =>Promise.resolve ({
json: () => Promise.resolve({Message:"User logged in successfully!"})
}));
assignMock = jest.spyOn(window.location , "assign");
assignMock.mockImplementation(() =>{});
require('../UI/js/login');
});
afterEach(() => {
fetchMock.mockRestore();
assignMock.mockRestore();
jest.resetModules()
});
it('fetch data and change the content of #notify', async function() {
document.getElementById('submit').click();
expect(fetchMock).toHaveBeenCalledTimes(1);
const fetchArgs = fetchMock.mock.calls[0];
expect(fetchArgs[0]).toBe('https://store-manager-api-app-v2.herokuapp.com/api/v2/auth/login');
expect(fetchArgs[1]).toEqual({
method: "POST",
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin':'*',
'Access-Control-Request-Method': '*'
},
mode: "cors",
body: JSON.stringify({
email: '[email protected]',
password: "test1234"
})
});
await Promise.resolve().then();
await Promise.resolve().then(); //on adding this the test passes
expect(document.getElementById('notify').innerHTML).toBe(`<div class="isa_success">
<i class="fa fa-check"></i>
User logged in successfully!
</div>`);
expect(assignMock).toHaveBeenCalledTimes(1);
expect(assignMock.mock.calls[0][0]).toBe("../HTML/index.html");
});
});
Upvotes: 2