How do I create and test environment-specific code? - ruby

I have a web app that hopes to track/write bills from different state legislatures. The problem I found, though, is that many states have different rules regarding bill schema, rules for progression (i.e. some states allow you to reconsider a failed bill while others do not), et cetera.
How I'm handling it right now in my models is to create a Bill class and then conditionally reopen the class and add additional fields and validations to the class, depending on environment variables. The intent is for each state to have its own installation of the app, so I would have one with STATE set to OR and make the app use Oregon bill rules.
This has become a huge problem for me, however. Re-opening the class like this works well enough in production, but it becomes really hard to test because the class needs to be opened up at startup and can't be disabled for testing unless I somehow reload the entire program with a different environment variable. I've searched through Google and StackOverflow, but I haven't gotten any results for best practices of what I'm looking for, either because they don't exist or I don't know the name for it.

Since you are asking about environment variables, why not use environment variables?
ENV can be the way to do this, just add the appropriate state in there.
>> ENV['State_Code'] = 'FL'
=> "FL"
>> ENV['State_Code']
=> "FL"
Change it as you want to test the different rules.
This has the advantage of being able to be set from outside of your application, as ENV is read from your environment, not surprisingly.

Related

Can pundit policies be loaded from database?

I like the simplicity of Pundit gem and I would like to make policies dynamic by storing them to database.
Basically I'm looking for a way to be able to change policies without need to redeploy the application.
1st way
Pundit policy is pure ruby code, so if you don't want to keep code inside database and evaluate it dynamically, I'd say the answer is no. It's unsafe. You may give it a go, though.
2nd way
But nothing prevents you from creating model which keeps rules in simple json and compare them using Pundit, e.g.:
class PostPolicy < ApplicationPolicy
def update?
access_setting = PolicySetting.find_by(key: self.class_name)
user.role.in?(access_setting['roles'])
end
end
Of course, complexity and flexibility of the tool directly depends on each other.
3rd way
Is just work around. You may set you authorisation project apart from the main one, so that it's deploys (zero-downtime, of course) would not affect the main big project.
4th way
Create your own DSL to be stored in Database
5th way
Use something like json-logic-ruby to store logic in database

How to get different parameter types per Joomla ACL ?

Right now you can only set 'Allowed', 'Inherited' and 'Prohibited' per Joomla ACL. That's fine but far from complete. Consider the simple case you want to set a string per ACL, like 'allowed upload extensions'. There seems little or no information about.
Any ideas on this ? Its seems even more complicated when you want to register 'dynamic' parameters on the fly, so all this XML based persistence model you have in Joomla will fall a part as well...
Thanks!
This would be wrong, and a nightmare to debug (imagine guiding users when they start calling because they can't do something, and you have no idea where to look).
If you want your component to have more user-configurable actions, you can define some params in the config, where you set the list of extensions allowed in a custom action level, such as "extensions.safe", then assign that. You can create as many as you want. Find more info here
Unless you're proposing that existing components take into consideration arbitrarily defined dynamic parameters, it's hard to see how it could work.

Puppet Dashboard with Resource Definitions

I have a puppet environment where I need to add a variable number of very similar objects to a single server. The objects vary only by attributes such as name and path, all of which can be extrapolated from a single name parameter.
This seems like the perfect use for puppet resource definitions since multiple definitions can be added to a single server and their specific attributes can be taken from the definition name declaration.
This setup works well for me and I have had no issues getting it up and running on several servers. I have a requirement now however to hand this over to an ops department with almost no scripting experience, so they aren't really comfortable managing from the file system.
They requested a dashboard, so I setup puppet dashboard for them. After I set the dashboard up however, I found out that it only supports adding classes to servers, not definitions. This seems pretty shortsighted on the part of the folks at PuppetLabs, so I can only think that I am approaching this problem the wrong way and that there must be a solution using classes whereby multiple almost identical entities can be added to a single node.
I realize I could create a class for each entity, but there are hundreds, even thousands of potential variations so that's not really practical.
I have also considered a wrapper class that declares each definition on a per node basis, but this seems like more work to manage than it's worth.
Any thoughts on alternate approaches that would be compatible with the dashboard would be appreciated.
To make ENCs such as dashboard work this way, you have to pass in node data in the form of node variables. Note that Hiera is often preferable to plain node variables.
Generally, the value you want to hand in is an array of your resource titles
$resources = [ "name1", "name2", ... ]
Then classify your node with (at least) one class that instanciates your defined type using this data, e.g.
class my_resources {
my_defined_type { $resources: }
}

TDD: why, how and real world test driven code

First, Please bear with me with all my questions. I have never used TDD before but more and more I come to realize that I should. I have read a lot of posts and how to guides on TDD but some things are still not clear. Most example used for demonstration are either math calculation or some other simple operations. I also started reading Roy Osherove's book about TDD. Here are some questions I have:
If you have an object in your solution, for instance an Account class, what is the benefit of testing setting a property on it, for example an account name, then you Assert that whatever you set is right. Would this ever fail?
Another example, an account balance, you create an object with balance 300 then you assert that the balance is actually 300. How would that ever fail? What would I be testing here? I can see testing a subtraction operation with different input parameters would be more of a good test.
What should I actually test my objects for? methods or properties? sometime you also have objects as service in an infrastructure layer. In the case of methods, if you have a three tier app and the business layer is calling the data layer for some data. What gets tested in that case? the parameters? the data object not being null? what about in the case of services?
Then on to my question regarding real life project, if you have a green project and you want to start it with TDD. What do you start with first? do you divide your project into features then tdd each one or do you actually pick arbitrarily and you go from there.
For example, I have a new project and it requires a login capability. Do I start with creating User tests or Account tests or Login tests. Which one I start with first? What do I test in that class first?
Let's say I decide to create a User class that has a username and password and some other properties. I'm supposed to create the test first, fix all build error, run the test for it to fail then fix again to get a green light then refactor. So what are the first tests I should create on that class? For example, is it:
Username_Length_Greater_Than_6
Username_Length_Less_Than_12
Password_Complexity
If you assert that length is greater than 6, how is that testing the code? do we test that we throw an error if it's less than 6?
I am sorry if I was repetitive with my questions. I'm just trying to get started with TDD and I have not been able to have a mindset change. Thank you and hopefully someone can help me determine what am I missing here. By the way, does anyone know of any discussion groups or chats regarding TDD that I can join?
Have a look at low-level BDD. This post by Dan North introduces it quite well.
Rather than testing properties, think about the behavior you're looking for. For instance:
Account Behavior:
should allow a user to choose the account name
should allow funds to be added to the account
User Registration Behavior:
should ensure that all usernames are between 6 and 12 characters
should ask the password checker if the password is complex enough <-- you'd use a mock here
These would then become tests for each class, with the "should" becoming the test name. Each test is an example of how the class can be used valuably. Instead of testing methods and properties, you're showing someone else (or your future self) why the class is valuable and how to change it safely.
We also do something in BDD called "outside-in". So start with the GUI (or normally the controller / presenter, since we don't often unit-test the GUI).
You already know how the GUI will use the controller. Now write an example of that. You'll probably have more than one aspect of behavior, so write more examples until the controller works. The controller will have a number of collaborating classes that you haven't written yet, so mock those out - just dependency inject them via an interface. You can write them later.
When you've finished with the controller, replace the next thing you've mocked out in the real system by real code, and test-drive that. Oh, and don't bother mocking out domain objects (like Account) - it'll be a pain in the neck - but do inject any complex behavior into them and mock that out instead.
This way, you're always writing the interface that you wish you had - something that's easy to use - for every class. You're describing the behavior of that class and providing some examples of how to use it. You're making it safe and easy to change, and the appropriate design will emerge (feel free to be guided by patterns, thoughtful common sense and experience).
BTW, with Login, I tend to work out what the user wants to log in for, then code that first. Add Login later - it's usually not very risky and doesn't change much once it's written, so you may not even need to unit-test it. Up to you.
Test until fear is replaced by boredom. Property accessors and constructors are high cost to benefit to write tests against. I usually test them indirectly as part of some other (higher) test.
For a new project, I'd recommend looking at ATDD. Find a user-story that you want to pick first (based on user value). Write an acceptance test that should pass when the user story is done. Now drill down into the types that you'd need to get the AT to pass -- using TDD. The acceptance test will tell you which objects and what behaviors are required. You then implement them one at a time using TDD. When all your tests (incl your acc. test) pass - you pick up the next user story and repeat.
Let's say you pick 'Create user' as your first story. Then you write examples of how that should work. Turn them into automated acceptance tests.
create valid user -> account should be created
create invalid user ( diff combinations that show what is invalid ) -> account shouldn't be created, helpful error shown to the user
AccountsVM.CreateUser(username, password)
AccountsVM.HasUser(username)
AccountsVM.ErrorMessage
The test would show that you need the above. You then go test-drive them them out.
Don't test what is too simple to break.
getters and setters are too simple to be broken, so said, the code is so simple that an error can not happen.
you test the public methods and assert the response is as expected. If the method return void you have to test "collateral consequences" (sometimes is not easy, eg to test a email was sent). When this happens you can use mocks to test not the response but how the method executes (you ask the mockk if the Class Under Test called him the desired way)
I start doing Katas to learn the basics: JUnit and TestNG; then Harmcrest; then read EasyMock or Mockito documentation.
Look for katas at github, or here
http://codekata.pragprog.com
http://codingdojo.org/
The first test should be the easiest one! Maybe one that just force you to create the CUT (class under test)
But again, try katas!
http://codingdojo.org/cgi-bin/wiki.pl?KataFizzBuzz

Could this be a good use of global variables?

Global state is conventionally frowned upon. However, I think I can use it clientside to make my app simpler.
I have an AJAX web app that sets up several values when the user logs in - user id, as well as some other information. This info does not change for the lifetime of the app.
I also have a cache of data to minimize trips to the server.
Can I safely make all these global? (the read-only user info and the cache) I think it would make it simpler because then I wouldn't have to worry about passing the values off between functions in sometimes awkward ways.
Essentially, it'd be like constants whose values aren't known at "compile-time."
In some ways, the DOM itself serves as a form of global state - I could store a value in HTML and it would be accessible from anywhere in the program.
There's nothing wrong in using globals, if you know what you're doing. Try to keep it clean by wrapping all your "constants" in a single global object. The major concern with globals is that you're tied to a single instance of whatever state your globals store, which may or may not be a problem in your case.
You could create a namespace, this way variables would be like global, but you wouldn't have to worry too much for clashes and that kind of stuff. Facebook does that on some of it's APIs.
Just to be safe, here's an example safe namespace implementation:
if(!window.MY_NAMESPACE){
MY_NAMESPACE = {
a_variable : "some value",
a_function: function(params){
return a_variable;
},
};
}
That way you get something like global stuff, without clashing with other variables in the document (or duplicates of your script)
I think it is perfectly OK to use global state for the purposes you mentioned. Just make sure they are written to only once, i.e. not changed during execution. So try to give them names that you won't accidentally overwrite them afterwards (which is always a danger in Javascript - forgeting var and your variable becomes global, i.e. attached to the window object) and preferably put them all into the same structure, to further minimize the danger of name collisions (less names, less collisions).
Also keep in mind, that the variables are not really 'global'; if the user keeps logged in but opens a new window to your site, the 'global' variables are gone. In this case you have to ensure, that there won't be an inconsistency, i.e. the server assumes that given a user is logged in, the variables are set.

Resources