Improved data fixtures with Faker (#234)

This commit is contained in:
Kevin Papst
2018-07-24 19:24:58 +02:00
committed by GitHub
parent 20a2d94996
commit 5ccc1c991b
12 changed files with 362 additions and 442 deletions

View File

@@ -40,6 +40,7 @@
"dama/doctrine-test-bundle": "^5.0",
"doctrine/doctrine-fixtures-bundle": "^3.0",
"friendsofphp/php-cs-fixer": "^2.10",
"fzaninotto/faker": "^1.8",
"phpunit/phpunit": "^7.0",
"squizlabs/php_codesniffer": "^3.2",
"symfony/browser-kit": "^4.0",

52
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "1ebffbf7579748f5352725fdc5c63676",
"content-hash": "abbcd10d5163d2365b716059f5587932",
"packages": [
{
"name": "beberlei/DoctrineExtensions",
@@ -5444,6 +5444,56 @@
"description": "A tool to automatically fix PHP code style",
"time": "2018-06-10T08:26:56+00:00"
},
{
"name": "fzaninotto/faker",
"version": "v1.8.0",
"source": {
"type": "git",
"url": "https://github.com/fzaninotto/Faker.git",
"reference": "f72816b43e74063c8b10357394b6bba8cb1c10de"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fzaninotto/Faker/zipball/f72816b43e74063c8b10357394b6bba8cb1c10de",
"reference": "f72816b43e74063c8b10357394b6bba8cb1c10de",
"shasum": ""
},
"require": {
"php": "^5.3.3 || ^7.0"
},
"require-dev": {
"ext-intl": "*",
"phpunit/phpunit": "^4.8.35 || ^5.7",
"squizlabs/php_codesniffer": "^1.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.8-dev"
}
},
"autoload": {
"psr-4": {
"Faker\\": "src/Faker/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "François Zaninotto"
}
],
"description": "Faker is a PHP library that generates fake data for you.",
"keywords": [
"data",
"faker",
"fixtures"
],
"time": "2018-07-12T10:23:15+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.8.1",

View File

@@ -0,0 +1,132 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\DataFixtures;
use App\Entity\Activity;
use App\Entity\Customer;
use App\Entity\Project;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Faker\Factory;
use Faker\Generator;
/**
* Defines the sample data to load in the database when running the unit and
* functional tests or while development.
*
* Execute this command to load the data:
* bin/console doctrine:fixtures:load
*/
class CustomerFixtures extends Fixture
{
public const MIN_CUSTOMERS = 5;
public const MAX_CUSTOMERS = 15;
public const MIN_BUDGET = 0;
public const MAX_BUDGET = 100000;
public const MIN_PROJECTS_PER_CUSTOMER = 10;
public const MAX_PROJECTS_PER_CUSTOMER = 50;
public const MIN_ACTIVITIES_PER_PROJECT = 0;
public const MAX_ACTIVITIES_PER_PROJECT = 15;
/**
* @param ObjectManager $manager
*/
public function load(ObjectManager $manager)
{
$faker = Factory::create();
$amountCustomers = rand(self::MIN_CUSTOMERS, self::MAX_CUSTOMERS);
for ($c = 1; $c <= $amountCustomers; $c++) {
$visibleCustomer = 0 != $c % 3;
$customer = $this->createCustomer($faker, $visibleCustomer);
$projectForCustomer = rand(self::MIN_PROJECTS_PER_CUSTOMER, self::MAX_PROJECTS_PER_CUSTOMER);
for ($p = 1; $p <= $projectForCustomer; $p++) {
$visibleProject = 0 != $p % 3;
$project = $this->createProject($faker, $customer, $visibleProject);
$manager->persist($project);
$activityForProject = rand(self::MIN_ACTIVITIES_PER_PROJECT, self::MAX_ACTIVITIES_PER_PROJECT);
for ($a = 1; $a <= $activityForProject; $a++) {
$visibleActivity = 0 != $a % 3;
$activity = $this->createActivity($faker, $project, $visibleActivity);
$manager->persist($activity);
}
}
$manager->persist($customer);
$manager->flush();
$manager->clear();
}
}
/**
* @param Generator $faker
* @param boolean $visible
* @return Customer
*/
private function createCustomer(Generator $faker, $visible)
{
$entry = new Customer();
$entry
->setCurrency($faker->currencyCode)
->setName($faker->company . ($visible ? '' : ' (x)'))
->setAddress($faker->address)
->setComment($faker->text)
->setNumber('C-' . $faker->ean8)
->setCountry($faker->countryCode)
->setTimezone($faker->timezone)
->setVisible($visible)
;
return $entry;
}
/**
* @param Generator $faker
* @param Customer $customer
* @param boolean $visible
* @return Project
*/
private function createProject(Generator $faker, Customer $customer, $visible)
{
$entry = new Project();
$entry
->setName($faker->catchPhrase . ($visible ? '' : ' (x)'))
->setBudget(rand(self::MIN_BUDGET, self::MAX_BUDGET))
->setComment($faker->text)
->setCustomer($customer)
->setVisible($visible)
;
return $entry;
}
/**
* @param Generator $faker
* @param Project $project
* @param boolean $visible
* @return Activity
*/
private function createActivity(Generator $faker, Project $project, $visible)
{
$entry = new Activity();
$entry
->setName($faker->bs . ($visible ? '' : ' (x)'))
->setProject($project)
->setComment($faker->text)
->setVisible($visible)
;
return $entry;
}
}

View File

@@ -1,50 +0,0 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\DataFixtures;
/**
* Defines reusable sample data.
*/
trait FixturesTrait
{
/**
* @return string[]
*/
protected function getPhrases()
{
return [
'Lorem ipsum dolor sit amet consectetur adipiscing elit',
'Pellentesque vitae velit ex',
'Mauris dapibus risus quis suscipit vulputate',
'Eros diam egestas libero eu vulputate risus',
'In hac habitasse platea dictumst',
'Morbi tempus commodo mattis',
'Ut suscipit posuere justo at vulputate',
'Ut eleifend mauris et risus ultrices egestas',
'Aliquam sodales odio id eleifend tristique',
'Urna nisl sollicitudin id varius orci quam id turpis',
'Nulla porta lobortis ligula vel egestas',
'Curabitur aliquam euismod dolor non ornare',
'Sed varius a risus eget aliquam',
'Nunc viverra elit ac laoreet suscipit',
'Pellentesque et sapien pulvinar consectetur',
];
}
/**
* @return string
*/
protected function getRandomPhrase()
{
$phrases = $this->getPhrases();
return $phrases[array_rand($phrases)];
}
}

View File

@@ -12,6 +12,7 @@ namespace App\DataFixtures;
use App\Entity\InvoiceTemplate;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Faker\Factory;
/**
* Defines the sample data to load in the database when running the unit and
@@ -35,11 +36,13 @@ class InvoiceFixtures extends Fixture
*/
private function loadInvoiceTemplates(ObjectManager $manager)
{
$faker = Factory::create();
$template = new InvoiceTemplate();
$template
->setName('Invoice')
->setTitle('Your company name')
->setCompany('Kimai, Inc.')
->setCompany($faker->company)
->setVat(19)
->setDueDays(14)
->setPaymentTerms(
@@ -49,10 +52,10 @@ class InvoiceFixtures extends Fixture
'as reference.'
)
->setAddress(
'795 Folsom Ave, Suite 600' . PHP_EOL .
'San Francisco, CA 94107' . PHP_EOL .
'Phone: (804) 123-456789' . PHP_EOL .
'Email: email@example.com'
$faker->streetAddress . PHP_EOL .
$faker->city . ', ' . $faker->stateAbbr . ' ' . $faker->postcode . PHP_EOL .
'Phone: ' . $faker->phoneNumber . PHP_EOL .
'Email: ' . $faker->safeEmail
)
;

View File

@@ -10,37 +10,94 @@
namespace App\DataFixtures;
use App\Entity\Activity;
use App\Entity\Customer;
use App\Entity\Project;
use App\Entity\Timesheet;
use App\Entity\User;
use App\Entity\UserPreference;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Faker\Factory;
/**
* Defines the sample data to load in the database when running the unit and
* functional tests or while development.
*
* Execute this command to load the data:
* $ php bin/console doctrine:fixtures:load
* bin/console doctrine:fixtures:load
*/
class TimesheetFixtures extends Fixture
class TimesheetFixtures extends Fixture implements DependentFixtureInterface
{
use FixturesTrait;
public const MIN_TIMESHEETS_PER_USER = 50;
public const MAX_TIMESHEETS_PER_USER = 500;
public const MAX_TIMESHEETS_TOTAL = 5000;
public const MIN_RUNNING_TIMESHEETS_PER_USER = 0;
public const MAX_RUNNING_TIMESHEETS_PER_USER = 3;
public const AMOUNT_TIMESHEET = 5000; // timesheet entries total
public const RATE_MIN = 10; // minimum rate for one hour
public const RATE_MAX = 80; // maximum rate for one hour
public const BATCH_SIZE = 100;
/**
* @return array
*/
public function getDependencies()
{
return array(
UserFixtures::class,
CustomerFixtures::class,
);
}
/**
* {@inheritdoc}
*/
public function load(ObjectManager $manager)
{
$this->loadCustomers($manager);
$this->loadProjects($manager);
$this->loadActivities($manager);
$this->loadTimesheet($manager);
$allUser = $this->getAllUsers($manager);
$activities = $this->getAllActivities($manager);
$faker = Factory::create();
// by using array_pop we make sure that at least one activity has NO entry!
array_pop($activities);
foreach ($allUser as $user) {
// random amount of timesheet entries for every user
$timesheetForUser = rand(self::MIN_TIMESHEETS_PER_USER, self::MAX_TIMESHEETS_PER_USER);
for ($i = 1; $i <= $timesheetForUser; $i++) {
if ($i > self::MAX_TIMESHEETS_TOTAL) {
break;
}
$entry = $this->createTimesheetEntry(
$user,
$activities[array_rand($activities)],
($i % 3 == 0 ? $faker->text : ''),
round($i / 2),
true
);
$manager->persist($entry);
if ($i % self::BATCH_SIZE == 0) {
//echo '['.$i.'] Timesheets for User ' . $user->getId() . PHP_EOL;
$manager->flush();
$manager->clear(Timesheet::class);
}
}
// create active recordings for test user
$activeEntries = rand(self::MIN_RUNNING_TIMESHEETS_PER_USER, self::MAX_RUNNING_TIMESHEETS_PER_USER);
for ($i = 0; $i < $activeEntries; $i++) {
$entry = $this->createTimesheetEntry(
$user,
$activities[array_rand($activities)],
$faker->text
);
$manager->persist($entry);
}
$manager->flush();
$manager->clear(Timesheet::class);
}
$manager->flush();
}
/**
@@ -59,38 +116,6 @@ class TimesheetFixtures extends Fixture
return $all;
}
/**
* @param ObjectManager $manager
* @return Customer[]
*/
protected function getAllCustomers(ObjectManager $manager)
{
$all = [];
/* @var Customer[] $entries */
$entries = $manager->getRepository(Customer::class)->findAll();
foreach ($entries as $temp) {
$all[$temp->getId()] = $temp;
}
return $all;
}
/**
* @param ObjectManager $manager
* @return Project[]
*/
protected function getAllProjects(ObjectManager $manager)
{
$all = [];
/* @var Project[] $entries */
$entries = $manager->getRepository(Project::class)->findAll();
foreach ($entries as $temp) {
$all[$temp->getId()] = $temp;
}
return $all;
}
/**
* @param ObjectManager $manager
* @return Activity[]
@@ -98,7 +123,7 @@ class TimesheetFixtures extends Fixture
protected function getAllActivities(ObjectManager $manager)
{
$all = [];
/* @var Activity[] $entries */
/* @var User[] $entries */
$entries = $manager->getRepository(Activity::class)->findAll();
foreach ($entries as $temp) {
$all[$temp->getId()] = $temp;
@@ -107,44 +132,7 @@ class TimesheetFixtures extends Fixture
return $all;
}
private function loadTimesheet(ObjectManager $manager)
{
$allUser = $this->getAllUsers($manager);
$amountUser = count($allUser);
$allActivity = $this->getAllActivities($manager);
// by using array_pop we make sure that at least one activity has NO entry!
array_pop($allActivity);
for ($i = 0; $i <= self::AMOUNT_TIMESHEET; $i++) {
$entry = $this->createTimesheetEntry(
$allUser[rand(1, $amountUser)],
$allActivity[array_rand($allActivity)],
round($i / 2),
true
);
$manager->persist($entry);
}
// by using array_pop we make sure that at least one user has NO running entry!
array_pop($allUser);
// create active recodinge for test user
foreach ($allUser as $id => $user) {
for ($i = 0; $i < rand(1, 4); $i++) {
$entry = $this->createTimesheetEntry(
$user,
$allActivity[array_rand($allActivity)]
);
$manager->persist($entry);
}
}
$manager->flush();
}
private function createTimesheetEntry(User $user, Activity $activity, $startDay = 0, $setEndDate = false)
private function createTimesheetEntry(User $user, Activity $activity, $description, $startDay = 0, $setEndDate = false)
{
$start = new \DateTime();
if ($startDay > 0) {
@@ -157,12 +145,12 @@ class TimesheetFixtures extends Fixture
//$duration = $end->modify('- ' . $start->getTimestamp() . ' seconds')->getTimestamp();
$duration = $end->getTimestamp() - $start->getTimestamp();
$rate = rand(self::RATE_MIN, self::RATE_MAX);
$rate = $user->getPreferenceValue(UserPreference::HOURLY_RATE);
$entry = new Timesheet();
$entry
->setActivity($activity)
->setDescription($this->getRandomPhrase())
->setDescription($description)
->setUser($user)
->setRate(round(($duration / 3600) * $rate))
->setBegin($start);
@@ -175,270 +163,4 @@ class TimesheetFixtures extends Fixture
return $entry;
}
private function loadCustomers(ObjectManager $manager)
{
$allTimezones = \DateTimeZone::listIdentifiers();
$amountTimezone = count($allTimezones);
$allCustomer = $this->getCustomers();
shuffle($allCustomer);
$i = 1;
foreach ($allCustomer as $customerName) {
$visible = 0 != $i++ % 6;
$entry = new Customer();
$entry
->setCurrency($this->getRandomCurrency())
->setName($customerName . ($visible ? '' : '.'))
->setAddress($this->getRandomLocation())
->setComment($this->getRandomPhrase())
->setVisible($visible)
->setNumber('C0815-42-' . $i)
->setCountry('DE') // TODO randomize country ?
->setTimezone($allTimezones[rand(1, $amountTimezone)]);
$manager->persist($entry);
}
$manager->flush();
}
private function loadProjects(ObjectManager $manager)
{
$allCustomer = $this->getAllCustomers($manager);
foreach ($allCustomer as $id => $customer) {
$projectForCustomer = rand(0, 7);
for ($i = 1; $i <= $projectForCustomer; $i++) {
$visible = 0 != $i % 5;
$entry = new Project();
$entry
->setName($this->getRandomProject() . ($visible ? '' : '.'))
->setBudget(rand(500, 100000))
->setComment($this->getRandomPhrase())
->setCustomer($customer)
->setVisible($visible);
$manager->persist($entry);
}
}
$manager->flush();
}
private function loadActivities(ObjectManager $manager)
{
$allProject = $this->getAllProjects($manager);
foreach ($allProject as $projectId => $project) {
$activityCount = rand(0, 10);
for ($i = 1; $i <= $activityCount; $i++) {
$visible = 0 != $i % 4;
$entry = new Activity();
$entry
->setName($this->getRandomActivity() . ($visible ? '' : '.'))
->setProject($project)
->setComment($this->getRandomPhrase())
->setVisible($visible);
$manager->persist($entry);
}
}
$manager->flush();
}
/**
* @return string[]
*/
private function getActivities()
{
return [
'Designing',
'Programming',
'Testing',
'Documentation',
'Pause',
'Research',
'Meeting',
'Hosting',
'Relaunch',
'Support',
'Refactoring',
'Interview',
'Administration',
'DevOps',
'Management',
'Setup',
'Planning',
'Skiing',
'Eating',
'Watching TV',
'Talking',
'Cooking',
'Writing',
'Reading',
'Brainstroming',
'Post Processing',
];
}
/**
* @return string
*/
private function getRandomActivity()
{
$all = $this->getActivities();
return $all[array_rand($all)];
}
/**
* @return string[]
*/
private function getProjects()
{
return [
'User Experience',
'Database Migration',
'Test Automatisation',
'Website Redesign',
'API Development',
'Hosting & Server',
'Customer Relations',
'Infrastructure',
'Princess Cat',
'Software Upgrade',
'Office Management',
'Project X',
'Customer Excellence',
'Crazy Monkey',
'Interface Design',
'Human Ressources',
'Book Release',
'Studio Photography',
'Professional Art',
'Video Production',
];
}
/**
* @return string
*/
private function getRandomProject()
{
$all = $this->getProjects();
return $all[array_rand($all)];
}
/**
* @return string[]
*/
private function getLocations()
{
return [
'Köln',
'München',
'New York',
'Buenos Aires',
'Hawai',
'Amsterdam',
'London',
'San Francisco',
'Tokyo',
'Berlin',
'Sao Paulo',
'Mexico City',
'Moscow',
'Sankt Petersburg',
'Taiwan',
'Perth',
'Sydney',
'Mumbai',
'Lagos',
'Karachi',
'Shanghai',
'Delhi',
];
}
/**
* @return string
*/
private function getRandomLocation()
{
$all = $this->getLocations();
return $all[array_rand($all)];
}
/**
* @return string[]
*/
private function getCustomers()
{
return [
'Acme University',
'Snake Oil',
'Apple',
'Microsoft',
'Google',
'Oracle',
'Yahoo',
'Twitter',
'Zend',
'SensioLabs',
'Samsung',
'Huawai',
'Yandex',
'Baidu',
'Alphabet',
'Amazon.com',
'Berkshire Hathaway',
'Facebook',
'ExxonMobil',
'Nestle',
'Johnson & Johnson',
'Alibaba',
'General Electric',
'Procter & Gamble',
'Wal-Mart Stores',
'Novartis',
'Coca-Cola',
'Wikipedia',
'Walt Disney',
'Merck',
'Pfizer',
"L'Oréal Group",
"McDonald's",
'China Petroleum & Chemical',
'GlaxoSmithKline'
];
}
/**
* @return string[]
*/
private function getCurrencies()
{
return [
'EUR',
'GBP',
'USD',
'RUB',
'JPY',
'CNY',
'INR'
];
}
/**
* @return string
*/
private function getRandomCurrency()
{
$all = $this->getCurrencies();
return $all[array_rand($all)];
}
}

View File

@@ -13,6 +13,7 @@ use App\Entity\User;
use App\Entity\UserPreference;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Faker\Factory;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
/**
@@ -22,16 +23,23 @@ use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
* Execute this command to load the data:
* $ php bin/console doctrine:fixtures:load
*/
class AppFixtures extends Fixture
class UserFixtures extends Fixture
{
use FixturesTrait;
public const DEFAULT_PASSWORD = 'kitten';
public const DEFAULT_AVATAR = 'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=retro&f=y';
public const USERNAME_USER = 'john_user';
public const USERNAME_TEAMLEAD = 'tony_teamlead';
public const USERNAME_ADMIN = 'anna_admin';
public const USERNAME_SUPER_ADMIN = 'susan_super';
public const AMOUNT_EXTRA_USER = 2;
public const MIN_RATE = 30;
public const MAX_RATE = 120;
public const BATCH_SIZE = 50;
/**
* @var UserPasswordEncoderInterface
*/
@@ -51,17 +59,21 @@ class AppFixtures extends Fixture
*/
public function load(ObjectManager $manager)
{
$this->loadUsers($manager);
$this->loadDefaultAccounts($manager);
$this->loadTestUsers($manager);
}
/**
* Default users for all test cases
*
* @param ObjectManager $manager
*/
private function loadUsers(ObjectManager $manager)
private function loadDefaultAccounts(ObjectManager $manager)
{
$passwordEncoder = $this->encoder;
foreach ($this->getUserDefinition() as $userData) {
$allUsers = $this->getUserDefinition();
foreach ($allUsers as $userData) {
$user = new User();
$user
->setAlias($userData[0])
@@ -72,18 +84,64 @@ class AppFixtures extends Fixture
->setAvatar($userData[5])
->setEnabled($userData[6])
->setPassword($passwordEncoder->encodePassword($user, self::DEFAULT_PASSWORD))
->setPreferences([$this->getUserPreference($user)])
;
$preference = new UserPreference();
$preference->setName(UserPreference::HOURLY_RATE);
$preference->setValue(rand(0, 100));
$preference->setUser($user);
$user->setPreferences([$preference]);
$manager->persist($user);
}
$manager->flush();
$manager->clear();
}
/**
* @param User $user
* @return UserPreference
*/
private function getUserPreference(user $user)
{
$preference = new UserPreference();
$preference->setName(UserPreference::HOURLY_RATE);
$preference->setValue(rand(self::MIN_RATE, self::MAX_RATE));
$preference->setUser($user);
return $preference;
}
/**
* Generate randomized test users
*
* @param ObjectManager $manager
*/
private function loadTestUsers(ObjectManager $manager)
{
$passwordEncoder = $this->encoder;
$faker = Factory::create();
for($i = 1; $i <= self::AMOUNT_EXTRA_USER; $i++) {
$user = new User();
$user
->setAlias($faker->name)
->setTitle(substr($faker->jobTitle, 0, 49))
->setUsername($faker->userName)
->setEmail($faker->email)
->setRoles([User::ROLE_USER])
->setAvatar(self::DEFAULT_AVATAR)
->setEnabled(true)
->setPassword($passwordEncoder->encodePassword($user, self::DEFAULT_PASSWORD))
->setPreferences([$this->getUserPreference($user)])
;
if ($i % self::BATCH_SIZE == 0) {
$manager->flush();
$manager->clear();
}
$manager->persist($user);
}
$manager->flush();
$manager->clear();
}
/**
@@ -93,29 +151,29 @@ class AppFixtures extends Fixture
{
return [
[
'Clara Haynes', 'CFO', 'clara_customer', 'clara_customer@example.com', 'ROLE_CUSTOMER',
'Clara Haynes', 'CFO', 'clara_customer', 'clara_customer@example.com', User::ROLE_CUSTOMER,
'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=monsterid&f=y', true
],
[
'John Doe', 'Developer', self::USERNAME_USER, 'john_user@example.com', 'ROLE_USER',
'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=retro&f=y', true
'John Doe', 'Developer', self::USERNAME_USER, 'john_user@example.com', User::ROLE_USER,
self::DEFAULT_AVATAR, true
],
// inactive user to test login
[
'Chris Deactive', 'Developer (left company)', 'chris_user', 'chris_user@example.com', 'ROLE_USER',
'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=retro&f=y', false
'Chris Deactive', 'Developer (left company)', 'chris_user', 'chris_user@example.com', User::ROLE_USER,
self::DEFAULT_AVATAR, false
],
[
'Tony Maier', 'Head of Sales', self::USERNAME_TEAMLEAD, 'tony_teamlead@example.com', 'ROLE_TEAMLEAD',
'Tony Maier', 'Head of Sales', self::USERNAME_TEAMLEAD, 'tony_teamlead@example.com', User::ROLE_TEAMLEAD,
'https://en.gravatar.com/userimage/3533186/bf2163b1dd23f3107a028af0195624e9.jpeg', true
],
// no avatar to test default image macro
[
'Anna Smith', 'Administrator', self::USERNAME_ADMIN, 'anna_admin@example.com', 'ROLE_ADMIN', null, true
'Anna Smith', 'Administrator', self::USERNAME_ADMIN, 'anna_admin@example.com', User::ROLE_ADMIN, null, true
],
// no alias to test twig username macro
[
null, 'Super Administrator', self::USERNAME_SUPER_ADMIN, 'susan_super@example.com', 'ROLE_SUPER_ADMIN',
null, 'Super Administrator', self::USERNAME_SUPER_ADMIN, 'susan_super@example.com', User::ROLE_SUPER_ADMIN,
'/build/images/default_avatar.png', true
]
];

View File

@@ -43,7 +43,7 @@ class ActivityType extends AbstractType
{
$resolver->setDefaults([
'label' => 'label.activity',
'class' => 'Kimai:Activity',
'class' => Activity::class,
'choice_label' => [$this, 'choiceLabel'],
'group_by' => [$this, 'groupBy'],
'query_builder' => function (ActivityRepository $repo) {

View File

@@ -9,6 +9,7 @@
namespace App\Form\Type;
use App\Entity\Customer;
use App\Repository\CustomerRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
@@ -26,7 +27,7 @@ class CustomerType extends AbstractType
{
$resolver->setDefaults([
'label' => 'label.customer',
'class' => 'Kimai:Customer',
'class' => Customer::class,
'choice_label' => 'name',
'query_builder' => function (CustomerRepository $repo) {
return $repo->builderForEntityType(null);

View File

@@ -113,6 +113,9 @@
"friendsofsymfony/user-bundle": {
"version": "v2.1.2"
},
"fzaninotto/faker": {
"version": "v1.8.0"
},
"jdorn/sql-formatter": {
"version": "v1.2.17"
},

View File

@@ -9,7 +9,7 @@
namespace App\Tests\Controller;
use App\DataFixtures\AppFixtures;
use App\DataFixtures\UserFixtures;
use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Client;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
@@ -31,29 +31,29 @@ abstract class ControllerBaseTest extends WebTestCase
switch ($role) {
case User::ROLE_SUPER_ADMIN:
$client = self::createClient([], [
'PHP_AUTH_USER' => AppFixtures::USERNAME_SUPER_ADMIN,
'PHP_AUTH_PW' => AppFixtures::DEFAULT_PASSWORD,
'PHP_AUTH_USER' => UserFixtures::USERNAME_SUPER_ADMIN,
'PHP_AUTH_PW' => UserFixtures::DEFAULT_PASSWORD,
]);
break;
case User::ROLE_ADMIN:
$client = self::createClient([], [
'PHP_AUTH_USER' => AppFixtures::USERNAME_ADMIN,
'PHP_AUTH_PW' => AppFixtures::DEFAULT_PASSWORD,
'PHP_AUTH_USER' => UserFixtures::USERNAME_ADMIN,
'PHP_AUTH_PW' => UserFixtures::DEFAULT_PASSWORD,
]);
break;
case User::ROLE_TEAMLEAD:
$client = self::createClient([], [
'PHP_AUTH_USER' => AppFixtures::USERNAME_TEAMLEAD,
'PHP_AUTH_PW' => AppFixtures::DEFAULT_PASSWORD,
'PHP_AUTH_USER' => UserFixtures::USERNAME_TEAMLEAD,
'PHP_AUTH_PW' => UserFixtures::DEFAULT_PASSWORD,
]);
break;
case User::ROLE_USER:
$client = self::createClient([], [
'PHP_AUTH_USER' => AppFixtures::USERNAME_USER,
'PHP_AUTH_PW' => AppFixtures::DEFAULT_PASSWORD,
'PHP_AUTH_USER' => UserFixtures::USERNAME_USER,
'PHP_AUTH_PW' => UserFixtures::DEFAULT_PASSWORD,
]);
break;

View File

@@ -9,7 +9,7 @@
namespace App\Tests\Controller;
use App\DataFixtures\AppFixtures;
use App\DataFixtures\UserFixtures;
/**
* @coversDefaultClass \App\Controller\InvoiceController
@@ -19,20 +19,20 @@ class ProfileControllerTest extends ControllerBaseTest
{
public function testIsSecure()
{
$this->assertUrlIsSecured('/profile/' . AppFixtures::USERNAME_USER);
$this->assertUrlIsSecured('/profile/' . UserFixtures::USERNAME_USER);
}
public function testIndexAction()
{
$client = $this->getClientForAuthenticatedUser();
$this->request($client, '/profile/' . AppFixtures::USERNAME_USER);
$this->request($client, '/profile/' . UserFixtures::USERNAME_USER);
$this->assertTrue($client->getResponse()->isSuccessful());
}
public function testIndexActionWithDifferentUsername()
{
$client = $this->getClientForAuthenticatedUser();
$this->request($client, '/profile/' . AppFixtures::USERNAME_TEAMLEAD);
$this->request($client, '/profile/' . UserFixtures::USERNAME_TEAMLEAD);
$this->assertFalse($client->getResponse()->isSuccessful());
}
}