Merge branch 'dev' into real-time-devices

This commit is contained in:
faris Aljohari
2024-08-11 12:56:22 +03:00
113 changed files with 1208 additions and 718 deletions

View File

@ -0,0 +1,86 @@
import { convertKeysToCamelCase } from './camelCaseConverter';
describe('convertKeysToCamelCase', () => {
it('should return the same value if not an object or array', () => {
expect(convertKeysToCamelCase(null)).toBeNull();
expect(convertKeysToCamelCase(undefined)).toBeUndefined();
expect(convertKeysToCamelCase(123)).toBe(123);
expect(convertKeysToCamelCase('string')).toBe('string');
expect(convertKeysToCamelCase(true)).toBe(true);
expect(convertKeysToCamelCase(false)).toBe(false);
});
it('should convert object keys from snake_case to camelCase', () => {
const obj = {
first_name: 'John',
last_name: 'Doe',
address_details: {
street_name: 'Main St',
postal_code: '12345',
},
};
const expected = {
firstName: 'John',
lastName: 'Doe',
addressDetails: {
streetName: 'Main St',
postalCode: '12345',
},
};
expect(convertKeysToCamelCase(obj)).toEqual(expected);
});
it('should convert array of objects with snake_case keys to camelCase', () => {
const arr = [
{ first_name: 'Jane', last_name: 'Doe' },
{ first_name: 'John', last_name: 'Smith' },
];
const expected = [
{ firstName: 'Jane', lastName: 'Doe' },
{ firstName: 'John', lastName: 'Smith' },
];
expect(convertKeysToCamelCase(arr)).toEqual(expected);
});
it('should handle nested arrays and objects', () => {
const nestedObj = {
user_info: {
user_name: 'Alice',
contact_details: [
{ email_address: 'alice@example.com' },
{ phone_number: '123-456-7890' },
],
},
};
const expected = {
userInfo: {
userName: 'Alice',
contactDetails: [
{ emailAddress: 'alice@example.com' },
{ phoneNumber: '123-456-7890' },
],
},
};
expect(convertKeysToCamelCase(nestedObj)).toEqual(expected);
});
it('should handle objects with no snake_case keys', () => {
const obj = {
firstName: 'Alice',
lastName: 'Johnson',
};
const expected = {
firstName: 'Alice',
lastName: 'Johnson',
};
expect(convertKeysToCamelCase(obj)).toEqual(expected);
});
});

View File

@ -7,8 +7,8 @@ import { TuyaWebSocketService } from './services/tuya.web.socket.service';
import { OneSignalService } from './services/onesignal.service';
import { DeviceMessagesService } from './services/device.messages.service';
import { DeviceNotificationRepositoryModule } from '../modules/device-notification/device.notification.module';
import { DeviceNotificationRepository } from '../modules/device-notification/repositories';
import { DeviceRepositoryModule } from '../modules/device/device.repository.module';
import { DeviceNotificationRepository } from '../modules/device/repositories';
import { DeviceStatusFirebaseModule } from '../firebase/devices-status/devices-status.module';
@Global()
@ -26,7 +26,7 @@ import { DeviceStatusFirebaseModule } from '../firebase/devices-status/devices-s
controllers: [],
imports: [
SpaceRepositoryModule,
DeviceNotificationRepositoryModule,
DeviceRepositoryModule,
DeviceStatusFirebaseModule,
],
})

View File

@ -1,5 +1,5 @@
import { Injectable } from '@nestjs/common';
import { DeviceNotificationRepository } from '@app/common/modules/device-notification/repositories';
import { DeviceNotificationRepository } from '@app/common/modules/device/repositories';
import { OneSignalService } from './onesignal.service';
@Injectable()

View File

@ -0,0 +1,99 @@
import { HelperHashService } from './helper.hash.service';
import { enc, SHA256 } from 'crypto-js';
describe('HelperHashService', () => {
let service: HelperHashService;
const secretKey = '12345678901234567890123456789012';
const iv = '1234567890123456';
const password = 'password123';
let salt: string;
let hashedPassword: string;
beforeEach(() => {
service = new HelperHashService();
salt = service.randomSalt(10);
hashedPassword = service.bcrypt(password, salt);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
describe('randomSalt', () => {
it('should generate a salt of the specified length', () => {
expect(service.randomSalt(10)).toHaveLength(29);
});
});
describe('bcrypt', () => {
it('should hash the password with the given salt', () => {
expect(service.bcrypt(password, salt)).toBe(hashedPassword);
});
});
describe('bcryptCompare', () => {
it('should return true for correct password comparison', () => {
expect(service.bcryptCompare(password, hashedPassword)).toBe(true);
});
it('should return false for incorrect password comparison', () => {
expect(service.bcryptCompare('wrongpassword', hashedPassword)).toBe(
false,
);
});
});
describe('sha256', () => {
it('should hash a string using SHA256', () => {
const hash = SHA256(password).toString(enc.Hex);
expect(service.sha256(password)).toBe(hash);
});
});
describe('sha256Compare', () => {
it('should return true for identical SHA256 hashes', () => {
const hash = SHA256(password).toString(enc.Hex);
expect(service.sha256Compare(hash, hash)).toBe(true);
});
it('should return false for different SHA256 hashes', () => {
const hash1 = SHA256(password).toString(enc.Hex);
const hash2 = SHA256('anotherpassword').toString(enc.Hex);
expect(service.sha256Compare(hash1, hash2)).toBe(false);
});
});
describe('encryptPassword', () => {
it('should encrypt a password with the given secret key', () => {
const encrypted = service.encryptPassword(password, secretKey);
const decrypted = service.decryptPassword(encrypted, secretKey);
expect(decrypted).toBe('trx8g6gi');
});
});
describe('decryptPassword', () => {
it('should decrypt an encrypted password with the given secret key', () => {
const encrypted = service.encryptPassword(password, secretKey);
const decrypted = service.decryptPassword(encrypted, secretKey);
expect(decrypted).toBe('trx8g6gi');
});
});
describe('aes256Encrypt', () => {
it('should encrypt data with AES-256 and return the ciphertext', () => {
const data = { key: 'value' };
const encrypted = service.aes256Encrypt(data, secretKey, iv);
expect(encrypted).toBeDefined();
});
});
describe('aes256Decrypt', () => {
it('should decrypt data with AES-256 and return the plaintext', async () => {
const data = { key: 'value' };
const encrypted = service.aes256Encrypt(data, secretKey, iv);
const decrypted = service.aes256Decrypt(encrypted, secretKey, iv);
expect(decrypted).toBeDefined();
expect(() => JSON.parse(decrypted)).not.toThrow();
expect(JSON.parse(decrypted)).toEqual(data);
});
});
});

View File

@ -0,0 +1,54 @@
import { convertKeysToSnakeCase } from './snakeCaseConverter';
describe('convertKeysToSnakeCase', () => {
it('should convert single level object keys to snake case', () => {
const input = { camelCase: 'value', anotherKey: 'anotherValue' };
const expected = { camel_case: 'value', another_key: 'anotherValue' };
expect(convertKeysToSnakeCase(input)).toEqual(expected);
});
it('should convert nested object keys to snake case', () => {
const input = {
camelCaseKey: 'value',
nestedObject: {
nestedCamelCase: 'nestedValue',
arrayOfObjects: [
{ arrayCamelCase: 'arrayValue' },
{ anotherCamelCase: 'anotherValue' },
],
},
};
const expected = {
camel_case_key: 'value',
nested_object: {
nested_camel_case: 'nestedValue',
array_of_objects: [
{ array_camel_case: 'arrayValue' },
{ another_camel_case: 'anotherValue' },
],
},
};
expect(convertKeysToSnakeCase(input)).toEqual(expected);
});
it('should handle arrays of objects', () => {
const input = [{ camelCaseItem: 'value' }, { anotherItem: 'anotherValue' }];
const expected = [
{ camel_case_item: 'value' },
{ another_item: 'anotherValue' },
];
expect(convertKeysToSnakeCase(input)).toEqual(expected);
});
it('should handle empty objects and arrays', () => {
expect(convertKeysToSnakeCase({})).toEqual({});
expect(convertKeysToSnakeCase([])).toEqual([]);
});
it('should handle primitive values without modification', () => {
expect(convertKeysToSnakeCase('string')).toEqual('string');
expect(convertKeysToSnakeCase(123)).toEqual(123);
expect(convertKeysToSnakeCase(null)).toEqual(null);
expect(convertKeysToSnakeCase(undefined)).toEqual(undefined);
});
});