diff --git a/module/ZfModule/src/ZfModule/Service/Module.php b/module/ZfModule/src/ZfModule/Service/Module.php index c79d69ce..b6644d0f 100644 --- a/module/ZfModule/src/ZfModule/Service/Module.php +++ b/module/ZfModule/src/ZfModule/Service/Module.php @@ -4,7 +4,9 @@ use EdpGithub\Client; use EdpGithub\Collection\RepositoryCollection; +use EdpGithub\Http\Client as HttpClient; use stdClass; +use Zend\Http; use ZfcBase\EventManager\EventProvider; use ZfModule\Entity; use ZfModule\Mapper; @@ -32,27 +34,28 @@ public function __construct(Mapper\Module $moduleMapper, Client $githubClient) } /** - * @param stdClass $data - * @return object|Entity\Module + * @param stdClass $repository + * @return Entity\Module */ - public function register($data) + public function register($repository) { - $url = $data->html_url; - $module = $this->moduleMapper->findByUrl($url); - $update = true; - if (!$module) { + $isUpdate = false; + + $module = $this->moduleMapper->findByUrl($repository->html_url); + + if ($module) { + $isUpdate = true; + } else { $module = new Entity\Module(); - $update = false; } - $module->setName($data->name); - $module->setDescription($data->description); - $module->setUrl($data->html_url); - $owner = $data->owner; - $module->setOwner($owner->login); - $module->setPhotoUrl($owner->avatar_url); + $module->setName($repository->name); + $module->setDescription($repository->description); + $module->setUrl($repository->html_url); + $module->setOwner($repository->owner->login); + $module->setPhotoUrl($repository->owner->avatar_url); - if ($update) { + if ($isUpdate) { $this->moduleMapper->update($module); } else { $this->moduleMapper->insert($module); @@ -69,9 +72,24 @@ public function register($data) */ public function isModule(stdClass $repository) { - $query = 'repo:' . $repository->owner->login . '/' . $repository->name . ' filename:Module.php "class Module"'; - $response = $this->githubClient->getHttpClient()->request('search/code?q=' . $query); - $result = json_decode($response->getbody(), true); + $query = sprintf( + 'repo:%s/%s filename:Module.php "class Module"', + $repository->owner->login, + $repository->name + ); + + $path = sprintf( + 'search/code?q=%s', + $query + ); + + /* @var HttpClient $httpClient */ + $httpClient = $this->githubClient->getHttpClient(); + + /* @var Http\Response $response */ + $response = $httpClient->request($path); + + $result = json_decode($response->getBody(), true); if (isset($result['total_count']) && $result['total_count'] > 0) { return true; diff --git a/module/ZfModule/test/ZfModuleTest/Service/ModuleTest.php b/module/ZfModule/test/ZfModuleTest/Service/ModuleTest.php index c0cb9bd5..cc5420a5 100644 --- a/module/ZfModule/test/ZfModuleTest/Service/ModuleTest.php +++ b/module/ZfModule/test/ZfModuleTest/Service/ModuleTest.php @@ -4,8 +4,10 @@ use EdpGithub\Api; use EdpGithub\Client; +use EdpGithub\Http\Client as HttpClient; use PHPUnit_Framework_TestCase; use stdClass; +use Zend\Http; use ZfModule\Entity; use ZfModule\Mapper; use ZfModule\Service; @@ -77,7 +79,7 @@ public function testListAllModulesWithArgumentListsModulesFromDatabaseLimited() $this->assertSame($modules, $service->allModules($limit)); } - public function testListUserModuleListsCurrentUsersModulesFromApiFoundInDatabase() + public function testListUserModulesListsCurrentUsersModulesFromApiFoundInDatabase() { $name = 'foo'; @@ -174,7 +176,7 @@ public function testListUserModulesDoesNotLookupModulesFromApiWhereUserHasNoPush $this->assertSame([], $service->currentUserModules()); } - public function testListUsersModuleDoesNotLookupModulesFromApiThatAreForks() + public function testListUserModulesDoesNotLookupModulesFromApiThatAreForks() { $repository = new stdClass(); $repository->fork = true; @@ -262,4 +264,246 @@ public function testListUserModulesDoesNotListModulesFromApiNotFoundInDatabase() $this->assertSame([], $service->currentUserModules()); } + + public function testIsModuleQueriesGitHubApi() + { + $moduleMapper = $this->getMockBuilder(Mapper\Module::class) + ->disableOriginalConstructor() + ->getMock() + ; + + $repository = $this->repository(); + + $path = sprintf( + 'search/code?q=repo:%s/%s filename:Module.php "class Module"', + $repository->owner->login, + $repository->name + ); + + $response = $this->getMockBuilder(Http\Response::class)->getMock(); + + $httpClient = $this->getMockBuilder(HttpClient::class)->getMock(); + + $httpClient + ->expects($this->once()) + ->method('request') + ->with($this->equalTo($path)) + ->willReturn($response); + + $githubClient = $this->getMockBuilder(Client::class) + ->disableOriginalConstructor() + ->getMock() + ; + + $githubClient + ->expects($this->once()) + ->method('getHttpClient') + ->willReturn($httpClient) + ; + + $service = new Service\Module( + $moduleMapper, + $githubClient + ); + + $service->isModule($repository); + } + + /** + * @dataProvider providerIsModuleReturnsTrueIfResultCountIsGreaterThanZero + * + * @param bool $isModule + * @param array $data + */ + public function testIsModuleReturnValueDependsOnTotalCountInResponseBody($isModule, $data) + { + $moduleMapper = $this->getMockBuilder(Mapper\Module::class) + ->disableOriginalConstructor() + ->getMock() + ; + + $repository = $this->repository(); + + $response = $this->getMockBuilder(Http\Response::class)->getMock(); + + $response + ->expects($this->once()) + ->method('getBody') + ->willReturn(json_encode($data)) + ; + + $httpClient = $this->getMockBuilder(HttpClient::class)->getMock(); + + $httpClient + ->expects($this->once()) + ->method('request') + ->willReturn($response); + + $githubClient = $this->getMockBuilder(Client::class) + ->disableOriginalConstructor() + ->getMock() + ; + + $githubClient + ->expects($this->once()) + ->method('getHttpClient') + ->willReturn($httpClient) + ; + + $service = new Service\Module( + $moduleMapper, + $githubClient + ); + + $this->assertSame($isModule, $service->isModule($repository)); + } + + /** + * @return array + */ + public function providerIsModuleReturnsTrueIfResultCountIsGreaterThanZero() + { + return [ + [ + false, + [], + ], + [ + false, + [ + 'total_count' => 0, + ], + ], + [ + true, + [ + 'total_count' => 1, + ], + ], + ]; + } + + public function testRegisterInsertsModule() + { + $repository = $this->repository(); + + $moduleMapper = $this->getMockBuilder(Mapper\Module::class)->getMock(); + + $moduleMapper + ->expects($this->once()) + ->method('findByUrl') + ->with($this->equalTo($repository->html_url)) + ->willReturn(null) + ; + + $moduleMapper + ->expects($this->once()) + ->method('insert') + ->with($this->isInstanceOf(Entity\Module::class)) + ; + + $githubClient = $this->getMockBuilder(Client::class) + ->disableOriginalConstructor() + ->getMock() + ; + + $service = new Service\Module( + $moduleMapper, + $githubClient + ); + + $module = $service->register($repository); + + $this->assertSame($repository->name, $module->getName()); + $this->assertSame($repository->description, $module->getDescription()); + $this->assertSame($repository->html_url, $module->getUrl()); + $this->assertSame($repository->owner->login, $module->getOwner()); + $this->assertSame($repository->owner->avatar_url, $module->getPhotoUrl()); + } + + public function testRegisterUpdatesExistingModule() + { + $repository = $this->repository(); + + $module = $this->getMockBuilder(Entity\Module::class)->getMock(); + + $module + ->expects($this->once()) + ->method('setName') + ->with($this->equalTo($repository->name)) + ; + + $module + ->expects($this->once()) + ->method('setDescription') + ->with($this->equalTo($repository->description)) + ; + + $module + ->expects($this->once()) + ->method('setUrl') + ->with($this->equalTo($repository->html_url)) + ; + + $module + ->expects($this->once()) + ->method('setOwner') + ->with($this->equalTo($repository->owner->login)) + ; + $module + ->expects($this->once()) + ->method('setPhotoUrl') + ->with($this->equalTo($repository->owner->avatar_url)) + ; + + $moduleMapper = $this->getMockBuilder(Mapper\Module::class)->getMock(); + + $moduleMapper + ->expects($this->once()) + ->method('findByUrl') + ->with($this->equalTo($repository->html_url)) + ->willReturn($module) + ; + + $moduleMapper + ->expects($this->once()) + ->method('update') + ->with($this->equalTo($module)) + ; + + $githubClient = $this->getMockBuilder(Client::class) + ->disableOriginalConstructor() + ->getMock() + ; + + $service = new Service\Module( + $moduleMapper, + $githubClient + ); + + $this->assertSame($module, $service->register($repository)); + } + + /** + * @return stdClass + */ + private function repository() + { + $repository = new stdClass(); + + $repository->name = 'foo'; + $repository->description = 'blah blah'; + $repository->fork = false; + $repository->created_at = '1970-01-01 00:00:00'; + $repository->html_url = 'http://www.example.org'; + + $repository->owner = new stdClass(); + $repository->owner->login = 'suzie'; + $repository->owner->avatar_url = 'http://www.example.org/img/suzie.gif'; + + $repository->permissions = new stdClass(); + $repository->permissions->push = true; + + return $repository; + } }