diff --git a/.scrutinizer.yml b/.scrutinizer.yml
index 49e8c56..7da841a 100644
--- a/.scrutinizer.yml
+++ b/.scrutinizer.yml
@@ -2,3 +2,4 @@ filter:
excluded_paths:
- "public/"
- "tests/"
+ - "resources/assets/js/mixpanel.js"
diff --git a/.travis.yml b/.travis.yml
index 505a405..2ff3f83 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -23,4 +23,3 @@ notifications:
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: never # options: [always|never|change] default: always
-
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7bd8f7e..58a897f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).
(This is already detected in subscription update.)
- Filter any incoming web-hook events that are in test mode.
+## [WIP] - 5 Nov 2017
+### Added
+- unit and feature tests.
+
+### Changed
+- class structure as part of refactoring.
+
## [0.7.2] - 5 Nov 2017
### Fixed
- inclusion of auto-track JS scripts. NPM library is broken and seems to not be maintained anymore, switched to script provided by mixpanel setup instructions.
diff --git a/composer.json b/composer.json
index 4fb76f7..470b014 100644
--- a/composer.json
+++ b/composer.json
@@ -30,6 +30,7 @@
"require-dev": {
"fzaninotto/faker": "~1.4",
"laravel/laravel": "5.5.*",
+ "laravel/browser-kit-testing": "^2.0",
"mockery/mockery": "0.9.*",
"phpmd/phpmd": "^2.6",
"phpunit/phpunit": "5.7.*",
diff --git a/phpunit.xml b/phpunit.xml
index 730c6c8..d7b48a9 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -32,5 +32,6 @@
+
diff --git a/src/LaravelMixpanel.php b/src/LaravelMixpanel.php
index e65c6b5..eba335d 100644
--- a/src/LaravelMixpanel.php
+++ b/src/LaravelMixpanel.php
@@ -12,12 +12,6 @@ class LaravelMixpanel extends Mixpanel
private $defaults;
private $request;
- /**
- * @param Request $request
- * @param array $options
- *
- * @internal param Result $browser
- */
public function __construct(Request $request, array $options = [])
{
$this->defaults = [
@@ -33,12 +27,6 @@ public function __construct(Request $request, array $options = [])
);
}
- /**
- * @param string $event
- * @param array $properties
- *
- * @internal param array $data
- */
public function track($event, $properties = [])
{
$browserInfo = new Browser();
diff --git a/src/Listeners/LaravelMixpanelEventHandler.php b/src/Listeners/LaravelMixpanelEventHandler.php
deleted file mode 100644
index c38252c..0000000
--- a/src/Listeners/LaravelMixpanelEventHandler.php
+++ /dev/null
@@ -1,47 +0,0 @@
-credentials['email'] ?? $event['email'] ?? '';
-
- $authModel = config('auth.providers.users.model', config('auth.model'));
- $user = app($authModel)
- ->where('email', $email)
- ->first();
- $eventName = 'Login Attempted';
-
- event(new MixpanelEvent($user, $eventName));
- }
-
- public function onUserLogin($login)
- {
- $user = $login->user ?? $login;
- event(new MixpanelEvent($user, 'User Logged In'));
- }
-
- public function onUserLogout($logout)
- {
- $user = $logout->user ?? $logout;
- event(new MixpanelEvent($user, 'User Logged Out'));
- }
-
- public function subscribe(Dispatcher $events)
- {
- $events->listen('auth.attempt', self::class . '@onUserLoginAttempt');
- $events->listen('auth.login', self::class . '@onUserLogin');
- $events->listen('auth.logout', self::class . '@onUserLogout');
-
- $events->listen(Attempting::class, self::class . '@onUserLoginAttempt');
- $events->listen(Login::class, self::class . '@onUserLogin');
- $events->listen(Logout::class, self::class . '@onUserLogout');
- }
-}
diff --git a/src/Listeners/LaravelMixpanelUserObserver.php b/src/Listeners/LaravelMixpanelUserObserver.php
index 002a889..b707758 100644
--- a/src/Listeners/LaravelMixpanelUserObserver.php
+++ b/src/Listeners/LaravelMixpanelUserObserver.php
@@ -1,26 +1,26 @@
user, 'User Logged In'));
+ }
+}
diff --git a/src/Listeners/LoginAttempt.php b/src/Listeners/LoginAttempt.php
new file mode 100644
index 0000000..8d56059
--- /dev/null
+++ b/src/Listeners/LoginAttempt.php
@@ -0,0 +1,20 @@
+credentials['email'] ?? $event['email'] ?? '';
+
+ $authModel = config('auth.providers.users.model', config('auth.model'));
+ $user = app($authModel)
+ ->where('email', $email)
+ ->first();
+ $eventName = 'Login Attempted';
+
+ event(new Mixpanel($user, $eventName));
+ }
+}
diff --git a/src/Listeners/Logout.php b/src/Listeners/Logout.php
new file mode 100644
index 0000000..ed769c8
--- /dev/null
+++ b/src/Listeners/Logout.php
@@ -0,0 +1,12 @@
+user, 'User Logged Out'));
+ }
+}
diff --git a/src/Providers/Service.php b/src/Providers/Service.php
index 62e9f86..37d5a2a 100644
--- a/src/Providers/Service.php
+++ b/src/Providers/Service.php
@@ -1,12 +1,17 @@
[
- MixpanelEventListener::class,
- ],
+ MixpanelEvent::class => [MixpanelEventListener::class],
+ Attempting::class => [LoginAttempt::class],
+ Login::class => [LoginListener::class],
+ Logout::class => [LogoutListener::class],
];
public function boot()
{
parent::boot();
- $this->initialize();
- }
-
- protected function initialize()
- {
include __DIR__ . '/../../routes/api.php';
$this->loadViewsFrom(__DIR__ . '/../../resources/views', 'genealabs-laravel-mixpanel');
@@ -39,7 +40,6 @@ protected function initialize()
if (config('services.mixpanel.enable-default-tracking')) {
$authModel = config('auth.providers.users.model') ?? config('auth.model');
$this->app->make($authModel)->observe(new LaravelMixpanelUserObserver());
- app('events')->subscribe(new LaravelMixpanelEventHandler());
}
}
@@ -50,10 +50,7 @@ public function register()
$this->app->singleton('mixpanel', LaravelMixpanel::class);
}
- /**
- * @return array
- */
- public function provides()
+ public function provides() : array
{
return ['genealabs-laravel-mixpanel'];
}
diff --git a/tests/CreatesApplication.php b/tests/CreatesApplication.php
new file mode 100644
index 0000000..30c9253
--- /dev/null
+++ b/tests/CreatesApplication.php
@@ -0,0 +1,40 @@
+copyFixtures([
+ __DIR__ . '/Fixtures/app/Http/Controllers/HomeController.php' => __DIR__ . '/../vendor/laravel/laravel/app/Http/Controllers/HomeController.php',
+ __DIR__ . '/Fixtures/resources/views/home.blade.php' => __DIR__ . '/../vendor/laravel/laravel/resources/views/home.blade.php',
+ __DIR__ . '/Fixtures/resources/views/auth/login.blade.php' => __DIR__ . '/../vendor/laravel/laravel/resources/views/auth/login.blade.php',
+ __DIR__ . '/Fixtures/resources/views/auth/register.blade.php' => __DIR__ . '/../vendor/laravel/laravel/resources/views/auth/register.blade.php',
+ __DIR__ . '/Fixtures/resources/views/auth/passwords/email.blade.php' => __DIR__ . '/../vendor/laravel/laravel/resources/views/auth/passwords/email.blade.php',
+ __DIR__ . '/Fixtures/resources/views/auth/passwords/reset.blade.php' => __DIR__ . '/../vendor/laravel/laravel/resources/views/auth/passwords/email.blade.php',
+ __DIR__ . '/Fixtures/resources/views/layouts/app.blade.php' => __DIR__ . '/../vendor/laravel/laravel/resources/views/layouts/app.blade.php',
+ __DIR__ . '/Fixtures/routes/web.php' => __DIR__ . '/../vendor/laravel/laravel/routes/web.php',
+ ]);
+ $app = require __DIR__ . '/../vendor/laravel/laravel/bootstrap/app.php';
+ $app->make(Kernel::class)->bootstrap();
+ $app->register(Service::class);
+
+ return $app;
+ }
+
+ protected function copyFixtures(array $fixtures)
+ {
+ $fixtures = collect($fixtures)->each(function ($destination, $source) {
+ $pathInfo = pathinfo($destination);
+
+ if (! file_exists($pathInfo['dirname'])) {
+ mkdir($pathInfo['dirname'], 0777, true);
+ }
+
+ copy($source, $destination);
+ });
+ }
+}
diff --git a/tests/Feature/AuthenticationTest.php b/tests/Feature/AuthenticationTest.php
new file mode 100644
index 0000000..c35eec4
--- /dev/null
+++ b/tests/Feature/AuthenticationTest.php
@@ -0,0 +1,69 @@
+create();
+
+ $result = $this->visit('/login')
+ ->type($user->email, 'email')
+ ->type('hoogabaloo', 'password')
+ ->press('Login');
+
+ $this->assertResponseStatus(200);
+ $result->seePageIs('/login');
+ Event::assertDispatched(MixpanelEvent::class, function ($event) use ($user) {
+ return ($event->user->email === $user->email && $event->eventName === 'Login Attempted');
+ });
+ }
+
+ public function testLoginSuccess()
+ {
+ Event::fake([MixpanelEvent::class]);
+ $password = 'hoogabaloo';
+ $user = factory(User::class)->create([
+ 'password' => bcrypt($password),
+ ]);
+
+ $result = $this->visit('/login')
+ ->type($user->email, 'email')
+ ->type($password, 'password')
+ ->press('Login');
+
+ $this->assertResponseStatus(200);
+ $result->seePageIs('/home');
+ Event::assertDispatched(MixpanelEvent::class, function ($event) use ($user) {
+ return ($event->user->email === $user->email && $event->eventName === 'User Logged In');
+ });
+ }
+
+ public function testLogoutSuccess()
+ {
+ Event::fake([MixpanelEvent::class]);
+ $user = factory(User::class)->create();
+
+ $result = $this->actingAs($user)
+ ->post('/logout');
+
+ $this->assertRedirectedTo('/');
+ Event::assertDispatched(MixpanelEvent::class, function ($event) use ($user) {
+ return ($event->user->email === $user->email && $event->eventName === 'User Logged Out');
+ });
+ }
+}
diff --git a/tests/FeatureTestCase.php b/tests/FeatureTestCase.php
new file mode 100644
index 0000000..cb9b9cf
--- /dev/null
+++ b/tests/FeatureTestCase.php
@@ -0,0 +1,13 @@
+middleware('auth');
+ }
+
+ /**
+ * Show the application dashboard.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function index()
+ {
+ return view('home');
+ }
+}
diff --git a/tests/Fixtures/resources/views/auth/login.blade.php b/tests/Fixtures/resources/views/auth/login.blade.php
new file mode 100644
index 0000000..ad371e3
--- /dev/null
+++ b/tests/Fixtures/resources/views/auth/login.blade.php
@@ -0,0 +1,67 @@
+@extends('layouts.app')
+
+@section('content')
+
+@endsection
diff --git a/tests/Fixtures/resources/views/auth/passwords/email.blade.php b/tests/Fixtures/resources/views/auth/passwords/email.blade.php
new file mode 100644
index 0000000..ad38245
--- /dev/null
+++ b/tests/Fixtures/resources/views/auth/passwords/email.blade.php
@@ -0,0 +1,47 @@
+@extends('layouts.app')
+
+@section('content')
+
+
+
+
+
Reset Password
+
+
+ @if (session('status'))
+
+ {{ session('status') }}
+
+ @endif
+
+
+
+
+
+
+
+@endsection
diff --git a/tests/Fixtures/resources/views/auth/passwords/reset.blade.php b/tests/Fixtures/resources/views/auth/passwords/reset.blade.php
new file mode 100644
index 0000000..84ec010
--- /dev/null
+++ b/tests/Fixtures/resources/views/auth/passwords/reset.blade.php
@@ -0,0 +1,70 @@
+@extends('layouts.app')
+
+@section('content')
+
+@endsection
diff --git a/tests/Fixtures/resources/views/auth/register.blade.php b/tests/Fixtures/resources/views/auth/register.blade.php
new file mode 100644
index 0000000..38eef83
--- /dev/null
+++ b/tests/Fixtures/resources/views/auth/register.blade.php
@@ -0,0 +1,77 @@
+@extends('layouts.app')
+
+@section('content')
+
+@endsection
diff --git a/tests/Fixtures/resources/views/home.blade.php b/tests/Fixtures/resources/views/home.blade.php
new file mode 100644
index 0000000..d8437bf
--- /dev/null
+++ b/tests/Fixtures/resources/views/home.blade.php
@@ -0,0 +1,23 @@
+@extends('layouts.app')
+
+@section('content')
+
+
+
+
+
Dashboard
+
+
+ @if (session('status'))
+
+ {{ session('status') }}
+
+ @endif
+
+ You are logged in!
+
+
+
+
+
+@endsection
diff --git a/tests/Fixtures/resources/views/layouts/app.blade.php b/tests/Fixtures/resources/views/layouts/app.blade.php
new file mode 100644
index 0000000..6d3bf22
--- /dev/null
+++ b/tests/Fixtures/resources/views/layouts/app.blade.php
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+ {{ config('app.name', 'Laravel') }}
+
+
+
+
+
+
+
+
+ @yield('content')
+
+
+
+
+
+
diff --git a/tests/Fixtures/routes/web.php b/tests/Fixtures/routes/web.php
new file mode 100644
index 0000000..12fc04c
--- /dev/null
+++ b/tests/Fixtures/routes/web.php
@@ -0,0 +1,20 @@
+name('home');
diff --git a/tests/Unit/ExampleTest.php b/tests/Unit/ExampleTest.php
new file mode 100644
index 0000000..70dc327
--- /dev/null
+++ b/tests/Unit/ExampleTest.php
@@ -0,0 +1,12 @@
+assertTrue(true);
+ }
+}
diff --git a/tests/UnitTestCase.php b/tests/UnitTestCase.php
new file mode 100644
index 0000000..9e88a60
--- /dev/null
+++ b/tests/UnitTestCase.php
@@ -0,0 +1,8 @@
+