Archive

Archive for the ‘CodeProject’ Category

Adding Bootstrap to SPFx web parts

Hi Folks

So we have an SPFx web part that shows how to integrate the React ‘Thinking’ tutorial with the SPFx tutorial but it looks pretty nasty:

thinking-webpart-000

Read more…

Using Themed StyleSheets in your SharePoint Web Parts

Hi Folks

A simple little trick here.  We have developed a nice tabbing web part (which is NOT a jQuery wrapper which shows and hides but a ‘proper’ we only load what you need tabbing system) and as part of it we wanted to use the Search Navigation Web Parts theming.

We did this for consistency so that out of the box the experience with our web part is identical to the only other tabbed interface in SharePoint.

We also wanted to respect any theming that was in place rather than force our own onto the part.

Now its very easy to reference a SharePoint themed style sheet in a web part the trick is simply in OnLoad to use the CssRegistration class as follows:

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
CssRegistration.Register(“Themable/searchv15.css”);
}

Now the style sheet will be loaded and you can use its styles.  In addition if you are using theming the themed version will be loaded for you so your colour and font choices are respected and finally if anything else has requested the same style sheet it will only be loaded once.

Cheers

Sebastian

 

Pulling the table cloth from under the enumeration glasses

Hi Folks

Ever had a need to do something to every item in a collection that would change the collection?  I don’t know lets say removing all SharePoint Site Collections under a managed path.

Now we all know that you can enumerate a collection and then loop through acting on each element but if you change the element in a way that’s meaningful to the enumeration, say adding or removing an element or changing its identifier then, quite rightly, the enumeration throws an error.

Now this is correct when developing a generic solution as it prevents a number of context specific bugs, i.e. I remove all the elements but another process adds one whilst I’m doing it so at the end I think my collection is empty but actually its not.  If this is important to you then this technique is not correct, I’d suggest a while enumeration is not empty remove loop instead.

However often when acting as an administrator such concerns don’t apply, for example I’m the only one acting on the elements of the enumeration or I can always run it twice if needed. In this case there is a well known solution we enumerate the collection and store the result as a variable of a suitable type, probably a list or array, and then act on the variable by enumerating it. As we are modifying the ‘copy’ of the references and not the elements themselves we can happily add, edit and remove them because we are affecting the original elements and not the references we are now enumerating.

So how do we do this in PowerShell?

$Collection = Get-SPSite -Limit:All

This will get us a reference to all the site collections we can now act on, be careful though this will remove all the site collections in your farm.  For safety I’ve put the somewhat confusing double negative confirm flag on so at least you will be prompted before a site is deleted.  If you want it to not prompt you use -Confirm:$false, i.e. do not ask me for confirmation.

$Collection |% { Remove-SPSite -Identity:$_ -Confirm:$true }

Lovely in just two lines we have acted on every site.  We can reduce it to a single line but not as we would expect.

Get-SPSite -Limit:All |% { Remove-SPSite -Identity:$_ -Confirm:$true }

Instead we have to cast our results to an array to force the enumeration to complete before passing it to our script block.

@(Get-SPSite -Limit:All) |% { Remove-SPSite -Identity:$_ -Confirm:$true }

Bish bosh, job’s a good’un!

Cheers

Sebastian

Minimum Possible Client

Hi Folks

Interesting conversation on Thursday I overheard at a client site.

Mature Development Manager: Does it pass the unit tests?

Cocky Young Developer: Pardon?

MDM: What unit tests do we have?

CYD: Kim and Chris. <brittle laugh>

MDM: Don’t we have any unit tests?

CYD: Its written in Word so no, unit tests aren’t possible.

MDM: Isn’t most of it in C#?  You can unit test that at least.  Where is the code in TFS?

CYD: I don’t put it in TFS.

If I had been that developer’s manager he would have either put the source code in that instant or have been no longer employed.

I looked at my code and the unit test I was just writing.  My code is for SharePoint and that is also not easy to test but over the years I have learnt to keep the linkages to SharePoint very light, e.g. event receivers and feature receivers have no code in them except for a single call into the class that does the actual work and use dependency injection to pass anything environmental, e.g. an SPWeb, so that the functionality can be unit tested.

However what I was testing not really unit testable as it had to copy something from one web to another and then call a SharePoint method on it and I wanted to check that it had worked.  Problem is that I can’t easily mock up the SPWeb objects they are just too big and complex and the environment is crucial because it can fail for multiple reasons.  Before I have written unit tests that create SPWebs and SPSites but these are really integration tests.  Then I realised that what I needed at that moment was not a unit test, or an integration test because the deployment invoked, via a feature stapler, a feature that called the static method on the static class that invoked the copy functionality and our deployment process requires us to create a series of SPWebs that cover all the possibilities.  So it can’t be easily released without being tested.  What I needed was a cheap way to invoke the method so I could do ad hoc testing without having to create an SPWeb and easily debug it if it did.  What I needed was the Minimum Possible Client for this method and I had such a thing.  It was a very simple unit test.

[Fact]

public void DoesChangeThemeInNonRootSiteRootWeb()

{

   using (var rootSite = new SPSite(http://root.local/&#8221;))

   using (var rootWeb = rootSite.OpenWeb())

   using (var site = new SPSite(http://root.local/office/london/&#8221;))

   using (var web = site.OpenWeb())

{

     // Arrange

     var expectedTheme = rootWeb.GetCurrentTheme();

     // Act

web.ApplyParentTheme();

     // Assert

     var actualTheme = web.GetCurrentTheme();

    Assert.Equal(expectedTheme[Theme.FontSchemeUrlFieldInternalName], actualTheme[Theme.FontSchemeUrlFieldInternalName]);

    Assert.Equal(expectedTheme[Theme.ImageUrlFieldInternalName], actualTheme[Theme.ImageUrlFieldInternalName]);

    Assert.Equal(expectedTheme[Theme.NameFieldInternalName], actualTheme[Theme.NameFieldInternalName]);

    Assert.Equal(expectedTheme[Theme.ThemeUrlFieldInternalName], actualTheme[Theme.ThemeUrlFieldInternalName]);

}

}

Now this does not appear to have dependency injection but the method is actually an extender so we can call anything that implements SPWeb, there is an internal method called ApplyTheme(this SPWeb sourceWeb, SPWeb destinationWeb) which I could have tested instead but I wanted to test the minimum possible and the name of the method ApplyParentTheme makes its purpose obvious.  If I was properly testing I’d have two sets of tests for GetParentWeb() and ApplyTheme() but this is enough because of the deployment tests.

It turns out Unit tests make excellent Minimum Possible Clients.

And yes, dear listener, all of my code lives in TFS.

Cheers

Sebastian

Categories: CodeProject Tags: ,

Adding the org chart back into a SharePoint 2013 My Site

One thing everyone loved about the SharePoint 2010 my sites was the Silverlight Organisation chart.

It seems to have been dropped from SharePoint 2013, my guess as Silverlight is no longer flavour of the month.

However its still there on the \organizationview.aspx page in the My Site Host Collection Site.

All we need to do to bring it back is modify the quick navigation and add a link to it and hey presto!

We can do this via the GUI or we can use PowerShell to do this.

Using the GUI

Log onto the my site root site as a site collection administrator.

Select the ‘Gear Wheel’

Select ‘Site Settings’.

Under ‘Look and Feel’ select ‘Quick Launch’.

Select ‘New Heading’.

New Heading

Set the web address to http://<my site host collection root site URL>/organizationview.aspx’.

Set the description to ‘Organisation Chart’.

Select ‘OK‘.

Using PowerShell

$Web = Get-SPWeb -Identity:http://<my site host collection root site URL>/”

$Navigation = $Web.Navigation.QuickLaunch

$Node = New-Object `

-TypeName:“Microsoft.SharePoint.Navigation.SPNavigationNode” `

-ArgumentList:“Organisation Chart”, http://<my site host collection root site URL>/OrganisationView.aspx”, $true

$Web.Navigation.QuickLaunch.AddAsLast($Node)

Organisation Chart Link

Enjoy

Sebastian

Too many numbers

For a long time now I’ve been telling people that there are only three numbers in computing:

  • None
  • One
  • Many (and for our purposes Many will actually be Two)

Thus when testing if we cover these bases then that should be enough.  For example if testing that modifying properties on a record I might have a set of unit tests as follows:

  • AddsNoProperties
  • AddsOneProperty
  • AddsTwoProperties

However even though records are by definition immutable in practice records managers sometimes have to amend them so we also need to test.

  • UpdatesNoProperties
  • UpdatesOneProperty
  • UpdatesTwoProperties

Worse still they sometimes update records by removing information (typically due to a ‘misfile’) so we also need:

  • DeletesNoProperties
  • DeletesOneProperty
  • DeletesTwoProperties

That’s nine tests not too bad.  Hold on what if in a single transaction we add some properties, update some properties and delete some properties?

  • AddsNoPropertiesUpdatesNoPropertiesDeletesNoProperties
  • AddsOnePropertyUpdatesNoPropertiesDeletesNoProperties
  • AddsTwoPropertiesUpdatesNoPropertiesDeletesNoProperties
  • AddsNoPropertiesUpdatesOnePropertyDeletesNoProperties
  • AddsOnePropertyUpdatesOnePropertyDeletesNoProperties
  • AddsTwoPropertiesUpdatesOnePropertyDeletesNoProperties
  • AddsNoPropertiesUpdatesTwoPropertiesDeletesNoProperties
  • AddsOnePropertyUpdatesTwoPropertiesDeletesNoProperties
  • AddsTwoPropertiesUpdatesTwoPropertiesDeletesNoProperties

If you work it out that’s 54 tests.  That’s too many.  We use xUnit so as well as Facts (xUnit tests) we have Theories (xUnit ‘data-driven’ tests) so maybe we really have one ‘theory’.

  • AddsSomePropertiesUpdatesSomePropertiesDeletesSomeProperties

It will have fifty four examples, so while its better its still long to run and set up.  It smells of hidden complexity.

Hold on do we really have three numbers?  I don’t think so in fact we may have only one number:

  • Some, and for our purposes this can be defined as any number greater than the minimum value and less than the maximum value.

In addition we probably have two edge cases:

  • Minimum value, which we can assume as zero.
  • Maximum value, which if we assume is two we can easily handle.

For this to be useful we need to be working with a collection of separate things, that is they must all be homogeneous and independent.  If they are not homogeneous then we need to treat each separately and if they have dependency on each other then which one we change becomes important.  However when using collections, e.g. lists, arrays, dictionaries, this is nearly always the case.

So this means I can now have a single test so long as I have enough things in my collection to allow for each action. I choose to split my actions and end up with three tests based on an object with two properties.

  • AddsSomeProperties, using one existing property and adding one new property.
  • UpdatesSomeProperties, using two properties and updating one and not the other.
  • DeletesSomeProperties, using two properties and deleting one and not the other.

This is quick and easy and covers all the bases, except for those pesky edge cases.  However if these are important, e.g. deleting all properties, then we can convert our facts into theories and test for them.

So in this case we don’t have three numbers, in this case we only have one number:

  • Some

Happy testing

Sebastian

Avoiding SharePoint Magic Numbers in Unit Testing

Unit testing really is good. No surprise to those who do it but recently we had a test go red when changing how we configure Enhanced Records Manager, see
Appropriate use of AppInstalled for a Provider Hosted SharePoint App for more details.

Not a problem we have broken something lets fix it.

It turns out that every properties metadata was being added twice to our configuration database.  Simple.  We had inadvertently called the ImportProperties method twice.  So all we have to do is remove the wrong call and we are away.  Hold on isn’t import properties supposed to update if the same property is imported twice not add.  Lets dig further.

So when we unit test we don’t use SharePoint, its too ‘heavy’, but we have abstracted it in the design to an Interface called the RecordRepository Interface which has ‘generic’ methods, such as GetProperties which returns all the properties the Records Management system.  This gives us two great benefits:

  1. We can replace it for unit testing by a lightweight RecordsRepository currently a pure in memory one.
  2. We can use Records Repositories other than SharePoint by ‘merely’ replacing the Records Repository as it only deals with access, not logic.

The ImportProperties unit tests weren’t failing so the actual logic was okay, well we all know GIGO (Garbage In, Garbage Out) so if the output is wrong but the logic is right it must be the input.  And Lo and behold so it was.  Our Unit test Records Repository generates a defined set of properties using Guids as their unique identifiers.  Good.  Problem was they were generated each time the GetProperties method was called so if you called it twice you get two sets of properties identical in all but identifier.

A long preamble but it got me thinking.  Why hadn’t we just used the known identifiers for the SharePoint built in fields?  Title is always {fa564e0f-0c70-4ab9-b863-0177e6ddd247}.  We didn’t so why?  Ah yes go back to point 2 the design of ERM is that it is repository agnostic.  If we had just used the ‘magic’ value when we changed the actual Records Repository we could have been in the position where our unit tests passed fine but it failed in practice because we had been lazy and also used the magic value somewhere in the business logic.

So we generated Guids just for our Unit test Records Repository as fixed Guids and that sorted that.

Cheers

Sebastian