logo

NJP

Inside the Barrel - Scripting Architecture in ServiceNow

Import · Feb 18, 2022 · video

welcome to another episode of inside the barrel where john and i talk about consulting life behind the scenes getting into service now from a technical standpoint and today we have a juicy topic around uh scripting juicy yeah not as juicy as your background john we're doing some remodeling and some stuff all over well over there stuff's in the way and yeah yeah so so today is one that i feel like i've been converted to a believer in that there's only one right way to do something in service now and and normally it's like there's like four or five different ways but like i think this this is the the only way to do something i don't i don't know that i'm converted i i still like options i like uh freedom to do how i how i think it might work the best for me so so let's see if i can convince you by by the end of this all right yeah sure why not so really the the first part about this is um it is the problem that we have is servicenow has a lot of different fields that have the word script whether it's a business rule a transform map before and after transforms like ui policies um client scripts like there's so many different places you could add a script and and so most of the time someone's like oh i need to build a client script or i need to build a business rule it's simple i'm just going to write the script in there and you know off they go yeah i think when i first started with servicenow my biggest hang up was knowing where i was with scripts like was i on the client side or was i in the server side so it was always like wow i don't know where i don't know where the script lives yeah yeah and and and i think that's like uh one of the downfalls is like if you ever had to like troubleshoot something like you you're you're and you had to like you know as a client script or ui policy and maybe a business rule it may be a flow like there's so many different places that you would have to potentially debug to even find the thing that is then being called and like that logic may be different than how someone else is doing it in another part of the system um and so the the rule of thumb that i like to to use is every script and i'll use the word like all of them every no exceptions every time you have to write code it should be in a script include and and so grant sorry anytime you have to write javascript code so the exception of html and a little bit of service portal um is aside but i think even the [Music] server side script part of service portal should be in a script include so you shouldn't have long blocks of text there so well i think we agree to disagree on that one and don't get me wrong i love server script includes but yeah so there's a time and place for everything i will tell you the biggest benefit of why i truly believe that is the only way you can really truly test your code from a unit test from like a developer best practice is if it's in a script include and that's and that's hands down like if you write some script or some logic in a widget in a server side script you actually can't test that programmatically you would only be able to test that essentially manually um without recreating or copying pasting the code but doesn't that create so lately i've been spending a lot of time with catalog items and i am not a fan of glide ajax when it comes to catalog items just because you have an on change that doesn't wait right so you then have to move it over to a submit which kind of you lose some of the flexibility and real time uh information conveyance to the user right so if i have an on change on a field dates and i've got to go run a glide ajax to use the date utils right i don't get my response in time for them to submit right you know and so i'm not sure that i totally agree on that i should have done it through a script to include because i don't like well you're glad ajax right could call a script include right like all i know exactly that's why you would do it but if you can't if it's what is it asynchronous is that the right term if it's going to continue without waiting for my response i potentially could have a submit on my hands so i'll give you the i'll give you the secret and we should do another podcast on just that okay there's a secret i'd love yeah yeah the solution is you essentially add a true or false field on every catalog to determine if that catalog is ready to be submitted so all of your ajax things can totally you know be firing off and filling out and doing validation but until all of the fields that you are truly requiring that have an ajax are are filled in then there you would turn like that true or false field to true and then your on submit requires that to be and you don't show that to the user uh i would agree with that i've actually done a few things kind of like that where i've kind of pre-loaded the form with glide ajax before it's available so what i mean is like um i had what did i need i needed to find something out i had a sis property that had a value it had a date um and i needed to to uh validate against that date so i would gliding jack's call you know on load and then fill that hidden field in with that date um so i i agree that that's a that is usable that way but um i really wish it was more straightforward you know like i wish there was a way to get or a better way to deal with server calls from the client side as far as the catalog items went but i i will quasi allow that yeah yeah and i think there's like a pattern you could truly follow like maybe adding a a field on um [Music] uh like on a catalog item and then having a variable set like there's probably ways you could speed it up so that like you're it's you have a routine pattern for all of your catalog and that's why i say we could do an entire other video on just solving that problem because i think that's a really valid one i think i do too i think a lot of people run into this issue and and and that then that may be why they have a bad taste on server side you know yeah because i don't because glide ajax is tricky it's it's not super straightforward and you really have to understand what's going to happen when you use it yeah so let's let's we'll table that one and we'll we'll do another podcast on that one specifically um so let's let's kind of dive in and see if i can convince you that one the different types of script includes you can have so there isn't just one uh and two how you can test all of your scripts um so we'll see if i can you know convince you that there's this is the right way to test it and then three maybe show off some uh atf and some of the new features with that with with doing that that test to really show like how you the power of unit testing and um and yeah so we'll again unscripted so i don't have all the answers we may have to write some code on screen but do you have a magic of a code of them i do sometimes so we'll see if my magic code oven uh works this time so sweet let's do it we'll see if that works so let's get nice you know at some point a long time ago i wrote a blog article about um different uses for the script include that it was there were only three that i came across at that time this was like three or four years ago but it was uh you could write a you know you have a script include but you can write it to be used via you know like uh through an a uh a rest call where you pass this dot um what is the parameter you know you could multi-use the script include to where you could call it from a portal widget or through a rest api call right um and uh i i think i put my thoughts in there and why because back then i i also thought a lot of things should be backed up by a script include like widgets and so forth and then i realize that there's different use cases there where if you have a widget that's really portable i don't necessarily want it backed up with a scripting clue because then you have additional components that have to go with it right now in consulting though like i you know i did a really big portal for a really big company and i backed a lot of stuff up to a scripting club because i was using it in multiple places and i didn't want to you know if i have to write code twice no no i'll put it into a script include because i don't want to rewrite stuff or if i have to change it i don't want to go to multiple places to change it so they're like i said there are cases where yeah i'll have a a heavy lifter behind all my widgets but that's a unified portal right not disparate different clients and stuff like that so there are some some things to think about when you when you do that though yeah totally so let's um i think i like this over here um let's let's kind of jump in and see what we can what we can get into so who is that s in utils or run script still still beautiful shout out to our nude yeah yeah and i i do want to give out a shout out to travis so i stumbled upon it from an article from 2017 about interface design patterns for script includes i'll kind of just show it on the screen real quick to kind of show people what this this article is really really good we'll we'll include it in the links as well to help people um get started and uh so a lot of the reference material will come from there and we'll we'll kind of jump back between that in the instance for it i i wonder if this video will cause him to revisit that with new thoughts interesting yeah that would that would be cool maybe someone sent it to him yeah that's uh what uh five years ago lots of change lots of things have changed in service now in five years yeah wow i can't believe it's five years ago wow so let's kind of let's let's kind of start with like um like the basic pattern for script include and what i think we're going to do is we're going to write script includes that modify user records and the reason why we're we're going to do that is because it's very common to have like business rules potentially lock people out or transform maps for um like user provisioning have to manipulate users so i think it's a it's yes it's still a little demoy but it's still potentially valid um it's a really easy one to potentially test well i mean it's it's it's the same idea you know a business rule allows you to modify a record you know on change or at you know before or after and it's it's due to something right so i want to make this change because of another change yep so what we're going to do is we have our our favorite able if you haven't seen his linkedin profile it's awesome so shout out to the sn dev community for doing that and the thing that we'll probably try to modify in our script is whether this is active true or false um and so what we'll start doing is you'll want to make sure you're in the right scope so but we're just going to be in global for this you'd want to make sure you're in an update set but we're going to we've done videos on that so we're going to skip that and now it comes to naming conventions is our first step in this architecture and if we're gonna follow something that servicenow does um they either do something like uh a dia object well yeah so that's where i picked up my habit of doing daos but uh just be aware i don't know that servicenow even follows something yeah because there's different yeah exactly different teams do different things so either it'll be something like you'll see something like a utils or maybe like a dao i like utils i think utils is a i think utils is good um and notice that it'll pre-populate some of this stuff for you we're going to select all application scopes in this case in case you want to call it and whether or not you want to make it an ajax or not is simply this yeah and and just as a side note here um if you are going to put something in the store and you mark client callable and this script includes never gets called from the client they will get on your face about that and make you they'll fail it um i like it i like it yeah so if you're building something for the store make sure you're clicking on things that you should be clicking on because servicenow doesn't like it yeah and um and so we kind of talked about naming conventions like normally the naming convention is what is the thing you're gonna modify in service now and then add utils potentially next to it so if i'm modifying user groups right i would probably do user group or maybe user role or maybe just roles in general or groups in general so i really try to keep it related to the thing that you're actually taking action on um whether there's intermediate steps or not so how do you feel about um let's let's go to the portal side for a second here and say you know we're doing a large scale portal um project and uh you have a master script include do you think it's appropriate to have children below that that are referenced in a master like so you know you have the the master one and then you have like you know maybe pages or something like that where it has other things below it yeah so my rule of thumb is um break out your script includes one that are logical so let's say you've already done that and then two break it out so that multiple developers can work potentially work on it at the same time yeah so you don't want one giant one because then you're in like a merge conflict kind of oh i over wrote your code sorry yeah or like to to get it actually merged you're like looking at some diffs all the time so you really want to find the right balance um between multiple people being able to work on it and you know not too many script includes that don't have meaning so in your case yes it's totally fine to have uh either really big ones that have separate functions and we'll kind of talk about that pattern or maybe even having certain just don't name it like use your utils one use your utils to use your heat o3 because it it won't make much sense who does that with gr's gr1 gr2 now i totally agree though and that's that's the big proponent in my head is why i would have a parent child is malty developer right if it's just me on the project i'm usually with just one giant script include because who's going to be in there just me but if i've got multiple guys on the team working on the same project yeah splitting it out makes it easier to handle um the the other developers and lets them do their own thing and and nobody steps on each other someone uh we got somebody asking a question can you post the link yeah this is the the link that we're referencing devin so [Music] i'll also put that in the description after so um thanks for thanks for asking so let's go back to where we're at all right so let's start with the basic pattern which is where uh travis starts us off is there's essentially a script include pattern and it looks something like something like this just to let you know what is what his um thing is doing you essentially have an initialize function which is kind of similar to you know what do you want to set on start um so once this is initialized you essentially it's like you're kind of like your global variables in here and um oh i'm not sharing [Laughter] um so essentially what uh to back us up i'm just kind of talking through the like initialize function um essentially it's like setting your scoped global variables that's a tough one um so once you call this user utils it will initialize any of those things and we'll we'll play around with it and what um what we can what we can do first is talk about um uh these two concepts the idea of having a private uh function and also we're also gonna do this class pattern since we'll start with this um a private function and a public function and travis kind of talks about that as well in uh in his uh uh in his v in his uh document as well so so we'll start off pretty easy right we'll let's let's let's do some things here so we'll just do like a gs print you know you know my function and we'll start with just understanding or how to like call these so that they make sense and this will be you know my private function and then [Music] we'll just show this as well initialize you think you think it'll think this will work sure why not why not all right so now how do we call that so we're going to go to our our background script and then we'll we'll switch over to atf shortly but just to kind of get us going um and then you essentially call the apparently my so as another side note i really wish servicenow would buy explore and replace background scripts with that i gotta tell you it is so more it's much more handy and user-friendly i 100 agree with you so uh what do we think is going to happen if i just do this what do you think uh i think you're only going to get the initialize function or the initialize print okay and i'm probably gonna get it like a global object right or just an object right oh yeah because i think this creates an object hey look at that so we know initialize works and we instantiated this object so now let's see if we can you know call our function right so c dot my function and we called it and then we also got some undefined that's uh yeah um and i don't know where that undefined is coming from [Laughter] so that's uh that's fine maybe someone uh someone else can smarter than you can can tell us and then we're also going to go and try to call our private function so in theory yeah it'll work it's not necessarily like really private private it's it's more like these are the these are the internal functions i need for my script include but they're accessible by anyone you know they're accessible by anything so it's not really private right right in this case right we'll we'll get a little bit further and and see how that works but yeah um so that's that's kind of that's kind of your basic you know pattern and function right and so this is what you're used to most i mean this is how you build them most of the time like for me in five years i don't think i've ever changed how i built um script includes i have started getting into that initialize area where i've done my constants and stuff like that so they're available but uh yeah i really haven't changed much you know old dog new trick thing if it works it works right totally so let's see if we could do something a little bit more advanced i don't think some is an actual function though so or maybe uh yeah let's do return one plus two and return count plus one so let's let's see let's see what happens here right so when i call that i only get the three right so i have no idea what count is but let's see if we can we you think we can access count anyway if you just if you just do c yeah and then and then what how do i actually get that variable if possible can i do like c dot count i think that won't work no because it'll say that that's so there's no real way to get this other than using it to initialize at least in this current context yes correct you're really just setting a constant up there is what's happening in order to essentially be called right so see i always thought you would have to access count so in the second function you'd actually have to do this dot count this dot count uh we'll see uh count is not defined so you are correct so if you do this dot count you should pick up yeah yep which makes sense right because if this is a javascript object it's initialized as an object and then you have to to call um those those uh the the object itself which is this in this case so but now we got nan so it doesn't like this dot count plus one interest i wonder why um or why it considers count to be a noun and not a number yeah maybe we could do something like number but i don't think this is going to work either um but you can wrap things like number um around things if it's supposed to but yeah so there's there's probably some scoping issue here now right um if you what if you well i'm trying to think because i thought it's either inside the initialize or outside that you can do that i think it's like actually something like this dot count oh equals one right yeah i think that is the the right way to reference it i think if you move it outside of the initialize like if you did uh above my function and did like yeah var and so this is another thing where it comes into what you think's right like i always do capitals if i'm going to do constants so i do the entire that's you know i don't know if that's a it's not a requirement but how would you add it here right you have to you don't use a i thought it was uh maybe it's a above that but it's not a semicolon i mean maybe i have to put it put it in above the initialize and above the initialize yeah that's probably a bad uh practice um and you can do a comma yeah and do a comma i don't know if that would work right so let's just let's just say you shouldn't do that um i think you could do it outside of this right i think we could do something like var count two equals four and then i think you can i think you can write call i call this but i don't remember i think i think we could just reference it here as count two but no i don't know i don't think that's gonna work either yeah i don't think so i'd have to look at how let me see if i can find an old oh it worked it worked so you can it must just be the well this is this is scary to do right because this is i think a global um this makes it like global and it's not scoped to this function yeah very very scary so i would be careful with manipulation there um yes i would i would agree with that one so but we're moving along um this dot count so we've and then we'll do this dot count and we're we're in a good state so now i'll just quickly show now that we have a function that's working what would you do in an atf like remember i said the biggest benefit of putting every script into a script include is so that you can unit test it so let's see if i can you know prove prove that um and we're going to name this like script include or scripts um [Music] script includes unit tests you can put them all in here but you probably don't you probably want user utils uh unit tests and we could probably parameterize this too if we really wanted yeah let's let's go let's go super advanced because there's a new feature here that we can take advantage of um so john you're typing away so loud i'm about to send you a message on uh what how it works you don't do var yeah you do this so we showed that right no adding the the constants if you will you you you um initiate them above the initialize without the var and then they're accessible with this dot variable gotcha so what john sent me was something like and i don't think it matters where you do it it'll be like fun or let's say count colon one and then let's just comment this out and see if this still works right yeah yep so one plus one is two so so that's this looks like another way and again i don't know what the scope is or the safety of this so um something to to keep in mind um that's a another question well you could always see if you could call count outside of your new um in your background script um oh oh yeah because it would be potentially a property of israel if if it's global then it would be available but uh so c dot count should return yeah so yeah so that way this is a way you could if you didn't want to initialize but well if you wanted you wanted to have it available with just your um your call to the the script include you know so you can get you don't have to run the function you can just run the uh property i guess is what it turns into right c dot yeah property and let's see if if we can call we should be able to call counter as well so you could call it it looks like it's just another route you could do again like this is scoped inside of a self-executing function right but this like they're both accessible because it's an object right like i can call c dot counter in this case as well so i would probably put them in the initialize um there's there is probably a use case of this may actually be more memory efficient because it it probably isn't called where this is called right away like i i don't actually know that's a that's a deeper deeper question out of my uh skill set right now yeah no that's fine so so now let's say we have our our test um and we essentially want to do something probably a little bit more um useful like setting a user to active or not right so set active let's say that that's the name of this function and it probably needs to take in a user record so now we're getting somewhere and we're gonna do something like user record let's check if user record exists then set a user record i guess this would we could be like super fancy here and do like a draw yeah but if you're pat if you're passing over the glide record object which is a weird beast then yeah you could probably just do user record dot active equals true and then [Music] user dot record ah do you do a set value i i think set value is the safer route than than calling a dot oh oh oh oh sure and then you can do a user record update right yep yep or well i guess it depends oh what business rule are you using this on yeah no you're right um uh well i think because you can check can't you you can do that there's a an uh an action or something that tells you if it's like a new record or not we'll keep it simple um in this case but like imagine there's like a a set record or a set active and like maybe there's like um um let's do something like like this dot active user so if you only want to set them active if they're an inactive user and we're going to make that our private function that grow your throw your underscore up there too so you know else um return three don't tell me [Laughter] tell me what to do obviously you should return something more useful but um so now set them to false deactivate them so we'll do of our activity equals openness also has to take a user record just use a different one um equals userrec.getvalue of active if activity exists so if it's true return false else return true with me on that i am there there is some issue here and i only bring this up because i ran into it at some point where someone else wrote the the script includes and did it this way but from the portal from the the server side on the portal i didn't have you know when i see the user i i just passed over the sys id and so there was we just had to re change or we just had to update them to say yeah if user record is not the object then go get the object um because i wasn't sure i could pass the glide record object from server side on the widget to a script include very well and so we just had to add another layer of check you know try catch if you will yeah so let's let's see if how should we test this in a background script first um and then we'll go into making this an atf and so all right so to call that private function glide record equals new glide record we should be using glide query but that's fine cis user and user gr we're going to choose wide query is not always the answer dorian yeah that's true um and we're gonna use a get on email i think that's or maybe it's the other way it's been a while since i've used gets i never remember what goes first the sys id you just plug that in there but if you're doing two videos that's okay we'll just just id it for now yeah and now that again you know you should do some error handling here but in our case we're passing in user gr and let's just see if this returns a true or false right so uh new private doesn't exist right there's my quick fingers here and we're using real things now yeah yeah all right so are they an inactive user the answer was no but now if we go here and make them an inactive user should get true oh don't go too fast yeah it should get true but we don't so something's wrong with our code um and i wonder if it's because um get value yeah i don't think that works i think you need to [Music] i almost say i think you have to do like the user.wreck.active but let's see what we we're getting here you may have to do type of also to see what it is zero to zero interesting or one wow so the active field isn't a true or false or for some reason or maybe this get value it's a boolean it's a boolean so zero would be false one should be true but i i think that's like that's not true and truthy so uh there's a i i thought i put a thing at some point in my i think i have a script snippet for that how you can do an easy we'll just check your version on that let me see if i can find it um if we're we're going at light speed here all right so we got we got them to be inactive i did it the wrong way not equal to zero okay so if they're active um it should return uh false which they are and now if they're inactive i had one of those shorthand javascript snippets that would do the zero because you know and then sometimes you get them as strings which is really annoying oh my gosh so now let's so now that we know that they're inactive right let's see if we can call our set active right so we can uncomment out well we don't need to act there does this doesn't return anything i guess uh it doesn't return anything but we can make it return something if we want we'll make it return the user record yeah you also need to change your function call on the background screen ah no it wasn't gonna mess up twice [Laughter] so set active and we're gonna pass in the user gr cool so this should return an object in our case right because it should return it should return that sys id yeah nice and you can see that we updated right that user ah yeah now if we run it again it shouldn't update that user and it returns three so cool we got our script working beautiful so so now let's add a a um uh an atf for this and we could show again my main point is so that we can update so um let's say user this will be user id maxline32 okay i think is this id one of them keyword no okay string it is i couldn't remember um save there's probably a standard here you may not want to call this column you underscore users id you may want to call it after the actual atf itself um but that's another another discussion for standards of that so we got a ssid and we want a test step first right so um the first test step is we're going to actually create a user who will this this work will it automatically go active actually i'm going to delete this because i want to reference first um and i want to reference the user table maybe this will let me just change it since i haven't done anything with this that'll be really great um save wow just allowing us to change database things no problem look at that well you had no you had no records on it so yeah yeah no i know but i was worried for a second i was like create organs yes go ahead um so in this case we're gonna use able right so that's essentially you know a test parameter right so now we're gonna we're gonna be passing in the the gr record um and we're gonna do a test step and the test step we're gonna do is run a server side script and we don't really need most of this but i wonder if they updated this to be um to support something new that they did so there's a lot of stuff in here that are that are really cool um specifically you can the new thing here is params so you can now access parameter data um so that's the the big new san diego feature here is before you couldn't access parameterized data in your run server script include so it's really a pain in the butt you'd have to use some sort of step previously in order to to get it but do they give you an example of how to actually access that parameter [Music] they don't beautiful okay so we're gonna cheat and we're just gonna just stop printing well wouldn't it wouldn't it be i was gonna say wouldn't it be the you might have to jason stringify that in case that comes out as an object shall we do both rams is it no this is too no no you do jason dot string oh yeah okay yeah but i wanted it to be pretty and i think it's like i think it's like that i can't remember if the twos first or the pretty [Music] i don't know why don't they just do prettify yeah run test see what we get of course our test pass because we weren't actually testing anything but we want to see okay so you just you access it by its name but you said it was empty but i don't know if that's always going to be the case all right well we'll see we'll see we'll see um so now let's try to to access uh paramso params let's see if we could params dot this we think that because if it's empty it's not ideal right because we would need to pass that in or i guess what we can do is we'll just call our function so where's ours well so before you do that though can you just pass it right there in the script and say here's my sis id or is that is that not like you can't um i guess my my question is is how do you do dynamic here in the testing that you want to just choose any any different person that you want yeah you would put it in the parameters right so like if this user is so it's something like this so ideally this is passing the gr record right which should tell us returning true or false right um and where do you set your params i'll show you where we set it oh just a print for us so we're just seeing if we can get closer to what we were doing before right so [Music] so here we essentially on your test run data sets is where we you know add people right so this is where we added able we'll add abraham here as well um and now this should be callable from from this from this script all right that makes sense yep so we're gonna run this and again it's it's only passing because we're not actually asserting anything um but we got false on this so we're again pretty good and what about abe is abe gonna be false it is also false so um this person is active so let's let's just run that one more time but make them inactive so that we have some different test data and what's actually cool is well i guess we should show the next feature is this debug test so what that does is you can add a breakpoint um at any point in your test so we're going to add a breakpoint here and then we're going to debug test and we're not going to pause before rollback in this case but i'll show what that is later but we're now in the break point so in theory we could you know go and inspect something if we needed to we're not really doing anything so we're just going to step over it in this case but it's a like in theory you can you know step over these the the break points and inspect stuff so that'll come in handy later so abe in this case should be true right oh but it wasn't so something is still not right with our function right because we said abe to to act or it is inactive so that should have returned true and this one and then abraham is active so this should have returned different results and they're not right so so something something's fishy but what we should do is essentially like start doing the the part that is actually gonna to validate our tests so if we go in here so normally what you do is something like a you know a before all um so i'm gonna copy some some some pseudo code right so this is from who wrote this oh i'm going to butcher your name [Music] on the unlearned series on the community forum um uh pretty much wrote a little bit of how you can do unit tests um within atf's so here's an example where what they do is they they set something up so before all right so before everything um they're they're saying you know do some stuff um which is essentially initializing our pattern right now so now that we've initialized our pattern we can then say that you know does or so let's use some user utils class patterns you know expect that our script when it's calling this function is to equal and then we expect it to be you know uh false right like that's like essentially how you would do it um now it gets tricky here because we're we're like this this test should only test one thing right so like in this case if we're passing this user it should equal false but it should fail for somebody right because they're not um because they're different results right so for one of them i should fail the other one it should pass but this is essentially the premise of of of this and so we'll show you what this looks like so if you are planning on using um jasmine so that's where this expect comes in you want to uncomment out this line and so click save and we'll run this test again and we're going to remove this breakpoint for now run test and they both return false which we know isn't true right so a for example is not inactive right and it's saying that the test passed right and it shouldn't so that means something is is not working as as it should um i wonder if you're getting back a string so you think because it's not a background script now it's operating differently i i don't know those check boxes the true false guys i always are like super painted yeah i double my chances and say hey does it equal zero or does it equal string zero but i don't know it could totally be something else that's causing it but man and i've heard from other people where they could never they could never get uh a condition on okay so let's say so if they're inactive right so if they're inactive we're saying um so i would also do one that has the zero and the quote was the what was our inactive so is abe considered inactive yes yes okay so not equals to zero so so if it equals zero it's false right or sorry it's not equal to zero so zero is true and other one is false zero was false one was true we have to just print this again i'd also do a type of just i mean i guess from a background it comes back as a boolean but [Music] i mean we're here right so but i feel like your center one is incorrect yeah that should also be a not equals two yeah it's so weird that if it's not equal to false return false i know i i i probably shouldn't you wrote it here you know what we're gonna change this to active user um so if it equals to zero it's true you wouldn't have to change anything you just could have changed the two [Laughter] well if you if you had left everything is not equal to you could have just changed the uh those two returns so leave that is not equal to and then change it to true yeah and then the bottom one's false okay there we go so we but let's also add because we don't really know no yeah see i mean it's and we'll add a type of here just here it's so ridiculous this is where i don't think there's around it's just type of space in the variable disagree with you fine whatever oh did i not save it no you got to take the prize off wait i need to i'll change the name yeah all right so are they an active so it's a type of string it's a zero type of string c and it's unchecked is false so in the record it is unchecked which is false if it was checked it'd be true okay so so what should this logic be right because or because something is all right here right yeah if active equals false it should return false if active equals false should return false yes so if if this is false it should return false so if but apparently currently it does equal zero so it about it's returning true huh so it's saying that it's equal to zero and this is returning true wow [Music] here let's let's use uh we'll just do the dot notation and do it two string and then you know for positive what it is okay string it no no no no no dot this this is the this is the actual right yeah they changed it didn't they you should because this is a service now native function so let's see okay we got false type string okay so the activity is we know it's a false string so so this should be fine right saying it's false if it's returning false then it should be false not true oh yes oh but yeah so but this is the check right if activity equals false true then it's yeah see it should return just in this case if they're an active user it's saying they're false now let's make them an active user and it should return true and this should return true there you go now we're correct so now we're gonna do expect it to return false okay so this so this is still good now um except it's now an active user and i probably should have done is active user instead of but that's okay um all right so now let's run this and see [Music] one of our tests should fail right hey there we go both of them failed expected true oh oh are you looking at a bully a bullion though that's okay though because we're returning i think it's just only one test should fail yeah there we go all right we're our code is popping look at that i got you um so that's so that's how you're using these parameters and you're you're passing those in and this should return failed in our case um so that's working as is so now so that's essentially how you could write unit tests right like for parameterized data for this function right so now no matter where i call this i can then um you know run this unit test to see if it worked right and so then the next thing is is if we really wanted to also tested the set active we could query um okay we'll finish up here and on the last step and then we'll we'll call it um i know so what the last the last part of this is the [Music] um is you want to validate that the the record that is um uh is is actually changing right so from this parameter this uh sys id or this use i guess we'll just do user id well but that's not i don't know if that's correct uh so it's looking to see that the user changes yeah exactly right and because we're setting them to active right and active is true right so we're checking this user to see if they are now actually active right like uh is it going to be a problem that you went with user id and not sys id though because we're not passing user [Music] it'll be fine because the parameter has access to that right okay so this was expecting them to be um false inactive yeah and then i think i think we can call after all function i think after all works um did i not do that right oh geez can you get can you get a if you type in after all like if you just type it in does it give you a oh i think i did this too many times there we go um oh no you still need a bracket or a paren after the curly yeah there you go there we go um and what we're gonna do is call script dot what was it would i name this function set active and we're going to pass in params.you user cis id so that will only after all only calls if you get a fail uh no it's it's after all of your tests right so oh so you can't can you not specify that says only if it's well this function will only do it if they're inactive right so okay um conditional inside that you probably could you can write if statements right um i just don't know if we'll get we'll get value out of it right sure um interesting so it only worked for oh i think it stopped after abel's because the the test up failed so it didn't run right but um yeah and it's also well no no so that should have should have worked maybe the after all isn't what i wanted to do in that case um and it's also a little tricky because i'm using like an actual record um versus normally what you would do is we would create a user and then set those parameters then run the script on that user versus actually using user data so so i think i would just put this here and call that oh i think you had oh too much [Music] okay so all right and we'll probably call it there whether this runs or not hmm a part two coming up i i feel yeah yeah so um so i think the the tough part is what we did here is oh forget to change this oh gosh all right that would be problematic yeah because i was like it shouldn't fail on able so this should in theory turn into active it should pass okay did it turn into active interesting oh okay so i'd have to we have to come back but yeah i think the the true thing what we should be doing is creating a user rather than updating actual user records yeah and so then it should be a three-step process you do some setup data you're creating some stuff you're running your function and then you're validating that that function changed those things right so that's kind of the the three different ways you would you know potentially use this um and then we also showed how you can in that script um new in san diego like call these parameters parameters yeah and we and we talked a little bit about patterns but there definitely needs to be more because we didn't even only got through one yeah we bare we we only discussed the common one and uh we definitely need another part to this because i would like to go through the other patterns yeah yeah they're they are not something that i use very often in fact i don't know that i've ever done any of those those patterns um yeah that he goes over just because they weren't you know it's just not something that i've i guess i've i've not run into a need and so it'd be it would be nice to go over them to discuss why you would want to do it this way versus you know the original um pattern yeah so i think what i'll do is i'll keep this instance up so we don't have to like redo that um you know maybe maybe what we can do is just do a couple of shorts on each pattern you know in the coming weeks maybe just hit one pattern discuss it and then the next one we hit the next pattern and so forth just so we can actually um get into it a little bit on each pattern versus trying to take them all together and go through totally yeah i i'm with you i think uh i think that's a good idea maybe we'll spend a few minutes now that the we'll get i'll get the atf stuff set up so that right in the pattern it will uh we'll be able to test it um okay but at least we showed like you can't have an atf you can run a unit test inside of um uh atf so there's no excuse to not uh to put your stuff into the scripts if you if you truly wanted to embody the like software development practice of unit testing your your scripts even if they're intended to modify data all you have to do is set up the data first write a record insert on some table because it's going to roll it back anyways on an atf so it's totally fine you just set up some record insert create user whatever that is run your script and then query to see if that record was actually created or not right so yeah modified so no i agree so i'll get some of that set up and uh it'll be we'll do some quick shorts next time sweet i love it all right if you like this content we know we've had some more subscribers and if you truly want to see john clean up his back office you just have more subscribers [Laughter] man if you like if you like us you know fumbling through service now and uh you know we're real users experiencing real service now right yeah yeah exactly exactly so all right take it easy everyone all right we'll see ya

View original source

https://www.youtube.com/watch?v=wTwUlmDrEdo