I'm designing a small application using Symfony2, with a DDD domain conceived as a vendor. This allows me to abstract my domain by not making any assumptions on what uses it. Basically, this domain is a set of business entities and services which perform their internal stuff. The business operations are called from the outside (Symfony controllers) by simple facades that do not expose anything from the domain.
Now, I would like to test my domain to validate its business rules. Given that this domain can't work on its own as it needs concrete repositories implementations, I set up my tests to use mocks of these repositories. My question is : how can I validate all the domain actions which are performed internally ?
For instance, suppose my domain is made of two entities : Article and Category. I can traverse an article to get its category, but I can't traverse a category to get its articles as it doesn't make sense in the context of my domain. Now, I have a business rule that states that whenever a category is disabled, all the articles on this category should be disabled as well.
The entry point for this action would be a disable($category) method on a CategoryFacade service. This action would first disable the category, then fetch all the articles of this category and disable them.
If I call the disable() action from a test case, I can validate that my category was correctly disabled as it is the actual object on which I am performing the test. But what about the articles ? I don't have a getArticles() method on my category, and since my domain only uses mocks as repositories, it wouldn't make any sense to fetch manually the articles and asserting on them.
Edit
The answer proposed below reminded me of something critical. Indeed, in my example, a category is to be considered as an AR as it has an existence outside the scope of an article. But since an article is an AR as well, it should be entirely responsible for its own consistency. That means that the deactivation of all articles linked to a category should not be initiated by a category service, as this service shouldn't know anything about articles. My choice will be the one proposed below : dispatch en event whenever a category is disabled, and perform deactivation on articles in a service which is inside the boundaries of my article.
In first place it is best to not test repositories togheter with domain logic and since repositories should be used only in application layer, then you shoudln't test application services. If you have to, then just create some test repository (memory based).
You should test your business rules just on domain objects. In example if you want to test if user rating works fine then do:
rated_user = UserFactory(parameters)
assertEqual(rated_user.rating, Rating(0))
rating_user = UserFactory(parameters)
rating_value = 3
rating_user.rateUser(rated_user, rating)
assertEqual(rated_user.rating, Rating(3))
Testing of your case is difficult because ARs should be changed in different transactions (probably even not in the same request). From what you say it seems that Category should be an AR (aggregate root), because in order to disable category we have to fetch one category without using an article to do so.
Now when you disable category, you should send event that articles should get and disable itself then. You can test if articles are disabled just by calling EventListener callback, that would be better IMHO. Testing both ARs togheter would be actually an integration test, which requires more setup.
Anyway, to test if all articles of a given category are disabled, you have to fetch them, probably using something like "articlesRepository.getArticlesOfCategory(category)" and check one by one if it's disabled. There is no other way.
Related
I have two queries related to SCRUM. They are as follows:
I have read that the format of SCRUM story is "As a < type of user >, I want < some goal > so that < some reason >". I have to write a story for an API. This API will send an email with a link to validate the email address of the user. What will be the type of user here? Will it be the user logged in?
Do subtasks have story format similar to a story or it can be a normal description?
The trouble you are encountering is likely that you are starting from a determined implementation and then trying to work backwards to the need (unless your product is an API that your users leverage, in which case I think that answers your questions).
When we approach it from a user need, we'll usually end up with more of a problem statement, like
"As a vacationer, I'd like the site to calculate the best route across
all types of transportation for me so that I don't have to run many
searches to figure it out myself."
One of the pieces of delivering on this need will be creating the API calls if your application architecture calls for that. Then "add API method for aggregated call" may be a task under that user story.
You will have cases where all a particular story needs is API work, and that's fine, but it won't come out in the user story. For example, let's say we did the about user story but limited it to planes and trains for the first start, then we created another story that reads:
"As a vacationer in the US, I want my trip planner to factor in buses
so that I can make use of bus tours in my vacation."
Now, maybe the only task in there is to create a some API changes to include the bus routes in the search, but that doesn't cause a problem with your user stories because we started back at the user's problem statement in the beginning instead of starting at the desired implementation and working backward.
Let's start clarifying some concepts first.
Scrum is not an acronym so is written as Scrum (proper name). Then, there is nothing called "Scrum Stories". What you are referring to is called: user story. User stories were wide used in the Chrysler C3 project were eXtreme Programming was developed. Furthermore, you are referring to a particular template which was popularized by Mike Cohn known as canonical form. So it's ok to express your Product Backlog Item as user stories for an API. But take into account that you can use this template, you can use user stories or you can write the Product Backlog Item the way has more sense and value to you. In your case, which is the persona, machine or service which will be used the API?
About your second question. The Scrum Guide just says you should decompose your Sprint Planning in unit of work of 1 day or less. Normally, the implementation is to create this unit of work and call them task which are the work necessary to carry out the user story. The way the are written is open too but is not quite common to write them in the canonical form. So you can write it as an ID, title and a description.
these days I’m facing a fundamental problem – let’s call it an architectural design decision.
So my team and I build typical line of business (lob)-web-applications for my company. For my purpose, lob means especially this:
A lot of user-interaction (entering data, CRUD entities, display data, aggregating data, statistics and reports, validation and so on)
Very restrictive (users have to login, users have different permission-levels, they can make different kinds of changes on different entities, display various reports and so on)
For an example, let’s take an ordinary approval-workflow: I need a new laptop, so I go to the “ressources-webApp” and create a new purchase requisition. My boss gets a notification and has to approve my request. In the next step, the proper department has to buy the laptop and finish my requisition.
I know this is a simple “hello world”-example and in real life you would use an existing software for this purpose (SAP or something like that), but it describes my use-case pretty well: data-driven and very restrictive (I can see all requisitions of my department but only change or delete my ones, I should not see the page for the approval or call the approval-api, my boss should only see the requests of his employees but not for the empolyees of another department, neither my boss nor I should see the page or be able to finish a requisition and so on).
Currently we are using ASP.NET MVC and WebAPI in combination with angularjs 1. For each “action” (page or view) exists a mvc-controller which listens to a specific route and returns the appropriate view. Each view references a specific angular-controller. Also each view may consist of different “partial views” (components or controls). To handle data the angular-controller calls webAPI-controllers which also listen to specific routes and handle the request (GET/POST/PUT/DELETE). Each controller (mvc and webAPI) checks the authorization-token of each http-request which comes in a cookie, if the user is allowed to open the page or call the action.
Now I’m wondering how to do this in a SPA-application with angular 2. Angular 2 sounds pretty interesting for me and has some nice benefits over angular 1, so I want to try angular 2. It seems that with angular 2 you only can build a SPA-application (compared to the “classical” MPA-application I mentioned above, where every page comes from the server and contains a angular-controller).
Generally I’m not disinclined to SPA, but I’m not sure how to handle the security-questions mentioned above.
In addition there are other common problems with SPA: not working back-buttons from the browser, no way to enter a specific url directly to the browser, no bookmarking etc.
So, do you have any advice, tip or best practice for me? Do you think that SPA is a good “pattern” for lob-web-applications? And if yes, how would you handle the security-problems as well as the other common SPA-problems?
Best regards,
Alex
This is my current understanding of the events on pressing the Activate button:
If the user has replication permission, the content is sent to the dispatcher.
If the user does not have replicate, the Request for Activate workflow is run. Out of the Box this performs two steps which are both sent to the Administrators group.
If I change the OOB Request for Activation workflow to assign to another group then this group gets the message in their CQ Inbox instead.
My requirement is that I have multiple websites belonging to different divisions within the company, meaning that each has separate groups for users who can only author content and users who can Approve/Activate that content. In one case there is an additional requirement for the content in the careers section to be approved by the HR team only.
How can I alter the workflow to achieve these requirements?
I can think of two ways of doing this:
1) Change the OOB box workflow to use OR steps to switch to differnt groups based on the content path. This could get very complex when dealing with pages for both pages and assets, and the special conditions like the careers example.
2) Create a custom step that runs Java code that uses the AccessControlManager class to look for replicate permissions on the node, and if there aren't any then to traverse up the tree until it finds a node with permissions.
I've gone with option 1) for a similar problem.
If your main concern is having too many branches in your OR Split, maybe there's an opportunity to break down the workflow's decisions into multiple steps, instead of having one decision point where it branches out to many different paths.
For example, you might first split by what site the payload is on, and then split again based on user type, or section of the site. So, something like:
site 1
section 1
role 1
role 2
section 2
site 2
... and so on, where each level of indentation represents a separate OR Split.
If you use the Container Step to trigger a sub-workflow at each of these decision points, that may help keep your workflow more organised.
Because I didn't love the idea of changing the OOB Request for Activation workflow, I minimised that by making the first step an OR Split that does a generic check - basically:
Pseudo-code:
if (we're in one of the sites that's subject to my custom workflows) {
Container step that points to my main custom workflow;
} else {
Continue with the default Request for Activation workflow steps;
}
That way you make minimal changes to the OOB workflow, and leave yourself open to running the default workflow if you set up a new site on the same instance, and don't want it subject to your custom workflow.
We've created a custom property in each page, "page owner", which in fact is a pointer to a group (I wish we have made it inheritable through the tree since beginning). Then workflow was customized so that page owner group receives this in their inbox for approval.
I'm sorry if this is not within the acceptable question guidelines for Stack Overflow, but I am feeling stumped, and I feel that what I'm trying to do might just be incredibly simple for some of the veterans here.
I've set up an Ubercart on a Drupal installation for a small gym website. What they are wanting is to allow a customer to register and pay for various memberships for their children (youth flag football, teeball, etc.). One person may come back and sign up multiple times throughout the year, and each customer may have multiple children who can each participate in multiple programs.
What I'm thinking is to disable anonymous checkout on Ubercart. The customer billing address will be the saved information for the "parent." I'm thinking that the parents could create Members (their children) which could be stored in a content type called Members and the Members could be linked to the programs of which they are a member via entity reference. The children could maintain their relationship to their parents by authorship.
I've been trying to work through this for the last few hours. Does anyone know of a way the I can accomplish this--maybe with rules? I'm thinking some kind of credit system in which for each quantity of a membership (per program) that they pay for, they get one "credit" to create one entity reference between a member and a program.
Any brainstorming and help on this topic would be majorly appreciated. Thanks.
Your use case sounds more like event registration than selling memberships. Each class would be an event that parents would register their children for. It may seem like overkill here, but I would use something like CiviCRM or RedHen CRM for this. Both support the concept of relationships between members and provide event management tools. You could make each class an event that people would sign up for, pay (they could even register multiple children at the same time) and get a receipt. The event history information would be stored so parents could sign in and see what each child has done. You could even make the list of kids in the class public so parents could see who else is in the class.
Afterward, it would be easy to put together a survey to send to the "attendees" to get feedback on the event/class and notify them about future events. I can think of a dozen different things that these systems cover that you may need in the future (early bird event registration, special pricing for returning parents/children, activity reports to email to parents every year so they can see what their children did...).
You may be able to pull together modules and custom content types (Ubercart Event Registration module as a starting point), but a CRM would provide the things you are looking for now, and the features your customer will be asking for in the future.
We're investigating Alfresco for doing wideband delphi ("planning poker") based on submitted statements of work (collected user stories). I've been reading through the Alfresco documentation, and there are two questions that I haven't been able to get clear answers to:
Can we set it up so users can write, but not read, to a folder or node? (To support "anonymous" planning, without users knowing what the other users submitted estimates were)
Can workflow tasks be implemented to ask users to comment or submit items to a node or director with the above model, rather than just simple approve or deny?
Workflow:
User submits a statement of work
All users (or selected users at random, or ... ) in group get notice to review
Reviews include estimates on the overall SOW or specific phases
Reviews are anonymous/secret to all but the manager
Have you implemented something similar in Alfresco with fine grained access control? Sharing your experience would be very helpful... i'm not looking for someone to do the work for me, just to confirm it can be done.
I would use some kind of parallel workflow for this.
First the managers starts the workflow and the task type of this first node will have additional info about the user story and such, then the manager selects a people or a group to which it will send this user story.
Here comes the parallel thing into play. Because it's parallel noone sees the results of the other members of the workflow. The members fill in the requested fields (another custom task type with data like: score (estimate) and maybe explanation.
Before the workflow goes back to manager the automatic calculations are made in a non-user task/node where you calculate overall score for the story. You can include each individual user and their score in the result/report if necessary.
Now the results are sent to the manager.