diff --git a/src/resources/js/app.js b/src/resources/js/app.js
index 65c7c6f5..226f6ff5 100644
--- a/src/resources/js/app.js
+++ b/src/resources/js/app.js
@@ -1,82 +1,85 @@
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap')
window.Vue = require('vue')
import AppComponent from '../vue/components/App'
import MenuComponent from '../vue/components/Menu'
import router from '../vue/js/routes.js'
import VueToastr from '@deveodk/vue-toastr'
-const app = new Vue({
- el: '#app',
- components: {
- 'app-component': AppComponent,
- 'menu-component': MenuComponent
- },
- router,
- methods: {
- clearFormValidation: form => {
- $(form).find('.is-invalid').removeClass('is-invalid')
- $(form).find('.invalid-feedback').remove()
- }
- },
- mounted() {
- this.$root.$on('clearFormValidation', (form) => {
- this.clearFormValidation(form)
- })
- }
-})
-
-Vue.use(VueToastr, {
- defaultPosition: 'toast-bottom-right',
- defaultTimeout: 50000
-})
-
// Add a response interceptor for general/validation error handler
+// This have to be before Vue and Router setup. Otherwise we would
+// not be able to handle axios responses initiated from inside
+// components created/mounted handlers (e.g. signup code verification link)
window.axios.interceptors.response.use(
response => {
// Do nothing
return response
},
error => {
var error_msg
if (error.response && error.response.status == 422) {
error_msg = "Form validation error"
$.each(error.response.data.errors || {}, (idx, msg) => {
$('form').each((i, form) => {
const input_name = ($(form).data('validation-prefix') || '') + idx
const input = $('#' + input_name)
if (input.length) {
input.addClass('is-invalid')
.parent().append($('
')
.text($.type(msg) === 'string' ? msg : msg.join('
')))
return false
}
});
})
$('form .is-invalid').first().focus()
}
else if (error.response && error.response.data) {
error_msg = error.response.data.message
}
else {
error_msg = error.request ? error.request.statusText : error.message
}
app.$toastr('error', error_msg || "Server Error", 'Error')
// Pass the error as-is
return Promise.reject(error)
}
)
+
+const app = new Vue({
+ el: '#app',
+ components: {
+ 'app-component': AppComponent,
+ 'menu-component': MenuComponent
+ },
+ router,
+ methods: {
+ clearFormValidation: form => {
+ $(form).find('.is-invalid').removeClass('is-invalid')
+ $(form).find('.invalid-feedback').remove()
+ }
+ },
+ mounted() {
+ this.$root.$on('clearFormValidation', (form) => {
+ this.clearFormValidation(form)
+ })
+ }
+})
+
+Vue.use(VueToastr, {
+ defaultPosition: 'toast-bottom-right',
+ defaultTimeout: 50000
+})
diff --git a/src/resources/views/layouts/app.blade.php b/src/resources/views/layouts/app.blade.php
index 23908f25..463a090d 100644
--- a/src/resources/views/layouts/app.blade.php
+++ b/src/resources/views/layouts/app.blade.php
@@ -1,22 +1,22 @@
{{ config('app.name') }} -- @yield('title')
- @laravelPWA
+ {{-- TODO: PWA disabled for now: @laravelPWA --}}
+
@yield('content')
-
diff --git a/src/resources/vue/components/Signup.vue b/src/resources/vue/components/Signup.vue
index 2575efb0..5be756f5 100644
--- a/src/resources/vue/components/Signup.vue
+++ b/src/resources/vue/components/Signup.vue
@@ -1,165 +1,184 @@
Step 1/3
Sign up to start your free month.
Step 2/3
We sent out a confirmation code to your email address.
Enter the code we sent you, or click the link in the message.
Step 3/3
Create your Kolab identity (you can choose additional addresses later).
diff --git a/src/resources/vue/js/routes.js b/src/resources/vue/js/routes.js
index c414645b..2e4373a0 100644
--- a/src/resources/vue/js/routes.js
+++ b/src/resources/vue/js/routes.js
@@ -1,69 +1,70 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import DashboardComponent from '../components/Dashboard'
import Error404Component from '../components/404'
import LoginComponent from '../components/Login'
import LogoutComponent from '../components/Logout'
import SignupComponent from '../components/Signup'
import store from './store'
const routes = [
{
path: '/',
redirect: { name: 'login' }
},
{
path: '/dashboard',
name: 'dashboard',
component: DashboardComponent,
meta: { requiresAuth: true }
},
{
path: '/login',
name: 'login',
component: LoginComponent
},
{
path: '/logout',
name: 'logout',
component: LogoutComponent
},
{
path: '/signup/:code?',
name: 'signup',
component: SignupComponent
},
{
+ name: '404',
path: '*',
component: Error404Component
}
]
const router = new VueRouter({
mode: 'history',
routes
})
router.beforeEach((to, from, next) => {
// check if the route requires authentication and user is not logged in
if (to.matched.some(route => route.meta.requiresAuth) && !store.state.isLoggedIn) {
// redirect to login page
next({ name: 'login' })
return
}
// if logged in redirect to dashboard
if (to.path === '/login' && store.state.isLoggedIn) {
next({ name: 'dashboard' })
return
}
next()
})
export default router
diff --git a/src/tests/Browser/ErrorTest.php b/src/tests/Browser/ErrorTest.php
index f0e674b3..a92d4f4d 100644
--- a/src/tests/Browser/ErrorTest.php
+++ b/src/tests/Browser/ErrorTest.php
@@ -1,36 +1,38 @@
browse(function (Browser $browser) {
$browser->visit('/unknown');
$browser->waitFor('#app > #error-page');
$browser->assertVisible('#app > #primary-menu');
$this->assertSame('404', $browser->text('#error-page .code'));
$this->assertSame('Not Found', $browser->text('#error-page .message'));
+ });
+ $this->browse(function (Browser $browser) {
$browser->visit('/login/unknown');
$browser->waitFor('#app > #error-page');
$browser->assertVisible('#app > #primary-menu');
$this->assertSame('404', $browser->text('#error-page .code'));
$this->assertSame('Not Found', $browser->text('#error-page .message'));
});
// TODO: Test the same as above, but with use of Vue router
}
}
diff --git a/src/tests/Browser/SignupTest.php b/src/tests/Browser/SignupTest.php
index b6b5c63e..5fe5382d 100644
--- a/src/tests/Browser/SignupTest.php
+++ b/src/tests/Browser/SignupTest.php
@@ -1,267 +1,320 @@
delete();
+ User::where('email', 'signuptestdusk@' . \config('app.domain'))->delete();
parent::tearDown();
}
+ /**
+ * Test signup code verification with a link
+ *
+ * @return void
+ */
+ public function testSignupCodeByLink()
+ {
+ // Test invalid code (invalid format)
+ $this->browse(function (Browser $browser) {
+ // Register Signup page element selectors we'll be using
+ $browser->onWithoutAssert(new Signup());
+
+ // TODO: Test what happens if user is logged in
+
+ $browser->visit('/signup/invalid-code');
+
+ // TODO: According to https://github.com/vuejs/vue-router/issues/977
+ // it is not yet easily possible to display error page component (route)
+ // without changing the URL
+ // TODO: Instead of css selector we should probably define page/component
+ // and use it instead
+ $browser->waitFor('#error-page');
+ });
+
+ // Test invalid code (valid format)
+ $this->browse(function (Browser $browser) {
+ $browser->visit('/signup/XXXXX-code');
+
+ // FIXME: User will not be able to continue anyway, so we should
+ // either display 1st step or 404 error page
+ $browser->waitFor('@step1');
+ $browser->waitFor('.toast-error');
+ $browser->click('.toast-error'); // remove the toast
+ });
+
+ // Test valid code
+ $this->browse(function (Browser $browser) {
+ $code = SignupCode::create([
+ 'data' => [
+ 'email' => 'User@example.org',
+ 'name' => 'User Name',
+ ]
+ ]);
+
+ $browser->visit('/signup/' . $code->short_code . '-' . $code->code);
+
+ $browser->waitFor('@step3');
+ $browser->assertMissing('@step1');
+ $browser->assertMissing('@step2');
+
+ // FIXME: Find a nice way to read javascript data without using hidden inputs
+ $this->assertSame($code->code, $browser->value('@step2 #signup_code'));
+
+ // TODO: Test if the signup process can be completed
+ });
+ }
+
/**
* Test 1st step of the signup process
*
* @return void
*/
public function testSignupStep1()
{
$this->browse(function (Browser $browser) {
$browser->visit(new Signup());
$browser->assertVisible('@step1');
// Here we expect two text inputs and Continue
$browser->with('@step1', function ($step) {
$step->assertVisible('#signup_name');
$step->assertFocused('#signup_name');
$step->assertVisible('#signup_email');
$step->assertVisible('[type=submit]');
});
// Submit empty form
// Both Step 1 inputs are required, so after pressing Submit
// we expect focus to be moved to the first input
$browser->with('@step1', function ($step) {
$step->click('[type=submit]');
$step->assertFocused('#signup_name');
});
// Submit invalid email
// We expect email input to have is-invalid class added, with .invalid-feedback element
$browser->with('@step1', function ($step) use ($browser) {
$step->type('#signup_name', 'Test User');
$step->type('#signup_email', '@test');
$step->click('[type=submit]');
$step->waitFor('#signup_email.is-invalid');
$step->waitFor('#signup_email + .invalid-feedback');
$browser->waitFor('.toast-error');
$browser->click('.toast-error'); // remove the toast
});
// Submit valid data
// We expect error state on email input to be removed, and Step 2 form visible
$browser->with('@step1', function ($step) {
$step->type('#signup_name', 'Test User');
$step->type('#signup_email', 'BrowserSignupTestUser1@kolab.org');
$step->click('[type=submit]');
$step->assertMissing('#signup_email.is-invalid');
$step->assertMissing('#signup_email + .invalid-feedback');
$step->waitUntilMissing('#signup_code[value=""]');
});
$browser->waitFor('@step2');
$browser->assertMissing('@step1');
});
}
/**
* Test 2nd Step of the signup process
*
* @depends testSignupStep1
* @return void
*/
public function testSignupStep2()
{
$this->browse(function (Browser $browser) {
$browser->assertVisible('@step2');
// Here we expect one text input, Back and Continue buttons
$browser->with('@step2', function ($step) {
$step->assertVisible('#signup_short_code');
$step->assertFocused('#signup_short_code');
$step->assertVisible('[type=button]');
$step->assertVisible('[type=submit]');
});
// Test Back button functionality
$browser->click('@step2 [type=button]');
$browser->waitFor('@step1');
+ $browser->assertFocused('@step1 #signup_name');
$browser->assertMissing('@step2');
// Submit valid Step 1 data (again)
$browser->with('@step1', function ($step) {
$step->type('#signup_name', 'Test User');
$step->type('#signup_email', 'BrowserSignupTestUser1@kolab.org');
$step->click('[type=submit]');
});
$browser->waitFor('@step2');
$browser->assertMissing('@step1');
// Submit invalid code
// We expect code input to have is-invalid class added, with .invalid-feedback element
$browser->with('@step2', function ($step) use ($browser) {
$step->type('#signup_short_code', 'XXXXX');
$step->click('[type=submit]');
$browser->waitFor('.toast-error');
$step->assertVisible('#signup_short_code.is-invalid');
$step->assertVisible('#signup_short_code + .invalid-feedback');
$step->assertFocused('#signup_short_code');
$browser->click('.toast-error'); // remove the toast
});
// Submit valid code
// We expect error state on code input to be removed, and Step 3 form visible
$browser->with('@step2', function ($step) {
// Get the code and short_code from database
// FIXME: Find a nice way to read javascript data without using hidden inputs
$code = $step->value('#signup_code');
$this->assertNotEmpty($code);
$code = SignupCode::find($code);
$step->type('#signup_short_code', $code->short_code);
$step->click('[type=submit]');
$step->assertMissing('#signup_short_code.is-invalid');
$step->assertMissing('#signup_short_code + .invalid-feedback');
});
$browser->waitFor('@step3');
$browser->assertMissing('@step2');
});
-
- // TODO: Test code verification with an external link
}
/**
* Test 3rd Step of the signup process
*
* @depends testSignupStep2
* @return void
*/
public function testSignupStep3()
{
$this->browse(function (Browser $browser) {
$browser->assertVisible('@step3');
// Here we expect one text input, Back and Continue buttons
$browser->with('@step3', function ($step) {
$step->assertVisible('#signup_login');
$step->assertVisible('#signup_password');
$step->assertVisible('#signup_confirm');
$step->assertVisible('[type=button]');
$step->assertVisible('[type=submit]');
$step->assertFocused('#signup_login');
$step->assertSeeIn('#signup_login + span', '@' . \config('app.domain'));
});
// Test Back button
$browser->click('@step3 [type=button]');
$browser->waitFor('@step2');
+ $browser->assertFocused('@step2 #signup_short_code');
$browser->assertMissing('@step3');
// TODO: Test form reset when going back
// Submit valid code again
$browser->with('@step2', function ($step) {
$code = $step->value('#signup_code');
$this->assertNotEmpty($code);
$code = SignupCode::find($code);
$step->type('#signup_short_code', $code->short_code);
$step->click('[type=submit]');
});
$browser->waitFor('@step3');
// Submit invalid data
$browser->with('@step3', function ($step) use ($browser) {
$step->assertFocused('#signup_login');
$step->type('#signup_login', '*');
$step->type('#signup_password', '12345678');
$step->type('#signup_confirm', '123456789');
$step->click('[type=submit]');
$browser->waitFor('.toast-error');
$step->assertVisible('#signup_login.is-invalid');
$step->assertVisible('#signup_login + span + .invalid-feedback');
$step->assertVisible('#signup_password.is-invalid');
$step->assertVisible('#signup_password + .invalid-feedback');
$step->assertFocused('#signup_login');
$browser->click('.toast-error'); // remove the toast
});
// Submit invalid data (valid login, invalid password)
$browser->with('@step3', function ($step) use ($browser) {
- // Make sure the user does not exist (it may happen when executing
- // tests again after failure)
- User::where('email', 'SignupTestDusk@' . \config('app.domain'))->delete();
-
// FIXME: For some reason I can't just use ->value() here
$step->clear('#signup_login');
$step->type('#signup_login', 'SignupTestDusk');
$step->click('[type=submit]');
$browser->waitFor('.toast-error');
$step->assertVisible('#signup_password.is-invalid');
$step->assertVisible('#signup_password + .invalid-feedback');
$step->assertMissing('#signup_login.is-invalid');
$step->assertMissing('#signup_login + span + .invalid-feedback');
$step->assertFocused('#signup_password');
$browser->click('.toast-error'); // remove the toast
});
// Submit valid data
$browser->with('@step3', function ($step) {
// FIXME: For some reason I can't just use ->value() here
$step->clear('#signup_confirm');
$step->type('#signup_confirm', '12345678');
$step->click('[type=submit]');
});
$browser->waitUntilMissing('@step3');
// At this point we should be auto-logged-in to dashboard
$dashboard = new Dashboard();
$dashboard->assert($browser);
// FIXME: Is it enough to be sure user is logged in?
});
}
}
diff --git a/src/tests/Feature/Controller/SignupTest.php b/src/tests/Feature/Controller/SignupTest.php
index 8987411f..eddd25df 100644
--- a/src/tests/Feature/Controller/SignupTest.php
+++ b/src/tests/Feature/Controller/SignupTest.php
@@ -1,409 +1,405 @@
'SignupControllerTest1@' . \config('app.domain')]);
}
/**
* {@inheritDoc}
*
* @return void
*/
public function tearDown(): void
{
- User::where('email', 'SignupLogin@' . \config('app.domain'))
+ User::where('email', 'signuplogin@' . \config('app.domain'))
->orWhere('email', 'SignupControllerTest1@' . \config('app.domain'))
->delete();
parent::tearDown();
}
/**
* Test signup initialization with invalid input
*
* @return void
*/
public function testSignupInitInvalidInput()
{
// Empty input data
$data = [];
$response = $this->post('/api/auth/signup/init', $data);
$json = $response->json();
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
$this->assertCount(2, $json['errors']);
$this->assertArrayHasKey('email', $json['errors']);
$this->assertArrayHasKey('name', $json['errors']);
// Data with missing name
$data = [
'email' => 'UsersApiControllerTest1@UsersApiControllerTest.com',
'password' => 'simple123',
'password_confirmation' => 'simple123'
];
$response = $this->post('/api/auth/signup/init', $data);
$json = $response->json();
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
$this->assertCount(1, $json['errors']);
$this->assertArrayHasKey('name', $json['errors']);
// Data with invalid email (but not phone number)
$data = [
'email' => '@example.org',
'name' => 'Signup User',
'password' => 'simple123',
'password_confirmation' => 'simple123'
];
$response = $this->post('/api/auth/signup/init', $data);
$json = $response->json();
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
$this->assertCount(1, $json['errors']);
$this->assertArrayHasKey('email', $json['errors']);
// TODO: Test phone validation
}
/**
* Test signup initialization with valid input
*
* @return array
*/
public function testSignupInitValidInput()
{
Queue::fake();
// Assert that no jobs were pushed...
Queue::assertNothingPushed();
$data = [
'email' => 'testuser@external.com',
'name' => 'Signup User',
'password' => 'simple123',
'password_confirmation' => 'simple123'
];
$response = $this->post('/api/auth/signup/init', $data);
$json = $response->json();
$response->assertStatus(200);
$this->assertCount(2, $json);
$this->assertSame('success', $json['status']);
$this->assertNotEmpty($json['code']);
// Assert the email sending job was pushed once
Queue::assertPushed(\App\Jobs\SignupVerificationEmail::class, 1);
// Assert the job has proper data assigned
Queue::assertPushed(\App\Jobs\SignupVerificationEmail::class, function ($job) use ($data, $json) {
// Access protected property
$reflection = new \ReflectionClass($job);
$code = $reflection->getProperty('code');
$code->setAccessible(true);
$code = $code->getValue($job);
return $code->code === $json['code']
&& $code->data['email'] === $data['email']
&& $code->data['name'] === $data['name'];
});
return [
'code' => $json['code'],
'email' => $data['email'],
'name' => $data['name'],
];
}
/**
* Test signup code verification with invalid input
*
* @depends testSignupInitValidInput
* @return void
*/
public function testSignupVerifyInvalidInput(array $result)
{
// Empty data
$data = [];
$response = $this->post('/api/auth/signup/verify', $data);
$json = $response->json();
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
$this->assertCount(2, $json['errors']);
$this->assertArrayHasKey('code', $json['errors']);
$this->assertArrayHasKey('short_code', $json['errors']);
// Data with existing code but missing short_code
$data = [
'code' => $result['code'],
];
$response = $this->post('/api/auth/signup/verify', $data);
$json = $response->json();
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
$this->assertCount(1, $json['errors']);
$this->assertArrayHasKey('short_code', $json['errors']);
// Data with invalid short_code
$data = [
'code' => $result['code'],
'short_code' => 'XXXX',
];
$response = $this->post('/api/auth/signup/verify', $data);
$json = $response->json();
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
$this->assertCount(1, $json['errors']);
$this->assertArrayHasKey('short_code', $json['errors']);
// TODO: Test expired code
}
/**
* Test signup code verification with valid input
*
* @depends testSignupInitValidInput
*
* @return array
*/
public function testSignupVerifyValidInput(array $result)
{
$code = SignupCode::find($result['code']);
$data = [
'code' => $code->code,
'short_code' => $code->short_code,
];
$response = $this->post('/api/auth/signup/verify', $data);
$json = $response->json();
$response->assertStatus(200);
$this->assertCount(3, $json);
$this->assertSame('success', $json['status']);
$this->assertSame($result['email'], $json['email']);
$this->assertSame($result['name'], $json['name']);
return $result;
}
/**
* Test last signup step with invalid input
*
* @depends testSignupVerifyValidInput
* @return void
*/
public function testSignupInvalidInput(array $result)
{
// Empty data
$data = [];
$response = $this->post('/api/auth/signup', $data);
$json = $response->json();
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
$this->assertCount(2, $json['errors']);
$this->assertArrayHasKey('login', $json['errors']);
$this->assertArrayHasKey('password', $json['errors']);
// Passwords do not match
$data = [
'login' => 'test',
'password' => 'test',
'password_confirmation' => 'test2',
];
$response = $this->post('/api/auth/signup', $data);
$json = $response->json();
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
$this->assertCount(1, $json['errors']);
$this->assertArrayHasKey('password', $json['errors']);
// Login too short
$data = [
'login' => '1',
'password' => 'test',
'password_confirmation' => 'test',
];
$response = $this->post('/api/auth/signup', $data);
$json = $response->json();
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
$this->assertCount(1, $json['errors']);
$this->assertArrayHasKey('login', $json['errors']);
// Login invalid
$data = [
'login' => 'żżżżż',
'password' => 'test',
'password_confirmation' => 'test',
];
$response = $this->post('/api/auth/signup', $data);
$json = $response->json();
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
$this->assertCount(1, $json['errors']);
$this->assertArrayHasKey('login', $json['errors']);
// Data with invalid short_code
$data = [
'login' => 'TestLogin',
'password' => 'test',
'password_confirmation' => 'test',
'code' => $result['code'],
'short_code' => 'XXXX',
];
$response = $this->post('/api/auth/signup', $data);
$json = $response->json();
$response->assertStatus(422);
$this->assertSame('error', $json['status']);
$this->assertCount(1, $json['errors']);
$this->assertArrayHasKey('short_code', $json['errors']);
}
/**
* Test last signup step with valid input (user creation)
*
* @depends testSignupVerifyValidInput
* @return void
*/
public function testSignupValidInput(array $result)
{
$identity = \strtolower('SignupLogin@') . \config('app.domain');
- // Make sure the user does not exist (it may happen when executing
- // tests again after failure)
- User::where('email', $identity)->delete();
-
$code = SignupCode::find($result['code']);
$data = [
'login' => 'SignupLogin',
'password' => 'test',
'password_confirmation' => 'test',
'code' => $code->code,
'short_code' => $code->short_code,
];
$response = $this->post('/api/auth/signup', $data);
$json = $response->json();
$response->assertStatus(200);
$this->assertCount(4, $json);
$this->assertSame('success', $json['status']);
$this->assertSame('bearer', $json['token_type']);
$this->assertTrue(!empty($json['expires_in']) && is_int($json['expires_in']) && $json['expires_in'] > 0);
$this->assertNotEmpty($json['access_token']);
// Check if the code has been removed
$this->assertNull(SignupCode::where($result['code'])->first());
// Check if the user has been created
$user = User::where('email', $identity)->first();
$this->assertNotEmpty($user);
$this->assertSame($identity, $user->email);
$this->assertSame($result['name'], $user->name);
// Check external email in user settings
$this->assertSame($result['email'], $user->getSetting('external_email', 'not set'));
// TODO: Check if the access token works
}
/**
* List of email address validation cases for testValidateEmail()
*
* @return array Arguments for testValidateEmail()
*/
public function dataValidateEmail()
{
// To access config from dataProvider method we have to refreshApplication() first
$this->refreshApplication();
$domain = \config('app.domain');
return [
// general cases (invalid)
['', false, 'validation.emailinvalid'],
['example.org', false, 'validation.emailinvalid'],
['@example.org', false, 'validation.emailinvalid'],
['test@localhost', false, 'validation.emailinvalid'],
// general cases (valid)
['test@domain.tld', false, null],
['&@example.org', false, null],
// kolab identity cases
['admin@' . $domain, true, 'validation.emailexists'],
['administrator@' . $domain, true, 'validation.emailexists'],
['sales@' . $domain, true, 'validation.emailexists'],
['root@' . $domain, true, 'validation.emailexists'],
['&@' . $domain, true, 'validation.emailinvalid'],
['testnonsystemdomain@invalid.tld', true, 'validation.emailinvalid'],
// existing account
['SignupControllerTest1@' . $domain, true, 'validation.emailexists'],
// valid for signup
['test.test@' . $domain, true, null],
['test_test@' . $domain, true, null],
['test-test@' . $domain, true, null],
];
}
/**
* Signup email validation.
*
* Note: Technicly these are mostly unit tests, but let's keep it here for now.
* FIXME: Shall we do a http request for each case?
*
* @dataProvider dataValidateEmail
*/
public function testValidateEmail($email, $signup, $expected_result)
{
$method = new \ReflectionMethod('App\Http\Controllers\API\SignupController', 'validateEmail');
$method->setAccessible(true);
$is_phone = false;
$result = $method->invoke(new SignupController(), $email, $signup);
$this->assertSame($expected_result, $result);
}
}