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/CHANGELOG.md b/CHANGELOG.md index b40f9d3..fe04df2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,15 @@ # Changelog All Notable changes to `jobs-careercast` will be documented in this file +## 1.0.0 - 2015-09-22 + +### Added +- Support for V2 of jobs common +- Real API call integration test + +### Changed +- Default to JSON output format which limits the input parameters, but allows more detailed job objects. + ## 0.2.0 - 2015-10-19 ### Added diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4957f30..652397c 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-careercast). +We accept contributions via Pull Requests on [Github](https://github.com/jobapis/jobs-careercast). ## 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 c575a77..9e1d15e 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,64 @@ # CareerCast RSS Jobs Client -[![Latest Version](https://img.shields.io/github/release/JobBrander/jobs-careercast.svg?style=flat-square)](https://github.com/JobBrander/jobs-careercast/releases) +[![Latest Version](https://img.shields.io/github/release/jobapis/jobs-careercast.svg?style=flat-square)](https://github.com/jobapis/jobs-careercast/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-careercast/master.svg?style=flat-square&1)](https://travis-ci.org/JobBrander/jobs-careercast) -[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/JobBrander/jobs-careercast.svg?style=flat-square)](https://scrutinizer-ci.com/g/JobBrander/jobs-careercast/code-structure) -[![Quality Score](https://img.shields.io/scrutinizer/g/JobBrander/jobs-careercast.svg?style=flat-square)](https://scrutinizer-ci.com/g/JobBrander/jobs-careercast) -[![Total Downloads](https://img.shields.io/packagist/dt/jobbrander/jobs-careercast.svg?style=flat-square)](https://packagist.org/packages/jobbrander/jobs-careercast) +[![Build Status](https://img.shields.io/travis/jobapis/jobs-careercast/master.svg?style=flat-square&1)](https://travis-ci.org/jobapis/jobs-careercast) +[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/jobapis/jobs-careercast.svg?style=flat-square)](https://scrutinizer-ci.com/g/jobapis/jobs-careercast/code-structure) +[![Quality Score](https://img.shields.io/scrutinizer/g/jobapis/jobs-careercast.svg?style=flat-square)](https://scrutinizer-ci.com/g/jobapis/jobs-careercast) +[![Total Downloads](https://img.shields.io/packagist/dt/jobapis/jobs-careercast.svg?style=flat-square)](https://packagist.org/packages/jobapis/jobs-careercast) This package provides [CareerCast Jobs RSS](http://www.careercast.com/jobs/results/keyword?format=rss) -support for the JobBrander's [Jobs Client](https://github.com/JobBrander/jobs-common). +support for the [Jobs Common project](https://github.com/JobBrander/jobs-common). ## Installation To install, use composer: ``` -composer require jobbrander/jobs-careercast +composer require jobapis/jobs-careercast ``` ## Usage -Usage is the same as Job Branders's Jobs Client, using `\JobBrander\Jobs\Client\Providers\Careercast` 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\CareercastQuery([ + 'keyword' => 'engineering' +]); +``` + +Or via the "set" method. All of the parameters documented can be added. + +```php +// Add parameters via the set() method +$query->set('location', 'Chicago, IL'); +``` + +You can even chain them if you'd like. + +```php +// Add parameters via the set() method +$query->set('company', 'General Electric') + ->set('page', '2'); +``` + +Then inject the query object into the provider. + +```php +// Instantiating provider with a query object +$client = new JobApis\Jobs\Client\Provider\CareercastProvider($query); +``` + +And call the "getJobs" method to retrieve results. ```php -$client = new JobBrander\Jobs\Client\Provider\Careercast(); - -// Search for 100 job listings for 'project manager' in Chicago, IL -$jobs = $client - // Setters from CareerCast's [Advanced Search](http://www.careercast.com/jobs/search/advanced) - ->setRows() // Number of jobs to return per page - ->setPage() // Set page number - ->setRadius() // Location search radius - ->setNormalizedJobTitle() // Choose from a standard list of job titles - ->setCategory() // Category name - ->setCompany() // Company name - ->setJobSource() // "staffing_firm" or "direct_employer" - ->setPostDate() // Post date range string wrapped in brackets and URL encoded, eg: "%5BNOW-7DAYS+TO+NOW%5D" - ->setFormat() // Defaults to "rss" - ->setWorkStatus() // "full_time" or "part_time" - ->setLocation('Chicago, Illinois, United States') - ->setKwsJobTitleOnly() // Set to "true" to only search job titles - // More - ->setKeyword('project manager') // Keyword to search as part of the URL - ->setCount(100) // Alias for setRows() above - ->getJobs(); +// Get a Collection of Jobs +$jobs = $client->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. +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 @@ -56,14 +68,14 @@ $ ./vendor/bin/phpunit ## Contributing -Please see [CONTRIBUTING](https://github.com/jobbrander/jobs-careercast/blob/master/CONTRIBUTING.md) for details. +Please see [CONTRIBUTING](https://github.com/jobapis/jobs-careercast/blob/master/CONTRIBUTING.md) for details. ## Credits - [Karl Hughes](https://github.com/karllhughes) - [Steven Maguire](https://github.com/stevenmaguire) -- [All Contributors](https://github.com/jobbrander/jobs-careercast/contributors) +- [All Contributors](https://github.com/jobapis/jobs-careercast/contributors) ## License -The Apache 2.0. Please see [License File](https://github.com/jobbrander/jobs-careercast/blob/master/LICENSE) for more information. +The Apache 2.0. Please see [License File](https://github.com/jobapis/jobs-careercast/blob/master/LICENSE) for more information. diff --git a/composer.json b/composer.json index 758a33e..3652204 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "jobbrander/jobs-careercast", + "name": "jobapis/jobs-careercast", "type": "library", "description": "Making it simple to integrate your application with Careercast's Jobs RSS feed.", "keywords": [ @@ -20,7 +20,7 @@ ], "require": { "php": ">=5.5.0", - "jobbrander/jobs-common": "~1.0.3" + "jobapis/jobs-common": "^2.0.0" }, "require-dev": { "phpunit/phpunit": ">=4.6", @@ -30,12 +30,12 @@ }, "autoload": { "psr-4": { - "JobBrander\\Jobs\\Client\\Providers\\": "src/" + "JobApis\\Jobs\\Client\\": "src/" } }, "autoload-dev": { "psr-4": { - "JobBrander\\Jobs\\Client\\Providers\\Test\\": "tests/src/" + "JobApis\\Jobs\\Client\\Providers\\Test\\": "tests/src/" } } } diff --git a/src/Careercast.php b/src/Careercast.php deleted file mode 100644 index 5c385db..0000000 --- a/src/Careercast.php +++ /dev/null @@ -1,215 +0,0 @@ - 'rows', - 'setPage' => 'page', - 'setRadius' => 'radius', - 'setNormalizedJobTitle' => 'normalizedJobTitle', - 'setCategory' => 'category', - 'setCompany' => 'company', - 'setJobSource' => 'jobSource', - 'setPostDate' => 'postDate', - 'setFormat' => 'format', - 'setWorkStatus' => 'workStatus', - 'setLocation' => 'location', - 'setKwsJobTitleOnly' => 'kwsJobTitleOnly', - 'setCount' => 'rows', - ]; - - /** - * Current url query parameters - * - * @var array - */ - protected $queryParams = [ - 'rows' => null, - 'page' => null, - 'radius' => null, - 'normalizedJobTitle' => null, - 'category' => null, - 'company' => null, - 'jobSource' => null, - 'postDate' => null, - 'format' => 'rss', - 'workStatus' => null, - 'location' => null, - 'kwsJobTitleOnly' => null, - ]; - - /** - * Create new Careercast jobs client. - * - * @param array $parameters - */ - 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) - { - if (isset($this->queryMap[$method], $parameters[0])) { - $this->updateQuery($parameters[0], $this->queryMap[$method]); - } - return parent::__call($method, $parameters); - } - - /** - * Returns the standardized job object - * - * @param array $payload - * - * @return \JobBrander\Jobs\Client\Job - */ - public function createJobObject($payload) - { - $defaults = [ - 'title', - 'link', - 'description', - 'pubDate', - ]; - - $payload = static::parseAttributeDefaults($payload, $defaults); - - $job = new Job([ - 'description' => $payload['description'], - 'title' => $payload['title'], - 'name' => $payload['title'], - 'url' => $payload['link'], - 'query' => $this->keyword, - 'source' => $this->getSource(), - 'location' => $this->getLocation(), - ]); - - $job->setDatePostedAsString($payload['pubDate']); - - if (isset($this->city)) { - $job->setCity($this->city); - } - if (isset($this->state)) { - $job->setState($this->state); - } - $job->setCompany($this->parseCompanyFromDescription($job->getDescription())); - - return $job; - } - - /** - * Get data format - * - * @return string - */ - public function getFormat() - { - return 'xml'; - } - - /** - * Get listings path - * - * @return string - */ - public function getListingsPath() - { - return 'channel.item'; - } - - /** - * Get Location from input params - * - * @return string Location string - */ - public function getLocation() - { - if (isset($this->queryParams['location'])) { - return $this->queryParams['location']; - } - return null; - } - - /** - * Get query string for client based on properties - * - * @return string - */ - public function getQueryString() - { - return http_build_query($this->queryParams); - } - - /** - * Get url - * - * @return string - */ - public function getUrl() - { - $query_string = $this->getQueryString(); - if ($this->getKeyword()) { - $keyword = urlencode($this->getKeyword()); - } else { - $keyword = urlencode(' '); - } - - return 'http://www.careercast.com/jobs/results/keyword/'.$keyword.'?'.$query_string; - } - - /** - * Get http verb - * - * @return string - */ - public function getVerb() - { - return 'GET'; - } - - /** - * Attempt to get the company name from the description - * - * @return string - */ - public function parseCompanyFromDescription($description) - { - $array = explode(' - ', $description); - if (isset($array[0]) && isset($array[1])) { - return $array[0]; - } - return null; - } - - /** - * Attempts to update current query parameters. - * - * @param string $value - * @param string $key - * - * @return Careercast - */ - protected function updateQuery($value, $key) - { - if (array_key_exists($key, $this->queryParams)) { - $this->queryParams[$key] = $value; - } - return $this; - } -} diff --git a/src/Providers/CareercastProvider.php b/src/Providers/CareercastProvider.php new file mode 100644 index 0000000..5f53e7f --- /dev/null +++ b/src/Providers/CareercastProvider.php @@ -0,0 +1,135 @@ + $payload['Description'], + 'title' => $payload['JobTitle'], + 'name' => $payload['JobTitle'], + 'url' => $payload['Url'], + 'sourceId' => $payload['Id'], + 'datePosted' => $payload['PostDate'], + 'validThrough' => $payload['ExpireDate'], + 'qualifications' => $payload['Requirements'], + 'maximumSalaray' => $payload['SalaryMax'], + 'minimumSalaray' => $payload['SalaryMin'], + 'baseSalaray' => $payload['SalaryMin'], + ]); + $job = $this->setCategory($payload, $job); + $job = $this->setCompany($payload, $job); + return $this->setLocation($payload, $job); + } + + /** + * Job response object default keys that should be set + * + * @return string + */ + public function getDefaultResponseFields() + { + return [ + 'Description', + 'JobTitle', + 'Url', + 'Id', + 'PostDate', + 'ExpireDate', + 'Requirements', + 'SalaryMax', + 'SalaryMin', + 'SalaryMin', + 'CategoryDisplay', + 'WorkStatusDisplay', + ]; + } + + /** + * Get listings path + * + * @return string + */ + public function getListingsPath() + { + return 'Jobs'; + } + + /** + * Parses the category and work type and attaches it to the job + * + * @param $payload array + * @param $job \JobApis\Jobs\Client\Job + * + * @return \JobApis\Jobs\Client\Job + */ + protected function setCategory($payload, $job) + { + if (isset($payload['CategoryDisplay']) && is_array($payload['CategoryDisplay'])) { + $job->setOccupationalCategory(implode(', ', $payload['CategoryDisplay'])); + } + if (isset($payload['CategoryDisplay']) && is_array($payload['WorkStatusDisplay'])) { + $job->setEmploymentType(implode(', ', $payload['WorkStatusDisplay'])); + } + return $job; + } + + /** + * Parses the company name and attaches it to the job + * + * @param $payload array + * @param $job \JobApis\Jobs\Client\Job + * + * @return \JobApis\Jobs\Client\Job + */ + protected function setCompany($payload, $job) + { + if (isset($payload['Company'])) { + $job->setCompany($payload['Company']); + } + return $job; + } + + /** + * Parses the location and attaches it to the job + * + * @param $payload array + * @param $job \JobApis\Jobs\Client\Job + * + * @return \JobApis\Jobs\Client\Job + */ + protected function setLocation($payload, $job) + { + if (isset($payload['FormattedCityState'])) { + $job->setLocation($payload['FormattedCityState']); + } + if (isset($payload['State'])) { + $job->setState($payload['State']); + } + if (isset($payload['Country'])) { + $job->setCountry($payload['Country']); + } + if (isset($payload['City'])) { + $job->setCity($payload['City']); + } + if (isset($payload['Longitude'])) { + $job->setLongitude($payload['Longitude']); + } + if (isset($payload['Latitude'])) { + $job->setLatitude($payload['Latitude']); + } + if (isset($payload['Zip'])) { + $job->setPostalCode($payload['Zip']); + } + return $job; + } +} diff --git a/src/Queries/CareercastQuery.php b/src/Queries/CareercastQuery.php new file mode 100644 index 0000000..849894c --- /dev/null +++ b/src/Queries/CareercastQuery.php @@ -0,0 +1,183 @@ +keyword; + } + + /** + * Get query string for client based on properties + * + * @return string + */ + public function getQueryString() + { + $keyword = urlencode($this->keyword); + + return $keyword.'?'.http_build_query($this->getQueryAttributes()); + } + + /** + * Default parameters + * + * @var array + */ + protected function defaultAttributes() + { + return [ + 'format' => 'json', + ]; + } + + /** + * Gets the attributes to use for this API's query + * + * @var array + */ + protected function getQueryAttributes() + { + $attributes = get_object_vars($this); + unset($attributes['keyword']); + return $attributes; + } + + /** + * Required attributes for the query + * + * @var array + */ + protected function requiredAttributes() + { + return [ + 'keyword', + ]; + } +} diff --git a/tests/src/CareercastProviderTest.php b/tests/src/CareercastProviderTest.php new file mode 100644 index 0000000..5165133 --- /dev/null +++ b/tests/src/CareercastProviderTest.php @@ -0,0 +1,195 @@ +query = m::mock('JobApis\Jobs\Client\Queries\CareercastQuery'); + + $this->client = new CareercastProvider($this->query); + } + + public function testItCanGetDefaultResponseFields() + { + $fields = [ + 'Description', + 'JobTitle', + 'Url', + 'Id', + 'PostDate', + 'ExpireDate', + 'Requirements', + 'SalaryMax', + 'SalaryMin', + 'SalaryMin', + 'CategoryDisplay', + 'WorkStatusDisplay', + ]; + $this->assertEquals($fields, $this->client->getDefaultResponseFields()); + } + + public function testItCanGetListingsPath() + { + $this->assertEquals('Jobs', $this->client->getListingsPath()); + } + + public function testItCanCreateJobObjectFromPayload() + { + $payload = $this->createJobArray(); + + $results = $this->client->createJobObject($payload); + + $this->assertInstanceOf(Job::class, $results); + $this->assertEquals($payload['JobTitle'], $results->title); + $this->assertEquals($payload['Description'], $results->description); + $this->assertEquals($payload['Url'], $results->url); + } + + /** + * Integration test for the client's getJobs() method. + */ + public function testItCanGetJobs() + { + $options = [ + 'keyword' => uniqid(), + 'location' => uniqid(), + 'rows' => uniqid(), + ]; + + $guzzle = m::mock('GuzzleHttp\Client'); + + $query = new CareercastQuery($options); + + $client = new CareercastProvider($query); + + $client->setClient($guzzle); + + $response = m::mock('GuzzleHttp\Message\Response'); + + $jobs = json_encode(['Jobs' => [ + 0 => $this->createJobArray(), + 1 => $this->createJobArray(), + 2 => $this->createJobArray(), + ]]); + + $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(3, $results); + } + + /** + * 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.'); + } + + $keyword = 'sales'; + + $query = new CareercastQuery([ + 'keyword' => $keyword, + ]); + + $client = new CareercastProvider($query); + + $results = $client->getJobs(); + // var_dump($results); exit; + + $this->assertInstanceOf('JobApis\Jobs\Client\Collection', $results); + + foreach($results as $job) { + $this->assertEquals($keyword, $job->query); + } + } + + private function createJobArray() { + return json_decode('{ + "NormalizedJobTitle": "Automation Engineer", + "AdId": "57d10f1f7d6210", + "ApplyCity": "", + "ApplyCountry": "", + "ApplyEmail": "", + "ApplyFax": "", + "ApplyName": "", + "ApplyPhone": "", + "ApplyState": "", + "ApplyUrl": "https://my.jobs/1f46f5d0f4af4973aff849f085bfb100105", + "ApplyZip": "", + "City": "Chicago", + "CityDisplay": "Chicago", + "ClientId": "", + "CompanyId": "", + "Company": "Volt", + "CompanyProfileUrl": "", + "Country": "United States", + "Description": "Volt has been serving some of the nation\'s strongest companies for over 60 years. We have a talented and upbeat staffing team focused on the quality of your career. As a Volt employee, you can expect the highest level of on-site support. We have a long-standing tradition of developing lasting and mutually beneficial relationships with our employees. We are a Six Sigma company that also offers many direct hire, full-time positions.Volt Workforce Solutions has an opportunity for you to become part of a prestigious team of professionals.Our client, located in Chicago, IL, is looking for a Senior Automation Engineer. This position can also possibly be a remote opportunity in Chicago OR on the East coast only. The candidate will be part of the Client Care - Field Services team to provide world-class project support to the clients. The individual must be able to work independently with minimal supervision to efficiently resolve electro-mechanical issues and equipment errors on automated materials handling systems and related equipment. Candidate will be responsible for site/application specific equipment set-up and programming and client training on proper equipment usage. Flexibility and adaptability to work safely at various worksites are required.The candidate will be working with PLC\'s and having Allen Bradley PLC experience is a huge plus for the role and equipment you will be working with and on along with having experience to diagnose mechanical and electrical problems using technical drawings. The candidate will have a very strong background being able to debug and troubleshoot the specified equipment (usually AB). The candidate must also be computer savvy and able to generate and conduct comprehensive service reports. The candidate should also have experience working directly in the mechanical/electronics field as well as the ability to read and utilize mechanical and electrical schematics to assist in troubleshooting and resolution of those components. *Must possess Bachelor\'s Degree (BSEE, BSME, BSE, etc) + Mechanically troubleshoot and repair minor mechanical problems. + Must know the capabilities and functionality of a PLC. + Interact courteously and professionally with clients, other engineers, managers, subcontractors, and other communications as assigned. + Diagnose mechanical and electrical problems using technical drawings. + Perform preventative maintenance and repairs on equipment. + Compile thorough, detailed reports, based on the work completed onsite. + Follow up with customers and other departments to ensure issues have been resolved.Submit your resume today! Contact a Volt representative by applying to this posting online for immediate consideration. We look forward to speaking with you soon. **Volt is an Equal Opportunity Employer.**", + "ExpireDate": "2016-10-22T04:59:59Z", + "HtmlFileUri": "http://slb.adicio.com/files/adguy-c-02/2016-09/22/00/10/57e383eb758d.html", + "Id": "90129569", + "JobCode": "", + "JobSource": "direct_employer", + "JobSummary": " professionals.Our client, located in Chicago, IL, is looking for a Senior Automation Engineer. This position can also possibly be a remote opportunity in Chicago OR on the East coast only....", + "JobTitle": "AUTOMATION ENGINEER", + "Latitude": "41.8781136", + "Longitude": "-87.6297982", + "ModifiedDate": "2016-09-22T07:00:00Z", + "NormalizedCountry": "US", + "NormalizedState": "IL", + "ParserId": "49baaecd3", + "PostDate": "2016-09-22T07:00:00Z", + "PostingCompany": "Volt", + "PostingCompanyId": "0", + "Requirements": "", + "ResponseMethod": "url", + "SalaryMax": "", + "SalaryMin": "", + "Source": "", + "State": "IL", + "Zip": "", + "CompanyConfidential": "", + "Category": [ + "engineering" + ], + "AssignedCategory": [ + "engineering" + ], + "Upgrades": [], + "CategoryDisplay": [ + "Engineering" + ], + "SearchNetworks": "", + "MatchedCategory": "", + "CompanyLogo": "", + "CompanyProfileDescription": "", + "CompanyIndustry": "", + "WorkStatus": "", + "WorkStatusDisplay": [], + "WorkShift": "", + "WorkType": "", + "CompanySize": "", + "CompanyType": "", + "RemoteDetailUrl": "", + "PaymentInterval": "", + "FormattedCityState": "Chicago, IL", + "FormattedCityStateCountry": "Chicago, IL US", + "Url": "http://careers.glassceiling.com/jobs/automation-engineer-chicago-il-90129569-d?rsite=careercast&rgroup=1&clientid=glass&widget=1&type=job&" + }', true); + } +} diff --git a/tests/src/CareercastQueryTest.php b/tests/src/CareercastQueryTest.php new file mode 100644 index 0000000..82ce711 --- /dev/null +++ b/tests/src/CareercastQueryTest.php @@ -0,0 +1,86 @@ +query = new CareercastQuery(); + } + + public function testItCanGetBaseUrl() + { + $this->assertEquals( + 'http://www.careercast.com/jobs/results/keyword/', + $this->query->getBaseUrl() + ); + } + + public function testItCanGetKeyword() + { + $keyword = uniqid(); + $this->query->set('keyword', $keyword); + $this->assertEquals($keyword, $this->query->getKeyword()); + } + + public function testItReturnsFalseIfRequiredAttributesMissing() + { + $this->assertFalse($this->query->isValid()); + } + + public function testItReturnsTrueIfRequiredAttributesPresent() + { + $this->query->set('keyword', uniqid()); + + $this->assertTrue($this->query->isValid()); + } + + public function testItCanAddAttributesToUrl() + { + $keyword = uniqid(); + + $this->query->set('keyword', $keyword); + $this->query->set('rows', rand(1,10)); + + $url = $this->query->getUrl(); + + $this->assertContains('keyword/'.$keyword, $url); + $this->assertContains('rows=', $url); + } + + /** + * @expectedException OutOfRangeException + */ + public function testItThrowsExceptionWhenSettingInvalidAttribute() + { + $this->query->set(uniqid(), uniqid()); + } + + /** + * @expectedException OutOfRangeException + */ + public function testItThrowsExceptionWhenGettingInvalidAttribute() + { + $this->query->get(uniqid()); + } + + public function testItSetsAndGetsValidAttributes() + { + $attributes = [ + 'keyword' => uniqid(), + 'rows' => uniqid(), + 'page' => uniqid(), + 'company' => uniqid(), + ]; + + foreach ($attributes as $key => $value) { + $this->query->set($key, $value); + } + + foreach ($attributes as $key => $value) { + $this->assertEquals($value, $this->query->get($key)); + } + } +} diff --git a/tests/src/CareercastTest.php b/tests/src/CareercastTest.php deleted file mode 100644 index 3ce783b..0000000 --- a/tests/src/CareercastTest.php +++ /dev/null @@ -1,236 +0,0 @@ -client = new Careercast(); - } - - public function testItWillUseXmlFormat() - { - $format = $this->client->getFormat(); - - $this->assertEquals('xml', $format); - } - - public function testItWillUseGetHttpVerb() - { - $verb = $this->client->getVerb(); - - $this->assertEquals('GET', $verb); - } - - public function testListingPath() - { - $path = $this->client->getListingsPath(); - - $this->assertEquals('channel.item', $path); - } - - public function testItWillProvideEmptyParameters() - { - $parameters = $this->client->getParameters(); - - $this->assertEmpty($parameters); - $this->assertTrue(is_array($parameters)); - } - - public function testUrlIncludesKeywordWhenProvided() - { - $keyword = uniqid().' '.uniqid(); - $param = 'keyword/'.urlencode($keyword); - - $url = $this->client->setKeyword($keyword)->getUrl(); - - $this->assertContains($param, $url); - } - - public function testUrlNotIncludesKeywordWhenNotProvided() - { - $param = 'keyword/'.urlencode(' '); - - $url = $this->client->getUrl(); - - $this->assertContains($param, $url); - } - - public function testUrlIncludesLocationWhenCityAndStateProvided() - { - $city = uniqid(); - $state = uniqid(); - $param = 'location='.urlencode($city.', '.$state); - - $url = $this->client->setLocation($city.', '.$state)->getUrl(); - - $this->assertContains($param, $url); - } - - public function testItWillNotGetLocationWhenNoneProvided() - { - $param = 'location'; - - $url = $this->client->getUrl(); - - $this->assertNotContains($param, $url); - } - - public function testItWillGetCount() - { - $count = rand(1, 50); - $this->client->setCount($count); - - $results = $this->client->getCount(); - - $this->assertEquals($count, $results); - } - - public function testUrlIncludesPageWhenProvided() - { - $page = uniqid(); - $param = 'page='.$page; - - $url = $this->client->setPage($page)->getUrl(); - - $this->assertContains($param, $url); - } - - public function testUrlNotIncludesPageWhenNotProvided() - { - $param = 'page='; - - $url = $this->client->setPage(null)->getUrl(); - - $this->assertNotContains($param, $url); - } - - public function testUrlIncludesCountWhenProvided() - { - $count = rand(0, 50); - $param = 'rows='.$count; - - $url = $this->client->setCount($count)->getUrl(); - - $this->assertContains($param, $url); - } - - public function testUrlNotIncludesStartWhenNotProvided() - { - $param = 'rows='; - - $url = $this->client->setCount(null)->getUrl(); - - $this->assertNotContains($param, $url); - } - - public function testItCanCreateJobFromPayload() - { - $city = uniqid(); - $state = uniqid(); - $this->client->setLocation($city.', '.$state); - $payload = $this->createJobArray(); - - $results = $this->client->createJobObject($payload); - - $this->assertEquals($payload['title'], $results->title); - $this->assertEquals($payload['description'], $results->description); - $this->assertEquals($payload['link'], $results->url); - $this->assertNotNull($results->company); - $this->assertInstanceOf('DateTime', $results->datePosted); - } - - public function testItCanCreateJobFromPayloadWithoutCompanyInDescription() - { - $city = uniqid(); - $state = uniqid(); - $this->client->setLocation($city.', '.$state); - $payload = $this->createJobArrayWithoutCompany(); - - $results = $this->client->createJobObject($payload); - - $this->assertEquals($payload['title'], $results->title); - $this->assertEquals($payload['description'], $results->description); - $this->assertEquals($payload['link'], $results->url); - $this->assertInstanceOf('DateTime', $results->datePosted); - } - - public function testItCanConnect() - { - $provider = $this->getProviderAttributes(['format' => 'xml']); - $payload = []; - - $responseBody = ""; - - for ($i = 0; $i < $provider['jobs_count']; $i++) { - $jobArray = $this->createJobArray(); - $path = $provider['path']; - array_push($payload, $jobArray); - $responseBody .= "".$jobArray['title'].""; - $responseBody .= "".$jobArray['pubDate'].""; - $responseBody .= ""; - $responseBody .= ""; - } - - $responseBody .= ""; - - $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(); - - $response = m::mock('GuzzleHttp\Message\Response'); - $response->shouldReceive('getBody')->once()->andReturn($responseBody); - - $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); - - $results = $this->client->getJobs(); - - $this->assertInstanceOf($this->collectionClass, $results); - $this->assertCount($provider['jobs_count'], $results); - } - - private function createJobArray() { - return [ - 'title' => uniqid(), - 'description' => uniqid().' - '.uniqid().' '.uniqid(), - 'link' => uniqid(), - 'pubDate' => date('F j, Y, g:i a'), - ]; - } - - private function createJobArrayWithoutCompany() { - return [ - 'title' => uniqid(), - 'description' => uniqid(), - 'link' => uniqid(), - 'pubDate' => date('F j, Y, g:i a'), - ]; - } - - 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); - } -}