How to write unit test with Jasmine-Karma in Angular? - javascript

I have two functions I need to write unit test for it. I tried some test but I don't know to check whether my variable value is changing according to the condition.
ifAllowed: Boolean = false;
checkRoleModifierExists() {
if (this.userDetails && this.userDetails.roles) {
for (
let userRolesIndex = 0;
userRolesIndex < this.userDetails.roles.length;
userRolesIndex++
) {
if (this.userDetails.roles[userRolesIndex] === 'ROLE_ADMIN_SUPPORT' &&
this.roleModifiers.body &&
this.roleModifiers.body.length) {
this.ifAllowed = this.ifAllowedFun();
}
if (this.userDetails.roles[userRolesIndex] === 'ROLE_ADMIN') {
this.ifAllowed = true;
}
}
}
}
ifAllowedFun() {
let ifRole = false;
for (const roleModifier of this.roleModifiers.body) {
if (roleModifier === 'PC-ABC') {
ifRole = true;
}
}
return ifRole;
}
this is test which I tried but it's failing.
it('should check roles modifiers ', () => {
component.ifAllowed = false;
component.ngOnInit();
spyOn(component, 'checkRoleModifierExists').and.callThrough();
component.userDetails = {
roles: ''
};
component.userDetails.roles = [ 'ROLE_ADMIN_SUPPORT' ];
component.roleModifiers = {
body: [ 'PC-ABC' ]
};
component.checkRoleModifierExists();
expect(component.ifAllowed).toEqual(true);
});

Related

How to override a owl function in odoo?

I want to override a function in companyService but have no idea how to do it.
Here is the code in company_service.js and I want to override the start function.
/** #odoo-module **/
import { browser } from "#web/core/browser/browser";
import { registry } from "#web/core/registry";
import { symmetricalDifference } from "#web/core/utils/arrays";
import { session } from "#web/session";
function parseCompanyIds(cidsFromHash) {
const cids = [];
if (typeof cidsFromHash === "string") {
cids.push(...cidsFromHash.split(",").map(Number));
} else if (typeof cidsFromHash === "number") {
cids.push(cidsFromHash);
}
return cids;
}
function computeAllowedCompanyIds(cids) {
const { user_companies } = session;
let allowedCompanyIds = cids || [];
const availableCompaniesFromSession = user_companies.allowed_companies;
const notReallyAllowedCompanies = allowedCompanyIds.filter(
(id) => !(id in availableCompaniesFromSession)
);
if (!allowedCompanyIds.length || notReallyAllowedCompanies.length) {
allowedCompanyIds = [user_companies.current_company];
}
return allowedCompanyIds;
}
export const companyService = {
dependencies: ["user", "router", "cookie"],
start(env, { user, router, cookie }) {
let cids;
if ("cids" in router.current.hash) {
cids = parseCompanyIds(router.current.hash.cids);
} else if ("cids" in cookie.current) {
cids = parseCompanyIds(cookie.current.cids);
}
let allowedCompanyIds = Object.values(session.user_companies.allowed_companies).map(company => company.id);
const stringCIds = allowedCompanyIds.join(",");
router.replaceState({ cids: stringCIds }, { lock: true });
cookie.setCookie("cids", stringCIds);
user.updateContext({ allowed_company_ids: allowedCompanyIds });
const availableCompanies = session.user_companies.allowed_companies;
return {
availableCompanies,
get allowedCompanyIds() {
return allowedCompanyIds.slice();
},
get currentCompany() {
return availableCompanies[allowedCompanyIds[0]];
},
setCompanies(mode, ...companyIds) {
// compute next company ids
let nextCompanyIds;
if (mode === "toggle") {
nextCompanyIds = symmetricalDifference(allowedCompanyIds, companyIds);
} else if (mode === "loginto") {
const companyId = companyIds[0];
if (allowedCompanyIds.length === 1) {
// 1 enabled company: stay in single company mode
nextCompanyIds = [companyId];
} else {
// multi company mode
nextCompanyIds = [
companyId,
...allowedCompanyIds.filter((id) => id !== companyId),
];
}
}
nextCompanyIds = nextCompanyIds.length ? nextCompanyIds : [companyIds[0]];
// apply them
router.pushState({ cids: nextCompanyIds }, { lock: true });
cookie.setCookie("cids", nextCompanyIds);
browser.setTimeout(() => browser.location.reload()); // history.pushState is a little async
},
};
},
};
registry.category("services").remove("company").add("company", companyService);
You can use the patch utility
However, there are situations for which it is not sufficient. In those cases, we may need to modify an object or a class in place. To achieve that, Odoo provides the utility function patch. It is mostly useful to override/update the behavior of some other component/piece of code that one does not control.
Example:
/** #odoo-module **/
import { patch } from "#web/core/utils/patch";
import { companyService } from "#web/webclient/company_service";
patch(companyService, 'module_name.companyService', {
start(env, { user, router, cookie }) {
return this._super(env, { user, router, cookie });
}
});

How to make search case insensitive in Angular

I have a list of data names and I want to search through it. It should give result irrespective of the case.
this is what I have:
public groups = [{ name: '"Grx-1"', selected: false }, { name: '"Grx-man-2"', selected: false }, { name: '"Grx-up-3"', selected: false }];
queryGroups(groupName) {
this.groups = this.totalGroupsList.filter((group) => {
if (group.userId.includes(groupName) || group.dps.includes(groupName) || group.sourceType.includes(groupName)) {
return true;
} else {
let isRole = false;
group.role.forEach((role) => {
if (role.name.includes(groupName)) {
isRole = true;
return;
}
});
if (isRole === false) {
return false;
} else {
return true;
}
}
});
}
If I search for "Grx" I get all the results. I want that if I search for "grx" i should get all the results.
You can use toLowerCase()
role.name.toLowerCase().includes(groupName.toLowerCase())
You must use more than one search method :
queryGroups(groupName: string) {
this.groups = this.totalGroupsList.filter((group) => {
let isExist = this.searchFunc(groupName, group.userId)
|| this.searchFunc(groupName, group.dps)
|| this.searchFunc(groupName, group.sourceType)
if (isExist) {
return true;
} else {
let isRole = false;
group.role.forEach((role) => {
if (this.searchFunc(groupName, role.name)) {
isRole = true;
break;
}
});
return isRole !== false;
}
});
}
private searchFunc(searchKey, searchTarget): boolean {
if(!searchKey) {
return false;
}
return (searchTarget.toLocaleUpperCase().includes(searchKey.toLocaleUpperCase())) ||
(searchTarget.toUpperCase().includes(searchKey.toUpperCase())) ||
(searchTarget.includes(searchKey.toLocaleUpperCase())) ||
(searchTarget.includes(searchKey.toUpperCase())) ||
(searchTarget.toLocaleUpperCase().includes(searchKey)) ||
(searchTarget.toUpperCase().includes(searchKey)) ||
(searchTarget.includes(searchKey))
}

Dynamically building a complex object

This will be the different for every user based on their roles. I am looking to build an object that can look like this:
let permissions = {
'state': {
'tool': ['subTool1', 'subTool2']
}
}
An example:
roles = ['NY_email_submit', 'NY_email_approve', 'NY_build_submit', 'NY_build_view', 'DC_email_submit']
let permissions = {
'NY': {
'email': ['submit', 'approve'],
'build': ['submit', 'view']
},
'DC': {
'email': ['submit']
}
};
I am looping through a list, named roles, passed in that contains strings broken up like state_tool_subTool.
I would like it to have no duplicates. For example, if the next user role ran through the loop with the object above is NY_build_approve, I would like to simply add approve to the the list at ['build'].
Currently I have this that is not working correctly.
roles.forEach(role => {
role = role.split('_');
let state = role[0];
let tool = role[1];
let subTool = role[2];
if ([state] in permissions) {
permissions[state] = { [`${tool}`]: [subTool] };
} else {
//permissions[state][`${tool}`].push(subTool);
}
});
This should do the trick! You were on the right track, just needed another layer of checks
let permissions = {};
roles = ['NY_email_submit','NY_email_approve','NY_build_submit','NY_build_view', 'DC_email_submit'];
roles.forEach(role => {
let [state, tool, subTool] = role.split('_');
if (state in permissions) {
if (tool in permissions[state]) {
permissions[state][tool].push(subTool)
} else {
permissions[state][tool] = [subTool]
}
} else {
permissions[state] = {[tool]: [subTool]}
}
});
console.log(permissions);
roles = ['NY_email_submit', 'NY_email_approve', 'NY_build_submit', 'NY_build_view', 'DC_email_submit']
let permissions = {};
roles.forEach(role => {
role = role.split('_');
let state = role[0];
let tool = role[1];
let subTool = role[2];
if (!permissions[state]) {
permissions[state] = {[tool] : [subTool]};
} else {
if (permissions[state][tool]) {
if(!permissions[state][tool].includes(subTool)) {
permissions[state][tool] = [...permissions[state][tool], subTool];
}
}
else {
permissions[state][tool] = [subTool];
}
}
});
console.log(permissions);
here is another approach using reduce
roles = ['NY_email_submit', 'NY_email_approve', 'NY_build_submit', 'NY_build_view', 'DC_email_submit']
sp=roles.map(o=>o.split("_")).reduce((acc,curr)=>{
if (!acc[curr[0]]) acc[curr[0]]={...acc[curr[0]],[curr[1]]:[...[curr[2]]]}
else {
if(acc[curr[0]][curr[1]]) {
i=acc[curr[0]][curr[1]]
acc[curr[0]]={...acc[curr[0]],[curr[1]]:[...i,...[curr[2]]]} }
else {acc[curr[0]]={...acc[curr[0]],[curr[1]]:[...[curr[2]]]} }
}
return acc
},{})
console.log(sp)

How to add a value into an object which is inside map function?

I am using map function to iterate an object. but in one scenario i have to use nested map function. I try to add an value to an empty object inside an map function, but instead of adding values it replacing it. can anyone help me with this?
// object stores final results
let valid_data={}
//object to iterate
let test_cases = {
sample:
[ { test_case_no: 1,
test_case_description: 'user-status active - response 200',
value: 'active',
response_code: 200,
valid: 'yes' },
{ test_case_no: 2,
test_case_description: 'user-status inactive - response 200',
value: 'inactive',
response_code: 200,
valid: 'no' },
{ test_case_no: 3,
test_case_description: ' inappropriate user-status - response 400',
value: 'notAdmin',
response_code: 400,
valid: 'no' } ],
sample1: [ { obj1: [Array], obj2: [Array], test_case_no: 4 } ]
}
//my code to iterate an object
Object.entries(test_cases).map((property) => {
const field_name = property[0]
const field_definition = property[1]
Object.entries(field_definition).map((property) => {
if (property[1].valid != 'yes' && property[1].valid != 'no') {
Object.entries(field_definition).map((property) => {
Object.entries(property[1]).map((propertyy) => {
Object.entries(propertyy[1]).map((property) => {
nested_data = []
nested_value = {}
if (property[1].valid == 'yes') {
nested_value[propertyy[0]] = property[1].value
nested_data.push(Object.assign({}, nested_value))
valid_data[field_name] = (Object.assign({}, nested_value))
}
})
})
})
}
else if (property[1].valid == 'yes') {
valid_data[field_name] = property[1].value;
}
})
})
console.log(valid_data);
Actual result:
“{ sample: 'active',
sample1: { obj2: 2019-07-01T09:50:46.266Z } }”
Expected result:
“{ sample: 'active',
sample1: [{ obj1: 2019-07-01T09:50:46.266Z,obj2: 2019-07-01T09:50:46.266Z }] }”
Wrong var initialisation in your code.
Try this loop :
Object.entries(test_cases).map((property) => {
const field_name = property[0]
const field_definition = property[1]
Object.entries(field_definition).map((property) => {
if (property[1].valid != 'yes' && property[1].valid != 'no') {
nested_value = {}
Object.entries(property[1]).map((propertyy) => {
Object.entries(propertyy[1]).map((property) => {
if (property[1].valid == 'yes') {
nested_value[propertyy[0]] = property[1].value;
valid_data[field_name] = (Object.assign({},
nested_value))
}
})
})
} else if (property[1].valid == 'yes') {
valid_data[field_name] = property[1].value;
}
})
});
Working jsfiddle
Object.entries(test_cases).map((property) => {
const field_name = property[0]
const field_definition = property[1]
Object.entries(field_definition).map((property) => {
if (property[1].valid != 'yes' && property[1].valid != 'no') {
nested_data = []
nested_value = {}
Object.entries(property[1]).map((propertyy) => {
Object.entries(propertyy[1]).map((property) => {
if (property[1].valid == 'yes') {
nested_value[propertyy[0]] = property[1].value;
if(!nested_data.includes(nested_value)){
nested_data.push(nested_value)
valid_data[field_name] = nested_data
}
}
})
})
} else if (property[1].valid == 'yes') {
valid_data[field_name] = property[1].value;
}
})
})

Better way to map a deep object to new object

This code works for converting the JSON to an object where each name object turns into the key for either its value, or if it instead has its own element object breaks that out and does the same to its contents.
Is there a better way to do this that would also allow for more extensiblity of the JSON schema?
Is there a way I can get it all down to a simpler function that I can pass the first element and have it convert it down to whatever depth the schema goes?
const fs = require('fs');
{
let scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version='1.0'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
let depth = 0;
var compiled = {
[scheme.ele.name]: scheme.ele.ele.map(function(i) {
if (typeof i.ele != 'undefined') {
return {
[i.name]: i.ele.map(function(k) {
if (typeof k.ele != 'undefined') {
return {
[k.name]: k.ele.map(function(p) {
if (typeof p.ele != 'undefined') {
return {
[p.name]: p.ele
};
} else {
return {
[p.name]: p.value
};
}
})
};
} else {
return {
[k.name]: k.value
};
}
})
};
} else {
return {
[i.name]: i.value
};
}
})
};
}
console.log(JSON.stringify(compiled, 0, 2));
I should add, this is intended to eventually also apply validation and grab real data when it gets to the string objects.
The output looks like this:
{
"REPORT": [
{
"SEGMENT0": [
{
"NUMBER1": ""
},
{
"NUMBER2": ""
}
]
},
{
"SEGMENT1": [
{
"RECORD1": [
{
"NUMBER1": ""
},
{
"NUMBER2": ""
}
]
}
]
},
{
"SEGMENT2": []
},
{
"SEGMENT3": []
},
{
"SEGMENT4": []
},
{
"SEGMENT5": []
}
]
}
You could destructure the object, get name, ele and value and return a new object with name as key and either an array by mapping the objects of ele or the value.
const
getData = ({ name, ele, value }) => ({
[name]: Array.isArray(ele)
? ele.map(getData)
: value
});
var scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0\'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root,
result = getData(scheme.ele);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina's answer is cleaner but this looks a bit more like your code so I figured I'd post it anyway.
let scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0 \'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":"1"}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":"2"},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
let newScheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0 \'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":"1"},{"name":"NUMBER2","value":"3"}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":"4"},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
//Yay, recursion!
function mapObj(a, o = {}) {
let array = o[a.name] || [];
for (let i = 0; i < a.ele.length; i++) {
let b = a.ele[i];
array[i] = b.ele ?
mapObj(b, array[i]) : {
[b.name]: b.value
};
}
o[a.name] = array;
return o;
}
let obj = mapObj(scheme.ele);
console.log(obj);
console.log(mapObj(newScheme.ele, obj));

Categories

Resources