ft/JD-741: add isTrusted() with conditions templates (#41)

* JD-741: add isTrusted() with conditions lists
* JD-741: fix typo DELIMETER -> DELIMITER
* JD-741: remove unused dependencies, bump junit4
This commit is contained in:
mr-impossibru 2021-11-10 12:20:09 +03:00 committed by GitHub
parent e541e47ebc
commit 5b70d04d60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 368 additions and 85 deletions

@ -1 +1 @@
Subproject commit 540183862bc9fd04682e226de2056a320fd44be9
Subproject commit be44d69fc87b22a0bb82d98d6eae7658d1647f98

40
pom.xml
View File

@ -11,7 +11,7 @@
</parent>
<artifactId>fraudo</artifactId>
<version>0.0.22</version>
<version>0.0.23</version>
<name>Fraudo</name>
<description>Language for describing antifraud patterns</description>
@ -33,15 +33,14 @@
</scm>
<properties>
<hamcrest.junit.version>2.0.0.0</hamcrest.junit.version>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<antlr4.version>4.7.1</antlr4.version>
</properties>
<dependencies>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.7.1</version>
<version>${antlr4.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
@ -60,13 +59,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-junit</artifactId>
<version>${hamcrest.junit.version}</version>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
@ -88,7 +81,7 @@
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.7.1</version>
<version>${antlr4.version}</version>
<configuration>
<arguments>
<argument>-package</argument>
@ -106,29 +99,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.4</version>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
<excludes>
<exclude>com/rbkmoney/fraudo/constant/**/*</exclude>
<exclude>com/rbkmoney/fraudo/model/**/*</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -56,5 +56,5 @@ floatExpression
;
in
: 'in' LPAREN (stringExpression) DELIMETER string_list RPAREN
;
: 'in' LPAREN (stringExpression) DELIMITER string_list RPAREN
;

View File

@ -71,7 +71,7 @@ count_success
;
count_error
: 'countError' LPAREN STRING time_window DELIMETER STRING (group_by)? RPAREN
: 'countError' LPAREN STRING time_window DELIMITER STRING (group_by)? RPAREN
;
count_chargeback
@ -87,7 +87,7 @@ sum_success
;
sum_error
: 'sumError' LPAREN STRING time_window DELIMETER STRING (group_by)? RPAREN
: 'sumError' LPAREN STRING time_window DELIMITER STRING (group_by)? RPAREN
;
sum_chargeback
@ -99,7 +99,7 @@ sum_refund
;
in
: 'in' LPAREN (stringExpression) DELIMETER string_list RPAREN
: 'in' LPAREN (stringExpression) DELIMITER string_list RPAREN
;
is_mobile
@ -111,5 +111,33 @@ is_recurrent
;
is_trusted
: 'isTrusted' LPAREN RPAREN
: 'isTrusted' LPAREN RPAREN #isTrusted
| 'isTrusted' LPAREN (payment_conditions | withdrawal_conditions) RPAREN #isTrustedConditionsSingleList
| 'isTrusted' LPAREN payment_conditions DELIMITER withdrawal_conditions RPAREN #isTrustedPaymentsAndWithdrawalConditions
;
payment_conditions
: 'paymentsConditions' LPAREN conditions_list RPAREN
;
withdrawal_conditions
: 'withdrawalsConditions' LPAREN conditions_list RPAREN
;
conditions_list
: trusted_token_condition (DELIMITER trusted_token_condition | WS)*
;
trusted_token_condition
: 'condition' LPAREN
STRING DELIMITER //transactions_currency
INTEGER DELIMITER //transactions_years_offset
INTEGER DELIMITER //transactions_count
INTEGER //transactions_sum
RPAREN
| 'condition' LPAREN
STRING DELIMITER //transactions_currency
INTEGER DELIMITER //transactions_years_offset
INTEGER //transactions_count
RPAREN
;

View File

@ -49,11 +49,11 @@ sum
;
unique
: 'unique' LPAREN STRING DELIMETER STRING time_window (group_by)? RPAREN
: 'unique' LPAREN STRING DELIMITER STRING time_window (group_by)? RPAREN
;
in
: 'in' LPAREN (country_by | STRING) DELIMETER string_list RPAREN
: 'in' LPAREN (country_by | STRING) DELIMITER string_list RPAREN
;
in_white_list
@ -69,11 +69,11 @@ in_grey_list
;
in_list
: 'inList' LPAREN STRING DELIMETER string_list RPAREN
: 'inList' LPAREN STRING DELIMITER string_list RPAREN
;
like
: 'like' LPAREN STRING DELIMETER STRING RPAREN
: 'like' LPAREN STRING DELIMITER STRING RPAREN
;
country_by
@ -98,22 +98,22 @@ catch_result
;
string_list
: STRING (DELIMETER STRING | WS)*
: STRING (DELIMITER STRING | WS)*
;
time_window
: DELIMETER INTEGER | DELIMETER INTEGER DELIMETER INTEGER
: DELIMITER INTEGER | DELIMITER INTEGER DELIMITER INTEGER
;
group_by
: DELIMETER string_list
: DELIMITER string_list
;
STRING
: '"' (~["\r\n] | '""')* '"'
;
DELIMETER : ',' ;
DELIMITER : ',' ;
COMMENT
: '#' ~[\r\n]* -> skip
@ -138,6 +138,6 @@ RPAREN : ')' ;
DECIMAL : '-'? ('0'..'9')+ '.' ('0'..'9')+;
INTEGER : '-'? ('0'..'9')+;
IDENTIFIER : [a-zA-Z_] [a-zA-Z_0-9]* ;
WS : [ \u000C\n]+ -> skip;
WS : [ \u000C\t\n]+ -> skip;
SCOL : ';';
BOOLEAN : TRUE | FALSE;
BOOLEAN : TRUE | FALSE;

View File

@ -0,0 +1,42 @@
package com.rbkmoney.fraudo.converter;
import com.rbkmoney.fraudo.FraudoPaymentParser;
import com.rbkmoney.fraudo.model.TrustCondition;
import lombok.RequiredArgsConstructor;
import org.antlr.v4.runtime.tree.TerminalNode;
import java.util.List;
import java.util.stream.Collectors;
import static com.rbkmoney.fraudo.utils.TextUtil.safeGetInteger;
import static com.rbkmoney.fraudo.utils.TextUtil.safeGetText;
@RequiredArgsConstructor
public class TrustConditionConverter {
private static final int YEARS_OFFSET_INDEX = 0;
private static final int COUNT_INDEX = 1;
private static final int SUM_INDEX = 2;
public List<TrustCondition> convertToList(FraudoPaymentParser.Conditions_listContext conditionsListContext) {
return conditionsListContext.trusted_token_condition().stream()
.map(this::convert)
.collect(Collectors.toList());
}
public TrustCondition convert(FraudoPaymentParser.Trusted_token_conditionContext ctx) {
List<TerminalNode> intNodes = ctx.INTEGER();
return TrustCondition.builder()
.transactionsCurrency(safeGetText(ctx.STRING()))
.transactionsYearsOffset(safeGetInteger(intNodes.get(YEARS_OFFSET_INDEX)))
.transactionsCount(safeGetInteger(intNodes.get(COUNT_INDEX)))
.transactionsSum(
hasSumArgument(intNodes.size()) ? safeGetInteger(intNodes.get(SUM_INDEX)) : null)
.build();
}
private boolean hasSumArgument(int intNodesSize) {
return intNodesSize > SUM_INDEX;
}
}

View File

@ -0,0 +1,15 @@
package com.rbkmoney.fraudo.model;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class TrustCondition {
private String transactionsCurrency;
private Integer transactionsYearsOffset;
private Integer transactionsSum;
private Integer transactionsCount;
}

View File

@ -1,6 +1,7 @@
package com.rbkmoney.fraudo.payment.factory;
import com.rbkmoney.fraudo.aggregator.UniqueValueAggregator;
import com.rbkmoney.fraudo.converter.TrustConditionConverter;
import com.rbkmoney.fraudo.finder.InListFinder;
import com.rbkmoney.fraudo.model.BaseModel;
import com.rbkmoney.fraudo.payment.aggregator.CountPaymentAggregator;
@ -11,6 +12,7 @@ import com.rbkmoney.fraudo.payment.resolver.PaymentTimeWindowResolver;
import com.rbkmoney.fraudo.payment.resolver.PaymentTypeResolver;
import com.rbkmoney.fraudo.payment.visitor.CountVisitor;
import com.rbkmoney.fraudo.payment.visitor.CustomFuncVisitor;
import com.rbkmoney.fraudo.payment.visitor.IsTrustedFuncVisitor;
import com.rbkmoney.fraudo.payment.visitor.ListVisitor;
import com.rbkmoney.fraudo.payment.visitor.SumVisitor;
import com.rbkmoney.fraudo.payment.visitor.impl.*;
@ -31,8 +33,10 @@ public class FraudVisitorFactoryImpl implements FraudVisitorFactory {
PaymentTimeWindowResolver timeWindowResolver,
PaymentTypeResolver<T> paymentTypeResolver,
CustomerTypeResolver<T> customerTypeResolver) {
CountVisitor<T> countVisitor = new CountVisitorImpl<>(countPaymentAggregator, fieldResolver, paymentGroupResolver, timeWindowResolver);
SumVisitor<T> sumVisitor = new SumVisitorImpl<>(sumPaymentAggregator, fieldResolver, paymentGroupResolver, timeWindowResolver);
CountVisitor<T> countVisitor =
new CountVisitorImpl<>(countPaymentAggregator, fieldResolver, paymentGroupResolver, timeWindowResolver);
SumVisitor<T> sumVisitor =
new SumVisitorImpl<>(sumPaymentAggregator, fieldResolver, paymentGroupResolver, timeWindowResolver);
ListVisitor<T> listVisitor = new ListVisitorImpl<>(listFinder, fieldResolver);
CustomFuncVisitor<T> customFuncVisitor = new CustomFuncVisitorImpl<>(
uniqueValueAggregator,
@ -40,9 +44,20 @@ public class FraudVisitorFactoryImpl implements FraudVisitorFactory {
fieldResolver,
paymentGroupResolver,
timeWindowResolver,
paymentTypeResolver,
customerTypeResolver);
return new FirstFindVisitorImpl<>(countVisitor, sumVisitor, listVisitor, customFuncVisitor, fieldResolver);
paymentTypeResolver
);
IsTrustedFuncVisitor<T> isTrustedFuncVisitor = new IsTrustedFuncVisitorImpl<>(customerTypeResolver);
TrustConditionConverter trustConditionConverter = new TrustConditionConverter();
return new FirstFindVisitorImpl<>(
countVisitor,
sumVisitor,
listVisitor,
customFuncVisitor,
isTrustedFuncVisitor,
fieldResolver,
trustConditionConverter
);
}
}

View File

@ -1,6 +1,7 @@
package com.rbkmoney.fraudo.payment.factory;
import com.rbkmoney.fraudo.aggregator.UniqueValueAggregator;
import com.rbkmoney.fraudo.converter.TrustConditionConverter;
import com.rbkmoney.fraudo.finder.InListFinder;
import com.rbkmoney.fraudo.model.BaseModel;
import com.rbkmoney.fraudo.payment.aggregator.CountPaymentAggregator;
@ -11,6 +12,7 @@ import com.rbkmoney.fraudo.payment.resolver.PaymentTimeWindowResolver;
import com.rbkmoney.fraudo.payment.resolver.PaymentTypeResolver;
import com.rbkmoney.fraudo.payment.visitor.CountVisitor;
import com.rbkmoney.fraudo.payment.visitor.CustomFuncVisitor;
import com.rbkmoney.fraudo.payment.visitor.IsTrustedFuncVisitor;
import com.rbkmoney.fraudo.payment.visitor.ListVisitor;
import com.rbkmoney.fraudo.payment.visitor.SumVisitor;
import com.rbkmoney.fraudo.payment.visitor.impl.*;
@ -34,15 +36,24 @@ public class FullVisitorFactoryImpl implements FraudVisitorFactory {
CountVisitor<T> countVisitor = new CountVisitorImpl<>(countPaymentAggregator, fieldResolver, paymentGroupResolver, timeWindowResolver);
SumVisitor<T> sumVisitor = new SumVisitorImpl<>(sumPaymentAggregator, fieldResolver, paymentGroupResolver, timeWindowResolver);
ListVisitor<T> listVisitor = new ListVisitorImpl<>(listFinder, fieldResolver);
IsTrustedFuncVisitor<T> isTrustedFuncVisitor = new IsTrustedFuncVisitorImpl<>(customerTypeResolver);
TrustConditionConverter trustConditionConverter = new TrustConditionConverter();
CustomFuncVisitor<T> customFuncVisitor = new CustomFuncVisitorImpl<>(
uniqueValueAggregator,
countryResolver,
fieldResolver,
paymentGroupResolver,
timeWindowResolver,
paymentTypeResolver,
customerTypeResolver);
return new FullVisitorImpl<>(countVisitor, sumVisitor, listVisitor, customFuncVisitor, fieldResolver);
paymentTypeResolver);
return new FullVisitorImpl<>(
countVisitor,
sumVisitor,
listVisitor,
customFuncVisitor,
isTrustedFuncVisitor,
fieldResolver,
trustConditionConverter
);
}
}

View File

@ -1,7 +1,13 @@
package com.rbkmoney.fraudo.payment.resolver;
import com.rbkmoney.fraudo.model.TrustCondition;
import java.util.List;
public interface CustomerTypeResolver<T> {
Boolean isTrusted(T model);
Boolean isTrusted(List<TrustCondition> paymentsConditions, List<TrustCondition> withdrawalsConditions);
}

View File

@ -14,6 +14,4 @@ public interface CustomFuncVisitor<T> {
boolean visitCheckRecurrent(Is_recurrentContext ctx, T model);
boolean visitCheckTrusted(Is_trustedContext ctx, T model);
}

View File

@ -0,0 +1,13 @@
package com.rbkmoney.fraudo.payment.visitor;
import com.rbkmoney.fraudo.model.TrustCondition;
import java.util.List;
public interface IsTrustedFuncVisitor<T> {
boolean visitCheckTrusted(T model);
boolean visitCheckTrusted(List<TrustCondition> paymentsConditionsList,
List<TrustCondition> withdrawalConditionsList);
}

View File

@ -23,7 +23,6 @@ public class CustomFuncVisitorImpl<T, U> implements CustomFuncVisitor<T> {
private final PaymentGroupResolver<T, U> groupResolver;
private final PaymentTimeWindowResolver timeWindowResolver;
private final PaymentTypeResolver<T> paymentTypeResolver;
private final CustomerTypeResolver<T> customerTypeResolver;
@Override
public String visitCountryBy(Country_byContext ctx, T model) {
@ -63,9 +62,4 @@ public class CustomFuncVisitorImpl<T, U> implements CustomFuncVisitor<T> {
return paymentTypeResolver.isRecurrent(model);
}
@Override
public boolean visitCheckTrusted(Is_trustedContext ctx, T model) {
return customerTypeResolver.isTrusted(model);
}
}

View File

@ -2,15 +2,18 @@ package com.rbkmoney.fraudo.payment.visitor.impl;
import com.rbkmoney.fraudo.FraudoPaymentBaseVisitor;
import com.rbkmoney.fraudo.constant.ResultStatus;
import com.rbkmoney.fraudo.converter.TrustConditionConverter;
import com.rbkmoney.fraudo.exception.NotImplementedOperatorException;
import com.rbkmoney.fraudo.exception.NotValidContextException;
import com.rbkmoney.fraudo.exception.UnknownResultException;
import com.rbkmoney.fraudo.model.BaseModel;
import com.rbkmoney.fraudo.model.ResultModel;
import com.rbkmoney.fraudo.model.RuleResult;
import com.rbkmoney.fraudo.model.TrustCondition;
import com.rbkmoney.fraudo.payment.generator.RuleKeyGenerator;
import com.rbkmoney.fraudo.payment.visitor.CountVisitor;
import com.rbkmoney.fraudo.payment.visitor.CustomFuncVisitor;
import com.rbkmoney.fraudo.payment.visitor.IsTrustedFuncVisitor;
import com.rbkmoney.fraudo.payment.visitor.ListVisitor;
import com.rbkmoney.fraudo.payment.visitor.SumVisitor;
import com.rbkmoney.fraudo.resolver.FieldResolver;
@ -42,7 +45,9 @@ public class FirstFindVisitorImpl<T extends BaseModel, U> extends FraudoPaymentB
private final SumVisitor<T> sumVisitor;
private final ListVisitor<T> listVisitor;
private final CustomFuncVisitor<T> customFuncVisitor;
private final IsTrustedFuncVisitor<T> isTrustedFuncVisitor;
private final FieldResolver<T, U> fieldResolver;
private final TrustConditionConverter trustConditionConverter;
@Override
public void close() {
@ -376,7 +381,32 @@ public class FirstFindVisitorImpl<T extends BaseModel, U> extends FraudoPaymentB
}
@Override
public Boolean visitIs_trusted(Is_trustedContext ctx) {
return customFuncVisitor.visitCheckTrusted(ctx, threadLocalModel.get());
public Object visitIsTrusted(IsTrustedContext ctx) {
return isTrustedFuncVisitor.visitCheckTrusted(threadLocalModel.get());
}
@Override
public Object visitIsTrustedConditionsSingleList(IsTrustedConditionsSingleListContext ctx) {
if (ctx.payment_conditions() != null && !ctx.payment_conditions().isEmpty()) {
List<TrustCondition> paymentsConditions =
trustConditionConverter.convertToList(ctx.payment_conditions().conditions_list());
return isTrustedFuncVisitor.visitCheckTrusted(paymentsConditions, null);
}
if (ctx.withdrawal_conditions() != null && !ctx.withdrawal_conditions().isEmpty()) {
List<TrustCondition> withdrawalsConditions =
trustConditionConverter.convertToList(ctx.withdrawal_conditions().conditions_list());
return isTrustedFuncVisitor.visitCheckTrusted(null, withdrawalsConditions);
}
throw new NotValidContextException();
}
@Override
public Object visitIsTrustedPaymentsAndWithdrawalConditions(IsTrustedPaymentsAndWithdrawalConditionsContext ctx) {
List<TrustCondition> paymentsConditions =
trustConditionConverter.convertToList(ctx.payment_conditions().conditions_list());
List<TrustCondition> withdrawalsConditions =
trustConditionConverter.convertToList(ctx.withdrawal_conditions().conditions_list());
return isTrustedFuncVisitor.visitCheckTrusted(paymentsConditions, withdrawalsConditions);
}
}

View File

@ -1,6 +1,7 @@
package com.rbkmoney.fraudo.payment.visitor.impl;
import com.rbkmoney.fraudo.constant.ResultStatus;
import com.rbkmoney.fraudo.converter.TrustConditionConverter;
import com.rbkmoney.fraudo.exception.UnknownResultException;
import com.rbkmoney.fraudo.model.BaseModel;
import com.rbkmoney.fraudo.model.ResultModel;
@ -8,6 +9,7 @@ import com.rbkmoney.fraudo.model.RuleResult;
import com.rbkmoney.fraudo.payment.generator.RuleKeyGenerator;
import com.rbkmoney.fraudo.payment.visitor.CountVisitor;
import com.rbkmoney.fraudo.payment.visitor.CustomFuncVisitor;
import com.rbkmoney.fraudo.payment.visitor.IsTrustedFuncVisitor;
import com.rbkmoney.fraudo.payment.visitor.ListVisitor;
import com.rbkmoney.fraudo.payment.visitor.SumVisitor;
import com.rbkmoney.fraudo.resolver.FieldResolver;
@ -22,8 +24,17 @@ import static com.rbkmoney.fraudo.FraudoPaymentParser.ParseContext;
@Slf4j
public class FullVisitorImpl<T extends BaseModel, U> extends FirstFindVisitorImpl<T, U> {
public FullVisitorImpl(CountVisitor<T> countVisitor, SumVisitor<T> sumVisitor, ListVisitor<T> listVisitor, CustomFuncVisitor<T> customFuncVisitor, FieldResolver<T, U> fieldResolver) {
super(countVisitor, sumVisitor, listVisitor, customFuncVisitor, fieldResolver);
public FullVisitorImpl(
CountVisitor<T> countVisitor,
SumVisitor<T> sumVisitor,
ListVisitor<T> listVisitor,
CustomFuncVisitor<T> customFuncVisitor,
IsTrustedFuncVisitor<T> isTrustedFuncVisitor,
FieldResolver<T, U> fieldResolver,
TrustConditionConverter trustConditionConverter
) {
super(countVisitor, sumVisitor, listVisitor, customFuncVisitor, isTrustedFuncVisitor, fieldResolver,
trustConditionConverter);
}
@Override

View File

@ -0,0 +1,26 @@
package com.rbkmoney.fraudo.payment.visitor.impl;
import com.rbkmoney.fraudo.model.TrustCondition;
import com.rbkmoney.fraudo.payment.resolver.CustomerTypeResolver;
import com.rbkmoney.fraudo.payment.visitor.IsTrustedFuncVisitor;
import lombok.RequiredArgsConstructor;
import java.util.List;
@RequiredArgsConstructor
public class IsTrustedFuncVisitorImpl<T> implements IsTrustedFuncVisitor<T> {
private final CustomerTypeResolver<T> customerTypeResolver;
@Override
public boolean visitCheckTrusted(T model) {
return customerTypeResolver.isTrusted(model);
}
@Override
public boolean visitCheckTrusted(List<TrustCondition> paymentsConditionsList,
List<TrustCondition> withdrawalConditionsList) {
return customerTypeResolver.isTrusted(paymentsConditionsList, withdrawalConditionsList);
}
}

View File

@ -16,4 +16,10 @@ public class TextUtil {
.getText().replace("\"", "");
}
public static Integer safeGetInteger(TerminalNode field) {
return Optional.ofNullable(field)
.map(node -> Integer.parseInt(node.getText()))
.orElseThrow(FieldUnsetException::new);
}
}

View File

@ -134,17 +134,6 @@ public class CustomTest extends AbstractPaymentTest {
assertEquals(ResultStatus.ACCEPT, ResultUtils.findFirstNotNotifyStatus(result).get().getResultStatus());
}
@Test
public void trustedTest() throws Exception {
InputStream resourceAsStream = CustomTest.class.getResourceAsStream("/rules/is_trusted.frd");
when(customerTypeResolver.isTrusted(any())).thenReturn(true);
ParseContext parseContext = getParseContext(resourceAsStream);
PaymentModel model = new PaymentModel();
ResultModel result = invoke(parseContext, model);
assertEquals(ResultStatus.ACCEPT, ResultUtils.findFirstNotNotifyStatus(result).get().getResultStatus());
}
@Test
public void payerTypeTest() throws Exception {
InputStream resourceAsStream = CustomTest.class.getResourceAsStream("/rules/is_recurrent.frd");

View File

@ -0,0 +1,98 @@
package com.rbkmoney.fraudo;
import com.rbkmoney.fraudo.constant.ResultStatus;
import com.rbkmoney.fraudo.model.ResultModel;
import com.rbkmoney.fraudo.model.TrustCondition;
import com.rbkmoney.fraudo.test.model.PaymentModel;
import com.rbkmoney.fraudo.utils.ResultUtils;
import lombok.SneakyThrows;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.MockitoAnnotations;
import java.io.InputStream;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class IsTrustedTest extends AbstractPaymentTest {
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void trustedTest() {
when(customerTypeResolver.isTrusted(any())).thenReturn(true);
testIsTrusted("/rules/is_trusted.frd");
}
@Test
public void trustedWithWithdrawalsConditionsTest() {
when(customerTypeResolver.isTrusted(isNull(List.class), anyListOf(TrustCondition.class)))
.thenReturn(true);
testIsTrusted("/rules/is_trusted_with_withdrawals_conditions.frd");
}
@Test
public void trustedWithPaymentsConditionsTest() {
when(customerTypeResolver.isTrusted(anyListOf(TrustCondition.class), isNull(List.class)))
.thenReturn(true);
testIsTrusted("/rules/is_trusted_with_payments_conditions.frd");
}
@Test
public void trustedWithPaymentsAndWithdrawalSingleConditionsTest() {
when(customerTypeResolver.isTrusted(anyListOf(TrustCondition.class), anyListOf(TrustCondition.class)))
.thenReturn(true);
testIsTrusted("/rules/is_trusted_with_payments_and_withdrawals_single_conditions.frd");
}
@Test
public void trustedWithPaymentsAndWithdrawalTest() {
when(customerTypeResolver.isTrusted(anyListOf(TrustCondition.class), anyListOf(TrustCondition.class)))
.thenReturn(true);
testIsTrusted("/rules/is_trusted_with_payments_and_withdrawals_conditions.frd");
ArgumentCaptor<List<TrustCondition>> paymentsCaptor = ArgumentCaptor.forClass((Class) List.class);
ArgumentCaptor<List<TrustCondition>> withdrawalsCaptor = ArgumentCaptor.forClass((Class) List.class);
verify(customerTypeResolver, times(1))
.isTrusted(paymentsCaptor.capture(), withdrawalsCaptor.capture());
assertEquals(1, paymentsCaptor.getAllValues().size());
List<TrustCondition> payments = paymentsCaptor.getValue();
assertTrustedCondition("RUB",1,1000,10, payments.get(0));
assertTrustedCondition("EUR", 2, 20, null, payments.get(1));
assertEquals(1, withdrawalsCaptor.getAllValues().size());
List<TrustCondition> withdrawals = withdrawalsCaptor.getValue();
assertTrustedCondition("USD",3,3000,3, withdrawals.get(0));
assertTrustedCondition("CAD", 4, 4, null, withdrawals.get(1));
}
@SneakyThrows
private void testIsTrusted(String testCaseFilePath) {
InputStream resourceAsStream = IsTrustedTest.class.getResourceAsStream(testCaseFilePath);
com.rbkmoney.fraudo.FraudoPaymentParser.ParseContext parseContext = getParseContext(resourceAsStream);
PaymentModel model = new PaymentModel();
ResultModel result = invoke(parseContext, model);
assertEquals(ResultStatus.ACCEPT, ResultUtils.findFirstNotNotifyStatus(result).get().getResultStatus());
}
private void assertTrustedCondition(
String currency, Integer yearsOffset, Integer count, Integer sum, TrustCondition condition) {
assertEquals(currency, condition.getTransactionsCurrency());
assertEquals(yearsOffset, condition.getTransactionsYearsOffset());
assertEquals(count, condition.getTransactionsCount());
assertEquals(sum, condition.getTransactionsSum());
}
}

View File

@ -23,7 +23,7 @@ public class RealTimerTest extends AbstractPaymentTest {
public static final long TIME_CALL_AGGR_FUNC = 200L;
public static final long MILLISTIME_FAST_FUNC = 10L;
public static final long TIME_CALLING = 200L;
public static final long TIME_CALLING = 300L;
@Before
public void init() {
@ -50,7 +50,7 @@ public class RealTimerTest extends AbstractPaymentTest {
assertEquals(0, countDownLatch.getCount());
assertTrue(executionTime < TIME_CALL_AGGR_FUNC + 1 + TIME_CALLING);
System.out.println("executionTime=" + executionTime);
System.out.println("timingTest.executionTime=" + executionTime);
result = invokeFullVisitor(parseContext, model);
assertEquals(2, result.getRuleResults().size());
@ -71,6 +71,7 @@ public class RealTimerTest extends AbstractPaymentTest {
long start = System.currentTimeMillis();
ResultModel result = invoke(parseContext, model);
long executionTime = System.currentTimeMillis() - start;
System.out.println("timingWithSuccessTest.executionTime=" + executionTime);
Assert.assertEquals(ResultStatus.ACCEPT, ResultUtils.findFirstNotNotifyStatus(result).get().getResultStatus());
assertTrue(executionTime < TIME_CALL_AGGR_FUNC * 4 + TIME_CALLING);

View File

@ -0,0 +1,10 @@
rule: isTrusted(
paymentsConditions(
condition("RUB",1,1000,10),
condition("EUR", 2, 20)
),
withdrawalsConditions(
condition("USD",3,3000,3),
condition("CAD", 4, 4)
)
) -> accept;

View File

@ -0,0 +1,8 @@
rule: isTrusted(
paymentsConditions(
condition("RUB",1,1000,10)
),
withdrawalsConditions(
condition("CAD", 4, 4)
)
) -> accept;

View File

@ -0,0 +1,6 @@
rule: isTrusted(
paymentsConditions(
condition("RUB",1,1000,10),
condition("EUR", 2, 20)
)
) -> accept;

View File

@ -0,0 +1,6 @@
rule: isTrusted(
withdrawalsConditions(
condition("USD",3,3000,3),
condition("CAD", 4, 4)
)
) -> accept;