RSpec: undefined method for #<ActionController::TestResponse. Testing a dynamic flash message - ruby-on-rails-4

I have a simple spec testing the creation of an object of the Baseline class.
it "allows a user to create a baseline score with valid content" do
expect(#user.baselines.count).to eq(0)
#baseline = post(:create, :user_id => #user.id, :baseline => valid_attributes)
expect(response).to redirect_to '/patients/list'
expect(flash[:notice]).to eq("Baseline scores for case #{#baseline.case_id} was successfully created.")
expect(Baseline.all.count).to eq(1)
end
But I get this. I am uncertain where to begin with this - I am uncertain why I can't access the case_id attribute of #baseline.
NoMethodError:undefined method `case_id' for <ActionController::TestResponse:0x007f8f5ab4f3c0>
Just to show...these are the valid attributes
let(:valid_attributes) do {
:dx1 => "IPF",
:dxcon1 => 100,
:db1 => "Progressive",
:dbcon1 => 100,
:mgt=> "Drugs",
:biopsy => "Yes",
:patient_id => #patient.id,
:case_id => #patient.case,
}
end

post doesn't return a model instance it returns a TestResponse object which gives you access to headers, status code, etc. To access the object created as a side effect of calling the :create action you can do Baseline.last (in this case Baseline.first would also work since there are no existing baseline objects)
Also note - if you have an instance variable named #baseline that is assigned in the controller you can access that with assigns(:baseline)
expect(assigns[:baseline]).to be_a(Baseline)

Related

Can't see custom attributes set on a user from their Google_Service_Directory_User object

When a custom attribute is set on a user from googles admin page I am unable to see it in their Google_Service_Directory_User object the client has this scope and is able to see the users data but no attributes are shown.
$client->setScopes(
[
Google_Service_Directory::ADMIN_DIRECTORY_USER_READONLY,
Google_Service_Directory::ADMIN_DIRECTORY_GROUP_READONLY,
]
);
I would have expected it to be in the customSchemas but that is null for all the users
When requesting user's informations, you need to set the projection parameter to FULL when using the method users.get (projection parameter is also avaible with method users.list). Default settings to not return custom schemas. You can have more informations here (Google documentation).
You seem to be using PHP (I've never coded in PHP so I may be wrong), so the request should look like this:
$optParams = array(
'userKey' => 'my_customer#example.com',
'projection' => 'full', // or maybe 'FULL' ?
);
$results = $service->users->get($optParams);
If you only want the return some of the schemas, then use :
$optParams = array(
'userKey' => 'my_customer#example.com',
'projection' => 'custom', // or maybe 'CUSTOM' ?,
'customFieldMask' => 'A comma-separated list of schema names'
);
$results = $service->users->get($optParams);

EF CORE: How to modify owned collection on entity

I have entity "MyEntity" with a list of owners. Each owner object has 3 properties - Id, type, link.
In the configuration, I am mapping this like owned object.
builder.OwnsMany(a => a.Owner, ownershipBuilder =>
{
ownershipBuilder.HasKey(x => x.Link);
ownershipBuilder.Property(x => x.Id).IsRequired();
ownershipBuilder.Property(x => x.Type)
.HasConversion(t => t.ToString(),
value => (MyType) Enum.Parse(typeof(MyType), value))
.IsRequired();
});
Now, when I try to update this collection of owners, I got DbUpdateConcurrencyException
The flow of update is:
find parent entity by its ID
add owner into the list
call Update method on the dbContext and SaveChanges.
After calling savechanges I got mentioned exception.
Any idea here?
THX.
I solved it,
I am generating Link (Owner entity) in code and this is key in table also. Thus I must use ValueGeneratedNever in the entity configuration.
ownershipBuilder.Property(x => x.Link).ValueGeneratedNever().IsRequired();
Problem solved.

cakephp 2.6 controller test case throwing MissingActionException on duplicate testAction()-call

I hope anyone can help me out with my testing environment.
my setup
I am implementing unit tests based on phpunit 3.7.22 with the cake release 2.6.9. Running on ubuntu 12.04 LTS with PHP 5.4.43-1 and postgresql 9.1.
I immplemented controller tests mocking cakes Auth Component to have a user in the session, since my tests depent on that. My controllers return json results, since its an API for a JS-based frontend. I call my controller methods using the testAction() call of a generated controller.
<?php
App::uses('RequesttypesController', 'Svc.Controller');
class RequesttypesWithResultControllerTest extends ControllerTestCase
{
public $fixtures = array(
'app.requesttype',
'app.user',
'app.privilege',
'app.groupsprivilege',
'app.groupsuser',
'app.groupscompany',
'app.company',
);
/**
* Mock the requesttype object so that it can return results depending on the desired outcome
*
* #see CakeTestCase::setUp()
*/
public function setUp()
{
parent::setUp();
$this->controller = $this->generate('Svc.Requesttypes', array(
'models' => array(
'Requesttype'
),
'components' => array(
'Auth' => array(
'user'
),
'Session',
'RequestHandler'
)
));
$this->controller->Auth->staticExpects($this->any())
->method('user')
->will($this->returnValue(array(
'id' => 123,
'username' => 'myTestUser',
'company' => 'myTestCompany',
'usertype_id' => '456',
))
);
$authResult = $this->controller->Auth->user();
}
public function tearDown()
{
parent::tearDown();
unset($this->controller);
}
/**
* A logged in user produces a number of requesttypes
*/
public function testLoggedInUser()
{
$result = $this->testAction('/svc/requesttypes/getMyRequesttypes', array('return' => 'vars'));
$this->assertNotEmpty($this->vars, 'Did not receive webservice response');
$this->assertTrue(isset($this->vars['data']['code']), 'Received invalid webservice response');
$this->assertEqual($this->vars['data']['code'], SvcAppController::RESPONSE_CODE_SUCCESS);
}
}
?>
This test passes without errors. Now I want to test my controller-action with different setups, for example users with a different usertype, from a different company, and so on. If I now create a second test-method in my RequesttypesWithResultControllerTest-class, calling the same testAction-url, i get a MissingActionException saying:
"Action RequesttypesController::() could not be found."
It seems that the testAction calls an empty controller-action, even if the action-url is passed as a parameter. I tried reinitializing the controller by nulling it and calling $this->generate() again, but this does not help either.
Of course I can help myself out by creating an own test-controller for every test ending up in a bunch of duplicate test-code, but this somehow seems not right to me.
Am I misusing the test-environment or how can this exception be explained? Any ideas?
Thanks in advance for sharing my headache!
After some further code debugging we finally found the error. We accidently changed the require statement of the last line of the /Config/routes.php file to a require_once because of some "Class already defined Exceptions" thrown in the test-environment.
Wrong routes.php:
require_once CAKE . 'Config' . DS . 'routes.php';
For the application itself that made no difference, since the routes are only needed to be initialized once per request. But in a test-environment, the routes are reinitialized several times, which was not possible anymore with the require_once include.
This is how the line is supposed to look like, which it does by default:
Correct routes.php:
require CAKE . 'Config' . DS . 'routes.php';

rails4 Devise omniauth How to modify dynamically one of the strategy options?

I am using Devise+Omniauth , and I defined my own doorkeeper strategy to add a language option
In config/initializers/devise.rb , I set up :
require 'omniauth/strategies/doorkeeper'
config.omniauth :doorkeeper, Rails.application.secrets.doorkeeper_app_id, Rails.application.secrets.doorkeeper_app_secret,
:client_options => {
:site => Rails.application.secrets.doorkeeper_url
},
:authorize_params =>{:lang => I18n.locale}
which initially set lang to :en ( default locale )
this works fine and send the lang options to the remote server for Doorkeeperprocessing
now, how can I change this parameter in my client calling controller ?
I tried to use :
def index
I18n.locale = :fr
Rails.application.config.middleware.use OmniAuth::Builder do
provider :doorkeeper, :setup => lambda{|env| env['omniauth.strategy'].options[:authorize_params][:lang] = env['rack.session'][I18n.locale] }
end
but I got an error :
RuntimeError (can't modify frozen Array):
app/controllers/home_controller.rb:7:in `index'
Is there any better way to do it ? thanks for help
I modified the config/initializers/devise.rb, adding :setup => true
require 'omniauth/strategies/doorkeeper'
config.omniauth :doorkeeper, Rails.application.secrets.doorkeeper_app_id, Rails.application.secrets.doorkeeper_app_secret,
:client_options => {
:site => Rails.application.secrets.doorkeeper_url
},
:authorize_params =>{:lang => I18n.locale},
:setup => true
and I modified my doorkeeper strategy, to include the setup_phase, in which I set the lang option to the current locale.
def setup_phase
request.env['omniauth.strategy'].options[:authorize_params][:lang] = request.params["locale"]
end

How to develop input object with TDD / BDD?

I have a method called ProcessPayment() that I'm developing via BDD and mspec. I need help with a new challenge. My user story says:
Given a payment processing context,
When payment is processed with valid payment information,
Then it should return a successful gateway response code.
To set up the context, I am stubbing my gateway service using Moq.
_mockGatewayService = Mock<IGatewayService>();
_mockGatewayService.Setup(x => x.Process(Moq.It.IsAny<PaymentInfo>()).Returns(100);
Here's the spec:
public class when_payment_is_processed_with_valid_information {
static WebService _webService;
static int _responseCode;
static Mock<IGatewayService> _mockGatewayService;
static PaymentProcessingRequest _paymentProcessingRequest;
Establish a_payment_processing_context = () => {
_mockGatewayService = Mock<IGatewayService>();
_mockGatewayService
.Setup(x => x.Process(Moq.It.IsAny<PaymentInfo>())
.Returns(100);
_webService = new WebService(_mockGatewayService.Object);
_paymentProcessingRequest = new PaymentProcessingRequest();
};
Because payment_is_processed_with_valid_payment_information = () =>
_responseCode = _webService.ProcessPayment(_paymentProcessingRequest);
It should_return_a_successful_gateway_response_code = () =>
_responseCode.ShouldEqual(100);
It should_hit_the_gateway_to_process_the_payment = () =>
_mockGatewayService.Verify(x => x.Process(Moq.It.IsAny<PaymentInfo>());
}
The method should take a `PaymentProcessingRequest' object (not domain obj), map that obj to a domain obj, and pass the domain obj to the stubbed method on the gateway service. The response from the gateway service is what gets returned by the method. However, because of the way I am stubbing my gateway service method, it doesn't care what gets passed in to it. As a result, it seems I have no way to test whether or not the method maps the request object to the domain object properly.
When can I do here and still adhere to BDD?
To check that the object sent to your IGatewayService is correct, you can use a callback to set a reference to the domain object. You can then write your assertions on properties of that object.
Example:
_mockGatewayService
.Setup(x => x.Process(Moq.It.IsAny<PaymentInfo>())
.Callback<PaymentInfo>(paymentInfo => _paymentInfo = paymentInfo);
So from what I understand,
You want to test the mapping logic in the WebService.ProcessPayment method ; there is a mapping of an input parameter A to an object B, which is used as an input to a GateWayService collaborator.
It should_hit_the_gateway_to_process_the_payment = () =>
_mockGatewayService.Verify(
x => x.Process( Moq.It.Is<PaymentInfo>( info => CheckPaymentInfo(info) ));
Use the Moq It.Is constraint which takes in a Predicate (a test for the argument to satisfy). Implement CheckPaymentInfo to assert against the expected PaymentInfo.
e.g. to check if Add is Passed an even number as an argument,
mock.Setup(foo => foo.Add(It.Is<int>(i => i % 2 == 0))).Returns(true);