diff --git a/src/Http/Client.php b/src/Http/Client.php index d6504dd..667ff54 100644 --- a/src/Http/Client.php +++ b/src/Http/Client.php @@ -5,6 +5,7 @@ use Hotmart\Http\Endpoints\Authentication; use Hotmart\Http\Endpoints\Subscriptions; use Hotmart\Http\Endpoints\Transactions; +use Hotmart\Http\Endpoints\Club; class Client { @@ -43,6 +44,11 @@ class Client */ private $transactions; + /** + * @var \Hotmart\Http\Endpoints\Club + */ + private $club; + /** * @param string $clientId * @param string $clientSecret @@ -64,6 +70,7 @@ public function __construct($clientId, $clientSecret, $clientBasic, $extras = [] $this->authentication = new Authentication($this, $this->http); $this->subscriptions = new Subscriptions($this, $this->http); $this->transactions = new Transactions($this, $this->http); + $this->club = new Club($this, $this->http); } /** @@ -82,6 +89,14 @@ public function transactions() return $this->transactions; } + /** + * @return \Hotmart\Http\Endpoints\Club + */ + public function club() + { + return $this->club; + } + /** * @return \Hotmart\Http\Endpoints\Authentication */ diff --git a/src/Http/Endpoints/Club.php b/src/Http/Endpoints/Club.php new file mode 100644 index 0000000..d37b91e --- /dev/null +++ b/src/Http/Endpoints/Club.php @@ -0,0 +1,81 @@ + $subdomain], $params); + + return $this->http->request( + self::GET, + Routes::club()->modules(), + $this->bindQueryParams($params, $this->bindToken()) + ); + } + + /** + * @param string $subdomain + * @param string $moduleId + * @param array $params + * @return array + */ + public function modulePages(string $subdomain, string $moduleId) + { + $params = [ + 'subdomain' => $subdomain, + 'module_id' => $moduleId + ]; + + return $this->http->request( + self::GET, + Routes::club()->modulePages($moduleId), + $this->bindQueryParams($params, $this->bindToken()) + ); + } + + /** + * @param string $subdomain + * @param array $params + * @return array + */ + public function users(string $subdomain) + { + $params = [ + 'subdomain' => $subdomain, + ]; + + return $this->http->request( + self::GET, + Routes::club()->users(), + $this->bindQueryParams($params, $this->bindToken()) + ); + } + + /** + * @param string $subdomain + * @param array $params + * @param string $userId + * @return array + */ + public function userLessons(string $subdomain, string $userId) + { + $params = [ + 'subdomain' => $subdomain, + ]; + + return $this->http->request( + self::GET, + Routes::club()->userLessons($userId), + $this->bindQueryParams($params, $this->bindToken()) + ); + } +} \ No newline at end of file diff --git a/tests/unit/BaseTestCase.php b/tests/unit/BaseTestCase.php index 8192a9e..6babdaf 100644 --- a/tests/unit/BaseTestCase.php +++ b/tests/unit/BaseTestCase.php @@ -17,7 +17,7 @@ abstract class BaseTestCase extends TestCase */ protected static function jsonMock($mockName) { - return file_get_contents(__DIR__ . "/Http/Endpoints/Mocks/Endpoints/$mockName.json"); + return file_get_contents(__DIR__ . "/Mocks/Endpoints/$mockName.json"); } /** diff --git a/tests/unit/Http/ClientTest.php b/tests/unit/Http/ClientTest.php index cfc2ace..a005e4f 100644 --- a/tests/unit/Http/ClientTest.php +++ b/tests/unit/Http/ClientTest.php @@ -7,6 +7,7 @@ use Hotmart\Http\Endpoints\Transactions; use Hotmart\Http\Endpoints\Subscriptions; use Hotmart\Http\Endpoints\Authentication; +use Hotmart\Http\Endpoints\Club; class ClientTest extends BaseTestCase { @@ -40,6 +41,12 @@ public function test_get_authentication_instance() $this->assertInstanceOf(Authentication::class, $this->client->authentication()); } + public function test_get_Club_instance() + { + $this->assertTrue(method_exists($this->client, 'club')); + $this->assertInstanceOf(Club::class, $this->client->club()); + } + public function test_get_credentials() { $this->assertTrue(method_exists($this->client, 'clientId')); diff --git a/tests/unit/Http/Endpoints/ClubTest.php b/tests/unit/Http/Endpoints/ClubTest.php new file mode 100644 index 0000000..5ee584b --- /dev/null +++ b/tests/unit/Http/Endpoints/ClubTest.php @@ -0,0 +1,152 @@ + new MockHandler([ + new Response(200, [], self::jsonMock('Authentication')), + new Response(200, [], self::jsonMock('ClubModules')), + ]), + 'modulePages' => new MockHandler([ + new Response(200, [], self::jsonMock('Authentication')), + new Response(200, [], self::jsonMock('ClubModulePages')), + ]), + 'users' => new MockHandler([ + new Response(200, [], self::jsonMock('Authentication')), + new Response(200, [], self::jsonMock('ClubUsers')), + ]), + 'userLessons' => new MockHandler([ + new Response(200, [], self::jsonMock('Authentication')), + new Response(200, [], self::jsonMock('ClubUserLessons')), + ]), + ]]]; + } + + /** + * @dataProvider mockProvider + */ + public function test_get_modules($mock) + { + $container = []; + + $client = self::buildClient($container, $mock['modules']); + $response = $client->club()->modules('SUBDOMAIN', ['is_extra' => true]); + + $this->assertEquals( + Club::GET, + self::getRequestMethod($container[1]) + ); + + $this->assertEquals( + Routes::club()->modules(), + self::getRequestUri($container[1]) + ); + + $this->assertEquals( + json_decode(self::jsonMock('ClubModules'), true), + $response + ); + + $query = self::getQueryString($container[1]); + $this->assertContains('subdomain=SUBDOMAIN', $query); + $this->assertContains('is_extra=1', $query); + } + + /** + * @dataProvider mockProvider + */ + public function test_get_module_pages($mock) + { + $container = []; + + $client = self::buildClient($container, $mock['modulePages']); + $response = $client->club()->modulePages('SUBDOMAIN', 'MODULE_ID'); + + $this->assertEquals( + Club::GET, + self::getRequestMethod($container[1]) + ); + + $this->assertEquals( + Routes::club()->modulePages('MODULE_ID'), + self::getRequestUri($container[1]) + ); + + $this->assertEquals( + json_decode(self::jsonMock('ClubModulePages'), true), + $response + ); + + $query = self::getQueryString($container[1]); + $this->assertContains('subdomain=SUBDOMAIN', $query); + $this->assertContains('module_id=MODULE_ID', $query); + } + + /** + * @dataProvider mockProvider + */ + public function test_get_users($mock) + { + $container = []; + + $client = self::buildClient($container, $mock['users']); + $response = $client->club()->users('SUBDOMAIN'); + + $this->assertEquals( + Club::GET, + self::getRequestMethod($container[1]) + ); + + $this->assertEquals( + Routes::club()->users(), + self::getRequestUri($container[1]) + ); + + $this->assertEquals( + json_decode(self::jsonMock('ClubUsers'), true), + $response + ); + + $query = self::getQueryString($container[1]); + $this->assertContains('subdomain=SUBDOMAIN', $query); + } + + /** + * @dataProvider mockProvider + */ + public function test_get_user_lessons($mock) + { + $container = []; + + $client = self::buildClient($container, $mock['userLessons']); + $response = $client->club()->userLessons('SUBDOMAIN', 'USER_ID'); + + $this->assertEquals( + Club::GET, + self::getRequestMethod($container[1]) + ); + + $this->assertEquals( + Routes::club()->userLessons('USER_ID'), + self::getRequestUri($container[1]) + ); + + $this->assertEquals( + json_decode(self::jsonMock('ClubUserLessons'), true), + $response + ); + + $query = self::getQueryString($container[1]); + $this->assertContains('subdomain=SUBDOMAIN', $query); + } +} \ No newline at end of file diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/Authentication.json b/tests/unit/Mocks/Endpoints/Authentication.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/Authentication.json rename to tests/unit/Mocks/Endpoints/Authentication.json diff --git a/tests/unit/Mocks/Endpoints/ClubModulePages.json b/tests/unit/Mocks/Endpoints/ClubModulePages.json new file mode 100644 index 0000000..c6fd72d --- /dev/null +++ b/tests/unit/Mocks/Endpoints/ClubModulePages.json @@ -0,0 +1,41 @@ +[ + { + "liberation_days": 100, + "name": "Dripping 100 days", + "total_comments": 0, + "liberation_type": "BY_DAYS", + "page_order": 1, + "days_of_duration": 120, + "has_media": false, + "type": "CONTENT", + "has_duration": true + }, + { + "name": "Dripping BY_DATE", + "liberation_date": 1585278000000, + "liberation_type": "BY_DATE", + "page_order": 2, + "type": "CONTENT", + "total_comments": 5, + "has_media": false, + "has_duration": false, + "rates": [ + { + "rate": 3, + "total": 1 + }, + { + "rate": 5, + "total": 1 + } + ] + }, + { + "page_order": 3, + "type": "ADVERTISEMENT", + "has_media": false, + "name": "Offer product", + "has_duration": false, + "total_comments": 0 + } +] \ No newline at end of file diff --git a/tests/unit/Mocks/Endpoints/ClubModules.json b/tests/unit/Mocks/Endpoints/ClubModules.json new file mode 100644 index 0000000..0da5874 --- /dev/null +++ b/tests/unit/Mocks/Endpoints/ClubModules.json @@ -0,0 +1,62 @@ +[ + { + "module_id": "2z7ramxejw", + "name": "Hotmart Club - Module 1", + "sequence": 1, + "is_extra": false, + "is_extra_paid": false, + "is_public": false, + "classes": [ + "qV7y1Jm7Jn" + ], + "total_pages": 2 + }, + { + "module_id": "j14okvB4pL", + "name": "Hotmart Club - Module 2", + "sequence": 2, + "is_extra": false, + "is_extra_paid": false, + "is_public": true, + "classes": [ + "qV7y1Jm7Jn" + ], + "total_pages": 4 + }, + { + "module_id": "v94JMxYOgZ", + "name": "Hotmart Club - Module 3", + "sequence": 3, + "is_extra": false, + "is_extra_paid": false, + "is_public": false, + "classes": [ + "qV7y1Jm7Jn" + ], + "total_pages": 3 + }, + { + "module_id": "d64l09Q4jW", + "name": "Hotmart Club - Module 4", + "sequence": 4, + "is_extra": false, + "is_extra_paid": false, + "is_public": false, + "classes": [ + "qV7y1Jm7Jn" + ], + "total_pages": 1 + }, + { + "module_id": "DPeA5MoeWE", + "name": "Hotmart Club - Module Dripping", + "sequence": 5, + "is_extra": false, + "is_extra_paid": false, + "is_public": true, + "classes": [ + "qV7y1Jm7Jn" + ], + "total_pages": 3 + } +] \ No newline at end of file diff --git a/tests/unit/Mocks/Endpoints/ClubUserLessons.json b/tests/unit/Mocks/Endpoints/ClubUserLessons.json new file mode 100644 index 0000000..aaf23cb --- /dev/null +++ b/tests/unit/Mocks/Endpoints/ClubUserLessons.json @@ -0,0 +1,80 @@ +{ + "lessons": [ + { + "page_id": "RMe1YEyeYx", + "page_name": "Page 1 Module 1", + "module_name": "Module 1", + "is_module_extra": false, + "is_completed": true, + "completed_date": 1609984800000 + }, + { + "page_id": "gmeLEpY7nJ", + "page_name": "Page 2 Module 1", + "module_name": "Module 1", + "is_module_extra": false, + "is_completed": true, + "completed_date": 1609984800000 + }, + { + "page_id": "0Z721zyeNm", + "page_name": "Page 1 Module 3", + "module_name": "Module 3", + "is_module_extra": false, + "is_completed": true, + "completed_date": 1609984800000 + }, + { + "page_id": "KR4jKkwea2", + "page_name": "Page 3 Module 3", + "module_name": "Module 3", + "is_module_extra": false, + "is_completed": true, + "completed_date": 1609984800000 + }, + { + "page_id": "qV7ypJGeJn", + "page_name": "Conclusion", + "module_name": "Module 4", + "is_module_extra": false, + "is_completed": true, + "completed_date": 1609984800000 + }, + { + "page_id": "Zy4bwy5eRw", + "page_name": "Page 1 Module 2", + "module_name": "Module 2", + "is_module_extra": false, + "is_completed": true, + "completed_date": 1609984800000 + }, + { + "page_id": "PBeZln8Ow5", + "page_name": "Page 2 Module 2", + "module_name": "Module 2", + "is_module_extra": false, + "is_completed": false + }, + { + "page_id": "xkOXXBXOWb", + "page_name": "Page 3 Module 2", + "module_name": "Module 2", + "is_module_extra": false, + "is_completed": false + }, + { + "page_id": "ny4PkVLOxV", + "page_name": "Page 4 Module 2", + "module_name": "Module 2", + "is_module_extra": false, + "is_completed": false + }, + { + "page_id": "EM7qz2NOxw", + "page_name": "Module driping - BY_DATE", + "module_name": "Module Dripping", + "is_module_extra": false, + "is_completed": false + } + ] +} \ No newline at end of file diff --git a/tests/unit/Mocks/Endpoints/ClubUsers.json b/tests/unit/Mocks/Endpoints/ClubUsers.json new file mode 100644 index 0000000..65b20f7 --- /dev/null +++ b/tests/unit/Mocks/Endpoints/ClubUsers.json @@ -0,0 +1,75 @@ +{ + "items": [ + { + "user_id": "n2OM623n46", + "engagement": "NONE", + "name": "Hotmart Example User One", + "email": "user.one@hotmart.com", + "last_access_date": 1546728645, + "role": "FREE_STUDENT", + "first_access_date": 1607054711, + "locale": "pt_BR", + "plus_access": "WITHOUT_PLUS_ACCESS", + "progress": { + "completed_percentage": 45, + "total": 11, + "completed": 5 + }, + "status": "ACTIVE", + "access_count": 1, + "is_deletable": true, + "class_id": "qV7y1Jm7Jn", + "type": "FREE" + }, + { + "user_id": "ZYOmWXlded", + "engagement": "LOW", + "name": "Hotmart Example User Two", + "email": "user.two@hotmart.com", + "last_access_date": 1819975825, + "role": "STUDENT", + "first_access_date": 1532627687, + "locale": "pt_BR", + "plus_access": "WITHOUT_PLUS_ACCESS", + "progress": { + "completed_percentage": 0, + "total": 11, + "completed": 0 + }, + "status": "ACTIVE", + "purchase_date": 1616501263, + "access_count": 2, + "is_deletable": true, + "class_id": "qV7y1Jm7Jn", + "type": "BUYER" + }, + { + "user_id": "wx7WpWrQO2", + "engagement": "MEDIUM", + "name": "Hotmart Example User Three", + "email": "user.three@hotmart.com", + "last_access_date": 1278881901, + "role": "STUDENT", + "first_access_date": 1607054711, + "locale": "pt_BR", + "plus_access": "WITHOUT_PLUS_ACCESS", + "progress": { + "completed_percentage": 0, + "total": 11, + "completed": 0 + }, + "status": "BLOCKED", + "purchase_date": 1616501263, + "access_count": 1, + "is_deletable": true, + "class_id": "qV7y1Jm7Jn", + "type": "IMPORTED" + } + ], + "page_info": { + "total_results": 111, + "next_page_token": "eyJwYWdlIjoyLCJyb3dzIjoxMH0=", + "prev_page_token": "eyJwYWdlIjoyLCJyb3dzIjoxMH0=", + "results_per_page": 3 + } +} \ No newline at end of file diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/SubscriptionCancel.json b/tests/unit/Mocks/Endpoints/SubscriptionCancel.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/SubscriptionCancel.json rename to tests/unit/Mocks/Endpoints/SubscriptionCancel.json diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/SubscriptionCancelList.json b/tests/unit/Mocks/Endpoints/SubscriptionCancelList.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/SubscriptionCancelList.json rename to tests/unit/Mocks/Endpoints/SubscriptionCancelList.json diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/SubscriptionPurchases.json b/tests/unit/Mocks/Endpoints/SubscriptionPurchases.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/SubscriptionPurchases.json rename to tests/unit/Mocks/Endpoints/SubscriptionPurchases.json diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/SubscriptionReactivate.json b/tests/unit/Mocks/Endpoints/SubscriptionReactivate.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/SubscriptionReactivate.json rename to tests/unit/Mocks/Endpoints/SubscriptionReactivate.json diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/SubscriptionReactivateList.json b/tests/unit/Mocks/Endpoints/SubscriptionReactivateList.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/SubscriptionReactivateList.json rename to tests/unit/Mocks/Endpoints/SubscriptionReactivateList.json diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/Subscriptions.json b/tests/unit/Mocks/Endpoints/Subscriptions.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/Subscriptions.json rename to tests/unit/Mocks/Endpoints/Subscriptions.json diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/SubscriptionsSummary.json b/tests/unit/Mocks/Endpoints/SubscriptionsSummary.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/SubscriptionsSummary.json rename to tests/unit/Mocks/Endpoints/SubscriptionsSummary.json diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/TransactionCommissions.json b/tests/unit/Mocks/Endpoints/TransactionCommissions.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/TransactionCommissions.json rename to tests/unit/Mocks/Endpoints/TransactionCommissions.json diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/TransactionHistory.json b/tests/unit/Mocks/Endpoints/TransactionHistory.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/TransactionHistory.json rename to tests/unit/Mocks/Endpoints/TransactionHistory.json diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/TransactionParticipants.json b/tests/unit/Mocks/Endpoints/TransactionParticipants.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/TransactionParticipants.json rename to tests/unit/Mocks/Endpoints/TransactionParticipants.json diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/TransactionPriceDetails.json b/tests/unit/Mocks/Endpoints/TransactionPriceDetails.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/TransactionPriceDetails.json rename to tests/unit/Mocks/Endpoints/TransactionPriceDetails.json diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/TransactionSummary.json b/tests/unit/Mocks/Endpoints/TransactionSummary.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/TransactionSummary.json rename to tests/unit/Mocks/Endpoints/TransactionSummary.json diff --git a/tests/unit/Http/Endpoints/Mocks/Endpoints/Unauthorized.json b/tests/unit/Mocks/Endpoints/Unauthorized.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Endpoints/Unauthorized.json rename to tests/unit/Mocks/Endpoints/Unauthorized.json diff --git a/tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_APPROVED.json b/tests/unit/Mocks/Webhooks/V2/PURCHASE_APPROVED.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_APPROVED.json rename to tests/unit/Mocks/Webhooks/V2/PURCHASE_APPROVED.json diff --git a/tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_BILLET_PRINTED.json b/tests/unit/Mocks/Webhooks/V2/PURCHASE_BILLET_PRINTED.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_BILLET_PRINTED.json rename to tests/unit/Mocks/Webhooks/V2/PURCHASE_BILLET_PRINTED.json diff --git a/tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_CANCELED.json b/tests/unit/Mocks/Webhooks/V2/PURCHASE_CANCELED.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_CANCELED.json rename to tests/unit/Mocks/Webhooks/V2/PURCHASE_CANCELED.json diff --git a/tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_CHARGEBACK.json b/tests/unit/Mocks/Webhooks/V2/PURCHASE_CHARGEBACK.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_CHARGEBACK.json rename to tests/unit/Mocks/Webhooks/V2/PURCHASE_CHARGEBACK.json diff --git a/tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_COMPLETE.json b/tests/unit/Mocks/Webhooks/V2/PURCHASE_COMPLETE.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_COMPLETE.json rename to tests/unit/Mocks/Webhooks/V2/PURCHASE_COMPLETE.json diff --git a/tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_DELAYED.json b/tests/unit/Mocks/Webhooks/V2/PURCHASE_DELAYED.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_DELAYED.json rename to tests/unit/Mocks/Webhooks/V2/PURCHASE_DELAYED.json diff --git a/tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_EXPIRED.json b/tests/unit/Mocks/Webhooks/V2/PURCHASE_EXPIRED.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_EXPIRED.json rename to tests/unit/Mocks/Webhooks/V2/PURCHASE_EXPIRED.json diff --git a/tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_PROTEST.json b/tests/unit/Mocks/Webhooks/V2/PURCHASE_PROTEST.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_PROTEST.json rename to tests/unit/Mocks/Webhooks/V2/PURCHASE_PROTEST.json diff --git a/tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_REFUNDED.json b/tests/unit/Mocks/Webhooks/V2/PURCHASE_REFUNDED.json similarity index 100% rename from tests/unit/Http/Endpoints/Mocks/Webhooks/V2/PURCHASE_REFUNDED.json rename to tests/unit/Mocks/Webhooks/V2/PURCHASE_REFUNDED.json