How to solve toUpperCase issue in Jest testing? - vue.js

I am using Vuejs and Jest. I have following statement in my component:
...mapGetters('type', [
'selectedAddressType',
'checkDeliveryType',
]),
const keyToDisplayMessage = `${this.checkDeliveryType.toUpperCase()}_${this.selectedAddressType.toUpperCase()}`;
and in test file, I have following code:
test('If a check is requested', () => {
const selectedCheckAddress = {
addressLine1: 'test',
city: 'test',
state: 'test',
zipCode: '12345',
};
getters.selectedAddressType.mockReturnValue('Home');
getters.checkDeliveryType.mockRejectedValue('Regular');
expect(wrapper.vm.pageTitle).toStrictEqual('Request Submitted');
expect(wrapper.html()).toMatchSnapshot();
});
it is giving an error as
TypeError: this.checkDeliveryType.toUpperCase is not a function
How can we resolve this?

.toUpperCase() is a method provided by the String-class. It seems your variable this.checkDeliveryType isn't a string, hence you can not call this method (as it does not exist on whatever type your variable is at that point in time).
Either fix the type or cast the value manually to a string before and call .toUpperCase() on it afterwards. One way would be:
const checkDeliveryTypeStr = `${this.checkDeliveryType}`;
const keyToDisplayMessage = `${checkDeliveryTypeStr.toUpperCase()}_${this.selectedAddressType.toUpperCase()}`;
But in general it would be a better idea to fix the type correctly in your entire flow.

Related

vue-test-utils | TypeError: s.split is not a function

I try to run a test with vue-test-utils, including a component that has a mixin included, which has a function using split() on a string. The test looks like this:
describe('adminExample.vue Test', () => {
const wrapper = shallowMount(adminExample, {
global: {
mixins: [globalHelpers, authGatewayForElements, storeService],
plugins: [store]
}
})
it('renders component and is named properly', () => {
// check the name of the component
expect(wrapper.vm.$options.name).toMatch('adminExample')
})
})
adminExample.vue doesn't give any error, so I don't include it here, bit it uses a mixin.
The included mixin, called authGatewayForElements, has a function called decryptToken() and simply decrypt a jwt to get some info. The parameter userToken is declared within data of this mixin. The function looks like this:
decryptToken() {
let base64Split = this.userToken.split('.')[1];
let base64 = base64Split.replace(/-/g, '+').replace(/_/g, '/');
let jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
},
Running the test giving me the error TypeError: this.userToken.split is not a function . I´m new to testing with vue-test-utils and maybe or definitely missing something that needs to beincluded in the wrapper, as I expected functions like split() don't need to be included additionally.
EDIT: I get this error on multiple functions, like find(), so I'm pretty sure I just do something wrong. Thanks in advance to anybody pointing that out.

how to react native images to server by use apollo-client

currently i use apollo-client in react-navie and strapi as the backend. i try to upload images which get by ImageCropPicker to server by use apollo-client, but it always show "‘Upload’ scalar serialization unsupported." error . is there anyone know how to fix it?
export const UploadScalar = new GraphQLScalarType({
name: 'Upload',
description: 'The `Upload` scalar type represents a file upload.',
parseValue(value: any) {
return value
},
serialize(value: any) {
return value
},
parseLiteral(ast) {
throw new Error('‘Upload’ scalar literal unsupported.')
},
})

Getting Undefined while fetching particular key value from get method using Lodash

I have following array of data.
const filterToolTips = [{
remember_tip: 'some remember tip data.'
},
{
background_tip: 'some background tip data'
},
{
remember_on: 'some remember on tip data'
},
{
remember_off: 'some remember off data.'
},
{
background_on: 'some background on data '
}
];
I am trying to get each key text for different use case.
So, I am using lodash, But, It is showing undefined.
const toolText = get(filterToolTips,'remember_tip');
console.log('toolTipText', toolTipText); // 'toolTipText', undefined
Even I tried find too.
Any suggestions?
Use _.find() with _.has() to find an object with the requested key, and then use _.get() to take the value:
const filterToolTips = [{"remember_tip":"some remember tip data."},{"background_tip":"some background tip data"},{"remember_on":"some remember on tip data"},{"remember_off":"some remember off data."},{"background_on":"some background on data "}];
const key = 'remember_tip';
const toolText = _.get(
_.find(filterToolTips, o => _.has(o, key)),
key
);
console.log(toolText);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
However, this is a really weird data structure, and you should transform it (or ask the server guys to send you something more usable). This solution converts the data structure to a Map, and then gets the value:
const filterToolTips = [{"remember_tip":"some remember tip data."},{"background_tip":"some background tip data"},{"remember_on":"some remember on tip data"},{"remember_off":"some remember off data."},{"background_on":"some background on data "}];
const tipsMap = new Map(Object.entries(Object.assign({}, ...filterToolTips)));
const key = 'remember_tip';
const toolText = tipsMap.get(key);
console.log(toolText);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

jest snapshot testing: how to ignore part of the snapshot file in jest test results

Problem: ignore some part of the .snap file test results
the question here: there are some components in my test that have a random values and i don't really care about testing them. is there any way to ignore part of my X.snap file? so when i run tests in the future it won't give me test fail results.
Now you can also use property matcher for these cases.
By example to be able to use snapshot with these object :
const obj = {
id: dynamic(),
foo: 'bar',
other: 'value',
val: 1,
};
You can use :
expect(obj).toMatchSnapshot({
id: expect.any(String),
});
Jest will just check that id is a String and will process the other fields in the snapshot as usual.
Actually, you need to mock the moving parts.
As stated in jest docs:
Your tests should be deterministic. That is, running the same tests multiple times on a component that has not changed should produce the same results every time. You're responsible for making sure your generated snapshots do not include platform specific or other non-deterministic data.
If it's something related to time, you could use
Date.now = jest.fn(() => 1482363367071);
I know it's quite old question but I know one more solution. You can modify property you want to ignore, so it will be always constant instead of random / dynamic. This is best for cases when you are using third party code and thus may not be able to control the non deterministic property generation
Example:
import React from 'react';
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Card from './Card';
import toJSON from 'enzyme-to-json';
Enzyme.configure({ adapter: new Adapter() });
describe('<Card />', () => {
it('renders <Card /> component', () => {
const card = shallow(
<Card
baseChance={1}
name={`test name`}
description={`long description`}
imageURL={'https://d2ph5fj80uercy.cloudfront.net/03/cat1425.jpg'}
id={0}
canBeIgnored={false}
isPassive={false}
/>
);
const snapshot = toJSON(card);
// for some reason snapshot.node.props.style.backgroundColor = "#cfc5f6"
// does not work, seems the prop is being set later
Object.defineProperty(snapshot.node.props.style, 'backgroundColor', { value: "#cfc5f6", writable: false });
// second expect statement is enaugh but this is the prop we care about:
expect(snapshot.node.props.style.backgroundColor).toBe("#cfc5f6");
expect(snapshot).toMatchSnapshot();
});
});
You can ignore some parts in the snapshot tests replacing the properties in the HTML. Using jest with testing-library, it would look something like this:
it('should match snapshot', async () => {
expect(removeUnstableHtmlProperties(await screen.findByTestId('main-container'))).toMatchSnapshot();
});
function removeUnstableHtmlProperties(htmlElement: HTMLElement) {
const domHTML = prettyDOM(htmlElement, Infinity);
if (!domHTML) return undefined;
return domHTML.replace(/id(.*)"(.*)"/g, '');
}
I used this to override moment's fromNow to make my snapshots deterministic:
import moment, {Moment} from "moment";
moment.fn.fromNow = jest.fn(function (this: Moment) {
const withoutSuffix = false;
return this.from(moment("2023-01-12T20:14:00"), withoutSuffix);
});

vue js returned value gives undefined error

i want to check the returned value of $http.get() but i get undefined value. Here is my vue js code:
var vm = new Vue({
el: '#permissionMgt',
data: {
permissionID: []
},
methods:{
fetchPermissionDetail: function (id) {
this.$http.get('../api/getComplaintPermission/' + id, function (data) {
this.permissionID = data.permissionID; //permissionID is a data field of the database
alert(this.permissionID); //*****this alert is giving me undefined value
});
},
}
});
Can you tell me thats the problem here?.. btw $http.get() is properly fetching all the data.
You need to check what type is the data returned from the server. If #Raj's solution didn't resolve your issue then probably permissionID is not present in the data that is returned.
Do a colsole.log(data) and check whether data is an object or an array of objects.
Cheers!
Its a common js error. Make the following changes and it will work.
fetchPermissionDetail: function (id) {
var self = this; //add this line
this.$http.get('../api/getComplaintPermission/' + id, function (data) {
self.permissionID = data.permissionID; //replace "this" with "self"
});
},
}
the reason is this points to window inside the anonymous function function()
This is a well known js problem. If you are using es2015 you can use arrow syntax (() => { /*code*/ }) syntax which sets this correctly