rivantsov / vita

VITA Application Framework
MIT License
59 stars 15 forks source link

PropagateUpdatedOn does not trigger when adding new line #202

Closed jasonlaw closed 1 year ago

jasonlaw commented 2 years ago

It triggers only for update and delete, but not add new. Bug?

rivantsov commented 2 years ago

looking at it.

rivantsov commented 1 year ago

Hi, and sorry it took so long. I am preparing update, and looked at this issue.

It looks like it works correctly. I'm afraid there's some confusion here. The goal is not to 'fire', but to mark parent/target entity as Modified whenever child is added, updated or deleted. For update and delete, an event fires on child entity, attribute handles it, reaches to the parent and marks it Modified if its status is Loaded. Simple. For added child record, it is a bit different. The New event is fired immediately when it is created; it is empty yet, parent ref is not assigned. So instead, I intercept assignment of the parent ref to the child property. Look at the code in the attribute, SetMemberValue interceptor.

I wrote a test method for adding a BookOrderLine to existing order:

    // Investigating reported issue #202: PropagateUpdatedOn does not trigger when adding new line
    // Dec 2022 - so far no problem detected, works as expected without fixes

    [TestMethod]
    public void TestBugPropagateUpdatedOnAttr() {
      Startup.BooksApp.LogTestStart();

      var app = Startup.BooksApp;
      var session = app.OpenSession();

      // IBookOrderLine has [PropagateUpdateOn] on Order property. 
      // For an existing order, after we add/modify/delete any line, the parent Order's status should be Modified, and UpdatedOn field should be updated 
      //  on SaveChanges.

      // We create order with one book; save it; and then add another book - the BookOrder should be set to Modified
      var ferb = session.EntitySet<IUser>().First(u => u.UserName == "Ferb");
      var order = session.NewOrder(ferb);
      var csBook = session.EntitySet<IBook>().First(b => b.Title.StartsWith("c#"));
      order.Add(csBook, 1);
      session.SaveChanges();

      var orderRec = EntityHelper.GetRecord(order);
      Assert.AreEqual(EntityStatus.Loaded, orderRec.Status);
      var updOn = order.UpdatedOn;
      Thread.Sleep(100); // to make difference in UpdatedOn noticeable

      // now lets add another book and check the order status
      var vbBook = session.EntitySet<IBook>().First(b => b.Title.StartsWith("VB"));
      order.Add(vbBook, 1);
      // Check that order state changed to modified
      Assert.AreEqual(EntityStatus.Modified, orderRec.Status, "Expected Order status changed to Modified");
      session.SaveChanges();
      var newUpdOn = order.UpdatedOn;
      Assert.IsTrue(newUpdOn > updOn.AddMilliseconds(50), "Expected later new UpdatedOn value");
    }

this test will be in coming update.

jasonlaw commented 1 year ago

Ok thanks!