Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard bugg #9

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
82473f3
installation
Jan 18, 2022
16c27ce
rajout des .catch dans Login.js
Jan 19, 2022
47c7631
sortedBilled OK
Jan 19, 2022
392121d
error and lodin page tests
Jan 19, 2022
2ce444d
tests Bills.js terminé
Jan 19, 2022
5e5bd9c
commentaire
Jan 19, 2022
44a3178
début des newBills Tests
Jan 19, 2022
8d72426
test git
Jan 19, 2022
4c51cce
tests handleSubmit NewBills ok
Jan 19, 2022
07ca246
test du format de l'image lors de la soumission d'un newBill
Jan 20, 2022
3821bf0
commentaire et modif code
Jan 20, 2022
27212e4
commentaire + test si la modale s'ouvre lors du clique sur un oeil
Jan 21, 2022
3d8d7d6
commentaire
Jan 21, 2022
5d382e8
ajout des tests d'intégration de bills.js
Jan 21, 2022
b541439
ajout de commantaires istanbul ignore next
Jan 21, 2022
1a97cfc
ajout de la vérification de 'licone mail en surbrillance si on est su…
Jan 21, 2022
9be8c77
modif commentaire
Jan 21, 2022
0b2238d
com
Jan 22, 2022
e1e638e
modif css image justif (width à 100%)
Jan 22, 2022
b508695
css image justif dashboard + com
Jan 22, 2022
b027dd1
fix bug newBill
Jan 23, 2022
9e66b69
fix vertical navbar srcoll
Jan 23, 2022
4a74f88
commentaire dashboard.js
Jan 23, 2022
46260c3
com
Jan 23, 2022
e6ccb5b
fix bug 4
Jan 24, 2022
0f21464
fix bug 4
Jan 24, 2022
a2ddf40
test d(integration post
Jan 25, 2022
5b01834
com
Jan 25, 2022
5e9a673
ras
Jan 25, 2022
72a3b69
ajout d ela balise accept sur le justificatif
Jan 25, 2022
be5eef6
100% ok
Jan 26, 2022
576bd67
dernier réglages
Jan 26, 2022
5efea78
commentaire
Feb 1, 2022
f5a1e55
ajout des tests e2e
Feb 1, 2022
bccace6
derniere retouche
Feb 9, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"liveServer.settings.port": 8080
}
Binary file added Billed+-+E2E+parcours+administrateur(2).pdf
Binary file not shown.
1 change: 1 addition & 0 deletions setup-jest.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import $ from 'jquery';
global.$ = global.jQuery = $;
$.fn.modal = jest.fn(() => $());// permet d'utiliser jest.fn avec jquerry (vu sur stack overflow)
7 changes: 7 additions & 0 deletions src/__mocks__/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,12 @@ export default {
"fileUrl": "https://test.storage.tld/v0/b/billable-677b6.a…f-1.jpg?alt=media&token=4df6ed2c-12c8-42a2-b013-346c1346f732"
}]
})
},
post:(data)=>{
return Promise.resolve({
data,
status : 200
})
}

}
114 changes: 109 additions & 5 deletions src/__tests__/Bills.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
/**
* @jest-environment jsdom
*/

import { screen } from "@testing-library/dom"
import'@testing-library/jest-dom'
import { screen,fireEvent } from "@testing-library/dom"
import BillsUI from "../views/BillsUI.js"
import Bills from "../containers/Bills.js"
import { bills } from "../fixtures/bills.js"
import {ROUTES_PATH,ROUTES} from "../constants/routes.js"
import store from "../__mocks__/store.js"
import Router from '../app/Router.js'

describe("Given I am connected as an employee", () => {
//billUI tests
describe("When I am on Bills Page", () => {

test("Then bill icon in vertical layout should be highlighted", () => {
const html = BillsUI({ data: []})
document.body.innerHTML = html
//to-do write expect expression

window.localStorage.setItem('user', JSON.stringify({type: 'Employee'}))// défini l'User en tant qu'employé dans le local storage
Object.defineProperty(window, "location", { value: { hash: ROUTES_PATH['Bills'] } });// défini l'url comme étant '#employee/bills'
document.body.innerHTML = `<div id="root"></div>` // crée le noeud pour que le router injecte l'objet correspondant à l'url
Router();// lance le router
expect(screen.getByTestId('icon-window').classList.contains('active-icon')).toBe(true) // vérifie si l'icone est en surbrillance
})

test("Then bills should be ordered from earliest to latest", () => {
const html = BillsUI({ data: bills })
document.body.innerHTML = html
Expand All @@ -23,3 +33,97 @@ describe("Given I am connected as an employee", () => {
})
})
})
describe('Given i am on the loading page',()=>{
test('Should show Loading...',()=>{
const html = BillsUI({loading : true})
document.body.innerHTML = html
expect(screen.getAllByText('Loading...')).toBeTruthy()

})
})

describe('Given i am on error page', () => {
test('should show the error message',()=>{
const html = BillsUI({error : 'error message'})
document.body.innerHTML = html
expect(screen.getAllByText('error message')).toBeTruthy()
})
})

//Bill tests

describe('Given i am on bills page',()=>{
//methode handleClickNewBill
test('Should called the handleClickNewBill method when i click on newBill button',()=>{
window.localStorage.setItem('user', JSON.stringify({type: 'Employee'}))
const html = BillsUI({ data: bills })
document.body.innerHTML = html
let pathname = ROUTES_PATH['Bills']
const onNavigate = ((pathname) => document.body.innerHTML = ROUTES({ pathname }))
const bill= new Bills({
document,
onNavigate
})
const handleClickNewBill = jest.fn(bill.handleClickNewBill)
const buttonNewBill = screen.getByTestId('btn-new-bill')
expect(buttonNewBill).toBeTruthy()
buttonNewBill.addEventListener('click', handleClickNewBill)
fireEvent.click(buttonNewBill)
expect(handleClickNewBill).toHaveBeenCalled()
expect(screen.getByText('Envoyer une note de frais')).toBeTruthy()
})


//methode handleClickIconEye
test('Should called the handleClickIconEye when i click on iconEye',()=>{
const html = BillsUI({ data: bills })
document.body.innerHTML = html
let pathname = ROUTES_PATH['Bills']
const bill= new Bills({
document,
onNavigate: (pathname) => document.body.innerHTML = ROUTES({ pathname })
})
const allIconEye = screen.getAllByTestId('icon-eye')
expect(allIconEye).toBeTruthy()
const iconEye1 = allIconEye[0]
const handleClickIconEye = jest.fn(bill.handleClickIconEye(iconEye1))
iconEye1.addEventListener('click', handleClickIconEye)
expect(iconEye1).toBeTruthy()
fireEvent.click(iconEye1)
expect(handleClickIconEye).toHaveBeenCalled()
const modale = document.getElementById('modaleFile')
expect(modale).toBeTruthy()
expect(modale).toHaveTextContent('Justificatif')
})

})
// test d'intégration GET
describe("Given I am a user connected as Employee", () => {
describe("When I navigate to BillUI", () => {
test("fetches bills from mock API GET", async () => {
const getSpy = jest.spyOn(store, "get") // fonction simulée qui surveille l'appel de la méthode get de l'objet store mocké
const bills = await store.get() //récupère les données du store mocké
expect(getSpy).toHaveBeenCalledTimes(1) //sore.get a été appelé 1 fois
expect(bills.data.length).toBe(4) // les données contiennent 4 objets
})
test("fetches bills from an API and fails with 404 message error", async () => {
store.get.mockImplementationOnce(() => // simule un rejet de la promesse
Promise.reject(new Error("Erreur 404"))

)
const html = BillsUI({ error: "Erreur 404" })
document.body.innerHTML = html
const message = await screen.getByText(/Erreur 404/)
expect(message).toBeTruthy()
})
test("fetches messages from an API and fails with 500 message error", async () => {
store.get.mockImplementationOnce(() =>
Promise.reject(new Error("Erreur 500"))
)
const html = BillsUI({ error: "Erreur 500" })
document.body.innerHTML = html
const message = await screen.getByText(/Erreur 500/)
expect(message).toBeTruthy()
})
})
})
10 changes: 5 additions & 5 deletions src/__tests__/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ describe('Given I am connected as an Admin', () => {
document.body.innerHTML = html
expect(screen.getAllByText('Erreur')).toBeTruthy()
})

})

describe('When I am on Dashboard page and I click on arrow', () => {
Expand Down Expand Up @@ -99,7 +100,7 @@ describe('Given I am connected as an Admin', () => {
document.body.innerHTML = ROUTES({ pathname })
}
const store = null

// modifie le localStorage par le localStorageMock
Object.defineProperty(window, 'localStorage', { value: localStorageMock })
const dashboard = new Dashboard({
document, onNavigate, store, bills, localStorage: window.localStorage
Expand Down Expand Up @@ -211,13 +212,13 @@ describe('Given I am connected as Admin and I am on Dashboard page and I clicked
describe("Given I am a user connected as Admin", () => {
describe("When I navigate to Dashboard", () => {
test("fetches bills from mock API GET", async () => {
const getSpy = jest.spyOn(store, "get")
const bills = await store.get()
const getSpy = jest.spyOn(store, "get") // fonction simulée qui surveille l'appel de la méthode get de l'objet store
const bills = await store.get()
expect(getSpy).toHaveBeenCalledTimes(1)
expect(bills.data.length).toBe(4)
})
test("fetches bills from an API and fails with 404 message error", async () => {
store.get.mockImplementationOnce(() =>
store.get.mockImplementationOnce(() => // simule un rejet de la promesse
Promise.reject(new Error("Erreur 404"))
)
const html = DashboardUI({ error: "Erreur 404" })
Expand All @@ -236,4 +237,3 @@ describe("Given I am a user connected as Admin", () => {
})
})
})

153 changes: 148 additions & 5 deletions src/__tests__/NewBill.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,161 @@
/**
* @jest-environment jsdom
*/

import { screen } from "@testing-library/dom"
import '@testing-library/jest-dom'
import { screen,fireEvent, getByTestId} from "@testing-library/dom"
import NewBillUI from "../views/NewBillUI.js"
import NewBill from "../containers/NewBill.js"

import BillsUI from '../views/BillsUI.js'
import {localStorageMock } from '../__mocks__/localStorage.js'
import { ROUTES ,ROUTES_PATH} from '../constants/routes.js'
import Router from "../app/Router.js"
import store from "../__mocks__/store.js"

describe("Given I am connected as an employee", () => {
describe("When I am on NewBill Page", () => {
test("Then ...", () => {
test("Then mail icon in vertical layout should be highlighted",()=>{
window.localStorage.setItem('user', JSON.stringify({type: 'Employee'}))// défini l'user en tant qu'employé dans le local storage
Object.defineProperty(window, "location", { value: { hash: ROUTES_PATH['NewBill'] } });// défini l'url comme étant '#employee/bill/new'
document.body.innerHTML = `<div id="root"></div>` // crée le noeud pour que le router injecte l'objet correspondant à l'url
Router();// lance le router
expect(screen.getByTestId('icon-mail').classList.contains('active-icon')).toBe(true) // vérifie si l'icone est en surbrillance
})
test("Then Envoyer une note de frais displayed", () => {
const html = NewBillUI()
document.body.innerHTML = html
expect(screen.getAllByText('Envoyer une note de frais')).toBeTruthy()
})

test('Then, I submit form-new-bill, handleSubmit called',()=>{
const html = NewBillUI()
document.body.innerHTML = html
let pathname = ROUTES_PATH['NewBill']
const onNavigate = (pathname) => {
document.body.innerHTML = ROUTES({ pathname })
}

// modifie le localStorage par le localStorageMock
Object.defineProperty(window, 'localStorage', { value: localStorageMock })
window.localStorage.setItem('user', JSON.stringify({type: 'Employee'}))


const newBill = new NewBill({document, onNavigate})
expect(newBill).toBeDefined()
const handleSubmit = jest.fn(newBill.handleSubmit)
const newBillform = screen.getByTestId("form-new-bill")
newBillform.addEventListener('submit', handleSubmit)
fireEvent.submit(newBillform)
expect(handleSubmit).toHaveBeenCalled()

})

test('Then, I click on Justificatif, handleChangeFile called',()=> {
const html = NewBillUI()
document.body.innerHTML = html
let pathname = ROUTES_PATH['NewBill']
const onNavigate = (pathname) => {
document.body.innerHTML = ROUTES({ pathname })
}

// modifie le localStorage par le localStorageMock
Object.defineProperty(window, 'localStorage', { value: localStorageMock })
window.localStorage.setItem('user', JSON.stringify({type: 'Employee'}))
const newBill = new NewBill({document, onNavigate})
const handleChangeFile = jest.fn(newBill.handleChangeFile)
const fileBtn = screen.getByTestId('file')
expect(fileBtn).toBeDefined()
fileBtn.addEventListener('click', handleChangeFile)
fireEvent.click(fileBtn)
expect(handleChangeFile).toHaveBeenCalled()


})

})
})
describe("When I select a file", () => {
test("Then it should be changed in the input", () => {
Object.defineProperty(window, 'localStorage', { value: localStorageMock })// Set localStorage
window.localStorage.setItem('user', JSON.stringify({type: 'Employee'}))// Set user as Employee in localStorage
const html = NewBillUI()
document.body.innerHTML = html
let pathname = ROUTES_PATH['NewBill']

const newBill = new NewBill({
document,
onNavigate: (pathname) => document.body.innerHTML = ROUTES({ pathname }),
firestore: null,
localStorage: window.localStorage,
validFormat : true
})


const handleChangeFile = jest.fn(newBill.handleChangeFile)
const inputFile = screen.getByTestId("file")
inputFile.addEventListener('change', handleChangeFile)
fireEvent.change(inputFile, {
target: {
files: [new File(["test.jpeg"], "test.jpeg", { type: "image/jpeg" })]
}
})
expect(handleChangeFile).toHaveBeenCalled();
expect(inputFile.files[0].name).toBe("test.jpeg");
})
})
// test d'intégration POST
describe("Given I am a user connected as Admin", () => {
describe("When I navigate to Dashboard", () => {
test("fetches bills from mock API POST", async () => {
const html = NewBillUI()
document.body.innerHTML = html
let pathname = ROUTES_PATH['NewBill']

const onNavigate = (pathname) => {
document.body.innerHTML = ROUTES({ pathname })
}
const testBill =
{
"id": "qcCK3SzECmaZAGRrHjaC",
"status": "refused",
"pct": 20,
"amount": 200,
"email": "a@a",
"name": "test2",
"vat": "40",
"fileName": "preview-facture-free-201801-pdf-1.jpg",
"date": "2002-02-02",
"commentAdmin": "pas la bonne facture",
"commentary": "test2",
"type": "Restaurants et bars",
"fileUrl": "https://test.storage.tld/v0/b/billable-677b6.a…f-1.jpg?alt=media&token=4df6ed2c-12c8-42a2-b013-346c1346f732"
}

const getSpy = jest.spyOn(store, "post") // fonction simulée qui surveille l'appel de la méthode post de l'objet store
const bills = await store.post(testBill)
expect(getSpy).toHaveBeenCalledTimes(1)
expect(bills.status).toBe(200)
expect(bills.data.status).toBe("refused")
expect(bills.data.id).toBe("qcCK3SzECmaZAGRrHjaC")


})
test("fetches bills from an API and fails with 404 message error", async () => {
store.post.mockImplementationOnce(() => // simule un rejet de la promesse
Promise.reject(new Error("Erreur 404"))
)
const html = BillsUI({ error: "Erreur 404" })
document.body.innerHTML = html
const message = await screen.getByText(/Erreur 404/)
expect(message).toBeTruthy()
})
test("fetches messages from an API and fails with 500 message error", async () => {
store.post.mockImplementationOnce(() =>
Promise.reject(new Error("Erreur 500"))
)
const html = BillsUI({ error: "Erreur 500" })
document.body.innerHTML = html
//to-do write assertion
const message = await screen.getByText(/Erreur 500/)
expect(message).toBeTruthy()
})
})
})
7 changes: 4 additions & 3 deletions src/app/Store.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@

// renvoi un msg d'erreur si le status de la réponse n'est pas ok
const jsonOrThrowIfError = async (response) => {
if(!response.ok) throw new Error((await response.json()).message)
return response.json()
}


class Api {
constructor({baseUrl}) {
this.baseUrl = baseUrl;
Expand All @@ -25,7 +26,7 @@ class Api {
const getHeaders = (headers) => {
const h = { }
if (!headers.noContentType) h['Content-Type'] = 'application/json'
const jwt = localStorage.getItem('jwt')
const jwt = localStorage.getItem('jwt') //jsonwebtocken
if (jwt && !headers.noAuthorization) h['Authorization'] = `Bearer ${jwt}`
return {...h, ...headers}
}
Expand Down Expand Up @@ -53,7 +54,7 @@ class ApiEntity {
}



// selon la méthode appelé renvoi vers une méthode de l'apiEntity ou crée une nouvelle instance de cette api
class Store {
constructor() {
this.api = new Api({baseUrl: 'http://localhost:5678'})
Expand Down
Loading