Skip to content

Commit 5a5c328

Browse files
committed
perf: ⚡ Implementado novos testes unitários e melhorias nos logs
Adicionado testes caixa preta para a funcão validate
1 parent b7843b8 commit 5a5c328

11 files changed

+692
-33
lines changed

.github/workflows/codacy-analysis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
# For more information on Codacy Analysis CLI in general, see
77
# https://github.com/codacy/codacy-analysis-cli.
88

9-
name: Codacy Security Scan
9+
name: Codacy
1010

1111
on: ['push']
1212

1313
jobs:
1414
codacy-security-scan:
15-
name: Codacy Security Scan
15+
name: Codacy Analysis
1616
runs-on: ubuntu-latest
1717
steps:
1818
# Checkout the repository to the GitHub Actions runner
@@ -21,7 +21,7 @@ jobs:
2121

2222
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
2323
- name: Run Codacy Analysis CLI
24-
uses: codacy/codacy-analysis-cli-action@2.0.1
24+
uses: codacy/codacy-analysis-cli-action@3.0.0
2525
with:
2626
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
2727
# You can also omit the token and run the tools that support default configurations

.github/workflows/format-lint.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ name: Lint and format
22
on: ['push']
33
jobs:
44
format:
5+
name: Lint and format
56
runs-on: ubuntu-latest
67
steps:
78
- uses: actions/checkout@v2
@@ -19,7 +20,7 @@ jobs:
1920
npm ci
2021
npm run format
2122
- name: Commit changes
22-
uses: stefanzweifel/git-auto-commit-action@v4.1.2
23+
uses: stefanzweifel/git-auto-commit-action@v4.10.0
2324
with:
2425
commit_message: 'style: :lipstick: Apply formatting changes'
2526
branch: ${{ github.head_ref }}

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ name: Test
22
on: [push, pull_request]
33
jobs:
44
run:
5+
name: Test
56
runs-on: ubuntu-latest
67
steps:
78
- name: Checkout

datalayer-validation-core.js

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
const schemaParser = require('./schema-parser');
22
const Ajv = require('ajv');
3-
const debugging = process.env.PENGUIN_DEBUGGING || false;
3+
const debugging = process.env.PENGUIN_DEBUGGING;
44
let fullValidation = [];
55
let objTreated;
6+
let itemTreated;
7+
let partialError = { occurrences: 0, trace: '' };
68

79
const ajv = new Ajv({
810
schemaId: 'auto',
@@ -27,6 +29,7 @@ function validationResult(status, message, dlObject, objectName, keyName) {
2729
dataLayerObject: dlObject,
2830
objectName: objectName,
2931
keyName: keyName,
32+
partialError: partialError,
3033
});
3134
}
3235

@@ -59,32 +62,31 @@ function checkValidEvent(schemaItem, dataLayer) {
5962
*/
6063
function revalidateSchema(shadowSchema, errorMessage, dataLayer, schemaIndex, schemaArray, dlObj) {
6164
let tempObj = JSON.parse(JSON.stringify(dataLayer));
62-
let innerSchema = JSON.parse(JSON.stringify(shadowSchema)); //ajustei o innerSchema pra receber o objeto como uma nova instância, e não por referência
63-
let verify_required = Object.keys(innerSchema).indexOf('required'); //Verifica se existe required dentro do innerSchema
65+
let innerSchema = JSON.parse(JSON.stringify(shadowSchema));
66+
let verify_required = Object.keys(innerSchema).indexOf('required');
6467

6568
if (verify_required == -1) {
6669
let found = innerSchema.contains.required.indexOf(errorMessage.params.missingProperty);
6770

6871
if (found > -1) {
6972
dlObjProperty = errorMessage.params.missingProperty;
7073

71-
innerSchema.contains.required = innerSchema.contains.required.filter((keyword) => keyword === dlObjProperty); //Então agora ele passa a remover do required todas as propriedades que não são iguais à que está dentro do tempObj
74+
innerSchema.contains.required = innerSchema.contains.required.filter((keyword) => keyword === dlObjProperty);
7275

7376
for (prop in innerSchema.contains.properties) {
7477
if (prop !== dlObjProperty) {
7578
delete innerSchema.contains.properties[prop];
76-
} //e faz o mesmo com as propriedades do schema pra igualar e deixar ele somente com o que precisa ser validado
79+
}
7780
}
7881

7982
let isInnerSchemaEmpty =
80-
Object.entries(innerSchema.contains.properties).length === 0 && dataLayer.constructor === Object; //um safe check pra garantir que o objeto não ficou vazio
83+
Object.entries(innerSchema.contains.properties).length === 0 && dataLayer.constructor === Object;
8184

8285
if (
8386
innerSchema.contains.required.length > 0 &&
8487
!isInnerSchemaEmpty &&
85-
/*ajv.validate(innerSchema, tempObj) &&*/ Object.keys(innerSchema.contains.properties)[0] !== 'event'
88+
Object.keys(innerSchema.contains.properties)[0] !== 'event'
8689
) {
87-
8890
validationResult(
8991
'ERROR',
9092
`Hit sent without the following property: ${errorMessage.params.missingProperty}`,
@@ -95,13 +97,19 @@ function revalidateSchema(shadowSchema, errorMessage, dataLayer, schemaIndex, sc
9597
try {
9698
let schemaItemKeys = Object.keys(schemaArray[schemaIndex].properties);
9799
if (errorMessage.dataPath.indexOf(schemaItemKeys[1]) > -1) {
98-
if (errorMessage.dataPath.indexOf("[0]") > -1) {
100+
if (errorMessage.dataPath.indexOf('[0]') > -1) {
99101
schemaArray.splice(schemaIndex, 1);
100-
objTreated = true
102+
objTreated = true;
101103
}
102-
};
103-
} catch {
104-
console.log("Objeto " + errorMessage.dataPath + " já teve seu erro tratado!!")
104+
}
105+
} catch (e) {
106+
if (schemaArray[schemaIndex] == undefined) {
107+
partialError.occurrences++;
108+
partialError.trace = e;
109+
trace(e);
110+
} else {
111+
trace('Objeto ' + errorMessage.dataPath + ' já teve seu erro tratado!!');
112+
}
105113
}
106114
}
107115
} else {
@@ -118,7 +126,7 @@ function revalidateSchema(shadowSchema, errorMessage, dataLayer, schemaIndex, sc
118126
}
119127
}
120128
} else {
121-
let found = innerSchema.required.indexOf(errorMessage.params.missingProperty); //ainda mantive esse laço que checa se o schema interno tem a propriedade descrita na mensagem de erro filtrada
129+
let found = innerSchema.required.indexOf(errorMessage.params.missingProperty);
122130

123131
if (found > -1) {
124132
//e caso o valor seja encontrado
@@ -127,37 +135,41 @@ function revalidateSchema(shadowSchema, errorMessage, dataLayer, schemaIndex, sc
127135
} else {
128136
dlObjProperty = Object.keys(tempObj)[0];
129137
}
130-
innerSchema.required = innerSchema.required.filter((keyword) => keyword === dlObjProperty); //Então agora ele passa a remover do required todas as propriedades que não são iguais à que está dentro do tempObj
138+
innerSchema.required = innerSchema.required.filter((keyword) => keyword === dlObjProperty);
131139

132140
for (prop in innerSchema.properties) {
133141
if (prop !== dlObjProperty) {
134142
delete innerSchema.properties[prop];
135-
} //e faz o mesmo com as propriedades do schema pra igualar e deixar ele somente com o que precisa ser validado
143+
}
136144
}
137-
let isInnerSchemaEmpty = Object.entries(innerSchema.properties).length === 0 && dataLayer.constructor === Object; //um safe check pra garantir que o objeto não ficou vazio
145+
let isInnerSchemaEmpty = Object.entries(innerSchema.properties).length === 0 && dataLayer.constructor === Object;
138146

139147
if (
140148
innerSchema.required.length > 0 &&
141149
!isInnerSchemaEmpty &&
142-
/*ajv.validate(innerSchema, tempObj) &&*/ Object.keys(innerSchema.properties)[0] !== 'event'
150+
Object.keys(innerSchema.properties)[0] !== 'event'
143151
) {
144-
//essa validação tava cagada pq ele tava validando o event no nível de base e fodendo com a porra toda. Isso ainda pode ser um problema mais pra frente se alguém
145152
validationResult(
146153
'ERROR',
147154
`Hit "${errorMessage.dataPath}" sent without the following property: ${errorMessage.params.missingProperty}`,
148155
JSON.stringify(dlObj, null, 2),
149156
errorMessage.dataPath,
150157
errorMessage.params.missingProperty
151158
);
152-
// TODO: Avaliar melhor essa lógica
153159
try {
154160
let schemaItemKeys = Object.keys(schemaArray[schemaIndex].properties);
155161
if (errorMessage.dataPath.indexOf(schemaItemKeys[1]) > -1) {
156162
schemaArray.splice(schemaIndex, 1);
157-
objTreated = true
163+
objTreated = true;
164+
}
165+
} catch (e) {
166+
if (schemaArray[schemaIndex] == undefined) {
167+
partialError.occurrences++;
168+
partialError.trace = e;
169+
trace(e);
170+
} else {
171+
trace('Objeto ' + errorMessage.dataPath + ' já teve seu erro tratado!!');
158172
}
159-
} catch {
160-
console.log("Objeto " + errorMessage.dataPath + " já teve seu erro tratado!!")
161173
}
162174
}
163175
} else {
@@ -218,7 +230,7 @@ function checkMissingProperty(schemaItem, dataLayer) {
218230
* @param {*} dataLayer
219231
*/
220232
function checkErrorsPerSchema(schemaItem, dataLayer) {
221-
let itemTreated = false;
233+
itemTreated = false;
222234
schemaItem.forEach((item, index) => {
223235
let valid = ajv.validate(item, dataLayer);
224236
let errors = ajv.errors;
@@ -245,7 +257,8 @@ function checkErrorsPerSchema(schemaItem, dataLayer) {
245257
case 'enum':
246258
validationResult(
247259
'WARNING',
248-
`"${eachError.dataPath.replace(/^\./g, '')}" ${eachError.message}: "${eachError.schema.length > 1 ? eachError.schema.join(', ') : eachError.schema[0]
260+
`"${eachError.dataPath.replace(/^\./g, '')}" ${eachError.message}: "${
261+
eachError.schema.length > 1 ? eachError.schema.join(', ') : eachError.schema[0]
249262
}", but Hit send: "${eachError.data}"`,
250263
JSON.stringify(dataLayer, null, 2),
251264
eachError.dataPath,
@@ -297,6 +310,7 @@ let validate = (schema, dataLayer, callback) => {
297310
let isSchemaEmpty = schemaItem.length === 0;
298311
let isObjEmpty = Object.entries(dataLayer).length === 0 && dataLayer.constructor === Object;
299312
objTreated = false;
313+
itemTreated = false;
300314

301315
if (isSchemaEmpty) {
302316
validationResult('ERROR', `No more items to validate`, JSON.stringify(dataLayer));
@@ -318,7 +332,7 @@ let validate = (schema, dataLayer, callback) => {
318332
* @param {Object} log Que será apresentado no stdout
319333
*/
320334
function trace(log) {
321-
if (debugging) {
335+
if (debugging === 'true') {
322336
console.log(log);
323337
}
324338
}

docs/functions.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
## Functions
2+
3+
<dl>
4+
<dt><a href="#validationResult">validationResult(status, message, dlObject, objectName, keyName)</a></dt>
5+
<dd></dd>
6+
<dt><a href="#checkValidEvent">checkValidEvent(schemaItem, dataLayer)</a></dt>
7+
<dd></dd>
8+
<dt><a href="#revalidateSchema">revalidateSchema(shadowSchema, errorMessage, dataLayer, schemaIndex, schemaArray, dlObj)</a></dt>
9+
<dd></dd>
10+
<dt><a href="#checkMissingProperty">checkMissingProperty(schemaItem, dataLayer)</a></dt>
11+
<dd></dd>
12+
<dt><a href="#checkErrorsPerSchema">checkErrorsPerSchema(schemaItem, dataLayer)</a></dt>
13+
<dd></dd>
14+
<dt><a href="#checkMissingEvents">checkMissingEvents(schemaItem, dataLayer)</a></dt>
15+
<dd></dd>
16+
<dt><a href="#validate">validate(schema, dataLayer, callback)</a></dt>
17+
<dd><p>Valida as chaves da camada de dados com base no schema informado</p>
18+
</dd>
19+
<dt><a href="#trace">trace(log)</a></dt>
20+
<dd><p>Enviado o log para o stdout, se somente se, a variável debugging = true</p>
21+
</dd>
22+
<dt><a href="#parseEvent">parseEvent(event)</a></dt>
23+
<dd><p>Converte a chave para objeto de verificação</p>
24+
</dd>
25+
<dt><a href="#parseToDataLayer">parseToDataLayer(items)</a></dt>
26+
<dd><p>Converte a regra de validação para a respesentação da camada de dados.</p>
27+
</dd>
28+
</dl>
29+
30+
<a name="validationResult"></a>
31+
32+
## validationResult(status, message, dlObject, objectName, keyName)
33+
34+
**Kind**: global function
35+
36+
| Param | Type |
37+
| ---------- | --------------- |
38+
| status | <code>\*</code> |
39+
| message | <code>\*</code> |
40+
| dlObject | <code>\*</code> |
41+
| objectName | <code>\*</code> |
42+
| keyName | <code>\*</code> |
43+
44+
<a name="checkValidEvent"></a>
45+
46+
## checkValidEvent(schemaItem, dataLayer)
47+
48+
**Kind**: global function
49+
50+
| Param | Type |
51+
| ---------- | --------------- |
52+
| schemaItem | <code>\*</code> |
53+
| dataLayer | <code>\*</code> |
54+
55+
<a name="revalidateSchema"></a>
56+
57+
## revalidateSchema(shadowSchema, errorMessage, dataLayer, schemaIndex, schemaArray, dlObj)
58+
59+
**Kind**: global function
60+
61+
| Param | Type |
62+
| ------------ | --------------- |
63+
| shadowSchema | <code>\*</code> |
64+
| errorMessage | <code>\*</code> |
65+
| dataLayer | <code>\*</code> |
66+
| schemaIndex | <code>\*</code> |
67+
| schemaArray | <code>\*</code> |
68+
| dlObj | <code>\*</code> |
69+
70+
<a name="checkMissingProperty"></a>
71+
72+
## checkMissingProperty(schemaItem, dataLayer)
73+
74+
**Kind**: global function
75+
76+
| Param | Type |
77+
| ---------- | --------------- |
78+
| schemaItem | <code>\*</code> |
79+
| dataLayer | <code>\*</code> |
80+
81+
<a name="checkErrorsPerSchema"></a>
82+
83+
## checkErrorsPerSchema(schemaItem, dataLayer)
84+
85+
**Kind**: global function
86+
87+
| Param | Type |
88+
| ---------- | --------------- |
89+
| schemaItem | <code>\*</code> |
90+
| dataLayer | <code>\*</code> |
91+
92+
<a name="checkMissingEvents"></a>
93+
94+
## checkMissingEvents(schemaItem, dataLayer)
95+
96+
**Kind**: global function
97+
98+
| Param | Type |
99+
| ---------- | --------------- |
100+
| schemaItem | <code>\*</code> |
101+
| dataLayer | <code>\*</code> |
102+
103+
<a name="validate"></a>
104+
105+
## validate(schema, dataLayer, callback)
106+
107+
Valida as chaves da camada de dados com base no schema informado
108+
109+
**Kind**: global function
110+
111+
| Param | Type | Description |
112+
| --------- | ------------------- | ---------------------------------------------------------------------------------------------------------- |
113+
| schema | <code>object</code> | Json com as regras de validação da camada |
114+
| dataLayer | <code>object</code> | Json com as chaves da camada de dados |
115+
| callback | <code>\*</code> | Função que será executada após o sucesso da validação, como parâmetro um array com o status das validações |
116+
117+
<a name="trace"></a>
118+
119+
## trace(log)
120+
121+
Enviado o log para o stdout, se somente se, a variável debugging = true
122+
123+
**Kind**: global function
124+
125+
| Param | Type | Description |
126+
| ----- | ------------------- | ------------------------------ |
127+
| log | <code>Object</code> | Que será apresentado no stdout |
128+
129+
<a name="parseEvent"></a>
130+
131+
## parseEvent(event)
132+
133+
Converte a chave para objeto de verificação
134+
135+
**Kind**: global function
136+
137+
| Param | Type |
138+
| ----- | ------------------- |
139+
| event | <code>Object</code> |
140+
141+
<a name="parseToDataLayer"></a>
142+
143+
## parseToDataLayer(items)
144+
145+
Converte a regra de validação para a respesentação da camada de dados.
146+
147+
**Kind**: global function
148+
149+
| Param | Type |
150+
| ----- | ------------------- |
151+
| items | <code>Object</code> |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"scripts": {
1111
"format": "prettier --write .",
1212
"lint-md": "remark .",
13-
"lint-prettier": "npx prettier --check .",
13+
"lint-prettier": "npx prettier --check . || exit 0",
1414
"lint": "npm run lint-md && npm run lint-prettier",
1515
"unit-test": "mocha ./test/unit -timeout 8000",
1616
"all-test": "npm run unit-test",

0 commit comments

Comments
 (0)