From 85f40d32f9f2080f9a89e6817d4d140227de759b Mon Sep 17 00:00:00 2001 From: Karl Date: Sat, 27 Aug 2016 08:11:58 -0500 Subject: [PATCH 01/12] Updating namespace, documentation --- .gitignore | 1 + CONTRIBUTING.md | 2 +- LICENSE.md | 2 +- README.md | 28 ++++++++++++++-------------- composer.json | 20 ++++++++++---------- src/Govt.php | 8 ++++---- tests/src/GovtTest.php | 10 +++++----- 7 files changed, 36 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 32efe4a..fef1e7b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ build/ phpunit.xml composer.lock vendor +.idea diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 92babe2..329a3f2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ Contributions are **welcome** and will be fully **credited**. -We accept contributions via Pull Requests on [Github](https://github.com/jobbrander/jobs-indeed). +We accept contributions via Pull Requests on [Github](https://github.com/jobapis/jobs-govt). ## Pull Requests diff --git a/LICENSE.md b/LICENSE.md index 859af6c..78aeab7 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ # The Apache 2.0 License -Copyright 2015 Karl Hughes , Steven Maguire +Copyright 2016 Karl Hughes > Licensed under the Apache License, Version 2.0 (the "License"); > you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 9fccbda..a769ae8 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,30 @@ # Government Jobs Client -[![Latest Version](https://img.shields.io/github/release/JobBrander/jobs-govt.svg?style=flat-square)](https://github.com/JobBrander/jobs-govt/releases) +[![Latest Version](https://img.shields.io/github/release/jobapis/jobs-govt.svg?style=flat-square)](https://github.com/jobapis/jobs-govt/releases) [![Software License](https://img.shields.io/badge/license-APACHE%202.0-brightgreen.svg?style=flat-square)](LICENSE.md) -[![Build Status](https://img.shields.io/travis/JobBrander/jobs-govt/master.svg?style=flat-square&1)](https://travis-ci.org/JobBrander/jobs-govt) -[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/JobBrander/jobs-govt.svg?style=flat-square)](https://scrutinizer-ci.com/g/JobBrander/jobs-govt/code-structure) -[![Quality Score](https://img.shields.io/scrutinizer/g/JobBrander/jobs-govt.svg?style=flat-square)](https://scrutinizer-ci.com/g/JobBrander/jobs-govt) -[![Total Downloads](https://img.shields.io/packagist/dt/jobbrander/jobs-govt.svg?style=flat-square)](https://packagist.org/packages/jobbrander/jobs-govt) +[![Build Status](https://img.shields.io/travis/jobapis/jobs-govt/master.svg?style=flat-square&1)](https://travis-ci.org/jobapis/jobs-govt) +[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/jobapis/jobs-govt.svg?style=flat-square)](https://scrutinizer-ci.com/g/jobapis/jobs-govt/code-structure) +[![Quality Score](https://img.shields.io/scrutinizer/g/jobapis/jobs-govt.svg?style=flat-square)](https://scrutinizer-ci.com/g/jobapis/jobs-govt) +[![Total Downloads](https://img.shields.io/packagist/dt/jobapis/jobs-govt.svg?style=flat-square)](https://packagist.org/packages/jobapis/jobs-govt) This package provides [Government Jobs API](http://search.digitalgov.gov/developer/jobs.html) -support for the JobBrander's [Jobs Client](https://github.com/JobBrander/jobs-common). +support for the [Jobs Common Project](https://github.com/jobapis/jobs-common). ## Installation To install, use composer: ``` -composer require jobbrander/jobs-govt +composer require jobapis/jobs-govt ``` ## Usage -Usage is the same as Job Branders's Jobs Client, using `\JobBrander\Jobs\Client\Provider\Govt` +Usage is the same as JobApis' Jobs Client, using `\JobApis\Jobs\Client\Provider\Govt` as the provider. ```php -$client = new JobBrander\Jobs\Client\Provider\Govt(); +$client = new JobApis\Jobs\Client\Provider\Govt(); // Search for 200 job listings for 'project manager' in Chicago, IL $jobs = $client @@ -36,13 +36,13 @@ $jobs = $client ->setFrom() // Specifies the starting record. ->setTags() // A comma-separated string specifying the level of government. Current tags are federal, state, county, and city. ->setLatLon() // Comma-separated pair denoting the position of the searcher looking for a job. For example, 'lat_lon=37.783333,-122.416667' is the value for San Francisco, CA. - // Jobbrander parameters + // Extra parameters ->setKeyword('project manager') // See "setQuery()" method above ->setCount(100) // See "setSize()" method above ->getJobs(); ``` -The `getJobs` method will return a [Collection](https://github.com/JobBrander/jobs-common/blob/master/src/Collection.php) of [Job](https://github.com/JobBrander/jobs-common/blob/master/src/Job.php) objects. +The `getJobs` method will return a [Collection](https://github.com/jobapis/jobs-common/blob/master/src/Collection.php) of [Job](https://github.com/jobapis/jobs-common/blob/master/src/Job.php) objects. ### Location Queries @@ -61,14 +61,14 @@ $ ./vendor/bin/phpunit ## Contributing -Please see [CONTRIBUTING](https://github.com/jobbrander/jobs-govt/blob/master/CONTRIBUTING.md) for details. +Please see [CONTRIBUTING](https://github.com/jobapis/jobs-govt/blob/master/CONTRIBUTING.md) for details. ## Credits - [Steven Maguire](https://github.com/stevenmaguire) - [Karl Hughes](https://github.com/karllhughes) -- [All Contributors](https://github.com/jobbrander/jobs-govt/contributors) +- [All Contributors](https://github.com/jobapis/jobs-govt/contributors) ## License -The Apache 2.0. Please see [License File](https://github.com/jobbrander/jobs-govt/blob/master/LICENSE) for more information. +The Apache 2.0. Please see [License File](https://github.com/jobapis/jobs-govt/blob/master/LICENSE) for more information. diff --git a/composer.json b/composer.json index e585b32..381f339 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "jobbrander/jobs-govt", + "name": "jobapis/jobs-govt", "type": "library", "description": "Making it simple to integrate your application with the Government Jobs API.", "keywords": [ @@ -8,23 +8,23 @@ "object", "government jobs" ], - "homepage": "https://github.com/JobBrander/jobs-govt", + "homepage": "https://github.com/jobapis/jobs-govt", "license": "Apache-2.0", "authors": [ - { - "name": "Steven Maguire", - "email": "stevenmaguire@gmail.com", - "homepage": "https://github.com/stevenmaguire" - }, { "name": "Karl Hughes", "email": "khughes.me@gmail.com", "homepage": "https://github.com/karllhughes" + }, + { + "name": "Steven Maguire", + "email": "stevenmaguire@gmail.com", + "homepage": "https://github.com/stevenmaguire" } ], "require": { "php": ">=5.5.0", - "jobbrander/jobs-common": "~1.0.3" + "jobbrander/jobs-common": "dev-v2-beta" }, "require-dev": { "phpunit/phpunit": ">=4.6", @@ -34,12 +34,12 @@ }, "autoload": { "psr-4": { - "JobBrander\\Jobs\\Client\\Providers\\": "src/" + "JobApis\\Jobs\\Client\\Providers\\": "src/" } }, "autoload-dev": { "psr-4": { - "JobBrander\\Jobs\\Client\\Providers\\Test\\": "tests/src/" + "JobApis\\Jobs\\Client\\Providers\\Test\\": "tests/src/" } } } diff --git a/src/Govt.php b/src/Govt.php index 6a8d3a5..3e06a01 100644 --- a/src/Govt.php +++ b/src/Govt.php @@ -1,7 +1,7 @@ - Date: Sat, 27 Aug 2016 08:24:49 -0500 Subject: [PATCH 02/12] Implementing abstract methods --- CHANGELOG.md | 17 +++++ src/Govt.php | 205 ++++++++++++++++++--------------------------------- 2 files changed, 87 insertions(+), 135 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 848e95b..5769757 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,23 @@ # Changelog All Notable changes to `jobs-govt` will be documented in this file +## 1.0.0 - 2016-08-27 + +### Added +- Changed namespace and organization to `jobapis`. + +### Deprecated +- Nothing + +### Fixed +- Nothing + +### Removed +- Nothing + +### Security +- Nothing + ## 0.6.0 - 2015-09-28 ### Added diff --git a/src/Govt.php b/src/Govt.php index 3e06a01..ccd6088 100644 --- a/src/Govt.php +++ b/src/Govt.php @@ -5,63 +5,28 @@ class Govt extends AbstractProvider { - /** - * Map of setter methods to query parameters - * - * @var array - */ - protected $queryMap = [ - 'setCount' => 'size', - 'setFrom' => 'from', - 'setHl' => 'hl', - 'setKeyword' => 'query', - 'setLatLon' => 'lat_lon', - 'setOrganizationIds' => 'organization_ids', - 'setQuery' => 'query', - 'setSize' => 'size', - 'setTags' => 'tags', - ]; + protected $baseUrl = 'http://api.usa.gov/jobs/search.json'; /** - * Current api query parameters + * Takes a job valid for multiple locations and turns it into multiple jobs * - * @var array - */ - protected $queryParams = [ - 'from' => null, - 'hl' => null, - 'lat_lon' => null, - 'organization_ids' => null, - 'query' => null, - 'size' => null, - 'tags' => null, - ]; - - /** - * Create new Govt jobs client. + * @param array $item * - * @param array $parameters + * @return array */ - public function __construct($parameters = []) - { - parent::__construct($parameters); - array_walk($parameters, [$this, 'updateQuery']); - } - - /** - * Magic method to handle get and set methods for properties - * - * @param string $method - * @param array $parameters - * - * @return mixed - */ - public function __call($method, $parameters) + public function createJobArray($item) { - if (isset($this->queryMap[$method], $parameters[0])) { - $this->updateQuery($parameters[0], $this->queryMap[$method]); + $jobs = []; + if (isset($item['locations']) && count($item['locations']) > 1) { + foreach ($item['locations'] as $location) { + $item['location'] = $location; + $jobs[] = $item; + } + } else { + $item['location'] = $item['locations'][0]; + $jobs[] = $item; } - return parent::__call($method, $parameters); + return $jobs; } /** @@ -73,20 +38,6 @@ public function __call($method, $parameters) */ public function createJobObject($payload) { - $defaults = [ - 'id', - 'position_title', - 'organization_name', - 'location', - 'start_date', - 'end_date', - 'url', - 'minimum', - 'maximum' - ]; - - $payload = static::parseAttributeDefaults($payload, $defaults); - $job = new Job([ 'sourceId' => $payload['id'], 'title' => $payload['position_title'], @@ -115,54 +66,45 @@ public function createJobObject($payload) } /** - * Create and get collection of jobs from given listings + * Get default parameters and values * - * @param array $listings - * - * @return Collection + * @return string */ - protected function getJobsCollectionFromListings(array $listings = array()) - { - $collection = new Collection; - array_map(function ($item) use ($collection) { - $jobs = $this->createJobArray($item); - foreach ($jobs as $item) { - $job = $this->createJobObject($item); - $job->setQuery($this->keyword) - ->setSource($this->getSource()); - $collection->add($job); - } - }, $listings); - return $collection; - } - - public function createJobArray($item) + public function defaultParameters() { - $jobs = []; - if (isset($item['locations']) && count($item['locations']) > 1) { - foreach ($item['locations'] as $location) { - $item['location'] = $location; - $jobs[] = $item; - } - } else { - $item['location'] = $item['locations'][0]; - $jobs[] = $item; - } - return $jobs; + return [ + 'from' => null, + 'hl' => null, + 'lat_lon' => null, + 'organization_ids' => null, + 'query' => null, + 'size' => null, + 'tags' => null, + ]; } /** - * Get data format + * Job object default keys that must be set. * - * @return string + * @return string */ - public function getFormat() + public function defaultResponseFields() { - return 'json'; + return [ + 'id', + 'position_title', + 'organization_name', + 'location', + 'start_date', + 'end_date', + 'url', + 'minimum', + 'maximum' + ]; } /** - * Get page + * Get from page number * * @return string */ @@ -170,15 +112,35 @@ public function getFrom() { if ($this->page) { $from = ($this->page - 1) * $this->count; - if ($from) { return $from; } } - return null; } + /** + * Create and get collection of jobs from given listings + * + * @param array $listings + * + * @return Collection + */ + protected function getJobsCollectionFromListings(array $listings = array()) + { + $collection = new Collection; + array_map(function ($item) use ($collection) { + $jobs = $this->createJobArray($item); + foreach ($jobs as $item) { + $job = $this->createJobObject($item); + $job->setQuery($this->keyword) + ->setSource($this->getSource()); + $collection->add($job); + } + }, $listings); + return $collection; + } + /** * Get keyword(s) * @@ -206,49 +168,22 @@ public function getListingsPath() } /** - * Get query string for client based on properties - * - * @return string - */ - public function getQueryString() - { - return http_build_query($this->queryParams); - } - - /** - * Get url + * Get parameters that MUST be set in order to satisfy the APIs requirements * * @return string */ - public function getUrl() + public function requiredParameters() { - $query_string = $this->getQueryString(); - return 'http://api.usa.gov/jobs/search.json?'.$query_string; + return []; } /** - * Get http verb + * Get parameters that CAN be set * * @return string */ - public function getVerb() + public function validParameters() { - return 'GET'; - } - - /** - * Attempts to update current query parameters. - * - * @param string $value - * @param string $key - * - * @return Careerbuilder - */ - protected function updateQuery($value, $key) - { - if (array_key_exists($key, $this->queryParams)) { - $this->queryParams[$key] = $value; - } - return $this; + return array_keys($this->defaultParameters()); } } From 9197e06868252ee5e22fd2f564e45515fa489ff4 Mon Sep 17 00:00:00 2001 From: Karl Date: Sat, 27 Aug 2016 09:03:11 -0500 Subject: [PATCH 03/12] Upping test coverage --- src/Govt.php | 87 +++++++++++++++++++++++++++++++++--------- tests/src/GovtTest.php | 83 +++++++++++++++++----------------------- 2 files changed, 106 insertions(+), 64 deletions(-) diff --git a/src/Govt.php b/src/Govt.php index ccd6088..a724a84 100644 --- a/src/Govt.php +++ b/src/Govt.php @@ -104,19 +104,13 @@ public function defaultResponseFields() } /** - * Get from page number + * Get count * - * @return string + * @return string */ - public function getFrom() + public function getCount() { - if ($this->page) { - $from = ($this->page - 1) * $this->count; - if ($from) { - return $from; - } - } - return null; + return $this->size; } /** @@ -132,8 +126,9 @@ protected function getJobsCollectionFromListings(array $listings = array()) array_map(function ($item) use ($collection) { $jobs = $this->createJobArray($item); foreach ($jobs as $item) { + $item = static::parseAttributeDefaults($item, $this->defaultResponseFields()); $job = $this->createJobObject($item); - $job->setQuery($this->keyword) + $job->setQuery($this->getKeyword()) ->setSource($this->getSource()); $collection->add($job); } @@ -148,13 +143,17 @@ protected function getJobsCollectionFromListings(array $listings = array()) */ public function getKeyword() { - $keyword = ($this->keyword ? $this->keyword : null); - - if ($keyword) { - return $keyword; - } + return $this->query; + } - return null; + /** + * Get lat_lon + * + * @return string + */ + public function getLatLon() + { + return $this->lat_lon; } /** @@ -167,6 +166,16 @@ public function getListingsPath() return null; } + /** + * Get organization_ids + * + * @return string + */ + public function getOrganizationIds() + { + return $this->organization_ids; + } + /** * Get parameters that MUST be set in order to satisfy the APIs requirements * @@ -177,6 +186,50 @@ public function requiredParameters() return []; } + /** + * Set count (aka size) + * + * @return string + */ + public function setCount($value) + { + $this->size = $value; + return $this; + } + + /** + * Set keyword + * + * @return string + */ + public function setKeyword($value) + { + $this->query = $value; + return $this; + } + + /** + * Set lat_lon + * + * @return string + */ + public function setLatLon($value) + { + $this->lat_lon = $value; + return $this; + } + + /** + * Set organization_ids + * + * @return string + */ + public function setOrganizationIds($value) + { + $this->organization_ids = $value; + return $this; + } + /** * Get parameters that CAN be set * diff --git a/tests/src/GovtTest.php b/tests/src/GovtTest.php index a86508b..65cb0bc 100644 --- a/tests/src/GovtTest.php +++ b/tests/src/GovtTest.php @@ -36,14 +36,6 @@ public function testListingPath() $this->assertEquals(null, $path); } - public function testItWillProvideEmptyParameters() - { - $parameters = $this->client->getParameters(); - - $this->assertEmpty($parameters); - $this->assertTrue(is_array($parameters)); - } - public function testUrlIncludesKeywordWhenKeywordProvided() { $keyword = uniqid().' '.uniqid(); @@ -129,9 +121,11 @@ public function testItCreatesOneJobWhenOneLocationsReturned() $this->assertEquals($loc_count, count($array)); } - public function testItCanCreateJobFromPayload() + public function testItCanCreateJobObjectFromCleanedPayload() { - $payload = $this->createJobArray(2); + $payload = $this->createJobArray(1); + $payload['location'] = $payload['locations'][0]; + $results = $this->client->createJobObject($payload); $this->assertEquals($payload['id'], $results->sourceId); @@ -140,36 +134,45 @@ public function testItCanCreateJobFromPayload() $this->assertEquals($payload['url'], $results->url); } - public function testItCanConnect() + public function testItCanSetAllMethodsInReadme() { - $provider = $this->getProviderAttributes(); - - for ($i = 0; $i < $provider['jobs_count']; $i++) { - $payload[] = $this->createJobArray(); + $attributes = [ + 'keyword' => uniqid(), + 'organizationIds' => uniqid(), + 'hl' => rand(0,1), + 'count' => rand(1,5), + 'from' => rand(1,5), + 'tags' => uniqid(), + 'latLon' => uniqid(), + ]; + $client = new Govt; + // Set all values + foreach ($attributes as $key => $val) { + $client->{'set'.ucfirst($key)}($val); } + // Get all values + foreach ($attributes as $key => $val) { + $this->assertEquals($val, $client->{'get'.ucfirst($key)}(), "$key was not set or retrieved properly."); + } + } - $responseBody = json_encode($payload); - - $job = m::mock($this->jobClass); - $job->shouldReceive('setQuery')->with($provider['keyword']) - ->times($provider['jobs_count'])->andReturnSelf(); - $job->shouldReceive('setSource')->with($provider['source']) - ->times($provider['jobs_count'])->andReturnSelf(); + public function testItCanRetreiveRealResults() + { + if (!getenv('REAL_CALL')) { + $this->markTestSkipped('REAL_CALL not set. Real API call will not be made.'); + } - $response = m::mock('GuzzleHttp\Message\Response'); - $response->shouldReceive('getBody')->once()->andReturn($responseBody); + $client = new Govt; - $http = m::mock('GuzzleHttp\Client'); - $http->shouldReceive(strtolower($this->client->getVerb())) - ->with($this->client->getUrl(), $this->client->getHttpClientOptions()) - ->once() - ->andReturn($response); - $this->client->setClient($http); + $keyword = 'engineering'; + $client->setKeyword($keyword); + $results = $client->getJobs(); - $results = $this->client->getJobs(); + $this->assertInstanceOf('JobApis\Jobs\Client\Collection', $results); - $this->assertInstanceOf($this->collectionClass, $results); - $this->assertCount($provider['jobs_count'], $results); + foreach($results as $job) { + $this->assertEquals($keyword, $job->query); + } } private function createJobArray($loc_count = 1) { @@ -195,18 +198,4 @@ private function createLocationsArray($loc_count = 3) { } return $locations; } - - private function getProviderAttributes($attributes = []) - { - $defaults = [ - 'path' => uniqid(), - 'format' => 'json', - 'keyword' => uniqid(), - 'source' => uniqid(), - 'params' => [uniqid()], - 'jobs_count' => rand(2,10), - - ]; - return array_replace($defaults, $attributes); - } } From d91d278182a6e8c59e4870cb8e907c7a6ea6dd74 Mon Sep 17 00:00:00 2001 From: Karl Date: Sat, 27 Aug 2016 09:04:45 -0500 Subject: [PATCH 04/12] Updating changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5769757..9d50720 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All Notable changes to `jobs-govt` will be documented in this file ### Added - Changed namespace and organization to `jobapis`. +- Support for v2 of jobs-common package. ### Deprecated - Nothing @@ -13,7 +14,7 @@ All Notable changes to `jobs-govt` will be documented in this file - Nothing ### Removed -- Nothing +- Old getters and setters that were not accurately reflected in the API (eg: setLocation) ### Security - Nothing From 89bffeddf9932cfbb193d67349780fe01b1a6e96 Mon Sep 17 00:00:00 2001 From: Karl Date: Fri, 2 Sep 2016 14:11:33 -0500 Subject: [PATCH 05/12] Moving to new file structure --- CHANGELOG.md | 4 +- composer.json | 4 +- src/{Govt.php => Providers/GovtProvider.php} | 0 src/Queries/GovtQuery.php | 227 ++++++++++++++++++ .../{GovtTest.php => GovtProviderTest.php} | 0 tests/src/GovtQueryTest.php | 92 +++++++ 6 files changed, 323 insertions(+), 4 deletions(-) rename src/{Govt.php => Providers/GovtProvider.php} (100%) create mode 100644 src/Queries/GovtQuery.php rename tests/src/{GovtTest.php => GovtProviderTest.php} (100%) create mode 100644 tests/src/GovtQueryTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d50720..c54d811 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog All Notable changes to `jobs-govt` will be documented in this file -## 1.0.0 - 2016-08-27 +## 1.0.0-beta - 2016-00-02 ### Added - Changed namespace and organization to `jobapis`. @@ -14,7 +14,7 @@ All Notable changes to `jobs-govt` will be documented in this file - Nothing ### Removed -- Old getters and setters that were not accurately reflected in the API (eg: setLocation) +- Old getters and setters. ### Security - Nothing diff --git a/composer.json b/composer.json index 381f339..9a652fa 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ ], "require": { "php": ">=5.5.0", - "jobbrander/jobs-common": "dev-v2-beta" + "jobbrander/jobs-common": "^2.0.0-beta" }, "require-dev": { "phpunit/phpunit": ">=4.6", @@ -34,7 +34,7 @@ }, "autoload": { "psr-4": { - "JobApis\\Jobs\\Client\\Providers\\": "src/" + "JobApis\\Jobs\\Client\\": "src/" } }, "autoload-dev": { diff --git a/src/Govt.php b/src/Providers/GovtProvider.php similarity index 100% rename from src/Govt.php rename to src/Providers/GovtProvider.php diff --git a/src/Queries/GovtQuery.php b/src/Queries/GovtQuery.php new file mode 100644 index 0000000..91583f9 --- /dev/null +++ b/src/Queries/GovtQuery.php @@ -0,0 +1,227 @@ +q; + } + + /** + * Default parameters + * + * @return array + */ + protected function defaultAttributes() + { + return [ + 'useragent' => $this->userAgent(), + 'userip' => $this->userIp(), + 'v' => static::API_VERSION, + 'format' => static::API_FORMAT, + ]; + } + + /** + * Required parameters + * + * @return array + */ + protected function requiredAttributes() + { + return [ + 'useragent', + 'userip', + 'publisher', + ]; + } + + /** + * Return the user agent from server + * + * @return string + */ + protected function userAgent() + { + return isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null; + } + + /** + * Return the IP address from server + * + * @return string + */ + protected function userIp() + { + return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null; + } +} diff --git a/tests/src/GovtTest.php b/tests/src/GovtProviderTest.php similarity index 100% rename from tests/src/GovtTest.php rename to tests/src/GovtProviderTest.php diff --git a/tests/src/GovtQueryTest.php b/tests/src/GovtQueryTest.php new file mode 100644 index 0000000..6e598d1 --- /dev/null +++ b/tests/src/GovtQueryTest.php @@ -0,0 +1,92 @@ +query = new IndeedQuery(); + } + + public function testItAddsDefaultAttributes() + { + $this->assertEquals($_SERVER['HTTP_USER_AGENT'], $this->query->get('useragent')); + $this->assertEquals($_SERVER['REMOTE_ADDR'], $this->query->get('userip')); + $this->assertEquals('2', $this->query->get('v')); + } + + public function testItCanGetBaseUrl() + { + $this->assertEquals( + 'http://api.indeed.com/ads/apisearch', + $this->query->getBaseUrl() + ); + } + + public function testItCanGetKeyword() + { + $keyword = uniqid(); + $this->query->set('q', $keyword); + $this->assertEquals($keyword, $this->query->getKeyword()); + } + + public function testItReturnsFalseIfRequiredAttributesMissing() + { + $this->assertFalse($this->query->isValid()); + } + + public function testItReturnsTrueIfRequiredAttributesPresent() + { + $this->query->set('publisher', uniqid()); + + $this->assertTrue($this->query->isValid()); + } + + public function testItCanAddAttributesToUrl() + { + $url = $this->query->getUrl(); + $this->assertContains('v=', $url); + $this->assertContains('userip=', $url); + $this->assertContains('useragent=', $url); + } + + /** + * @expectedException OutOfRangeException + */ + public function testItThrowsExceptionWhenSettingInvalidAttribute() + { + $this->query->set(uniqid(), uniqid()); + } + + /** + * @expectedException OutOfRangeException + */ + public function testItThrowsExceptionWhenGettingInvalidAttribute() + { + $this->query->get(uniqid()); + } + + public function testItSetsAndGetsValidAttributes() + { + $attributes = [ + 'q' => uniqid(), + 'l' => uniqid(), + 'publisher' => uniqid(), + 'highlight' => uniqid(), + ]; + + foreach ($attributes as $key => $value) { + $this->query->set($key, $value); + } + + foreach ($attributes as $key => $value) { + $this->assertEquals($value, $this->query->get($key)); + } + } +} From c8e8169d99211f63f59ae7b7502f301b7ebaa993 Mon Sep 17 00:00:00 2001 From: Karl Date: Fri, 2 Sep 2016 14:22:46 -0500 Subject: [PATCH 06/12] Updating query, test --- src/Queries/GovtQuery.php | 192 ++++-------------------------------- tests/src/GovtQueryTest.php | 56 +++-------- 2 files changed, 36 insertions(+), 212 deletions(-) diff --git a/src/Queries/GovtQuery.php b/src/Queries/GovtQuery.php index 91583f9..64a4ae7 100644 --- a/src/Queries/GovtQuery.php +++ b/src/Queries/GovtQuery.php @@ -1,160 +1,57 @@ q; - } - - /** - * Default parameters - * - * @return array - */ - protected function defaultAttributes() - { - return [ - 'useragent' => $this->userAgent(), - 'userip' => $this->userIp(), - 'v' => static::API_VERSION, - 'format' => static::API_FORMAT, - ]; - } - - /** - * Required parameters - * - * @return array - */ - protected function requiredAttributes() - { - return [ - 'useragent', - 'userip', - 'publisher', - ]; - } - - /** - * Return the user agent from server - * - * @return string - */ - protected function userAgent() - { - return isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null; - } - - /** - * Return the IP address from server - * - * @return string - */ - protected function userIp() - { - return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null; + return $this->query; } } diff --git a/tests/src/GovtQueryTest.php b/tests/src/GovtQueryTest.php index 6e598d1..3df5abf 100644 --- a/tests/src/GovtQueryTest.php +++ b/tests/src/GovtQueryTest.php @@ -1,30 +1,19 @@ query = new IndeedQuery(); - } - - public function testItAddsDefaultAttributes() - { - $this->assertEquals($_SERVER['HTTP_USER_AGENT'], $this->query->get('useragent')); - $this->assertEquals($_SERVER['REMOTE_ADDR'], $this->query->get('userip')); - $this->assertEquals('2', $this->query->get('v')); + $this->query = new GovtQuery(); } public function testItCanGetBaseUrl() { $this->assertEquals( - 'http://api.indeed.com/ads/apisearch', + 'https://api.usa.gov/jobs/search.json', $this->query->getBaseUrl() ); } @@ -32,30 +21,10 @@ public function testItCanGetBaseUrl() public function testItCanGetKeyword() { $keyword = uniqid(); - $this->query->set('q', $keyword); + $this->query->set('query', $keyword); $this->assertEquals($keyword, $this->query->getKeyword()); } - public function testItReturnsFalseIfRequiredAttributesMissing() - { - $this->assertFalse($this->query->isValid()); - } - - public function testItReturnsTrueIfRequiredAttributesPresent() - { - $this->query->set('publisher', uniqid()); - - $this->assertTrue($this->query->isValid()); - } - - public function testItCanAddAttributesToUrl() - { - $url = $this->query->getUrl(); - $this->assertContains('v=', $url); - $this->assertContains('userip=', $url); - $this->assertContains('useragent=', $url); - } - /** * @expectedException OutOfRangeException */ @@ -75,10 +44,10 @@ public function testItThrowsExceptionWhenGettingInvalidAttribute() public function testItSetsAndGetsValidAttributes() { $attributes = [ - 'q' => uniqid(), - 'l' => uniqid(), - 'publisher' => uniqid(), - 'highlight' => uniqid(), + 'query' => uniqid(), + 'hl' => uniqid(), + 'size' => uniqid(), + 'from' => uniqid(), ]; foreach ($attributes as $key => $value) { @@ -88,5 +57,12 @@ public function testItSetsAndGetsValidAttributes() foreach ($attributes as $key => $value) { $this->assertEquals($value, $this->query->get($key)); } + + $url = $this->query->getUrl(); + + $this->assertContains('query=', $url); + $this->assertContains('size=', $url); + $this->assertContains('from=', $url); + $this->assertContains('hl=', $url); } } From 98def040f2b8546d954a2cdbd944f861159c87c1 Mon Sep 17 00:00:00 2001 From: Karl Date: Fri, 2 Sep 2016 14:37:56 -0500 Subject: [PATCH 07/12] Finishing provider and tests --- src/Providers/GovtProvider.php | 144 ++------------------------ tests/src/GovtProviderTest.php | 184 ++++++++++++++------------------- 2 files changed, 87 insertions(+), 241 deletions(-) diff --git a/src/Providers/GovtProvider.php b/src/Providers/GovtProvider.php index a724a84..dd9246c 100644 --- a/src/Providers/GovtProvider.php +++ b/src/Providers/GovtProvider.php @@ -3,10 +3,8 @@ use JobApis\Jobs\Client\Job; use JobApis\Jobs\Client\Collection; -class Govt extends AbstractProvider +class GovtProvider extends AbstractProvider { - protected $baseUrl = 'http://api.usa.gov/jobs/search.json'; - /** * Takes a job valid for multiple locations and turns it into multiple jobs * @@ -66,29 +64,11 @@ public function createJobObject($payload) } /** - * Get default parameters and values - * - * @return string - */ - public function defaultParameters() - { - return [ - 'from' => null, - 'hl' => null, - 'lat_lon' => null, - 'organization_ids' => null, - 'query' => null, - 'size' => null, - 'tags' => null, - ]; - } - - /** - * Job object default keys that must be set. + * Job response object default keys that should be set * - * @return string + * @return array */ - public function defaultResponseFields() + public function getDefaultResponseFields() { return [ 'id', @@ -104,13 +84,13 @@ public function defaultResponseFields() } /** - * Get count + * Get listings path * - * @return string + * @return string */ - public function getCount() + public function getListingsPath() { - return $this->size; + return ''; } /** @@ -126,117 +106,13 @@ protected function getJobsCollectionFromListings(array $listings = array()) array_map(function ($item) use ($collection) { $jobs = $this->createJobArray($item); foreach ($jobs as $item) { - $item = static::parseAttributeDefaults($item, $this->defaultResponseFields()); + $item = static::parseAttributeDefaults($item, $this->getDefaultResponseFields()); $job = $this->createJobObject($item); - $job->setQuery($this->getKeyword()) + $job->setQuery($this->query->getKeyword()) ->setSource($this->getSource()); $collection->add($job); } }, $listings); return $collection; } - - /** - * Get keyword(s) - * - * @return string - */ - public function getKeyword() - { - return $this->query; - } - - /** - * Get lat_lon - * - * @return string - */ - public function getLatLon() - { - return $this->lat_lon; - } - - /** - * Get listings path - * - * @return string - */ - public function getListingsPath() - { - return null; - } - - /** - * Get organization_ids - * - * @return string - */ - public function getOrganizationIds() - { - return $this->organization_ids; - } - - /** - * Get parameters that MUST be set in order to satisfy the APIs requirements - * - * @return string - */ - public function requiredParameters() - { - return []; - } - - /** - * Set count (aka size) - * - * @return string - */ - public function setCount($value) - { - $this->size = $value; - return $this; - } - - /** - * Set keyword - * - * @return string - */ - public function setKeyword($value) - { - $this->query = $value; - return $this; - } - - /** - * Set lat_lon - * - * @return string - */ - public function setLatLon($value) - { - $this->lat_lon = $value; - return $this; - } - - /** - * Set organization_ids - * - * @return string - */ - public function setOrganizationIds($value) - { - $this->organization_ids = $value; - return $this; - } - - /** - * Get parameters that CAN be set - * - * @return string - */ - public function validParameters() - { - return array_keys($this->defaultParameters()); - } } diff --git a/tests/src/GovtProviderTest.php b/tests/src/GovtProviderTest.php index 65cb0bc..4e90cc7 100644 --- a/tests/src/GovtProviderTest.php +++ b/tests/src/GovtProviderTest.php @@ -1,105 +1,46 @@ client = new Govt(); - } - - public function testItWillUseJsonFormat() - { - $format = $this->client->getFormat(); - - $this->assertEquals('json', $format); - } - - public function testItWillUseGetHttpVerb() - { - $verb = $this->client->getVerb(); - - $this->assertEquals('GET', $verb); - } - - public function testListingPath() - { - $path = $this->client->getListingsPath(); - - $this->assertEmpty($path); - $this->assertEquals(null, $path); - } - - public function testUrlIncludesKeywordWhenKeywordProvided() - { - $keyword = uniqid().' '.uniqid(); - $param = 'query='.urlencode($keyword); - - $url = $this->client->setKeyword($keyword)->getUrl(); - - $this->assertContains($param, $url); - } - - public function testUrlNotIncludesKeywordWhenNotProvided() - { - $param = 'query='; - - $url = $this->client->getUrl(); - - $this->assertNotContains($param, $url); - } - - public function testUrlIncludesSizeWhenProvided() - { - $size = uniqid(); - $param = 'size='.$size; - - $url = $this->client->setCount($size)->getUrl(); - - $this->assertContains($param, $url); - } - - public function testUrlNotIncludesSizeWhenNotProvided() - { - $param = 'size='; - - $url = $this->client->setCount(null)->getUrl(); + $this->query = m::mock('JobApis\Jobs\Client\Queries\GovtQuery'); - $this->assertNotContains($param, $url); + $this->client = new GovtProvider($this->query); } - public function testUrlIncludesFromWhenProvided() + public function testItCanGetDefaultResponseFields() { - $from = rand(10, 100); - $param = 'from='.$from; - - $url = $this->client->setFrom($from)->getUrl(); - - $this->assertContains($param, $url); + $fields = [ + 'id', + 'position_title', + 'organization_name', + 'location', + 'start_date', + 'end_date', + 'url', + 'minimum', + 'maximum' + ]; + $this->assertEquals($fields, $this->client->getDefaultResponseFields()); } - public function testUrlNotIncludesFromWhenNotProvided() + public function testItCanGetListingsPath() { - $param = 'from='; - - $url = $this->client->setFrom(null)->getUrl(); - - $this->assertNotContains($param, $url); + $this->assertEmpty($this->client->getListingsPath()); } public function testItCreatesMultipleJobsWhenMultipleLocationsReturned() { $loc_count = rand(2,5); $jobArray = $this->createJobArray($loc_count); - $array = $this->client->createJobArray($jobArray); - foreach ($array as $key => $job) { $this->assertEquals($jobArray['position_title'], $array[0]['position_title']); $this->assertEquals($jobArray['locations'][$key], $array[$key]['location']); @@ -111,9 +52,7 @@ public function testItCreatesOneJobWhenOneLocationsReturned() { $loc_count = 1; $jobArray = $this->createJobArray($loc_count); - $array = $this->client->createJobArray($jobArray); - foreach ($array as $key => $job) { $this->assertEquals($jobArray['position_title'], $array[0]['position_title']); $this->assertEquals($jobArray['locations'][$key], $array[$key]['location']); @@ -121,51 +60,82 @@ public function testItCreatesOneJobWhenOneLocationsReturned() $this->assertEquals($loc_count, count($array)); } - public function testItCanCreateJobObjectFromCleanedPayload() + public function testItCanCreateJobObjectFromPayload() { - $payload = $this->createJobArray(1); + $payload = $this->createJobArray(); $payload['location'] = $payload['locations'][0]; $results = $this->client->createJobObject($payload); + $this->assertInstanceOf(Job::class, $results); $this->assertEquals($payload['id'], $results->sourceId); $this->assertEquals($payload['position_title'], $results->title); $this->assertEquals($payload['organization_name'], $results->company); $this->assertEquals($payload['url'], $results->url); } - public function testItCanSetAllMethodsInReadme() + /** + * Integration test for the client's getJobs() method. + */ + public function testItCanGetJobs() { - $attributes = [ - 'keyword' => uniqid(), - 'organizationIds' => uniqid(), - 'hl' => rand(0,1), - 'count' => rand(1,5), - 'from' => rand(1,5), - 'tags' => uniqid(), - 'latLon' => uniqid(), + $url = 'https://api.usa.gov/jobs/search.json'; + + $options = [ + 'query' => uniqid(), + 'hl' => uniqid(), + 'size' => uniqid(), ]; - $client = new Govt; - // Set all values - foreach ($attributes as $key => $val) { - $client->{'set'.ucfirst($key)}($val); - } - // Get all values - foreach ($attributes as $key => $val) { - $this->assertEquals($val, $client->{'get'.ucfirst($key)}(), "$key was not set or retrieved properly."); - } + + $guzzle = m::mock('GuzzleHttp\Client'); + + $query = new GovtQuery($options); + + $client = new GovtProvider($query); + + $client->setClient($guzzle); + + $response = m::mock('GuzzleHttp\Message\Response'); + + $jobObjects = [ + (object) $this->createJobArray(), + (object) $this->createJobArray(), + (object) $this->createJobArray(), + ]; + + $jobs = json_encode($jobObjects); + + $guzzle->shouldReceive('get') + ->with($query->getUrl(), []) + ->once() + ->andReturn($response); + $response->shouldReceive('getBody') + ->once() + ->andReturn($jobs); + + $results = $client->getJobs(); + + $this->assertInstanceOf(Collection::class, $results); + $this->assertCount(count($jobObjects), $results); } - public function testItCanRetreiveRealResults() + /** + * Integration test with actual API call to the provider. + */ + public function testItCanGetJobsFromApi() { if (!getenv('REAL_CALL')) { $this->markTestSkipped('REAL_CALL not set. Real API call will not be made.'); } - $client = new Govt; - $keyword = 'engineering'; - $client->setKeyword($keyword); + + $query = new GovtQuery([ + 'query' => $keyword, + ]); + + $client = new GovtProvider($query); + $results = $client->getJobs(); $this->assertInstanceOf('JobApis\Jobs\Client\Collection', $results); From ce8eee818656028c1a10b1c00ff8e80b89102925 Mon Sep 17 00:00:00 2001 From: Karl Date: Fri, 2 Sep 2016 14:42:57 -0500 Subject: [PATCH 08/12] Updating readme --- README.md | 55 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index a769ae8..7790a7c 100644 --- a/README.md +++ b/README.md @@ -20,39 +20,48 @@ composer require jobapis/jobs-govt ## Usage -Usage is the same as JobApis' Jobs Client, using `\JobApis\Jobs\Client\Provider\Govt` -as the provider. +Create a Query object and add all the parameters you'd like via the constructor. + +```php +// Add parameters to the query via the constructor +$query = new JobApis\Jobs\Client\Queries\GovtQuery([ + 'hl' => '1' +]); +``` + +Or via the "set" method. All of the parameters documented in the API's documentation can be added. ```php -$client = new JobApis\Jobs\Client\Provider\Govt(); - -// Search for 200 job listings for 'project manager' in Chicago, IL -$jobs = $client - // API parameters - ->setQuery() // Attempts to extract as much "signal" as possible from the input text. Handles word variants, so a search on "nursing jobs" will find a job titled "nurse practitioner" and "RN." When parts of the query parameter are used to search against the position title, the results are ordered by relevance. When no query parameter is specified, they are ordered by date with the most recent listed first. - ->setOrganizationIds() // A comma-separated string specifying which federal, state, or local agencies to use as a filter. - ->setHl() // No highlighting is included by default. Use 'hl=1' to highlight terms in the position title that match terms in the user's search. - ->setSize() // Specifies how many results are returned (up to 100 at a time). - ->setFrom() // Specifies the starting record. - ->setTags() // A comma-separated string specifying the level of government. Current tags are federal, state, county, and city. - ->setLatLon() // Comma-separated pair denoting the position of the searcher looking for a job. For example, 'lat_lon=37.783333,-122.416667' is the value for San Francisco, CA. - // Extra parameters - ->setKeyword('project manager') // See "setQuery()" method above - ->setCount(100) // See "setSize()" method above - ->getJobs(); +// Add parameters via the set() method +$query->set('query', 'engineering'); ``` -The `getJobs` method will return a [Collection](https://github.com/jobapis/jobs-common/blob/master/src/Collection.php) of [Job](https://github.com/jobapis/jobs-common/blob/master/src/Job.php) objects. +You can even chain them if you'd like. + +```php +// Add parameters via the set() method +$query->set('size', '100') + ->set('from', '200'); +``` -### Location Queries +*Note: The government jobs API doesn't support adding location as a parameter, but their keyword or lat_lon parameters can be used for this purpose.* -Because this API does not support location-based queries, you will need to add the location -to your setKeyword() method call. For example: +Then inject the query object into the provider. +```php +// Instantiating an IndeedProvider with a query object +$client = new JobApis\Jobs\Client\Provider\GovtProvider($query); ``` -$jobs = $client->setKeyword('project manager in chicago, il')->getJobs(); + +And call the "getJobs" method to retrieve results. + +```php +// Get a Collection of Jobs +$jobs = $client->getJobs(); ``` +This will return a [Collection](https://github.com/jobapis/jobs-common/blob/master/src/Collection.php) of [Job](https://github.com/jobapis/jobs-common/blob/master/src/Job.php) objects. + ## Testing ``` bash From e36e965640c2c65d36a4ddcb74db7a148b137fb7 Mon Sep 17 00:00:00 2001 From: Karl Date: Fri, 2 Sep 2016 14:48:44 -0500 Subject: [PATCH 09/12] Typo in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c54d811..c3d8968 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog All Notable changes to `jobs-govt` will be documented in this file -## 1.0.0-beta - 2016-00-02 +## 1.0.0-beta - 2016-09-02 ### Added - Changed namespace and organization to `jobapis`. From 0f60ae0f835d3467ef8f702c1bd7f450ea0d32e7 Mon Sep 17 00:00:00 2001 From: Karl Date: Fri, 2 Sep 2016 15:14:12 -0500 Subject: [PATCH 10/12] Removing url from test (not needed) --- tests/src/GovtProviderTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/src/GovtProviderTest.php b/tests/src/GovtProviderTest.php index 4e90cc7..6eec737 100644 --- a/tests/src/GovtProviderTest.php +++ b/tests/src/GovtProviderTest.php @@ -79,8 +79,6 @@ public function testItCanCreateJobObjectFromPayload() */ public function testItCanGetJobs() { - $url = 'https://api.usa.gov/jobs/search.json'; - $options = [ 'query' => uniqid(), 'hl' => uniqid(), From 3f60a9368a2c47282c2b33e58e4ffcf9f44941be Mon Sep 17 00:00:00 2001 From: Karl Date: Fri, 2 Sep 2016 15:27:26 -0500 Subject: [PATCH 11/12] Typo in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7790a7c..32a277e 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ $query->set('size', '100') Then inject the query object into the provider. ```php -// Instantiating an IndeedProvider with a query object +// Instantiating provider with a query object $client = new JobApis\Jobs\Client\Provider\GovtProvider($query); ``` From b770f0a41560b6e614ac0dd24c799eff100923a7 Mon Sep 17 00:00:00 2001 From: Karl Date: Sat, 3 Sep 2016 10:17:21 -0500 Subject: [PATCH 12/12] Prep for v1 release --- CHANGELOG.md | 8 ++++++++ composer.json | 4 ++-- tests/src/GovtProviderTest.php | 2 +- tests/src/GovtQueryTest.php | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3d8968..dd98700 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # Changelog All Notable changes to `jobs-govt` will be documented in this file +## 1.0.0 - 2016-09-03 + +### Added +- Updated package name in composer file. + +### Fixed +- Test namespace. + ## 1.0.0-beta - 2016-09-02 ### Added diff --git a/composer.json b/composer.json index 9a652fa..cf01d25 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ ], "require": { "php": ">=5.5.0", - "jobbrander/jobs-common": "^2.0.0-beta" + "jobapis/jobs-common": "^2.0.0" }, "require-dev": { "phpunit/phpunit": ">=4.6", @@ -39,7 +39,7 @@ }, "autoload-dev": { "psr-4": { - "JobApis\\Jobs\\Client\\Providers\\Test\\": "tests/src/" + "JobApis\\Jobs\\Client\\Test\\": "tests/src/" } } } diff --git a/tests/src/GovtProviderTest.php b/tests/src/GovtProviderTest.php index 6eec737..f7a71bc 100644 --- a/tests/src/GovtProviderTest.php +++ b/tests/src/GovtProviderTest.php @@ -1,4 +1,4 @@ -