what are the assertions that are used for check the order in below body in api tesing using cypress - api

This is the body for reorder. How can I do assertions to check the order for particular in array[3]
{
"dimName": "Women's Clothing",
"dimOrder": 2,
"dimType": "wa",
"dimId": "category#womens-clothing",
"dimParent": "category"
},
{
"dimName": "Jewelry 1",
"dimOrder": 1,
"dimType": "wa",
"dimId": "category#jewelry",
"dimParent": "category"
},
{
"dimName": "Handbags",
"dimOrder": 3,
"dimType": "wa",
"dimId": "category#handbags",
"dimParent": "category"
}

If you received the above as a json response in an API test, a couple of quick examples:
Check the order of id's like this
cy.request(...)
.then(response => {
expect(response[0].dimId).to.eq('category#womens-clothing')
expect(response[1].dimId).to.eq('category#jewelry')
expect(response[2].dimId).to.eq('category#handbags')
})
Check the dimOrder field is sequential like this
cy.request(...)
.then(response => {
const dimOrder = response.map(item => item.dimOrder)
expect(dimOrder).to.deep.eq([1,2,3]) // deep because is array matching
})

For easier assertions on a response, especially nested properties, you can use cy-spok. It's also quicker to comprehend.
const spok = require('cy-spok')
cy.request(...)
.its('response.body')
.should(spok({
propertieWithArray: [
{
// you can assert the properties equal exact values
dimName: "Women's Clothing",
dimOrder: 2,
dimType: "wa",
dimId: "category#womens-clothing",
dimParent: "category"
},
{
// you can assert properties meet specifications
dimName: spok.string, // Jewelry 1
dimOrder: spok.number, // 1
dimType: spok.type('string'), // wa
dimId: spok.startsWith('category'), // category#jewelry
dimParent: spok.endsWith('category') // category
},
{
// use combination
dimName: spok.string,
dimOrder: spok.gt(0),
dimType: "wa",
dimId: spok.test(/#/),
dimParent: "category"
}

Related

How to use a part of intercepted endpoint as a variable in my stub with Cypress

I am testing a frontend and I want to make my test more efficient
I have the following custom command:
cy.intercept('**/api/classification/dd86ac0a-ca23-413b-986c-535b6aad659c/items/**',
{ fixture: 'ItemsInEditor.json' }).as('ItemsInEditorStub')
This works correctly and is intercepts 25 times :). But the Id in the stub file has to be the same as in the requested Endpoint. Otherwise the frontEnd wilt not process it.
At this point I do not want to make 25 stubfiles in the fixture map.
In the printscreen you can see the different calls I need to intercept. The last ID I would like to save as variable and use it in the stub file
The Stub is like this:
{
"item": {
"version": 3,
"title": "Cars",
"rows": [],
"id": "dynamicIdBasedOnEndPoint" <- *Can we make it dynamic based on the ID in the endpoint*
},
"itemState": "Submitted"
}
UPDATE:
What I have for now is just the basic I guess:
cy.intercept('**/api/classification/*/items/**', {
body:
{
item: {
version: 3,
title: 'Cars',
rows: [],
id: '55eb5a28-24d8-4705-b465-8e1454f73ac8' //Still need this value to be dynamic and always the same as the intercepted '**'(wildcard)
},
itemState: "Submitted"
}
})
.as('ItemsInEditorStub')
cy.fixture('ItemsInEditor.json').then(ModFixture => {
cy.intercept('GET', '**/api/classification/**/items/id/**', (req) => {
const id = req.url.split('/').pop(); // last part of url path
ModFixture.item.id = id; // add the id dynamically
req.reply(ModFixture); // send altered fixture
})
}).as('ItemsInEditorStub')
Thanks to #Fody
You can make a dynamic fixture using javascript.
Ref Providing a stub response with req.reply()
cy.fixture('ItemsInEditor.json').then(fixture => {
cy.intercept('**/api/classification/dd86ac0a-ca23-413b-986c-535b6aad659c/items/**',
(req) => {
const id = req.url.split('/').pop(); // last part of url path
fixture.item.id = id; // add the id dynamically
req.reply(fixture); // send altered fixture
}
).as('ItemsInEditorStub')
})

React Native - Using promises when fetching and returning them to components

i want to display related data on react native, i have 2 response api
response 1
{
"total": 2,
"data" : [
{
"date" : "2020-12-01",
"time" : "08:00:00"
},
{
"date" : "2020-12-02",
"time" : "09:00:00"
}
]
}
response 2, date is parameter
date : 2020-12-01
{
"total": 2,
"data" : [
{
"date" : "2020-12-01",
"description" : "bla bla bla"
},
{
"date" : "2020-12-01",
"description" : "vla vla vla"
}
]
}
date : 2020-12-02
{
"total": 1,
"data" : [
{
"date" : "2020-12-02",
"description" : "cla cla cla"
}
]
}
how to use promises on fetch and how components return them,
so it can display content descriptions like this
Are you asking how to use promises with Fetch? Or how to take the results of those promises and use them to create a visual component?
It doesn't look like you've put any work into asking this question and it's quite wide ranging, from setting up components, creating fetch requests to an API and formatting them into visual components.
I'd consider starting here for your fetch request:
https://reactnative.dev/docs/network#making-requests
Then look at how they take the text and place it on a screen here:
https://reactnative.dev/docs/network#making-requests
EDIT:
Per the comments below.
You would most likely want to store the results of your request in some form of local state, and pass that state to your FlatList or similar, for instance:
const PromiseExample = () => {
const [listItems, setListItems] = useState([])
useEffect(() => {
async function fetchData() {
const data = await fetch('localhost:3000/data').json()
const otherData = await fetch('localhost:3000/otherData').json()
let joinedData = []
// at this point you would join your two data structures in whatever way you need to and push the joined data to the var.
setListItems(joinedData)
}
}, [])
return (
<FlatList data={listItems} />
)
}

Filtering 2 or more categories in vue.js

I have a code where i filtered an array with a specific category.
response.data.items.filter(item => item.category_id === categ_id_1)
Now i want to add more categories in the filter (categ_id_2, categ_id_3). How do i do that?
Assuming the category_id is a primitive (ie string, number, etc), the easiest way I can think of is to maintain a Set of wanted categories and use Set.prototype.has() for filtering.
const categories = new Set(['categ_id_1', 'categ_id_2', ...])
response.data.items.filter(({ category_id }) => categories.has(category_id))
If you're wanting the list to be reactive in Vue, something like this...
data: () => ({
categoryFilters: ['categ_id_1', 'categ_id_2']
}),
computed: {
categoryFilterSet () {
return new Set(this.categoryFilters)
}
},
methods: {
async loadAndFilterData () {
const response = await axios({...}) // just guessing
const filtered = response.data.items.filter(({ category_id }) =>
this.categoryFilterSet.has(category_id))
}
}
The reason for using the computed property is that Vue does not work reactively with Set so you must back it up with an array.
Another way using Array.prototype.includes() which is used to pass/fail the test of filter for each element.
const items = [{
"a": 1,
"category_id": "categ_id_1"
}, {
"a": 2,
"category_id": "categ_id_2"
}, {
"a": 3,
"category_id": "categ_id_3"
}, {
"a": 4,
"category_id": "categ_id_4"
}, {
"a": 5,
"category_id": "categ_id_5"
}];
const search = ["categ_id_2", "categ_id_3"];
const result = items.filter(e => search.includes(e.category_id));
console.info("result::", result);
Try it as
response.data.items.filter(item => item.category_id === categ_id_1 ||item.category_id === categ_id_2 ||item.category_id === categ_id_3)

How to Merge two array of object with the same keys that have the same values and the different value will be stored in an array?

I got data from database like this:
[
{
id_user:1,
expense:3000
},
{
id_user:1,
expense:5000
},
{
id_user:2,
expense:35000
},
{
id_user:3,
expense:50100
}
]
How can i convert to json like this ?
[
{
id_user:1,
expense:[3000,5000]
},
{
id_user:2,
expense:35000
},
{
id_user:3,
expense:50100
}
]
Reduce & Map is way to go. And it's way better to have all expense fields to be an array, so you don't have to check weather it's an array or not
const sample = [{
id_user: 1, expense: 3000
}, {
id_user: 1, expense: 5000
}, {
id_user: 2, expense: 35000
}, {
id_user: 3, expense: 50100
}]
const parseData = data => {
return [...data.reduce((acc, { id_user, expense }) => {
const currentUser = acc.get(id_user)
const newExpense = currentUser ? currentUser.expense : []
newExpense.push(expense)
acc.set(id_user, { id_user, expense: newExpense })
return acc
}, new Map()).values()]
}
console.log(parseData(sample))
You would just need to write a program to do it. This is how I'd approach it:
// phase 1
const combined = {};
for (const item of data) {
if (!combined[item.id_user]) {
combined[item.id_user] = [];
}
combined[item.id_user].push(item.expense);
}
// phase 2
const newData = [];
for (const id of Object.keys(combined)) {
newData.push({id_user: id, expense: combined[id]});
}
The approach is 2 phases. The first phase goes through the data and combines expense values for the same user into an array. I build it into an Object since it's efficient to look up entries by their key this way. If there are a lot of records to process this will be faster than pushing into an Array and using .includes to find entries that already exist.
The 2nd phase is building the new array with the combined expense arrays. This is done by pushing each new object into the output Array.
Note that I chose to make the new expense always be an array even if there's only one expense. It's cleaner to have an attribute have a consistent type rather than having to check if it's an Array when accessing the data.

How can I use Ember Data's FixtureAdapter with real API content

I want to populate my Ember Data fixtures with real content taken from an API data dump instead of the standard fixtures. I don't want to use the API directly.
I want to do this so I can imitate a local instance of the API data.
How can I streamline this and also how might I configure the adapter to allow this?
Consider this default FIXTURE:
App.Comment = DS.Model.extend({
article: DS.belongsTo('article'),
author: DS.belongsTo('user'),
dateCreated: DS.attr('date', {readOnly: true}),
dateModified: DS.attr('date', {readOnly: true}),
description: DS.attr('string')
});
App.Comment.FIXTURES = [{
id: 1,
temp: 1,
author: 1,
dateCreated: 'Mon Jul 28 2014 12:00:00 GMT+1000 (EST)',
dateModified: null,
description: 'lorem ipsum'
}];
Consider this API response:
{"comments": [
{
"articleID": 1,
"description": "I am a comment",
"authorID": 1,
"dateCreated": "2014-09-04T02:39:00",
"createdBy": "Elise Chant",
"dateModified": "2014-09-04T02:39:00",
"id": 1
},
{
"articleID": 1,
"description": "I am another comment",
"authorID": 1,
"dateCreated": "2014-09-04T02:48:00",
"createdBy": "Elise Chant",
"dateModified": "2014-09-04T02:48:00",
"id": 2
}
]}
Get your backend to provide a data dump method from the API with the resources, such as:
http://myapi/dump
The method shall return a zipped folder of files representing the site's resources, such as Comment.js, User.js, Article.js.
Each of these files should return the JSON resource wrapped by DS.Model.FIXTURES array, such as
App.Comment.FIXTURES =
[
{
"articleID": 1,
"userID": 1,
"description": "I am a comment.",
"category": 0,
"authorID": 1,
"dateCreated": "2014-09-04T02:39:00",
"id": 1
},
// ...
];
Remember to make sure that each .js file is an included script tag in html and appears after its corresponding model. Check this is available in the Browser's Developer Console.
Finally, In order to correctly connect asynchronous relationships such as articleID and authorID, property names need to be normalised like that would be if you were using normal fixture data. So configure the adapter to strip 'ID' from the end of any belongsTo relationships by parsing the FIXTURES payload:
if (App.ENV === 'DEV') {
App.ApplicationSerializer = DS.JSONSerializer.extend({
// access to the payload
extractArray: function(store, type, payload) {
var self = this;
return payload.map(function(item) {
// normalise incoming data
return self.normalize(type, item);
});
},
normalize: function(type, hash) {
if (!hash) { return hash; }
var normalizedHash = {},
normalizedProp;
for (var prop in hash) {
if (!!prop.match(/ID$/)) {
// belongs to / has Many attribute
// remove 'ID' from the end of the property name
normalizedProp = prop.substr(0, prop.length-2);
} else { // regular attribute
normalizedProp = prop;
}
normalizedHash[normalizedProp] = hash[prop];
}
this.normalizeId(normalizedHash);
this.normalizeUsingDeclaredMapping(type, normalizedHash);
this.applyTransforms(type, normalizedHash);
return normalizedHash;
}
});
App.ApplicationAdapter = DS.FixtureAdapter.extend({
simulateRemoteResponse: true,
latency: 1000,
// This "unsets" serializer so that the store will lookup the proper serializer
// #see https://github.com/emberjs/data/issues/1333
serializer: function() {
return;
}.property()
});
} else {
DS.CustomRESTSerializer = DS.RESTSerializer.extend({
keyForRelationship: function(key, kind) {
if (kind === 'belongsTo') {
return key + 'ID';
} else {
return key;
}
}
});
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: App.HOST,
namespace: App.NAMESPACE,
ajax: function(url, method, hash) {
hash = hash || {}; // hash may be undefined
hash.crossDomain = true;
hash.xhrFields = {withCredentials: true};
return this._super(url, method, hash);
},
defaultSerializer: 'DS/customREST'
});
}