diff --git a/server/AyaNova/biz/TagUtil.cs b/server/AyaNova/biz/TagUtil.cs new file mode 100644 index 00000000..c3b9b89c --- /dev/null +++ b/server/AyaNova/biz/TagUtil.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using System; +using AyaNova.Util; + +namespace AyaNova.Biz +{ + public static class TagUtil + { + public static List NormalizeTags(List inTags) + { + if (inTags==null || inTags.Count == 0) return inTags; + + List outTags = new List(); + foreach (var tag in inTags) + { + outTags.Add(CleanTagName(tag)); + } + return outTags; + } + + + private static string CleanTagName(string inObj) + { + //Must be lowercase per rules + //This may be naive when we get international customers but for now supporting utf-8 and it appears it's safe to do this with unicode + inObj = inObj.ToLowerInvariant(); + //No spaces in tags, replace with dashes + inObj = inObj.Replace(" ", "-"); + //Remove multiple dash sequences + inObj = System.Text.RegularExpressions.Regex.Replace(inObj, "-+", "-"); + //Ensure doesn't start or end with a dash + inObj = inObj.Trim('-'); + //No longer than 255 characters + inObj = StringUtil.MaxLength(inObj, 255); + return inObj; + } + + + }//eoc +}//ens diff --git a/server/AyaNova/biz/WidgetBiz.cs b/server/AyaNova/biz/WidgetBiz.cs index 4dd54e7a..8ee772fb 100644 --- a/server/AyaNova/biz/WidgetBiz.cs +++ b/server/AyaNova/biz/WidgetBiz.cs @@ -87,6 +87,7 @@ namespace AyaNova.Biz //Test get serial id visible id number from generator outObj.Serial = ServerBootConfig.WIDGET_SERIAL.GetNext(); + outObj.Tags = TagUtil.NormalizeTags(outObj.Tags); await ct.Widget.AddAsync(outObj); await ct.SaveChangesAsync(); @@ -118,6 +119,7 @@ namespace AyaNova.Biz outObj.OwnerId = UserId; //Test get serial id visible id number from generator outObj.Serial = ServerBootConfig.WIDGET_SERIAL.GetNext(); + outObj.Tags = TagUtil.NormalizeTags(outObj.Tags); TempContext.Widget.Add(outObj); TempContext.SaveChanges(); @@ -272,10 +274,14 @@ namespace AyaNova.Biz //Replace the db object with the PUT object CopyObject.Copy(inObj, dbObj, "Id,Serial"); + + dbObj.Tags = TagUtil.NormalizeTags(dbObj.Tags); + //Set "original" value of concurrency token to input token //this will allow EF to check it out ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = inObj.ConcurrencyToken; + Validate(dbObj, false); if (HasErrors) return false; @@ -298,6 +304,9 @@ namespace AyaNova.Biz //Do the patching objectPatch.ApplyTo(dbObj); + + dbObj.Tags = TagUtil.NormalizeTags(dbObj.Tags); + ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = concurrencyToken; Validate(dbObj, false); if (HasErrors) diff --git a/server/AyaNova/models/Widget.cs b/server/AyaNova/models/Widget.cs index 5ac1379e..9b9a3eaf 100644 --- a/server/AyaNova/models/Widget.cs +++ b/server/AyaNova/models/Widget.cs @@ -26,6 +26,10 @@ namespace AyaNova.Models public int Count {get;set;} public List Tags { get; set; } + public Widget(){ + Tags=new List(); + } + } } diff --git a/test/raven-integration/Widget/WidgetCrud.cs b/test/raven-integration/Widget/WidgetCrud.cs index c6c56d7b..44df52a7 100644 --- a/test/raven-integration/Widget/WidgetCrud.cs +++ b/test/raven-integration/Widget/WidgetCrud.cs @@ -32,52 +32,33 @@ namespace raven_integration w1.roles = 0; w1.notes = "The quick brown fox jumped over the six lazy dogs!"; - //Tags test + //Tags dynamic dTagsArray = new JArray(); - - //name starts with filter to constrict to widgets that this test block created only - // dynamic DataFilterNameStart = new JObject(); - // DataFilterNameStart.fld = "name"; - // DataFilterNameStart.op = OpStartsWith; - // DataFilterNameStart.value = WidgetNameStart; - // dTagsArray.Add(DataFilterNameStart); - - // //## INCLUSIVE FILTER - // dynamic FilterItem = new JObject(); - // FilterItem.fld = "startdate"; - // FilterItem.op = OpEquality; - // FilterItem.value = FilterToken; - //dTagsArray.Add(FilterItem); - dTagsArray.Add("red"); - dTagsArray.Add("orange"); + dTagsArray.Add("Red Tag"); + dTagsArray.Add("ORANGE IS THE NEW BLACK"); dTagsArray.Add("yellow"); dTagsArray.Add("green"); dTagsArray.Add("blue"); dTagsArray.Add("indigo"); - dTagsArray.Add("violet"); - - w1.tags = dTagsArray;//.ToString();//it expects it to be a json string, not actual json - // - - + dTagsArray.Add("VIOLET Tag"); + w1.tags = dTagsArray; ApiResponse r1 = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w1.ToString()); Util.ValidateDataReturnResponseOk(r1); long w1Id = r1.ObjectResponse["data"]["id"].Value(); - dynamic w2 = new JObject(); w2.name = Util.Uniquify("Second Test WIDGET"); w2.dollarAmount = 2.22m; w2.active = true; w2.roles = 0; w2.notes = "What is the frequency Kenneth?"; + w2.tags = dTagsArray; ApiResponse r2 = await Util.PostAsync("Widget", await Util.GetTokenAsync("manager", "l3tm3in"), w2.ToString()); Util.ValidateDataReturnResponseOk(r2); long w2Id = r2.ObjectResponse["data"]["id"].Value(); - //RETRIEVE //Get one @@ -85,7 +66,15 @@ namespace raven_integration Util.ValidateDataReturnResponseOk(r3); r3.ObjectResponse["data"]["name"].Value().Should().Be(w2.name.ToString()); r3.ObjectResponse["data"]["notes"].Value().Should().Be(w2.notes.ToString()); - + var returnedTags = ((JArray)r3.ObjectResponse["data"]["tags"]); + returnedTags.Count.Should().Be(7); + returnedTags[0].Value().Should().Be("red-tag"); + returnedTags[1].Value().Should().Be("orange-is-the-new-black"); + returnedTags[2].Value().Should().Be("yellow"); + returnedTags[3].Value().Should().Be("green"); + returnedTags[4].Value().Should().Be("blue"); + returnedTags[5].Value().Should().Be("indigo"); + returnedTags[6].Value().Should().Be("violet-tag");