Completed
Push — master ( 8807d9...d7a3f6 )
by
unknown
14:20
created

FeatureContext::iFillTemplateWithData()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 8.5906
c 0
b 0
f 0
cc 5
eloc 15
nc 5
nop 1
1
<?php
2
3
namespace OroCRM\Bundle\SalesBundle\Tests\Behat\Context;
4
5
use Behat\Gherkin\Node\TableNode;
6
use Behat\Mink\Element\NodeElement;
7
use Behat\Symfony2Extension\Context\KernelAwareContext;
8
use Behat\Symfony2Extension\Context\KernelDictionary;
9
use Guzzle\Http\Client;
10
use Guzzle\Plugin\Cookie\Cookie;
11
use Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar;
12
use Guzzle\Plugin\Cookie\CookiePlugin;
13
use Oro\Bundle\DataGridBundle\Tests\Behat\Element\Grid;
14
use Oro\Bundle\FormBundle\Tests\Behat\Element\OroForm;
15
use Oro\Bundle\FormBundle\Tests\Behat\Element\Select2Entity;
16
use Oro\Bundle\NavigationBundle\Tests\Behat\Element\MainMenu;
17
use Oro\Bundle\TestFrameworkBundle\Behat\Context\OroFeatureContext;
18
use Oro\Bundle\TestFrameworkBundle\Behat\Element\OroElementFactoryAware;
19
use Oro\Bundle\TestFrameworkBundle\Behat\Fixtures\FixtureLoaderAwareInterface;
20
use Oro\Bundle\TestFrameworkBundle\Behat\Fixtures\FixtureLoaderDictionary;
21
use Oro\Bundle\TestFrameworkBundle\Tests\Behat\Context\ElementFactoryDictionary;
22
use Oro\Bundle\UserBundle\Entity\User;
23
use OroCRM\Bundle\AccountBundle\Entity\Account;
24
use OroCRM\Bundle\ChannelBundle\Entity\Channel;
25
use OroCRM\Bundle\SalesBundle\Entity\B2bCustomer;
26
27
class FeatureContext extends OroFeatureContext implements
28
    FixtureLoaderAwareInterface,
29
    OroElementFactoryAware,
30
    KernelAwareContext
31
{
32
    use FixtureLoaderDictionary, ElementFactoryDictionary, KernelDictionary;
33
34
    /**
35
     * @var string Path to saved template
36
     */
37
    protected $template;
38
39
    /**
40
     * @var string Path to import file
41
     */
42
    protected $importFile;
43
44
    /**
45
     * @Given /^(?:|I )open (Opportunity) creation page$/
46
     */
47
    public function openOpportunityCreationPage()
48
    {
49
        /** @var MainMenu $menu */
50
        $menu = $this->createElement('MainMenu');
51
        $menu->openAndClick('Sales/ Opportunities');
52
        $this->waitForAjax();
53
        $this->getPage()->clickLink('Create Opportunity');
54
    }
55
56
    /**
57
     * @Given /^"(?P<channelName>([\w\s]+))" is a channel with enabled (?P<entities>(.+)) entities$/
58
     */
59
    public function createChannelWithEnabledEntities($channelName, $entities)
60
    {
61
        /** @var MainMenu $menu */
62
        $menu = $this->createElement('MainMenu');
63
        $menu->openAndClick('System/ Channels');
64
        $this->waitForAjax();
65
        $this->getPage()->clickLink('Create Channel');
66
        $this->waitForAjax();
67
68
        /** @var OroForm $form */
69
        $form = $this->createElement('OroForm');
70
        $form->fillField('Name', $channelName);
71
        $form->fillField('Channel Type', 'Sales');
72
        $this->waitForAjax();
73
74
        /** @var Grid $grid */
75
        $grid = $this->createElement('Grid');
76
        $channelEntities = array_map('trim', explode(',', $entities));
77
        $rowsForDelete = [];
78
79
        foreach ($grid->getRows() as $row) {
80
            foreach ($channelEntities as $key => $channelEntity) {
81
                if (false !== stripos($row->getText(), $channelEntity)) {
82
                    unset($channelEntities[$key]);
83
                    continue 2;
84
                }
85
            }
86
87
            $rowsForDelete[] = $row;
88
        }
89
90
        foreach ($rowsForDelete as $row) {
91
            $grid->getActionLink('Delete', $row)->click();
92
        }
93
94
        $entitySelector = $this->elementFactory->findElementContains('EntitySelector', 'Please select entity');
95
96
        foreach ($channelEntities as $channelEntity) {
97
            $entitySelector->click();
98
            $this->elementFactory->findElementContains('SelectToResultLabel', $channelEntity)->click();
99
            $this->getPage()->clickLink('Add');
100
        }
101
102
        $form->saveAndClose();
103
    }
104
105
    /**
106
     * @Given they has their own Accounts and Business Customers
107
     */
108
    public function accountHasBusinessCustomers()
109
    {
110
        $this->fixtureLoader->loadFixtureFile('accounts_with_customers.yml');
111
    }
112
113
    /**
114
     * @Given /^two users (?P<user1>(\w+)) and (?P<user2>(\w+)) exists in the system$/
115
     */
116
    public function twoUsersExistsInTheSystem()
117
    {
118
        $this->fixtureLoader->loadFixtureFile('users.yml');
119
    }
120
121
    /**
122
     * @Then /^Accounts and Customers in the control are filtered according to (?P<user>(\w+)) ACL permissions$/
123
     */
124
    public function accountsInTheControlAreFilteredAccordingToUserAclPermissions($username)
125
    {
126
        $doctrine = $this->getContainer()->get('oro_entity.doctrine_helper');
127
        $owner = $doctrine->getEntityRepositoryForClass(User::class)->findOneBy(['username' => $username]);
128
        $ownAccounts = $doctrine->getEntityRepositoryForClass(B2bCustomer::class)->findBy(['owner' => $owner]);
129
130
        /** @var Select2Entity $accountField */
131
        $accountField = $this->createElement('OroForm')->findField('Account');
132
        $visibleAccounts = $accountField->getSuggestedValues();
133
134
        self::assertCount(count($ownAccounts), $visibleAccounts);
135
136
        /** @var B2bCustomer $account */
137
        foreach ($ownAccounts as $account) {
138
            $value = sprintf('%s (%s)', $account->getName(), $account->getAccount()->getName());
139
            self::assertContains($value, $visibleAccounts);
140
        }
141
    }
142
143
    /**
144
     * @Given CRM has second sales channel with Accounts and Business Customers
145
     */
146
    public function crmHasSecondSalesChannel()
147
    {
148
        $this->fixtureLoader->loadFixtureFile('second_sales_channel.yml');
149
    }
150
151
    /**
152
     * @Then Accounts and Customers in the control are filtered by selected sales channel and :username ACL permissions
153
     */
154
    public function accountsInTheControlAreFilteredBySelected($username)
155
    {
156
        /** @var Select2Entity $channelField */
157
        $channelField = $this->createElement('OroForm')->findField('Channel');
158
        $channels = $channelField->getSuggestedValues();
159
160
        foreach ($channels as $channelName) {
161
            $channelField->setValue($channelName);
162
163
            $expectedCustomers = $this->getCustomers($channelName, $username);
164
165
            /** @var Select2Entity $accountField */
166
            $accountField = $this->createElement('OroForm')->findField('Account');
167
            $actualCustomers = $accountField->getSuggestedValues();
168
169
            self::assertEquals(
170
                sort($expectedCustomers),
171
                sort($actualCustomers)
172
            );
173
        }
174
    }
175
176
    /**
177
     * @Given Account Name is equal to Business Customer name
178
     */
179
    public function accountNameEqualToBusinessCustomer()
180
    {
181
        $this->fixtureLoader->loadFixtureFile('account_name_equal_to_business_customer_name.yml');
182
    }
183
184
    /**
185
     * @Then /^I see only Account name in Account\/Customer field choice$/
186
     */
187
    public function iSeeAccountNameOnly()
188
    {
189
        /** @var Select2Entity $accountField */
190
        $accountField = $this->createElement('OroForm')->findField('Account');
191
        $actualCustomers = $accountField->getSuggestedValues();
192
193
        self::assertContains('Samantha Customer', $actualCustomers);
194
        self::assertNotContains('Samantha Customer (Samantha Customer)', $actualCustomers);
195
    }
196
197
    /**
198
     * @Given Account :name has no customers
199
     */
200
    public function accountHasNoCustomers($name)
201
    {
202
        $this->fixtureLoader->load([
203
            Account::class => [
204
                uniqid('account_', true) => [
205
                    'name' => $name,
206
                    'owner' => '@samantha',
207
                    'organization' => '@organization'
208
                ]
209
            ]
210
        ]);
211
    }
212
213
    /**
214
     * @When I select :name
215
     */
216
    public function selectAccount($name)
217
    {
218
        /** @var Select2Entity $accountField */
219
        $accountField = $this->createElement('OroForm')->findField('Account');
220
        $accountField->fillSearchField($name);
221
        $results = $accountField->getSuggestions();
222
        foreach ($results as $result) {
223
            if (false !== stripos($result->getText(), $name)) {
224
                $result->click();
225
226
                return;
227
            }
228
        }
229
        self::fail('Not found account in suggested variants');
230
    }
231
232
    /**
233
     * @Then :content Customer was created
234
     */
235
    public function customerWasCreated($content)
236
    {
237
        /** @var MainMenu $menu */
238
        $menu = $this->createElement('MainMenu');
239
        $menu->openAndClick('Customers/ Business Customers');
240
        $this->waitForAjax();
241
242
        $this->assertRowInGrid($content);
243
    }
244
245
    /**
246
     * @Then :content Account was created
247
     */
248
    public function accountWasCreated($content)
249
    {
250
        /** @var MainMenu $menu */
251
        $menu = $this->createElement('MainMenu');
252
        $menu->openAndClick('Customers/ Accounts');
253
        $this->waitForAjax();
254
255
        $this->assertRowInGrid($content);
256
    }
257
258
    /**
259
     * @param string $content
260
     */
261
    private function assertRowInGrid($content)
262
    {
263
        $row = $this->elementFactory
264
            ->findElementContains('Grid', $content)
265
            ->findElementContains('GridRow', $content);
266
267
        self::assertTrue($row->isValid(), "Can't find '$content' in grid");
268
    }
269
270
    /**
271
     * @When type :text into Account field
272
     */
273
    public function iTypeIntoAccountField($text)
274
    {
275
        /** @var Select2Entity $accountField */
276
        $accountField = $this->createElement('OroForm')->findField('Account');
277
        $accountField->fillSearchField($text);
278
    }
279
280
    /**
281
     * @Then I should see only existing accounts
282
     */
283
    public function iShouldSeeOnlyExistingAccounts()
284
    {
285
        $existingCustomers = $this->getCustomers('First Sales Channel', 'samantha');
286
287
        /** @var Select2Entity $accountField */
288
        $accountField = $this->createElement('OroForm')->findField('Account');
289
        $actualCustomers = $accountField->getSuggestedValues();
290
291
        self::assertEquals(
292
            sort($existingCustomers),
293
            sort($actualCustomers)
294
        );
295
    }
296
297
    /**
298
     * @Then should not see :text account
299
     */
300
    public function shouldNotSeeAccount($text)
301
    {
302
        /** @var Select2Entity $accountField */
303
        $accountField = $this->createElement('OroForm')->findField('Account');
304
        $actualCustomers = $accountField->getSuggestedValues();
305
306
        self::assertNotContains($text, $actualCustomers);
307
    }
308
309
    /**
310
     * @param string $channelName
311
     * @param string $username
312
     * @return array
313
     */
314
    private function getCustomers($channelName, $username)
315
    {
316
        $doctrine = $this->getContainer()->get('oro_entity.doctrine_helper');
317
        $customerRepository = $doctrine->getEntityManagerForClass(B2bCustomer::class)
318
            ->getRepository(B2bCustomer::class);
319
        $channelRepository = $doctrine->getEntityManagerForClass(Channel::class)->getRepository(Channel::class);
320
321
        $user = $doctrine->getEntityManagerForClass(User::class)->getRepository(User::class)
322
            ->findOneBy(['username' => $username]);
323
        $channel = $channelRepository->findOneBy(['name' => $channelName]);
324
325
        $customers = [];
326
327
        /** @var B2bCustomer $customer */
328
        foreach ($customerRepository->findBy(['owner' => $user, 'dataChannel' => $channel]) as $customer) {
329
            $customers[] = sprintf('%s (%s)', $customer->getName(), $customer->getAccount()->getName());
330
        }
331
332
        return $customers;
333
    }
334
335
    /**
336
     * @Given /^(?:|I )go to Opportunity Index page$/
337
     */
338
    public function iGoToOpportunityIndexPage()
339
    {
340
        /** @var MainMenu $mainMenu */
341
        $mainMenu = $this->createElement('MainMenu');
342
        $mainMenu->openAndClick("Sales/Opportunities");
343
    }
344
345
    /**
346
     * @When I download Data Template file
347
     */
348
    public function iDownloadDataTemplateFile()
349
    {
350
        $importButton = $this->getSession()
351
            ->getPage()
352
            ->findLink('Import');
353
        self::assertNotNull($importButton);
354
355
        $importButton
356
            ->getParent()
357
            ->find('css', 'a.dropdown-toggle')
358
            ->click();
359
        $link = $importButton->getParent()->findLink('Download Data Template');
360
361
        self::assertNotNull($link);
362
363
        $url = $this->locatePath($this->getContainer()->get('router')->generate(
364
            'oro_importexport_export_template',
365
            ['processorAlias' => 'orocrm_sales_opportunity']
366
        ));
367
        $this->template = tempnam(sys_get_temp_dir(), 'opportunity_template_');
368
369
        $cookies = $this->getSession()->getDriver()->getWebDriverSession()->getCookie()[0];
370
        $cookie = new Cookie();
371
        $cookie->setName($cookies['name']);
372
        $cookie->setValue($cookies['value']);
373
        $cookie->setDomain($cookies['domain']);
374
375
        $jar = new ArrayCookieJar();
376
        $jar->add($cookie);
377
378
        $client = new Client($this->getSession()->getCurrentUrl());
379
        $client->addSubscriber(new CookiePlugin($jar));
380
        $request = $client->get($url, null, ['save_to' => $this->template]);
381
        $response = $request->send();
382
383
        self::assertEquals(200, $response->getStatusCode());
384
    }
385
386
    /**
387
     * @Then /^(?:|I )don't see (?P<column>([\w\s]+)) column$/
388
     */
389
    public function iDonTSeeBbCustomerNameColumn($column)
390
    {
391
        $csv = array_map('str_getcsv', file($this->template));
392
        self::assertNotContains($column, $csv[0]);
393
    }
394
395
    /**
396
     * @Then /^(?:|I )see (?P<column>([\w\s]+)) column$/
397
     */
398
    public function iSeeAccountColumn($column)
399
    {
400
        $csv = array_map('str_getcsv', file($this->template));
401
        self::assertContains($column, $csv[0]);
402
    }
403
404
    /**
405
     * @Given crm has (Acme) Account with (Charlie) and (Samantha) customers
406
     */
407
    public function crmHasAcmeAccountWithCharlieAndSamanthaCustomers()
408
    {
409
        $this->fixtureLoader->loadFixtureFile('account_with_customers.yml');
410
    }
411
412
    /**
413
     * @Given I fill template with data:
414
     */
415
    public function iFillTemplateWithData(TableNode $table)
416
    {
417
        $this->importFile = tempnam(sys_get_temp_dir(), 'opportunity_import_data_');
418
        $fp = fopen($this->importFile, 'w');
419
        $csv = array_map('str_getcsv', file($this->template));
420
        $headers = array_shift($csv);
421
        fputcsv($fp, $headers);
422
423
        foreach ($table as $row) {
424
            $values = [];
425
            foreach ($headers as $header) {
426
                $value = '';
427
                foreach ($row as $rowHeader => $rowValue) {
428
                    if (preg_match(sprintf('/^%s$/i', $rowHeader), $header)) {
429
                        $value = $rowValue;
430
                    }
431
                }
432
433
                $values[] = $value;
434
            }
435
            fputcsv($fp, $values);
436
        }
437
    }
438
439
    /**
440
     * @When /^(?:|I )import file$/
441
     */
442
    public function iImportFile()
443
    {
444
        $this->tryImportFile();
445
        $this->getSession()->getPage()->pressButton('Import');
446
        $this->waitForAjax();
447
    }
448
449
    /**
450
     * @When /^(?:|I )try import file$/
451
     */
452
    public function tryImportFile()
453
    {
454
        $page = $this->getSession()->getPage();
455
        $page->clickLink('Import');
456
        $this->waitForAjax();
457
        $this->createElement('ImportFileField')->attachFile($this->importFile);
458
        $page->pressButton('Submit');
459
        $this->waitForAjax();
460
    }
461
462
    /**
463
     * @Then /^(?:|I )should see validation message "(?P<validationMessage>[^"]+)"$/
464
     */
465
    public function iShouldSeeValidationMessage($validationMessage)
466
    {
467
        $errorsHolder = $this->createElement('ImportErrors');
468
        self::assertTrue($errorsHolder->isValid(), 'No import errors found');
469
470
        $errors = $errorsHolder->findAll('css', 'ol li');
471
        $existedErrors = [];
472
473
        /** @var NodeElement $error */
474
        foreach ($errors as $error) {
475
            $error = $error->getHtml();
476
            $existedErrors[] = $error;
477
            if (false !== stripos($error, $validationMessage)) {
478
                return;
479
            }
480
        }
481
482
        self::fail(sprintf(
483
            '"%s" error message not found in errors: "%s"',
484
            $validationMessage,
485
            implode('", "', $existedErrors)
486
        ));
487
    }
488
489
    /**
490
     * @Then /^(?P<customerName>[\w\s]+) customer has (?P<opportunityName>[\w\s]+) opportunity$/
491
     */
492
    public function customerHasOpportunity($customerName, $opportunityName)
493
    {
494
        /** @var MainMenu $mainMenu */
495
        $mainMenu = $this->createElement('MainMenu');
496
        $mainMenu->openAndClick('Customers/ Business Customers');
497
        $this->waitForAjax();
498
499
        /** @var Grid $grid */
500
        $grid = $this->createElement('Grid');
501
        self::assertTrue($grid->isValid(), 'Grid not found');
502
        $grid->clickActionLink($customerName, 'View');
503
        $this->waitForAjax();
504
505
        /** @var Grid $customerOpportunitiesGrid */
506
        $customerOpportunitiesGrid = $this->createElement('CustomerOpportunitiesGrid');
507
        $row = $customerOpportunitiesGrid->getRowByContent($opportunityName);
508
509
        self::assertTrue($row->isValid());
510
    }
511
}
512