LogicException: Missing default data in Symfony\Bundle\SwiftmailerBundle\DataCollector\MessageDataCollector - symfony

Getting this exception in Symfony 2.5.5 with Swiftmailer 5.3.0. I'm following the cookbook example exactly. The error is thrown when calling MessageDataCollector#getMessages():
// Check that an e-mail was sent
$this->assertEquals(1, $mailCollector->getMessageCount());
$collectedMessages = $mailCollector->getMessages();
$message = $collectedMessages[0];
The message count assertion is also failing with a value of zero.
As far as I can tell the collector is failing to do any actual collecting in the action. Any ideas?

I encountered the same problem after I applied kriswallsmith's test optimization trick. I could see the result of the mail sending in the web profiler when running the development version, but couldn't get the data in the testing environment.
After applying Kris' trick I noticed that the swiftmailer.mailer.default.plugin.messagelogger service was not registered with the container during the test, so the collect() method of the MessageDataCollector class did not log the data for the mail sending. This is why it wasn't possible to retrieve information from the swiftmailer collector.
The solution is either not to overrride the initializeContainer() method in AppKernel.php or to override it, but making sure messagelogger service is available for test cases that send mails.

#codeBetyar is right - problem occurs when swiftmailer.mailer.default.plugin.messagelogger is not registered in container.
But instead of getting rid of the optimization trick - you just need to update swiftmailer configuration for test environment
swiftmailer:
logging: true
The thing is logging config value by default equals to kernel.debug (https://github.com/symfony/swiftmailer-bundle/blob/master/DependencyInjection/Configuration.php#L121) which (thanks to the trick) is true for the first test request, and false - for all following requests.
Above config forces logger being registered.

In my case I had multiple mailers in the config.yml file and the same problem was due to a missing parameter in the getMessages() call.
My config.yml file:
swiftmailer:
default_mailer: default_mailer
mailers:
default_mailer:
# some configuration
another_mailer:
# some configuration
The correct call was:
$mailCollector = $this->client->getProfile()->getCollector('swiftmailer');
$collectedMessages = $mailCollector->getMessages('default_mailer'); // please note the 'default_mailer' argument
$messagesCount = $mailCollector->getMessageCount('default_mailer')

My problem was that apparently if there are no messages to retrieve (or perhaps no swiftmailer instantiation in the code being tested?), the call to getMessages() returns this obtuse error. So I bypassed the problem by testing for getMessageCount() first.

Related

Access monolog configuration values

I need to get the list of available channels from monolog configuration file , whene i try to inject these parameters into my custom service like this
logger:
class: App\Services\Logger
arguments:
$channels: '%monolog.channels%'
i got
You have requested a non-existent parameter "monolog.channels".
is odd that symfony don't provide a simple way to access all configurations (even for other bundles like monolog )
is their a way to do this or am i missing something ?

Meteor - Accounts.forgotPassword triggers internal server error whil Email.send is working fine

I'm meeting an issue on Meteor with Accounts.forgotPassword method.
My email smtp is well set up as I can use Email.send() without any issue once app is deployed.
But strangely, accounts.forgotPassword return an internal error.
When looking at the logs I have this error :
Exception while invoking method 'forgotPassword' Error: Mail command failed: 550-Requested action not taken: mailbox unavailable
I do not really understand why I would have mailbox unavailable error with Accounts.forgotPassword but not with Email.send()
Does anyone already met that kind of issues ?
I have already searched on the web for any clues but did not find anything :(
FYI I use ionos smtp
Since Email.send is working, I assume your MAIL_URL is set correctly, but your Accounts.emailTemplates is not. From https://docs.meteor.com/api/passwords.html:
In addition to configuring the email package’s MAIL_URL, it is critical that you set proper values (specifically the from address) in Accounts.emailTemplates to ensure proper delivery of e-mails!

Symfony 5.3 Mailer setup env vars not reading correctly

In a Symfony 5.3 project I am using the Mailer (..\Symfony\Component\Mailer\MailerInterface) to send mails.
For devolopment I required "symfony/google-mailer" with composer and set it up in .env.local.
Say username is "example#gmail.com" and password is "0000".
In .env.local I specified
MAILER_USER='example#gmail.com'
MAILER_PASSWORD='0000'
MAILER_DSN=gmail://MAILER_USER:MAILER_PASSWORD#default
which results in error
Failed to authenticate on SMTP server with username "MAILER_USER" using the following authenticators: "LOGIN", "PLAIN", "XOAUTH2". Authenticator "LOGIN" returned "Symfony\Component\Mailer\Exception\TransportException: Expected response code "235" but got code "535", with message "535-5.7.8 Username and Password not accepted.
As stated in the docs I changed the one special character in user name ("#") to it's URL-encoded form like
MAILER_USER='example%40gmail.com'
which then results in the error
Email "example%40gmail.com" does not comply with addr-spec of RFC 2822.
(Obviously the URL-encoding didn't work like expected (because it wasn't reversed?))
I tried to load the env vars in paramaters in services.yaml and use the parameters instead - but that lead to the first error too.
If I write the auth infos into the MAILER_DSN env var directly it just works fine without problems, like
MAILER_DSN=gmail://example#gmail.com:0000#default
So this seems to be a syntax problem which I can't figure out from the docs.
Any hints?
You should remove the single quotes and you need to wrap the env variables used in other env variables with ${} sic
MAILER_USER=example#gmail.com
MAILER_PASSWORD=0000
MAILER_DSN=gmail://${MAILER_USER}:${MAILER_PASSWORD}#default
Result:
$_SERVER['MAILER_DSN'] = "gmail://example#gmail.com:0000#default"
.env :
MAILER_DSN=smtp://username:password#smtp.gmail.com
You have to enable access to applications in google parameters (security).

You must either configure a "public_key" or a "secret_key".[Symfony]

I tried to setup a login authentication using LexikJWTAuthentication, I already generated the necessary keys
Here is how its called
config/packages/lexik_jwt_authentication.yaml
lexik_jwt_authentication:
secret_key:'%kernel.project_dir%/config/jwt/private.pem' # required for token creation
public_key:'%kernel.project_dir%/config/jwt/public.pem' # required for token verification
pass_phrase:'mafdhklkjkn234kas' # required for token creation, usage of an environment variable is recommended
token_ttl: 3600
Here is return when I try to login, I used postman
Here is the var_dump of config in vendor/lexik/jwt-authentication-bundle/DependencyInjection/LexikJWTAuthenticationExtension.php
bundles.php
I got the same error and it was from "lexik_jwt_authentication.yaml" was not in my repo, after adding it, the problem was fixed.
I pass the same error when passing a production, and honestly it's a bit silly. Cannot find keys because they are not loaded in configuration, ie dependency "nelmio/cors-bundle" was installed as dev.
By reinstalling it
composer require nelmio/cors-bundle
everything works again.
My apologies for my english

Behat step definition sometimes executed, sometimes not

I have the following scenario's:
#wip
Scenario: Attempt to get account information of an activator without credentials
Given an activator with e-mail "dietervds#email.com" and password "testpassword" already exists
When I send a GET request to "/activators/1"
Then the response code should be 401
#wip
Scenario: Attempt to get account information of another activator then myself
Given an activator with e-mail "dietervds#email.com" and password "testpassword" already exists
And an activator with e-mail "eviltwin#email.com" and password "testpassword" already exists
And I am authenticating as "eviltwin#email.com" with "testpassword" password
When I send a GET request to "/activators/1"
Then the response code should be 401
The database is dropped and re-created from schema before every scenario.
The step 'given an activator with ...' inserts a new user into the database.
However! It doesn't always do that for both users.
This is the step implementation:
/**
* #Given /^an activator with e-mail "([^"]*)" and password "([^"]*)" already exists$/
*/
public function anActivatorWithEMailAndPasswordAlreadyExists($email, $password)
{
$activatorManager = $this->getContainer()->get('am.manager.activator');
#$logger = $this->getContainer()->get('logger');
#$logger->debug("Email: $email, password: $password");
$activator = $activatorManager->createActivator($email, $password);
$activatorManager->save($activator);
}
Now the weird thing:
In that last step, I should be getting two inserts: one for dietervds, one of eviltwin.
I get the two inserts when I:
Run only one scenario
Output something in logging (creating the 'logger' doesn't help, I need to output something. What I output doesn't have to be dynamic, it can just be a fixed string)
I only get one insert (for dietervds) when I:
Run the two scenarios together
Or when I don't output any logging in the step implementation
I am completely baffled by this.
Is there something obvious that's missing? Might it be some sort of caching problem in the step definitions? (the logging might change the signature or something, not sure)
Any feedback is welcome :-)
Cheers!
Dieter
Does this step def do an ajax call?
When I send a GET request to "/activators/1"
if it does you could try adding some wait time in there to give your dom time to load the result
Whens to Thens work best when you are submitting forms with press or following links or doing go to's to redirect the browser which initiates a full request response cycle that triggers the robot to wait for a new dom to load.
With ajax that doesn't happen exactly the same way.
If you aren't doing ajax I recommend you just use the built in step defs of
When I follow "/activators/1" instead
There is a way to prevent caching in your yaml config. Here is an example config we use for chrome but it should work the same for any browser driver
default:
extensions:
Behat\MinkExtension\Extension:
base_url: https://yurwebsite.com
goutte: ~
browser_name: "googlechrome"
selenium2:
capabilities: { "browser": "googlechrome", "version": "23", "applicationCacheEnabled": false }
The last boolean param does the trick for our browser caching issues

Resources