Skip to content

Instantly share code, notes, and snippets.

@yourwebmaker
Last active June 10, 2016 05:03
Show Gist options
  • Save yourwebmaker/35e2368c53f3eed7816c to your computer and use it in GitHub Desktop.
Save yourwebmaker/35e2368c53f3eed7816c to your computer and use it in GitHub Desktop.
Just sharing some pieces of code with others. Every file has your own comments described on the top of each one.
<?php
namespace GivenTree\Certification;
/**
* A simple example orepository pattern (http://martinfowler.com/eaaCatalog/repository.html)
* In this example I've used in-memory strategy to retrieve records
* Project: http://test.giventree.org/
* Framework: Laravel
*/
class PageRepository
{
/**
* @var array
*/
protected $data = [
1 => [
'id' => 1,
'status' => UserPage::STATUS_NEW,
'title' => 'Basic Info',
'validation' => [
'organization_name' => 'max:255',
],
'inputs' => [
'websiteInformation' => [
1 => 'Mission Statement',
2 => 'Pictures',
3 => 'Address',
4 => 'Vision',
5 => 'Live Feed',
6 => 'Value / Philosophy',
7 => 'Phone',
8 => 'Informational Video(s)',
9 => 'Email',
],
'financialInformation' => [
['name' => '990 Forms', 'options' => [1 => 'Most Recent Year', 2 => 'Past 2 Years', 3 => 'Past 3 Years']],
['name' => 'Financial Reports', 'options' => [4 => 'Most Recent Year', 5 => 'Past 2 Years', 6 => 'Past 3 Years']],
['name' => 'Project Info', 'options' => [7 => 'Past Projects(s)', 8 => 'Current Project(s)', 9 => 'Future Projects(s)']],
['name' => 'Board of Directors', 'options' => [10 => 'Names', 11 => 'Pictures', 12 => 'Bio']],
],
'socialNetworks' => [
1 => 'Facebook',
2 => 'Twitter',
3 => 'Blogs',
4 => 'Linkedin',
5 => 'YouTube',
6 => 'Pinterest',
7 => 'Instagram',
],
],
'requiredFields' => [
"organization_name","year_founded","hq_street_address","ein","address","501c3_since",
"zip_code","country","hq_phone","contact_tital","contact_email","contact_phone","website",
"office_outside_us",
],
'comments' => []
],
2 => [
'id' => 2,
'status' => UserPage::STATUS_NEW,
'title' => 'Philosophy & Approach',
'validation' => [
],
'inputs' => [
'relyOnExpeditionsFunds' => [
1 => 'Overhead Expenses',
2 => 'Project Materials',
3 => 'Expedition Expenses',
4 => 'Other',
],
'frequencyOfBoardMember' => [
1 => 'Monthly',
2 => 'Quarterly',
3 => 'Bi-Annually',
4 => 'Annually',
],
'yesNo' => [
'yes' => 'Yes',
'no' => 'No',
]
],
'requiredFields' => [
"mission_statement","value","vision","elevator_speech","strengths","weaknesses","opportunities",
"challenges","ceo_title","ceo_position_since","board_meetings_frequency",
"total_paid_employees_fulltime","total_paid_employees_parttime",
"number_local_employees_parttime","have_volunteer_program",
"volunteer_program_majority","do_expeditions","total_volunteers_past_year",
"total_volunteers_from_local","total_volunteers_from_outside","total_volunteers_hours",
"total_volunteers_hours_local","total_volunteers_hours_outside","staff_insurance",
"staff_insurance_limits",
"have_community_approach_program","community_approach_model","how_involve_community",
"first_steps_entering_community","how_help_community_decision","conduct_evaluations_community_program",
"community_program_require_community","partners_organizations","partners_organizations_past",
"teach_skills","what_skills","promote_self_reliance","how_promote_self_reliance","service_to_neighbor",
"how_service_to_neighbor"
],
'comments' => []
],
3 => [
'id' => 3,
'status' => UserPage::STATUS_NEW,
'title' => 'Financial Health',
'inputs' => [
'fundraising' => [
1 => 'Board Members',
2 => 'Volunteer Program',
3 => 'Government',
4 => 'Companies',
5 => 'Small donations',
6 => 'Grants',
7 => 'Website (Online donations)',
8 => 'Large donors',
9 => 'Foundations',
10 => 'Fundraisers',
11 => 'Other',
],
'financialTransparency' => [
1 => 'Are your 990 Forms available to public?',
2 => 'Do you have Financial Statements available to public?',
3 => 'Do you have Annual Reports available to public?'
]
],
'validation' => [],
'requiredFields' => [
"total_revenue","total_expenses","overhead_costs","funds_spents_on_salaries","top_5_funders",
"recent_financial_statement","donations_amount","organizations_amount","financial_goals_next_years",
"financial_goals_next_5_years"
],
'comments' => []
],
4 => [
'id' => 4,
'status' => UserPage::STATUS_NEW,
'title' => 'Performance',
'inputs' => [],
'validation' => [],
'requiredFields' => [
'annual_activity_report', 'quarterly_activity_updates'
],
'comments' => []
],
];
function find($pageNumber)
{
return (object) $this->data[$pageNumber];
}
function findAll()
{
foreach ($this->data as $i => $page) {
$pages[$i] = (object) $page;
}
return $pages;
}
}
<?php
namespace CityManager\Tests;
use CityManager\Problem\Problem;
use CityManager\Problem\Category;
use CityManager\Problem\Photo;
use \DateTime;
/**
* Unit-test class using PHPUnit Framework, DateTime mocking
* Project: Comercial (I can't share the link)
* Frameworks/Libs: Symfony 2, Doctrine, PHPUnit, php-timecop
*/
class ProblemTest extends \PHPUnit_Framework_TestCase
{
/**
* @var string
*/
protected $title = 'There is a BIG hole on my street';
/**
* @var string
*/
protected $description = 'What a hole!!!!';
/**
* @var \DateTime
*/
protected $reportedAt;
/**
* @var Category|\PHPUnit_Framework_MockObject_MockObject
*/
protected $category;
/**
* @var Problem
*/
protected $problem;
/**
* @var Photo|\PHPUnit_Framework_MockObject_MockObject
*/
protected $photo;
/**
* @inheritdoc
*/
function setUp()
{
$this->category = $this->getMockBuilder(Category::class)
->disableOriginalConstructor()
->getMock();
$this->photo = $this->getMockBuilder(Photo::class)
->disableOriginalConstructor()
->getMock();
/**
* Mocking current time
* @see https://github.com/hnw/php-timecop
*/
$newTime = mktime(12, 0, 0, 4, 11, 2000);
timecop_freeze($newTime);
$this->reportedAt = new DateTime('2000-04-01 00:00:00');
}
/**
* @return Problem
*/
function createProblem()
{
$problem = new Problem($this->title, $this->description, $this->category);
$reflectionClass = new \ReflectionClass(Problem::class);
$reflectionProperty = $reflectionClass->getProperty('reportedAt');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue($problem, $this->reportedAt);
return $problem;
}
/**
* @test
*/
function constructorShouldAssignCorrectAttributes()
{
$problem = $this->createProblem();
$this->assertAttributeEquals($this->title, 'title', $problem);
$this->assertAttributeEquals($this->description, 'description', $problem);
$this->assertAttributeEquals($this->category, 'category', $problem);
}
/**
* @test
*/
function constructorShouldAssignCurrentTimeToReportedAtAttribute()
{
$problem = $this->createProblem();
$this->assertAttributeEquals($this->reportedAt, 'reportedAt', $problem);
}
/**
* @test
*/
function newProblemMustHaveItsStatusAsUnpublished()
{
$problem = $this->createProblem();
$this->assertEquals(Problem::STATUS_WAITING_REVISION, $problem->getStatus());
}
/**
* @test
*/
function publishShouldChangeStatusToPublished()
{
$problem = $this->createProblem();
$problem->publish();
$this->assertEquals(Problem::STATUS_PUBLISHED, $problem->getStatus());
}
/**
* @test
*/
function addPhotosMustPhotoToStack()
{
$problem = $this->createProblem();
$problem->addPhoto($this->photo);
$this->assertContains($this->photo, $problem->getPhotos());
}
/**
* @test
*/
function getDaysSinceReportMustReturnTotalDaysDifferenceFromReportDate()
{
$problem = $this->createProblem();
$this->assertEquals(10, $problem->getDaysSinceReport());
}
/**
* @test
*/
function isResolvedMustReturnProblemInstance()
{
$problem = $this->createProblem();
$this->assertInstanceOf(Problem::class, $problem->isResolved());
}
/**
* @test
*/
function isResolvedMustChangeSituationToResolved()
{
$problem = $this->createProblem();
$problem->isResolved();
$this->assertAttributeEquals(Problem::SITUATION_RESOLVED, 'situation', $problem);
}
/**
* @test
*/
function isResolvedMustChangeResolvedMessageAttribute()
{
$message = 'WOW... Nice Jobs guys!';
$problem = $this->createProblem();
$problem->isResolved($message);
$this->assertAttributeEquals($message, 'isResolvedMessage', $problem);
}
/**
* @inheritdoc
*/
function tearDown()
{
timecop_return();
}
}
<?php
/**
*
*/
namespace Iugu\Api;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;
use Iugu\Api\Exception\ClientException as IuguClientException;
use Iugu\Api\Exception\ServerException as IuguServerException;
/**
* Class tested on RestWrapperTest.php file.
* @package Iugu\Api
*/
class RestWrapper
{
/**
* @var ClientInterface
*/
protected $client;
/**
* @var ResponseHandler
*/
protected $handler;
/**
* RestWrapper constructor.
* @param ClientInterface $client
* @param ResponseHandler $handler
*/
public function __construct(ClientInterface $client, ResponseHandler $handler)
{
$this->client = $client;
$this->handler = $handler;
}
/**
* @param $uri
* @param $options
* @return array
*/
function get($uri, array $options = [])
{
try {
return $this->handler->handle($this->client->request('get', $uri, ['json' => $options]));
} catch (ClientException $e) {
throw new IuguClientException($e->getResponse()->getBody(), $e->getCode());
} catch (ServerException $e) {
throw new IuguServerException($e->getResponse()->getBody(), $e->getCode());
}
}
}
<?php
namespace Iugu\Api;
use GuzzleHttp\ClientInterface;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Client;
/**
* Unit-test class using PHPUnit Framework and mocking HTTP requests using Guzzle
* I've made this class to reduce complexity existent on client code.
* Project: http://c.iugu.com/ (it's a kind of PayPal for startups)
* Frameworks/Libs: Zend Framework 2, Guzzle
* @package Iugu\Api
*/
class RestWrapperTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \PHPUnit_Framework_MockObject_MockObject|Client
*/
protected $client;
/**
* @var \PHPUnit_Framework_MockObject_MockObject|ResponseInterface
*/
protected $response;
/**
* @var \PHPUnit_Framework_MockObject_MockObject|ResponseHandler
*/
protected $handler;
function setUp()
{
$this->client = $this->getMockBuilder(ClientInterface::class)
->disableOriginalConstructor()
->getMock();
$this->handler = $this->getMockBuilder(ResponseHandler::class)
->disableOriginalConstructor()
->getMock();
$this->response = $this->getMockBuilder(ResponseInterface::class)
->disableOriginalConstructor()
->getMock();
}
/**
* @test
* @dataProvider getMethods
* @param $method
*/
function allMethodsMustConvertResponsesIntoArray($method)
{
$uri = 'foo';
$this->client->expects($this->once())
->method('request')
->with($method, $uri)
->will($this->returnValue($this->response));
$this->handler->expects($this->once())
->method('handle')
->with($this->response)
->will($this->returnValue([]));
$wrapper = new RestWrapper($this->client, $this->handler);
$this->assertInternalType('array', $wrapper->$method($uri));
}
/**
* @param Response $response
* @return Client
*/
function createClient(Response $response)
{
$token = 'test-token';
// Create a mock and queue two responses.
$mock = new MockHandler([$response]);
$handler = HandlerStack::create($mock);
return new Client([
'base_uri' => 'https://api.iugu.com',
'auth' => [$token, ''],
'handler' => $handler
]);
}
/**
* @test
* @expectedException \Iugu\Api\Exception\ClientException
* @expectedExceptionMessage Unauthorized
* @expectedExceptionCode 400
* @dataProvider getMethods
*
* @param $method
*/
function mustThrowExceptionForClientErrors($method)
{
$response = new Response(400, [], '{"errors": "Unauthorized"}');
$handler = new ResponseHandler(new ResponseConverter());
$wrapper = new RestWrapper($this->createClient($response), $handler);
$wrapper->$method('x');
}
/**
* @test
* @expectedException \Iugu\Api\Exception\ServerException
* @expectedExceptionMessage Server Error
* @expectedExceptionCode 500
* @dataProvider getMethods
*
* @param $method
*/
function mustThrowExceptionForServerErrors($method)
{
$response = new Response(500, [], '{"errors": "Server Error"}');
$handler = new ResponseHandler(new ResponseConverter());
$wrapper = new RestWrapper($this->createClient($response), $handler);
$wrapper->$method('x');
}
/**
* @return array
*/
function getMethods()
{
return [
['get'],
['post'],
['put'],
['delete'],
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment