I got this test from another site. They are injecting a mock route. I think I need to mock router itself or pass a real one into the test so the page can run. There is a way to do this in vue 2, but I haven't found an example for vue 3.
import { mount } from "#vue/test-utils";
import Nav from "./Nav.vue";
test("it displays a menu item", () => {
const mockRoute = {
params: {
id: 1,
},
};
const mockRouter = {
push: jest.fn(),
};
const wrapper = mount(Nav, {
props: {
isAuthenticated: true,
},
global: {
mocks: {
$route: mockRoute,
$router: mockRouter,
},
},
});
expect(wrapper.find("#navLabel_0").text()).toEqual("Appointments");
});
The component I'm testing has tags.
The test fails with:
Failed to resolve component: router-link
You have to pass the router-link as a stub: stubs: ['router-link'] when you mount the component:
const wrapper = mount(Nav, {
props: {
isAuthenticated: true,
},
global: {
mocks: {
$route: mockRoute,
$router: mockRouter,
},
},
stubs: ['router-link'] });
Related
Strapi doesn't have any endpoint to get random data for this purpose you should write some custom code for your endpoint
custom route for that endpoint you want
// path: ./src/api/[your-endpiont]/routes/[custom-route].js
module.exports = {
"routes": [
{
"method": "GET",
"path": "/[your-endpiont]/random", // you can define everything you want for url endpoint
"handler": "[your-endpiont].random", // random is defined as a method
"config": {
"policies": []
}
}
]
}
now you have to run yarn develop or npm ... to display a random method in your strapi panel
Save this setting and retry to reach the random endpoint.
create a function as a service for getting random data in your endpoint API services.
// path: ./src/api/[your-endpiont]/services/[your-endpiont].js
'use strict';
/**
* news-list service.
*/
const { createCoreService } = require('#strapi/strapi').factories;
module.exports = createCoreService('api::news-list.news-list', ({ strapi }) => ({
async serviceGetRandom({ locale, id_nin }) { // these parametrs come from query
function getRandomElementsFromArray(array, numberOfRandomElementsToExtract = 1) {
const elements = [];
function getRandomElement(arr) {
if (elements.length < numberOfRandomElementsToExtract) {
const index = Math.floor(Math.random() * arr.length)
const element = arr.splice(index, 1)[0];
elements.push(element)
return getRandomElement(arr)
} else {
return elements
}
}
return getRandomElement([...array])
}
const newsListArray = await strapi
.db
.query("api::news-list.news-list")
.findMany({
where: {
locale: locale, // if you have multi-language data
$not: {
id: id_nin, // depend on where this endpoint API use
},
publishedAt: {
$notNull: true,
},
},
sort: [{ datetime: 'asc' }],
limit: 10,
populate: {
content: {
populate: {
thumbnail: true,
},
},
},
//? filter object throws an error when you used populate object, everything you want to filter properly best write into where{}
// filters: {
// publishedAt: {
// $notNull: true,
// },
// locale: locale
// }
})
if (!newsListArray.length) {
return null
}
return getRandomElementsFromArray(newsListArray, 2)
}
}));
explain code:
Strapi provides a Query Engine API to interact with the database layer at a lower level
strapi.db.query("api::news-list.news-list").findMany({})
The Query Engine allows operations on database entries,
I wrote this for my purpose probably you should change based on what you needed
{
where: {
locale: locale,
$not: {
id: id_nin
},
publishedAt: {
$notNull: true,
},
},
sort: [{ datetime: 'asc' }],
limit: 10,
populate: {
content: {
populate: {
thumbnail: true,
},
},
}
}
when you get data from your query, passed it to that function getRandomElementsFromArray(newsListArray, 2) to get some random item (how many random items do you want ? pass the second parameter)
At least if your array is null return null otherwise return data
create the controller
Controllers are JavaScript files that contain a set of methods, called actions, reached by the client according to the requested route so we going to call our services in this section
// path: ./src/api/[your-endpoint]/controllers/[your-endpoint].js
'use strict';
/**
* news-list controller
*/
const { createCoreController } = require('#strapi/strapi').factories;
module.exports = createCoreController('api::news-list.news-list', ({ strapi }) => ({
async random(ctx) { // name of this methods related to something we define in route ("handler": "[your-endpiont].random",)
const entity = await strapi.service('api::news-list.news-list').serviceGetRandom(ctx.query) // call our services, you can send all query you get from url endpoint (notice that you should write your endpoint api in strapi.service("your-endpoint"))
const sanitizedEntity = await this.sanitizeOutput(entity, ctx);
return this.transformResponse(sanitizedEntity);
// console.log(entity);
}
}));
I call this endpoint in my project nextjs & stapi cms
export const getRandomNewsItem = (id, locale) => {
return API
.get(`/news-list/random?locale=${locale}&id_nin=${id}`)
.then(res => res.data);
};
That's it, I'll hope you all get what to do
all resources you need
https://docs.strapi.io/developer-docs/latest/development/backend-customization/routes.html#creating-custom-routers
https://docs.strapi.io/developer-docs/latest/development/backend-customization/services.html#implementation
https://docs.strapi.io/developer-docs/latest/development/backend-customization/controllers.html#adding-a-new-controller
https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/query-engine-api.html
https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/query-engine/filtering.html#and
https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/entity-service/order-pagination.html#ordering
https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/entity-service/order-pagination.html#ordering
https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/query-engine/populating.html
I want to add a custom schema formatter for fastify.
import fastify from 'fastify'
import AjvCompiler from '#fastify/ajv-compiler'
const ajvFormatter = AjvCompiler(ajv);
ajvFormatter.addFormat('new-format', /hello/);
const app = fastify({
schemaController: {
compilersFactory: {
buildValidator: ajvFormatter
}
}
})
I add the format but still gives the error:
Failed building the validation schema for POST: /hey, due to error unknown format
"new-format" ignored in schema at path
I guess latest fastify does not support this functionality.
You are using in the wrong way the #fastify/ajv-compiler module. It does not accept an ajv input parameter at all. not it exports an addFormat method.
You need to use the customOption option:
const fastify = require('fastify')
const app = fastify({
logger: true,
ajv: {
customOptions: {
formats: {
'new-format': /hello/,
},
},
},
})
app.get(
'/:hello',
{
schema: {
params: {
type: 'object',
properties: {
hello: {
type: 'string',
format: 'new-format',
},
},
},
},
},
async (request, reply) => {
return request.params
}
)
app.listen(8080, '0.0.0.0')
// curl http://127.0.0.1:8080/hello
// curl http://127.0.0.1:8080/hello-foo
I am writing a Jest test for a Vue component's method. Specifically, I want to test that a Vuex action (I've mapped to this action in the component with mapActions) was called with a certain argument.
I mock the argument that should be passed to the action-- my test is close, but the argument the action receives has a bunch of extra information, and I'm not sure why.
The method in my component that I'm testing is:
triggerSave (trip) {
if (this.canSave) {
const tripToSave = { tripInProcess: true, trip: { tripId: trip.tripId, }, };
this.updateMyTrips(tripToSave);
}
},
Where updateMyTrips is the Vuex action I've mapped to in my component.
In my jest tests, I mock the action that I'm testing in a beforeEach (along with the store)
describe('TripPlanner', () => {
let actions;
let store;
beforeEach(() => {
actions = {
updateMyTrips: jest.fn(),
},
store = new Vuex.Store({
modules: {
trips: {
namespaced: true,
actions,
},
},
});
});
The test itself that I have is
test('trigger save calls updateMyTrips action', () => {
const mockTrip = [
{
tripId: 1234,
tripDestination: 'Rio di Janeiro',
},
];
const wrapper = shallowMount(TripPlanner, { store, localVue, propsData: { trip: mockTrip, canSave: true, }, },);
wrapper.vm.updateMyTrips(mockTrip[0]);
const mockUpdate = { tripInProcess: true, trip: { tripId: mockTrip.tripId }, };
expect(actions.updateMyTrips).toHaveBeenCalledWith(mockUpdate);
});
When I run the test, and look at the Expected/Received values, it does receive my mockUpdate object, but also receives
"commit": [Function anonymous],
+ "dispatch": [Function anonymous],
+ "getters": Object {},
+ "rootGetters": Object {},
+ "rootState": Object {
+ "addOns": Object {},
+ "state": Object {},
So the test fails.
If I just test that expect(actions.updateMyTrips).toHaveBeenCalled the test passes...but when I test that it was called WITH that specific argument, it fails.
I don't understand why the store's dispatch, getters, state, etc. are also being received!
The first argument is pass automatic, the second argument is your data that you are passing to vuex.
You can pass like first argument this:
expect.any(Object),
And the second argument will be your data
const mockTrip = [
{
tripId: 1234,
tripDestination: 'Rio di Janeiro',
},
];
I dont understand for what it not say nothing the documentation about this issue.
I am digging into moleculer.js the only thing i am finding difficult to understand;how to get parameters inside actions of a service
below given is my code
const ApiGateway = require("moleculer-web");
module.exports = {
name: "api",
mixins: [ApiGateway],
settings: {
port: process.env.PORT || 3000,
bodyParsers: {
json: true,
urlencoded: { extended: true }
},
routes: [{
path: "/api",
whitelist: [
"**"
]
}],
assets: {
folder: "public"
}
},
};
Below is my user service where i want to get post parameters
module.exports = {
name: "users",
dependencies: ["guard"],
actions: {
create: {
restricted: [
"api"
],
async handler(ctx,route, req, res) {
this.logger.info(req);
this.logger.info("'users.create' has been called.");
const token=await ctx.call("guard.generate",{service:"abc"});
what i want is
const token=await ctx.call("guard.generate",{service:req.body.name});
instead of
const token=await ctx.call("guard.generate",{service:"abc"});
const verify=await ctx.call("guard.check",{token:token});
return [token,verify,req];
}
},
}
MoleculerĀ“s Actions has the following signature: <actionName> (ctx) {// logic} or <actionName>: { handler (ctx) { // logic}}.
So what you have to do is this:
module.exports = {
name: "users",
actions: {
welcome: {
handler(ctx) {
console.log(ctx.params) // Print the request params
// Call other actions ctx.call('serviceName.actionName`, ...data...)
return ctx.params
}
}
}
}
More info about Actions: https://moleculer.services/docs/0.13/actions.html
The function signaturehandler(ctx,route, req, res) is a route hook that is used only in API gateway.
More info about Route hooks: https://moleculer.services/docs/0.13/moleculer-web.html#Route-hooks
Also, the req and res can't be passed to other services because these objects are not serializable.
Anyway, you might consider checking the video tutorial: https://www.youtube.com/watch?v=t4YR6MWrugw
It covers Moleculer's core concepts and shows how to call actions
I'm trying to write unit tests which will test if the search query is right In other words if the logic written in where statement is returning expected results.
async function search(some_data){
return Event.findOne({
where: {
id: 123435,
[Op.or]: [
days: {
[Op.overlap]: some_data.days,
},
[Op.or]: [
{
startTime: {
[Op.gt]: some_data.start1,
},
endTime: {
[Op.lt]:some_data.end1,
},
},
{
startTime: {
[Op.lt]: some_data.start2,
[Op.lt]: some_data.end2,
},
endTime: {
[Op.gt]: some_data.end2,
[Op.gt]: some_data.start2,
},
},
],
],
},
})};
I need to test the result for different inputs.
I don't want to convert this test into integration test and use the original db, so I used sequelize-mock lib, but this returns only the result that I've defined and does not run the real query.
To test that your method is called with the correct parameters, you will need to use dependency injetion and a library to "spy" on your findOne method. In the example below, I am using Sinon
// app.js
// Note that "Event" must be used an argument in order to mock it out
async function search(Event, some_data) {
return Event.findOne({
where: {
id: 123435
}
})
}
If your test file:
// your test file
const app = require('./app');
const sinon = require('sinon');
const EventMock = {
findOne: sinon.spy()
};
describe('search', () => {
it('should call with the right parameters', () => {
const some_data = {};
search(EventMock, some_data);
assert(EventMock.findOne.calledWith({
where: {
id: 123435
}
}))
});
});