Followed guidelines in article Custom Filters
Having difficulty with unit testing as the IPrincipalAccessor is always null, and even if it were to be injected the claims will never be added. Using the claims therefore seems the wrong way to do this - how should we implement to also allow for unit tests?
4 Answer(s)
-
0
hi
You can create a service and inject
IPrincipalAccessor
in this service to get the claim, inject this service inCustomFilterSampleDbContext
, and then mock this service in the unit test to isolateIPrincipalAccessor
. -
0
Thank you - found a hack and it seems to work. Have a new issue with the data filter following the article though.
When I evaluate the generated SQL command of the IQuerayable prior to execution all seems fine. The filter and parameters seems to be captured (replaced the select columns with * for readability)
SELECT `c* FROM `Comments` AS `c` INNER JOIN ( SELECT `p* FROM `Programmes` AS `p` WHERE (@__ef_filter__p_1 OR NOT (`p`.`IsDeleted`)) AND ((@__ef_filter__p_2 AND (@__ef_filter__p_3 OR EXISTS ( SELECT 1 FROM `ProgrammeBrokers` AS `p0` WHERE ((@__ef_filter__p_6 OR NOT (`p0`.`IsDeleted`)) AND (`p`.`Id` = `p0`.`ProgrammeId`)) AND ((`p0`.`BrokerId` = @__ef_filter__CurrentTenantId_4) AND (`p0`.`Status` <> 2))))) AND (@__ef_filter__p_5 OR ((`p`.`ProtectionBuyerId` = @__ef_filter__CurrentTenantId_4) OR (`p`.`ProtectionBuyerId` IS NULL AND @__ef_filter__CurrentTenantId_4 IS NULL)))) ) AS `t` ON `c`.`ProgrammeId` = `t`.`Id` LEFT JOIN ( SELECT `p1* FROM `ProgrammeAccess` AS `p1` INNER JOIN ( SELECT `a* FROM `Approvals` AS `a` WHERE @__ef_filter__p_8 OR NOT (`a`.`IsDeleted`) ) AS `t0` ON `p1`.`AccessStatusId` = `t0`.`Id` WHERE @__ef_filter__p_7 OR NOT (`p1`.`IsDeleted`) ) AS `t1` ON `t`.`Id` = `t1`.`ProgrammeId` LEFT JOIN ( SELECT `p2`.`* FROM `ProgrammeBrokers` AS `p2` WHERE @__ef_filter__p_6 OR NOT (`p2`.`IsDeleted`) ) AS `t2` ON `t`.`Id` = `t2`.`ProgrammeId` WHERE (`c`.`Discriminator` = 'ProgrammeComment') AND (@__ef_filter__p_0 OR NOT (`c`.`IsDeleted`)) ORDER BY `c`.`Id`, `t`.`Id`, `t1`.`Id`, `t1`.`Id0`, `t2`.`Id`
The final query only includes the isDeleted filter though and everything else is dropped
DbCommand (3ms) [Parameters=[@__ef_filter__p_0='False'], CommandType='Text', CommandTimeout='30'] SELECT COUNT(*) FROM `Comments` AS `c` WHERE (`c`.`Discriminator` = 'ProgrammeComment') AND (@__ef_filter__p_0 OR NOT (`c`.`IsDeleted`))
The documentation suggests that it should pass the values via the property and it should all flow through. My code includes
In the context:
protected virtual bool CurrentIsBroker => GetCurrentIsBroker(); protected virtual bool CurrentIsBuyer => GetCurrentIsBuyer(); protected virtual bool CurrentIsSeller => GetCurrentIsSeller(); ... protected override bool ShouldFilterEntity<TEntity>(IMutableEntityType entityType) { if (typeof(IMustHaveProgramme).IsAssignableFrom(typeof(TEntity))) return true; ... return base.ShouldFilterEntity<TEntity>(entityType); } protected override Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>() { if (typeof(IMustHaveProgramme).IsAssignableFrom(typeof(TEntity))) { Expression<Func<TEntity, bool>> progFilter = p => !CurrentIsBroker || !IsMustHaveProgrammeFilterEnabled || ((IMustHaveProgramme)p).Programme.Brokers.Any(b => b.BrokerId == this.CurrentTenantId && b.Status != BrokerAppointmentStatus.BrokerWithdrawn); Expression<Func<TEntity, bool>> buyerExpr = p => !CurrentIsBuyer || !IsMustHaveProgrammeFilterEnabled || (((IMustHaveProgramme)p).Programme.ProtectionBuyerId == this.CurrentTenantId); progFilter = progFilter == null ? buyerExpr : CombineExpressions(progFilter, buyerExpr); Expression<Func<TEntity, bool>> sellerExpr = p => !CurrentIsSeller || !IsMustHaveProgrammeFilterEnabled || ((IMustHaveProgramme)p).Programme.AccessRequests.Any(a => a.AccessStatus.Status == ApprovalStatus.Approved && a.TenantId == this.CurrentTenantId); progFilter = progFilter == null ? sellerExpr : CombineExpressions(progFilter, sellerExpr); expression = expression == null ? progFilter : CombineExpressions(expression, progFilter); } ... }
and in core module - PreInitialize
Configuration.UnitOfWork.RegisterFilter(ReinsuranceConst.IMustHaveProgramme, true);
I can also see my filters are enabled and the property values are correctly set when debugging, but the final query doesn't filter.
The 3 properties have the correct value:
The filter is enabled and correctly refelcts in the property in the context:
Is there anything else I need to do that is not included in the documentation?
Many thanks
-
0
Can you create a project using abp's free template? I can check it for you.
https://aspnetboilerplate.com/Templates