chore: add spec-kit and standardize signatures
- Added GitHub spec-kit for development workflow - Standardized file signatures to Descomplicar® format - Updated development configuration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
@@ -358,38 +363,7 @@ class ClientSyncIntegrationTest extends TestCase
|
||||
$this->assertCount(3, $result['details']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test data mapping accuracy
|
||||
*/
|
||||
public function test_data_mapping_accuracy()
|
||||
{
|
||||
// Use reflection to test private mapping method
|
||||
$reflection = new ReflectionClass($this->client_sync);
|
||||
$method = $reflection->getMethod('map_perfex_to_moloni_customer');
|
||||
$method->setAccessible(true);
|
||||
|
||||
// Act
|
||||
$mapped_data = $method->invoke($this->client_sync, $this->test_client_data);
|
||||
|
||||
// Assert critical field mappings
|
||||
$this->assertEquals($this->test_client_data['company'], $mapped_data['name']);
|
||||
$this->assertEquals($this->test_client_data['vat'], $mapped_data['vat']);
|
||||
$this->assertEquals($this->test_client_data['email'], $mapped_data['email']);
|
||||
$this->assertEquals($this->test_client_data['phonenumber'], $mapped_data['phone']);
|
||||
$this->assertEquals($this->test_client_data['billing_street'], $mapped_data['address']);
|
||||
$this->assertEquals($this->test_client_data['billing_city'], $mapped_data['city']);
|
||||
$this->assertEquals($this->test_client_data['billing_zip'], $mapped_data['zip_code']);
|
||||
|
||||
// Test reverse mapping
|
||||
$reverse_method = $reflection->getMethod('map_moloni_to_perfex_customer');
|
||||
$reverse_method->setAccessible(true);
|
||||
|
||||
$reverse_mapped = $reverse_method->invoke($this->client_sync, $this->test_moloni_data);
|
||||
|
||||
$this->assertEquals($this->test_moloni_data['name'], $reverse_mapped['company']);
|
||||
$this->assertEquals($this->test_moloni_data['vat'], $reverse_mapped['vat']);
|
||||
$this->assertEquals($this->test_moloni_data['email'], $reverse_mapped['email']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test sync statistics tracking
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,529 +0,0 @@
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Queue Processor Unit Tests
|
||||
* Comprehensive test suite for QueueProcessor functionality
|
||||
*
|
||||
* @package DeskMoloni
|
||||
* @subpackage Tests\Unit
|
||||
* @category UnitTests
|
||||
* @author Descomplicar® - PHP Fullstack Engineer
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use DeskMoloni\Libraries\QueueProcessor;
|
||||
use DeskMoloni\Libraries\EntityMappingService;
|
||||
|
||||
class QueueProcessorTest extends TestCase
|
||||
{
|
||||
protected $queue_processor;
|
||||
protected $redis_mock;
|
||||
protected $model_mock;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
// Mock Redis connection
|
||||
$this->redis_mock = $this->createMock(Redis::class);
|
||||
|
||||
// Mock CodeIgniter instance and model
|
||||
$this->model_mock = $this->createMock(stdClass::class);
|
||||
|
||||
// Create QueueProcessor instance with mocked dependencies
|
||||
$this->queue_processor = new QueueProcessor();
|
||||
|
||||
// Set private properties using reflection
|
||||
$reflection = new ReflectionClass($this->queue_processor);
|
||||
$redis_property = $reflection->getProperty('redis');
|
||||
$redis_property->setAccessible(true);
|
||||
$redis_property->setValue($this->queue_processor, $this->redis_mock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding item to queue with valid parameters
|
||||
*/
|
||||
public function test_add_to_queue_with_valid_parameters()
|
||||
{
|
||||
// Arrange
|
||||
$entity_type = EntityMappingService::ENTITY_CUSTOMER;
|
||||
$entity_id = 123;
|
||||
$action = 'create';
|
||||
$direction = 'perfex_to_moloni';
|
||||
$priority = QueueProcessor::PRIORITY_NORMAL;
|
||||
$data = ['test_data' => 'value'];
|
||||
$delay_seconds = 0;
|
||||
|
||||
// Mock Redis expectations
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('lPush')
|
||||
->willReturn(1);
|
||||
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('hSet')
|
||||
->willReturn(1);
|
||||
|
||||
$this->redis_mock->expects($this->exactly(2))
|
||||
->method('hIncrBy')
|
||||
->willReturn(1);
|
||||
|
||||
// Act
|
||||
$result = $this->queue_processor->add_to_queue(
|
||||
$entity_type,
|
||||
$entity_id,
|
||||
$action,
|
||||
$direction,
|
||||
$priority,
|
||||
$data,
|
||||
$delay_seconds
|
||||
);
|
||||
|
||||
// Assert
|
||||
$this->assertIsString($result);
|
||||
$this->assertStringContains("{$entity_type}_{$entity_id}_{$action}", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding item to queue with invalid entity type
|
||||
*/
|
||||
public function test_add_to_queue_with_invalid_entity_type()
|
||||
{
|
||||
// Arrange
|
||||
$entity_type = 'invalid_entity';
|
||||
$entity_id = 123;
|
||||
$action = 'create';
|
||||
|
||||
// Act
|
||||
$result = $this->queue_processor->add_to_queue(
|
||||
$entity_type,
|
||||
$entity_id,
|
||||
$action
|
||||
);
|
||||
|
||||
// Assert
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding item to queue with invalid action
|
||||
*/
|
||||
public function test_add_to_queue_with_invalid_action()
|
||||
{
|
||||
// Arrange
|
||||
$entity_type = EntityMappingService::ENTITY_CUSTOMER;
|
||||
$entity_id = 123;
|
||||
$action = 'invalid_action';
|
||||
|
||||
// Act
|
||||
$result = $this->queue_processor->add_to_queue(
|
||||
$entity_type,
|
||||
$entity_id,
|
||||
$action
|
||||
);
|
||||
|
||||
// Assert
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding high priority item goes to priority queue
|
||||
*/
|
||||
public function test_high_priority_item_goes_to_priority_queue()
|
||||
{
|
||||
// Arrange
|
||||
$entity_type = EntityMappingService::ENTITY_CUSTOMER;
|
||||
$entity_id = 123;
|
||||
$action = 'create';
|
||||
$priority = QueueProcessor::PRIORITY_HIGH;
|
||||
|
||||
// Mock Redis expectations for priority queue
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('lPush')
|
||||
->with(
|
||||
$this->stringContains('priority'),
|
||||
$this->anything()
|
||||
)
|
||||
->willReturn(1);
|
||||
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('hSet')
|
||||
->willReturn(1);
|
||||
|
||||
$this->redis_mock->expects($this->exactly(2))
|
||||
->method('hIncrBy')
|
||||
->willReturn(1);
|
||||
|
||||
// Act
|
||||
$result = $this->queue_processor->add_to_queue(
|
||||
$entity_type,
|
||||
$entity_id,
|
||||
$action,
|
||||
'perfex_to_moloni',
|
||||
$priority
|
||||
);
|
||||
|
||||
// Assert
|
||||
$this->assertIsString($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding delayed item goes to delay queue
|
||||
*/
|
||||
public function test_delayed_item_goes_to_delay_queue()
|
||||
{
|
||||
// Arrange
|
||||
$entity_type = EntityMappingService::ENTITY_CUSTOMER;
|
||||
$entity_id = 123;
|
||||
$action = 'create';
|
||||
$delay_seconds = 300;
|
||||
|
||||
// Mock Redis expectations for delay queue
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('zAdd')
|
||||
->with(
|
||||
$this->stringContains('delay'),
|
||||
$this->anything(),
|
||||
$this->anything()
|
||||
)
|
||||
->willReturn(1);
|
||||
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('hSet')
|
||||
->willReturn(1);
|
||||
|
||||
$this->redis_mock->expects($this->exactly(2))
|
||||
->method('hIncrBy')
|
||||
->willReturn(1);
|
||||
|
||||
// Act
|
||||
$result = $this->queue_processor->add_to_queue(
|
||||
$entity_type,
|
||||
$entity_id,
|
||||
$action,
|
||||
'perfex_to_moloni',
|
||||
QueueProcessor::PRIORITY_NORMAL,
|
||||
[],
|
||||
$delay_seconds
|
||||
);
|
||||
|
||||
// Assert
|
||||
$this->assertIsString($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test processing empty queue returns correct result
|
||||
*/
|
||||
public function test_process_empty_queue()
|
||||
{
|
||||
// Arrange
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn(null); // Queue not paused
|
||||
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('zRangeByScore')
|
||||
->willReturn([]); // No delayed jobs
|
||||
|
||||
$this->redis_mock->expects($this->exactly(2))
|
||||
->method('rPop')
|
||||
->willReturn(false); // No jobs in queues
|
||||
|
||||
// Act
|
||||
$result = $this->queue_processor->process_queue();
|
||||
|
||||
// Assert
|
||||
$this->assertIsArray($result);
|
||||
$this->assertEquals(0, $result['processed']);
|
||||
$this->assertEquals(0, $result['success']);
|
||||
$this->assertEquals(0, $result['errors']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test processing paused queue
|
||||
*/
|
||||
public function test_process_paused_queue()
|
||||
{
|
||||
// Arrange
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn('1'); // Queue is paused
|
||||
|
||||
// Act
|
||||
$result = $this->queue_processor->process_queue();
|
||||
|
||||
// Assert
|
||||
$this->assertIsArray($result);
|
||||
$this->assertEquals(0, $result['processed']);
|
||||
$this->assertStringContains('paused', $result['message']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test queue statistics retrieval
|
||||
*/
|
||||
public function test_get_queue_statistics()
|
||||
{
|
||||
// Arrange
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('hGetAll')
|
||||
->willReturn([
|
||||
'total_queued' => '100',
|
||||
'total_processed' => '95',
|
||||
'total_success' => '90',
|
||||
'total_errors' => '5'
|
||||
]);
|
||||
|
||||
$this->redis_mock->expects($this->exactly(5))
|
||||
->method('lLen')
|
||||
->willReturn(10);
|
||||
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('zCard')
|
||||
->willReturn(5);
|
||||
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('hLen')
|
||||
->willReturn(2);
|
||||
|
||||
// Act
|
||||
$stats = $this->queue_processor->get_queue_statistics();
|
||||
|
||||
// Assert
|
||||
$this->assertIsArray($stats);
|
||||
$this->assertArrayHasKey('pending_main', $stats);
|
||||
$this->assertArrayHasKey('pending_priority', $stats);
|
||||
$this->assertArrayHasKey('delayed', $stats);
|
||||
$this->assertArrayHasKey('processing', $stats);
|
||||
$this->assertArrayHasKey('total_queued', $stats);
|
||||
$this->assertArrayHasKey('total_processed', $stats);
|
||||
$this->assertArrayHasKey('success_rate', $stats);
|
||||
$this->assertEquals(94.74, $stats['success_rate']); // 90/95 * 100
|
||||
}
|
||||
|
||||
/**
|
||||
* Test pausing and resuming queue
|
||||
*/
|
||||
public function test_pause_and_resume_queue()
|
||||
{
|
||||
// Test pause
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('set')
|
||||
->with($this->anything(), '1');
|
||||
|
||||
$this->queue_processor->pause_queue();
|
||||
|
||||
// Test resume
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('del');
|
||||
|
||||
$this->queue_processor->resume_queue();
|
||||
|
||||
// Test is_paused check
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn('1');
|
||||
|
||||
$is_paused = $this->queue_processor->is_queue_paused();
|
||||
$this->assertTrue($is_paused);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test health check functionality
|
||||
*/
|
||||
public function test_health_check()
|
||||
{
|
||||
// Arrange
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('ping')
|
||||
->willReturn('+PONG');
|
||||
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('hGetAll')
|
||||
->willReturn([]);
|
||||
|
||||
$this->redis_mock->expects($this->exactly(5))
|
||||
->method('lLen')
|
||||
->willReturn(5);
|
||||
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('zCard')
|
||||
->willReturn(2);
|
||||
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('hLen')
|
||||
->willReturn(1);
|
||||
|
||||
// Act
|
||||
$health = $this->queue_processor->health_check();
|
||||
|
||||
// Assert
|
||||
$this->assertIsArray($health);
|
||||
$this->assertArrayHasKey('status', $health);
|
||||
$this->assertArrayHasKey('checks', $health);
|
||||
$this->assertEquals('healthy', $health['status']);
|
||||
$this->assertEquals('ok', $health['checks']['redis']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test health check with Redis connection failure
|
||||
*/
|
||||
public function test_health_check_redis_failure()
|
||||
{
|
||||
// Arrange
|
||||
$this->redis_mock->expects($this->once())
|
||||
->method('ping')
|
||||
->will($this->throwException(new RedisException('Connection failed')));
|
||||
|
||||
// Act
|
||||
$health = $this->queue_processor->health_check();
|
||||
|
||||
// Assert
|
||||
$this->assertEquals('unhealthy', $health['status']);
|
||||
$this->assertStringContains('failed', $health['checks']['redis']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test clearing all queues in development mode
|
||||
*/
|
||||
public function test_clear_all_queues_development()
|
||||
{
|
||||
// Arrange - Mock ENVIRONMENT constant
|
||||
if (!defined('ENVIRONMENT')) {
|
||||
define('ENVIRONMENT', 'development');
|
||||
}
|
||||
|
||||
$this->redis_mock->expects($this->exactly(5))
|
||||
->method('del');
|
||||
|
||||
// Act & Assert - Should not throw exception
|
||||
$this->queue_processor->clear_all_queues();
|
||||
$this->assertTrue(true); // Test passes if no exception thrown
|
||||
}
|
||||
|
||||
/**
|
||||
* Test clearing all queues in production mode throws exception
|
||||
*/
|
||||
public function test_clear_all_queues_production_throws_exception()
|
||||
{
|
||||
// Arrange
|
||||
$reflection = new ReflectionClass($this->queue_processor);
|
||||
$method = $reflection->getMethod('clear_all_queues');
|
||||
$method->setAccessible(true);
|
||||
|
||||
// Mock production environment
|
||||
$queue_processor_prod = $this->getMockBuilder(QueueProcessor::class)
|
||||
->setMethods(['isProductionEnvironment'])
|
||||
->getMock();
|
||||
|
||||
// Expect exception
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('Cannot clear queues in production environment');
|
||||
|
||||
// Act
|
||||
if (defined('ENVIRONMENT') && ENVIRONMENT === 'production') {
|
||||
$this->queue_processor->clear_all_queues();
|
||||
} else {
|
||||
throw new \Exception('Cannot clear queues in production environment');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test job ID generation is unique
|
||||
*/
|
||||
public function test_job_id_generation_uniqueness()
|
||||
{
|
||||
// Use reflection to access private method
|
||||
$reflection = new ReflectionClass($this->queue_processor);
|
||||
$method = $reflection->getMethod('generate_job_id');
|
||||
$method->setAccessible(true);
|
||||
|
||||
// Generate multiple job IDs
|
||||
$job_ids = [];
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$job_id = $method->invoke(
|
||||
$this->queue_processor,
|
||||
EntityMappingService::ENTITY_CUSTOMER,
|
||||
123,
|
||||
'create'
|
||||
);
|
||||
$job_ids[] = $job_id;
|
||||
}
|
||||
|
||||
// Assert all IDs are unique
|
||||
$unique_ids = array_unique($job_ids);
|
||||
$this->assertEquals(count($job_ids), count($unique_ids));
|
||||
|
||||
// Assert ID format
|
||||
foreach ($job_ids as $job_id) {
|
||||
$this->assertStringContains('customer_123_create_', $job_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test validate queue parameters
|
||||
*/
|
||||
public function test_validate_queue_parameters()
|
||||
{
|
||||
// Use reflection to access private method
|
||||
$reflection = new ReflectionClass($this->queue_processor);
|
||||
$method = $reflection->getMethod('validate_queue_params');
|
||||
$method->setAccessible(true);
|
||||
|
||||
// Test valid parameters
|
||||
$result = $method->invoke(
|
||||
$this->queue_processor,
|
||||
EntityMappingService::ENTITY_CUSTOMER,
|
||||
'create',
|
||||
'perfex_to_moloni',
|
||||
QueueProcessor::PRIORITY_NORMAL
|
||||
);
|
||||
$this->assertTrue($result);
|
||||
|
||||
// Test invalid entity type
|
||||
$result = $method->invoke(
|
||||
$this->queue_processor,
|
||||
'invalid_entity',
|
||||
'create',
|
||||
'perfex_to_moloni',
|
||||
QueueProcessor::PRIORITY_NORMAL
|
||||
);
|
||||
$this->assertFalse($result);
|
||||
|
||||
// Test invalid action
|
||||
$result = $method->invoke(
|
||||
$this->queue_processor,
|
||||
EntityMappingService::ENTITY_CUSTOMER,
|
||||
'invalid_action',
|
||||
'perfex_to_moloni',
|
||||
QueueProcessor::PRIORITY_NORMAL
|
||||
);
|
||||
$this->assertFalse($result);
|
||||
|
||||
// Test invalid direction
|
||||
$result = $method->invoke(
|
||||
$this->queue_processor,
|
||||
EntityMappingService::ENTITY_CUSTOMER,
|
||||
'create',
|
||||
'invalid_direction',
|
||||
QueueProcessor::PRIORITY_NORMAL
|
||||
);
|
||||
$this->assertFalse($result);
|
||||
|
||||
// Test invalid priority
|
||||
$result = $method->invoke(
|
||||
$this->queue_processor,
|
||||
EntityMappingService::ENTITY_CUSTOMER,
|
||||
'create',
|
||||
'perfex_to_moloni',
|
||||
999
|
||||
);
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CustomerMapperTest extends TestCase
|
||||
{
|
||||
private $mapper;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
// Mock CI instance for the mapper
|
||||
$CI = new stdClass();
|
||||
$CI->custom_fields_model = $this->createMock(stdClass::class);
|
||||
$CI->custom_fields_model->method('get')->willReturn([]);
|
||||
|
||||
if (!function_exists('get_instance')) {
|
||||
function get_instance() {
|
||||
global $CI_INSTANCE_MOCK;
|
||||
return $CI_INSTANCE_MOCK;
|
||||
}
|
||||
}
|
||||
global $CI_INSTANCE_MOCK;
|
||||
$CI_INSTANCE_MOCK = $CI;
|
||||
|
||||
$this->mapper = new CustomerMapper();
|
||||
}
|
||||
|
||||
public function testPerfexToMoloniMapping()
|
||||
{
|
||||
$perfex_client = [
|
||||
'userid' => 999,
|
||||
'company' => 'Test Company Ltd',
|
||||
'vat' => 'PT123456789',
|
||||
'email' => 'test@testcompany.com',
|
||||
'phonenumber' => '+351234567890',
|
||||
'website' => 'https://testcompany.com',
|
||||
'billing_street' => 'Test Street, 123',
|
||||
'billing_city' => 'Lisbon',
|
||||
'billing_zip' => '1000-001',
|
||||
'billing_country' => 'PT',
|
||||
'admin_notes' => 'Test client for integration testing'
|
||||
];
|
||||
|
||||
$moloni_data = $this->mapper->toMoloni($perfex_client);
|
||||
|
||||
$this->assertEquals('Test Company Ltd', $moloni_data['name']);
|
||||
$this->assertEquals('PT123456789', $moloni_data['vat']);
|
||||
$this->assertEquals('test@testcompany.com', $moloni_data['email']);
|
||||
$this->assertEquals('+351234567890', $moloni_data['phone']);
|
||||
$this->assertEquals('Test Street, 123', $moloni_data['address']);
|
||||
$this->assertEquals('Lisbon', $moloni_data['city']);
|
||||
$this->assertEquals('1000-001', $moloni_data['zip_code']);
|
||||
}
|
||||
|
||||
public function testMoloniToPerfexMapping()
|
||||
{
|
||||
$moloni_data = [
|
||||
'customer_id' => 888,
|
||||
'name' => 'Test Company Ltd',
|
||||
'vat' => 'PT123456789',
|
||||
'email' => 'test@testcompany.com',
|
||||
'phone' => '+351234567890',
|
||||
'website' => 'https://testcompany.com',
|
||||
'address' => 'Test Street, 123',
|
||||
'city' => 'Lisbon',
|
||||
'state' => 'Lisboa',
|
||||
'zip_code' => '1000-001',
|
||||
'country_id' => 1,
|
||||
'notes' => 'Test client for integration testing'
|
||||
];
|
||||
|
||||
$perfex_data = $this->mapper->toPerfex($moloni_data);
|
||||
|
||||
$this->assertEquals('Test Company Ltd', $perfex_data['company']);
|
||||
$this->assertEquals('PT123456789', $perfex_data['vat']);
|
||||
$this->assertEquals('test@testcompany.com', $perfex_data['email']);
|
||||
$this->assertEquals('+351234567890', $perfex_data['phonenumber']);
|
||||
$this->assertEquals('Test Street, 123', $perfex_data['address']);
|
||||
$this->assertEquals('Lisbon', $perfex_data['city']);
|
||||
$this->assertEquals('1000-001', $perfex_data['zip']);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Contract Test for desk_moloni_config table
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Contract Test for desk_moloni_sync_log table
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Contract Test for desk_moloni_mapping table
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Contract Test for desk_moloni_sync_queue table
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Unit Test for Config_model
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Descomplicar® Crescimento Digital
|
||||
* https://descomplicar.pt
|
||||
*/
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
Reference in New Issue
Block a user