Base solution for your next web application
Open Closed

Configuration.UnitOfWork.OverrideFilter(AbpDataFilters.SoftDelete, false) breaks a test #8055


User avatar
0
mhrabak created

Tested version: Latest Tested app: Demo Project type: ASP.NET Core & Angular

Hi guys, We are facing an issue in abp/zero. We consider build as failure when all tests does not pass so we had to skip only one test of yours for now. use case:

  1. Download any demo or live project - we are using ASP.NET Core & Angular
  2. Disable SoftDelete filter - I added Configuration.UnitOfWork.OverrideFilter(AbpDataFilters.SoftDelete, false); line to <ProjectName>ApplicationModule.Preinitialize method
  3. Run Localization.LanguageAppService_Tests.Delete_Language test in <ProjectName>.Tests.csproj

Assertion error occurs: Shouldly.ShouldAssertException : currentLanguages.Any(l => l.Name == randomLanguage.Name) should be False but was True I guess problem is that instance of deleted ApplicationLanguage is not removed from cache. I had to admit I don't have time to research why now but I guess IEventHandler<in TEventData>.HandleEvent is not called.

Thanks.


10 Answer(s)
  • User Avatar
    0
    musa.demir created

    Thanks @mhrabak we will check it.

  • User Avatar
    0
    musa.demir created

    It is not an error. If you disable AbpDataFilters.SoftDelete as default, your db queries will not be filtered by IsDeleted property. But entities inherited from ISoftDelete will still work normally. When you delete them their IsDeleted property will be true and they will keep existing. That's why it is still on the list.


    You can also disable filter in current ouw.

    using (CurrentUnitOfWork.DisableFilter(AbpDataFilters.SoftDelete))
    {
        var list = _myEntityRepo.GetAllList();//it will contain deleted rows too
        //do your logic here
    }
    

    In this way, it will not affect all current logics. These will disable the filter for just that code block.

    For more information https://aspnetboilerplate.com/Pages/Documents/Data-Filters https://aspnetboilerplate.com/Pages/Documents/Articles\How-To\add-custom-data-filter-ef-core

  • User Avatar
    0
    mhrabak created

    Thanks for answer. I read articles you post and I found out myself what you wrote, but we have our custom filter and interface for deleting records so it is necessary to disable yours (reason is legacy database which has it's own SofDelete mechanics). Problem is that when we disable SoftDelete filter your test starts to fail. For me expected behavior is that when default SoftDelete filter is disabled Abp starts to Hard Delete records because we can not apply our custom SoftDelete interface to entities builded into your assemblies. Expected behavior: We delete ApplicationLanguage record -> It is hard deleted -> test pass successfully Current behavior(for me false) : We delete ApplicationLanguage record -> it is only marked as IsDeleted -> test fails As user I expect when I delet record this record dissapear from list but without SoftDelete filter it is still part of result from repository becasue Abp does not delete the record. Reason behind this is that now when we disable your SoftDelete filter no record - where we are unable to apply our own SoftDelete mechanism - is really deleted.

  • User Avatar
    0
    musa.demir created

    If you use (IRepository).HardDelete it will delete row permanently evenif it is an ISoftDelete entity.

  • User Avatar
    0
    mhrabak created

    Ok just sum it up. Your advice is to rework your original tests and your original app services for entities which inherits from ISoftDelete to use HardDelete instead of Delete method to make it work when ISoftDelete filter is disabled? Really? It doesn't make sense to me. Why should I update your codes and tests to make your supported scenario (disable filters) works (logically) right?

    For me logical behavior: When I disable ISoftDelete - which is supported scenario based on your documentation - I expect deleted entity will not load from DB - such entity should be hard deleted because ISoftDelete is disabled.

    Maybe I missing something but from what I know it shouldn't be such problem. We already implemented our own deleting strategy for our entities and we expect yours will be deleted permanently but without any updates to your codes nor tests.

    Thanks for reply.

  • User Avatar
    0
    musa.demir created

    Hi @mhrabak That advice was just for you to use it in your logics. not for test functions.

    Seems like our test functions are not designed for that. You must reenable that filter on AbpZeroTemplateTestBaseModule.

    AbpZeroTemplateTestBaseModule.cs

     public override void PreInitialize(){
        ... 
        Configuration.UnitOfWork.OverrideFilter(AbpDataFilters.SoftDelete, true);
    }
    

    What do you think @ismcagdas, should our test functions check if our default filters disabled or we should add something like Configuration.UnitOfWork.OverrideFilter([ALLOURDEFAULTFILTERS], [THEIRDEFAULTVALUES]); to AbpZeroTemplateTestBaseModule?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @mhrabak

    For me logical behavior: When I disable ISoftDelete - which is supported scenario based on your documentation - I expect deleted entity will not load from DB - such entity should be hard deleted because ISoftDelete is disabled.

    Our design is not like that. Disabling soft-delete filter will include deleted (IsDeleted=true) records in the result. As you can see, the SoftDelete entities are not actually deleted, just marked with a boolean flag. Sorry but this is by design.

    Also, when you disable soft-delete filter, just 1 test fails with initial template. So, you just need to change one test.

    For your own soft-delete logic, you can design it on your own way.

    So, there is nothing related to cache.

  • User Avatar
    0
    mhrabak created

    Thanks for reply. Still it doesn't make sense to me unfortunately. I understandt that when record inherits from ISoftDelete its IsDeleted property is set to true which is independent from filters but in my opinion this functionality should be coupled.

    The reason behind this is that what I mentioned earlier - when I delete record using repository I don't expect this record to be loaded from database no matter what. Deleted record should be deleted period.

    This condition is not fulfilled when ISoftDelete filter is disabled for example for ApplicationLanguage (yours entity type). User use case:

    • User enter list of languages
    • Delete one language
    • Language is not deleted - yes the reason is disabled ISoftDelete filter

    ApplicationLanguageAppService is generated by aspnetzero automatically - DeleteLanguage method recall IApplicationLanguageManager.RemoveAsync method so deletion of ApplicationLanguage record from database is out of our reach - only thing we can do is implement our own implementation of IApplicationLanguageManager where we will use HardDelete or rewrite DeleteLanguage method itself with multitenancy in our minds and call HardDelete.

    Sorry but it sounds more like bug to me when I have to rewrite your generated code or create our custom implementation of the manager to be able to delete a record - yes in this particular case it is only one entity type -ApplicationLanguage - which cause us problem but maybe there could be more we just didn't find yet.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    If you don't want to use soft delete feature at all, you can override CancelDeletionForSoftDelete method in your DbContext and just delete the record in any case instead of setting IsDeleted property to true.

    See https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.EntityFrameworkCore/EntityFrameworkCore/AbpDbContext.cs#L447

  • User Avatar
    0
    ismcagdas created
    Support Team

    This issue is closed because it has not had recent activity for a long time.