How Test e2e Nestjs API with GRAPHQL - testing

When I create my Owner via graphql-playground it works fine,
but my test fail and response me that 'body.data.createOwner is undefined', there no data.
// owner.e2e.spec.ts
describe('Owner test (e2e)', () => {
let app: INestApplication;
beforeAll(async () => {
const moduleRef = await Test.createTestingModule({
imports: [
GraphQLModule.forRoot({
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}),
OwnerModule,
DatabaseModule
]
}).compile();
app = moduleRef.createNestApplication();
await app.init();
});
afterAll(async () => {
await app.close();
})
const createOwnerQuery = `
mutation createOwner($OwnerInput: OwnerInput!) {
createOwner(ownerInput: $OwnerInput) {
_id
name
firstname
email
password
firstsub
expsub
createdAt
updatedAt
}
}
`;
let id: string = '';
it('createOwner', () => {
return request(app.getHttpServer())
.post('/graphql')
.send({
operationName: 'createOwner',
variables: {
OwnerInput: {
name: 'adar',
firstname: 'adar',
email: 'adar#test.com',
password: 'testing',
firstsub: '2020-08-14',
expsub: '2020-07-13'
}
},
query: createOwnerQuery,
})
.expect(({ body }) => {
const data = body.data.createOwner <-- test fail at this line
id = data._id
expect(data.name).toBe(owner.name)
expect(data.email).toBe(owner.email)
expect(data.firstsub).toBe(owner.firstsub)
})
.expect(200)
})
// Output terminal
FAIL test/owner.e2e-spec.ts (9.567 s)
Owner test (e2e)
✕ createOwner (79 ms)
● Owner test (e2e) › createOwner
TypeError: Cannot read property 'createOwner' of undefined
98 | })
99 | .expect(({ body }) => {
> 100 | const data = body.data.createOwner
| ^
101 | id = data._id
102 | expect(data.name).toBe(owner.name)
103 | expect(data.email).toBe(owner.email)
at owner.e2e-spec.ts:100:40
at Test._assertFunction (../node_modules/supertest/lib/test.js:283:11)
at Test.assert (../node_modules/supertest/lib/test.js:173:18)
at Server.localAssert (../node_modules/supertest/lib/test.js:131:12)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 9.645 s, estimated 10 s
Ran all test suites.

My problem was from CLI plugin which generate automatically nullable Graphql fields without putting the #Field decorator in my ObjectType.
The creator of nest gave a trick about this issue.
--> https://github.com/nestjs/graphql/issues/810
but this doesn't works for me, so I simply added "#Field" decorator to all attributs in my model #ObjectType().

Related

How can I test action in vuex with vue-test-utils and jest when this actions uses a globalProperties?

I'm really new at testing with vue-test-utis/jest, but I've stumbled upon an issue that I'm not sure how to test it. Could someone help me? I have an action in my store that uses a globalProperties and when I try to use it in tests it's not working.
Basically this is my test:
describe('test: actions', () => {
it('buildReservationsTableData', () => {
let data = actions.buildReservationsTableData(mockDataBefore);
expect(data).toEqual(tableData);
})
})
And this is the action that I'm trying to write a test:
buildReservationsTableData(channelsData) {
let renderTable = ant_table.getRender('table');
if (!channelsData) {
return renderTable.handle([], []);
}
let data = [],
sortable = [],
headers = {
"code" : "Code",
"guestName" : "Guest name",
"checkin" : "Check-in",
"checkout" : "Check-out",
"nights": "Nights",
"ratePlan": "Rate plan",
"roomType": "Room Type",
"totalAmount": "Total amount",
"channel": "Channel",
"status": "Status",
"date": "Date"
},
slots = {};
for (let idx in channelsData){
if (Object.prototype.hasOwnProperty.call(channelsData[idx], "sentToPms")) {
headers.sentToPms = "Sent to PMS";
break;
}
}
for (let idx in channelsData) {
let record = {
id : channelsData[idx].code,
child : channelsData[idx].teste
};
for (let key in headers) {
record[key] = channelsData[idx][key];
if (key == "totalAmount"){
record[key] = global.dashboards.$filters.currency(channelsData[idx][key]);
}
sortable.push(key);
if (key == 'status' || key == 'sentToPms'){
slots[key] = {customRender : 'format'};
}
}
data.push(record);
}
return renderTable.handle(headers, data, {"sortable": sortable, slots: slots});
},
My problem is that the test suit doesn't know what is global.dashboards.$filters.currency, my globalProperties. I get this error:
● test: actions › buildReservationsTableData
TypeError: Cannot read properties of undefined (reading '$filters')
84 | record[key] = channelsData[idx][key];
85 | if (key == "totalAmount"){
> 86 | record[key] = global.dashboards.$filters.currency(channelsData[idx][key]);
| ^
87 | }
88 |
89 | sortable.push(key);
On my jest.init.js file I have this config, but the action is not aware of that.
import { config } from "#vue/test-utils";
config.global.mocks = {
$filters: {
translate: (msg) => msg,
currency: (currency) => currency
},
$t: (text) => text
}
How do I fix it? Thanks in advance.
Judging by the error it your dashboards object which is not defined.
I don't know how you create it or what it is, but if you want to try to mock in Vue-test-utils config file please note that global doesn't seem to be a valid config option, you might want to try:
config.mocks = {
global: {
dashboards: {
$filters: {
translate: (msg) => msg,
currency: (currency) => currency
},
$t: (text) => text
}
}
}
Alternatively Jest provide a way to define global variables that need to be available in all test in jest.config.js:
// globals: {},

Creating a Heatmap for Rooms - No Structureinfo

I'm working on a project in which I have to generate a heatmap for some sensors that are beeing rendered inside of a modell using forgeviewer. For the implementation I'm following this tutorial: https://forge.autodesk.com/en/docs/dataviz/v1/developers_guide/examples/create_heatmap_for_rooms/
The modell I'm using was generated through Revit and translated into .svf using the Model-Derivative-API.
My problem now is, that I cant get any room or level data from my model which are needed for the generation of the heatmap.
These lines always give me no rooms or levels, eventhough there are rooms shown in the viewers modellbrowser as shown in the picture below.
modellbrowser with rooms
const structureInfo = new Autodesk.DataVisualization.Core.ModelStructureInfo(viewer.model);
console.log("STRUCTUREINFO");
console.log(structureInfo);
...
const shadingdata= await structureInfo.generateSurfaceShadingData(devices);
console.log("SHADINGDATA");
console.log(shadingdata);
StructureInfo in console
ShadingData in console
Question now is: Why cant I get any room or level data and how can I fix this?
The only thing that came to my mind so far that I have tried was to convert the revit file into .nwd using navisworks and translating that file into .svf. But the results where the same.
Here is some more Code. Please note that the application is clientside only and wont go into production like this. I'm only creating a prototype for presentations.
export const initializeViewer = async (urn: string) => {
let viewer: Autodesk.Viewing.GuiViewer3D;
fetch("https://developer.api.autodesk.com/authentication/v1/authenticate", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
client_id: "ClinetID",
client_secret: "ClentSecret",
grant_type: "client_credentials",
scope: "viewables:read",
}),
}) .then((res) => res.json())
.then((value) => {
const options = {
document: urn,
env: "AutodeskProduction",
accessToken: value.access_token,
api: "derivativeV2",
};
var container = document.getElementById("viewer-container");
if (container !== null) {
viewer = new Autodesk.Viewing.GuiViewer3D(container, {
extensions: [],
});
}
Autodesk.Viewing.Initializer(options, function onInitialized() {
addEvents();
viewer.start();
Autodesk.Viewing.Document.load(urn, onSuccess, onFailure);
});
});
const addEvents = () => {
viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, () => {
loadExtensions();
onModelLoaded(viewer);
});
....
....
async function onModelLoaded(viewer: Autodesk.Viewing.GuiViewer3D) {
const dataVizExtn: any | Autodesk.Extensions.DataVisualization = await viewer.loadExtension("Autodesk.DataVisualization");
...
const aecModelData = await viewerDocument.downloadAecModelData();
if (aecModelData) {
const levelsExt: any | Autodesk.AEC.LevelsExtension = await viewer.loadExtension("Autodesk.AEC.LevelsExtension", {
doNotCreateUI: true,
});
const floorData = levelsExt.floorSelector.floorData;
const floor = floorData[2];
levelsExt.floorSelector.selectFloor(floor.index, true);
}
const structureInfo = new Autodesk.DataVisualization.Core.ModelStructureInfo(viewer.model);
let roomDevices: Autodesk.DataVisualization.Core.RoomDevice[] = [];
devices.forEach((device) => {
let autodeskDevice: Autodesk.DataVisualization.Core.RoomDevice = {
id: device.id, // An ID to identify this device
position: device.position, // World coordinates of this device
sensorTypes: device.sensorTypes, // The types/properties this device exposes
type: "Thermometer",
};
roomDevices.push(autodeskDevice);
});
const heatmap = await structureInfo.generateSurfaceShadingData(roomDevices, undefined, "Rooms");
};
Looks your source model is RVT in Deutschland. If so, please use this code snippet instead.
const shadingdata = await structureInfo.generateSurfaceShadingData(devices, null, 'Räumen')
For RVT -> NWD/DWC, please check my blog post here Add Data Visualization Heatmaps for Rooms of non-Revit model part I - NWC
Querying Revit master views in the viewer:
const root = viewerDocument.getRoot();
const viewables = root.search({'type':'geometry', 'role': '3d'});
console.log('Viewables:', viewables);
const phaseViews = viewables.filter(v => v.data.name === v.data.phaseNames && v.getViewableRootPath().includes('08f99ae5-b8be-4f8d-881b-128675723c10'));
console.log('Master Views:', phaseViews);
// or this one if you just have one master view (phase) inside your model.
// viewerDocument.getRoot().getDefaultGeometry(true);

how to deal with testing that uses uuid inside the component

I try to test my component that has a function to add an item to the array and each of those items has UUID property but I get this error when I try to run the unit test for that.
TypeError: Cannot read property 'v1' of undefined
const basicDataItem = {
> 380 | id: this.$uuid.v1()
How can I test the code that uses UUID like in this case?
edit:
this is the function that I want to test
addDataItem(key) {
const basicDataItem = {
id: this.$uuid.v1(),
units: '',
price: '',
label: '',
};
this.editableData[key].push(basicDataItem);
}
Here is a unit test solution for your case:
index.js:
export class SomeClass {
editableData = {
jest: []
};
$uuid = {
v1() {
return 'real uuid';
}
};
addDataItem(key) {
const basicDataItem = {
id: this.$uuid.v1(),
units: '',
price: '',
label: ''
};
this.editableData[key].push(basicDataItem);
}
}
index.spec.js:
import { SomeClass } from './';
describe('SomeClass', () => {
test('should add data item', () => {
const someClassInstance = new SomeClass();
const uuidv1Spy = jest.spyOn(someClassInstance.$uuid, 'v1').mockReturnValueOnce('fake uuid');
someClassInstance.addDataItem('jest');
expect(uuidv1Spy).toBeCalledTimes(1);
expect(someClassInstance.editableData).toEqual({ jest: [{ id: 'fake uuid', units: '', price: '', label: '' }] });
});
});
Unit test result with coverage report:
PASS src/stackoverflow/58710736/index.spec.js
SomeClass
✓ should add data item (14ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 88.89 | 100 | 66.67 | 87.5 | |
index.js | 88.89 | 100 | 66.67 | 87.5 | 7 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.909s, estimated 6s
Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58710736

How to mock a class being imported from a npm module

I am importing a class via const { PaymentRequest } = require("react-native-payments"); and I am trying to mock the functions it exposes when it is instantiated. For example:
const paymentRequest = new PaymentRequest(METHOD_DATA, DETAILS, OPTIONS);
paymentRequest.canMakePayments().then(res => {...})
I want to mock this and change the value coming back from the promise resolve so that I can test different scenarios from canMakePayments and other async functions the class exposes.
Here is the solution, you can use jest.mock method mock react-native-payments module manually.
index.ts:
const { PaymentRequest } = require('react-native-payments');
const METHOD_DATA = [
{
supportedMethods: ['apple-pay'],
data: {
merchantIdentifier: 'merchant.com.your-app.namespace',
supportedNetworks: ['visa', 'mastercard', 'amex'],
countryCode: 'US',
currencyCode: 'USD'
}
}
];
const DETAILS = {
id: 'basic-example',
displayItems: [
{
label: 'Movie Ticket',
amount: { currency: 'USD', value: '15.00' }
}
],
total: {
label: 'Merchant Name',
amount: { currency: 'USD', value: '15.00' }
}
};
const OPTIONS = {
requestPayerName: true
};
function main() {
const paymentRequest = new PaymentRequest(METHOD_DATA, DETAILS, OPTIONS);
return paymentRequest.canMakePayment();
}
export { main, METHOD_DATA, DETAILS, OPTIONS };
main function is going to be tested.
index.spec.ts:
import { main, METHOD_DATA, DETAILS, OPTIONS } from './';
const { PaymentRequest } = require('react-native-payments');
jest.mock('react-native-payments', () => {
const PaymentRequestMocked = {
canMakePayment: jest.fn()
};
return {
PaymentRequest: jest.fn(() => PaymentRequestMocked)
};
});
const paymentRequest = new PaymentRequest(METHOD_DATA, DETAILS, OPTIONS);
describe('main', () => {
beforeEach(() => {
paymentRequest.canMakePayment.mockReset();
});
it.each`
value | name
${'mocked value 1'} | ${'t1'}
${'mocked value 2'} | ${'t2'}
`(`$name`, async ({ value }) => {
paymentRequest.canMakePayment.mockResolvedValueOnce(value);
const actualValue = await main();
expect(actualValue).toEqual(value);
expect(paymentRequest.canMakePayment).toBeCalledTimes(1);
});
});
Unit test result with 100% coverage:
PASS src/stackoverflow/57565053/index.spec.ts
main
✓ t1 (5ms)
✓ t2 (1ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.ts | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 3.03s, estimated 6s
Here is the completed demo: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57565053

vue-test-utils how to use trigger's options

I want to test el-button if it can change to the correct view by $router,but I am confused weather the trigger supportted cause i find this in its document
The trigger method takes an optional options object. The properties in
the options object are added to the Event.
Note that target cannot be added in the options object.
const wrapper = mount(MyButton)
wrapper.trigger('click', {
button: 0
})
but failed and i get this info
TypeError: Cannot set property type of [object Event] which has only a
getter
65 | // expect(mockFn).toBeCalled
66 | // expect(mockFn).toBeCalledTimes(1)
67 | wrapper.find(ElementUI.Button).trigger('click', {
| ^
68 | id: 1,
69 | type: 'view'
70 | })
vue file
<el-button
plain
type="primary"
#click="changeView(-1, 'edit')">
newPicture
</el-button>
js
changeView(id, type) {
if (type === 'view') {
this.$router.push({ path: './detail', query: { id, type }})
} else if (type === 'edit') {
this.$router.push({ path: './edit', query: { id, type }})
}
},
And I want to write a test file for this button
...
it('add button click', () => {
const mockFn = jest.fn()
wrapper.setMethods({
changeView: mockFn
})
wrapper.find(ElementUI.Button).trigger('click', {
id: 1,
type: 'view'
})
wrapper.update()
expect(mockFn).toBeCalled
console.log(wrapper.vm.$route.path)
})
...
How can I fix this?
the options your passing are js $event properties. here's a list of them: https://www.w3schools.com/jsref/obj_event.asp
when you trigger that click event, the changeView will be called, with the parameters you passed to it(-1 and 'edit'). they are not event properties and you dont pass them as options. so your test whould look like:
it('add button click', () => {
const mockFn = jest.fn()
wrapper.setMethods({
changeView: mockFn
})
wrapper.find(ElementUI.Button).trigger('click');
wrapper.update();
expect(mockFn).toBeCalledWith(-1,'edit');
})