Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 82
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
ProviderService
0.00% covered (danger)
0.00%
0 / 82
0.00% covered (danger)
0.00%
0 / 8
272
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 testCredentials
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
12
 runTest
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 resolveTestTarget
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 testSms
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 testEmail
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
 testWhatsapp
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 buildCallbackUrl
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace App\Modules\ProviderModule\Services;
4
5use App\Modules\ChannelModule\Models\ChannelProviderModel;
6use App\Services\Communication\ProviderResolver;
7
8class ProviderService
9{
10    protected ChannelProviderModel $providerModel;
11    protected ProviderResolver $resolver;
12
13    public function __construct()
14    {
15        $this->providerModel = new ChannelProviderModel();
16        $this->resolver      = new ProviderResolver();
17    }
18
19    /*
20    |--------------------------------------------------------------------------
21    | TEST CREDENTIALS ENTRYPOINT
22    |--------------------------------------------------------------------------
23    */
24    public function testCredentials(int $channelProviderId, array $credentials, array $environment = []): array
25    {
26        try {
27            $provider = $this->providerModel->find($channelProviderId);
28
29            if (!$provider) {
30                return [
31                    'status'  => 'error',
32                    'message' => 'Provider introuvable'
33                ];
34            }
35
36            $instance = $this->resolver->instantiateWithCredentials(
37                $provider->code,
38                $credentials
39            );
40
41            return $this->runTest(
42                $instance,
43                $provider->channel,
44                $credentials,
45                $environment
46            );
47
48        } catch (\Throwable $e) {
49            log_message('error', '[ProviderService::testCredentials] ' . $e->getMessage());
50
51            return [
52                'status'  => 'error',
53                'message' => $e->getMessage()
54            ];
55        }
56    }
57
58    /*
59    |--------------------------------------------------------------------------
60    | ROUTER TEST
61    |--------------------------------------------------------------------------
62    */
63    private function runTest(object $instance, string $channel, array $credentials, array $environment = []): array
64    {
65        return match ($channel) {
66            'sms'      => $this->testSms($instance, $credentials, $environment),
67            'email'    => $this->testEmail($instance, $credentials, $environment),
68            'whatsapp' => $this->testWhatsapp($instance, $credentials, $environment),
69
70            default => [
71                'status'  => 'error',
72                'message' => "Canal '$channel' non supporté"
73            ]
74        };
75    }
76
77    /*
78    |--------------------------------------------------------------------------
79    | TARGET RESOLUTION (CORE LOGIC)
80    |--------------------------------------------------------------------------
81    */
82    private function resolveTestTarget(array $credentials, array $environment, string $type): ?string
83    {
84        return match ($type) {
85
86            'email' => $environment['test_email']
87                ?? $credentials['test_email']
88                ?? $credentials['from_email']
89                ?? env('TEST_EMAIL_ADDRESS'),
90
91            'sms', 'whatsapp' => $environment['test_number']
92                ?? $credentials['test_number']
93                ?? env('TEST_SMS_NUMBER'),
94
95            default => null
96        };
97    }
98
99    /*
100    |--------------------------------------------------------------------------
101    | SMS TEST
102    |--------------------------------------------------------------------------
103    */
104    private function testSms(object $instance, array $credentials, array $environment = []): array
105    {
106        $testNumber = $this->resolveTestTarget($credentials, $environment, 'sms');
107
108        if (!$testNumber) {
109            return [
110                'status'  => 'warning',
111                'message' => 'Numéro de test manquant (SMS)'
112            ];
113        }
114
115        $sent = $instance->send($testNumber, 'Test API — ' . date('H:i:s'));
116
117        return $sent
118            ? ['status' => 'success', 'message' => "SMS envoyé à $testNumber"]
119            : ['status' => 'error', 'message' => 'Échec envoi SMS'];
120    }
121
122    /*
123    |--------------------------------------------------------------------------
124    | EMAIL TEST
125    |--------------------------------------------------------------------------
126    */
127    private function testEmail(object $instance, array $credentials, array $environment = []): array
128    {
129        $testEmail = $this->resolveTestTarget($credentials, $environment, 'email');
130
131        if (!$testEmail) {
132            return [
133                'status'  => 'warning',
134                'message' => 'Email de test manquant'
135            ];
136        }
137
138        $sent = $instance->send(
139            $testEmail,
140            'Test API — ' . date('H:i:s'),
141            '<p>Email de test envoyé depuis le système.</p>'
142        );
143
144        return $sent
145            ? ['status' => 'success', 'message' => "Email envoyé à $testEmail"]
146            : ['status' => 'error', 'message' => 'Échec envoi email'];
147    }
148
149    /*
150    |--------------------------------------------------------------------------
151    | WHATSAPP TEST
152    |--------------------------------------------------------------------------
153    */
154    private function testWhatsapp(object $instance, array $credentials, array $environment = []): array
155    {
156        $testNumber = $this->resolveTestTarget($credentials, $environment, 'whatsapp');
157
158        if (!$testNumber) {
159            return [
160                'status'  => 'warning',
161                'message' => 'Numéro WhatsApp de test manquant'
162            ];
163        }
164
165        $sent = $instance->send($testNumber, 'Test API — ' . date('H:i:s'));
166
167        return $sent
168            ? ['status' => 'success', 'message' => "WhatsApp envoyé à $testNumber"]
169            : ['status' => 'error', 'message' => 'Échec envoi WhatsApp'];
170    }
171
172    // Dans ProviderService::testCredentials() ou ProviderContextService::saveCredentials()
173// orange_ci_sms → pays=CI, provider=orange
174// mtn_cm_sms    → pays=CM, provider=mtn
175
176    private function buildCallbackUrl(string $providerCode): string
177    {
178        // orange_ci_sms → ['orange', 'ci', 'sms']
179        $parts   = explode('_', $providerCode);
180        $carrier = $parts[0] ?? 'unknown';   // orange
181        $country = strtoupper($parts[1] ?? 'XX'); // CI
182
183        return rtrim(env('APP_CALLBACK_BASE_URL', base_url()), '/')
184            . "/api/sms/callback/{$country}/{$carrier}";
185    }
186
187}