|
6 | 6 | use Mailtrap\Api\General\Contact; |
7 | 7 | use Mailtrap\DTO\Request\Contact\CreateContact; |
8 | 8 | use Mailtrap\DTO\Request\Contact\CreateContactEvent; |
| 9 | +use Mailtrap\DTO\Request\Contact\ContactExportFilter; |
9 | 10 | use Mailtrap\DTO\Request\Contact\UpdateContact; |
10 | 11 | use Mailtrap\DTO\Request\Contact\ImportContact; |
11 | 12 | use Mailtrap\Exception\HttpClientException; |
@@ -925,6 +926,139 @@ public function testCreateContactEventRateLimitExceeded(): void |
925 | 926 | $this->contact->createContactEvent($contactIdentifier, $eventData); |
926 | 927 | } |
927 | 928 |
|
| 929 | + /** |
| 930 | + * ============================= |
| 931 | + * Contact Exports |
| 932 | + * ============================= |
| 933 | + */ |
| 934 | + public function testCreateContactExport(): void |
| 935 | + { |
| 936 | + $filters = [ |
| 937 | + new ContactExportFilter('list_id', 'equal', [101, 102]), |
| 938 | + new ContactExportFilter('subscription_status', 'equal', 'subscribed'), |
| 939 | + ]; |
| 940 | + $expectedResponse = [ |
| 941 | + 'id' => 1, |
| 942 | + 'status' => 'started', |
| 943 | + 'created_at' => '2025-01-01T00:00:00Z', |
| 944 | + 'updated_at' => '2025-05-01T00:00:00Z', |
| 945 | + 'url' => null, |
| 946 | + ]; |
| 947 | + $this->contact->expects($this->once()) |
| 948 | + ->method('httpPost') |
| 949 | + ->with( |
| 950 | + AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/contacts/exports', |
| 951 | + [], |
| 952 | + ['filters' => array_map(fn(ContactExportFilter $f) => $f->toArray(), $filters)] |
| 953 | + ) |
| 954 | + ->willReturn(new Response(201, ['Content-Type' => 'application/json'], json_encode($expectedResponse))); |
| 955 | + $response = $this->contact->createContactExport($filters); |
| 956 | + $responseData = ResponseHelper::toArray($response); |
| 957 | + $this->assertArrayHasKey('id', $responseData); |
| 958 | + } |
| 959 | + |
| 960 | + public function testCreateContactExportUnauthorized(): void |
| 961 | + { |
| 962 | + $this->contact->expects($this->once()) |
| 963 | + ->method('httpPost') |
| 964 | + ->with( |
| 965 | + AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/contacts/exports', |
| 966 | + [], |
| 967 | + ['filters' => []] |
| 968 | + ) |
| 969 | + ->willReturn(new Response(401, ['Content-Type' => 'application/json'], json_encode(['error' => 'Incorrect API token']))); |
| 970 | + $this->expectException(HttpClientException::class); |
| 971 | + $this->expectExceptionMessage('Errors: Incorrect API token.'); |
| 972 | + $this->contact->createContactExport(); |
| 973 | + } |
| 974 | + |
| 975 | + public function testCreateContactExportForbidden(): void |
| 976 | + { |
| 977 | + $this->contact->expects($this->once()) |
| 978 | + ->method('httpPost') |
| 979 | + ->with( |
| 980 | + AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/contacts/exports', |
| 981 | + [], |
| 982 | + ['filters' => []] |
| 983 | + ) |
| 984 | + ->willReturn(new Response(403, ['Content-Type' => 'application/json'], json_encode(['errors' => 'Access forbidden']))); |
| 985 | + $this->expectException(HttpClientException::class); |
| 986 | + $this->expectExceptionMessage('Errors: Access forbidden.'); |
| 987 | + $this->contact->createContactExport(); |
| 988 | + } |
| 989 | + |
| 990 | + public function testCreateContactExportValidationError(): void |
| 991 | + { |
| 992 | + $filters = [new ContactExportFilter('list_id', 'equal', [1])]; |
| 993 | + $errors = [ |
| 994 | + 'errors' => [ |
| 995 | + 'filters' => 'invalid', |
| 996 | + 'base' => [ |
| 997 | + 'There is a previous export initiated. You will be notified by email once it is completed.' |
| 998 | + ], |
| 999 | + ], |
| 1000 | + ]; |
| 1001 | + |
| 1002 | + $this->contact->expects($this->once()) |
| 1003 | + ->method('httpPost') |
| 1004 | + ->with( |
| 1005 | + AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/contacts/exports', |
| 1006 | + [], |
| 1007 | + ['filters' => array_map(fn(ContactExportFilter $f) => $f->toArray(), $filters)] |
| 1008 | + ) |
| 1009 | + ->willReturn(new Response(422, ['Content-Type' => 'application/json'], json_encode($errors))); |
| 1010 | + |
| 1011 | + $this->expectException(HttpClientException::class); |
| 1012 | + $this->expectExceptionMessage('Errors: filters -> invalid. base -> There is a previous export initiated. You will be notified by email once it is completed.'); |
| 1013 | + |
| 1014 | + $this->contact->createContactExport($filters); |
| 1015 | + } |
| 1016 | + |
| 1017 | + public function testCreateContactExportRateLimitExceeded(): void |
| 1018 | + { |
| 1019 | + $this->contact->expects($this->once()) |
| 1020 | + ->method('httpPost') |
| 1021 | + ->with( |
| 1022 | + AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/contacts/exports', |
| 1023 | + [], |
| 1024 | + ['filters' => []] |
| 1025 | + ) |
| 1026 | + ->willReturn(new Response(429, ['Content-Type' => 'application/json'], json_encode(['errors' => 'Rate limit exceeded']))); |
| 1027 | + $this->expectException(HttpClientException::class); |
| 1028 | + $this->expectExceptionMessage('Errors: Rate limit exceeded.'); |
| 1029 | + $this->contact->createContactExport(); |
| 1030 | + } |
| 1031 | + |
| 1032 | + public function testGetContactExport(): void |
| 1033 | + { |
| 1034 | + $exportId = 1; |
| 1035 | + $expectedResponse = [ |
| 1036 | + 'id' => $exportId, |
| 1037 | + 'status' => 'started', |
| 1038 | + 'created_at' => '2021-01-01T00:00:00Z', |
| 1039 | + 'updated_at' => '2021-01-01T00:00:00Z', |
| 1040 | + 'url' => null, |
| 1041 | + ]; |
| 1042 | + $this->contact->expects($this->once()) |
| 1043 | + ->method('httpGet') |
| 1044 | + ->with(AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/contacts/exports/' . $exportId) |
| 1045 | + ->willReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode($expectedResponse))); |
| 1046 | + $response = $this->contact->getContactExport($exportId); |
| 1047 | + $responseData = ResponseHelper::toArray($response); |
| 1048 | + $this->assertArrayHasKey('id', $responseData); |
| 1049 | + } |
| 1050 | + |
| 1051 | + public function testGetContactExportNotFound(): void |
| 1052 | + { |
| 1053 | + $exportId = 9999; |
| 1054 | + $this->contact->expects($this->once()) |
| 1055 | + ->method('httpGet') |
| 1056 | + ->with(AbstractApi::DEFAULT_HOST . '/api/accounts/' . self::FAKE_ACCOUNT_ID . '/contacts/exports/' . $exportId) |
| 1057 | + ->willReturn(new Response(404, ['Content-Type' => 'application/json'], json_encode(['error' => 'Not Found']))); |
| 1058 | + $this->expectException(HttpClientException::class); |
| 1059 | + $this->expectExceptionMessage('Errors: Not Found.'); |
| 1060 | + $this->contact->getContactExport($exportId); |
| 1061 | + } |
928 | 1062 | private function getExpectedContactFields(): array |
929 | 1063 | { |
930 | 1064 | return [ |
|
0 commit comments