Meteor & Mocha Chai : test insert function - javascript

I'm trying to test my insert function but It fail with UserAccount: Error: Cannot read property 'username' of undefined
I don't know how to make the test pass for inserting a post, here is my method:
Meteor.methods({
'posts.insert'(title, content) {
check(title, String);
check(content, String);
if (! this.userId) {
throw new Meteor.Error('not-authorized');
}
const urlSlug = getSlug(title);
Posts.insert({
title,
content,
urlSlug,
createdAt: new Date(),
owner: this.userId,
username: Meteor.users.findOne(this.userId).username,
});
},
});
And here is the test method I'm trying to test:
if (Meteor.isServer) {
describe('Posts', () => {
describe('methods', () => {
const userId = Random.id();
let postId;
beforeEach(() => {
Posts.remove({});
postId = Posts.insert({
title: 'test post',
content: 'test content',
urlSlug: 'test-post',
createdAt: new Date(),
owner: userId,
username: 'toto',
});
});
// TEST INSERT METHOD
it('can insert post', () => {
const title = "test blog 2";
const content = "test content blog 2";
const insertPost Meteor.server.method_handlers['posts.insert'];
const invocation = { userId };
insertPost.apply(invocation, [title, content]);
assert.equal(Posts.find().count(), 2);
});
});
});
}
Could you help me please ?

How about using sinon to stub the meteor call? Although I'm not sure if it works with nested object (if someone can confirm).
sinon.stub(Meteor, 'users.findOne').returns({ username: 'Foo' });
And don't forget to restore it after you have used it (in afterEach() for example).
Meteor.users.findOne.restore();

Related

Two requests inside a service in express

Currently I'm working in a project where I'm trying to build a service in express which calls another two external EP. I have a trouble here, because express shows me an error that I can't understand. But I suppose, the way I'm working it should be wrong.
So
app.get("/items/:id", (req, res) => {
return request.get({
url: `https://myapi.com/${req.params.id}`,
json: true
},
(error, response) => {
if(error) {
return res.send("Error ocurred");
}
const itemDesc = request.get({ // Here I'm trying to do the second call and use it later
url: `https://myapi.com/${req.params.id}/description`,
json: true
},
(error, responseDesc) => {
return responseDesc
});
const itemDetails = response.body;
const strPrice = itemDetails.price.toString().split('.');
const numberPrice = parseInt(strPrice[0]);
const floatPrice = strPrice[1] ? parseInt(strPrice[1]) : 00;
return res.send({
id: itemDetails.id,
title: itemDetails.title,
price: {
currency: itemDetails.currency_id,
amount: numberPrice,
decimals: floatPrice,
},
picture: itemDetails.pictures[0].url,
condition: itemDetails.condition,
free_shipping: itemDetails.shipping.free_shipping,
sold_quantity: itemDetails.sold_quantity,
description: itemDesc // Here I'm using the variable of the previous request
});
});
});
Basically, the error I get is that I can't do two calls. I know that because if I remove the nested request, it works.
The error I get is the following:
My question is: Is there any way to do two external request inside the same method?
Thanks in advance
it's cleaner if you do it with async await in your case.
modify your code like this
app.get("/items/:id", async(req, res) => {
try {
const promise1 = fetch(`https://myapi.com/${req.params.id}`).then(data => data.json())
const promise2 = fetch(`https://myapi.com/${req.params.id}/description`)
const [itemDetails, itemDesc] = await Promise.all([promise1, promise2])
const strPrice = itemDetails.price.toString().split('.');
const numberPrice = parseInt(strPrice[0]);
const floatPrice = strPrice[1] ? parseInt(strPrice[1]) : 00;
res.send({
id: itemDetails.id,
title: itemDetails.title,
price: {
currency: itemDetails.currency_id,
amount: numberPrice,
decimals: floatPrice,
},
picture: itemDetails.pictures[0].url,
condition: itemDetails.condition,
free_shipping: itemDetails.shipping.free_shipping,
sold_quantity: itemDetails.sold_quantity,
description: itemDesc // Here I'm using the variable of the previous request
});
} catch (
res.send("Error ocurred")
)
});

Facing some errors in CRUD operation?

I created a program for CRUD but facing issues
Controller program :-
const Greeting = require("../models/model.js");
exports.create = (req, res) => {
if (!req.body.message) {
return res.status(400).send({ message: "Note content can not be empty" });
}
const greeting = new Greeting({
name: req.body.name || "Name Needed",
message: req.body.message,
});
Greeting.pushData(greeting);
};
modules.js
const GreetingSchema = mongoose.Schema(
{
name: String,
message: String,
},
{
timestamps: true,
}
);
module.exports = mongoose.model("Greeting", GreetingSchema);
const Schema = mongoose.model("Greeting", GreetingSchema);
pushData = (greeting) => {
const data = new Schema({
name: greeting.name,
message: greeting.message
});
data
.save()
.then((data) => {
res.send(data);
})
.catch((err) => {
res
.status(500)
.send({
message: err.message || "Error Occurred while creating Greeting",
});
});
}
module.exports = {pushData};
and getting errors:
*
TypeError: Greeting is not a constructor
at exports.create (E:\Projects\Greeting-App_backend - Copy\controller\controller.js:9:20)
at Layer.handle [as handle_request] (E:\Projects\Greeting-App_backend - Copy\node_modules\express\lib\router\layer.js:95:5)
at next (E:\Projects\Greeting-App_backend - Copy\node_modules\express\lib\router\route.js:137:13)*
There are few errors in your code.
pushData method should be part of Schema if you want to keep it inside models and access through model Schema. No need to export pushData if you do it like below.
GreetingSchema.methods.pushData = (greeting) => {
// your code
}
module.exports = mongoose.model("Greeting", GreetingSchema);
In controller it will be -
greeting.pushData(greeting);
The error shows that your Greeting model is not a constructor. Check your model again to see if it's in the right format of how to create constructor in Javascript.
function Greeting(greeting) {
this.name = greeting.name;
this.message = greeting.message;
}

Why cant find db0bjects

I'm trying to create a "currency system" for a discord bot by following a guide, but when i try to start the bot it says Error: Cannot find module './dbObjects' my app.js code is this:
javascript
New error
The code of objects.js is this the error says: sequelize.import is not a funcion
const Sequelize = require ('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'sqlite',
logging: false,
storage: 'database.sqlite',
});
const Users = sequelize.import('models/Users');
const CurrencyShop = sequelize.import('models/CurrencyShop');
const UserItems = sequelize.import('models/UserItems');
UserItems.belongsTo(CurrencyShop, { foreignKey: 'item_id', as: 'item' });
Users.prototype.addItem = async function(item) {
const userItem = await UserItems.findOne({
where: { user_id: this.user_id, item_id: item.id },
});
if (userItem) {
userItem.amount += 1;
return userItem.save();
}
return UserItems.create({ user_id: this.user_id, item_id: item.id, amount: 1 });
};
Users.prototype.getItems = function() {
return UserItems.findAll({
where: { user_id: this.user_id },
include: ['item'],
});
};
module.exports = { Users, CurrencyShop, UserItems };
the error means that the probleme com from the directory here:
const { Users, CurrencyShop } = require('./dbObjects');
you should change that by
const { Users, CurrencyShop } = require("./models/dbObjects.js');
it should work but i'm not sure! can you add more details on what is the guide you're using?
also, for your code, it's better to use an switch case statement, instead of if, elif

How can i test my resolvers properly with jest?

I'm trying to test my resolvers but i'd like to test each field of the response, here's the code to call the response:
interface Options {
source: string;
variableValues?: Maybe<{ [key: string]: unknown | null }>;
}
let schema: GraphQLSchema;
const gCall = async ({
source,
variableValues,
}: Options): Promise<ExecutionResult> => {
if (!schema) {
schema = await createSchema();
}
return graphql({
schema,
source,
variableValues,
});
};
export default gCall;
And that's the code to test the resolver:
let connection: Connection;
const challengeMutation = `
mutation CreateChallenge($data: CreateChallengeInput!) {
createChallenge(data: $data) {
id
name
category
startDate
endDate
goal
description
}
}
`;
describe('Create Challenge', () => {
beforeAll(async () => {
connection = await databaseTestConnection();
await connection.createQueryBuilder().delete().from(Challenge).execute();
});
afterAll(async () => {
await connection.createQueryBuilder().delete().from(Challenge).execute();
await connection.close();
});
it('should create challenge', async () => {
const challenge = {
name: 'some awesome name',
category: 'distância',
startDate: new Date(2020, 7, 4).toISOString(),
endDate: new Date(2020, 7, 5).toISOString(),
goal: 5000,
description: 'some excelent challenge description',
};
const response = await gCall({
source: challengeMutation,
variableValues: {
data: challenge,
},
});
expect(response).toMatchObject({
data: {
createChallenge: {
name: challenge.name,
category: challenge.category,
startDate: challenge.startDate,
endDate: challenge.endDate,
goal: challenge.goal,
description: challenge.description,
},
},
});
});
});
What I'd like to do is test the fields separately, like this:
expect(response.data.createChallenge.name).toEqual(challenge.name);
But I'm getting the following error when I try to execute the above code:
Object is possibly 'null' or 'undefined'.
What can I do to solve this error and to make this test better?
Object is possibly 'null' or 'undefined'.
TypeScript warns you that the response data might not exist as the graphql "server" might return error instead. So you should use ! operator to assert it's not null.
You should also do that after checking it's not undefined with expect().

FindOne=>save() combination not working

I have this function:
router.route('/banner/:_id')
.post((req, res, next) => {
console.log('got here');
var r = req.body;
// console.log(r.message);
// console.log(req.params._id);
try {
Banner.findOne({_id: req.params._id}, (e, doc) => {
console.log(doc);
if (e) console.log(e);
doc.time = r.time;
doc.date = r.date;
doc.technicalIssue = r.technicalIssue;
doc.message = r.message;
doc.save(e => console.log(e));
})
}
catch (e) {
console.log(e);
}
res.redirect('/admin');
});
When I post to it I get this:
POST /admin/banner/5ac1574c734d1d4f8af95a69 302 41.225 ms - 56
{ partnersLogos: [],
_id: 5ac1574c734d1d4f8af95a69,
date: '1 May',
time: '1 - 5pm',
technicalIssue: '',
message: 'test2',
__v: 1 }
null
So I can see it finds the document needed. The problem is it doesn't save it. It's probably some stupid error, but I cannot see it anywhere. Any idea?
I'm using Express with Mongoose on mlab.
I tried mimicing this answer but something went wrong.
Banner model:
var mongoose = require('mongoose');
var bannerSchema = new mongoose.Schema({
technicalIssue: String,
time: String,
date: String,
partnersLogos: [],
});
module.exports = mongoose.model('banner', bannerSchema);
I forgot to add the message field in my model.

Categories