Merge branch 'charges_model' of DigiFi/digifi-BankToProductCore into master
This commit is contained in:
@@ -8,7 +8,7 @@ from app.models.loan_charge import LoanCharge
|
|||||||
from app.utils.logger import logger
|
from app.utils.logger import logger
|
||||||
from app.api.schemas.provide_loan import ProvideLoanSchema
|
from app.api.schemas.provide_loan import ProvideLoanSchema
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from app.models import Loan, Offer
|
from app.models import Loan, Offer, Charge
|
||||||
from app.api.enums import LoanStatus
|
from app.api.enums import LoanStatus
|
||||||
from app.extensions import db
|
from app.extensions import db
|
||||||
|
|
||||||
@@ -81,62 +81,16 @@ class ProvideLoanService(BaseService):
|
|||||||
"message": "Failed to save loan details."
|
"message": "Failed to save loan details."
|
||||||
}), 400
|
}), 400
|
||||||
|
|
||||||
|
|
||||||
|
charges = Charge.get_offer_charges(offer.id)
|
||||||
|
|
||||||
charges = [
|
logger.error(f"{charges}")
|
||||||
{"code": "INTEREST", "percent": 1.1, "due": 0, "description": "This is fee 9000"},
|
|
||||||
{"code": "MGTFEE", "percent": 1.5, "due": 0, "description": "This is fee 90002"},
|
|
||||||
{"code": "INSURANCE", "percent": 1.5, "due": 30, "description": "This is fee 90003"},
|
|
||||||
{"code": "VAT", "percent": 1.5, "due": 60, "description": "This is fee 90004"},
|
|
||||||
]
|
|
||||||
loan_id = loan.id
|
loan_id = loan.id
|
||||||
|
|
||||||
loan_charges = LoanCharge.create_charges_for_loan(loan_id = loan_id, transaction_id = transaction_id, referenced_amount = 800, charges = charges)
|
loan_charges = LoanCharge.create_charges_for_loan(loan_id = loan_id, transaction_id = transaction_id, referenced_amount = 800, charges = charges)
|
||||||
|
|
||||||
|
|
||||||
# logger.error(f"********* We need to develop the fee array here")
|
|
||||||
|
|
||||||
# loan_def = {
|
|
||||||
# "offers": [
|
|
||||||
# {
|
|
||||||
# "offerId": "SAL90",
|
|
||||||
# "productId": "2030",
|
|
||||||
# "minAmount": 5000,
|
|
||||||
# "maxAmount": 100000,
|
|
||||||
# "tenor": 30
|
|
||||||
# },
|
|
||||||
# {
|
|
||||||
# "offerId": "SAL30",
|
|
||||||
# "productId": "2090",
|
|
||||||
# "minAmount": 3000,
|
|
||||||
# "maxAmount": 500000,
|
|
||||||
# "tenor": 90
|
|
||||||
# }
|
|
||||||
# ],
|
|
||||||
# "loan_fee": {
|
|
||||||
# "SAL30": [
|
|
||||||
# {"code": "INTEREST", "percent": 1.1, "due": 0, "description": "This is fee 000"},
|
|
||||||
# {"code": "MGTFEE", "percent": 2.5, "due": 0, "description": "This is fee 001"},
|
|
||||||
# {"code": "INSURANCE", "percent": 3.5, "due": 0, "description": "This is fee 001"},
|
|
||||||
# {"code": "VAT", "percent": 1.0, "due": 0, "description": "This is fee 001"},
|
|
||||||
# ],
|
|
||||||
# "SAL90": [
|
|
||||||
# {"code": "INTEREST", "percent": 1.1, "due": 0, "description": "This is fee 9000"},
|
|
||||||
# {"code": "MGTFEE", "percent": 1.5, "due": 0, "description": "This is fee 90002"},
|
|
||||||
# {"code": "INSURANCE", "percent": 1.5, "due": 30, "description": "This is fee 90003"},
|
|
||||||
# {"code": "VAT", "percent": 1.5, "due": 60, "description": "This is fee 90004"},
|
|
||||||
# ]
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
|
|
||||||
|
|
||||||
# Log Transaction
|
|
||||||
# transaction = ProvideLoanService.log_transaction(validated_data = validated_data)
|
|
||||||
#
|
|
||||||
# if not transaction:
|
|
||||||
# logger.error(f"Failed to log transaction")
|
|
||||||
# return jsonify({
|
|
||||||
# "message": "Failed to log transaction."
|
|
||||||
# }), 400
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return jsonify({
|
return jsonify({
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from .transaction import Transaction
|
|||||||
from .repayment import Repayment
|
from .repayment import Repayment
|
||||||
from .loan_charge import LoanCharge
|
from .loan_charge import LoanCharge
|
||||||
from .offer import Offer
|
from .offer import Offer
|
||||||
|
from .charge import Charge
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['Customer', 'Account', 'Loan', 'Transaction', 'Repayment', 'LoanCharge', 'Offer']
|
__all__ = ['Customer', 'Account', 'Loan', 'Transaction', 'Repayment', 'LoanCharge', 'Offer', 'Charge']
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
from datetime import datetime, timezone, timedelta
|
||||||
|
from app.extensions import db
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
|
|
||||||
|
class Charge(db.Model):
|
||||||
|
__tablename__ = 'charges'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||||
|
offer_id = db.Column(db.String(50), nullable=False)
|
||||||
|
code = db.Column(db.String(50), nullable=False)
|
||||||
|
percent = db.Column(db.Float, default=0.0)
|
||||||
|
description = db.Column(db.Text, nullable=True)
|
||||||
|
due = db.Column(db.Integer, nullable=False)
|
||||||
|
created_at = db.Column(db.DateTime, default=datetime.now(timezone.utc))
|
||||||
|
updated_at = db.Column(db.DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc))
|
||||||
|
|
||||||
|
offer = relationship(
|
||||||
|
"Offer",
|
||||||
|
primaryjoin="Charge.offer_id == Offer.id",
|
||||||
|
foreign_keys=[offer_id],
|
||||||
|
back_populates="charges",
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_charges(cls, offer_id, charges):
|
||||||
|
"""
|
||||||
|
Add charges to an offer.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
offer_id (int): ID of the offer to associate charges with.
|
||||||
|
charges (list): A list of dictionaries with keys:
|
||||||
|
code (str), amount (float), percent (float), description (str), due (int)
|
||||||
|
"""
|
||||||
|
if not charges or not isinstance(charges, list):
|
||||||
|
raise ValueError("Charges must be a non-empty list of dictionaries")
|
||||||
|
|
||||||
|
if offer_id is None:
|
||||||
|
raise ValueError("offer_id cannot be None")
|
||||||
|
|
||||||
|
offer_charges = []
|
||||||
|
|
||||||
|
|
||||||
|
for charge in charges:
|
||||||
|
code = charge.get("code")
|
||||||
|
percent = charge.get("percent", 0.0)
|
||||||
|
description = charge.get("description", "")
|
||||||
|
due_days = charge.get("due", 0)
|
||||||
|
|
||||||
|
existing = cls.query.filter_by(offer_id=offer_id, code=code).first()
|
||||||
|
|
||||||
|
if existing:
|
||||||
|
continue
|
||||||
|
|
||||||
|
charge_obj = cls(
|
||||||
|
offer_id = offer_id,
|
||||||
|
code = code,
|
||||||
|
percent = percent,
|
||||||
|
description = description,
|
||||||
|
due = due_days
|
||||||
|
)
|
||||||
|
|
||||||
|
db.session.add(charge_obj)
|
||||||
|
offer_charges.append(charge_obj)
|
||||||
|
|
||||||
|
return offer_charges
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_offer_charges(cls, offer_id):
|
||||||
|
"""
|
||||||
|
Get all charges for a particular offer as a dictionary
|
||||||
|
|
||||||
|
Args:
|
||||||
|
offer_id (str): The offer ID.
|
||||||
|
"""
|
||||||
|
if not offer_id:
|
||||||
|
raise ValueError("offer_id not found")
|
||||||
|
|
||||||
|
charges = cls.query.filter_by(offer_id=offer_id).all()
|
||||||
|
|
||||||
|
return charges
|
||||||
|
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return {
|
||||||
|
'id': self.id,
|
||||||
|
'offerId': self.offer_id,
|
||||||
|
'code': self.code,
|
||||||
|
'percent': self.percent,
|
||||||
|
'description': self.description,
|
||||||
|
'due': self.due
|
||||||
|
}
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<Charge {self.id} - Offer {self.offer_id} - {self.code}>"
|
||||||
@@ -45,9 +45,9 @@ class LoanCharge(db.Model):
|
|||||||
now = datetime.now(timezone.utc)
|
now = datetime.now(timezone.utc)
|
||||||
|
|
||||||
for charge in charges:
|
for charge in charges:
|
||||||
due_days = charge.get("due", 0)
|
due_days = getattr(charge, "due", 0)
|
||||||
amount = charge.get("amount", 0.0)
|
amount = getattr(charge, "amount", 0.0)
|
||||||
percent = charge.get("percent", 0.0)
|
percent = getattr(charge, "percent", 0.0)
|
||||||
|
|
||||||
if amount == 0.0:
|
if amount == 0.0:
|
||||||
amount = (percent / 100.0) * referenced_amount
|
amount = (percent / 100.0) * referenced_amount
|
||||||
@@ -55,10 +55,10 @@ class LoanCharge(db.Model):
|
|||||||
charge_obj = cls(
|
charge_obj = cls(
|
||||||
loan_id = loan_id,
|
loan_id = loan_id,
|
||||||
transaction_id = transaction_id,
|
transaction_id = transaction_id,
|
||||||
code = charge.get("code"),
|
code = getattr(charge, "code"),
|
||||||
amount = amount,
|
amount = amount,
|
||||||
percent = percent,
|
percent = percent,
|
||||||
description = charge.get("description", ""),
|
description = getattr(charge, "description", ""),
|
||||||
due = due_days,
|
due = due_days,
|
||||||
due_date = now + timedelta(days=due_days)
|
due_date = now + timedelta(days=due_days)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from app.extensions import db
|
from app.extensions import db
|
||||||
|
from app.models.charge import Charge
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
class Offer(db.Model):
|
class Offer(db.Model):
|
||||||
__tablename__ = 'offers'
|
__tablename__ = 'offers'
|
||||||
@@ -12,6 +14,13 @@ class Offer(db.Model):
|
|||||||
created_at = db.Column(db.DateTime, default=datetime.now(timezone.utc))
|
created_at = db.Column(db.DateTime, default=datetime.now(timezone.utc))
|
||||||
updated_at = db.Column(db.DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc))
|
updated_at = db.Column(db.DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc))
|
||||||
|
|
||||||
|
charges = relationship(
|
||||||
|
"Charge",
|
||||||
|
primaryjoin="Offer.id == Charge.offer_id",
|
||||||
|
foreign_keys="Charge.offer_id",
|
||||||
|
back_populates="offer",
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_all_offers(cls):
|
def get_all_offers(cls):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
"""Migration on Thu Apr 17 14:15:36 UTC 2025
|
||||||
|
|
||||||
|
Revision ID: de9ad96ba34e
|
||||||
|
Revises: ec8d97f9b584
|
||||||
|
Create Date: 2025-04-17 14:16:16.537466
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'de9ad96ba34e'
|
||||||
|
down_revision = 'ec8d97f9b584'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table('charges',
|
||||||
|
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
||||||
|
sa.Column('offer_id', sa.String(length=50), nullable=False),
|
||||||
|
sa.Column('code', sa.String(length=50), nullable=False),
|
||||||
|
sa.Column('percent', sa.Float(), nullable=True),
|
||||||
|
sa.Column('description', sa.Text(), nullable=True),
|
||||||
|
sa.Column('due', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_table('charges')
|
||||||
|
# ### end Alembic commands ###
|
||||||
@@ -0,0 +1,651 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.6.3">
|
||||||
|
<hashTree>
|
||||||
|
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Simbrella FirstAdvance API Test">
|
||||||
|
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
|
||||||
|
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables">
|
||||||
|
<collectionProp name="Arguments.arguments">
|
||||||
|
<elementProp name="baseUrl" elementType="Argument">
|
||||||
|
<stringProp name="Argument.name">baseUrl</stringProp>
|
||||||
|
<stringProp name="Argument.value">http://localhost:4500</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="username" elementType="Argument">
|
||||||
|
<stringProp name="Argument.name">username</stringProp>
|
||||||
|
<stringProp name="Argument.value">user</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="password" elementType="Argument">
|
||||||
|
<stringProp name="Argument.name">password</stringProp>
|
||||||
|
<stringProp name="Argument.value">password</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</elementProp>
|
||||||
|
<boolProp name="TestPlan.functional_mode">false</boolProp>
|
||||||
|
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
|
||||||
|
</TestPlan>
|
||||||
|
<hashTree>
|
||||||
|
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Authorizaton Thread Group">
|
||||||
|
<intProp name="ThreadGroup.num_threads">1</intProp>
|
||||||
|
<intProp name="ThreadGroup.ramp_time">1</intProp>
|
||||||
|
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
|
||||||
|
<stringProp name="ThreadGroup.on_sample_error">stopthread</stringProp>
|
||||||
|
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller">
|
||||||
|
<stringProp name="LoopController.loops">1</stringProp>
|
||||||
|
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||||
|
</elementProp>
|
||||||
|
</ThreadGroup>
|
||||||
|
<hashTree>
|
||||||
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="1. Authorize" enabled="true">
|
||||||
|
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port">4500</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">/Authorize</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
|
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
|
||||||
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
|
||||||
|
<collectionProp name="Arguments.arguments">
|
||||||
|
<elementProp name="" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">{
|
||||||
|
"username":"${username}",
|
||||||
|
"password":"${password}"
|
||||||
|
}</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</elementProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree>
|
||||||
|
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
|
||||||
|
<collectionProp name="HeaderManager.headers">
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Content-Type</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Accept</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</HeaderManager>
|
||||||
|
<hashTree/>
|
||||||
|
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="JSON Extractor - Auth Token" enabled="true">
|
||||||
|
<stringProp name="JSONPostProcessor.referenceNames">access_token</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.jsonPathExprs">$.data.access_token</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.match_numbers">1</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.defaultValues">NOT_FOUND</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.scope">variable</stringProp>
|
||||||
|
<stringProp name="Scope.variable"></stringProp>
|
||||||
|
<stringProp name="Sample.scope">all</stringProp>
|
||||||
|
</JSONPostProcessor>
|
||||||
|
<hashTree/>
|
||||||
|
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="JSON Extractor - Auth Refresh Token" enabled="true">
|
||||||
|
<stringProp name="JSONPostProcessor.referenceNames">refresh_token</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.jsonPathExprs">$.data.refresh_token</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.match_numbers">1</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.defaultValues">NOT_FOUND</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.scope">variable</stringProp>
|
||||||
|
<stringProp name="Scope.variable"></stringProp>
|
||||||
|
<stringProp name="Sample.scope">all</stringProp>
|
||||||
|
</JSONPostProcessor>
|
||||||
|
<hashTree/>
|
||||||
|
<JSR223PostProcessor guiclass="TestBeanGUI" testclass="JSR223PostProcessor" testname="JSR223 PostProcessor" enabled="true">
|
||||||
|
<stringProp name="cacheKey">true</stringProp>
|
||||||
|
<stringProp name="filename"></stringProp>
|
||||||
|
<stringProp name="parameters"></stringProp>
|
||||||
|
<stringProp name="script">props.put("GLOBAL_ACCESS_TOKEN", vars.get("access_token"));
|
||||||
|
props.put("GLOBAL_REFRESH_TOKEN", vars.get("refresh_token"));</stringProp>
|
||||||
|
<stringProp name="scriptLanguage">groovy</stringProp>
|
||||||
|
</JSR223PostProcessor>
|
||||||
|
<hashTree/>
|
||||||
|
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
|
||||||
|
<collectionProp name="Asserion.test_strings"/>
|
||||||
|
<collectionProp name="Asserter.test_strings">
|
||||||
|
<stringProp name="49586">200</stringProp>
|
||||||
|
</collectionProp>
|
||||||
|
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
|
||||||
|
<boolProp name="Assertion.assume_success">false</boolProp>
|
||||||
|
<intProp name="Assertion.test_type">16</intProp>
|
||||||
|
<stringProp name="Assertion.custom_message"></stringProp>
|
||||||
|
</ResponseAssertion>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
<DebugSampler guiclass="TestBeanGUI" testclass="DebugSampler" testname="Debug Sampler" enabled="true">
|
||||||
|
<boolProp name="displayJMeterProperties">false</boolProp>
|
||||||
|
<boolProp name="displayJMeterVariables">true</boolProp>
|
||||||
|
<boolProp name="displaySystemProperties">false</boolProp>
|
||||||
|
</DebugSampler>
|
||||||
|
<hashTree/>
|
||||||
|
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
|
||||||
|
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||||
|
<objProp>
|
||||||
|
<name>saveConfig</name>
|
||||||
|
<value class="SampleSaveConfiguration">
|
||||||
|
<time>true</time>
|
||||||
|
<latency>true</latency>
|
||||||
|
<timestamp>true</timestamp>
|
||||||
|
<success>true</success>
|
||||||
|
<label>true</label>
|
||||||
|
<code>true</code>
|
||||||
|
<message>true</message>
|
||||||
|
<threadName>true</threadName>
|
||||||
|
<dataType>true</dataType>
|
||||||
|
<encoding>false</encoding>
|
||||||
|
<assertions>true</assertions>
|
||||||
|
<subresults>true</subresults>
|
||||||
|
<responseData>false</responseData>
|
||||||
|
<samplerData>false</samplerData>
|
||||||
|
<xml>false</xml>
|
||||||
|
<fieldNames>true</fieldNames>
|
||||||
|
<responseHeaders>false</responseHeaders>
|
||||||
|
<requestHeaders>false</requestHeaders>
|
||||||
|
<responseDataOnError>false</responseDataOnError>
|
||||||
|
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||||
|
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||||
|
<bytes>true</bytes>
|
||||||
|
<sentBytes>true</sentBytes>
|
||||||
|
<url>true</url>
|
||||||
|
<threadCounts>true</threadCounts>
|
||||||
|
<idleTime>true</idleTime>
|
||||||
|
<connectTime>true</connectTime>
|
||||||
|
</value>
|
||||||
|
</objProp>
|
||||||
|
<stringProp name="filename"></stringProp>
|
||||||
|
</ResultCollector>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="API Test Thread Group">
|
||||||
|
<intProp name="ThreadGroup.num_threads">1</intProp>
|
||||||
|
<intProp name="ThreadGroup.ramp_time">1</intProp>
|
||||||
|
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
|
||||||
|
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||||
|
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller">
|
||||||
|
<stringProp name="LoopController.loops">1</stringProp>
|
||||||
|
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||||
|
</elementProp>
|
||||||
|
</ThreadGroup>
|
||||||
|
<hashTree>
|
||||||
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="2. Authorize Refresh" enabled="true">
|
||||||
|
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port">4500</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">/AuthorizeRefresh</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
|
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
|
||||||
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
|
||||||
|
<collectionProp name="Arguments.arguments">
|
||||||
|
<elementProp name="" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">{
|
||||||
|

|
||||||
|
}
|
||||||
|
</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</elementProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree>
|
||||||
|
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
|
||||||
|
<collectionProp name="HeaderManager.headers">
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Content-Type</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Accept</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Authorization</stringProp>
|
||||||
|
<stringProp name="Header.value">Bearer ${__P(GLOBAL_REFRESH_TOKEN)}</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</HeaderManager>
|
||||||
|
<hashTree/>
|
||||||
|
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
|
||||||
|
<collectionProp name="Asserion.test_strings"/>
|
||||||
|
<collectionProp name="Asserter.test_strings">
|
||||||
|
<stringProp name="49586">200</stringProp>
|
||||||
|
</collectionProp>
|
||||||
|
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
|
||||||
|
<boolProp name="Assertion.assume_success">false</boolProp>
|
||||||
|
<intProp name="Assertion.test_type">16</intProp>
|
||||||
|
<stringProp name="Assertion.custom_message"></stringProp>
|
||||||
|
</ResponseAssertion>
|
||||||
|
<hashTree/>
|
||||||
|
<JSR223PreProcessor guiclass="TestBeanGUI" testclass="JSR223PreProcessor" testname="JSR223 PreProcessor" enabled="true">
|
||||||
|
<stringProp name="scriptLanguage">groovy</stringProp>
|
||||||
|
<stringProp name="parameters"></stringProp>
|
||||||
|
<stringProp name="filename"></stringProp>
|
||||||
|
<stringProp name="cacheKey">true</stringProp>
|
||||||
|
<stringProp name="script">// Generate random IDs and store them in JMeter variables
|
||||||
|
def transactionId = "TR" + org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric(12)
|
||||||
|
def customerId = "CN" + org.apache.commons.lang3.RandomUtils.nextInt(1000000, 9999999)
|
||||||
|
def accountId = "ACN" + org.apache.commons.lang3.RandomUtils.nextInt(1000000, 9999999)
|
||||||
|
def msisdn = "809" + org.apache.commons.lang3.RandomUtils.nextInt(1000000, 9999999)
|
||||||
|
|
||||||
|
// Generate requestId: current timestamp + 6-digit random number
|
||||||
|
def timestamp = new Date().format("yyyyMMddHHmmssSSS") // e.g., 20250414161243123
|
||||||
|
def randomSuffix = org.apache.commons.lang3.RandomStringUtils.randomNumeric(6)
|
||||||
|
def requestId = timestamp + randomSuffix
|
||||||
|
|
||||||
|
vars.put("transactionId", transactionId)
|
||||||
|
vars.put("customerId", customerId.toString())
|
||||||
|
vars.put("accountId", accountId.toString())
|
||||||
|
vars.put("msisdn", msisdn.toString())
|
||||||
|
vars.put("requestId", requestId)
|
||||||
|
</stringProp>
|
||||||
|
</JSR223PreProcessor>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="3. Eligibility Check">
|
||||||
|
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port">4500</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">/EligibilityCheck</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
|
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
|
||||||
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
|
||||||
|
<collectionProp name="Arguments.arguments">
|
||||||
|
<elementProp name="" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">{
|
||||||
|
"transactionId":"${transactionId}",
|
||||||
|
"countryCode":"NGR",
|
||||||
|
"customerId":"${customerId}",
|
||||||
|
"msisdn":"${msisdn}",
|
||||||
|
"channel":"100",
|
||||||
|
"accountId":"${accountId}"
|
||||||
|
}</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</elementProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree>
|
||||||
|
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
|
||||||
|
<collectionProp name="HeaderManager.headers">
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Content-Type</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Accept</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Authorization</stringProp>
|
||||||
|
<stringProp name="Header.value">Bearer ${__P(GLOBAL_ACCESS_TOKEN)}</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</HeaderManager>
|
||||||
|
<hashTree/>
|
||||||
|
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="JSON Extractor - Product ID">
|
||||||
|
<stringProp name="JSONPostProcessor.referenceNames">productId</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.jsonPathExprs">$.eligibleOffers[0].productId</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.match_numbers">0</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.defaultValues">NOT_FOUND</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.scope">variable</stringProp>
|
||||||
|
</JSONPostProcessor>
|
||||||
|
<hashTree/>
|
||||||
|
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
|
||||||
|
<collectionProp name="Asserion.test_strings"/>
|
||||||
|
<collectionProp name="Asserter.test_strings">
|
||||||
|
<stringProp name="49586">200</stringProp>
|
||||||
|
</collectionProp>
|
||||||
|
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
|
||||||
|
<boolProp name="Assertion.assume_success">false</boolProp>
|
||||||
|
<intProp name="Assertion.test_type">16</intProp>
|
||||||
|
<stringProp name="Assertion.custom_message"></stringProp>
|
||||||
|
</ResponseAssertion>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="4. Select Offer">
|
||||||
|
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port">4500</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">/SelectOffer</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
|
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
|
||||||
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
|
||||||
|
<collectionProp name="Arguments.arguments">
|
||||||
|
<elementProp name="" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">{
|
||||||
|
"requestId": "${requestId}",
|
||||||
|
"transactionId": "${transactionId}",
|
||||||
|
"customerId":"${customerId}",
|
||||||
|
"msisdn": "${msisdn}",
|
||||||
|
"requestedAmount": ${__Random(500000,1000000,)}.00,
|
||||||
|
"accountId":"${accountId}",
|
||||||
|
"productId": "${productId}",
|
||||||
|
"channel": "100"
|
||||||
|
}</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</elementProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree>
|
||||||
|
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
|
||||||
|
<collectionProp name="HeaderManager.headers">
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Content-Type</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Accept</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Authorization</stringProp>
|
||||||
|
<stringProp name="Header.value">Bearer ${__P(GLOBAL_ACCESS_TOKEN)}</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</HeaderManager>
|
||||||
|
<hashTree/>
|
||||||
|
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="JSON Extractor - Offer ID">
|
||||||
|
<stringProp name="JSONPostProcessor.referenceNames">offerId</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.jsonPathExprs">$.loan[0].offerId</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.match_numbers">0</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.scope">variable</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.defaultValues">NOT_FOUND</stringProp>
|
||||||
|
<stringProp name="Sample.scope">all</stringProp>
|
||||||
|
</JSONPostProcessor>
|
||||||
|
<hashTree/>
|
||||||
|
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="JSON Extractor - Requested Amount" enabled="true">
|
||||||
|
<stringProp name="JSONPostProcessor.referenceNames">amount</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.jsonPathExprs">$.loan[0].amount</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.match_numbers">0</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.defaultValues">800</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.scope">variable</stringProp>
|
||||||
|
<stringProp name="Sample.scope">all</stringProp>
|
||||||
|
</JSONPostProcessor>
|
||||||
|
<hashTree/>
|
||||||
|
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
|
||||||
|
<collectionProp name="Asserion.test_strings"/>
|
||||||
|
<collectionProp name="Asserter.test_strings">
|
||||||
|
<stringProp name="49586">200</stringProp>
|
||||||
|
</collectionProp>
|
||||||
|
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
|
||||||
|
<boolProp name="Assertion.assume_success">false</boolProp>
|
||||||
|
<intProp name="Assertion.test_type">16</intProp>
|
||||||
|
<stringProp name="Assertion.custom_message"></stringProp>
|
||||||
|
</ResponseAssertion>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="5. Provide Loan">
|
||||||
|
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port">4500</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">/ProvideLoan</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
|
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
|
||||||
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
|
||||||
|
<collectionProp name="Arguments.arguments">
|
||||||
|
<elementProp name="" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">{
|
||||||
|
"requestId":"${requestId}",
|
||||||
|
"transactionId":"${transactionId}",
|
||||||
|
"customerId":"${customerId}",
|
||||||
|
"accountId":"${accountId}",
|
||||||
|
"msisdn":"${msisdn}",
|
||||||
|
"requestedAmount":${amount},
|
||||||
|
"collectionType":1,
|
||||||
|
"offerId":"${offerId}",
|
||||||
|
"channel":"100"
|
||||||
|
}</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</elementProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree>
|
||||||
|
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
|
||||||
|
<collectionProp name="HeaderManager.headers">
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Content-Type</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Accept</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Authorization</stringProp>
|
||||||
|
<stringProp name="Header.value">Bearer ${__P(GLOBAL_ACCESS_TOKEN)}</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</HeaderManager>
|
||||||
|
<hashTree/>
|
||||||
|
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
|
||||||
|
<collectionProp name="Asserion.test_strings"/>
|
||||||
|
<collectionProp name="Asserter.test_strings">
|
||||||
|
<stringProp name="49586">200</stringProp>
|
||||||
|
</collectionProp>
|
||||||
|
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
|
||||||
|
<boolProp name="Assertion.assume_success">false</boolProp>
|
||||||
|
<intProp name="Assertion.test_type">16</intProp>
|
||||||
|
<stringProp name="Assertion.custom_message"></stringProp>
|
||||||
|
</ResponseAssertion>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="6. Loan Status" enabled="true">
|
||||||
|
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port">4500</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">/LoanStatus</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
|
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
|
||||||
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
|
||||||
|
<collectionProp name="Arguments.arguments">
|
||||||
|
<elementProp name="" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">{
|
||||||
|
"transactionId":"${transactionId}",
|
||||||
|
"customerId":"${customerId}",
|
||||||
|
"msisdn":"${msisdn}",
|
||||||
|
"channel":"100",
|
||||||
|
"accountId":"${accountId}"
|
||||||
|
}</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</elementProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree>
|
||||||
|
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
|
||||||
|
<collectionProp name="HeaderManager.headers">
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Content-Type</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Accept</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Authorization</stringProp>
|
||||||
|
<stringProp name="Header.value">Bearer ${__P(GLOBAL_ACCESS_TOKEN)}</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</HeaderManager>
|
||||||
|
<hashTree/>
|
||||||
|
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="JSON Extractor - Debt Id" enabled="true">
|
||||||
|
<stringProp name="JSONPostProcessor.referenceNames">debtId</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.jsonPathExprs">$.loans[0].debtId</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.match_numbers">0</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.defaultValues">800</stringProp>
|
||||||
|
<stringProp name="JSONPostProcessor.scope">variable</stringProp>
|
||||||
|
<stringProp name="Sample.scope">all</stringProp>
|
||||||
|
</JSONPostProcessor>
|
||||||
|
<hashTree/>
|
||||||
|
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
|
||||||
|
<collectionProp name="Asserion.test_strings"/>
|
||||||
|
<collectionProp name="Asserter.test_strings">
|
||||||
|
<stringProp name="49586">200</stringProp>
|
||||||
|
</collectionProp>
|
||||||
|
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
|
||||||
|
<boolProp name="Assertion.assume_success">false</boolProp>
|
||||||
|
<intProp name="Assertion.test_type">16</intProp>
|
||||||
|
<stringProp name="Assertion.custom_message"></stringProp>
|
||||||
|
</ResponseAssertion>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="7. Repayment" enabled="true">
|
||||||
|
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port">4500</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">/Repayment</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
|
<stringProp name="HTTPSampler.method">POST</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
|
||||||
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
|
||||||
|
<collectionProp name="Arguments.arguments">
|
||||||
|
<elementProp name="" elementType="HTTPArgument">
|
||||||
|
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||||
|
<stringProp name="Argument.value">{
|
||||||
|
"debtId":"${debtId}",
|
||||||
|
"transactionId":"${transactionId}",
|
||||||
|
"customerId":"${customerId}",
|
||||||
|
"msisdn":"${msisdn}",
|
||||||
|
"channel":"100",
|
||||||
|
"accountId":"${accountId}",
|
||||||
|
"productId": "${productId}"
|
||||||
|
}</stringProp>
|
||||||
|
<stringProp name="Argument.metadata">=</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</elementProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree>
|
||||||
|
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
|
||||||
|
<collectionProp name="HeaderManager.headers">
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Content-Type</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Accept</stringProp>
|
||||||
|
<stringProp name="Header.value">application/json</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<elementProp name="" elementType="Header">
|
||||||
|
<stringProp name="Header.name">Authorization</stringProp>
|
||||||
|
<stringProp name="Header.value">Bearer ${__P(GLOBAL_ACCESS_TOKEN)}</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
</collectionProp>
|
||||||
|
</HeaderManager>
|
||||||
|
<hashTree/>
|
||||||
|
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
|
||||||
|
<collectionProp name="Asserion.test_strings"/>
|
||||||
|
<collectionProp name="Asserter.test_strings">
|
||||||
|
<stringProp name="49586">200</stringProp>
|
||||||
|
</collectionProp>
|
||||||
|
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
|
||||||
|
<boolProp name="Assertion.assume_success">false</boolProp>
|
||||||
|
<intProp name="Assertion.test_type">16</intProp>
|
||||||
|
<stringProp name="Assertion.custom_message"></stringProp>
|
||||||
|
</ResponseAssertion>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
|
||||||
|
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||||
|
<objProp>
|
||||||
|
<name>saveConfig</name>
|
||||||
|
<value class="SampleSaveConfiguration">
|
||||||
|
<time>true</time>
|
||||||
|
<latency>true</latency>
|
||||||
|
<timestamp>true</timestamp>
|
||||||
|
<success>true</success>
|
||||||
|
<label>true</label>
|
||||||
|
<code>true</code>
|
||||||
|
<message>true</message>
|
||||||
|
<threadName>true</threadName>
|
||||||
|
<dataType>true</dataType>
|
||||||
|
<encoding>false</encoding>
|
||||||
|
<assertions>true</assertions>
|
||||||
|
<subresults>true</subresults>
|
||||||
|
<responseData>false</responseData>
|
||||||
|
<samplerData>false</samplerData>
|
||||||
|
<xml>false</xml>
|
||||||
|
<fieldNames>true</fieldNames>
|
||||||
|
<responseHeaders>false</responseHeaders>
|
||||||
|
<requestHeaders>false</requestHeaders>
|
||||||
|
<responseDataOnError>false</responseDataOnError>
|
||||||
|
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||||
|
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||||
|
<bytes>true</bytes>
|
||||||
|
<sentBytes>true</sentBytes>
|
||||||
|
<url>true</url>
|
||||||
|
<threadCounts>true</threadCounts>
|
||||||
|
<idleTime>true</idleTime>
|
||||||
|
<connectTime>true</connectTime>
|
||||||
|
</value>
|
||||||
|
</objProp>
|
||||||
|
<stringProp name="filename"></stringProp>
|
||||||
|
</ResultCollector>
|
||||||
|
<hashTree/>
|
||||||
|
<DebugSampler guiclass="TestBeanGUI" testclass="DebugSampler" testname="Debug Sampler" enabled="true">
|
||||||
|
<boolProp name="displayJMeterProperties">false</boolProp>
|
||||||
|
<boolProp name="displayJMeterVariables">true</boolProp>
|
||||||
|
<boolProp name="displaySystemProperties">false</boolProp>
|
||||||
|
</DebugSampler>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree">
|
||||||
|
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||||
|
<objProp>
|
||||||
|
<name>saveConfig</name>
|
||||||
|
<value class="SampleSaveConfiguration">
|
||||||
|
<time>true</time>
|
||||||
|
<latency>true</latency>
|
||||||
|
<timestamp>true</timestamp>
|
||||||
|
<success>true</success>
|
||||||
|
<label>true</label>
|
||||||
|
<code>true</code>
|
||||||
|
<message>true</message>
|
||||||
|
<threadName>true</threadName>
|
||||||
|
<dataType>true</dataType>
|
||||||
|
<encoding>false</encoding>
|
||||||
|
<assertions>true</assertions>
|
||||||
|
<subresults>true</subresults>
|
||||||
|
<responseData>false</responseData>
|
||||||
|
<samplerData>false</samplerData>
|
||||||
|
<xml>false</xml>
|
||||||
|
<fieldNames>true</fieldNames>
|
||||||
|
<responseHeaders>false</responseHeaders>
|
||||||
|
<requestHeaders>false</requestHeaders>
|
||||||
|
<responseDataOnError>false</responseDataOnError>
|
||||||
|
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||||
|
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||||
|
<bytes>true</bytes>
|
||||||
|
<sentBytes>true</sentBytes>
|
||||||
|
<url>true</url>
|
||||||
|
<threadCounts>true</threadCounts>
|
||||||
|
<idleTime>true</idleTime>
|
||||||
|
<connectTime>true</connectTime>
|
||||||
|
</value>
|
||||||
|
</objProp>
|
||||||
|
<stringProp name="filename"></stringProp>
|
||||||
|
</ResultCollector>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
</hashTree>
|
||||||
|
</jmeterTestPlan>
|
||||||
Reference in New Issue
Block a user