Anticipating and validating tracking events with Cypress - google-analytics

I am having problems using this plug with events that are triggered from the batch url. The plugin is as follows:
Cypress.Commands.add('eventCall' , function ({
alias = 'postEvent',
name,
event,
properties = {},
} = {})
const eventType = event ? 'track' : 'page';
const url =
eventType === 'track'
? 'https://api.segment.io/v1/t'
: 'https://api.segment.io/v1/batch';
const propertyNames = Object.keys(properties);
cy.wrap(alias).as('eventAlias');
if (propertyNames.length > 0) {
cy.wrap(propertyNames).as(`${alias}PropertyNames`);
cy.wrap(properties).as(`${alias}ExpectedProperties`);
cy.wrap({}).as(`${alias}ActualProperties`);
}
cy.intercept('POST', url, (req) => {
const requestBody = JSON.parse(req.body);
if (
(eventType === 'track' && requestBody.event === event) ||
(eventType === 'page' && requestBody.name === name) ||
(eventType === 'page' && !name)
) {
req.alias = alias;
if (propertyNames.length > 0) {
this[`${alias}ActualProperties`] = requestBody.properties;
}
}
});
});
the type of event I am trying to validate is the following:
analytics.track({
anonymousId: '123213123',
userId: '10000000000111111',
event: 'EVENT NUMBER1',
properties: {
cart_id: '4069313',
name: 'aaa',
price: 0,
product_id: '1234'
}
});
And in Cypress I am trying to access as follows:
cy.SegmentCall({
event: 'EVENT NUMBER1',
properties: {
cart_id: '4069313',
name: 'aaa',
price: 0,
product_id: '1234'
},
});
});
But I can't get it to work. Does anyone have any idea

Related

Gutenberg Infinite Loop

I'm working on building a Gutenberg block but it seems I keep getting an infinite loop. How can I invoke the rest API only once?
I am trying to get a list of officers - custom post type - but as the initial call doesn't provide the featured image I thought I should loop through and add the images "manually". If there is a better approach please do let me know.
registerBlockType('test/officers-block', {
title: __('Officers Block', 'test'),
description: __('Block to generate the officers block', 'test'),
icon: '',
category: 'test',
attributes: {
title: {
type: 'string',
},
posts: {
type: 'array',
}
},
edit: ({ attributes, setAttributes }) => {
const {
title,
posts,
} = attributes
// Request data
const data = useSelect((select) => {
return select('core').getEntityRecords('postType', 'officers', { per_page: -1 });
});
const isLoading = useSelect((select) => {
return select('core/data').isResolving('core', 'getEntityRecords', [
'postType', 'officers',
]);
});
const setOfficers = ( data ) => {
let officerData = [];
data.map(( officer ) => {
wp.apiFetch( { path: '/wp/v2/media/' + officer?.featured_media } ).then( function( image ){
officerDataEach.title = officer?.title?.rendered
officerDataEach.content = officer?.content?.rendered
officerDataEach.job = officer?.meta?._job_title
officerDataEach.phone = officer?.meta?._phone
officerDataEach.email = officer?.meta?._email
officerDataEach.image = image?.media_details?.sizes?.full?.source_url
officerData.push( officerDataEach )
})
})
console.log(officerData);
setAttributes( { posts: officerData } )
}
if( !isLoading && data ){
setOfficers( data );
}
if ( isLoading && !data ) {
return <h3>Loading...</h3>;
}
...
Thanks in advance

filter by category work not properly with remote search?

Hello I have problem compute vue filter by category it work not properly when I add item on Service tab and then click on Medicine tab remote search item by category it will stuck and filter not work and when I click in Service tab back it show only number 2.
this my template
<el-table
:data="itemFilters"
row-key="no"
style="width: 100%"
>
This my script
computed: {
itemFilters() {
const self = this
let item = self.form.items.filter(o => {
return o.categoryName === self.tabActive || o.itemId === ''
})
return item
},
},
this Method
methods: {
_getItemOpts(query, type) {
let exp = new RegExp(query)
let selector = {
$or: [
{ name: { $regex: exp, $options: 'i' } },
{ refNo: { $regex: exp, $options: 'i' } },
{ barcode: { $regex: exp, $options: 'i' } },
],
activityType: { $in: ['Sale'] },
status: 'Active',
'catDoc.name': this.tabActive,
}
// For form Sale Return and receipts refund
if (this.formName == 'Sale_Return' || this.formName == 'Receipt_Refund') {
selector.itemType = { $ne: 'Bundle' }
}
findItems
.callPromise({ selector: selector })
.then(result => {
// this.itemOpts = result
if (type == 'remote') {
// For remote
this.form.items[this.activeIndex].itemOpts = result
} else {
// For scan barcode
let item = result[0]
if (item) {
let row = {
itemId: item._id,
itemType: item.itemType,
memo: '',
qty: 1,
qtyRate: 1,
unitId: item.units[0].unitId,
units: item.units,
price: item.price,
amountBeforeDiscount: item.price,
discountRate: 0,
discountValue: 0,
amountAfterDiscount: item.price,
taxId: '',
taxAmount: 0,
// For expand bundle item
subItems: [],
expand: 'expand',
// For sales only(cash sales and invoice)
// refSaleOrderId: '',
// refSaleOrderDetailId: '',
// refNo: '',
itemOpts: result,
}
this.form.items.push(row)
} else {
Notify.warning({ message: 'This item do not set barcode!' })
}
}
this.loading = false
})
.catch(err => {
this.loading = false
this.$notify.error(err.reason)
})
},
}
Please help...

AngularFire2 query, join or filter with foreign keys from another firebase table

I have this firebase data structure
{
members: {
m1: {
lastName: "smith",
firstName: "john"
},
m2: {
lastName: "abc",
firstName: "mike"
}
},
userFavs: {
u1: {
m1:true
},
u2: {
m2:true
}
}
}
In my service, I have this method:
getMembers(): FirebaseListObservable<any[]> {
return this.af.database.list('/members',{
query: {
orderByChild: 'firstName'
}
});
}
In members page TS file, I have method to do search:
setFilteredItems(){
if (this.searchTerm == null || this.searchTerm == ''){
this.members = this.membersSvc.getMembers()
.map((members) => {return members});
}else{
//return items.filter(item => item.name.toLowerCase().indexOf(args[0].toLowerCase()) !== -1);
this.members = this.membersSvc.getMembers()
.map((members) =>
members.filter(member => member.lastName.toLowerCase().indexOf(this.searchTerm.toLowerCase()) !== -1 || member.firstName.toLowerCase().indexOf(this.searchTerm.toLowerCase()) !== -1));
}
}
The search for members is working fine. Now I am adding 2 buttons below the search bar, All and Favorites. A user can add a member in his/her favorites. In search, the app needs to be able to filter the results with member keys that exists in the user favorites.
How can I add the additional filter of member keys that exists in the userFavs node?
I added the additional filter by getting the array of userFavs keys. So in my user service I have a method:
getUserFavKeys(){
let favKeys = [];
const userKey = this.authService.getActiveUser().uid;
let url = `/userCircles/${userKey}`;
this.af.database.list(url, { preserveSnapshot: true})
.subscribe(itemKeys=>{
itemKeys.forEach(itemKey => {
//console.log(itemKey.key);
favKeys.push(itemKey.key);
});
})
return favKeys;
}
Then in the component ngOnInit method, I initialized the array of keys:
this.favKeys = this.userSvc.getUserFavKeys();
And when the circles is selected:
onCirclesSelected(){
this.searching = false;
this.members = this.membersSvc.getMembers()
.map((members) =>
members.filter(member => this.userCircles.indexOf(member.$key) !== -1)
);
if (this.searchTerm == null || this.searchTerm == ''){
//do nothing
}else{
//filter w the search text
this.members = this.members
.map((members) =>
members.filter(member => member.lastName.toLowerCase().indexOf(this.searchTerm.toLowerCase()) !== -1 || member.firstName.toLowerCase().indexOf(this.searchTerm.toLowerCase()) !== -1));
}
}
Hope that helps to anyone that needs the same search feature.

meteor : login with google (how display profile user?)

i had create login system with google Api but i have problem to display picture and name user. That is my code. Please anyone help me.
// js
if (Meteor.isClient){
Meteor.subscribe ('user');
Template.body.helpers({
firstName: function(){
var user = Meteor.user();
if (user) {
return user.services.google.given_name;
}
},
profileURL: function() {
var user = Meteor.user();
if (user) {
return user.services.google.picture;
}
}
});
//server
Meteor.publish("user", function () {
return Meteor.users.find({_id: this.userId},
{fields: {'other': 1, 'things': 1}});
});
You can save values with Accounts.onCreateUser and save the relevant information.
//in server
Accounts.onCreateUser(function(options,user){
if (typeof(user.services.google) != "undefined") {
user.email = user.services.google.email;
user.profilePicture = user.services.google.picture;
user.username = user.services.google.name;
}
return user;
});
Then you can return those fields using {{}}.
{{currentUser.username}} // returns email of the current user
Also, you need routing for defining routes. Check iron:router and flow:router
You have to add the desired values to the user document in the collection.
This code builds the user object with the common values from the login services for meteor.loginwith [facebook, google,twitter]. Then adds it to the mongo collection for the users.
Now all this data will be accessible from the currentUser object.
You can remove the values or networks you're not using.
Accounts.onCreateUser( ( options, user )=> {
user.profile = getProfile( user );
function getProfile( user ) {
let service = user.services;
let network = _.keys( service )[ 0 ];
let data = service[ network ];
let profile = {};
if ( network === 'facebook' ) {
profile.network = network;
profile.id = data.id;
profile.email = data.email;
profile.name = data.name;
profile.locale = data.locale;
profile.gender = data.gender;
profile.picture = 'http://graph.facebook.com/' + data.id + '/picture?type=square';
}
else if ( network === 'google' ) {
profile.network = network;
profile.id = data.id;
profile.email = data.email;
profile.name = data.name;
profile.locale = data.locale;
profile.picture = data.picture;
}
else if ( network === 'twitter' ) {
profile.network = network;
profile.id = data.id;
profile.email = data.email;
profile.name = data.screenName;
profile.locale = data.lang;
profile.picture = data.profile_image_url_https;
}
let value = {};
value[ network ] = profile;
return value;
}
Meteor.users.update( user._id, {
$set: {
profile: user.profile
}
} );
return user;
} );

Meteor.js : SearchSource + Publish composite

I'm currently creating a research engine for my app.
Until now, I used Publish composite + iron router : The user could had filters to search for some specific set of users.
Now, I want him to be able to look for some keywords too. For that I downloaded and tested the great SearchSource package.
The problem is that the SearchSource server side definition only seems to allow to return one cursor.
How could I combine the two logics ? Even if it's tricky, please, share.
Of course I could make an autorunned subscription where I look for every users loaded on the client and then subscribe to the additionnal documents, but it is not really the most performant and beautifull thing to do.
Some data :
Here is my current Publish Composite for filters :
Meteor.publishComposite("findTalkers", function(page, langs){
//console.log("Find Talkers");
//console.log("page : " + page);
//console.log("langs : " + langs);
if (langs.length)
{
return ({
find: function()
{
if (langs && langs.length)
{
var test = {$in: langs};
preSelectedUsers = [],
selector = {
_id: {$ne: this.userId},
"profile.completed": true,
"profile.firstName": {$exists: true},
"profile.languages.native": {$exists: false},
"profile.languages.lang": test
};
Counts.publish(this, "nbUsers", Meteor.users.find(selector, {
fields: {_id: 1}
}), {noReady: false, nonReactive: true});
if (page > 1)
{
preSelectedUsers = Meteor.users.find(selector, {
sort: {'profile.talkname': 1},
limit: 25,
skip: (25 * (page || 1)),
fields: {_id: 1}
}).fetch();
var i = -1;
while (preSelectedUsers[++i])
preSelectedUsers[i] = preSelectedUsers[i]._id;
}
if (page > 1)
selector._id = {$in: preSelectedUsers};
return Meteor.users.find(selector, {
fields: userFields,
sort: {'profile.talkname': 1},
limit: 25
});
}
},
children: [
{
// Finding user's profile picture if it is not url
find: function(user)
{
if (user && user.profile && user.profile.avatar.type != "url")
return Images.find({_id: user.profile.avatar.data}, {sort: {uploadedAt: -1}, limit: 1});
}
}
]
});
}
else
{
return ({
find: function()
{
return Meteor.users.find({_id: "flush"});
}
});
}
});
Here is my research with SearchSource :
Client :
var searchOptions = {
keepHistory: 1000 * 60 * 5,
localSearch: true
},
SearchSources = {
talkersSearch: new SearchSource('users', ['profile.talkname'], searchOptions)
};
Router.map(function(){
this.route('talkers/:page?',
{
template: "talkers",
onBeforeAction: function(pause){
(Meteor.user() && Meteor.user().profile.completed)
? this.next()
: this.render('/profile');
},
waitOn: function(){
var filters = MatesFilter.find().fetch(),
i = -1;
while (filters[++i])
filters[i] = filters[i].value;
if (filters.length)
{
return Meteor.subscribe("findTalkers", (this.params.page || 1), filters, function(){
Session.set('numberuser', Counts.get("nbUsers"));
});
}
return Meteor.subscribe('myself');
}
});
}
Template.talkers.helpers({
getPackages: function() {
return SearchSources.talkersSearch.getData({
transform: function(matchText, regExp) {
return matchText.replace(regExp, "<b>$&</b>")
},
sort: {isoScore: -1}
});
}
}
Template.talkers.events({
"keyup #header-search": _.throttle(function(e) {
Session.set("matesSearch", $(e.target).val().trim());
console.log("Searching for : " + text);
SearchSources.talkersSearch.search(Session.get("matesSearch"), {
page: (this.params.page || 1),
filters: filters
});
}, 200)
}
SERVER :
SearchSource.defineSource('users', function(searchText, options) {
var options = {sort: {"profile.talkname": -1}, limit: 25};
if(searchText)
{
var regExp = buildRegExp(searchText);
selector = { $or: [
{ "profile.talkname": regExp },
{ "profile.bio": regExp }
] };
return Meteor.users.find(selector, options).fetch();
}
return ;
});
All this Gives me two sources from which I can get users. I'd want to get a mean to merge the two ides (a composition of publication INSIDE the search, for example).
Thanks you.

Resources