Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Samplecode extractor
## Introducción

El script `test_code.sh` es una herramienta automatizada para procesar archivos que contienen bloques de código fuente en diferentes lenguajes de programación (Java, Node.js, Python, ...), extraer esos bloques de código por lenguaje de programación y caso de uso especifico. Una vez extraido y formateado, se testean y/o se ejecutan herramientas linter, para chequear su corrección y funcionamiento en la medida de lo posible.

## Premisas

El script sólo analiza los archivos ubicados en el directorio `../catalog`, cuyo nombre coincide con el formato `samplecode_<nombre_api>.md`.

Para que el script funcione correctamente, los archivos `samplecode_*.md` deben seguir el template actual para los bloques de código, es decir, cumplir las siguientes reglas:
- Los archivos deben estar ubicados en el directorio `../catalog`.
- Los nombres de los archivos deben tener el formato `samplecode_<nombre_api>.md`.
- Cada bloque de código debe estar delimitado por marcas de inicio y fin de bloque:
- La marca de inicio de bloque debe ser ` ``` <lenguaje de programación> <Descripción del caso de uso> `.
- La marca de fin de bloque debe ser ` ``` `.
- Los bloques de código deben estar correctamente indentados siguiendo las normas correspondientes para el lenguaje de programación al que corresponde.

## Funcionamiento

El script realiza las siguientes tareas o pasos:

1. Elimina datos de ejecuciones anteriores y crea una carpeta temporal para almacenar archivos procesados.
2. Recorre archivos `samplecode_*.md` en el directorio `../catalog` y extrae bloques de código, organizándolos en carpetas temporales según el lenguaje de programación.
3. Reorganiza el código en los archivos Node.js y Python extraídos cuyo nombre empieza por Auth_code, para colocar el código de "uso de API" en la posición correcta en el código, ya que inicialmente la primera parte del script, solo agrupa el código de los bloques secuencialmente.
4. Ejecuta pruebas y linters para los archivos procesados.

## Requisitos

Para ejecutar este script, necesitas tener instalados los siguientes programas y herramientas:

- **Bash**: Un shell compatible con Bash.
- **Node.js**: Incluyendo `npx` y `jest` para ejecutar pruebas y linters.
- **Python**: Incluyendo `flake8` para ejecutar linters.

## Instalación

1. **Instalar Node.js y npm**:
- Puedes descargar e instalar Node.js desde nodejs.org.
- npm se instala automáticamente con Node.js.

2. **Instalar las dependencias del proyecto**:

- Navega al directorio del proyecto `test`, donde se encuentra el archivo package.json.
- Ejecuta el siguiente comando para instalar las dependencias:
```bash
npm install
```

3. **Instalar Python**:
- Puedes descargar e instalar Python desde python.org.

4. **Instalar flake8**:
- Ejecuta el siguiente comando para instalar `flake8`:
```bash
pip install flake8
```

## Ejecución

Para ejecutar el script `test_code.sh`, sigue estos pasos:

1. Asegúrate de que los requisitos estén instalados.
2. Navega al directorio `test` donde se encuentra el script `test_code.sh`.
3. Ejecuta el script con el siguiente comando:
```bash
./test_code.sh
```
El script procesará los archivos de código fuente, reorganizará los bloques de código y ejecutará las pruebas y linters correspondientes. Los resultados se mostrarán en la terminal.

Notas:
* Asegúrate de tener permisos de ejecución para el script. Si no los tienes, puedes otorgarlos con el siguiente comando:
```bash
chmod +x test_code.sh
```
* Analiza la salida del script y ten encuenta que algunos de los warnings tiene sentido no corregirlos. Por ejemplo, algunas variables no se utilizan en el código pero se mantienen para que los usuarios tengan claro que existen y se pueden utilizar.
3 changes: 3 additions & 0 deletions test/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: ["@babel/preset-env"],
};
14 changes: 14 additions & 0 deletions test/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import globals from "globals";
import pluginJs from "@eslint/js";

/** @type {import('eslint').Linter.Config[]} */
export default [
{
files: ["**/*.js"],
languageOptions: {
sourceType: "module",
globals: globals.browser
}
},
pluginJs.configs.recommended,
];
137 changes: 137 additions & 0 deletions test/htmlForm.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
const { JSDOM } = require('jsdom');
const fs = require('fs');
const path = require('path');
const glob = require('glob');

describe('API Request Form', () => {
let documents = [];
let api = [];

const apiValues = {
devicelocation: {
scope: 'dpv:FraudPreventionAndDetection#device-location-read',
redirectUri: 'https://my_app_server/device-location-callback',
phoneNumberInput: 'phone_number',
phoneNumberValue: '+34666666666'
},
devicestatus: {
scope: 'dpv:FraudPreventionAndDetection#device-status-roaming-read',
redirectUri: 'https://my_app_server/device-status-callback',
phoneNumberInput: 'phone_number',
phoneNumberValue: '+34777777777'
},
deviceswap: {
scope: 'dpv:FraudPreventionAndDetection#device-swap',
redirectUri: 'https://my_app_server/deviceswap-callback',
phoneNumberInput: 'phone_number',
phoneNumberValue: '+34333333333'
},
knowyourcustomer: {
scope: 'dpv:FraudPreventionAndDetection#kyc-match:match',
redirectUri: 'https://my_app_server/kyc-match-callback',
phoneNumberInput: 'phone_number',
phoneNumberValue: '+34666666666'
},
numberverification: {
scope: 'dpv:FraudPreventionAndDetection#number-verification-verify-read',
redirectUri: '/numberverification-callback',
phoneNumberInput: 'state',
phoneNumberValue: '+34555555555'
},
qod: {
scope: 'dpv:RequestedServiceProvision#qod',
redirectUri: '/qod-auth-callback'
},
simswap: {
scope: 'dpv:FraudPreventionAndDetection#sim-swap',
redirectUri: '/simswap-callback',
phoneNumberInput: 'state',
phoneNumberValue: '+34555555555'
}
};

beforeAll((done) => {
try {
const files = glob.sync('./tmp/html/**/Auth_code_HTML_*.html');
files.forEach(file => {
const filePath = path.resolve(__dirname, file);
const html = fs.readFileSync(filePath, 'utf8');
const dom = new JSDOM(html);
documents.push(dom.window.document);

const dirPath = path.dirname(filePath);
const lastSubdirectory = path.basename(dirPath);
api.push(lastSubdirectory);
});
done();
} catch (err) {
console.error('Error:', err);
}
});

test('form should have correct action URL', () => {
documents.forEach((document, index) => {
try {
const form = document.getElementById('apiRequestForm');
expect(form.action).toBe('https://opengateway.aggregator.com/authorize', `Error in file of API:: ${api[index]}`);
} catch (error) {
console.error(`Error in file of API:: ${api[index]}`);
throw error;
}
});
});

test('form should use GET method', () => {
documents.forEach((document, index) => {
try {
const form = document.getElementById('apiRequestForm');
expect(form.method.toLowerCase()).toBe('get');
} catch (error) {
console.error(`Error in file of API:: ${api[index]}`);
throw error;
}
});
});

test('hidden inputs should have correct values', () => {
documents.forEach((document, index) => {
const clientIdInput = document.querySelector('input[name="client_id"]');
const responseTypeInput = document.querySelector('input[name="response_type"]');
const scopeInput = document.querySelector('input[name="scope"]');
const redirectUriInput = document.querySelector('input[name="redirect_uri"]');
try {
const apiValue = apiValues[api[index]];

expect(clientIdInput.value).toBe('my-app-id');
expect(responseTypeInput.value).toBe('code');
expect(scopeInput.value).toBe(apiValue.scope);
expect(redirectUriInput.value).toBe(apiValue.redirectUri);
} catch (error) {
console.error(`Error in file of API:: ${api[index]}`);
throw error;
}
});
});

test('phone number input should have correct value and be required', () => {
documents.forEach((document, index) => {
const apiValue = apiValues[api[index]];
if (api[index] === 'qod') {
console.log('Skipping test for API::', api[index]);
return;
}
const phoneNumberInput = document.getElementById(apiValue.phoneNumberInput);
try {
if (!phoneNumberInput) {
console.error(`Phone number input not found in API: ${api[index]}`);
return;
}
expect(phoneNumberInput.value).toBe(apiValue.phoneNumberValue);
expect(phoneNumberInput.required).toBe(true);
} catch (error) {
console.error(`Error in file of API:: ${api[index]}`);
throw error;
}
});
});
});
84 changes: 84 additions & 0 deletions test/nodeSandbox.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// CIBA_Sandbox_SDK_for_Node.js.test.js
import { jest } from '@jest/globals';
import sandboxSdk from '@telefonica/opengateway-sandbox-sdk';
import fs from 'fs';
import path from 'path';

const { DeviceLocation, Simswap } = sandboxSdk;

jest.mock('@telefonica/opengateway-sandbox-sdk', () => ({
DeviceLocation: jest.fn(),
Simswap: jest.fn()
}));

const credentials = {
clientId: 'your_client_id',
clientSecret: 'your_client_secret'
};
const CUSTOMER_PHONE_NUMBER = '+34666666666';

describe('DeviceLocation Client', () => {
let verifyMock;

beforeEach(() => {
jest.clearAllMocks();
verifyMock = jest.fn().mockReturnValue(true);
DeviceLocation.mockImplementation(() => ({
verify: verifyMock
}));
});

test('should call DeviceLocation and verify with correct parameters, and log correct output', () => {
console.log = jest.fn();

require('./tmp/js/devicelocation/CIBA_Sandbox_SDK_for_Node.js');

expect(DeviceLocation).toHaveBeenCalledWith(credentials, undefined, CUSTOMER_PHONE_NUMBER);

const latitude = 40.5150;
const longitude = -3.6640;
const radius = 10;
expect(verifyMock).toHaveBeenCalledWith(latitude, longitude, radius);

expect(console.log).toHaveBeenCalledWith('Is the device in location? true');

// Imprime el valor de console.log para verlo en la salida de la consola
console.log.mock.calls.forEach(call => console.log(...call));
});
});

describe('Simswap Client', () => {
let retrieveDateMock;

beforeEach(() => {
jest.clearAllMocks();
retrieveDateMock = jest.fn().mockReturnValue(new Date('2023-12-25T00:00:00Z'));
Simswap.mockImplementation(() => ({
retrieveDate: retrieveDateMock
}));
});

test('should call Simswap and retrieveDate with correct parameters, and log correct output', () => {
console.log = jest.fn();

const filePath = path.resolve(__dirname, './tmp/js/simswap/CIBA_Sandbox_SDK_for_Node.js.js');
let fileContent = fs.readFileSync(filePath, 'utf8');
fileContent = fileContent.replace(/await\s+/g, '');
fs.writeFileSync(filePath, fileContent, 'utf8');

require('./tmp/js/simswap/CIBA_Sandbox_SDK_for_Node.js');

// Verifica que Simswap se llamó con los parámetros correctos
expect(Simswap).toHaveBeenCalledWith(credentials.clientId, credentials.clientSecret, CUSTOMER_PHONE_NUMBER);

// Verifica que retrieveDate se llamó correctamente
expect(retrieveDateMock).toHaveBeenCalled();

// Verifica que la salida por consola es correcta
const expectedDate = new Date('2023-12-25T00:00:00Z').toLocaleString('en-GB', { timeZone: 'UTC' });
expect(console.log).toHaveBeenCalledWith(`SIM was swapped: ${expectedDate}`);

// Imprime el valor de console.log para verlo en la salida de la consola
console.log.mock.calls.forEach(call => console.log(...call));
});
});
26 changes: 26 additions & 0 deletions test/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "Testing sample code",
"version": "1.0.0",
"scripts": {
"test": "jest"
},
"jest": {
"transform": {
"^.+\\.jsx?$": "babel-jest"
}
},
"dependencies": {
"@telefonica/opengateway-sandbox-sdk": "^0.2.0-beta"
},
"devDependencies": {
"@babel/core": "^7.26.0",
"@babel/preset-env": "^7.26.0",
"@eslint/js": "^9.17.0",
"babel-jest": "^29.7.0",
"eslint": "^9.17.0",
"glob": "^10.4.5",
"globals": "^15.14.0",
"jest": "^29.0.0",
"jsdom": "^22.1.0"
}
}
Loading