From aa75e7d3ceb1598df110a974b48edbb483cad38e Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Sat, 4 May 2019 14:48:25 +0200 Subject: [PATCH] chore: add thecodingmachine/safe package (#2630) --- app/Console/Commands/ImportCSV.php | 39 ++-- app/Console/Commands/PingVersionServer.php | 1 + app/Console/Commands/SentryRelease.php | 2 + app/Console/Commands/SetupProduction.php | 1 + app/Helpers/ComposerScripts.php | 2 + app/Helpers/DateHelper.php | 1 + app/Helpers/InstanceHelper.php | 2 + app/Helpers/LocaleHelper.php | 2 + app/Helpers/SearchHelper.php | 1 + app/Helpers/TimezoneHelper.php | 1 + app/Http/Controllers/Api/ApiController.php | 16 +- .../Controllers/Api/Auth/OAuthController.php | 1 + app/Http/Controllers/DashboardController.php | 1 + .../Settings/MultiFAController.php | 1 + app/Models/Account/Place.php | 6 +- app/Models/Contact/Contact.php | 1 + .../Geolocalization/GetGPSCoordinate.php | 1 + .../Weather/GetWeatherInformation.php | 1 + app/Services/VCard/ImportVCard.php | 2 + composer.json | 2 + composer.lock | 184 +++++++++++++++++- config/passport.php | 2 + database/factories/ModelFactory.php | 1 + database/seeds/CurrenciesTableSeeder.php | 1 + database/seeds/FakeContentTableSeeder.php | 1 + phpstan.neon | 2 + resources/views/auth/validateu2f.blade.php | 4 +- resources/views/layouts/skeleton.blade.php | 2 +- resources/views/marketing/auth.blade.php | 2 +- resources/views/people/_header.blade.php | 4 +- .../views/people/documents/index.blade.php | 2 +- resources/views/people/edit.blade.php | 2 +- resources/views/people/photos/index.blade.php | 2 +- resources/views/people/profile.blade.php | 2 +- .../views/people/relationship/edit.blade.php | 2 +- resources/views/settings/index.blade.php | 4 +- .../settings/personalization/index.blade.php | 4 +- .../views/settings/security/index.blade.php | 6 +- .../settings/security/u2f-enable.blade.php | 6 +- tests/Api/Account/ApiUserControllerTest.php | 7 +- .../Contact/ApiLifeEventControllerTest.php | 4 +- tests/Commands/ImportCSVTest.php | 92 +++++++++ tests/Unit/Helpers/InstanceHelperTest.php | 1 + tests/stubs/single_contact_stub.csv | 2 + 44 files changed, 368 insertions(+), 55 deletions(-) create mode 100644 tests/Commands/ImportCSVTest.php create mode 100644 tests/stubs/single_contact_stub.csv diff --git a/app/Console/Commands/ImportCSV.php b/app/Console/Commands/ImportCSV.php index 545cc19b9..1a28fe560 100644 --- a/app/Console/Commands/ImportCSV.php +++ b/app/Console/Commands/ImportCSV.php @@ -2,7 +2,9 @@ namespace App\Console\Commands; +use function Safe\fopen; use App\Models\User\User; +use function Safe\fclose; use App\Helpers\DateHelper; use App\Models\Contact\Gender; use App\Models\Contact\Address; @@ -87,27 +89,26 @@ class ImportCSV extends Command $first = true; $imported = 0; - if (($handle = fopen($file, 'r')) !== false) { - try { - while (($data = fgetcsv($handle)) !== false) { - // don't import the columns - if ($first) { - $first = false; - continue; - } - - // if first & last name do not exist skip row - if (empty($data[1]) && empty($data[3])) { - continue; - } - - $this->csvToContact($data, $user->account_id, $gender->id); - - $imported++; + try { + $handle = fopen($file, 'r'); + while (($data = fgetcsv($handle)) !== false) { + // don't import the columns + if ($first) { + $first = false; + continue; } - } finally { - fclose($handle); + + // if first & last name do not exist skip row + if (empty($data[1]) && empty($data[3])) { + continue; + } + + $this->csvToContact($data, $user->account_id, $gender->id); + + $imported++; } + } finally { + fclose($handle); } $this->info("Imported {$imported} Contacts"); diff --git a/app/Console/Commands/PingVersionServer.php b/app/Console/Commands/PingVersionServer.php index bf6f711db..3c314d563 100644 --- a/app/Console/Commands/PingVersionServer.php +++ b/app/Console/Commands/PingVersionServer.php @@ -3,6 +3,7 @@ namespace App\Console\Commands; use GuzzleHttp\Client; +use function Safe\json_decode; use App\Models\Contact\Contact; use Illuminate\Console\Command; use App\Models\Instance\Instance; diff --git a/app/Console/Commands/SentryRelease.php b/app/Console/Commands/SentryRelease.php index a7b9940e8..be2c30e91 100644 --- a/app/Console/Commands/SentryRelease.php +++ b/app/Console/Commands/SentryRelease.php @@ -2,7 +2,9 @@ namespace App\Console\Commands; +use function Safe\mkdir; use Illuminate\Console\Command; +use function Safe\file_put_contents; use Illuminate\Console\ConfirmableTrait; use App\Console\Commands\Helpers\CommandExecutor; use Symfony\Component\Console\Output\OutputInterface; diff --git a/app/Console/Commands/SetupProduction.php b/app/Console/Commands/SetupProduction.php index a7d86a5fb..72445eb15 100644 --- a/app/Console/Commands/SetupProduction.php +++ b/app/Console/Commands/SetupProduction.php @@ -2,6 +2,7 @@ namespace App\Console\Commands; +use function Safe\touch; use App\Models\Account\Account; use Illuminate\Console\Command; diff --git a/app/Helpers/ComposerScripts.php b/app/Helpers/ComposerScripts.php index 92ff251c9..98ef89b73 100644 --- a/app/Helpers/ComposerScripts.php +++ b/app/Helpers/ComposerScripts.php @@ -2,6 +2,8 @@ namespace App\Helpers; +use function Safe\unlink; + class ComposerScripts { const CONFIG = 'bootstrap/cache/config.php'; diff --git a/app/Helpers/DateHelper.php b/app/Helpers/DateHelper.php index 4d62ff53d..7e47a6223 100644 --- a/app/Helpers/DateHelper.php +++ b/app/Helpers/DateHelper.php @@ -4,6 +4,7 @@ namespace App\Helpers; use Carbon\Carbon; use Jenssegers\Date\Date; +use function Safe\strtotime; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Auth; diff --git a/app/Helpers/InstanceHelper.php b/app/Helpers/InstanceHelper.php index b14905e7d..1518027f0 100644 --- a/app/Helpers/InstanceHelper.php +++ b/app/Helpers/InstanceHelper.php @@ -2,7 +2,9 @@ namespace App\Helpers; +use function Safe\json_decode; use App\Models\Account\Account; +use function Safe\file_get_contents; class InstanceHelper { diff --git a/app/Helpers/LocaleHelper.php b/app/Helpers/LocaleHelper.php index 09f415a1a..8f4c0794c 100644 --- a/app/Helpers/LocaleHelper.php +++ b/app/Helpers/LocaleHelper.php @@ -4,6 +4,8 @@ namespace App\Helpers; use Illuminate\Support\Arr; use Matriphe\ISO639\ISO639; +use function Safe\preg_match; +use function Safe\preg_split; use Illuminate\Support\Facades\App; use libphonenumber\PhoneNumberUtil; use Illuminate\Support\Facades\Auth; diff --git a/app/Helpers/SearchHelper.php b/app/Helpers/SearchHelper.php index 465460a72..014030359 100644 --- a/app/Helpers/SearchHelper.php +++ b/app/Helpers/SearchHelper.php @@ -2,6 +2,7 @@ namespace App\Helpers; +use function Safe\preg_match; use App\Models\Contact\Contact; use Illuminate\Support\Facades\Auth; use App\Models\Contact\ContactFieldType; diff --git a/app/Helpers/TimezoneHelper.php b/app/Helpers/TimezoneHelper.php index 719f130b2..b8012026b 100644 --- a/app/Helpers/TimezoneHelper.php +++ b/app/Helpers/TimezoneHelper.php @@ -3,6 +3,7 @@ namespace App\Helpers; use DateTimeZone; +use function Safe\substr; use Illuminate\Support\Arr; class TimezoneHelper diff --git a/app/Http/Controllers/Api/ApiController.php b/app/Http/Controllers/Api/ApiController.php index 691dc537b..06f43e538 100644 --- a/app/Http/Controllers/Api/ApiController.php +++ b/app/Http/Controllers/Api/ApiController.php @@ -2,7 +2,9 @@ namespace App\Http\Controllers\Api; +use function Safe\substr; use Illuminate\Http\Request; +use function Safe\json_decode; use App\Models\Account\ApiUsage; use App\Http\Controllers\Controller; use App\Traits\JsonRespondController; @@ -65,11 +67,15 @@ class ApiController extends Controller // if the call contains a JSON, the call must not be a GET or // a DELETE // TODO: there is probably a much better way to do that - if ($request->method() != 'GET' && $request->method() != 'DELETE' - && is_null(json_decode($request->getContent()))) { - return $this->setHTTPStatusCode(400) - ->setErrorCode(37) - ->respondWithError(); + try { + if ($request->method() != 'GET' && $request->method() != 'DELETE' + && is_null(json_decode($request->getContent()))) { + return $this->setHTTPStatusCode(400) + ->setErrorCode(37) + ->respondWithError(); + } + } catch (\Safe\Exceptions\JsonException $e) { + // no error } return $next($request); diff --git a/app/Http/Controllers/Api/Auth/OAuthController.php b/app/Http/Controllers/Api/Auth/OAuthController.php index 181b5c0e8..2d775b902 100644 --- a/app/Http/Controllers/Api/Auth/OAuthController.php +++ b/app/Http/Controllers/Api/Auth/OAuthController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api\Auth; use GuzzleHttp\Client; use App\Models\User\User; use Illuminate\Http\Request; +use function Safe\json_decode; use Illuminate\Support\Facades\App; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Auth; diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index 0bfa41d6d..23a885340 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -6,6 +6,7 @@ use App\Models\User\User; use App\Helpers\DateHelper; use App\Models\Contact\Debt; use Illuminate\Http\Request; +use function Safe\json_encode; use App\Helpers\InstanceHelper; use App\Models\Contact\Contact; use Illuminate\Support\Collection; diff --git a/app/Http/Controllers/Settings/MultiFAController.php b/app/Http/Controllers/Settings/MultiFAController.php index cd9634d68..08e74fd8a 100644 --- a/app/Http/Controllers/Settings/MultiFAController.php +++ b/app/Http/Controllers/Settings/MultiFAController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Settings; use Illuminate\Http\Request; +use function Safe\json_decode; use Lahaxearnaud\U2f\Models\U2fKey; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Auth; diff --git a/app/Models/Account/Place.php b/app/Models/Account/Place.php index 9f38c7bcc..3f60324e9 100644 --- a/app/Models/Account/Place.php +++ b/app/Models/Account/Place.php @@ -3,6 +3,7 @@ namespace App\Models\Account; use App\Models\Contact\Contact; +use function Safe\preg_replace; use App\Helpers\CountriesHelper; use App\Models\ModelBinding as Model; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -83,7 +84,10 @@ class Place extends Model } // trim extra whitespaces inside the address - return preg_replace('/\s+/', ' ', $address); + $address = preg_replace('/\s+/', ' ', $address); + if (is_string($address)) { + return $address; + } } /** diff --git a/app/Models/Contact/Contact.php b/app/Models/Contact/Contact.php index 1992144b6..9aabc03c3 100644 --- a/app/Models/Contact/Contact.php +++ b/app/Models/Contact/Contact.php @@ -13,6 +13,7 @@ use App\Helpers\WeatherHelper; use App\Models\Account\Account; use App\Models\Account\Weather; use App\Models\Account\Activity; +use function Safe\preg_match_all; use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use App\Models\Instance\SpecialDate; diff --git a/app/Services/Instance/Geolocalization/GetGPSCoordinate.php b/app/Services/Instance/Geolocalization/GetGPSCoordinate.php index 61bf31d0b..c6abec3de 100644 --- a/app/Services/Instance/Geolocalization/GetGPSCoordinate.php +++ b/app/Services/Instance/Geolocalization/GetGPSCoordinate.php @@ -5,6 +5,7 @@ namespace App\Services\Instance\Geolocalization; use Illuminate\Support\Str; use App\Models\Account\Place; use App\Services\BaseService; +use function Safe\json_decode; use Illuminate\Support\Facades\Log; use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\Exception\ClientException; diff --git a/app/Services/Instance/Weather/GetWeatherInformation.php b/app/Services/Instance/Weather/GetWeatherInformation.php index 3180d267a..0a98e2a96 100644 --- a/app/Services/Instance/Weather/GetWeatherInformation.php +++ b/app/Services/Instance/Weather/GetWeatherInformation.php @@ -5,6 +5,7 @@ namespace App\Services\Instance\Weather; use Illuminate\Support\Str; use App\Models\Account\Place; use App\Services\BaseService; +use function Safe\json_decode; use App\Models\Account\Weather; use Illuminate\Support\Facades\Log; use GuzzleHttp\Client as GuzzleClient; diff --git a/app/Services/VCard/ImportVCard.php b/app/Services/VCard/ImportVCard.php index 48cd83af3..8c9ab2098 100644 --- a/app/Services/VCard/ImportVCard.php +++ b/app/Services/VCard/ImportVCard.php @@ -5,6 +5,7 @@ namespace App\Services\VCard; use Ramsey\Uuid\Uuid; use App\Models\User\User; use App\Traits\DAVFormat; +use function Safe\substr; use Sabre\VObject\Reader; use App\Helpers\DateHelper; use Illuminate\Support\Arr; @@ -13,6 +14,7 @@ use App\Helpers\VCardHelper; use App\Helpers\LocaleHelper; use App\Helpers\RandomHelper; use App\Services\BaseService; +use function Safe\preg_split; use App\Models\Contact\Gender; use App\Models\Contact\Address; use App\Models\Contact\Contact; diff --git a/composer.json b/composer.json index 4aa063194..3e5e48598 100644 --- a/composer.json +++ b/composer.json @@ -43,6 +43,7 @@ "sentry/sentry-laravel": "^1.0", "stevebauman/location": "^3.0", "symfony/translation": "^4.0", + "thecodingmachine/safe": "^0.1.15", "vectorface/whip": "^0.3.2", "vinkla/hashids": "^6.0", "vluzrmos/language-detector": "^1.0" @@ -63,6 +64,7 @@ "roave/security-advisories": "dev-master", "symfony/css-selector": "~4.0", "symfony/dom-crawler": "~4.0", + "thecodingmachine/phpstan-safe-rule": "^0.1.3", "vimeo/psalm": "^3.0" }, "suggest": { diff --git a/composer.lock b/composer.lock index de6551e4d..b239c1c98 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "355c5c3513701f90a328206efc87a7d5", + "content-hash": "ef5ec4daa682acd3563f90150f93c78c", "packages": [ { "name": "aws/aws-sdk-php", @@ -7206,7 +7206,7 @@ }, { "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "email": "backendtea@gmail.com" } ], "description": "Symfony polyfill for ctype functions", @@ -7949,6 +7949,138 @@ ], "time": "2014-11-11T03:54:14+00:00" }, + { + "name": "thecodingmachine/safe", + "version": "v0.1.15", + "source": { + "type": "git", + "url": "https://github.com/thecodingmachine/safe.git", + "reference": "9a4dbc54e397e0bfb152f4b38f8a03040a1e9e3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/9a4dbc54e397e0bfb152f4b38f8a03040a1e9e3e", + "reference": "9a4dbc54e397e0bfb152f4b38f8a03040a1e9e3e", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpstan/phpstan": "^0.10.3", + "squizlabs/php_codesniffer": "^3.2", + "thecodingmachine/phpstan-strict-rules": "^0.10.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + }, + "autoload": { + "psr-4": { + "Safe\\": [ + "lib/", + "generated/" + ] + }, + "files": [ + "generated/apache.php", + "generated/apc.php", + "generated/apcu.php", + "generated/array.php", + "generated/bzip2.php", + "generated/classobj.php", + "generated/com.php", + "generated/cubrid.php", + "generated/curl.php", + "generated/datetime.php", + "generated/dir.php", + "generated/eio.php", + "generated/errorfunc.php", + "generated/exec.php", + "generated/fileinfo.php", + "generated/filesystem.php", + "generated/filter.php", + "generated/fpm.php", + "generated/ftp.php", + "generated/funchand.php", + "generated/gmp.php", + "generated/gnupg.php", + "generated/hash.php", + "generated/ibase.php", + "generated/ibmDb2.php", + "generated/iconv.php", + "generated/image.php", + "generated/imap.php", + "generated/info.php", + "generated/ingres-ii.php", + "generated/inotify.php", + "generated/json.php", + "generated/ldap.php", + "generated/libevent.php", + "generated/libxml.php", + "generated/lzf.php", + "generated/mailparse.php", + "generated/mbstring.php", + "generated/misc.php", + "generated/msql.php", + "generated/mssql.php", + "generated/mysql.php", + "generated/mysqli.php", + "generated/mysqlndMs.php", + "generated/mysqlndQc.php", + "generated/network.php", + "generated/oci8.php", + "generated/opcache.php", + "generated/openssl.php", + "generated/outcontrol.php", + "generated/password.php", + "generated/pcntl.php", + "generated/pcre.php", + "generated/pdf.php", + "generated/pgsql.php", + "generated/posix.php", + "generated/ps.php", + "generated/pspell.php", + "generated/readline.php", + "generated/rrd.php", + "generated/sem.php", + "generated/session.php", + "generated/shmop.php", + "generated/simplexml.php", + "generated/sockets.php", + "generated/sodium.php", + "generated/solr.php", + "generated/spl.php", + "generated/sqlsrv.php", + "generated/ssdeep.php", + "generated/ssh2.php", + "generated/stats.php", + "generated/stream.php", + "generated/strings.php", + "generated/swoole.php", + "generated/uodbc.php", + "generated/uopz.php", + "generated/url.php", + "generated/var.php", + "generated/xdiff.php", + "generated/xml.php", + "generated/xmlrpc.php", + "generated/yaml.php", + "generated/yaz.php", + "generated/zip.php", + "generated/zlib.php", + "lib/special_cases.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHP core functions that throw exceptions instead of returning FALSE on error", + "time": "2019-04-17T16:09:50+00:00" + }, { "name": "tijsverkoyen/css-to-inline-styles", "version": "2.2.1", @@ -12627,6 +12759,54 @@ "homepage": "https://symfony.com", "time": "2019-02-07T11:40:08+00:00" }, + { + "name": "thecodingmachine/phpstan-safe-rule", + "version": "v0.1.3", + "source": { + "type": "git", + "url": "https://github.com/thecodingmachine/phpstan-safe-rule.git", + "reference": "00f4845905feb5240ca62fb799e3c51ba85c9230" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thecodingmachine/phpstan-safe-rule/zipball/00f4845905feb5240ca62fb799e3c51ba85c9230", + "reference": "00f4845905feb5240ca62fb799e3c51ba85c9230", + "shasum": "" + }, + "require": { + "php": "^7.1", + "phpstan/phpstan": "^0.10 | ^0.11", + "thecodingmachine/safe": "^0.1.11" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^7.5.2", + "squizlabs/php_codesniffer": "^3.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + }, + "autoload": { + "psr-4": { + "TheCodingMachine\\Safe\\PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "David Négrier", + "email": "d.negrier@thecodingmachine.com" + } + ], + "description": "A PHPStan rule to detect safety issues. Must be used in conjunction with thecodingmachine/safe", + "time": "2019-03-07T13:52:42+00:00" + }, { "name": "theseer/fdomdocument", "version": "1.6.6", diff --git a/config/passport.php b/config/passport.php index 0c3ce1872..ae5dcf27b 100644 --- a/config/passport.php +++ b/config/passport.php @@ -1,5 +1,7 @@ {{ trans('auth.mfa_auth_u2f') }} + :callbackurl="{{ \Safe\json_encode(url()->current()) }}"> @if (app('pragmarx.google2fa')->isActivated()) diff --git a/resources/views/layouts/skeleton.blade.php b/resources/views/layouts/skeleton.blade.php index a26c238ab..aebe92037 100644 --- a/resources/views/layouts/skeleton.blade.php +++ b/resources/views/layouts/skeleton.blade.php @@ -17,7 +17,7 @@ @endif diff --git a/resources/views/settings/security/u2f-enable.blade.php b/resources/views/settings/security/u2f-enable.blade.php index 1fb5bdda7..c94a96102 100644 --- a/resources/views/settings/security/u2f-enable.blade.php +++ b/resources/views/settings/security/u2f-enable.blade.php @@ -37,10 +37,10 @@

{{ trans('settings.u2f_enable_description') }}

+ :callbackurl="{{ \Safe\json_encode(route('security.index')) }}"> {{ trans('app.cancel') }} diff --git a/tests/Api/Account/ApiUserControllerTest.php b/tests/Api/Account/ApiUserControllerTest.php index b771349e1..e68d107f6 100644 --- a/tests/Api/Account/ApiUserControllerTest.php +++ b/tests/Api/Account/ApiUserControllerTest.php @@ -118,11 +118,8 @@ class ApiUserControllerTest extends ApiTestCase $response = $this->post('/api/me/compliance'); - $response->assertStatus(400); - - $response->assertJsonFragment([ - 'error_code' => 37, - 'message' => 'Problems parsing JSON', + $this->expectDataError($response, [ + 'The ip address field is required.', ]); } diff --git a/tests/Api/Contact/ApiLifeEventControllerTest.php b/tests/Api/Contact/ApiLifeEventControllerTest.php index 39b156f79..f5be4b80c 100644 --- a/tests/Api/Contact/ApiLifeEventControllerTest.php +++ b/tests/Api/Contact/ApiLifeEventControllerTest.php @@ -173,7 +173,7 @@ class ApiLifeEventControllerTest extends ApiTestCase $response = $this->json('POST', '/api/lifeevents', [ 'contact_id' => $contact->id, - 'life_event_type_id' => 392029834029, + 'life_event_type_id' => 0, 'happened_at' => '1989-02-02', 'name' => 'This is a text', 'note' => 'This is a text', @@ -189,7 +189,7 @@ class ApiLifeEventControllerTest extends ApiTestCase ]); $response = $this->json('POST', '/api/lifeevents', [ - 'contact_id' => 9320984209, + 'contact_id' => 0, 'life_event_type_id' => $lifeEventType->id, 'happened_at' => '1989-02-02', 'name' => 'This is a text', diff --git a/tests/Commands/ImportCSVTest.php b/tests/Commands/ImportCSVTest.php new file mode 100644 index 000000000..a72514a33 --- /dev/null +++ b/tests/Commands/ImportCSVTest.php @@ -0,0 +1,92 @@ +withoutMockingConsoleOutput(); + Storage::fake('public'); + + $user = $this->getUser(); + $path = base_path('tests/stubs/single_contact_stub.csv'); + + $totalContacts = Contact::where('account_id', $user->account_id)->count(); + + $exitCode = $this->artisan('import:csv '.$user->email.' '.$path); + + $this->assertDatabaseHas('contacts', [ + 'first_name' => 'Bono', + 'last_name' => 'Hewson', + ]); + + $this->assertDatabaseHas('contact_fields', [ + 'data' => 'bono@example.com', + ]); + + // Allows checking if birthday was correctly set + $this->assertDatabaseHas('special_dates', [ + 'date' => '1960-05-10', + ]); + + // Asserts that only 3 new contacts were created + $this->assertEquals( + $totalContacts + 1, + Contact::where('account_id', $user->account_id)->count() + ); + + $this->assertEquals(0, $exitCode); + } + + public function test_csv_import_validates_user() + { + $this->withoutMockingConsoleOutput(); + + $path = base_path('tests/stubs/single_contact_stub.csv'); + + $command = m::mock('\App\Console\Commands\ImportCSV[error]', [new \Illuminate\Filesystem\Filesystem()]); + + $command->shouldReceive('error')->once()->with('You need to provide a valid User ID or email address!'); + + $this->app['Illuminate\Contracts\Console\Kernel']->registerCommand($command); + + $exitCode = $this->artisan('import:csv test@test.com '.$path); + + $this->assertEquals(-1, $exitCode); + } + + public function test_csv_import_validates_file() + { + $this->withoutMockingConsoleOutput(); + + $user = $this->getUser(); + + $command = m::mock('\App\Console\Commands\ImportCSV[error]', [new \Illuminate\Filesystem\Filesystem()]); + + $command->shouldReceive('error')->once()->with('You need to provide a valid file path.'); + + $this->app['Illuminate\Contracts\Console\Kernel']->registerCommand($command); + + $exitCode = $this->artisan('import:csv '.$user->email.' xxx'); + + $this->assertEquals(-1, $exitCode); + } + + private function getUser() + { + $account = Account::createDefault('John', 'Doe', 'johndoe@example.com', 'secret'); + + return $account->users()->first(); + } +} diff --git a/tests/Unit/Helpers/InstanceHelperTest.php b/tests/Unit/Helpers/InstanceHelperTest.php index 3005f2a44..2de40a718 100644 --- a/tests/Unit/Helpers/InstanceHelperTest.php +++ b/tests/Unit/Helpers/InstanceHelperTest.php @@ -3,6 +3,7 @@ namespace Tests\Unit\Helpers; use Tests\TestCase; +use function Safe\json_decode; use App\Helpers\InstanceHelper; use App\Models\Account\Account; use Illuminate\Foundation\Testing\DatabaseTransactions; diff --git a/tests/stubs/single_contact_stub.csv b/tests/stubs/single_contact_stub.csv new file mode 100644 index 000000000..0c5f6c9ed --- /dev/null +++ b/tests/stubs/single_contact_stub.csv @@ -0,0 +1,2 @@ +id,first_name,middle_name,last_name +0,Bono,Paul David,Hewson,,,,,,,,,,,1960-05-10,,,,,,,,,,,,,,bono@example.com \ No newline at end of file