I am currently trying to do a test on media queries but I can't figure out. How possibly I can change width of the window so it reflects to media query.
I have tried all commented code to mock the width but no use. I know it has something to do with jsdom but cant figure out.
it('when image is WIDE and media match with medium', () => {
Object.defineProperty(window, 'innerWidth', {writable: true, configurable: true, value: 900})
// window.resizeBy = jest.fn();
// window.resizeBy(900,300);
//const mediaQuery = '(min-width: 790px)';
// Object.defineProperty(window, "matchMedia", {
// value: jest.fn(() => { return { matches: true,media: mediaQuery } })
// });
// Object.defineProperty(window,'innerWidth', {
// configurable: true,
// writable: true,
// value: 790
// });
// Object.defineProperty(window,'innerHeight', {
// configurable: true,
// writable: true,
// value: 900
// });
window.matchMedia = jest.fn().mockImplementation(query => {
//query always display (min-width: 240px) and (max-width: 767px)
return {
matches: true,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
};
});
const result = imageStretcher(aWideImage);
expect(result).toEqual({ imgWidth: '90%', imgHeight: '40%' });
});
This is the code I want to test.
const screenResolution = {
smallSize: '(min-width: 240px) and (max-width: 767px)',
mediumSize: '(min-width: 768px) and (max-width: 1200px)',
};
const sizeTypes = {
smallSize: 'smallSize',
mediumSize: 'mediumSize',
normalSize: 'normalSize',
};
const sizeSettings = {
[PORTRAIT]: {
smallSize: { imgWidth: '62%', imgHeight: '50%' },
mediumSize: { imgWidth: '95%', imgHeight: '75%' },
normalSize: { imgWidth: '70%', imgHeight: '90%' },
},
[WIDE]: {
smallSize: { imgWidth: '90%', imgHeight: '30%' },
mediumSize: { imgWidth: '90%', imgHeight: '40%' },
normalSize: { imgWidth: '65%', imgHeight: '80%' },
},
};
const screenResolutionMatcher = (imageType: number) => {
if (window.matchMedia(screenResolution.smallSize).matches) {
return setNewImageSize(imageType, sizeTypes.smallSize);
} else if (window.matchMedia(screenResolution.mediumSize).matches) {
return setNewImageSize(imageType, sizeTypes.mediumSize);
} else {
return setNewImageSize(imageType, sizeTypes.normalSize);
}
};
export const imageStretcher = (source: string) => {
//....
return screenResolutionMatcher(imageType);
}
};
OK finally after having crazy rough time with this I have figured it out this way it test medium screen.
it('when image is WIDE and media match with medium', () => {
window.matchMedia = jest.fn().mockImplementation(query => ({
matches: query !== '(min-width: 240px) and (max-width: 767px)',
media: '',
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn()
}));
const result = imageStretcher(aWideImage);
expect(result).toEqual({ imgWidth: '90%', imgHeight: '40%' });
});
Related
Hi I can I test a function like this? I cannot test it properly because it says that relation "facilities" does not exist, however I now it exists because I can add a new record.
I should I test this code:
export async function postMemberController(req, res) {
try {
if (req.decodedToken.user_id || req.decodedToken.id) {
const facility = await db.facility.findOne({
where: { id: req.body.facility_id },
raw: true,
});
if (!facility?.id) {
res.send(
"no facilities"
);
} else {
let member = await db.member.findOne({
where: { id_no: Number(req.body.id_no) },
raw: true,
});
const admin = await db.user.findOne({
where: { facility_id: req.body.facility_id },
raw: true,
});
const data = await db.sequelize.transaction(async t => {
if (member?.id_no) {
await db.member
.update(
{
...req.body,
facility_id: [...new Set([...member.facility_id, req.body.facility_id])],
},
{ where: { id_no: member.id_no } },
{ transaction: t }
)
.catch(e => console.log('error : creation MEMBER??? ', e));
const adminToken = await tokenCreator({ ...admin }, 3);
!req.body?.from &&
(await axios
.put(
`${process.env.CENTRAL_URL}/members`,
{
body: {
...req.body,
facility_id: [...new Set([...member.facility_id, req.body.facility_id])],
from: 'web',
},
where: { id: member.id },
},
{
headers: { authorization: 'Bearer ' + adminToken },
}
)
.catch(e => console.log('erorr ', e.response.data, e.config.url)));
} else {
const auth = adminFirebase.auth;
const firebaseToken = await auth.createCustomToken(generateUUID());
member = await db.member
.create(
{
...req.body,
firebase_token: firebaseToken,
facility_id: [req.body.facility_id],
creator: admin.user_id,
updater: admin.user_id,
},
{ transaction: t }
)
.catch(e => console.log('error : creation MEMBER??? ', e));
if (member) {
const card = await db.card.findOne({
where: { card_id: member.dataValues.card_id },
raw: true,
});
if (card) {
await db.card.update(
{ card_number: req.body.card_number },
{
where: {
card_id: member.dataValues ? member.dataValues.card_id : member.card_id,
},
},
{ transaction: t }
);
} else {
const newCard = await db.card.create(
{
card_number: req.body?.card_number,
card_id: member?.dataValues?.card_id,
creator: admin.user_id,
updater: admin.user_id,
facility_id: req.body.facility_id,
credits: 0,
},
{ transaction: t }
);
}
}
const adminToken = await tokenCreator({ ...admin }, 3);
!req.body?.from &&
(await axios
.post(
`${process.env.CENTRAL_URL}/members`,
{
...req.body,
id: member.dataValues.id,
card_id: member.dataValues ? member.dataValues.card_id : member.card_id,
facility_id: req.body.facility_id,
from: 'web',
},
{
headers: { authorization: 'Bearer ' + adminToken },
}
)
.catch(e => console.log('erorr ', e, e?.response?.data, e.config.url)));
!req.body?.from &&
(await axios
.put(
`${process.env.CENTRAL_URL}/cards`,
{
body: {
card_number: req.body.card_number.toString(),
facility_id: req.body.facility_id,
from: 'web',
},
where: {
card_id: member.dataValues ? member.dataValues.card_id : member.card_id,
},
},
{
headers: { authorization: 'Bearer ' + adminToken },
}
)
.catch(e => console.log('erorr ', e.response.data, e.config.url)));
}
return member;
});
delete data.dataValues?.password;
delete data?.password;
const memberToken = await tokenCreator({ ...data.dataValues }, 3);
return res
.status(200)
.json({ data, session_id: data.id_no || data.dataValues.id_no, token: memberToken });
}
} else {
return res.sendStatus(401);
}
} catch (error) {
res.status(500).send(error.message);
}
}
this is how I try to test it:
it('post member from web terminal', async () => {
try {
jest.mock('../db/models/index.js', () => {
const SequelizeMock = require('sequelize-mock');
const dbMock = new SequelizeMock();
const facility = dbMock.define('facilities', {
id: '6-30189',
})
const member = dbMock.define('members', {});
const card = dbMock.card('cards', {});
});
const req = {
decodedToken: { user_id: makeId() },
body: member,
};
const res = {
sendStatus(num) {},
status(num) {
return { json(payload) {}, send(payload) {} };
},
};
const request = await postMemberController(req, res);
delete member.from;
expect(request).toHaveBeenCalledWith({ ...member });
} catch (error) {
console.log('ERROR post member ', error);
throw new Error(error);
}
});
How do I write a test for this???? when I call postMemberController inside jest it seems that can't find the relations in the table, I tried to console.log db.facility object from jest test output, there is nothing, not even empty object or null or undefined. I don't understand why? How can I solve this??
Here is the object I am sending:
const card_number = 11111111111111;
const card_id = makeId();
const schedule = makeId();
const club = makeId();
const trainer = makeId();
const user = makeId();
const facility_id = '6-30189';
const member = {
from: 'central',
card_number: card_number,
id: makeId(),
first_name: 'Demo',
last_name: 'Demo',
id_no: card_number,
card_id,
home_phone: null,
urgent_phone: null,
email: null,
registered: true,
schedule,
club,
trainer,
birthplace: 'Gölbaşı/Ankara',
birthdate: new Date().toISOString(),
father_name: null,
mother_name: null,
gender: null,
profession: null,
address: null,
phone_number: null,
hes_code: null,
blood_type: null,
nationality: null,
profile_photo: null,
is_employee: false,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
firebase_token: null,
file: null,
session_ids: null,
facility_id,
following: null,
creator: user,
updater: user,
};
**I am getting the error when I am connecting the frontend code as well as backend code with the database maybe the problem might be in front end but pls let me know the meaning of the error because I am newbie.I am getting the error on register pls help me and also when I register the website using frontend it shows me error on **localhost/register
enter image description here
const express = require('express');
const { listen } = require('express/lib/application');
const bodyParser=require('body-parser');
const bcrypt=require('bcrypt-nodejs')
const cors = require('cors')
const knex = require('knex');
const { response } = require('express');
const db=knex({
client: 'pg',
connection: {
host : '127.0.0.1',
user : 'postgres',
password : '224898',
database : 'smart-brain'
}
});
const app = express();
app.use(bodyParser.json());
app.use(cors())
const database={
users:[
{
id:'123',
name:'John',
email:'John#gmail.com',
password:'ABC',
entries:0,
joined:new Date()
},
{
id:'124',
name:'ABC',
email:'ABC',
password:'123',
entries:0,
joined:new Date()
}
],
login:[
{
id:'987',
hash:'',
email:'John#gmail.com'
}
]
}
app.get('/' ,(req,res)=>{
res.send(database.users);
})
app.post('/signin',(req,res)=>{
if(req.body.email===database.users[0].email && req.body.password===database.users[0].password){
res.json(database.users[0]);
}else{
res.status(400).json('error login in');
}
})
app.post('/register',(req,res)=>{
const{email,name,password}=req.body;
db('users')
.returning('*')
.insert({
email:email,
name:name,
joined: new Date()
})
.then(user=>{
res.json(user[0]);
})
. catch(err => console.log(err))
})
app.get('/profile/:id',(req,res)=>{
const{id}=req.params;
let found=false;
database.users.forEach(user=>{
if(user.id===id){
found=true;
return res.json(user);
}
})
if(!found){
res.status(400).json('not found');
}
})
app.put('/image',(req,res)=>{
const{id}=req.body;
let found=false;
database.users.forEach(user=>{
if(user.id===id){
found=true;
user.entries++
return res.json(user.entries);
}
})
if(!found){
res.status(400).json('not found');
}
})
// // Load hash from your password DB.
// bcrypt.compare("bacon", hash, function(err, res) {
// // res == true
// });
// bcrypt.compare("veggies", hash, function(err, res) {
// // res = false
// });
app.listen(3000,()=>{
console.log('app is running on port 3000 ');
})
AND ALSO I AM SHARING FRONTEND APP.JS CODE
APP.js code
import './App.css';
import Navigation from './Components/Navigation/Navigation';
import FaceRecognition from './Components/FaceRecognition/FaceRecognition';
import Logo from './Components/Logo/Logo'
import ImageLinkForm from './Components/ImageLinkForm/ImageLinkForm'
import Rank from './Components/Rank/Rank'
import { Component } from 'react';
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import SignIn from './Components/SignIn/SignIn';
import Register from './Components/Register/Register'
const USER_ID = 'aad';
const PAT = 'bd69e06e68f244ed83b9ce09ee560e7c';
const APP_ID = 'aaa';
const MODEL_ID = 'face-detection';
const MODEL_VERSION_ID = '45fb9a671625463fa646c3523a3087d5';
const particlesOption = {
fpsLimit: 120,
particles: {
links: {
color: "#ffffff",
distance: 150,
enable: true,
opacity: 0.5,
width: 1,
},
collisions: {
enable: true,
},
move: {
direction: "none",
enable: true,
outModes: {
default: "bounce",
},
random: true,
speed: 5,
straight: true,
},
},
detectRetina: true,
}
const particlesInit = async (main) => {
await loadFull(main);
};
const initialState = {
input: '',
imageUrl: '',
box: {},
route:'signin',
isSignedIn:false,
user: {
id: '',
name: '',
email: '',
joined: '',
entries: 0
}
};
class App extends Component {
constructor() {
super();
this.state = initialState;
};
loadUser = (data) => {
this.setState({
user: {
id: data.id,
name: data.name,
email: data.email,
entries: data.entries,
joined: data.joined
}
})
}
apiData = () => {
const raw = JSON.stringify({
"user_app_id": {
"user_id": USER_ID,
"app_id": APP_ID
},
"inputs": [
{
"data": {
"image": {
"url": this.state.input
}
}
}
]
});
const requestOptions = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Authorization': 'Key ' + PAT
},
body: raw
};
return requestOptions;
}
displayFaceBox = (box) => {
this.setState({ box: box });
}
onInputChange=(event) =>{
this.setState({input: event.target.value});
}
onImageSubmit = () => {
this.setState({ imageUrl: this.state.input });
const requestOptions = this.apiData();
fetch("https://api.clarifai.com/v2/models/" + MODEL_ID + "/versions/" + MODEL_VERSION_ID + "/outputs", requestOptions)
.then(response => response.text())
.then(result => JSON.parse(result))
.then(obj => {
if (obj) {
fetch('http://localhost:3000/image', {
method: 'put',
headers: {'content-type': 'application/json'},
body: JSON.stringify({
id: this.state.user.id
})
})
.then(response => response.json())
.then(count => {
this.setState(Object.assign(this.state.user, {entries: count}))
})
}
this.displayFaceBox(this.calculateFaceLocation(obj))
})
.catch(error => console.log('error', error));
}
calculateFaceLocation = (data) => {
const clarifaiFace = data.outputs[0].data.regions[0].region_info.bounding_box;
const image = document.getElementById('inputimage');
const width = Number(image.width);
const height = Number(image.height);
return ({
leftCol: clarifaiFace.left_col * width,
topRow: clarifaiFace.top_row * height,
rightCol: width - (clarifaiFace.right_col * width),
bottomRow: height - (clarifaiFace.bottom_row * height),
})
}
onRouteChange=(route)=>{
if(route==='signout'){
this.setState({isSignedIn:false})
}else if(route==='home'){
this.setState({isSignedIn:true})
}
this.setState({route:route})
}
render(){
const { imageUrl, box ,isSignedIn,route} = this.state;
return (
<div className="App">
<Particles className='particles'
init={particlesInit}
options={particlesOption}
/>
<Navigation isSignedIn={isSignedIn} onRouteChange={this.onRouteChange} />{ route==='home'?
<div>
<Logo />
<Rank name={this.state.user.name} entries={this.state.user.entries}/>
<ImageLinkForm onInputChange={this.onInputChange}
onImageSubmit={this.onImageSubmit}/>
<FaceRecognition box={box} imageUrl={imageUrl} />
</div> :(
route==='signin'?
<SignIn loadUser={this.loadUser} onRouteChange={this.onRouteChange} />
: <Register loadUser={this.loadUser}onRouteChange={this.onRouteChange}/>
)
}
</div>
);
}
}
export default App;
Do not use images for textual information, copy and paste the text into the question. This would make the following easier.
From error message code:23502. If you go here Error codes you find that corresponds to 23502 not_null_violation. So the value that is being set to NULL is being entered into a column that has NOT NULL set. Your choices are:
a) Make sure the value is not set to NULL.
b) If you can have NULL values in the column drop the NOT NULL constraint.
in order to cover all statements/branch/lines, I need to write two or more fn.spec.ts to test fn.ts, how can I merge fn.spec.ts and fn2.spec.ts to be one file ?
// fn.ts
export const getEnv = () => {
if (location.href.indexOf('localhost') !== -1 || /\d+\.\d+\.\d+\.\d+/.test(location.href)) {
return 'Test'
}
return 'Product'
}
// fn.spec.ts
describe('fn getEnv',()=>{
Object.defineProperty(window, 'location', {
value: {
href: 'http://192.168.2.3:9001'
},
})
const { getEnv } = require('./fn')
test('getEnv',()=>{
expect(getEnv()).toBe('Test')
})
})
// fn2.spec.ts
describe('fn getEnv',()=>{
Object.defineProperty(window, 'location', {
value: {
href: 'https://xx.com'
},
})
const { getEnv } = require('./fn')
test('getEnv',()=>{
expect(getEnv()).toBe('Product')
})
})
// jest.config.js
module.exports = {
testEnvironment: 'jest-environment-jsdom', // browser environment
}
Just merge it into one file with a clear expectation message.
import { getEnv } from './fn';
describe('fn', () => {
describe('getEnv', () => {
test('should return "Test" when window location is an IP address', () => {
Object.defineProperty(window, 'location', {
value: {
href: 'http://192.168.2.3:9001'
},
});
const actual = getEnv();
expect(actual).toBe('Test');
});
test('should return "Product" when window location is a domain', () => {
Object.defineProperty(window, 'location', {
value: {
href: 'https://xx.com'
},
});
const actual = getEnv();
expect(actual).toBe('Product');
})
});
});
I am planning to use XState for managing states in the backend of my application. When an api is called, a function will be called on successful state change. The result of the function call has to be returned as response of the api.
// Returns a Promise, e.g.:
// {
// id: 42,
// name: 'David',
// friends: [2, 3, 5, 7, 9] // friend IDs
// }
function getUserInfo(context) {
return fetch('/api/users/#{context.userId}').then(response =>
response.json()
);
}
// Returns a Promise
function getUserFriends(context) {
const { friends } = context.user;
return Promise.all(
friends.map(friendId =>
fetch('/api/users/#{context.userId}/').then(response => response.json())
)
);
}
const friendsMachine = Machine({
id: 'friends',
context: { userId: 42, user: undefined, friends: undefined },
initial: 'gettingUser',
states: {
gettingUser: {
invoke: {
src: getUserInfo,
onDone: {
target: 'gettingFriends',
actions: assign({
user: (context, event) => event.data
})
}
}
},
gettingFriends: {
invoke: {
src: getUserFriends,
onDone: {
target: 'success',
actions: assign({
friends: (context, event) => event.data
})
}
}
},
success: {
type: 'final'
}
}
});
interpret(friendsMachine).start()
I want the output of this of getUserFriends sent as a response from my api. How to wait for the transition and all the invocations to be completed?
You can use onDone (read the docs on invoking promises 📖)
Here's an example Express app that waits sequentially for 2 promises to finish, and then sends that data:
function eventuallyGet(value) {
return new Promise(res => {
setTimeout(() => {
res(value);
}, 1000)
})
}
const getUserMachine = Machine({
initial: 'fetchingName',
context: {
user: undefined
},
states: {
fetchingName: {
invoke: {
src: () => eventuallyGet('David'),
onDone: {
target: 'fetchingDetails',
actions: assign({
user: (ctx, e) => ({
...ctx.user,
name: e.data
})
})
}
}
},
fetchingDetails: {
invoke: {
src: () => eventuallyGet({ location: 'Florida' }),
onDone: {
target: 'success',
actions: assign({
user: (ctx, e) => ({
...ctx.user,
...e.data
})
})
}
}
},
success: {
type: 'final',
data: {
user: ctx => ctx.user
}
}
}
});
app.get('/user', function(request, response) {
interpret(getUserMachine)
.onDone(e => {
response.json(e.data);
})
.start();
});
You can see the code here: https://glitch.com/~pleasant-relish
I'm using Material-UI's useMediaQuery() function in one of my components to determine the size prop to use for a <Button> within the component.
I'm trying to test that it's working as expected in a jest test, however my current implementation isn't working:
describe("Unit: <Navbar> On xs screens", () => {
// Incorrectly returns `matches` as `false` ****************************
window.matchMedia = jest.fn().mockImplementation(
query => {
return {
matches: true,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn()
};
}
);
it("renders as snapshot", async () => {
const width = theme.breakpoints.values.sm - 1;
const height = Math.round((width * 9) / 16);
Object.defineProperty(window, "innerWidth", {
writable: true,
configurable: true,
value: width
});
const { asFragment } = render(
<Container backgroundColor={"#ffffff"}>
<Navbar />
</Container>
);
expect(asFragment()).toMatchSnapshot();
const screenshot = await generateImage({
viewport: { width, height }
});
expect(screenshot).toMatchImageSnapshot();
});
});
describe("Unit: <Navbar> On md and up screens", () => {
// Correctly returns `matches` as `false` ****************************
window.matchMedia = jest.fn().mockImplementation(
query => {
return {
matches: false,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn()
};
}
);
it("renders as snapshot", async () => {
const width = theme.breakpoints.values.md;
const height = Math.round((width * 9) / 16);
Object.defineProperty(window, "innerWidth", {
writable: true,
configurable: true,
value: width
});
const { asFragment } = render(
<Container backgroundColor={"#ffffff"}>
<Navbar />
</Container>
);
expect(asFragment()).toMatchSnapshot();
const screenshot = await generateImage({
viewport: { width, height }
});
expect(screenshot).toMatchImageSnapshot();
});
});
And the component I'm testing (removed irrelevant parts):
const Navbar = () => {
const theme = useTheme();
const matchXs = useMediaQuery(theme.breakpoints.down("xs"));
return (
<Button size={matchXs ? "medium" : "large"}>
Login
</Button>
);
};
export default Navbar;
It's returning matches as false for the first test, even though I've set it to return as true. I know this because it's generating a screenshot and I can see that the button size is set to large for the first test when it should be set to medium.
It works as expected in production.
How do I correctly get mock useMediaQuery() in a jest test?
The recommended way is using css-mediaquery which is now mentioned in the MUI docs:
import mediaQuery from 'css-mediaquery';
function createMatchMedia(width) {
return query => ({
matches: mediaQuery.match(query, { width }),
addListener: () => {},
removeListener: () => {},
});
}
describe('MyTests', () => {
beforeAll(() => {
window.matchMedia = createMatchMedia(window.innerWidth);
});
});
I figured it out...
useMediaQuery() needs to re-render the component to work, as the first render will return whatever you define in options.defaultMatches (false by default).
Also, the mock needs to be scoped to each test (it), not in the describe.
As I'm using react-testing-library, all I have to do is re-render the component again and change the scope of the mock and it works.
Here's the working example:
const initTest = width => {
Object.defineProperty(window, "innerWidth", {
writable: true,
configurable: true,
value: width
});
window.matchMedia = jest.fn().mockImplementation(
query => {
return {
matches: width >= theme.breakpoints.values.sm ? true : false,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn()
};
}
);
const height = Math.round((width * 9) / 16);
return { width, height };
};
describe("Unit: <Navbar> On xs screens", () => {
it("renders as snapshot", async () => {
const { width, height } = initTest(theme.breakpoints.values.sm - 1);
const { asFragment, rerender} = render(
<Container backgroundColor={"#ffffff"}>
<Navbar />
</Container>
);
rerender(
<Container backgroundColor={"#ffffff"}>
<Navbar />
</Container>
);
expect(asFragment()).toMatchSnapshot();
const screenshot = await generateImage({
viewport: { width, height }
});
expect(screenshot).toMatchImageSnapshot();
});
});
describe("Unit: <Navbar> On md and up screens", () => {
it("renders as snapshot", async () => {
const { width, height } = initTest(theme.breakpoints.values.md);
const { asFragment } = render(
<Container backgroundColor={"#ffffff"}>
<Navbar />
</Container>
);
rerender(
<Container backgroundColor={"#ffffff"}>
<Navbar />
</Container>
);
expect(asFragment()).toMatchSnapshot();
const screenshot = await generateImage({
viewport: { width, height }
});
expect(screenshot).toMatchImageSnapshot();
});
});
A simple approach that worked for me:
component.tsx
import { Fade, Grid, useMediaQuery } from '#material-ui/core';
...
const isMobile = useMediaQuery('(max-width:600px)');
component.spec.tsx
import { useMediaQuery } from '#material-ui/core';
// not testing for mobile as default
jest.mock('#material-ui/core', () => ({
...jest.requireActual('#material-ui/core'),
useMediaQuery: jest.fn().mockReturnValue(false),
}));
describe('...', () => {
it(...)
// test case for mobile
it('should render something for mobile', () => {
((useMediaQuery as unknown) as jest.Mock).mockReturnValue(true);
....
})
Inspired by #iman-mahmoudinasab's accepted answer, here is a TypeScript implementation. Essentially, we would want to create valid MediaQueryList-object:
// yarn add -D css-mediaquery #types/css-mediaquery
import mediaQuery from 'css-mediaquery';
describe('Foo Bar', () => {
beforeAll(() => {
function createMatchMedia(width: number) {
return (query: string): MediaQueryList => ({
matches: mediaQuery.match(query, { width }) as boolean,
media: '',
addListener: () => {},
removeListener: () => {},
onchange: () => {},
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => true,
});
}
// mock matchMedia for useMediaQuery to work properly
window.matchMedia = createMatchMedia(window.innerWidth);
});
});
Maybe we can do something like this:
const applyMock = (mobile) => {
window.matchMedia = jest.fn().mockImplementation((query) => {
return {
matches: mobile,
media: query,
addListener: jest.fn(),
removeListener: jest.fn(),
};
});
};
and use it like this:
const mockMediaQueryForMobile = () => applyMock(true);
const mockMediaQueryForDesktop = () => applyMock(false);