mirror of
https://github.com/bitinflow/accounts.git
synced 2026-03-13 13:35:52 +00:00
Initial commit
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
vendor
|
||||
.phpunit.result.cache
|
||||
.idea
|
||||
45
composer.json
Normal file
45
composer.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "ghostzero/bitinflow-accounts",
|
||||
"description": "bitinflow Accounts Client for Laravel",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "René Preuß",
|
||||
"email": "rene@preuss.io"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"illuminate/support": "^5.5",
|
||||
"illuminate/console": "^5.5",
|
||||
"guzzlehttp/guzzle": "^6.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.0",
|
||||
"orchestra/testbench": "~3.8.0",
|
||||
"codedungeon/phpunit-result-printer": "^0.26.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GhostZero\\BitinflowAccounts\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"GhostZero\\BitinflowAccounts\\Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vendor/bin/phpunit"
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"GhostZero\\BitinflowAccounts\\Providers\\BitinflowAccountsServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"BitinflowAccounts": "GhostZero\\BitinflowAccounts\\Facades\\BitinflowAccounts"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
4816
composer.lock
generated
Normal file
4816
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
7
config/bitinflow-accounts-api.php
Normal file
7
config/bitinflow-accounts-api.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'client_id' => env('BITINFLOW_ACCOUNTS_KEY', ''),
|
||||
'client_secret' => env('BITINFLOW_ACCOUNTS_SECRET', ''),
|
||||
'redirect_url' => env('BITINFLOW_ACCOUNTS_REDIRECT_URI', ''),
|
||||
];
|
||||
28
phpunit.xml
Normal file
28
phpunit.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit bootstrap="vendor/autoload.php"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
verbose="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
printerClass="\Codedungeon\PHPUnitPrettyResultPrinter\Printer">
|
||||
<testsuites>
|
||||
<testsuite name="Unit">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<php>
|
||||
<env name="CLIENT_ID" value="30" force="true" />
|
||||
<env name="CLIENT_KEY" value="E9p7Ieb4fCwWnipNgQUxE6LtInAP9i4ofHCPAx3E" force="true" />
|
||||
<env name="CLIENT_ACCESS_TOKEN" value="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjFlOTU5Mzc2NDdlNDU4MmNjNGNjOTFhY2YwNjQzNTM3ZGI0NTE3ZTg0ODJkMjNiZTFjYTYwNjc0MmQyZjk1NmY5NmE3ZTk1YzFmODBiYjAyIn0.eyJhdWQiOiIxOCIsImp0aSI6IjFlOTU5Mzc2NDdlNDU4MmNjNGNjOTFhY2YwNjQzNTM3ZGI0NTE3ZTg0ODJkMjNiZTFjYTYwNjc0MmQyZjk1NmY5NmE3ZTk1YzFmODBiYjAyIiwiaWF0IjoxNTY3MjQ4MTU0LCJuYmYiOjE1NjcyNDgxNTQsImV4cCI6MTU5ODg3MDU1NCwic3ViIjoiMzgiLCJzY29wZXMiOlsicmVhZF91c2VyIiwiYXBpIl19.IROsZlKhIqeFhQfz0PVGb6pUvuukOaShDNui8ArTb9WHy-z7BJha-50YWAgdGUb7IEX-5zBBiouvlnUb789O81hi2ZkPCcgHMw5zapXRaIwbKOMMjPy9-dLXtRz285bki4AuEz0jCyFVXemTIePPMSCdoOT2ZjN3jv18WpoOxEKr8RZK5Cy0LRQkbcWqbVU8rGdtxdiTwe0LDOwuf9N6s4I7FJJ5bEU7i7h3CYw7KX08sUURLerK9zm0BAJmKW_QtMBMVlzVLw42A8MrkfspSY9lCIkzWMLYpZoVHZkavW3_xJ2X0K9WLS9KJTysqS3jm_DBwWUh80mqfoCW8ubwELcoxp-NevlV5RMieu-8tB45xz-wMLYuHrN-5NH3M-_o_G5TTl7cdevYUsLnloQIc2IvEJDsSgDN3LxFI5eQdtnQAtjboVJ9RC670bqAlyIyd2EXk1Ptw8xZU9JmQKt2EzG0VpK0COnjGdaGMAF_tDHhgekTHIe8cKumrf65dFWImkuH-HlPxM4V-P8IZZLWNCtFsIOXuA4Pwkxlgv5S8pS0jbrMWP3j-ngpI0_2pSLO__rG5Bc-EjPC5ch6nyyuxPdyFtSwWSc_97a0sSNYtpzinihStJvN5_dqOL5vD18Sc0gnm3tS_DRDmuZBcKwvCXg3TuvnrG-ttwpXClX67YY" force="true" />
|
||||
</php>
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
12
src/ApiOperations/Delete.php
Normal file
12
src/ApiOperations/Delete.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\ApiOperations;
|
||||
|
||||
use GhostZero\BitinflowAccounts\Helpers\Paginator;
|
||||
|
||||
trait Delete
|
||||
{
|
||||
abstract public function delete(string $path = '', array $parameters = [], Paginator $paginator = null);
|
||||
}
|
||||
12
src/ApiOperations/Get.php
Normal file
12
src/ApiOperations/Get.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\ApiOperations;
|
||||
|
||||
use GhostZero\BitinflowAccounts\Helpers\Paginator;
|
||||
|
||||
trait Get
|
||||
{
|
||||
abstract public function get(string $path = '', array $parameters = [], Paginator $paginator = null);
|
||||
}
|
||||
12
src/ApiOperations/Post.php
Normal file
12
src/ApiOperations/Post.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\ApiOperations;
|
||||
|
||||
use GhostZero\BitinflowAccounts\Helpers\Paginator;
|
||||
|
||||
trait Post
|
||||
{
|
||||
abstract public function post(string $path = '', array $parameters = [], Paginator $paginator = null);
|
||||
}
|
||||
12
src/ApiOperations/Put.php
Normal file
12
src/ApiOperations/Put.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\ApiOperations;
|
||||
|
||||
use GhostZero\BitinflowAccounts\Helpers\Paginator;
|
||||
|
||||
trait Put
|
||||
{
|
||||
abstract public function put(string $path = '', array $parameters = [], Paginator $paginator = null);
|
||||
}
|
||||
392
src/BitinflowAccounts.php
Normal file
392
src/BitinflowAccounts.php
Normal file
@@ -0,0 +1,392 @@
|
||||
<?php
|
||||
|
||||
namespace GhostZero\BitinflowAccounts;
|
||||
|
||||
use GhostZero\BitinflowAccounts\Exceptions\RequestRequiresAuthenticationException;
|
||||
use GhostZero\BitinflowAccounts\Exceptions\RequestRequiresClientIdException;
|
||||
use GhostZero\BitinflowAccounts\Exceptions\RequestRequiresRedirectUriException;
|
||||
use GhostZero\BitinflowAccounts\Helpers\Paginator;
|
||||
use GhostZero\BitinflowAccounts\Traits;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
class BitinflowAccounts
|
||||
{
|
||||
|
||||
use Traits\UsersTrait;
|
||||
use Traits\SshKeysTrait;
|
||||
|
||||
const BASE_URI = 'https://accounts.bitinflow.com/api/';
|
||||
const OAUTH_BASE_URI = 'https://accounts.bitinflow.com/api/';
|
||||
|
||||
/**
|
||||
* Guzzle is used to make http requests.
|
||||
* @var \GuzzleHttp\Client
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* Paginator object.
|
||||
* @var Paginator
|
||||
*/
|
||||
protected $paginator;
|
||||
|
||||
/**
|
||||
* bitinflow Accounts OAuth token.
|
||||
* @var string|null
|
||||
*/
|
||||
protected $token = null;
|
||||
|
||||
/**
|
||||
* bitinflow Accounts client id.
|
||||
* @var string|null
|
||||
*/
|
||||
protected $clientId = null;
|
||||
|
||||
/**
|
||||
* bitinflow Accounts client secret.
|
||||
* @var string|null
|
||||
*/
|
||||
protected $clientSecret = null;
|
||||
|
||||
/**
|
||||
* bitinflow Accounts OAuth redirect url.
|
||||
* @var string|null
|
||||
*/
|
||||
protected $redirectUri = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if ($clientId = config('bitinflow-accounts-api.client_id')) {
|
||||
$this->setClientId($clientId);
|
||||
}
|
||||
if ($clientSecret = config('bitinflow-accounts-api.client_secret')) {
|
||||
$this->setClientSecret($clientSecret);
|
||||
}
|
||||
if ($redirectUri = config('bitinflow-accounts-api.redirect_url')) {
|
||||
$this->setRedirectUri($redirectUri);
|
||||
}
|
||||
$this->client = new Client([
|
||||
'base_uri' => self::BASE_URI,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get client id.
|
||||
* @return string
|
||||
* @throws RequestRequiresClientIdException
|
||||
*/
|
||||
public function getClientId(): string
|
||||
{
|
||||
if (!$this->clientId) {
|
||||
throw new RequestRequiresClientIdException;
|
||||
}
|
||||
|
||||
return $this->clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set client id.
|
||||
*
|
||||
* @param string $clientId bitinflow Accounts client id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClientId(string $clientId): void
|
||||
{
|
||||
$this->clientId = $clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fluid client id setter.
|
||||
*
|
||||
* @param string $clientId bitinflow Accounts client id.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function withClientId(string $clientId): self
|
||||
{
|
||||
$this->setClientId($clientId);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get client secret.
|
||||
* @return string
|
||||
* @throws RequestRequiresClientIdException
|
||||
*/
|
||||
public function getClientSecret(): string
|
||||
{
|
||||
if (!$this->clientSecret) {
|
||||
throw new RequestRequiresClientIdException;
|
||||
}
|
||||
|
||||
return $this->clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set client secret.
|
||||
*
|
||||
* @param string $clientSecret bitinflow Accounts client secret
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClientSecret(string $clientSecret): void
|
||||
{
|
||||
$this->clientSecret = $clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fluid client secret setter.
|
||||
*
|
||||
* @param string $clientSecret bitinflow Accounts client secret
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function withClientSecret(string $clientSecret): self
|
||||
{
|
||||
$this->setClientSecret($clientSecret);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get redirect url.
|
||||
* @return string
|
||||
* @throws RequestRequiresRedirectUriException
|
||||
*/
|
||||
public function getRedirectUri(): string
|
||||
{
|
||||
if (!$this->redirectUri) {
|
||||
throw new RequestRequiresRedirectUriException;
|
||||
}
|
||||
|
||||
return $this->redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set redirect url.
|
||||
*
|
||||
* @param string $redirectUri
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setRedirectUri(string $redirectUri): void
|
||||
{
|
||||
$this->redirectUri = $redirectUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fluid redirect url setter.
|
||||
*
|
||||
* @param string $redirectUri
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function withRedirectUri(string $redirectUri): self
|
||||
{
|
||||
$this->setRedirectUri($redirectUri);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OAuth token.
|
||||
* @return string bitinflow Accounts token
|
||||
* @return string|null
|
||||
* @throws RequestRequiresAuthenticationException
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
if (!$this->token) {
|
||||
throw new RequestRequiresAuthenticationException;
|
||||
}
|
||||
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set OAuth token.
|
||||
*
|
||||
* @param string $token bitinflow Accounts OAuth token
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setToken(string $token): void
|
||||
{
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fluid OAuth token setter.
|
||||
*
|
||||
* @param string $token bitinflow Accounts OAuth token
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function withToken(string $token): self
|
||||
{
|
||||
$this->setToken($token);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
* @param Paginator|null $paginator
|
||||
*
|
||||
* @return Result
|
||||
* @throws GuzzleException
|
||||
* @throws RequestRequiresClientIdException
|
||||
*/
|
||||
public function get(string $path = '', array $parameters = [], Paginator $paginator = null)
|
||||
{
|
||||
return $this->query('GET', $path, $parameters, $paginator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
* @param Paginator|null $paginator
|
||||
*
|
||||
* @return Result
|
||||
* @throws GuzzleException
|
||||
* @throws RequestRequiresClientIdException
|
||||
*/
|
||||
public function post(string $path = '', array $parameters = [], Paginator $paginator = null)
|
||||
{
|
||||
return $this->query('POST', $path, $parameters, $paginator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
* @param Paginator|null $paginator
|
||||
*
|
||||
* @return Result
|
||||
* @throws GuzzleException
|
||||
* @throws RequestRequiresClientIdException
|
||||
*/
|
||||
public function delete(string $path = '', array $parameters = [], Paginator $paginator = null)
|
||||
{
|
||||
return $this->query('DELETE', $path, $parameters, $paginator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param array $parameters
|
||||
* @param Paginator|null $paginator
|
||||
*
|
||||
* @return Result
|
||||
* @throws GuzzleException
|
||||
* @throws RequestRequiresClientIdException
|
||||
*/
|
||||
public function put(string $path = '', array $parameters = [], Paginator $paginator = null)
|
||||
{
|
||||
return $this->query('PUT', $path, $parameters, $paginator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $path
|
||||
* @param array|null $body
|
||||
*
|
||||
* @return Result
|
||||
* @throws GuzzleException
|
||||
* @throws RequestRequiresClientIdException
|
||||
*/
|
||||
public function json(string $method, string $path = '', array $body = null)
|
||||
{
|
||||
if ($body) {
|
||||
$body = json_encode(['data' => $body]);
|
||||
}
|
||||
|
||||
return $this->query($method, $path, [], null, $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build query & execute.
|
||||
*
|
||||
* @param string $method HTTP method
|
||||
* @param string $path Query path
|
||||
* @param array $parameters Query parameters
|
||||
* @param Paginator $paginator Paginator object
|
||||
* @param mixed|null $jsonBody JSON data
|
||||
*
|
||||
* @return Result Result object
|
||||
* @throws GuzzleException
|
||||
* @throws RequestRequiresClientIdException
|
||||
*/
|
||||
public function query(string $method = 'GET', string $path = '', array $parameters = [], Paginator $paginator = null, $jsonBody = null): Result
|
||||
{
|
||||
if ($paginator !== null) {
|
||||
$parameters[$paginator->action] = $paginator->cursor();
|
||||
}
|
||||
try {
|
||||
$response = $this->client->request($method, $path, [
|
||||
'headers' => $this->buildHeaders($jsonBody ? true : false),
|
||||
'query' => $this->buildQuery($parameters),
|
||||
'json' => $jsonBody ? $jsonBody : null,
|
||||
]);
|
||||
$result = new Result($response, null, $paginator);
|
||||
} catch (RequestException $exception) {
|
||||
$result = new Result($exception->getResponse(), $exception, $paginator);
|
||||
}
|
||||
$result->bitinflow = $this;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build query with support for multiple smae first-dimension keys.
|
||||
*
|
||||
* @param array $query
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function buildQuery(array $query): string
|
||||
{
|
||||
$parts = [];
|
||||
foreach ($query as $name => $value) {
|
||||
$value = (array) $value;
|
||||
array_walk_recursive($value, function ($value) use (&$parts, $name) {
|
||||
$parts[] = urlencode($name) . '=' . urlencode($value);
|
||||
});
|
||||
}
|
||||
|
||||
return implode('&', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build headers for request.
|
||||
*
|
||||
* @param bool $json Body is JSON
|
||||
*
|
||||
* @return array
|
||||
* @throws RequestRequiresClientIdException
|
||||
*/
|
||||
private function buildHeaders(bool $json = false): array
|
||||
{
|
||||
$headers = [
|
||||
'Client-ID' => $this->getClientId(),
|
||||
];
|
||||
if ($this->token) {
|
||||
$headers['Authorization'] = 'Bearer ' . $this->token;
|
||||
}
|
||||
if ($json) {
|
||||
$headers['Content-Type'] = 'application/json';
|
||||
$headers['Accept'] = 'application/json';
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
}
|
||||
18
src/Exceptions/RateLimitException.php
Normal file
18
src/Exceptions/RateLimitException.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
class RateLimitException extends Exception
|
||||
{
|
||||
public function __construct($message = 'Rate Limit exceeded', $code = 0, Exception $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
18
src/Exceptions/RequestRequiresAuthenticationException.php
Normal file
18
src/Exceptions/RequestRequiresAuthenticationException.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
class RequestRequiresAuthenticationException extends Exception
|
||||
{
|
||||
public function __construct($message = 'Request requires authentication', $code = 0, Exception $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
18
src/Exceptions/RequestRequiresClientIdException.php
Normal file
18
src/Exceptions/RequestRequiresClientIdException.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
class RequestRequiresClientIdException extends Exception
|
||||
{
|
||||
public function __construct($message = 'Request requires Client-ID', $code = 0, Exception $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
18
src/Exceptions/RequestRequiresParameter.php
Normal file
18
src/Exceptions/RequestRequiresParameter.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
class RequestRequiresParameter extends Exception
|
||||
{
|
||||
public function __construct($message = 'Request requires parameters', $code = 0, Exception $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
18
src/Exceptions/RequestRequiresRedirectUriException.php
Normal file
18
src/Exceptions/RequestRequiresRedirectUriException.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
class RequestRequiresRedirectUriException extends Exception
|
||||
{
|
||||
public function __construct($message = 'Request requires redirect uri', $code = 0, Exception $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
20
src/Facades/BitinflowAccounts.php
Normal file
20
src/Facades/BitinflowAccounts.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Facades;
|
||||
|
||||
use GhostZero\BitinflowAccounts\BitinflowAccounts as BitinflowAccountsService;
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
class BitinflowAccounts extends Facade
|
||||
{
|
||||
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return BitinflowAccountsService::class;
|
||||
}
|
||||
}
|
||||
91
src/Helpers/Paginator.php
Normal file
91
src/Helpers/Paginator.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Helpers;
|
||||
|
||||
use GhostZero\BitinflowAccounts\Result;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
class Paginator
|
||||
{
|
||||
|
||||
/**
|
||||
* bitinflow Accounts response pagination cursor.
|
||||
* @var null|stdClass
|
||||
*/
|
||||
private $pagination;
|
||||
|
||||
/**
|
||||
* Next desired action (first, after, before).
|
||||
* @var null|string
|
||||
*/
|
||||
public $action = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param null|stdClass $pagination bitinflow Accounts response pagination cursor
|
||||
*/
|
||||
public function __construct(stdClass $pagination = null)
|
||||
{
|
||||
$this->pagination = $pagination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Paginator from Result object.
|
||||
*
|
||||
* @param Result $result Result object
|
||||
*
|
||||
* @return self Paginator object
|
||||
*/
|
||||
public static function from(Result $result): self
|
||||
{
|
||||
return new self($result->pagination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current active cursor.
|
||||
* @return string bitinflow Accounts cursor
|
||||
*/
|
||||
public function cursor(): string
|
||||
{
|
||||
return $this->pagination->cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Paginator to fetch the next set of results.
|
||||
* @return self
|
||||
*/
|
||||
public function first(): self
|
||||
{
|
||||
$this->action = 'first';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Paginator to fetch the first set of results.
|
||||
* @return self
|
||||
*/
|
||||
public function next(): self
|
||||
{
|
||||
$this->action = 'after';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Paginator to fetch the last set of results.
|
||||
* @return self
|
||||
*/
|
||||
public function back(): self
|
||||
{
|
||||
$this->action = 'before';
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
46
src/Providers/BitinflowAccountsServiceProvider.php
Normal file
46
src/Providers/BitinflowAccountsServiceProvider.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Providers;
|
||||
|
||||
use GhostZero\BitinflowAccounts\BitinflowAccounts;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BitinflowAccountsServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->publishes([
|
||||
dirname(__DIR__) . '/../config/bitinflow-accounts-api.php' => config_path('bitinflow-accounts-api.php'),
|
||||
], 'config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the application services.
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->mergeConfigFrom(
|
||||
dirname(__DIR__) . '/../config/bitinflow-accounts-api.php', 'bitinflow-accounts-api'
|
||||
);
|
||||
$this->app->singleton(BitinflowAccounts::class, function () {
|
||||
return new BitinflowAccounts;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
* @return array
|
||||
*/
|
||||
public function provides()
|
||||
{
|
||||
return [BitinflowAccounts::class];
|
||||
}
|
||||
}
|
||||
251
src/Result.php
Normal file
251
src/Result.php
Normal file
@@ -0,0 +1,251 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts;
|
||||
|
||||
use Exception;
|
||||
use GhostZero\BitinflowAccounts\Helpers\Paginator;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use stdClass;
|
||||
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
class Result
|
||||
{
|
||||
|
||||
/**
|
||||
* Query successfull.
|
||||
* @var boolean
|
||||
*/
|
||||
public $success = false;
|
||||
|
||||
/**
|
||||
* Guzzle exception, if present.
|
||||
* @var null|mixed
|
||||
*/
|
||||
public $exception = null;
|
||||
|
||||
/**
|
||||
* Query result data.
|
||||
* @var array
|
||||
*/
|
||||
public $data = [];
|
||||
|
||||
/**
|
||||
* Total amount of result data.
|
||||
* @var integer
|
||||
*/
|
||||
public $total = 0;
|
||||
|
||||
/**
|
||||
* Status Code.
|
||||
* @var integer
|
||||
*/
|
||||
public $status = 0;
|
||||
|
||||
/**
|
||||
* bitinflow Accounts response pagination cursor.
|
||||
* @var null|\stdClass
|
||||
*/
|
||||
public $pagination;
|
||||
|
||||
/**
|
||||
* Internal paginator.
|
||||
* @var null|Paginator
|
||||
*/
|
||||
public $paginator;
|
||||
|
||||
/**
|
||||
* Original Guzzle HTTP Response.
|
||||
* @var Response
|
||||
*/
|
||||
public $response;
|
||||
|
||||
/**
|
||||
* Original bitinflow Accounts instance.
|
||||
* @var BitinflowAccounts
|
||||
*/
|
||||
public $bitinflow;
|
||||
|
||||
/**
|
||||
* Constructor,
|
||||
*
|
||||
* @param Response $response HTTP response
|
||||
* @param Exception|mixed $exception Exception, if present
|
||||
* @param null|Paginator $paginator Paginator, if present
|
||||
*/
|
||||
public function __construct(Response $response, Exception $exception = null, Paginator $paginator = null)
|
||||
{
|
||||
$this->response = $response;
|
||||
$this->success = $exception === null;
|
||||
$this->exception = $exception;
|
||||
$this->status = $response->getStatusCode();
|
||||
$jsonResponse = @json_decode($response->getBody()->getContents());
|
||||
if ($jsonResponse !== null) {
|
||||
$this->setProperty($jsonResponse, 'data');
|
||||
$this->setProperty($jsonResponse, 'total');
|
||||
$this->setProperty($jsonResponse, 'pagination');
|
||||
$this->paginator = Paginator::from($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a class attribute by given JSON Response Body.
|
||||
*
|
||||
* @param stdClass $jsonResponse Response Body
|
||||
* @param string $responseProperty Response property name
|
||||
* @param string|null $attribute Class property name
|
||||
*/
|
||||
private function setProperty(stdClass $jsonResponse, string $responseProperty, string $attribute = null)
|
||||
{
|
||||
$classAttribute = $attribute ?? $responseProperty;
|
||||
if (!empty($jsonResponse) && property_exists($jsonResponse, $responseProperty)) {
|
||||
$this->{$classAttribute} = $jsonResponse->{$responseProperty};
|
||||
} elseif ($responseProperty === 'data') {
|
||||
$this->{$classAttribute} = $jsonResponse;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns wether the query was successfull.
|
||||
* @return bool Success state
|
||||
*/
|
||||
public function success(): bool
|
||||
{
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response data, also available as public attribute.
|
||||
* @return mixed
|
||||
*/
|
||||
public function data()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last HTTP or API error.
|
||||
* @return string Error message
|
||||
*/
|
||||
public function error(): string
|
||||
{
|
||||
// TODO Switch Exception response parsing to this->data
|
||||
if ($this->exception === null || !$this->exception->hasResponse()) {
|
||||
return 'bitinflow Accounts API Unavailable';
|
||||
}
|
||||
$exception = (string) $this->exception->getResponse()->getBody();
|
||||
$exception = @json_decode($exception);
|
||||
if (property_exists($exception, 'message') && !empty($exception->message)) {
|
||||
return $exception->message;
|
||||
}
|
||||
|
||||
return $this->exception->getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shifts the current result (Use for single user/video etc. query).
|
||||
* @return mixed Shifted data
|
||||
*/
|
||||
public function shift()
|
||||
{
|
||||
if (!empty($this->data)) {
|
||||
$data = $this->data;
|
||||
|
||||
return array_shift($data);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current count of items in dataset.
|
||||
* @return int Count
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
return count((array) $this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Paginator to fetch the first set of results.
|
||||
* @return null|Paginator
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
return $this->paginator !== null ? $this->paginator->first() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Paginator to fetch the next set of results.
|
||||
* @return null|Paginator
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
return $this->paginator !== null ? $this->paginator->next() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Paginator to fetch the last set of results.
|
||||
* @return null|Paginator
|
||||
*/
|
||||
public function back()
|
||||
{
|
||||
return $this->paginator !== null ? $this->paginator->back() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rate limit information.
|
||||
*
|
||||
* @param string|null $key Get defined index
|
||||
*
|
||||
* @return string|array|null
|
||||
*/
|
||||
public function rateLimit(string $key = null)
|
||||
{
|
||||
if (!$this->response) {
|
||||
return null;
|
||||
}
|
||||
$rateLimit = [
|
||||
'limit' => (int) $this->response->getHeaderLine('X-RateLimit-Limit'),
|
||||
'remaining' => (int) $this->response->getHeaderLine('X-RateLimit-Remaining'),
|
||||
'reset' => (int) $this->response->getHeaderLine('Retry-After'),
|
||||
];
|
||||
if ($key === null) {
|
||||
return $rateLimit;
|
||||
}
|
||||
|
||||
return $rateLimit[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert users in data response.
|
||||
*
|
||||
* @param string $identifierAttribute Attribute to identify the users
|
||||
* @param string $insertTo Data index to insert user data
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function insertUsers(string $identifierAttribute = 'user_id', string $insertTo = 'user'): self
|
||||
{
|
||||
$data = $this->data;
|
||||
$userIds = collect($data)->map(function ($item) use ($identifierAttribute) {
|
||||
return $item->{$identifierAttribute};
|
||||
})->toArray();
|
||||
if (count($userIds) == 0) {
|
||||
return $this;
|
||||
}
|
||||
$users = collect($this->bitinflow->getUsersByIds($userIds)->data);
|
||||
$dataWithUsers = collect($data)->map(function ($item) use ($users, $identifierAttribute, $insertTo) {
|
||||
$item->$insertTo = $users->where('id', $item->{$identifierAttribute})->first();
|
||||
|
||||
return $item;
|
||||
});
|
||||
$this->data = $dataWithUsers->toArray();
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
56
src/Traits/SshKeysTrait.php
Normal file
56
src/Traits/SshKeysTrait.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Traits;
|
||||
|
||||
use GhostZero\BitinflowAccounts\ApiOperations\Delete;
|
||||
use GhostZero\BitinflowAccounts\ApiOperations\Get;
|
||||
use GhostZero\BitinflowAccounts\ApiOperations\Post;
|
||||
use GhostZero\BitinflowAccounts\Result;
|
||||
|
||||
trait SshKeysTrait
|
||||
{
|
||||
|
||||
use Get, Post, Delete;
|
||||
|
||||
/**
|
||||
* Get currently authed user with Bearer Token
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @return Result Result object
|
||||
*/
|
||||
public function getSshKeysByUserId(int $id): Result
|
||||
{
|
||||
return $this->get("users/$id/keys/json", [], null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get currently authed user with Bearer Token
|
||||
*
|
||||
* @param string $publicKey
|
||||
* @param string|null $name
|
||||
*
|
||||
* @return Result Result object
|
||||
*/
|
||||
public function createSshKey(string $publicKey, string $name = null): Result
|
||||
{
|
||||
return $this->post('ssh-keys', [
|
||||
'public_key' => $publicKey,
|
||||
'name' => $name,
|
||||
], null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get currently authed user with Bearer Token
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @return Result Result object
|
||||
*/
|
||||
public function deleteSshKey(int $id): Result
|
||||
{
|
||||
return $this->delete("ssh-keys/$id", [], null);
|
||||
}
|
||||
}
|
||||
23
src/Traits/UsersTrait.php
Normal file
23
src/Traits/UsersTrait.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Traits;
|
||||
|
||||
use GhostZero\BitinflowAccounts\ApiOperations\Get;
|
||||
use GhostZero\BitinflowAccounts\Result;
|
||||
|
||||
trait UsersTrait
|
||||
{
|
||||
|
||||
use Get;
|
||||
|
||||
/**
|
||||
* Get currently authed user with Bearer Token
|
||||
* @return Result Result object
|
||||
*/
|
||||
public function getAuthedUser(): Result
|
||||
{
|
||||
return $this->get('users/me', [], null);
|
||||
}
|
||||
}
|
||||
42
tests/ApiSshKeysTest.php
Normal file
42
tests/ApiSshKeysTest.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Tests;
|
||||
|
||||
use GhostZero\BitinflowAccounts\Result;
|
||||
use GhostZero\BitinflowAccounts\Tests\TestCases\ApiTestCase;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
class ApiSshKeysTest extends ApiTestCase
|
||||
{
|
||||
|
||||
public function testGetSshKeyByUserId()
|
||||
{
|
||||
$this->registerResult($result = $this->getClient()->getSshKeysByUserId(38));
|
||||
$this->assertInstanceOf(Result::class, $result);
|
||||
$this->assertEquals('rene.preuss@check24.de', $result->shift()->name);
|
||||
$this->assertGreaterThanOrEqual(2, $result->count());
|
||||
}
|
||||
|
||||
public function testSshKeyManagement()
|
||||
{
|
||||
$customName = 'Hello World!';
|
||||
$publicKey = 'ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEA3H7sYVrVCwwYIuRm3on3S9n/BCd2mBJrgCk6xTerbNmt0RyUZ+RtGsK6UYkgnRR2WWq9/Pv2s3RXJXPxbsIEYmKCcTdLUvDk56x9385cIVUX4w016mpe/8lyu+mIdqWYKsJMoab0oReCDX8Y9qBcaffDh8AgmYVN+86gXgoP1ITe9BDYrFiR6U571VyLDVN3OYOYPMF3/L9f0knMfM0T4LrS8oi6faVBCxZHRoBGtGmsTBkE0KwplYQFN2aa4Mxab+rTUFmJr3LYEcJF0J8wNJ3eEDFNOR0254jrjbGGAXGsc+cxJoNzech+GBkRMKMpNU0lds6VxP0ZB25VfzjEmQ== René Preuß';
|
||||
|
||||
$this->getClient()->withToken($this->getToken());
|
||||
$this->registerResult($result = $this->getClient()->createSshKey($publicKey, $customName));
|
||||
$this->assertInstanceOf(Result::class, $result);
|
||||
$this->assertEquals('6b:fa:33:da:6c:3a:08:05:6f:71:8b:d8:ed:06:37:b6', $result->data()->fingerprint);
|
||||
$this->assertEquals($customName, $result->data()->name);
|
||||
|
||||
$keyId = $result->data()->id;
|
||||
|
||||
$this->getClient()->withToken($this->getToken());
|
||||
$this->registerResult($result = $this->getClient()->deleteSshKey($keyId));
|
||||
$this->assertInstanceOf(Result::class, $result);
|
||||
$this->assertTrue($result->success());
|
||||
}
|
||||
}
|
||||
23
tests/ApiUsersTest.php
Normal file
23
tests/ApiUsersTest.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Tests;
|
||||
|
||||
use GhostZero\BitinflowAccounts\Result;
|
||||
use GhostZero\BitinflowAccounts\Tests\TestCases\ApiTestCase;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
class ApiUsersTest extends ApiTestCase
|
||||
{
|
||||
|
||||
public function testGetAuthedUser()
|
||||
{
|
||||
$this->getClient()->withToken($this->getToken());
|
||||
$this->registerResult($result = $this->getClient()->getAuthedUser());
|
||||
$this->assertInstanceOf(Result::class, $result);
|
||||
$this->assertEquals('rene@preuss.io', $result->data()->email);
|
||||
}
|
||||
}
|
||||
26
tests/ServiceInstantiationTest.php
Normal file
26
tests/ServiceInstantiationTest.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Tests;
|
||||
|
||||
use GhostZero\BitinflowAccounts\BitinflowAccounts;
|
||||
use GhostZero\BitinflowAccounts\Facades\BitinflowAccounts as BitinflowAccountsFacade;
|
||||
use GhostZero\BitinflowAccounts\Tests\TestCases\TestCase;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
class ServiceInstantiationTest extends TestCase
|
||||
{
|
||||
|
||||
public function testInstance()
|
||||
{
|
||||
$this->assertInstanceOf(BitinflowAccounts::class, app(BitinflowAccounts::class));
|
||||
}
|
||||
|
||||
public function testFacade()
|
||||
{
|
||||
$this->assertInstanceOf(BitinflowAccounts::class, BitinflowAccountsFacade::getFacadeRoot());
|
||||
}
|
||||
}
|
||||
56
tests/TestCases/ApiTestCase.php
Normal file
56
tests/TestCases/ApiTestCase.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Tests\TestCases;
|
||||
|
||||
use GhostZero\BitinflowAccounts\BitinflowAccounts;
|
||||
use GhostZero\BitinflowAccounts\Result;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
abstract class ApiTestCase extends TestCase
|
||||
{
|
||||
|
||||
protected static $rateLimitRemaining = null;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
if (!$this->getClientId()) {
|
||||
$this->markTestSkipped('No Client-ID given');
|
||||
}
|
||||
if (self::$rateLimitRemaining !== null && self::$rateLimitRemaining < 3) {
|
||||
$this->markTestSkipped('Rate Limit exceeded (' . self::$rateLimitRemaining . ')');
|
||||
}
|
||||
$this->getClient()->setClientId($this->getClientId());
|
||||
}
|
||||
|
||||
protected function registerResult(Result $result): Result
|
||||
{
|
||||
self::$rateLimitRemaining = $result->rateLimit('remaining');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getClientId()
|
||||
{
|
||||
return getenv('CLIENT_ID');
|
||||
}
|
||||
|
||||
protected function getClientSecret()
|
||||
{
|
||||
return getenv('CLIENT_KEY');
|
||||
}
|
||||
|
||||
protected function getToken()
|
||||
{
|
||||
return getenv('CLIENT_ACCESS_TOKEN');
|
||||
}
|
||||
|
||||
public function getClient(): BitinflowAccounts
|
||||
{
|
||||
return app(BitinflowAccounts::class);
|
||||
}
|
||||
}
|
||||
30
tests/TestCases/TestCase.php
Normal file
30
tests/TestCases/TestCase.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GhostZero\BitinflowAccounts\Tests\TestCases;
|
||||
|
||||
use GhostZero\BitinflowAccounts\BitinflowAccounts;
|
||||
use GhostZero\BitinflowAccounts\Providers\BitinflowAccountsServiceProvider;
|
||||
use Orchestra\Testbench\TestCase as BaseTestCase;
|
||||
|
||||
/**
|
||||
* @author René Preuß <rene@preuss.io>
|
||||
*/
|
||||
abstract class TestCase extends BaseTestCase
|
||||
{
|
||||
|
||||
protected function getPackageProviders($app)
|
||||
{
|
||||
return [
|
||||
BitinflowAccountsServiceProvider::class,
|
||||
];
|
||||
}
|
||||
|
||||
protected function getPackageAliases($app)
|
||||
{
|
||||
return [
|
||||
'BitinflowAccounts' => BitinflowAccounts::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user