Mocha MongoDB clean collection before each test - mongodb

I'm trying to cleanup 2 collections before each test. I'm using mocha --watch to rerun tests while editing the test source files. First run always executes as expected, but consecutive runs gives Topology was destroyed error from mongodb(indicated via result of http request).
I am not really sure why deleteMany deletes my inserted object in consecutive runs.
describe('myCollection1 related tests', () => {
// myCollection1 documents should refer to a valid myCollection2 document.
var foo;
const exampleObject = {name: 'TEST OBJECT', attr1: 'TO'};
beforeEach(() => {
return Promise.all([
mongo.db('mydb').collection('myCollection1').deleteMany({}), // clear collection 1
mongo.db('mydb').collection('myCollection2').deleteMany({}) // clear collection 2
.then(() => mongo.db('mydb').collection('myCollection2').insertOne(exampleObject) // and add a sample object
.then((value) => {
foo = value.ops[0]; // save this as test specific variable so I can use it in my tests.
return Promise.resolve();
})),
]);
});
it('should create a related object', (done) => {
chai.request(server)
.post('/api/v1/foos/')
.send({ related: foo._id })
.then((res) => {
res.should.have.status(200);
res.body.should.be.an('object').with.all.keys('status', 'errors', 'data');
done();
}).catch((err) => {
done(err);
});
});
});

I spotted issue with your promise structure in beforeEach. I'm not sure it is intended or not. I'm afraid it is the culprit. I'm fixing that into below:
beforeEach(() => {
return Promise.all([
mongo.db('mydb').collection('myCollection1').deleteMany({}),
mongo.db('mydb').collection('myCollection2').deleteMany({})
]) // close the promise.all here
.then(() => collections.engines().insertOne(exampleObject)) // close `then` here
.then((value) => {
foo = value.ops[0];
return Promise.resolve();
});
});
Hope it helps

Related

Fetch response not logging to Console

Im attempting to fetch from my localhost URL but the all the console.log() except for "done" do nothign and my .catch isnt receiving an error
fetch(tURL, {
method: 'POST',
body: JSON.stringify(post),
mode: 'cors',
headers:{
'content-type': 'application/json'
}
}).then(res => {
if (!res.ok) {
throw new Error(`HTTP error! Status: ${res.status}`);
}
form.reset();
console.log("Response received from server");
console.log(res.json);
return res.json();
})
.then(npost => {
console.log("Parsing response as JSON...");
form.style.display = '';
console.log(npost);
})
.catch(error => console.error(error));
console.log('done');
})
I put several debugging logs to see what was being reached but i get nothing
It looks like this is because of a syntax error, the }) at the end of your file should not be there, I think it is because the formatting is fairly difficult to read. If you write a .then statement between catch and console.log it will work fine. If you count the parenthesis between the fetch and the end, there is an extra set to close a block that doesn't exist. If you delete the }) at the end, your code will work, however the log statement will run before the fetch is complete; which I assume you don't want. To solve this, delete that }) and add this to the end of the chain:
.then(() => console.log('done'))
Original code
fetch(tURL, {
method: 'POST',
body: JSON.stringify(post),
mode: 'cors',
headers:{
'content-type': 'application/json'
}
}).then(res => {
if (!res.ok) {
throw new Error(`HTTP error! Status: ${res.status}`);
}
form.reset();
console.log("Response received from server");
console.log(res.json);
return res.json();
})
.then(npost => {
console.log("Parsing response as JSON...");
form.style.display = '';
console.log(npost);
})
.catch(error => console.error(error));
// This is where the error is, the catch statement was the last "block" in the callback chain, so the `})` is closing a "block" that doesn't exist.
// Delete the semicolon above and uncomment the next line to fix
// .then(() => {
console.log('done');
})

RTK query with Storybookjs

I am using RTK query with typescript in my react application and its working fine however storybookjs is not able to mock data for RTK query.
I am trying to mock store object as shown in this storybook document.
example -
export const Test = Template.bind({});
Test.decorators = [
(story) => <Mockstore data={myData}>{story()}</Mockstore>,
];
.
.
.
const customBaseQuery = (
args,
{ signal, dispatch, getState },
extraOptions
) => {
return { data: [] }; // <--- NOT SURE ABOUT THIS
};
const Mockstore = ({ myData, children }) => (
<Provider
store={configureStore({
reducer: {
[myApi.reducerPath]: createApi({
reducerPath: 'myApi',
baseQuery: customBaseQuery,
endpoints: (builder) => ({
getMyData: myData, //<-- my mock data
}),
}).reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(myApi.middleware),
})}
>
{children}
</Provider>
);
Since RTK query hook is autogenerated, I am not sure how to mock it in storybookjs. Instead of getting mock data storybook if trying to fetch actual data.
Please help me.
You'd do
endpoints: (builder) => ({
getMyData: builder.query({
queryFn: () => { data: myData }, //<-- my mock data
})
}),
alternatively you could leave the store setup just as it is and use msw to mock the real api.

Redux toolkit slice. Pure functions inside field reducers

Sup ya. Just wanna specify can we use it? I think we can just wanna be sure 100%
https://codesandbox.io/s/redux-toolkit-state-new-array-4sswi?file=/src/redux/slices/slice.js:111-425
const someSlice = createSlice({
name: "someSlice",
initialState: {
users: [],
status: ""
},
reducers: {
actionSuccess: (state, { payload }) => {
state.users = payload.users;
},
actionFailure: (state) => {
// can we use here function?
statusHandler(state)
}
}
});
A reducer should not trigger any side effects. That is, it should not do anything other than change the contents of the state. So you should not call a statusHandler which would trigger external effects.
If your statusHandler function does nothing but update the state, that does seem to work in my testing and I'm not aware of any reason why it shouldn't be okay.
Redux Toolkit uses Immer behind the scenes to deal with immutable updates, so this question basically boils down to whether these two functions, updatedInline and updatedExternally, are equivalent. They are, as far as I can tell.
const {produce} = immer;
const initialState = {
status: ''
};
const updatedInline = produce( initialState, draft => {
draft.status = 'failed';
})
const mutateStatus = (state) => {
state.status = 'failed';
}
const updatedExternally = produce( initialState, mutateStatus )
console.log("Updated Inline: \n", updatedInline);
console.log("Updated Externally: \n", updatedExternally);
<script src="https://cdn.jsdelivr.net/npm/immer#8.0.1/dist/immer.umd.production.min.js"></script>

MongoDB document deleted locally but not on MongoLab

This Mongoose delete method seems to work Ok locally with HttpRequester
router.delete('/', (req, res) => {
Book.findOneAndRemove({ title: req.body.title })
.then(() => res.json({ 'book deleted': 'success' }))
.catch(err => console.log('Couldn\'t delete book:', err));
}
);
but the MongoLab collection still shows the document. How to get it deleted remotely too? findOneAndDelete() didn't make a difference.
The complete repo is on https://github.com/ElAnonimo/booklist
findOneAndRemove had issues earlier.
findByIdAndRemove works fine.
router.delete('/', (req, res) => {
Book.findOne({ title: req.body.title })
.then((doc) => if(doc)return Book.findByIdAndRemove(doc._id))
.then(() => res.json({ 'book deleted': 'success' }))
.catch(err => console.log('Couldn\'t delete book:', err));
}
);
or even better you can do as follows
router.delete('/', (req, res) => {
Book.deleteOne({ title: req.body.title })
.then(() => res.json({ 'book deleted': 'success' }))
.catch(err => console.log('Couldn\'t delete book:', err));
}
);
Have you change your URI connection to MongoDB on mLab?. I think you've changed it yet.
Please sure use mongodb://<dbuser>:<dbpassword>#ds12xxxx.mlab.com:27342/[database_name], not locally 'mongodb://localhost/[database_name]'
If you've changed it, please use deleteOne https://mongoosejs.com/docs/api.html#model_Model.deleteOne, it's working well.

the best way to exclude some data from a method in sails controller

I want's to exclude some data in some controller method and in other method i want's that data. I do it with forEach function right into method after finding that :
nine: function (req, res) {
Dore.find()
.limit(9)
.sort('createdAt DESC')
.populate('file')
.exec(function (err, sh) {
if (err) {
return res.negotiate(err);
} else {
console.log('before : ', sh);
sh.forEach(function (item, i) {
delete item.zaman;
});
console.log('after : ', sh);
return res.send(sh);
}
});
},
I want to know how possible to do that with finding and do not included ever in finding so we don't need to remove that again with forEach.
tanks
As #zabware say we have select method in Query option I try this format but do not work and return all data :
I try to use that with following format but don't working :
Model.find( {
where: {},
limit: 9,
sort: 'createdAt DESC'
},
{
select: [ 'id', 'createdAt' ]
} )
and
Model.find( {
where: {},
limit: 9,
sort: 'createdAt DESC',
select: [ 'id', 'createdAt' ]
} )
and
Model.find( {}, select: [ 'id', 'createdAt' ] )
Although toJson is really designed to solve the kind of problem you are facing, it will not help you, since in some actions you want to exclude certain fields and in others not.
So we need to select fields per query. Luckily there is a solution for this in waterline:
Dore.find({}, {select: ['foo', 'bar']})
.limit(9)
.sort('createdAt DESC')
.populate('file')
.exec(function (err, sh) {
console.log(err);
console.log(sh);
});
This is supported since sails 0.11 but not really documented. You can find it under query options here https://github.com/balderdashy/waterline-docs/blob/e7b9ecf2510646b7de69663f709175a186da10d5/queries/query-language.md#query-options
I accidentally stumbled upon it while playing with the debugger - Sails version 1.2.3
There is something like omit and You can put it into your find method call:
const user = await User.findOne({
where: {email : inputs.email},
omit: ['password']
}); //There won't be password field in the user object
It is a pity that there is no word about it in the documentation.