diff --git a/.travis.yml b/.travis.yml index c48bd49..0d04169 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,11 +6,6 @@ php: - 7.0 - hhvm - -matrix: - allow_failures: - - php: 7.0 - install: - travis_retry composer install --no-interaction --prefer-source diff --git a/README.md b/README.md index d080404..0735b3e 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Teamwork is the fastest and easiest method to add a User / Team association with - [Team](#team) - [User](#user) - [Usage](#usage) + - [Scaffoling](#scaffolding) - [Basic concepts](#basic-concepts) - [Get to know my team(s)](#know-my-teams) - [Team owner](#team-owner) @@ -139,6 +140,27 @@ composer dump-autoload ## Usage + +### Scaffolding + +The easiest way to give your new Laravel project Team abilities is by using the `make:teamwork` command. + +```bash +php artisan make:teamwork +``` + +This command will create all views, routes and controllers to make your new project team-ready. + +Out of the box, the following parts will be created for you: + +* Team listing +* Team creation / editing / deletion +* Invite new members to teams + +Imagine it as a the `make:auth` command for Teamwork. + +To get started, take a look at the new installed `/teams` route in your project. + ### Basic concepts diff --git a/composer.json b/composer.json index 8de2d11..cc2df9e 100644 --- a/composer.json +++ b/composer.json @@ -16,17 +16,23 @@ }, "require": { "php": ">=5.5.9", - "illuminate/support": "~5.0" + "laravel/framework": "~5.0" }, "require-dev": { "phpunit/phpunit": "~4.1", "mockery/mockery": "dev-master", "illuminate/database": "~5.0", - "sami/sami": "dev-master" + "sami/sami": "dev-master", + "orchestra/testbench": "~3.0" }, "autoload": { "psr-0": { "Mpociot\\Teamwork": "src/" } + }, + "autoload-dev": { + "classmap": [ + "tests/models/User.php" + ] } } diff --git a/composer.lock b/composer.lock index 85040d0..f5ce812 100644 --- a/composer.lock +++ b/composer.lock @@ -4,37 +4,40 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "bd26a7d0171c7e3a5b1d98f397bb3e81", + "hash": "103e6d94072780fdda6a111dc4f276bd", + "content-hash": "9902da0543d847e19b502a27f2a8587a", "packages": [ { - "name": "danielstjules/stringy", - "version": "1.10.0", + "name": "classpreloader/classpreloader", + "version": "3.0.0", "source": { "type": "git", - "url": "https://github.com/danielstjules/Stringy.git", - "reference": "4749c205db47ee5b32e8d1adf6d9aff8db6caf3b" + "url": "https://github.com/ClassPreloader/ClassPreloader.git", + "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/danielstjules/Stringy/zipball/4749c205db47ee5b32e8d1adf6d9aff8db6caf3b", - "reference": "4749c205db47ee5b32e8d1adf6d9aff8db6caf3b", + "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/9b10b913c2bdf90c3d2e0d726b454fb7f77c552a", + "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a", "shasum": "" }, "require": { - "ext-mbstring": "*", - "php": ">=5.3.0" + "nikic/php-parser": "^1.0|^2.0", + "php": ">=5.5.9" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^4.8|^5.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, "autoload": { "psr-4": { - "Stringy\\": "src/" - }, - "files": [ - "src/Create.php" - ] + "ClassPreloader\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -42,38 +45,67 @@ ], "authors": [ { - "name": "Daniel St. Jules", - "email": "danielst.jules@gmail.com", - "homepage": "http://www.danielstjules.com" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com" } ], - "description": "A string manipulation library with multibyte support", - "homepage": "https://github.com/danielstjules/Stringy", + "description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case", "keywords": [ - "UTF", - "helpers", - "manipulation", - "methods", - "multibyte", - "string", - "utf-8", - "utility", - "utils" - ], - "time": "2015-07-23 00:54:12" + "autoload", + "class", + "preload" + ], + "time": "2015-11-09 22:51:51" + }, + { + "name": "dnoegel/php-xdg-base-dir", + "version": "0.1", + "source": { + "type": "git", + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/265b8593498b997dc2d31e75b89f053b5cc9621a", + "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "@stable" + }, + "type": "project", + "autoload": { + "psr-4": { + "XdgBaseDir\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "implementation of xdg base directory specification for php", + "time": "2014-10-24 07:27:01" }, { "name": "doctrine/inflector", - "version": "v1.0.1", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604" + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/0bcb2e79d8571787f18b7eb036ed3d004908e604", - "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", "shasum": "" }, "require": { @@ -85,7 +117,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -127,34 +159,126 @@ "singularize", "string" ], - "time": "2014-12-20 21:24:13" + "time": "2015-11-06 14:35:42" }, { - "name": "illuminate/contracts", - "version": "v5.1.16", + "name": "jakub-onderka/php-console-color", + "version": "0.1", "source": { "type": "git", - "url": "https://github.com/illuminate/contracts.git", - "reference": "610aea16e3d91dfd85db4cf43703403a83b7cba2" + "url": "https://github.com/JakubOnderka/PHP-Console-Color.git", + "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/610aea16e3d91dfd85db4cf43703403a83b7cba2", - "reference": "610aea16e3d91dfd85db4cf43703403a83b7cba2", + "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/e0b393dacf7703fc36a4efc3df1435485197e6c1", + "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1", "shasum": "" }, "require": { - "php": ">=5.5.9" + "php": ">=5.3.2" + }, + "require-dev": { + "jakub-onderka/php-code-style": "1.0", + "jakub-onderka/php-parallel-lint": "0.*", + "jakub-onderka/php-var-dump-check": "0.*", + "phpunit/phpunit": "3.7.*", + "squizlabs/php_codesniffer": "1.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "JakubOnderka\\PhpConsoleColor": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Jakub Onderka", + "email": "jakub.onderka@gmail.com", + "homepage": "http://www.acci.cz" + } + ], + "time": "2014-04-08 15:00:19" + }, + { + "name": "jakub-onderka/php-console-highlighter", + "version": "v0.3.2", + "source": { + "type": "git", + "url": "https://github.com/JakubOnderka/PHP-Console-Highlighter.git", + "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Highlighter/zipball/7daa75df45242c8d5b75a22c00a201e7954e4fb5", + "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5", + "shasum": "" + }, + "require": { + "jakub-onderka/php-console-color": "~0.1", + "php": ">=5.3.0" + }, + "require-dev": { + "jakub-onderka/php-code-style": "~1.0", + "jakub-onderka/php-parallel-lint": "~0.5", + "jakub-onderka/php-var-dump-check": "~0.1", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~1.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JakubOnderka\\PhpConsoleHighlighter": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jakub Onderka", + "email": "acci@acci.cz", + "homepage": "http://www.acci.cz/" + } + ], + "time": "2015-04-20 18:58:01" + }, + { + "name": "jeremeamia/SuperClosure", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/jeremeamia/super_closure.git", + "reference": "29a88be2a4846d27c1613aed0c9071dfad7b5938" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jeremeamia/super_closure/zipball/29a88be2a4846d27c1613aed0c9071dfad7b5938", + "reference": "29a88be2a4846d27c1613aed0c9071dfad7b5938", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^1.2|^2.0", + "php": ">=5.4", + "symfony/polyfill-php56": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-master": "2.2-dev" } }, "autoload": { "psr-4": { - "Illuminate\\Contracts\\": "" + "SuperClosure\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -163,52 +287,135 @@ ], "authors": [ { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia", + "role": "Developer" } ], - "description": "The Illuminate Contracts package.", - "homepage": "http://laravel.com", - "time": "2015-08-31 12:59:22" + "description": "Serialize Closure objects, including their context and binding", + "homepage": "https://github.com/jeremeamia/super_closure", + "keywords": [ + "closure", + "function", + "lambda", + "parser", + "serializable", + "serialize", + "tokenizer" + ], + "time": "2015-12-05 17:17:57" }, { - "name": "illuminate/support", - "version": "v5.1.16", + "name": "laravel/framework", + "version": "v5.2.32", "source": { "type": "git", - "url": "https://github.com/illuminate/support.git", - "reference": "c5389968d48517b3b51cfd8cd4abd72f0cc1575b" + "url": "https://github.com/laravel/framework.git", + "reference": "f688217113f70b01d0e127da9035195415812bef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/c5389968d48517b3b51cfd8cd4abd72f0cc1575b", - "reference": "c5389968d48517b3b51cfd8cd4abd72f0cc1575b", + "url": "https://api.github.com/repos/laravel/framework/zipball/f688217113f70b01d0e127da9035195415812bef", + "reference": "f688217113f70b01d0e127da9035195415812bef", "shasum": "" }, "require": { - "danielstjules/stringy": "~1.8", + "classpreloader/classpreloader": "~3.0", "doctrine/inflector": "~1.0", "ext-mbstring": "*", - "illuminate/contracts": "5.1.*", - "php": ">=5.5.9" + "ext-openssl": "*", + "jeremeamia/superclosure": "~2.2", + "league/flysystem": "~1.0", + "monolog/monolog": "~1.11", + "mtdowling/cron-expression": "~1.0", + "nesbot/carbon": "~1.20", + "paragonie/random_compat": "~1.4", + "php": ">=5.5.9", + "psy/psysh": "0.7.*", + "swiftmailer/swiftmailer": "~5.1", + "symfony/console": "2.8.*|3.0.*", + "symfony/debug": "2.8.*|3.0.*", + "symfony/finder": "2.8.*|3.0.*", + "symfony/http-foundation": "2.8.*|3.0.*", + "symfony/http-kernel": "2.8.*|3.0.*", + "symfony/polyfill-php56": "~1.0", + "symfony/process": "2.8.*|3.0.*", + "symfony/routing": "2.8.*|3.0.*", + "symfony/translation": "2.8.*|3.0.*", + "symfony/var-dumper": "2.8.*|3.0.*", + "vlucas/phpdotenv": "~2.2" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/exception": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/log": "self.version", + "illuminate/mail": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version" + }, + "require-dev": { + "aws/aws-sdk-php": "~3.0", + "mockery/mockery": "~0.9.4", + "pda/pheanstalk": "~3.0", + "phpunit/phpunit": "~4.1", + "predis/predis": "~1.0", + "symfony/css-selector": "2.8.*|3.0.*", + "symfony/dom-crawler": "2.8.*|3.0.*" }, "suggest": { - "jeremeamia/superclosure": "Required to be able to serialize closures (~2.0).", - "symfony/var-dumper": "Required to use the dd function (2.7.*)." + "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).", + "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", + "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~5.3|~6.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).", + "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).", + "predis/predis": "Required to use the redis cache and queue drivers (~1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0).", + "symfony/css-selector": "Required to use some of the crawler integration testing tools (2.8.*|3.0.*).", + "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (2.8.*|3.0.*).", + "symfony/psr-http-message-bridge": "Required to psr7 bridging features (0.2.*)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-master": "5.2-dev" } }, "autoload": { - "psr-4": { - "Illuminate\\Support\\": "" - }, + "classmap": [ + "src/Illuminate/Queue/IlluminateQueueClosure.php" + ], "files": [ - "helpers.php" - ] + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Support/helpers.php" + ], + "psr-4": { + "Illuminate\\": "src/Illuminate/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -220,45 +427,63 @@ "email": "taylorotwell@gmail.com" } ], - "description": "The Illuminate Support package.", + "description": "The Laravel Framework.", "homepage": "http://laravel.com", - "time": "2015-09-03 15:47:41" - } - ], - "packages-dev": [ + "keywords": [ + "framework", + "laravel" + ], + "time": "2016-05-17 13:24:40" + }, { - "name": "doctrine/instantiator", - "version": "1.0.5", + "name": "league/flysystem", + "version": "1.0.22", "source": { "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "bd73a91703969a2d20ab4bfbf971d6c2cbe36612" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/bd73a91703969a2d20ab4bfbf971d6c2cbe36612", + "reference": "bd73a91703969a2d20ab4bfbf971d6c2cbe36612", "shasum": "" }, "require": { - "php": ">=5.3,<8.0-DEV" + "php": ">=5.4.0" + }, + "conflict": { + "league/flysystem-sftp": "<1.0.6" }, "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" + "ext-fileinfo": "*", + "mockery/mockery": "~0.9", + "phpspec/phpspec": "^2.2", + "phpunit/phpunit": "~4.8 || ~5.0" + }, + "suggest": { + "ext-fileinfo": "Required for MimeType", + "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", + "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "league/flysystem-copy": "Allows you to use Copy.com storage", + "league/flysystem-dropbox": "Allows you to use Dropbox storage", + "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1-dev" } }, "autoload": { "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + "League\\Flysystem\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -267,91 +492,1425 @@ ], "authors": [ { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "name": "Frank de Jonge", + "email": "info@frenky.net" } ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "description": "Filesystem abstraction: Many filesystems, one API.", "keywords": [ - "constructor", - "instantiate" + "Cloud Files", + "WebDAV", + "abstraction", + "aws", + "cloud", + "copy.com", + "dropbox", + "file systems", + "files", + "filesystem", + "filesystems", + "ftp", + "rackspace", + "remote", + "s3", + "sftp", + "storage" + ], + "time": "2016-04-28 06:53:12" + }, + { + "name": "monolog/monolog", + "version": "1.19.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "5f56ed5212dc509c8dc8caeba2715732abb32dbf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/5f56ed5212dc509c8dc8caeba2715732abb32dbf", + "reference": "5f56ed5212dc509c8dc8caeba2715732abb32dbf", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "raven/raven": "^0.13", + "ruflin/elastica": ">=0.90 <3.0", + "swiftmailer/swiftmailer": "~5.3" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "raven/raven": "Allow sending log messages to a Sentry server", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" ], - "time": "2015-06-14 21:17:01" + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "time": "2016-04-12 18:29:35" }, { - "name": "hamcrest/hamcrest-php", - "version": "v1.2.2", + "name": "mtdowling/cron-expression", + "version": "v1.1.0", "source": { "type": "git", - "url": "https://github.com/hamcrest/hamcrest-php.git", - "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" + "url": "https://github.com/mtdowling/cron-expression.git", + "reference": "c9ee7886f5a12902b225a1a12f36bb45f9ab89e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", - "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", + "url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/c9ee7886f5a12902b225a1a12f36bb45f9ab89e5", + "reference": "c9ee7886f5a12902b225a1a12f36bb45f9ab89e5", "shasum": "" }, "require": { "php": ">=5.3.2" }, - "replace": { - "cordoval/hamcrest-php": "*", - "davedevelopment/hamcrest-php": "*", - "kodova/hamcrest-php": "*" + "require-dev": { + "phpunit/phpunit": "~4.0|~5.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Cron": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "time": "2016-01-26 21:23:30" + }, + { + "name": "nesbot/carbon", + "version": "1.21.0", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7b08ec6f75791e130012f206e3f7b0e76e18e3d7", + "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "symfony/translation": "~2.6|~3.0" }, "require-dev": { - "phpunit/php-file-iterator": "1.3.3", - "satooshi/php-coveralls": "dev-master" + "phpunit/phpunit": "~4.0|~5.0" }, "type": "library", "autoload": { - "classmap": [ - "hamcrest" - ], - "files": [ - "hamcrest/Hamcrest.php" - ] + "psr-4": { + "Carbon\\": "src/Carbon/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD" + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "http://nesbot.com" + } + ], + "description": "A simple API extension for DateTime.", + "homepage": "http://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "time": "2015-11-04 20:07:17" + }, + { + "name": "nikic/php-parser", + "version": "v1.4.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", + "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "files": [ + "lib/bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2015-09-19 14:15:08" + }, + { + "name": "paragonie/random_compat", + "version": "v1.4.1", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "c7e26a21ba357863de030f0b9e701c7d04593774" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/c7e26a21ba357863de030f0b9e701c7d04593774", + "reference": "c7e26a21ba357863de030f0b9e701c7d04593774", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ], + "time": "2016-03-18 20:34:03" + }, + { + "name": "psr/log", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Psr\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2012-12-21 11:40:51" + }, + { + "name": "psy/psysh", + "version": "v0.7.2", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/e64e10b20f8d229cac76399e1f3edddb57a0f280", + "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280", + "shasum": "" + }, + "require": { + "dnoegel/php-xdg-base-dir": "0.1", + "jakub-onderka/php-console-highlighter": "0.3.*", + "nikic/php-parser": "^1.2.1|~2.0", + "php": ">=5.3.9", + "symfony/console": "~2.3.10|^2.4.2|~3.0", + "symfony/var-dumper": "~2.7|~3.0" + }, + "require-dev": { + "fabpot/php-cs-fixer": "~1.5", + "phpunit/phpunit": "~3.7|~4.0|~5.0", + "squizlabs/php_codesniffer": "~2.0", + "symfony/finder": "~2.1|~3.0" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "0.8.x-dev" + } + }, + "autoload": { + "files": [ + "src/Psy/functions.php" + ], + "psr-4": { + "Psy\\": "src/Psy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "time": "2016-03-09 05:03:14" + }, + { + "name": "swiftmailer/swiftmailer", + "version": "v5.4.2", + "source": { + "type": "git", + "url": "https://github.com/swiftmailer/swiftmailer.git", + "reference": "d8db871a54619458a805229a057ea2af33c753e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/d8db871a54619458a805229a057ea2af33c753e8", + "reference": "d8db871a54619458a805229a057ea2af33c753e8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "mockery/mockery": "~0.9.1,<0.9.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.4-dev" + } + }, + "autoload": { + "files": [ + "lib/swift_required.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Corbyn" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Swiftmailer, free feature-rich PHP mailer", + "homepage": "http://swiftmailer.org", + "keywords": [ + "email", + "mail", + "mailer" + ], + "time": "2016-05-01 08:45:47" + }, + { + "name": "symfony/console", + "version": "v2.8.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "48221d3de4dc22d2cd57c97e8b9361821da86609" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/48221d3de4dc22d2cd57c97e8b9361821da86609", + "reference": "48221d3de4dc22d2cd57c97e8b9361821da86609", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1|~3.0.0", + "symfony/process": "~2.1|~3.0.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2016-04-26 12:00:47" + }, + { + "name": "symfony/debug", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "a06d10888a45afd97534506afb058ec38d9ba35b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/a06d10888a45afd97534506afb058ec38d9ba35b", + "reference": "a06d10888a45afd97534506afb058ec38d9ba35b", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + }, + "require-dev": { + "symfony/class-loader": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com", + "time": "2016-03-30 10:41:14" + }, + { + "name": "symfony/event-dispatcher", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "807dde98589f9b2b00624dca326740380d78dbbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/807dde98589f9b2b00624dca326740380d78dbbc", + "reference": "807dde98589f9b2b00624dca326740380d78dbbc", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2016-05-05 06:56:13" + }, + { + "name": "symfony/finder", + "version": "v2.8.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/ca24cf2cd4e3826f571e0067e535758e73807aa1", + "reference": "ca24cf2cd4e3826f571e0067e535758e73807aa1", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2016-03-10 10:53:53" + }, + { + "name": "symfony/http-foundation", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "18b24bc32d2495ae79d76e777368786a6536fe31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/18b24bc32d2495ae79d76e777368786a6536fe31", + "reference": "18b24bc32d2495ae79d76e777368786a6536fe31", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "symfony/expression-language": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpFoundation Component", + "homepage": "https://symfony.com", + "time": "2016-04-12 18:09:53" + }, + { + "name": "symfony/http-kernel", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "6a5010978edf0a9646342232531e53bfc7abbcd3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6a5010978edf0a9646342232531e53bfc7abbcd3", + "reference": "6a5010978edf0a9646342232531e53bfc7abbcd3", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "psr/log": "~1.0", + "symfony/debug": "~2.8|~3.0", + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0" + }, + "conflict": { + "symfony/config": "<2.8" + }, + "require-dev": { + "symfony/browser-kit": "~2.8|~3.0", + "symfony/class-loader": "~2.8|~3.0", + "symfony/config": "~2.8|~3.0", + "symfony/console": "~2.8|~3.0", + "symfony/css-selector": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/dom-crawler": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/finder": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0", + "symfony/routing": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0", + "symfony/templating": "~2.8|~3.0", + "symfony/translation": "~2.8|~3.0", + "symfony/var-dumper": "~2.8|~3.0" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/class-loader": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/finder": "", + "symfony/var-dumper": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpKernel Component", + "homepage": "https://symfony.com", + "time": "2016-05-09 22:13:13" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "1289d16209491b584839022f29257ad859b8532d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d", + "reference": "1289d16209491b584839022f29257ad859b8532d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2016-01-20 09:13:37" + }, + { + "name": "symfony/polyfill-php56", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php56.git", + "reference": "4d891fff050101a53a4caabb03277284942d1ad9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/4d891fff050101a53a4caabb03277284942d1ad9", + "reference": "4d891fff050101a53a4caabb03277284942d1ad9", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-util": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php56\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2016-01-20 09:13:37" + }, + { + "name": "symfony/polyfill-util", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-util.git", + "reference": "8de62801aa12bc4dfcf85eef5d21981ae7bb3cc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/8de62801aa12bc4dfcf85eef5d21981ae7bb3cc4", + "reference": "8de62801aa12bc4dfcf85eef5d21981ae7bb3cc4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Util\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony utilities for portability of PHP codes", + "homepage": "https://symfony.com", + "keywords": [ + "compat", + "compatibility", + "polyfill", + "shim" + ], + "time": "2016-01-20 09:13:37" + }, + { + "name": "symfony/process", + "version": "v2.8.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "1276bd9be89be039748cf753a2137f4ef149cd74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/1276bd9be89be039748cf753a2137f4ef149cd74", + "reference": "1276bd9be89be039748cf753a2137f4ef149cd74", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2016-04-14 15:22:22" + }, + { + "name": "symfony/routing", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "a6cd168310066176599442aa21f5da86c3f8e0b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/a6cd168310066176599442aa21f5da86c3f8e0b3", + "reference": "a6cd168310066176599442aa21f5da86c3f8e0b3", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "conflict": { + "symfony/config": "<2.8" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/common": "~2.2", + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/yaml": "~2.8|~3.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation loader", + "symfony/config": "For using the all-in-one router or any loader", + "symfony/dependency-injection": "For loading routes from a service", + "symfony/expression-language": "For using expression matching", + "symfony/http-foundation": "For using a Symfony Request object", + "symfony/yaml": "For using the YAML loader" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Routing Component", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "time": "2016-05-03 12:23:49" + }, + { + "name": "symfony/translation", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "f7a07af51ea067745a521dab1e3152044a2fb1f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/f7a07af51ea067745a521dab1e3152044a2fb1f2", + "reference": "f7a07af51ea067745a521dab1e3152044a2fb1f2", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/config": "<2.8" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0", + "symfony/intl": "~2.8|~3.0", + "symfony/yaml": "~2.8|~3.0" + }, + "suggest": { + "psr/log": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Translation Component", + "homepage": "https://symfony.com", + "time": "2016-03-25 01:41:20" + }, + { + "name": "symfony/var-dumper", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "0e918c269093ba4c77fca14e9424fa74ed16f1a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0e918c269093ba4c77fca14e9424fa74ed16f1a6", + "reference": "0e918c269093ba4c77fca14e9424fa74ed16f1a6", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "twig/twig": "~1.20|~2.0" + }, + "suggest": { + "ext-symfony_debug": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "time": "2016-04-25 11:17:47" + }, + { + "name": "vlucas/phpdotenv", + "version": "v2.2.1", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "63f37b9395e8041cd4313129c08ece896d06ca8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/63f37b9395e8041cd4313129c08ece896d06ca8e", + "reference": "63f37b9395e8041cd4313129c08ece896d06ca8e", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause-Attribution" + ], + "authors": [ + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "http://www.vancelucas.com" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "time": "2016-04-15 10:48:49" + } + ], + "packages-dev": [ + { + "name": "blackfire/php-sdk", + "version": "v1.5.13", + "source": { + "type": "git", + "url": "https://github.com/blackfireio/php-sdk.git", + "reference": "6e1bfe4d77f8d1a8a18315eef5f57e9211ba4729" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/blackfireio/php-sdk/zipball/6e1bfe4d77f8d1a8a18315eef5f57e9211ba4729", + "reference": "6e1bfe4d77f8d1a8a18315eef5f57e9211ba4729", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "suggest": { + "ext-blackfire": "The C version of the Blackfire probe", + "ext-xhprof": "XHProf is required as a fallback" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "autoload": { + "files": [ + "src/autostart.php" + ], + "psr-4": { + "Blackfire\\": "src/Blackfire" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Blackfire.io", + "email": "support@blackfire.io" + } + ], + "description": "Blackfire.io PHP SDK", + "keywords": [ + "performance", + "profiler", + "uprofiler", + "xhprof" + ], + "time": "2016-05-16 10:16:03" + }, + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" ], - "description": "This is the PHP port of Hamcrest Matchers", + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", "keywords": [ - "test" + "constructor", + "instantiate" ], - "time": "2015-05-11 14:41:42" + "time": "2015-06-14 21:17:01" }, { - "name": "illuminate/container", - "version": "v5.1.16", + "name": "fzaninotto/faker", + "version": "v1.6.0", "source": { "type": "git", - "url": "https://github.com/illuminate/container.git", - "reference": "66621248395705cc64bc1ce9262b99b4bfa606f2" + "url": "https://github.com/fzaninotto/Faker.git", + "reference": "44f9a286a04b80c76a4e5fb7aad8bb539b920123" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/container/zipball/66621248395705cc64bc1ce9262b99b4bfa606f2", - "reference": "66621248395705cc64bc1ce9262b99b4bfa606f2", + "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/44f9a286a04b80c76a4e5fb7aad8bb539b920123", + "reference": "44f9a286a04b80c76a4e5fb7aad8bb539b920123", "shasum": "" }, "require": { - "illuminate/contracts": "5.1.*", - "php": ">=5.5.9" + "php": "^5.3.3|^7.0" + }, + "require-dev": { + "ext-intl": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~1.5" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } + "branch-alias": [] }, "autoload": { "psr-4": { - "Illuminate\\Container\\": "" + "Faker\\": "src/Faker/" } }, "notification-url": "https://packagist.org/downloads/", @@ -360,85 +1919,77 @@ ], "authors": [ { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" + "name": "François Zaninotto" } ], - "description": "The Illuminate Container package.", - "homepage": "http://laravel.com", - "time": "2015-08-26 23:00:38" + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "time": "2016-04-29 12:21:54" }, { - "name": "illuminate/database", - "version": "v5.1.16", + "name": "hamcrest/hamcrest-php", + "version": "v2.0.0", "source": { "type": "git", - "url": "https://github.com/illuminate/database.git", - "reference": "7655e39c507776c9b9226a8f5619ed9933d3396e" + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/database/zipball/7655e39c507776c9b9226a8f5619ed9933d3396e", - "reference": "7655e39c507776c9b9226a8f5619ed9933d3396e", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/776503d3a8e85d4f9a1148614f95b7a608b046ad", + "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad", "shasum": "" }, "require": { - "illuminate/container": "5.1.*", - "illuminate/contracts": "5.1.*", - "illuminate/support": "5.1.*", - "nesbot/carbon": "~1.19", - "php": ">=5.5.9" + "php": "^5.3|^7.0" }, - "suggest": { - "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).", - "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", - "illuminate/console": "Required to use the database commands (5.1.*).", - "illuminate/events": "Required to use the observers with Eloquent (5.1.*).", - "illuminate/filesystem": "Required to use the migrations (5.1.*)." + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "1.3.3", + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "^1.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-master": "2.0-dev" } }, "autoload": { - "psr-4": { - "Illuminate\\Database\\": "" - } + "classmap": [ + "hamcrest" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } + "BSD" ], - "description": "The Illuminate Database package.", - "homepage": "http://laravel.com", + "description": "This is the PHP port of Hamcrest Matchers", "keywords": [ - "database", - "laravel", - "orm", - "sql" + "test" ], - "time": "2015-09-03 14:53:32" + "time": "2016-01-20 08:20:44" }, { "name": "michelf/php-markdown", - "version": "1.5.0", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/michelf/php-markdown.git", - "reference": "e1aabe18173231ebcefc90e615565742fc1c7fd9" + "reference": "156e56ee036505ec637d761ee62dc425d807183c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/michelf/php-markdown/zipball/e1aabe18173231ebcefc90e615565742fc1c7fd9", - "reference": "e1aabe18173231ebcefc90e615565742fc1c7fd9", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/156e56ee036505ec637d761ee62dc425d807183c", + "reference": "156e56ee036505ec637d761ee62dc425d807183c", "shasum": "" }, "require": { @@ -460,15 +2011,15 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "John Gruber", - "homepage": "http://daringfireball.net/" - }, { "name": "Michel Fortin", "email": "michel.fortin@michelf.ca", "homepage": "https://michelf.ca/", "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" } ], "description": "PHP Markdown", @@ -476,7 +2027,7 @@ "keywords": [ "markdown" ], - "time": "2015-03-01 12:03:08" + "time": "2015-12-24 01:37:31" }, { "name": "mockery/mockery", @@ -484,16 +2035,16 @@ "source": { "type": "git", "url": "https://github.com/padraic/mockery.git", - "reference": "e585573c91b0c821e511afd14666b4503ef7255b" + "reference": "ad31ff997d983e0d5d60ac80cfcedcbb4e6c4461" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/padraic/mockery/zipball/e585573c91b0c821e511afd14666b4503ef7255b", - "reference": "e585573c91b0c821e511afd14666b4503ef7255b", + "url": "https://api.github.com/repos/padraic/mockery/zipball/ad31ff997d983e0d5d60ac80cfcedcbb4e6c4461", + "reference": "ad31ff997d983e0d5d60ac80cfcedcbb4e6c4461", "shasum": "" }, "require": { - "hamcrest/hamcrest-php": "~1.1", + "hamcrest/hamcrest-php": "^2.0@dev", "lib-pcre": ">=7.0", "php": ">=5.4.0" }, @@ -541,33 +2092,36 @@ "test double", "testing" ], - "time": "2015-07-31 13:51:58" + "time": "2016-05-03 10:17:25" }, { - "name": "nesbot/carbon", - "version": "1.20.0", + "name": "orchestra/database", + "version": "v3.2.2", "source": { "type": "git", - "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "bfd3eaba109c9a2405c92174c8e17f20c2b9caf3" + "url": "https://github.com/orchestral/database.git", + "reference": "7bdcd44a722dd1afb9ad7fe1f2154059e325b275" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bfd3eaba109c9a2405c92174c8e17f20c2b9caf3", - "reference": "bfd3eaba109c9a2405c92174c8e17f20c2b9caf3", + "url": "https://api.github.com/repos/orchestral/database/zipball/7bdcd44a722dd1afb9ad7fe1f2154059e325b275", + "reference": "7bdcd44a722dd1afb9ad7fe1f2154059e325b275", "shasum": "" }, "require": { - "php": ">=5.3.0", - "symfony/translation": "~2.6|~3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" + "illuminate/contracts": "~5.2.0", + "illuminate/database": "~5.2.0", + "php": ">=5.5.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, "autoload": { - "psr-0": { - "Carbon": "src" + "psr-4": { + "Orchestra\\Database\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -576,64 +2130,86 @@ ], "authors": [ { - "name": "Brian Nesbitt", - "email": "brian@nesbot.com", - "homepage": "http://nesbot.com" + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com", + "homepage": "https://github.com/crynobone" + }, + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com", + "homepage": "https://github.com/taylorotwell" } ], - "description": "A simple API extension for DateTime.", - "homepage": "http://carbon.nesbot.com", + "description": "Database Component for Orchestra Platform", "keywords": [ - "date", - "datetime", - "time" + "database", + "orchestra-platform", + "orchestral" ], - "time": "2015-06-25 04:19:39" + "time": "2016-03-01 13:50:22" }, { - "name": "nikic/php-parser", - "version": "v1.4.0", + "name": "orchestra/testbench", + "version": "v3.2.4", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "196f177cfefa0f1f7166c0a05d8255889be12418" + "url": "https://github.com/orchestral/testbench.git", + "reference": "1cfc182f10e7d26aeac9a7a567334bdaf3279b08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/196f177cfefa0f1f7166c0a05d8255889be12418", - "reference": "196f177cfefa0f1f7166c0a05d8255889be12418", + "url": "https://api.github.com/repos/orchestral/testbench/zipball/1cfc182f10e7d26aeac9a7a567334bdaf3279b08", + "reference": "1cfc182f10e7d26aeac9a7a567334bdaf3279b08", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": ">=5.3" + "fzaninotto/faker": "~1.4", + "laravel/framework": "~5.2.28", + "orchestra/database": "~3.2.0", + "php": ">=5.5.0", + "symfony/css-selector": "2.8.*|3.0.*", + "symfony/dom-crawler": "2.8.*|3.0.*" + }, + "require-dev": { + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "~4.0|~5.0" + }, + "suggest": { + "phpunit/phpunit": "Allow to use PHPUnit for testing your Laravel Application/Package (~4.0|~5.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "3.3-dev" } }, "autoload": { - "files": [ - "lib/bootstrap.php" - ] + "psr-4": { + "Orchestra\\Testbench\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Nikita Popov" + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com", + "homepage": "https://github.com/crynobone" } ], - "description": "A PHP parser written in PHP", + "description": "Laravel Package Unit Testing Helper", + "homepage": "http://orchestraplatform.com/docs/latest/components/testbench/", "keywords": [ - "parser", - "php" + "BDD", + "TDD", + "laravel", + "orchestra-platform", + "orchestral", + "testing" ], - "time": "2015-07-14 17:31:05" + "time": "2016-05-02 16:26:45" }, { "name": "phpdocumentor/reflection-docblock", @@ -686,22 +2262,24 @@ }, { "name": "phpspec/prophecy", - "version": "v1.5.0", + "version": "v1.6.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7" + "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7", - "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972", + "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "~2.0", - "sebastian/comparator": "~1.1" + "sebastian/comparator": "~1.1", + "sebastian/recursion-context": "~1.0" }, "require-dev": { "phpspec/phpspec": "~2.0" @@ -709,7 +2287,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-master": "1.5.x-dev" } }, "autoload": { @@ -742,20 +2320,20 @@ "spy", "stub" ], - "time": "2015-08-13 10:07:40" + "time": "2016-02-15 07:46:21" }, { "name": "phpunit/php-code-coverage", - "version": "2.2.2", + "version": "2.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c" + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2d7c03c0e4e080901b8f33b2897b0577be18a13c", - "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", "shasum": "" }, "require": { @@ -804,7 +2382,7 @@ "testing", "xunit" ], - "time": "2015-08-04 03:42:39" + "time": "2015-10-06 15:47:00" }, { "name": "phpunit/php-file-iterator", @@ -896,21 +2474,24 @@ }, { "name": "phpunit/php-timer", - "version": "1.0.7", + "version": "1.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "phpunit/phpunit": "~4|~5" + }, "type": "library", "autoload": { "classmap": [ @@ -933,20 +2514,20 @@ "keywords": [ "timer" ], - "time": "2015-06-21 08:01:12" + "time": "2016-05-12 18:03:57" }, { "name": "phpunit/php-token-stream", - "version": "1.4.6", + "version": "1.4.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b" + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3ab72c62e550370a6cd5dc873e1a04ab57562f5b", - "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", "shasum": "" }, "require": { @@ -982,20 +2563,20 @@ "keywords": [ "tokenizer" ], - "time": "2015-08-16 08:51:00" + "time": "2015-09-15 10:49:45" }, { "name": "phpunit/phpunit", - "version": "4.8.6", + "version": "4.8.26", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "2246830f4a1a551c67933e4171bf2126dc29d357" + "reference": "fc1d8cd5b5de11625979125c5639347896ac2c74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2246830f4a1a551c67933e4171bf2126dc29d357", - "reference": "2246830f4a1a551c67933e4171bf2126dc29d357", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fc1d8cd5b5de11625979125c5639347896ac2c74", + "reference": "fc1d8cd5b5de11625979125c5639347896ac2c74", "shasum": "" }, "require": { @@ -1009,7 +2590,7 @@ "phpunit/php-code-coverage": "~2.1", "phpunit/php-file-iterator": "~1.4", "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": ">=1.0.6", + "phpunit/php-timer": "^1.0.6", "phpunit/phpunit-mock-objects": "~2.3", "sebastian/comparator": "~1.1", "sebastian/diff": "~1.2", @@ -1054,20 +2635,20 @@ "testing", "xunit" ], - "time": "2015-08-24 04:09:38" + "time": "2016-05-17 03:09:28" }, { "name": "phpunit/phpunit-mock-objects", - "version": "2.3.7", + "version": "2.3.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "5e2645ad49d196e020b85598d7c97e482725786a" + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5e2645ad49d196e020b85598d7c97e482725786a", - "reference": "5e2645ad49d196e020b85598d7c97e482725786a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", "shasum": "" }, "require": { @@ -1110,20 +2691,20 @@ "mock", "xunit" ], - "time": "2015-08-19 09:14:08" + "time": "2015-10-02 06:51:40" }, { "name": "pimple/pimple", - "version": "v3.0.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/silexphp/Pimple.git", - "reference": "3313af5935dbc560fab845b76a1ca351b47855af" + "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/silexphp/Pimple/zipball/3313af5935dbc560fab845b76a1ca351b47855af", - "reference": "3313af5935dbc560fab845b76a1ca351b47855af", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a", + "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a", "shasum": "" }, "require": { @@ -1150,13 +2731,13 @@ "email": "fabien@symfony.com" } ], - "description": "Pimple is a simple Dependency Injection Container for PHP 5.3", + "description": "Pimple, a simple Dependency Injection Container", "homepage": "http://pimple.sensiolabs.org", "keywords": [ "container", "dependency injection" ], - "time": "2015-07-30 09:57:46" + "time": "2015-09-11 15:10:35" }, { "name": "sami/sami", @@ -1164,15 +2745,16 @@ "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/Sami.git", - "reference": "5a468aa762c9426548af45b344a46083a54c52dc" + "reference": "3a46b98e2fa4d4819018e3767ba6346bfed92957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/Sami/zipball/5a468aa762c9426548af45b344a46083a54c52dc", - "reference": "5a468aa762c9426548af45b344a46083a54c52dc", + "url": "https://api.github.com/repos/FriendsOfPHP/Sami/zipball/3a46b98e2fa4d4819018e3767ba6346bfed92957", + "reference": "3a46b98e2fa4d4819018e3767ba6346bfed92957", "shasum": "" }, "require": { + "blackfire/php-sdk": "^1.5.6", "michelf/php-markdown": "~1.3", "nikic/php-parser": "~1.0", "php": ">=5.3.9", @@ -1191,7 +2773,7 @@ "type": "application", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -1214,7 +2796,7 @@ "keywords": [ "phpdoc" ], - "time": "2015-08-18 08:04:37" + "time": "2016-01-22 07:52:40" }, { "name": "sebastian/comparator", @@ -1282,28 +2864,28 @@ }, { "name": "sebastian/diff", - "version": "1.3.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "~4.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -1326,24 +2908,24 @@ } ], "description": "Diff implementation", - "homepage": "http://www.github.com/sebastianbergmann/diff", + "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ "diff" ], - "time": "2015-02-22 15:13:53" + "time": "2015-12-08 07:14:41" }, { "name": "sebastian/environment", - "version": "1.3.2", + "version": "1.3.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44" + "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44", - "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716", + "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716", "shasum": "" }, "require": { @@ -1380,7 +2962,7 @@ "environment", "hhvm" ], - "time": "2015-08-03 06:14:51" + "time": "2016-05-17 03:18:57" }, { "name": "sebastian/exporter", @@ -1450,16 +3032,16 @@ }, { "name": "sebastian/global-state", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", "shasum": "" }, "require": { @@ -1497,20 +3079,20 @@ "keywords": [ "global state" ], - "time": "2014-10-06 09:23:50" + "time": "2015-10-12 03:26:01" }, { "name": "sebastian/recursion-context", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "994d4a811bafe801fb06dccbee797863ba2792ba" + "reference": "913401df809e99e4f47b27cdd781f4a258d58791" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba", - "reference": "994d4a811bafe801fb06dccbee797863ba2792ba", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", + "reference": "913401df809e99e4f47b27cdd781f4a258d58791", "shasum": "" }, "require": { @@ -1550,7 +3132,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-06-21 08:04:50" + "time": "2015-11-11 19:50:13" }, { "name": "sebastian/version", @@ -1588,92 +3170,35 @@ "time": "2015-06-21 13:59:46" }, { - "name": "symfony/console", - "version": "v2.7.3", + "name": "symfony/css-selector", + "version": "v3.0.6", "source": { "type": "git", - "url": "https://github.com/symfony/Console.git", - "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e" + "url": "https://github.com/symfony/css-selector.git", + "reference": "65e764f404685f2dc20c057e889b3ad04b2e2db0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/d6cf02fe73634c96677e428f840704bfbcaec29e", - "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/65e764f404685f2dc20c057e889b3ad04b2e2db0", + "reference": "65e764f404685f2dc20c057e889b3ad04b2e2db0", "shasum": "" }, "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1", - "symfony/phpunit-bridge": "~2.7", - "symfony/process": "~2.1" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/process": "" + "php": ">=5.5.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\Console\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "Symfony\\Component\\CssSelector\\": "" }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Console Component", - "homepage": "https://symfony.com", - "time": "2015-07-28 15:18:12" - }, - { - "name": "symfony/filesystem", - "version": "v2.7.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/Filesystem.git", - "reference": "2d7b2ddaf3f548f4292df49a99d19c853d43f0b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/2d7b2ddaf3f548f4292df49a99d19c853d43f0b8", - "reference": "2d7b2ddaf3f548f4292df49a99d19c853d43f0b8", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - } + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1681,54 +3206,9 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Filesystem Component", - "homepage": "https://symfony.com", - "time": "2015-07-09 16:07:40" - }, - { - "name": "symfony/finder", - "version": "v2.7.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/Finder.git", - "reference": "ae0f363277485094edc04c9f3cbe595b183b78e4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/ae0f363277485094edc04c9f3cbe595b183b78e4", - "reference": "ae0f363277485094edc04c9f3cbe595b183b78e4", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" @@ -1738,40 +3218,47 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Finder Component", + "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2015-07-09 16:07:40" + "time": "2016-03-04 07:55:57" }, { - "name": "symfony/process", - "version": "v2.7.3", + "name": "symfony/dom-crawler", + "version": "v3.0.6", "source": { "type": "git", - "url": "https://github.com/symfony/Process.git", - "reference": "48aeb0e48600321c272955132d7606ab0a49adb3" + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "49b588841225b205700e5122fa01911cabada857" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/48aeb0e48600321c272955132d7606ab0a49adb3", - "reference": "48aeb0e48600321c272955132d7606ab0a49adb3", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/49b588841225b205700e5122fa01911cabada857", + "reference": "49b588841225b205700e5122fa01911cabada857", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "symfony/phpunit-bridge": "~2.7" + "symfony/css-selector": "~2.8|~3.0" + }, + "suggest": { + "symfony/css-selector": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\Process\\": "" - } + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1787,52 +3274,40 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Process Component", + "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2015-07-01 11:25:50" + "time": "2016-04-12 18:09:53" }, { - "name": "symfony/translation", - "version": "v2.7.3", + "name": "symfony/filesystem", + "version": "v2.8.6", "source": { "type": "git", - "url": "https://github.com/symfony/Translation.git", - "reference": "c8dc34cc936152c609cdd722af317e4239d10dd6" + "url": "https://github.com/symfony/filesystem.git", + "reference": "dee379131dceed90a429e951546b33edfe7dccbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/c8dc34cc936152c609cdd722af317e4239d10dd6", - "reference": "c8dc34cc936152c609cdd722af317e4239d10dd6", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/dee379131dceed90a429e951546b33edfe7dccbb", + "reference": "dee379131dceed90a429e951546b33edfe7dccbb", "shasum": "" }, "require": { "php": ">=5.3.9" }, - "conflict": { - "symfony/config": "<2.7" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.7", - "symfony/intl": "~2.3", - "symfony/phpunit-bridge": "~2.7", - "symfony/yaml": "~2.2" - }, - "suggest": { - "psr/log": "To use logging capability in translator", - "symfony/config": "", - "symfony/yaml": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\Translation\\": "" - } + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1848,40 +3323,40 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Translation Component", + "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2015-07-09 16:07:40" + "time": "2016-04-12 18:01:21" }, { "name": "symfony/yaml", - "version": "v2.7.3", + "version": "v2.8.6", "source": { "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "71340e996171474a53f3d29111d046be4ad8a0ff" + "url": "https://github.com/symfony/yaml.git", + "reference": "e4fbcc65f90909c999ac3b4dfa699ee6563a9940" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/71340e996171474a53f3d29111d046be4ad8a0ff", - "reference": "71340e996171474a53f3d29111d046be4ad8a0ff", + "url": "https://api.github.com/repos/symfony/yaml/zipball/e4fbcc65f90909c999ac3b4dfa699ee6563a9940", + "reference": "e4fbcc65f90909c999ac3b4dfa699ee6563a9940", "shasum": "" }, "require": { "php": ">=5.3.9" }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Yaml\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1899,20 +3374,20 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2015-07-28 14:07:07" + "time": "2016-03-29 19:00:15" }, { "name": "twig/twig", - "version": "v1.21.1", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "ca8d3aa90b6a01c82e07909fe815d6b443e75a23" + "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/ca8d3aa90b6a01c82e07909fe815d6b443e75a23", - "reference": "ca8d3aa90b6a01c82e07909fe815d6b443e75a23", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", + "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", "shasum": "" }, "require": { @@ -1925,7 +3400,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.21-dev" + "dev-master": "1.24-dev" } }, "autoload": { @@ -1960,7 +3435,7 @@ "keywords": [ "templating" ], - "time": "2015-08-26 08:58:31" + "time": "2016-01-25 21:22:18" } ], "aliases": [], diff --git a/phpunit.xml b/phpunit.xml index 1e76433..5803230 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -12,7 +12,7 @@ > - ./tests/ + tests/ diff --git a/src/Mpociot/Teamwork/Commands/MakeTeamwork.php b/src/Mpociot/Teamwork/Commands/MakeTeamwork.php new file mode 100644 index 0000000..6f6ca36 --- /dev/null +++ b/src/Mpociot/Teamwork/Commands/MakeTeamwork.php @@ -0,0 +1,147 @@ + 'teamwork/emails/invite.blade.php', + 'members/list.blade.php' => 'teamwork/members/list.blade.php', + 'create.blade.php' => 'teamwork/create.blade.php', + 'edit.blade.php' => 'teamwork/edit.blade.php', + 'index.blade.php' => 'teamwork/index.blade.php', + ]; + + /** + * Create a new command instance. + * + * @return void + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Execute the console command. + * + * @return mixed + */ + public function handle() + { + $this->createDirectories(); + + $this->exportViews(); + + if (! $this->option('views')) { + $this->info('Installed TeamController.'); + file_put_contents( + app_path('Http/Controllers/Teamwork/TeamController.php'), + $this->compileControllerStub('TeamController') + ); + + $this->info('Installed TeamMemberController.'); + file_put_contents( + app_path('Http/Controllers/Teamwork/TeamMemberController.php'), + $this->compileControllerStub('TeamMemberController') + ); + + $this->info('Installed AuthController.'); + file_put_contents( + app_path('Http/Controllers/Teamwork/AuthController.php'), + $this->compileControllerStub('AuthController') + ); + + $this->info('Installed JoinTeamListener'); + file_put_contents( + app_path('Listeners/Teamwork/JoinTeamListener.php'), + str_replace( + '{{namespace}}', + $this->getAppNamespace(), + file_get_contents(__DIR__ . '/../../../stubs/listeners/JoinTeamListener.stub') + ) + ); + + $this->info('Updated Routes File.'); + file_put_contents( + app_path('Http/routes.php'), + file_get_contents(__DIR__.'/../../../stubs/routes.stub'), + FILE_APPEND + ); + } + $this->comment('Teamwork scaffolding generated successfully!'); + } + + /** + * Create the directories for the files. + * + * @return void + */ + protected function createDirectories() + { + if (! is_dir(app_path('Http/Controllers/Teamwork'))) { + mkdir(app_path('Http/Controllers/Teamwork'), 0755, true); + } + if (! is_dir(app_path('Listeners/Teamwork'))) { + mkdir(app_path('Listeners/Teamwork'), 0755, true); + } + if (! is_dir(base_path('resources/views/teamwork'))) { + mkdir(base_path('resources/views/teamwork'), 0755, true); + } + if (! is_dir(base_path('resources/views/teamwork/emails'))) { + mkdir(base_path('resources/views/teamwork/emails'), 0755, true); + } + if (! is_dir(base_path('resources/views/teamwork/members'))) { + mkdir(base_path('resources/views/teamwork/members'), 0755, true); + } + } + + /** + * Export the authentication views. + * + * @return void + */ + protected function exportViews() + { + foreach ($this->views as $key => $value) { + $path = base_path('resources/views/'.$value); + $this->line('Created View: '.$path); + copy(__DIR__.'/../../../stubs/views/'.$key, $path); + } + } + + /** + * Compiles the HTTP controller stubs. + * + * @param $stubName + * @return string + */ + protected function compileControllerStub($stubName) + { + return str_replace( + '{{namespace}}', + $this->getAppNamespace(), + file_get_contents(__DIR__.'/../../../stubs/controllers/'.$stubName.'.stub') + ); + } +} diff --git a/src/Mpociot/Teamwork/TeamworkServiceProvider.php b/src/Mpociot/Teamwork/TeamworkServiceProvider.php index 4d7e31d..eb9a485 100644 --- a/src/Mpociot/Teamwork/TeamworkServiceProvider.php +++ b/src/Mpociot/Teamwork/TeamworkServiceProvider.php @@ -8,6 +8,7 @@ */ use Illuminate\Support\ServiceProvider; +use Mpociot\Teamwork\Commands\MakeTeamwork; class TeamworkServiceProvider extends ServiceProvider { @@ -49,7 +50,7 @@ protected function publishMigration() if( count( $published_migration ) === 0 ) { $this->publishes( [ - __DIR__ . '/../../database/migrations.stub' => database_path( '/migrations/' . date( 'Y_m_d_His' ) . '_teamwork_setup_tables.php' ), + __DIR__ . '/../../database/2016_05_18_000000_teamwork_setup_tables.php' => database_path( '/migrations/' . date( 'Y_m_d_His' ) . '_teamwork_setup_tables.php' ), ], 'migrations' ); } } @@ -64,6 +65,7 @@ public function register() $this->mergeConfig(); $this->registerTeamwork(); $this->registerFacade(); + $this->registerCommands(); } /** @@ -101,4 +103,18 @@ protected function mergeConfig() __DIR__ . '/../../config/config.php', 'teamwork' ); } + + /** + * Register scaffolding command + */ + protected function registerCommands() + { + $this->app['make.teamwork'] = $this->app->share(function () { + return new MakeTeamwork(); + }); + + $this->commands([ + 'make.teamwork' + ]); + } } diff --git a/src/Mpociot/Teamwork/TeamworkTeam.php b/src/Mpociot/Teamwork/TeamworkTeam.php index 24205ce..4db220b 100644 --- a/src/Mpociot/Teamwork/TeamworkTeam.php +++ b/src/Mpociot/Teamwork/TeamworkTeam.php @@ -16,6 +16,11 @@ class TeamworkTeam extends Model */ protected $table; + /** + * @var array + */ + protected $fillable = ['name', 'owner_id']; + /** * Creates a new instance of the model. * diff --git a/src/Mpociot/Teamwork/Traits/UserHasTeams.php b/src/Mpociot/Teamwork/Traits/UserHasTeams.php index 7ba9205..1fbfffb 100644 --- a/src/Mpociot/Teamwork/Traits/UserHasTeams.php +++ b/src/Mpociot/Teamwork/Traits/UserHasTeams.php @@ -21,7 +21,7 @@ trait UserHasTeams */ public function teams() { - return $this->belongsToMany( Config::get( 'teamwork.team_model' ),Config::get( 'teamwork.team_user_table' ), 'user_id', 'team_id' ); + return $this->belongsToMany( Config::get( 'teamwork.team_model' ),Config::get( 'teamwork.team_user_table' ), 'user_id', 'team_id' )->withTimestamps(); } /** @@ -143,6 +143,11 @@ public function attachTeam( $team ) { $this->current_team_id = $team; $this->save(); + + if( $this->relationLoaded('currentTeam') ) { + $this->load('currentTeam'); + } + } // Reload relation @@ -151,6 +156,10 @@ public function attachTeam( $team ) if( !$this->teams->contains( $team ) ) { $this->teams()->attach( $team ); + + if( $this->relationLoaded('teams') ) { + $this->load('teams'); + } } return $this; } @@ -165,14 +174,24 @@ public function detachTeam( $team ) { $team = $this->retrieveTeamId( $team ); $this->teams()->detach( $team ); + + if( $this->relationLoaded('teams') ) { + $this->load('teams'); + } + /** * If the user has no more teams, * unset the current_team_id */ - if( count( $this->teams ) === 0 ) + if( $this->teams()->count() === 0 || $this->current_team_id === $team ) { $this->current_team_id = null; $this->save(); + + if( $this->relationLoaded('currentTeam') ) { + $this->load('currentTeam'); + } + } return $this; } @@ -237,6 +256,11 @@ public function switchTeam( $team ) } $this->current_team_id = $team; $this->save(); + + if( $this->relationLoaded('currentTeam') ) { + $this->load('currentTeam'); + } + return $this; } } diff --git a/src/config/config.php b/src/config/config.php index 9a6e639..84c5b5f 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -88,4 +88,4 @@ | */ 'team_invites_table' => 'team_invites', -]; \ No newline at end of file +]; diff --git a/src/database/migrations.stub b/src/database/2016_05_18_000000_teamwork_setup_tables.php similarity index 97% rename from src/database/migrations.stub rename to src/database/2016_05_18_000000_teamwork_setup_tables.php index a8beae8..62270e5 100644 --- a/src/database/migrations.stub +++ b/src/database/2016_05_18_000000_teamwork_setup_tables.php @@ -19,7 +19,7 @@ public function up() } ); - Schema::create( \Config::get( 'teamwork.teams_table' ), function ( $table ) + Schema::create( \Config::get( 'teamwork.teams_table' ), function ( Blueprint $table ) { $table->increments( 'id' )->unsigned(); $table->integer( 'owner_id' )->unsigned()->nullable(); @@ -27,7 +27,7 @@ public function up() $table->timestamps(); } ); - Schema::create( \Config::get( 'teamwork.team_user_table' ), function ( $table ) + Schema::create( \Config::get( 'teamwork.team_user_table' ), function ( Blueprint $table ) { $table->integer( 'user_id' )->unsigned(); $table->integer( 'team_id' )->unsigned(); diff --git a/src/stubs/controllers/AuthController.stub b/src/stubs/controllers/AuthController.stub new file mode 100644 index 0000000..dd4e5dc --- /dev/null +++ b/src/stubs/controllers/AuthController.stub @@ -0,0 +1,35 @@ +check()) { + Teamwork::acceptInvite($invite); + return redirect()->route('teams.index'); + } else { + session(['invite_token' => $token]); + return redirect()->to('login'); + } + } + +} \ No newline at end of file diff --git a/src/stubs/controllers/TeamController.stub b/src/stubs/controllers/TeamController.stub new file mode 100644 index 0000000..24be4a9 --- /dev/null +++ b/src/stubs/controllers/TeamController.stub @@ -0,0 +1,135 @@ +middleware('auth'); + } + + /** + * Display a listing of the resource. + * + * @return \Illuminate\Http\Response + */ + public function index() + { + return view('teamwork.index') + ->with('teams', auth()->user()->teams); + } + + /** + * Show the form for creating a new resource. + * + * @return \Illuminate\Http\Response + */ + public function create() + { + return view('teamwork.create'); + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + $teamModel = config('teamwork.team_model'); + + $team = $teamModel::create([ + 'name' => $request->name, + 'owner_id' => $request->user()->getKey() + ]); + $request->user()->attachTeam($team); + + return redirect(route('teams.index')); + } + + /** + * Switch to the given team. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function switchTeam($id) + { + $teamModel = config('teamwork.team_model'); + $team = $teamModel::findOrFail($id); + try { + auth()->user()->switchTeam($team); + } catch ( UserNotInTeamException $e ) { + abort(403); + } + + return redirect(route('teams.index')); + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + $teamModel = config('teamwork.team_model'); + $team = $teamModel::findOrFail($id); + + if (!auth()->user()->isOwnerOfTeam($team)) { + abort(403); + } + + return view('teamwork.edit')->withTeam($team); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + $teamModel = config('teamwork.team_model'); + + $team = $teamModel::findOrFail($id); + $team->name = $request->name; + $team->save(); + + return redirect(route('teams.index')); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + $teamModel = config('teamwork.team_model'); + + $team = $teamModel::findOrFail($id); + if (!auth()->user()->isOwnerOfTeam($team)) { + abort(403); + } + + $team->delete(); + + $userModel = config('teamwork.user_model'); + $userModel::where('current_team_id', $id) + ->update(['current_team_id' => null]); + + return redirect(route('teams.index')); + } + +} \ No newline at end of file diff --git a/src/stubs/controllers/TeamMemberController.stub b/src/stubs/controllers/TeamMemberController.stub new file mode 100644 index 0000000..d7458b7 --- /dev/null +++ b/src/stubs/controllers/TeamMemberController.stub @@ -0,0 +1,101 @@ +middleware('auth'); + } + + /** + * Show the members of the given team. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + $teamModel = config('teamwork.team_model'); + $team = $teamModel::findOrFail($id); + + return view('teamwork.members.list')->withTeam($team); + } + + /** + * Remove the specified resource from storage. + * + * @param int $team_id + * @param int $user_id + * @return \Illuminate\Http\Response + * @internal param int $id + */ + public function destroy($team_id, $user_id) + { + $teamModel = config('teamwork.team_model'); + $team = $teamModel::findOrFail($team_id); + if (!auth()->user()->isOwnerOfTeam($team)) { + abort(403); + } + + $userModel = config('teamwork.user_model'); + $user = $userModel::findOrFail($user_id); + if ($user->getKey() === auth()->user()->getKey()) { + abort(403); + } + + $user->detachTeam($team); + + return redirect(route('teams.index')); + } + + /** + * @param Request $request + * @param int $team_id + * @return $this + */ + public function invite(Request $request, $team_id) + { + $teamModel = config('teamwork.team_model'); + $team = $teamModel::findOrFail($team_id); + + if( !Teamwork::hasPendingInvite( $request->email, $team) ) + { + Teamwork::inviteToTeam( $request->email, $team, function( $invite ) + { + Mail::send('teamwork.emails.invite', ['team' => $invite->team, 'invite' => $invite], function ($m) use ($invite) { + $m->to($invite->email)->subject('Invitation to join team '.$invite->team->name); + }); + // Send email to user + }); + } else { + return redirect()->back()->withErrors([ + 'email' => 'The email address is already invited to the team.' + ]); + } + } + + /** + * Resend an invitation mail. + * + * @param $invite_id + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector + */ + public function resendInvite($invite_id) + { + $invite = TeamInvite::findOrFail($invite_id); + Mail::send('teamwork.emails.invite', ['team' => $invite->team, 'invite' => $invite], function ($m) use ($invite) { + $m->to($invite->email)->subject('Invitation to join team '.$invite->team->name); + }); + + return redirect(route('teams.members.show', $invite->team)); + } + +} \ No newline at end of file diff --git a/src/stubs/listeners/JoinTeamListener.stub b/src/stubs/listeners/JoinTeamListener.stub new file mode 100644 index 0000000..9ce4e60 --- /dev/null +++ b/src/stubs/listeners/JoinTeamListener.stub @@ -0,0 +1,21 @@ +forget('invite_token'); + } + } +} \ No newline at end of file diff --git a/src/stubs/routes.stub b/src/stubs/routes.stub new file mode 100644 index 0000000..4fb439e --- /dev/null +++ b/src/stubs/routes.stub @@ -0,0 +1,19 @@ + + +/** + * Teamwork routes + */ +Route::get('teams', 'Teamwork\TeamController@index')->name('teams.index'); +Route::get('teams/create', 'Teamwork\TeamController@create')->name('teams.create'); +Route::post('teams', 'Teamwork\TeamController@store')->name('teams.store'); +Route::get('edit/{id}', 'Teamwork\TeamController@edit')->name('teams.edit'); +Route::put('edit/{id}', 'Teamwork\TeamController@update')->name('teams.update'); +Route::delete('destroy/{id}', 'Teamwork\TeamController@destroy')->name('teams.destroy'); +Route::get('teams/switch/{id}', 'Teamwork\TeamController@switchTeam')->name('teams.switch'); + +Route::get('teams/members/{id}', 'Teamwork\TeamMemberController@show')->name('teams.members.show'); +Route::get('teams/members/resend/{invite_id}', 'Teamwork\TeamMemberController@resendInvite')->name('teams.members.resend_invite'); +Route::post('teams/members/{id}', 'Teamwork\TeamMemberController@invite')->name('teams.members.invite'); +Route::delete('teams/members/{id}/{user_id}', 'Teamwork\TeamMemberController@destroy')->name('teams.members.destroy'); + +Route::get('accept/{token}', 'Teamwork\AuthController@acceptInvite')->name('teams.accept_invite'); \ No newline at end of file diff --git a/src/stubs/views/create.blade.php b/src/stubs/views/create.blade.php new file mode 100644 index 0000000..4ae96b9 --- /dev/null +++ b/src/stubs/views/create.blade.php @@ -0,0 +1,41 @@ +@extends('layouts.app') + +@section('content') +
+
+
+
+
Create a new team
+
+
+ {!! csrf_field() !!} + +
+ + +
+ + + @if ($errors->has('name')) + + {{ $errors->first('name') }} + + @endif +
+
+ + +
+
+ +
+
+
+
+
+
+
+
+@endsection diff --git a/src/stubs/views/edit.blade.php b/src/stubs/views/edit.blade.php new file mode 100644 index 0000000..3456abf --- /dev/null +++ b/src/stubs/views/edit.blade.php @@ -0,0 +1,42 @@ +@extends('layouts.app') + +@section('content') +
+
+
+
+
Edit team {{$team->name}}
+
+
+ + {!! csrf_field() !!} + +
+ + +
+ + + @if ($errors->has('name')) + + {{ $errors->first('name') }} + + @endif +
+
+ + +
+
+ +
+
+
+
+
+
+
+
+@endsection diff --git a/src/stubs/views/emails/invite.blade.php b/src/stubs/views/emails/invite.blade.php new file mode 100644 index 0000000..eb807e8 --- /dev/null +++ b/src/stubs/views/emails/invite.blade.php @@ -0,0 +1,2 @@ +You have been invited to join team {{$team->name}}.
+Click here to join:
{{route('teams.accept_invite', $invite->accept_token)}} diff --git a/src/stubs/views/index.blade.php b/src/stubs/views/index.blade.php new file mode 100644 index 0000000..dd538d1 --- /dev/null +++ b/src/stubs/views/index.blade.php @@ -0,0 +1,69 @@ +@extends('layouts.app') + +@section('content') +
+
+
+
+
+ Teams + + Create team + +
+
+ + + + + + + + + + @foreach($teams as $team) + + + + + + @endforeach + +
NameStatus
{{$team->name}} + @if(auth()->user()->isOwnerOfTeam($team)) + Owner + @else + Member + @endif + + @if(is_null(auth()->user()->currentTeam) || auth()->user()->currentTeam->getKey() !== $team->getKey()) + + Switch + + @else + Current team + @endif + + + Members + + + @if(auth()->user()->isOwnerOfTeam($team)) + + + Edit + + +
+ {!! csrf_field() !!} + + +
+ @endif +
+
+
+
+
+
+@endsection diff --git a/src/stubs/views/members/list.blade.php b/src/stubs/views/members/list.blade.php new file mode 100644 index 0000000..096cd9f --- /dev/null +++ b/src/stubs/views/members/list.blade.php @@ -0,0 +1,99 @@ +@extends('layouts.app') + +@section('content') +
+
+
+
+
+ Members of team "{{$team->name}}" + + Back + +
+
+ + + + + + + + @foreach($team->users AS $user) + + + + + @endforeach +
NameAction
{{$user->name}} + @if(auth()->user()->isOwnerOfTeam($team)) + @if(auth()->user()->getKey() !== $user->getKey()) +
+ {!! csrf_field() !!} + + +
+ @endif + @endif +
+
+
+
+
Pending invitations
+
+ + + + + + + + @foreach($team->invites AS $invite) + + + + + @endforeach +
E-MailAction
{{$invite->email}} + + Resend invite + +
+
+
+ + +
+
Invite to team "{{$team->name}}"
+
+
+ {!! csrf_field() !!} +
+ + +
+ + + @if ($errors->has('email')) + + {{ $errors->first('email') }} + + @endif +
+
+ + +
+
+ +
+
+
+
+
+
+
+
+@endsection diff --git a/tests/TeamInviteTest.php b/tests/TeamInviteTest.php deleted file mode 100644 index 08192be..0000000 --- a/tests/TeamInviteTest.php +++ /dev/null @@ -1,28 +0,0 @@ -once() - ->with('teamwork.team_invites_table') - ->andReturn('team_invites'); - - $teamInvite = new Mpociot\Teamwork\TeamInvite(); - $this->assertEquals( 'team_invites', $teamInvite->getTable() ); - } - -} \ No newline at end of file diff --git a/tests/TeamworkServiceProviderTest.php b/tests/TeamworkServiceProviderTest.php deleted file mode 100644 index cccef59..0000000 --- a/tests/TeamworkServiceProviderTest.php +++ /dev/null @@ -1,152 +0,0 @@ -shouldAllowMockingProtectedMethods(); - $sp->shouldReceive('publishConfig') - ->once() - ->withNoArgs(); - $sp->shouldReceive('publishMigration') - ->once() - ->withNoArgs(); - $sp->boot(); - } - - public function testCanPublishConfig() - { - $test = $this; - - $sp = m::mock('Mpociot\Teamwork\TeamworkServiceProvider[publishes]',['app']) - ->shouldAllowMockingProtectedMethods() - ->shouldDeferMissing(); - $sp->shouldReceive('publishes') - ->once() - ->with( m::type('array') ) - ->andReturnUsing(function ($array) use ($test) { - $test->assertContains('test_config_path/teamwork.php', $array); - }); - $sp->publishConfig(); - } - - public function testCanPublishMigrationOnce() - { - $test = $this; - self::$globResult = []; - $sp = m::mock('Mpociot\Teamwork\TeamworkServiceProvider[publishes]',['app']) - ->shouldAllowMockingProtectedMethods() - ->shouldDeferMissing(); - $sp->shouldReceive('publishes') - ->once() - ->with( m::type('array'), 'migrations' ) - ->andReturnUsing(function ($array) use ($test) { - $values = array_values( $array); - $target = array_pop( $values ); - $test->assertContains('_teamwork_setup_tables.php', $target); - }); - $sp->publishMigration(); - } - - public function testCanNotPublishMigrationWhenItExists() - { - $test = $this; - self::$globResult = [1,2,3]; - $sp = m::mock('Mpociot\Teamwork\TeamworkServiceProvider[publishes]',['app']) - ->shouldAllowMockingProtectedMethods() - ->shouldDeferMissing(); - $sp->shouldReceive('publishes') - ->never(); - $sp->publishMigration(); - } - - public function testCanRegister() - { - $sp = m::mock('Mpociot\Teamwork\TeamworkServiceProvider[mergeConfig,registerTeamwork,registerFacade]',['app']); - $sp->shouldAllowMockingProtectedMethods(); - $sp->shouldReceive('mergeConfig') - ->once() - ->withNoArgs(); - $sp->shouldReceive('registerTeamwork') - ->once() - ->withNoArgs(); - $sp->shouldReceive('registerFacade') - ->once() - ->withNoArgs(); - $sp->register(); - } - - public function testCanRegisterTeamwork() - { - $test = $this; - $app = m::mock('App'); - $sp = m::mock('Mpociot\Teamwork\TeamworkServiceProvider', [$app]); - - $app->shouldReceive('bind') - ->once()->andReturnUsing( - function ($name, $closure) use ($test, $app) { - $test->assertEquals('teamwork', $name); - $test->assertInstanceOf( - 'Mpociot\Teamwork\Teamwork', - $closure($app) - ); - } - ); - $sp->registerTeamwork(); - } - - public function testCanRegisterFacade() - { - $test = $this; - $app = m::mock('App'); - $app->shouldReceive('booting') - ->once() - ->with( m::type('callable') ); - - $sp = m::mock('Mpociot\Teamwork\TeamworkServiceProvider',[$app]) - ->shouldDeferMissing(); - $sp->registerFacade(); - } - - public function testShouldMergeConfig() - { - $test = $this; - $sp = m::mock('Mpociot\Teamwork\TeamworkServiceProvider',['app']) - ->shouldDeferMissing() - ->shouldAllowMockingProtectedMethods(); - - $sp->shouldReceive('mergeConfigFrom') - ->once() - ->with(m::type('string'),'teamwork'); - - $sp->mergeConfig(); - } - - -} \ No newline at end of file diff --git a/tests/TeamworkTeamInviteTraitTest.php b/tests/TeamworkTeamInviteTraitTest.php index 7894dfb..82ee429 100644 --- a/tests/TeamworkTeamInviteTraitTest.php +++ b/tests/TeamworkTeamInviteTraitTest.php @@ -2,10 +2,80 @@ use Illuminate\Support\Facades\Config; use Mockery as m; +use Mpociot\Teamwork\TeamInvite; +use Mpociot\Teamwork\TeamworkTeam; use Mpociot\Teamwork\Traits\TeamworkTeamInviteTrait; -class TeamworkTeamInviteTraitTest extends PHPUnit_Framework_TestCase +class TeamworkTeamInviteTraitTest extends Orchestra\Testbench\TestCase { + protected $user; + protected $invite; + protected $team; + protected $inviter; + + /** + * Define environment setup. + * + * @param \Illuminate\Foundation\Application $app + * + * @return void + */ + protected function getEnvironmentSetUp($app) + { + $app['config']->set('database.default', 'testing'); + $app['config']->set('teamwork.user_model', 'User'); + + \Schema::create('users', function ($table) { + $table->increments('id'); + $table->string('name'); + $table->string('email'); + $table->timestamps(); + $table->softDeletes(); + }); + } + + public function setUp() + { + parent::setUp(); + + $this->artisan('migrate', [ + '--database' => 'testing', + '--realpath' => realpath(__DIR__.'/../src/database'), + ]); + + $this->user = new User(); + $this->user->name = 'Julia'; + $this->user->email = 'foo@baz.com'; + $this->user->save(); + + $this->inviter = new User(); + $this->inviter->name = 'Marcel'; + $this->inviter->email = 'foo@bar.com'; + $this->inviter->save(); + + $this->team = TeamworkTeam::create(['name' => 'Test-Team 2']); + + $this->invite = new TeamInvite(); + $this->invite->team_id = $this->team->getKey(); + $this->invite->user_id = $this->inviter->getKey(); + $this->invite->email = $this->user->email; + $this->invite->type = 'invite'; + $this->invite->accept_token = md5( uniqid( microtime() ) ); + $this->invite->deny_token = md5( uniqid( microtime() ) ); + $this->invite->save(); + } + + protected function getPackageProviders($app) + { + return [\Mpociot\Teamwork\TeamworkServiceProvider::class]; + } + + protected function getPackageAliases($app) + { + return [ + 'Teamwork' => \Mpociot\Teamwork\Facades\Teamwork::class + ]; + } public function tearDown() { @@ -14,52 +84,17 @@ public function tearDown() public function testGetTeams() { - Config::shouldReceive('get') - ->once() - ->with('teamwork.team_model') - ->andReturn('Team'); - - $stub = m::mock( 'TestUserTeamInviteTraitStub[hasOne]' ); - $stub->shouldReceive('hasOne') - ->once() - ->with('Team', 'id', 'team_id' ) - ->andReturn( [] ); - $this->assertEquals( [], $stub->team() ); + $this->assertEquals($this->team->getKey(), $this->invite->team->getKey()); } public function testGetUser() { - Config::shouldReceive('get') - ->once() - ->with('teamwork.user_model') - ->andReturn('User'); - - $stub = m::mock( 'TestUserTeamInviteTraitStub[hasOne]' ); - $stub->shouldReceive('hasOne') - ->once() - ->with('User', 'email', 'email' ) - ->andReturn( [] ); - $this->assertEquals( [], $stub->user() ); + $this->assertEquals($this->user->getKey(), $this->invite->user->getKey()); } public function testGetInviter() { - Config::shouldReceive('get') - ->once() - ->with('teamwork.user_model') - ->andReturn('User'); - - $stub = m::mock( 'TestUserTeamInviteTraitStub[hasOne]' ); - $stub->shouldReceive('hasOne') - ->once() - ->with('User', 'id', 'user_id' ) - ->andReturn( [] ); - $this->assertEquals( [], $stub->inviter() ); + $this->assertEquals($this->inviter->getKey(), $this->invite->inviter->getKey()); } -} - -class TestUserTeamInviteTraitStub extends Illuminate\Database\Eloquent\Model { - - use TeamworkTeamInviteTrait; } \ No newline at end of file diff --git a/tests/TeamworkTeamTest.php b/tests/TeamworkTeamTest.php deleted file mode 100644 index 50afb53..0000000 --- a/tests/TeamworkTeamTest.php +++ /dev/null @@ -1,28 +0,0 @@ -once() - ->with('teamwork.teams_table') - ->andReturn('teams'); - - $team = new Mpociot\Teamwork\TeamworkTeam(); - $this->assertEquals( 'teams', $team->getTable() ); - } - -} \ No newline at end of file diff --git a/tests/TeamworkTest.php b/tests/TeamworkTest.php index 3f55188..b10b0ed 100644 --- a/tests/TeamworkTest.php +++ b/tests/TeamworkTest.php @@ -1,524 +1,269 @@ set('database.default', 'testing'); + $app['config']->set('teamwork.user_model', 'User'); + + \Schema::create('users', function ($table) { + $table->increments('id'); + $table->string('name'); + $table->timestamps(); + $table->softDeletes(); + }); } + public function setUp() + { + parent::setUp(); - public function testUser() + $this->artisan('migrate', [ + '--database' => 'testing', + '--realpath' => realpath(__DIR__.'/../src/database'), + ]); + + $this->user = new User(); + $this->user->name = 'Marcel'; + $this->user->save(); + } + + protected function getPackageProviders($app) { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ - $app = new stdClass(); - $app->auth = m::mock('Auth'); - $teamwork = new Teamwork($app); - $user = m::mock('_mockedUser'); - - /* - |------------------------------------------------------------ - | Expectation - |------------------------------------------------------------ - */ - $app->auth->shouldReceive('user') - ->andReturn($user) - ->once(); - - /* - |------------------------------------------------------------ - | Assertion - |------------------------------------------------------------ - */ - $this->assertSame($user, $teamwork->user()); + return [\Mpociot\Teamwork\TeamworkServiceProvider::class]; } - public function testGetInviteFromAcceptToken() + protected function getPackageAliases($app) { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $token = "asd"; - - - $inviteClass = 'Mpociot\Teamwork\TeamInvite'; - Config::shouldReceive('get') - ->once() - ->with('teamwork.invite_model') - ->andReturn($inviteClass); - $teaminvite = m::mock($inviteClass); - $app->shouldReceive('make')->with($inviteClass)->once()->andReturn( $teaminvite ); - - /* - |------------------------------------------------------------ - | Expectation - |------------------------------------------------------------ - */ - $teaminvite->shouldReceive('where')->once()->with('accept_token', '=', $token)->andReturnSelf(); - $teaminvite->shouldReceive('first')->andReturn( false ); - - /* - |------------------------------------------------------------ - | Assertion - |------------------------------------------------------------ - */ - $this->assertFalse( $teamwork->getInviteFromAcceptToken( $token ) ); + return [ + 'Teamwork' => \Mpociot\Teamwork\Facades\Teamwork::class + ]; } + protected function createInvite($team = null) + { + if(is_null($team)) { + $team = TeamworkTeam::create(['name' => 'Test-Team 1']); + } + + $invite = $this->app->make(Config::get('teamwork.invite_model')); + $invite->user_id = $this->user->getKey(); + $invite->team_id = $team->getKey(); + $invite->type = 'invite'; + $invite->email = 'foo@bar.com'; + $invite->accept_token = md5( uniqid( microtime() ) ); + $invite->deny_token = md5( uniqid( microtime() ) ); + $invite->save(); + + return $invite; + } + + public function tearDown() + { + m::close(); + } + + + public function testUser() + { + $this->assertNull(\Teamwork::user()); + auth()->login($this->user); + $this->assertEquals($this->user, \Teamwork::user()); + } - public function testGetInviteFromDenyToken() + public function testGetInviteFromTokens() { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $token = "asd"; - - $inviteClass = 'Mpociot\Teamwork\TeamInvite'; - Config::shouldReceive('get') - ->once() - ->with('teamwork.invite_model') - ->andReturn($inviteClass); - $teaminvite = m::mock($inviteClass); - $app->shouldReceive('make')->with($inviteClass)->once()->andReturn( $teaminvite ); - - /* - |------------------------------------------------------------ - | Expectation - |------------------------------------------------------------ - */ - $teaminvite->shouldReceive('where')->once()->with('deny_token', '=', $token)->andReturnSelf(); - $teaminvite->shouldReceive('first')->andReturn( false ); - - /* - |------------------------------------------------------------ - | Assertion - |------------------------------------------------------------ - */ - $this->assertFalse( $teamwork->getInviteFromDenyToken( $token ) ); + $invite = $this->createInvite(); + + $this->assertEquals($invite->toArray(), \Teamwork::getInviteFromAcceptToken($invite->accept_token)->toArray()); + $this->assertEquals($invite->toArray(), \Teamwork::getInviteFromDenyToken($invite->deny_token)->toArray()); } public function testDenyInvite() { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $token = "asd"; - $teaminvite = m::mock('Mpociot\Teamwork\TeamInvite'); - - /* - |------------------------------------------------------------ - | Expectation - |------------------------------------------------------------ - */ - $teaminvite->shouldReceive('delete')->once()->andReturn( true ); - - $teamwork->denyInvite( $teaminvite ); + $invite = $this->createInvite(); + \Teamwork::denyInvite( $invite ); + $this->assertNull(TeamInvite::find($invite->getKey())); } public function testHasPendingInviteFalse() { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ - $email = "asd@fake.com"; - $team_id = 1; - - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $token = "asd"; - - - $inviteClass = 'Mpociot\Teamwork\TeamInvite'; - Config::shouldReceive('get') - ->once() - ->with('teamwork.invite_model') - ->andReturn($inviteClass); - $teaminvite = m::mock($inviteClass); - $app->shouldReceive('make')->with($inviteClass)->once()->andReturn( $teaminvite ); - - /* - |------------------------------------------------------------ - | Expectation - |------------------------------------------------------------ - */ - $teaminvite->shouldReceive('where')->once()->with('email', "=", $email)->andReturnSelf(); - $teaminvite->shouldReceive('where')->once()->with('team_id', "=", $team_id)->andReturnSelf(); - $teaminvite->shouldReceive('first')->once()->andReturn( false ); - - $this->assertFalse( $teamwork->hasPendingInvite( $email, $team_id ) ); + $this->assertFalse( \Teamwork::hasPendingInvite( 'foo@bar.com', 1 ) ); } public function testHasPendingInviteTrue() { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ - $email = "asd@fake.com"; - $team_id = 1; - - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $token = "asd"; - - $inviteClass = 'Mpociot\Teamwork\TeamInvite'; - Config::shouldReceive('get') - ->once() - ->with('teamwork.invite_model') - ->andReturn($inviteClass); - $teaminvite = m::mock($inviteClass); - $app->shouldReceive('make')->with($inviteClass)->once()->andReturn( $teaminvite ); - - /* - |------------------------------------------------------------ - | Expectation - |------------------------------------------------------------ - */ - $teaminvite->shouldReceive('where')->once()->with('email', "=", $email)->andReturnSelf(); - $teaminvite->shouldReceive('where')->once()->with('team_id', "=", $team_id)->andReturnSelf(); - $teaminvite->shouldReceive('first')->once()->andReturnSelf(); - - $this->assertTrue( $teamwork->hasPendingInvite( $email, $team_id ) ); + $invite = $this->createInvite(); + $this->assertTrue( \Teamwork::hasPendingInvite( $invite->email, $invite->team_id ) ); } public function testHasPendingInviteFromObject() { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ - $email = "asd@fake.com"; - $team_id = 1; - - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $team = m::mock('stdClass'); - $team->shouldReceive('getKey')->once()->andReturn( $team_id ); - $token = "asd"; - - $inviteClass = 'Mpociot\Teamwork\TeamInvite'; - Config::shouldReceive('get') - ->once() - ->with('teamwork.invite_model') - ->andReturn($inviteClass); - $teaminvite = m::mock($inviteClass); - $app->shouldReceive('make')->with($inviteClass)->once()->andReturn( $teaminvite ); - - /* - |------------------------------------------------------------ - | Expectation - |------------------------------------------------------------ - */ - $teaminvite->shouldReceive('where')->once()->with('email', "=", $email)->andReturnSelf(); - $teaminvite->shouldReceive('where')->once()->with('team_id', "=", $team_id)->andReturnSelf(); - $teaminvite->shouldReceive('first')->once()->andReturnSelf(); - - $this->assertTrue( $teamwork->hasPendingInvite( $email, $team ) ); + $team = TeamworkTeam::create(['name' => 'Test-Team 1']); + $invite = $this->createInvite($team); + $this->assertTrue( \Teamwork::hasPendingInvite( $invite->email, $team ) ); } + public function testHasPendingInviteFromArray() { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ - $email = "asd@fake.com"; - $team_id = 1; - - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $team = ["id" => $team_id]; - $token = "asd"; - - $inviteClass = 'Mpociot\Teamwork\TeamInvite'; - Config::shouldReceive('get') - ->once() - ->with('teamwork.invite_model') - ->andReturn($inviteClass); - $teaminvite = m::mock($inviteClass); - $app->shouldReceive('make')->with($inviteClass)->once()->andReturn( $teaminvite ); - - /* - |------------------------------------------------------------ - | Expectation - |------------------------------------------------------------ - */ - $teaminvite->shouldReceive('where')->once()->with('email', "=", $email)->andReturnSelf(); - $teaminvite->shouldReceive('where')->once()->with('team_id', "=", $team_id)->andReturnSelf(); - $teaminvite->shouldReceive('first')->once()->andReturnSelf(); - - $this->assertTrue( $teamwork->hasPendingInvite( $email, $team ) ); + $team = TeamworkTeam::create(['name' => 'Test-Team 1']); + $invite = $this->createInvite($team); + $this->assertTrue( \Teamwork::hasPendingInvite( $invite->email, $team->toArray() ) ); + } + + public function testCanNotInviteToUserWithoutEmail() + { + $team = TeamworkTeam::create(['name' => 'Test-Team 1']); + $this->user->attachTeam($team); + auth()->login($this->user); + + $this->setExpectedException('Exception','The provided object has no "email" attribute and is not a string.'); + \Teamwork::inviteToTeam( $this->user ); + } + + public function testCanAcceptInvite() + { + $team = TeamworkTeam::create(['name' => 'Test-Team 1']); + $invite = $this->createInvite($team); + auth()->login($this->user); + \Teamwork::acceptInvite( $invite ); + + $this->assertCount(1, $this->user->teams); + $this->assertEquals($team->getKey(), $this->user->current_team_id); + + $this->assertNull(TeamInvite::find($invite->getKey())); } public function testCanInviteToTeam() { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ + auth()->login($this->user); + $email = "asd@fake.com"; - $team_id = 1; - - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $app->auth = m::mock('Auth'); - $user = m::mock('User'); - $user->shouldReceive('getKey')->once()->andReturn(1); - - $app->auth->shouldReceive('user') - ->andReturn($user) - ->once(); - - $inviteClass = 'Mpociot\Teamwork\TeamInvite'; - Config::shouldReceive('get') - ->once() - ->with('teamwork.invite_model') - ->andReturn($inviteClass); - $teaminvite = m::mock($inviteClass); - $app->shouldReceive('make')->with($inviteClass)->once()->andReturn( $teaminvite ); - - /* - |------------------------------------------------------------ - | Expectation - |------------------------------------------------------------ - */ - $teaminvite->shouldReceive('setAttribute')->andReturnSelf(); - $teaminvite->shouldReceive('save')->once()->andReturnSelf(); + $team = TeamworkTeam::create(['name' => 'test']); $callback = m::mock('stdClass'); $callback->shouldReceive('callback')->once() - ->with( $teaminvite )->andReturn(); - - $teamwork->inviteToTeam( $email, $team_id, array($callback,'callback') ); - + ->with( m::type(TeamInvite::class) )->andReturn(); + \Teamwork::inviteToTeam( $email, $team->getKey(), array($callback,'callback') ); + + $this->seeInDatabase(config('teamwork.team_invites_table'),[ + 'email' => 'asd@fake.com', + 'user_id' => $this->user->getKey(), + 'team_id' => $team->getKey() + ]); } public function testCanInviteToTeamWithObject() { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ + auth()->login($this->user); + $email = "asd@fake.com"; - $team_id = 1; - - $team = m::mock('stdClass'); - $team->shouldReceive('getKey')->once()->andReturn($team_id); - - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $app->auth = m::mock('Auth'); - $user = m::mock('User'); - $user->email = "test@mail.de"; - $user->shouldReceive('getKey')->once()->andReturn(1); - - $app->auth->shouldReceive('user') - ->andReturn($user) - ->once(); - - $inviteClass = 'Mpociot\Teamwork\TeamInvite'; - Config::shouldReceive('get') - ->once() - ->with('teamwork.invite_model') - ->andReturn($inviteClass); - $teaminvite = m::mock($inviteClass); - $app->shouldReceive('make')->with($inviteClass)->once()->andReturn( $teaminvite ); - - /* - |------------------------------------------------------------ - | Expectation - |------------------------------------------------------------ - */ - $teaminvite->shouldReceive('setAttribute')->andReturnSelf(); - $teaminvite->shouldReceive('save')->once()->andReturnSelf(); + $team = TeamworkTeam::create(['name' => 'test']); $callback = m::mock('stdClass'); $callback->shouldReceive('callback')->once() - ->with( $teaminvite )->andReturn(); - - $teamwork->inviteToTeam( $user, $team, array($callback,'callback') ); - + ->with( m::type(TeamInvite::class) )->andReturn(); + \Teamwork::inviteToTeam( $email, $team, array($callback,'callback') ); + + $this->seeInDatabase(config('teamwork.team_invites_table'),[ + 'email' => 'asd@fake.com', + 'user_id' => $this->user->getKey(), + 'team_id' => $team->getKey() + ]); } public function testCanInviteToTeamWithArray() { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ + auth()->login($this->user); + $email = "asd@fake.com"; - $team_id = 1; - - $team = ["id" => $team_id]; - - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $app->auth = m::mock('Auth'); - $user = m::mock('User'); - $user->email = "test@mail.de"; - $user->shouldReceive('getKey')->once()->andReturn(1); - - $app->auth->shouldReceive('user') - ->andReturn($user) - ->once(); - - $inviteClass = 'Mpociot\Teamwork\TeamInvite'; - Config::shouldReceive('get') - ->once() - ->with('teamwork.invite_model') - ->andReturn($inviteClass); - $teaminvite = m::mock($inviteClass); - $app->shouldReceive('make')->with($inviteClass)->once()->andReturn( $teaminvite ); - - /* - |------------------------------------------------------------ - | Expectation - |------------------------------------------------------------ - */ - $teaminvite->shouldReceive('setAttribute')->andReturnSelf(); - $teaminvite->shouldReceive('save')->once()->andReturnSelf(); + $team = TeamworkTeam::create(['name' => 'test']); $callback = m::mock('stdClass'); $callback->shouldReceive('callback')->once() - ->with( $teaminvite )->andReturn(); - - $teamwork->inviteToTeam( $user, $team, array($callback,'callback') ); - + ->with( m::type(TeamInvite::class) )->andReturn(); + \Teamwork::inviteToTeam( $email, $team->toArray(), array($callback,'callback') ); + + $this->seeInDatabase(config('teamwork.team_invites_table'),[ + 'email' => 'asd@fake.com', + 'user_id' => $this->user->getKey(), + 'team_id' => $team->getKey() + ]); } - public function testCanInviteToTeamWithNull() + public function testCanInviteToTeamWithUser() { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ - $email = "asd@fake.com"; - $team_id = 1; - - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $app->auth = m::mock('Auth'); - $user = m::mock('User'); - $user->current_team_id = $team_id; - $user->email = "test@mail.de"; - $user->shouldReceive('getKey')->once()->andReturn(1); - - $app->auth->shouldReceive('user') - ->andReturn($user); - - $inviteClass = 'Mpociot\Teamwork\TeamInvite'; - Config::shouldReceive('get') - ->once() - ->with('teamwork.invite_model') - ->andReturn($inviteClass); - $teaminvite = m::mock($inviteClass); - $app->shouldReceive('make')->with($inviteClass)->once()->andReturn( $teaminvite ); - - /* - |------------------------------------------------------------ - | Expectation - |------------------------------------------------------------ - */ - $teaminvite->shouldReceive('setAttribute')->andReturnSelf(); - $teaminvite->shouldReceive('save')->once()->andReturnSelf(); + auth()->login($this->user); + $this->user->email = "asd@fake.com"; + $team = TeamworkTeam::create(['name' => 'test']); $callback = m::mock('stdClass'); $callback->shouldReceive('callback')->once() - ->with( $teaminvite )->andReturn(); - - $teamwork->inviteToTeam( $user, null, array($callback,'callback') ); - + ->with( m::type(TeamInvite::class) )->andReturn(); + \Teamwork::inviteToTeam( $this->user, $team->toArray(), array($callback,'callback') ); + + $this->seeInDatabase(config('teamwork.team_invites_table'),[ + 'email' => 'asd@fake.com', + 'user_id' => $this->user->getKey(), + 'team_id' => $team->getKey() + ]); } - public function testCanNotInviteToUserWithoutEmail() + public function testCanInviteToTeamWithNull() { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ - $email = "asd@fake.com"; - $team_id = 1; - - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $app->auth = m::mock('Auth'); - $user = m::mock('User'); - $user->current_team_id = $team_id; - $user->shouldReceive('getKey')->never(); - - $app->auth->shouldReceive('user') - ->andReturn($user); - - $app->shouldReceive('make')->with('Mpociot\Teamwork\TeamInvite')->never(); + auth()->login($this->user); - $this->setExpectedException('Exception','The provided object has no "email" attribute and is not a string.'); + $email = "asd@fake.com"; + $team = TeamworkTeam::create(['name' => 'test']); + $this->user->attachTeam($team); - $teamwork->inviteToTeam( $user ); + $callback = m::mock('stdClass'); + $callback->shouldReceive('callback')->once() + ->with( m::type(TeamInvite::class) )->andReturn(); + \Teamwork::inviteToTeam( $email, null, array($callback,'callback') ); + $this->seeInDatabase(config('teamwork.team_invites_table'),[ + 'email' => 'asd@fake.com', + 'team_id' => $team->getKey() + ]); } - public function testCanAcceptInvite() + public function testCanInviteToTeamWithoutCallback() { - /* - |------------------------------------------------------------ - | Set - |------------------------------------------------------------ - */ - $team_id = 1; - - $app = m::mock('App'); - $teamwork = new Teamwork($app); - $app->auth = m::mock('Auth'); - $user = m::mock('User'); - $user->current_team_id = $team_id; - - $app->auth->shouldReceive('user') - ->andReturn($user); - - $teaminvite = m::mock('Mpociot\Teamwork\TeamInvite'); - $teaminvite->shouldReceive('setAttribute')->andReturnSelf(); - $teaminvite->shouldReceive('getAttribute')->andReturnSelf(); - $teaminvite->team = "1"; - $teaminvite->shouldReceive('delete')->once(); + auth()->login($this->user); + $email = "asd@fake.com"; + $team = TeamworkTeam::create(['name' => 'test']); + $this->user->attachTeam($team); - $user->shouldReceive('attachTeam')->with($teaminvite->team); - - $teamwork->acceptInvite( $teaminvite ); + \Teamwork::inviteToTeam( $email ); + $this->seeInDatabase(config('teamwork.team_invites_table'),[ + 'email' => 'asd@fake.com', + 'team_id' => $team->getKey() + ]); } + } + diff --git a/tests/UserHasTeamsTraitTest.php b/tests/UserHasTeamsTraitTest.php index 45b3e0c..371b06a 100644 --- a/tests/UserHasTeamsTraitTest.php +++ b/tests/UserHasTeamsTraitTest.php @@ -1,377 +1,278 @@ set('database.default', 'testing'); + $app['config']->set('teamwork.user_model', 'User'); + + \Schema::create('users', function ($table) { + $table->increments('id'); + $table->string('name'); + $table->timestamps(); + $table->softDeletes(); + }); } - public function testGetTeams() + public function setUp() { - Config::shouldReceive('get') - ->once() - ->with('teamwork.team_model') - ->andReturn('Team'); - - Config::shouldReceive('get') - ->once() - ->with('teamwork.team_user_table') - ->andReturn('team_user'); - - $stub = m::mock( 'TestUserHasTeamsTraitStub[belongsToMany]' ); - $stub->shouldReceive('belongsToMany') - ->once() - ->with('Team', 'team_user', 'user_id', 'team_id' ) - ->andReturn( [] ); - $this->assertEquals( [], $stub->teams() ); - } + parent::setUp(); - public function testGetCurrentTeam() - { - Config::shouldReceive('get') - ->once() - ->with('teamwork.team_model') - ->andReturn('Team'); - - $stub = m::mock( 'TestUserHasTeamsTraitStub[hasOne]' ); - $stub->shouldReceive('hasOne') - ->once() - ->with('Team', 'id', 'current_team_id' ) - ->andReturn( [] ); - $this->assertEquals( [], $stub->currentTeam() ); + $this->artisan('migrate', [ + '--database' => 'testing', + '--realpath' => realpath(__DIR__.'/../src/database'), + ]); + + $this->user = new User(); + $this->user->name = 'Marcel'; + $this->user->save(); } - public function testGetOwnedTeams() + protected function getPackageProviders($app) { - $stub = m::mock( 'TestUserHasTeamsTraitStub[teams,where,getKey]' ); - $stub->shouldReceive('teams')->andReturnSelf(); - $stub->shouldReceive('where') - ->once() - ->with('owner_id', '=', 'getKey' ) - ->andReturn( [] ); - $stub->shouldReceive('getKey') - ->once() - ->andReturn( 'getKey' ); - $this->assertEquals( [], $stub->ownedTeams() ); + return [\Mpociot\Teamwork\TeamworkServiceProvider::class]; } - - public function testGetInvites() + protected function getPackageAliases($app) { - Config::shouldReceive('get') - ->once() - ->with('teamwork.invite_model') - ->andReturn('Invite'); - - $stub = m::mock( 'TestUserHasTeamsTraitStub[hasMany]' ); - $stub->shouldReceive('hasMany') - ->once() - ->with('Invite', 'email', 'email' ) - ->andReturn( [] ); - $this->assertEquals( [], $stub->invites() ); + return [ + 'Teamwork' => \Mpociot\Teamwork\Facades\Teamwork::class + ]; } - - public function testIsTeamOwner() + public function testNewUserHasNoTeams() { - $stub = m::mock( 'TestUserHasTeamsTraitStub[isOwner]' ); - $stub->shouldReceive('isOwner') - ->once() - ->andReturn( false ); - $this->assertFalse( $stub->isTeamOwner() ); + $user = new User(); + $user->name = 'Marcel'; + $user->save(); + + $this->assertCount(0, $user->teams); + $this->assertEquals(0, $user->current_team_id); + $this->assertNull($user->currentTeam); + $this->assertCount(0, $user->ownedTeams); + $this->assertCount(0, $user->invites); } - public function testAttachTeams() + public function testAttachingTeamSetsCurrentTeam() { - $teams = array(1,2,3,4,5,6,7,8); - $stub = m::mock( 'TestUserHasTeamsTraitStub[attachTeam]' ); - $stub->shouldReceive('attachTeam') - ->times(count($teams)); - $stub->attachTeams($teams); - } + $team = TeamworkTeam::create(['name' => 'Test-Team']); + $this->assertNull($this->user->currentTeam); + $this->user->attachTeam($team); - public function testDetachTeams() - { - $teams = array(1,2,3,4,5,6,7,8); - $stub = m::mock( 'TestUserHasTeamsTraitStub[detachTeam]' ); - $stub->shouldReceive('detachTeam') - ->times(count($teams)); - $stub->detachTeams($teams); + $this->assertEquals(1, $this->user->currentTeam->getKey()); } - public function testRetrieveTeamIdReturnsInteger() + public function testCanAttachTeamToUser() { - $stub = m::mock( 'TestUserHasTeamsTraitStub' ); - $this->assertEquals(1, $stub->retrieveTeamId( 1 ) ); - } + $team = TeamworkTeam::create(['name' => 'Test-Team']); - public function testRetrieveTeamIdReturnsArrayKey() - { - $stub = m::mock( 'TestUserHasTeamsTraitStub' ); - $this->assertEquals(1, $stub->retrieveTeamId( ["id" => 1] ) ); - } + $this->user->attachTeam($team); - public function testRetrieveTeamIdReturnsObjectKey() - { - $team_id = 1; - $team = m::mock('stdClass'); - $team->shouldReceive('getKey')->once()->andReturn( $team_id ); - $stub = m::mock( 'TestUserHasTeamsTraitStub' ); - $this->assertEquals($team_id, $stub->retrieveTeamId( $team ) ); + // Reload relation + $this->assertCount(1, $this->user->teams); + $this->assertEquals(TeamworkTeam::find(1)->toArray(), $this->user->currentTeam->toArray()); } - public function testIsOwner() + public function testCanAttachTeamAsArrayToUser() { - $stub = m::mock( 'TestUserHasTeamsTraitStub[teams,first,getKey]' ); - $stub->shouldReceive('first') - ->once() - ->andReturn( true ); + $team = TeamworkTeam::create(['name' => 'Test-Team']); - $stub->shouldReceive('getKey') - ->once() - ->andReturn( "key" ); + $this->user->attachTeam($team->toArray()); - $stub->shouldReceive('where') - ->once() - ->with( "owner_id" , "=", "key" ) - ->andReturnSelf(); - - $stub->shouldReceive('teams') - ->andReturnSelf(); - - $this->assertTrue( $stub->isOwner() ); + // Reload relation + $this->assertCount(1, $this->user->teams); + $this->assertEquals(TeamworkTeam::find(1)->toArray(), $this->user->currentTeam->toArray()); } - - - public function testAttachTeamSetsCurrentTeamId() + public function testCanAttachTeamAsIDToUser() { - $team = 1; + $team = TeamworkTeam::create(['name' => 'Test-Team']); - $stub = m::mock( 'TestUserHasTeamsTraitStub[teams,save,attach,load]' ); - $stub->teams = m::mock('stdClass'); - $stub->teams->shouldReceive('contains') - ->with( $team ) - ->andReturn( false ); - $stub->shouldReceive('save') - ->once(); + $this->user->attachTeam($team->getKey()); - $stub->shouldReceive('teams') - ->once() - ->andReturnSelf(); + // Reload relation + $this->assertCount(1, $this->user->teams); + $this->assertEquals(TeamworkTeam::find(1)->toArray(), $this->user->currentTeam->toArray()); + } - $stub->shouldReceive('load') - ->once() - ->with('teams'); + public function testIsTeamOwner() + { + $team = TeamworkTeam::create(['name' => 'Test-Team']); + $this->user->attachTeam($team->getKey()); - $stub->shouldReceive('attach') - ->once() - ->with($team); + $this->assertFalse($this->user->isTeamOwner()); + $this->assertFalse($this->user->isOwner()); - $stub->current_team_id = null; - $stub->attachTeam( $team ); + $team2 = TeamworkTeam::create(['name' => 'Test-Team', 'owner_id' => $this->user->getKey()]); + $this->user->attachTeam($team2->getKey()); - $this->assertEquals( $team, $stub->current_team_id ); + $this->assertTrue($this->user->isTeamOwner()); + $this->assertTrue($this->user->isOwner()); } - public function testAttachTeamDoesNotOverrideCurrentTeamId() + public function testIsOwnerOfTeam() { - $team = 1; - - $stub = m::mock( 'TestUserHasTeamsTraitStub[teams,save,attach,load]' ); - $stub->teams = m::mock('stdClass'); - $stub->teams->shouldReceive('contains') - ->with( $team ) - ->andReturn( false ); - $stub->shouldReceive('save') - ->never(); + $team = TeamworkTeam::create(['name' => 'Test-Team']); + $this->user->attachTeam($team->getKey()); - $stub->shouldReceive('teams') - ->once() - ->andReturnSelf(); + $this->assertFalse($this->user->isOwnerOfTeam($team)); - $stub->shouldReceive('load') - ->once() - ->with('teams'); + $team = TeamworkTeam::create(['name' => 'Test-Team', 'owner_id' => $this->user->getKey()]); + $this->user->attachTeam($team->getKey()); - $stub->shouldReceive('attach') - ->once() - ->with($team); - - $stub->current_team_id = 2; - $stub->attachTeam( $team ); - - $this->assertEquals( 2, $stub->current_team_id ); + $this->assertTrue($this->user->isOwnerOfTeam($team)); } - public function testAttachTeamDoesNotAttachTeamIdWhenItExists() + public function testGetOwnedTeams() { - $team = 1; - - $stub = m::mock( 'TestUserHasTeamsTraitStub[teams,save,attach,load]' ); - $stub->teams = m::mock('stdClass'); - $stub->teams->shouldReceive('contains') - ->with( $team ) - ->andReturn( true ); - $stub->shouldReceive('save') - ->never(); - - $stub->shouldReceive('teams') - ->never() - ->andReturnSelf(); + $team = TeamworkTeam::create(['name' => 'Test-Team', 'owner_id' => $this->user->getKey()]); + $this->user->attachTeam($team->getKey()); + $this->assertCount(1, $this->user->ownedTeams); + } - $stub->shouldReceive('load') - ->once() - ->with('teams'); + public function testCanDetachTeam() + { + $team1 = TeamworkTeam::create(['name' => 'Test-Team 1']); + $team2 = TeamworkTeam::create(['name' => 'Test-Team 2']); + $team3 = TeamworkTeam::create(['name' => 'Test-Team 3']); - $stub->shouldReceive('attach') - ->never(); + $this->user->attachTeam($team1); + $this->user->attachTeam($team2); + $this->user->attachTeam($team3); - $stub->current_team_id = 2; - $stub->attachTeam( $team ); + $this->assertCount(3, $this->user->teams()->get()); - $this->assertEquals( 2, $stub->current_team_id ); + $this->user->detachTeam($team2); + $this->assertCount(2, $this->user->teams()->get()); } - public function testDetachTeamUnsetsCurrentTeamId() + public function testDetachTeamResetsCurrentTeam() { - $team = 1; - - $stub = m::mock( 'TestUserHasTeamsTraitStub[teams,save,detach]' ); - $stub->teams = []; - - $stub->shouldReceive('save') - ->once(); + $team = TeamworkTeam::create(['name' => 'Test-Team 1']); - $stub->shouldReceive('teams') - ->once() - ->andReturnSelf(); - $stub->shouldReceive('detach') - ->once() - ->with($team); + $this->user->attachTeam($team); - $stub->current_team_id = 1; - $stub->detachTeam( $team ); + $this->assertEquals($team->getKey(), $this->user->currentTeam->getKey()); - $this->assertNull( $stub->current_team_id ); + $this->user->detachTeam($team); + $this->assertNull($this->user->currentTeam); } - public function testDetachTeamDoesNotUnsetsCurrentTeamIdWhenSet() + public function testCanAttachMultipleTeams() { - $team = 1; + $team1 = TeamworkTeam::create(['name' => 'Test-Team 1']); + $team2 = TeamworkTeam::create(['name' => 'Test-Team 2']); + $team3 = TeamworkTeam::create(['name' => 'Test-Team 3']); - $stub = m::mock( 'TestUserHasTeamsTraitStub[teams,save,detach]' ); - $stub->teams = [2]; + $this->user->attachTeams([ + $team1, + $team2, + $team3 + ]); + + $this->assertCount(3, $this->user->teams()->get()); + } - $stub->shouldReceive('save') - ->never(); + public function testCanDetachMultipleTeams() + { + $team1 = TeamworkTeam::create(['name' => 'Test-Team 1']); + $team2 = TeamworkTeam::create(['name' => 'Test-Team 2']); + $team3 = TeamworkTeam::create(['name' => 'Test-Team 3']); - $stub->shouldReceive('teams') - ->once() - ->andReturnSelf(); - $stub->shouldReceive('detach') - ->once() - ->with($team); + $this->user->attachTeams([ + $team1, + $team2, + $team3 + ]); - $stub->current_team_id = 1; - $stub->detachTeam( $team ); + $this->assertCount(3, $this->user->teams()->get()); - $this->assertNotNull( $stub->current_team_id ); - } + $this->user->detachTeams([ + $team1, + $team3 + ]); - public function testSwitchTeamToNull() - { - Config::shouldReceive('get') - ->never(); - $stub = m::mock( 'TestUserHasTeamsTraitStub[save]' ); - $stub->shouldReceive('save') - ->once(); - $stub->current_team_id = 1; - $stub->switchTeam( 0 ); - $this->assertEquals( 0, $stub->current_team_id ); + $this->assertCount(1, $this->user->teams()->get()); } - public function testSwitchTeamToNullWithNull() + public function testCurrentTeamGetsResetWhenDetached() { - Config::shouldReceive('get') - ->never(); - $stub = m::mock( 'TestUserHasTeamsTraitStub[save]' ); - $stub->shouldReceive('save') - ->once(); - $stub->current_team_id = 1; - $stub->switchTeam( null ); - $this->assertNull( $stub->current_team_id ); - } + $team1 = TeamworkTeam::create(['name' => 'Test-Team 1']); + $team2 = TeamworkTeam::create(['name' => 'Test-Team 2']); + $team3 = TeamworkTeam::create(['name' => 'Test-Team 3']); - public function testSwitchTeamFails() - { - $team = 1; + $this->user->attachTeams([ + $team1, + $team2, + $team3 + ]); - Config::shouldReceive('get') - ->once() - ->with( 'teamwork.team_model' ) - ->andReturn( 'TestTeamworkTeamModelStub' ); + $this->assertEquals($team1->getKey(), $this->user->currentTeam->getKey()); + $this->user->detachTeam($team1); - $stub = m::mock( 'TestUserHasTeamsTraitStub[save]' ); - $stub->shouldReceive('save') - ->never(); - $stub->current_team_id = null; - $this->setExpectedException('Illuminate\Database\Eloquent\ModelNotFoundException'); - $stub->switchTeam( $team ); + $this->assertNull($this->user->currentTeam); } - public function testSwitchTeamUserNotInTeam() + public function testUserCanSwitchTeam() { - $team = 1; + $team1 = TeamworkTeam::create(['name' => 'Test-Team 1']); + $team2 = TeamworkTeam::create(['name' => 'Test-Team 2']); + $team3 = TeamworkTeam::create(['name' => 'Test-Team 3']); + + $this->user->attachTeams([ + $team1, + $team2, + $team3 + ]); + $this->assertEquals($team1->getKey(), $this->user->currentTeam->getKey()); + $this->user->switchTeam($team2); + $this->assertEquals($team2->getKey(), $this->user->currentTeam->getKey()); + } - Config::shouldReceive('get') - ->once() - ->with( 'teamwork.team_model' ) - ->andReturn( 'TestTeamworkTeamModelNotInTeamStub' ); + public function testUserCannotSwitchToInvalidTeam() + { + $team1 = TeamworkTeam::create(['name' => 'Test-Team 1']); + $team2 = TeamworkTeam::create(['name' => 'Test-Team 2']); + $team3 = TeamworkTeam::create(['name' => 'Test-Team 3']); - $stub = m::mock( 'TestUserHasTeamsTraitStub[save,getKey]' ); - $stub->shouldReceive('getKey') - ->once() - ->andReturn( 5 ); + $this->user->attachTeams([ + $team1, + $team2 + ]); - $stub->shouldReceive('save') - ->never(); $this->setExpectedException('Mpociot\Teamwork\Exceptions\UserNotInTeamException', - 'The user is not in the team Test Team'); - $stub->switchTeam( $team ); + 'The user is not in the team Test-Team 3'); + $this->user->switchTeam($team3); } + public function testUserCannotSwitchToNotExistingTeam() + { -} + $team1 = TeamworkTeam::create(['name' => 'Test-Team 1']); + $team2 = TeamworkTeam::create(['name' => 'Test-Team 2']); -class TestTeamworkTeamModelStub { - public function find(){} -} -class TestTeamworkTeamModelNotInTeamStub { + $this->user->attachTeams([ + $team1, + $team2 + ]); - public function find(){ - $mock = m::mock('stdClass'); - $mock->name = "Test Team"; - $mock->users = m::mock('stdClass'); - $mock->users->shouldReceive('contains') - ->once() - ->with( 5 ) - ->andReturn( false ); - return $mock; + $this->setExpectedException('Illuminate\Database\Eloquent\ModelNotFoundException'); + $this->user->switchTeam(3); } -} - -class TestUserHasTeamsTraitStub extends Illuminate\Database\Eloquent\Model { - use UserHasTeams; } \ No newline at end of file diff --git a/tests/models/User.php b/tests/models/User.php new file mode 100644 index 0000000..544e15d --- /dev/null +++ b/tests/models/User.php @@ -0,0 +1,5 @@ +