Transforms: automatic testing, readability, improvements

Dear Community,

While developing transforms I have encountered some limitations which contributed to the transforms getting out of hand in size and becoming unreadable without spending a lot of time. I have to re-read them every time and I would not be able to say with 100% certainty they are correct (just because of a simple typo).

Do you have transforms that are big and “unreadable”? How do you handle them?
How do you test them? Did anyone created a test harness for them? Does SailPoint has any plan for this?
As a developer I think that testing of code (or code-like) is paramount, and I can see easily how mistakes/typos can get introduced into the JSON.

I have also created a small dummy transform to make them in a more human readable format. In the case below the size is reduced from 159 lines to 61.

Name: Status Trigger
firstValid(
    [#if ($attrSamAccountName == 'not-set')waiting_AD_sAMAccountName_$now#elseif($attrMail == 'not-set')waiting_AD_mail_$now#end]
        attrSamAccountName => 
                              firstValid(
                                  [#if ($attr)set#end]
                                      comment => [If the attribute doesn't exist, the if condition will actually error out and return nothing]
                                      attr => 
                                              [Active Directory.sAMAccountName]
                                   "not-set"
                              )
        attrMail => 
                    firstValid(
                        [#if ($attr)set#end]
                            comment => [If the attribute doesn't exist, the if condition will actually error out and return nothing]
                            attr => 
                                    [Active Directory.mail]
                         "not-set"
                    )
        now => 
               dateFormat(yyyy-MM-dd'T'HH:mm -> ISO8601
                   dateMath(
                       now
                       <INPUT>
                   )
               )
    [#if ($joiner_triggered != 'null')joiner_triggered_${joiner_triggered}#end]
        joiner_triggered => 
                            firstValid(
                                [Identity State.joiner_triggered]
                                 "null"
                            )
    [#if($lifecyclestate == 'pre-hire' && $in14DaysIntervalBeforeStartDate == 'true')joiner_trigger_needed_${now}#end]
        lifecyclestate => 
                          transform:Lifecycle State Source
        in14DaysIntervalBeforeStartDate => 
                                           firstValid(
                                               dateCompare(
                                                   if
                                                       transform:Start Date (ISO8601) (Source)
                                                   >
                                                       dateFormat(yyyy-MM-dd'T'HH:mm -> ISO8601
                                                           dateMath(
                                                               now-14d
                                                               <INPUT>
                                                           )
                                                       )
                                                   then
                                                       "true"
                                                   else
                                                       "false"
                                                   end
                                           )
        now => 
               dateFormat(yyyy-MM-dd'T'HH:mm -> ISO8601
                   dateMath(
                       now
                       <INPUT>
                   )
               )
)

Consider you have a small typo, this is what you would see if you would compare the correct code with the wrong one:

I find it very hard to spot the change, if you wouldn’t have the correct code to compare with.

Comparing the outputs with the help of a tool would make the issue apparent immediately:

So to finish this post, what are your thoughts on transforms?
Is there any work being planned for the immediate future to improve them (e.g. the date* transforms should all support inputFormat/ outputFormat and now), or to make testing practicable?

Best regards,
Andrei

1 Like

These are good questions, there are few things I do that helps with transforms.

For one, the VSCode IDN/ISC extension makes working with transforms easier (in some cases it’ll catch errors, especially when you try to save them).

I’ve had a static transform where I needed to use a very long line of Velocity, so when I work on it, I copy it to Notepad++ so I can separate the lines and make it more readable, before copying it back to VSCode and combining them back into one line.

This part may be obvious, but I’ll post it just in case: To test the transform, first we apply it in Sandbox and rely on the “preview” button in the mappings tab of the identity profile to make sure we’re getting expected results on multiple identities before applying it to all identities.

This is much needed discussion.

There is no tool like Jupiter to test the code fragments. I create a test attribute and test the transform with a minimal logic and increment the logics one by one to avoid the mistakes.

I use Notepad++ and VS code. I have seen in developer days, you get boilerplate for Transforms with shortcut tr-static something for static transform, need to check it thoroughly.

It is good to use version controls like github to see the changes you made.