I was using jest to write a test for a function and I keep getting hit with an exceeded timeout issue. I tried to solve this by adding a bigger number to the second parameter in my test function and also by changing my jest config settings in my package.json file but both did not work. Any help would be appreciated.
Test File
const favoriteBlog = require('../utils/list_helper').favoriteBlog
describe(("fav blog"), () => {
const listWithOneBlog = [
{
_id: "5a422a851b54a676234d17f7",
title: "React patterns",
author: "Michael Chan",
url: "https://reactpatterns.com/",
likes: 7,
__v: 0
},
{
_id: "5a422aa71b54a676234d17f8",
title: "Go To Statement Considered Harmful",
author: "Edsger W. Dijkstra",
url: "http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html",
likes: 5,
__v: 0
},
{
_id: "5a422b3a1b54a676234d17f9",
title: "Canonical string reduction",
author: "Edsger W. Dijkstra",
url: "http://www.cs.utexas.edu/~EWD/transcriptions/EWD08xx/EWD808.html",
likes: 12,
__v: 0
},
{
_id: "5a422b891b54a676234d17fa",
title: "First class tests",
author: "Robert C. Martin",
url: "http://blog.cleancoder.com/uncle-bob/2017/05/05/TestDefinitions.htmll",
likes: 10,
__v: 0
},
{
_id: "5a422ba71b54a676234d17fb",
title: "TDD harms architecture",
author: "Robert C. Martin",
url: "http://blog.cleancoder.com/uncle-bob/2017/03/03/TDD-Harms-Architecture.html",
likes: 0,
__v: 0
},
{
_id: "5a422bc61b54a676234d17fc",
title: "Type wars",
author: "Robert C. Martin",
url: "http://blog.cleancoder.com/uncle-bob/2016/05/01/TypeWars.html",
likes: 2,
__v: 0
}
]
test("find the blog with the most likes", (blog) => {
const expected = {
title: "Canonical string reduction",
author: "Edsger W. Dijkstra",
likes: 12
}
const result = favoriteBlog(listWithOneBlog)
expect(result).toEqual(expected)
})
})
Function File
const favoriteBlog = (blog) => {
console.log("before is",blog.map(a => a.likes) )
const preArray = blog.map(a => a.likes)
console.log("Math max thing is", Math.max(...preArray))
const objArr = Math.max(...preArray)
console.log("objArr is",objArr)
const favBlog = blog.filter((x) => x.likes == objArr);
const favBlogObj = favBlog[0]
delete favBlogObj._id;
delete favBlogObj.__v;
delete favBlogObj.url;
console.log("Fav blog is now",favBlog)
return favBlogObj
}
module.exports = {
favoriteBlog
}
The test is failing because you have a blog parameter on the test callback, which Jest interprets to be a callback function which you must call to end the test. The param is not used by the test, so I think this is a mistake and should be removed. If you intend to use the callback, then just add blog() as the last statement in the test (perhaps renaming it to done which is the convention).
Completion callbacks are used for some API styles, but in most cases you don't need this parameter and can just end the test, or return a Promise if you are expecting something to end later.
test("find the blog with the most likes", (blog) => {
// ^^^^ HERE
const expected = {
title: "Canonical string reduction",
author: "Edsger W. Dijkstra",
likes: 12
}
const result = favoriteBlog(listWithOneBlog)
expect(result).toEqual(expected)
})
Related
So I want to update a document in Mongo.
I have a document and I want to modify it and send it back. But for some reason, when I do, it changes the value into ObjectId. And I figured out an alternative, but I don't like it...
async updateDogs() {
const cats = await this.catModel.find().exec();
const dog: DogDocument = await this.dogModel
.findOne({ _id: '62b57f65fa0e953b3e0494eb' })
.populate('cats')
.exec();
console.log('All cats:', cats);
console.log('Dingo Dog in find', dog);
dog.cats = cats;
console.log('Dingo dog in find but with Cat ObjectId()', dog.cats);
console.log(dog.cats[0].name);
dog.cats = [];
dog.cats.push(...cats);
console.log('Dingo dog in find and with cat', dog.cats);
console.log(dog.cats[0].name);
}
And this is the output:
All cats: [
{
_id: new ObjectId("62af2508025adb0b7e6e446f"),
name: 'Mikey',
age: 0,
breed: 'string',
__v: 0
},
{
_id: new ObjectId("62b57fd0fa0e953b3e0494f5"),
name: 'Mini',
age: 0,
breed: 'string',
__v: 0
}
]
Dingo Dog in find {
_id: new ObjectId("62b57f65fa0e953b3e0494eb"),
name: 'Dingo',
age: 0,
__v: 0,
cats: [
{
_id: new ObjectId("62af2508025adb0b7e6e446f"),
name: 'Mikey',
age: 0,
breed: 'string',
__v: 0
}
]
}
Dingo dog in find but with Cat ObjectId() [
new ObjectId("62af2508025adb0b7e6e446f"),
new ObjectId("62b57fd0fa0e953b3e0494f5")
]
First cat name is undefined
Dingo dog in find and with cat [
{
name: 'Mikey',
age: 0,
breed: 'string',
_id: new ObjectId("62af2508025adb0b7e6e446f"),
__v: 0
},
{
name: 'Mini',
age: 0,
breed: 'string',
_id: new ObjectId("62b57fd0fa0e953b3e0494f5"),
__v: 0
}
]
First cat name is Mikey
The way i add cats to dog.cats it change the result.
Do you have any idea why ? I Need to have CatDocument and not ObjectId.
And i can do another populate but i don't want to make another request because i already have it. And use push is ugly i think...
Restaurants is a collection and has objects like below:
{
_id: new ObjectId("61723c7378b6d3a5a02d908e"),
name: 'The Blue Hotel',
location: 'Noon city, New York',
phoneNumber: '122-536-7890',
website: 'http://www.bluehotel.com',
priceRange: '$$$',
cuisines: [ 'Mexican', 'Italian' ],
overallRating: 0,
serviceOptions: { dineIn: true, takeOut: true, delivery: true },
reviews: [
{
_id: new ObjectId("61736a0f65b9931b9e428789"),
title: 'asd',
reviewer: 'khoh',
rating: 3,
dateOfReview: '5/12/2002',
review: 'hey'
},
_id: new ObjectId("61736a0f65b9931b9e428790"),
title: 'dom',
reviewer: 'firuu',
rating: 4,
dateOfReview: '25/1/2002',
review: ' bruh'
}
]
}
I am using the below code to find this object based on the review id provided
async get(reviewId) {
const restaurantsCollection = await restaurants();
reviewId = ObjectId(reviewId)
const r = await restaurantsCollection.findOne({reviews: {$elemMatch: {_id: reviewId}}})
return r
This returns the whole object from the restaurant collection, what do I do if I want only the review displayed whose id is provided in get(reviewID)
Output:
{
_id: new ObjectId("61736a0f65b9931b9e428790"),
title: 'dom',
reviewer: 'firuu',
rating: 4,
dateOfReview: '25/1/2002',
review: ' bruh'
}
With a projection, specify the fields to return
The following returns only the review whose id is provided in get(reviewID)
async get(reviewId) {
const restaurantsCollection = await restaurants();
reviewId = ObjectId(reviewId)
const r = await restaurantsCollection.findOne(
{ reviews: { $elemMatch: { _id: reviewId } } },
{ "reviews.$": 1 }
)
return r
}
Test Here
You can also use find instead of fineOne
Query
replace the ObjectId("61736a0f65b9931b9e428789") with reviewId
this will return the reviews that match the _id in an array
if you want to get the first only, in case there is always max 1
you can replace the last project with
{"$project": {"_id": 0, "review": {"$arrayElemAt": ["$reviews", 0]}}}
*not sure if this is what you need
Test code here
aggregate(
[{"$match": {"reviews._id": ObjectId("61736a0f65b9931b9e428789")}}
{"$set":
{"reviews":
{"$filter":
{"input": "$reviews",
"cond":
{"$eq": ["$$this._id", ObjectId("61736a0f65b9931b9e428789")]}}}}},
{"$project": {"_id": 0, "reviews": 1}}])
This might not be the correct answer of your question but you can try something like this.
const r = await restaurantsCollection.findOne({reviews: {$elemMatch: {_id: reviewId}}})?.reviews.find(review => review._id.equals(reviewId))
I'm New To firebase, i have a query
const posts = database.child('posts');
const user = database.child('user');
posts.orderByChild("id").on('child_added', snap => {
let user_id = snap.val().user_id;
let userRef = database.child('user/' + snap.val().user_id)
userRef.on('value', userSnap => {
console.log(userSnap.val().name)
let content = snap.val().content;
let date_posted = snap.val().date_posted;
let id = snap.val().id;
let title = snap.val().title;
let user_id = snap.val().user_id;
let user_Name = userSnap.val().name;
a.push({
"id": id,
"title": title,
"date_posted": date_posted,
"content": content,
"user_Name": user_Name,
"user_id": user_id
})
});
});
before entering UserRef Query, The posts are well sorted With The id,
however after the 2nd query, it's no longer sorted, How Can i make them sorted even after the 2nd query
this is the db structure
!:
i want the output to be like this
{
id: 1,
title: 'My First Post',
date_posted: '2018-05-02 19:40:02',
content: 'This is my firstpost!',
user_Name: 'Abdelrahman',
user_id: '8721da2c-0028-430f-a995-0d03c8abb393'
},
{
id: 2,
title: 'My SecondPost',
date_posted: '2018-05-02 19:41:02',
content: 'This is my Second post!',
user_Name: 'Abdelrahman',
user_id: '8721da2c-0028-430f-a995-0d03c8abb393'
},
{
id: 3,
title: 'test Title',
date_posted: '2021-01-06 08:48:01',
content: 'test Content',
user_Name: 'Abdelrahman',
user_id: '8721da2c-0028-430f-a995-0d03c8abb393'
},
{
id: 4,
title: 'test Title2',
date_posted: '2021-01-06 08:49:42',
content: 'test Content2',
user_Name: 'Abdelrahman',
user_id: '8721da2c-0028-430f-a995-0d03c8abb393'
},
{
id: 5,
title: 'test 3',
date_posted: '2021-01-06 08:54:14',
content: 'COntent 3',
user_Name: 'Abdelrahman',
user_id: '8721da2c-0028-430f-a995-0d03c8abb393'
}
but the output i see is not sorted at all
Usually you store the token as state in vuex. In your method you commit a mutation to set the token state, something like:
this.$store.commit('SET_TOKEN', res.data)
In the store you will have
state: {
token: '',
},
mutations: {
SET_TOKEN(state, payload) {
state.token = payload.token
}
This is just an example to be adjusted depending on response you get.
If you need to persist the state you should use also vuex persisted state
I want to implement a search functionality that would query my MongoDB database and return all the objects which contain (full/partially) the name I am searching for.
Example:
My object collection is products, and I want to see every product which contains the name I search, from the product names.
My 'Products' collection looks like this...
[ { _id: 5f79,
productName: 'Test-image12345',
price: 60,
details: 'Test product' },
{ _id: 5f7d,
productName: 'Test-image1234',
price: 60,
details: 'Test product'},
{ _id: 5fv4,
productName: 'Test',
price: 60,
details: 'Test product'},
]
Now I need to find all the products with "Test-image1234"
// search a product by name
productRoute.get('/getproduct/:name', async (req,res) => {
try {
const findname = req.params.name;
const objs = await Product.find({productName:{ $regex:'.*'+findname+'.*'} });
res.json(objs);
} catch (error) {
res.json({message: error});
}
})
Now I get the answer as follows...
[ { _id: 5f79,
productName: 'Test-image12345',
price: 60,
details: 'Test product' },
{ _id: 5f7d,
productName: 'Test-image1234',
price: 60,
details: 'Test product'}
]
router.delete('/shopping-cart/:id', (req, res) => {
let cart = new Cart(req.session.cart);
console.log(req.params.id);
console.log(cart.generateArray());
});
console.log will output the following result (req.params.id):
5c863cc8ee0819f989acf9c3
console.log will output the following result (cart.generateArray()):
[ { item:
{ _id: '5c863cc8ee0819f989acf9c3',
imagePath: 'https://upload.wikimedia.org/wikipedia/en/5/5e/Gothiccover.png',
title: 'Gothic Video',
description: 'Absolutely stunning',
price: 10,
__v: 0 },
image: 'https://upload.wikimedia.org/wikipedia/en/5/5e/Gothiccover.png',
qty: 1,
price: 10,
id: '5c863cc8ee0819f989acf9c3' } ]
So how do I loop through all the items and check if id matches the req.params.id. If that is the case, it should remove that object and then return an updated array on the client side.
let cards = [{
item: {
_id: '5c863cc8ee0819f989acf9c3',
imagePath: 'https://upload.wikimedia.org/wikipedia/en/5/5e/Gothiccover.png',
title: 'Gothic Video',
description: 'Absolutely stunning',
price: 10,
__v: 0,
},
image: 'https://upload.wikimedia.org/wikipedia/en/5/5e/Gothiccover.png',
qty: 1,
price: 10,
id: '5c863cc8ee0819f989acf9c3',
}]
cards.forEach(element => {
delete element.id
})
console.info(cards)
I assume that is coming from cart.generateArray()?
If so, you probably should do that inside the function in question, but if you can't, then just map the results to a new array:
let result = cart.generateArray().map(item => {
const {id, ...entry} = item;
// if you want to also remove _id from the inner item, you can do the same
return entry;
});
console.log(result); // will have entries w/o id in them.
If you're looking to remove the nested item object as well, it's the smae approach, though I'll change some words to improve readability.
let result = cart.generateArray().map(cartItem => {
const {id, item, ...entry} = cartItem;
// this will remove both the id and the item keys
return entry;
});
console.log(result); // will have entries w/o id in them.