Category: poker planning

MVC-Planning Poker – Architecture versus unit testing fast

Now I have arrived to the moment when I want data to be persisted on disk. I choose SqlIte – because EF 7 is not yet on the market and SqlIte  could work on Windows Phone / Android.

So now I want to just serialize TableData and save . To serialize I have several options – yesterday was XML, not it is Json. The Newtosnoft Json library could do the serialization – and with SqlIte I could put into a database file.

 

However, the problem is with what we have for serialization / deserialization and how we have conceived the software.

For example, Table class does not have a public constructor – a Table does not exists without a Moderator to create it – and which Cards to display

internal Table(string moderatorName, List<Card> cards = null)

For Deserializer to work, the Table either should have a public constructor

p

 public Table(): this("", null)

, either  the deserializer will have a function to construct the Table.

The first option means that the architecture will be somehow not so good.

The second option means more work for the programmer.

In .NET we have the third option – we can use obsolete:

 

[Obsolete("Use CreateTable from TableFactory",true)]
        public Table(): this("", null)

The true option means raising an error when we COMPILE code that uses the constructor – not at run time, when the deserializer uses it.

So we maintain the architecture – and not enforce at run time.

If we wrote

 Table t = new Table();

the compiler gives

1>D:\sourcecontrol\Vs\MVC Planning Poker\PlanningPoker2013\PPTest2013\SerializeTableData.cs(68,23,68,34): error CS0619: ‘Table.Table()’ is obsolete: ‘Use CreateTable from TableFactory’

 

However , the serialization uses happily the constructor – even if it is obsolete , it works!

MVC planning poker–delete round – part 8

Stefan Petrini make a final test, DeleteRound ( with subcases for Moderator and for non-Moderator deleting a table)

bool DeleteNotModeratorSuccess = true;
            try
            {
                td.Table.DeleteRound(td.Table.Id + "NotModerator".GetHashCode(), "Round2");//Attempting to delete a round without being a Moderator
            }
            catch (PPSecurityExceptionModerator)
            {
                DeleteNotModeratorSuccess = false;
            }
            Assert.IsFalse(DeleteNotModeratorSuccess);

For now the application has 20 tests – all without data persistance ( all is in memory)
It is time to add a saving to database in order to persist data.

MVC planning poker–part 7

The latest 2 cases are

Use Case 5: Round reset
Moderator enters a round name (?) .
Participants choose a value.
Host press "reset round " and a fresh new round is created
The old one is not saved

Use Case 6: Round save
After a round is saved, the users can see the history round names and picked value
They can see also a total

 

There is not so more implementation – just save in the memory  a list and retrieve.

Next time we will be thinking about persistence – how this affect the structure of the application

MVC planning poker–part 6

The complete case 4 is:

Use Case 4: Estimation saved
Moderator enters a round name (?) .
Participants choose a value.
When all participants have choosen the value, the cards are shown
The cards with  high estimates and low estimates are highlighted
Host press "create new estimation" and create new estimation
The old estimation is saved in history

For now it is the moment to do estimation and save in the memory.

The code is

[TestMethod]
            public void EstimationSaved()
            {
                var td = createdTable();
                var rd = td.Table.StartRound("first");
                rd.AddCardChoice(1, newParticipantName1);
                rd.AddCardChoice(Card.NotSure, newParticipantName2);
                rd.AddCardChoice(3, newParticipantName3);
                
                rd.StartNewEstimation();
                rd.AddCardChoice(1,newParticipantName1);
                rd.AddCardChoice(3,newParticipantName2);

                var est=rd.ParticipantChoices(newParticipantName1).ToArray();
                Assert.AreEqual(1,est.First());
                Assert.AreEqual(1, est.Last());

                est = rd.ParticipantChoices(newParticipantName2).ToArray();
                Assert.AreEqual(Card.NotSure, est.First());
                Assert.AreEqual(3, est.Last());

                est = rd.ParticipantChoices(newParticipantName3).ToArray();
                Assert.AreEqual(3, est.First());
                Assert.AreEqual(Card.WithoutChoice, est.Last());


            }

MVC planning poker- implementing cards- part 5

The use case 4 states

Use Case 4: Estimation saved
Moderator enters a round name (?) .
Participants choose a value.

The value is a card – that have a value. Wikipedia states that

<<Several commercially available decks use the sequence: 0, ½, 1, 2, 3, 5, 8, 13, 20, 40, 100, and optionally a ? (unsure) and a coffee cup (I need a break). Some organizations use standard playing cards of Ace, 2, 3, 5, 8 and king. Where king means: "this item is too big or too complicated to estimate". "Throwing a king" ends discussion of the item for the current sprint. >>

It is clear that the value ( as stated incorrectly in the use case ) is a Card – and this will be a class that have a value( decimal / double ) and there will be some cards ( unsure, coffee cup, king) that do not have value.

However, the cards must

  1. be converted from and to the decimal / double value( if possible)
  2. be added and converted to decimal / double

The code for the tests will be the following and it is self explanatory

[TestMethod]
        public void CoffeeCupEqualsCoffeeCup()
        {
            var c1 = Card.CoffeeCup;
            var c2 = Card.CoffeeCup;
            Assert.AreEqual(c1,c2);
        }
        
        [TestMethod]
        public void ConvertValuesEqual()
        {
            var d = 1.2m;
            var c1 = (Card)d;
            var c2 = (Card)d;
            Assert.AreEqual(c1, c2);
        }
        
        [TestMethod]
        public void ValuesEqual()
        {
            var d = 1.2m;
            var c1 = new Card(d);
            var c2 = new Card(d);
            Assert.AreEqual(c1, c2);
        }
        [TestMethod]
        public void AddingValues()
        {
            var d1 = 1.2m;
            var d2 = 1.2m;

            var c1 = new Card(d1);
            var c2 = new Card(d2);
            var c3 = Card.CoffeeCup;
            var d = (decimal) (c1 + c2+c3);
            Assert.AreEqual(d1+d2 ,d);
        }

The code is much more complicated . I am thinking where and how to share it – I want to have CI and build on Azure.

MVC planning poker-implementing security-part 4

I figured a way to see how to implement security.  When the Moderator creates a table, the factory does not return a Table – but a combination of Table and ModeratorKey. Now the Moderator must maintain his ModeratorKey .The function that boots a participant requires passing this ModeratorKey – and , if it is correct, it boots the participant. The codes are the following:

 [TestMethod]
        public void UseCase3BootTemporary()
        {
            var td = createdTable();
            td.Table.BootParticipant(td.ModeratorKey, newParticipantName);
            Assert.AreEqual(0,td.Table.Participants.Count);
            td.Table.AddParticipant(newParticipantName);
            Assert.AreEqual(1, td.Table.Participants.Count);
            
        }

        [TestMethod]
        public void UseCase3BootPermanently()
        {
            var td = createdTable();
            td.Table.BootParticipant(td.ModeratorKey, newParticipantName,true);
            Assert.AreEqual(0, td.Table.Participants.Count);
            try
            {
                td.Table.AddParticipant(newParticipantName);
            }
            catch (PPBannedUserException)
            {
                return;//expecting this exception    
            }
            Assert.IsTrue(false,"the add participant should be throwing an error");
        }

Now, as you can see , anyone could boot a participant from the table – with the condition, of course, to know the Moderator key.
Next time we will implement cards.

MVC planning poker – First vertical – security – part 3

Let’s read the Use Case 3, Boot from table:

Use Case 3: Moderator can boot from the table
Moderator can boot from the table( permanently of just for this session ) any participant.
If permanently, the participant with this name can not join anymore

 

The following code is written , for adding a participant to be booted from table

public void UseCase3RightPath()
        {
            var ModeratorName = "ignat andrei";
            string newParticipantName = "new participant";
            var roundName = "UseCase2 - Join Table";
            var table = TableFactory.CreateTable(ModeratorName);
            table.AddParticipant(newParticipantName);
            table.BootParticipant(table.ModeratorName, newParticipantName);

        }

And after that? How do I recognize that is a Moderator from a participant?

I must have a layer that recognize that, either from name, either from an ID (because I said that the software is to be put on AD/LDAP , then the name will be unique). However, if I wrote code like that:

 

 table.BootParticipant(ModeratorName, newParticipantName);

Then any part of the software that can find the moderator name could boot any participant – even in the participant the code can be written like this:

table.BootParticipant(table.ModeratorName, newParticipantName);

I need to create a security layer to recognize moderator from participant and , when first adding a moderator, unique identify this moderator over the whole table.

So on the moderator the code will be:

moderator.BootParticipant(table.id, newParticipantName);

So I need now a User class –and a Moderator class – with a function that says: BootParticipant.

The problem is that a regular user is promoted as Moderator in this instruction

var table = TableFactory.CreateTable(ModeratorName);

How this is translated into code ? I am thinking and I will come with a solution next time.

MVC planning poker -Test driven development and Version control and Continuous Integration– foundation – 2

After setting the use cases, I have now think about code. ( Ok, maybe it should be first architecture, but I am a programmer first )

So I start to code the first Use case :

 
public class UseCase1CreateTable
    {
        [TestMethod]
        public void UseCase1RightPath()
        {
            var ModeratorName = "ignat andrei";
            var roundName = "UseCase1 - Create Table";
            var table = TableFactory.CreateTable(ModeratorName);
            table.AddDuration(1);
            table.AddDuration(2);
            table.AddDuration(3);
            table.AddRoundName(roundName);
            
            Assert.AreNotEqual(0,table.Id.Length);
            Assert.AreEqual(true,table.CanAddUser);
            Assert.AreEqual(ModeratorName,table.ModeratorName);
            Assert.AreEqual(1,table.Rounds.Length);
            Assert.AreEqual(roundName, table.Rounds[0].Name);


        }
    }
 

Running the test was a no-brainer – it does not even compile. And it is good, according to https://msdn.microsoft.com/en-us/library/aa730844(v=vs.80).aspx 

Now I want to test the code, so I created the classes and now the  tests were all red (because there is nothing implemented yet, just compiling) . A hour and all is going smoothly until the test was green – http://en.wikipedia.org/wiki/Test-driven_development

Now the point is to enforce this behavior every time the programmer checks in some code.

So I think about Visual Studio Online – to test if , aside Version Control, it can help me with running test.

And yes, they have builds.And, being the single contributor to this project, I choose Gated Checkins

image

 

Now every time I check-in some code, the build will start and see what’s happening.

The code is at https://ignatandrei.visualstudio.com/DefaultCollection/MVC%20Planning%20Poker 

Exercise  for home:

Do you spot what is missing from
this test code ?

 
public class UseCase1CreateTable
    {
        [TestMethod]
        public void UseCase1RightPath()
        {
            var ModeratorName = "ignat andrei";
            var roundName = "UseCase1 - Create Table";
            var table = TableFactory.CreateTable(ModeratorName);
            table.AddDuration(1);
            table.AddDuration(2);
            table.AddDuration(3);
            table.AddRoundName(roundName);
            
            Assert.AreNotEqual(0,table.Id.Length);
            Assert.AreEqual(true,table.CanAddUser);
            Assert.AreEqual(ModeratorName,table.ModeratorName);
            Assert.AreEqual(1,table.Rounds.Length);
            Assert.AreEqual(roundName, table.Rounds[0].Name);


        }
    }
 

MVC planning poker – use cases and mockups – 1

 

I have decided to start a new project – MVC planning poker . This is inspired by http://en.wikipedia.org/wiki/Planning_poker  – and it is a program to sharpen my skills

The project is aimed to software enterprises using Active Directory – however, it can be used by any organization.

 

UseCase 1: Create table
Moderator identified by Name -  creates the table and the duration times(1,2,3,5,10) and optional the round name.

He has an ID to share to the next participants

UseCase 2: Participants join the table
Any user can join the table by entering the ID + name .

Use Case 3: Moderator can boot from the table
Moderator can boot from the table( permanently of just for this session ) any participant.
If permanently, the participant with this name can not join anymore

Use Case 4: Estimation saved
Moderator enters a round name (?) .
Participants choose a value.
When all participants have choosen the value, the cards are shown
The cards with  high estimates and low estimates are highlighted
Host press "create new estimation" and create new estimation
The old estimation is saved in history

Use Case 5: Round reset
Moderator enters a round name (?) .
Participants choose a value.
Host press "reset round " and a fresh new round is created
The old one is not saved

Use Case 6: Round save
After a round is saved, the users can see the history round names and picked value
They can see also a total

Use Case 7: Export
Participants can choose if they download the results in CSV / EXCEL / Word /PDF format

Use Case 8: Round delete
The host can delete a round previously saved

 

The mockups are the following:

 

create_table table