diff --git a/.github/workflows/prod_ci.yml b/.github/workflows/prod_ci.yml new file mode 100644 index 0000000..da10e07 --- /dev/null +++ b/.github/workflows/prod_ci.yml @@ -0,0 +1,34 @@ +name: e2e prod test +on: + push: + branches: + - master + tags: + - v[0-9]+.[0-9]+.[0-9]+* + pull_request: + branches: + - master +jobs: + test: + name: Run tests and publish test coverage + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - name: Install dependencies + run: npm install + - name: Run tests + run: npm run env -- mocha --timeout 10000 --recursive --require babel-register test_prod/ + env: + API_KEY: ${{ secrets.API_KEY }} + API_SECRET: ${{ secrets.API_SECRET }} + PRODUCT_API_KEY: ${{ secrets.PRODUCT_API_KEY }} + PRODUCT_API_SECRET: ${{ secrets.PRODUCT_API_SECRET }} diff --git a/test_prod/product.js b/test_prod/product.js new file mode 100644 index 0000000..957e7aa --- /dev/null +++ b/test_prod/product.js @@ -0,0 +1,25 @@ +'use strict'; + +const Razorpay = require("../dist/razorpay"); +let request = require('request-promise'); + +class RazorpayBeta extends Razorpay { + constructor(options) { + super(options) + this.api.rq = request.defaults({ + baseUrl: options.hostUrl, + json: true, + auth: { + user: options.key_id, + pass: options.key_secret + } + }) + } +} + + +module.exports = new RazorpayBeta({ + key_id: process.env.PRODUCT_API_KEY || "", + key_secret: process.env.PRODUCT_API_SECRET || "", + hostUrl : "https://api-web.dev.razorpay.in" +}); diff --git a/test_prod/resources/dummy.pdf b/test_prod/resources/dummy.pdf new file mode 100644 index 0000000..774c2ea Binary files /dev/null and b/test_prod/resources/dummy.pdf differ diff --git a/test_prod/resources/product.spec.js b/test_prod/resources/product.spec.js new file mode 100644 index 0000000..a1b3052 --- /dev/null +++ b/test_prod/resources/product.spec.js @@ -0,0 +1,130 @@ +'use strict' + +var assert = require('assert'); +const rzpInstance = require('../product') +let productId = null; +let accountId = null; +let setAccount = { + "email": `gauriagain.kumar_${Math.floor(Date.now() / 1000)}@example.org`, + "phone": "9000090000", + "legal_business_name": "Acme Corp", + "business_type": "partnership", + "customer_facing_business_name": "Example", + "profile": { + "category": "healthcare", + "subcategory": "clinic", + "description": "Healthcare E-commerce platform", + "addresses": { + "operation": { + "street1": "507, Koramangala 6th block", + "street2": "Kormanagala", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": 560047, + "country": "IN" + }, + "registered": { + "street1": "507, Koramangala 1st block", + "street2": "MG Road", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": 560034, + "country": "IN" + } + }, + "business_model": "Online Clothing ( men, women, ethnic, modern ) fashion and lifestyle, accessories, t-shirt, shirt, track pant, shoes." + }, + "legal_info": { + "pan": "AAACL1234C", + "gst": "18AABCU9603R1ZM" + }, + "brand": { + "color": "FFFFFF" + }, + "notes": { + "internal_ref_id": "123123" + }, + "contact_name": "Gaurav Kumar", + "contact_info": { + "chargeback": { + "email": "cb@example.org" + }, + "refund": { + "email": "cb@example.org" + }, + "support": { + "email": "support@example.org", + "phone": "9999999998", + "policy_url": "https://www.google.com" + } + }, + "apps": { + "websites": [ + "https://www.example.org" + ], + "android": [ + { + "url": "playstore.example.org", + "name": "Example" + } + ], + "ios": [ + { + "url": "appstore.example.org", + "name": "Example" + } + ] + } +} + +describe('PRODUCT CONFIGURATION', () => { + + it('request a product configuration', (done) => { + + rzpInstance.accounts.create(setAccount) + .then((response) => { + accountId = response.id + console.log(`created account id: ${accountId}`) + return accountId + }) + .then((id) => { + rzpInstance.products.requestProductConfiguration(id, { + "product_name" : "payment_gateway", + "tnc_accepted" : true, + "ip" : "233.233.233.234" + }) + .then((response)=>{ + productId = response.id + assert.ok(response.hasOwnProperty('id')) + assert.ok(response.hasOwnProperty('account_id')) + done() + }).catch(err => console.log(err)) + }).catch(err => console.log(err)) + + }) + + it('fetch product by id', (done) => { + rzpInstance.products.fetch(accountId, productId).then((response) => { + assert.ok(response.hasOwnProperty('id')) + assert.ok((response.id === productId)) + done() + }).catch(err => console.log(err)) + }) + + it('fetch terms and conditions for a sub-merchant', (done) => { + rzpInstance.products.fetchTnc("payments").then((response) => { + assert.ok(response.hasOwnProperty('entity')) + assert.ok(response.hasOwnProperty('id')) + done() + }).catch(err => console.log(err)) + }) + + it('delete account', (done) => { + rzpInstance.accounts.delete(accountId).then((response) => { + console.log(`deleted account id: ${accountId}`) + assert.ok((response.id === accountId)) + assert.ok(response.hasOwnProperty('id')) + done() + }).catch(err => console.log(err)) + }) +}) diff --git a/test_prod/resources/stakeholder.spec.js b/test_prod/resources/stakeholder.spec.js new file mode 100644 index 0000000..62c79e3 --- /dev/null +++ b/test_prod/resources/stakeholder.spec.js @@ -0,0 +1,201 @@ +'use strict' + +var assert = require('assert'); +const rzpInstance = require('../product') +const path = require('path') +const fs = require('fs'); +const crpyto = require('crypto') +let skipDoc = true; + +let accountId = null; +let stakeholderId = null; + +let setAccount = { + "email": `gauriagain.${crpyto.randomBytes(4).toString('hex')}@example.org`, + "phone": "9000090000", + "legal_business_name": "Acme Corp", + "business_type": "partnership", + "customer_facing_business_name": "Example", + "profile": { + "category": "healthcare", + "subcategory": "clinic", + "description": "Healthcare E-commerce platform", + "addresses": { + "operation": { + "street1": "507, Koramangala 6th block", + "street2": "Kormanagala", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": 560047, + "country": "IN" + }, + "registered": { + "street1": "507, Koramangala 1st block", + "street2": "MG Road", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": 560034, + "country": "IN" + } + }, + "business_model": "Online Clothing ( men, women, ethnic, modern ) fashion and lifestyle, accessories, t-shirt, shirt, track pant, shoes." + }, + "legal_info": { + "pan": "AAACL1234C", + "gst": "18AABCU9603R1ZM" + }, + "brand": { + "color": "FFFFFF" + }, + "notes": { + "internal_ref_id": "123123" + }, + "contact_name": "Gaurav Kumar", + "contact_info": { + "chargeback": { + "email": "cb@example.org" + }, + "refund": { + "email": "cb@example.org" + }, + "support": { + "email": "support@example.org", + "phone": "9999999998", + "policy_url": "https://www.google.com" + } + }, + "apps": { + "websites": [ + "https://www.example.org" + ], + "android": [ + { + "url": "playstore.example.org", + "name": "Example" + } + ], + "ios": [ + { + "url": "appstore.example.org", + "name": "Example" + } + ] + } +} + +let SetStakeholder = { + "percentage_ownership": 10, + "name": "Gaurav Kumar", + "email": `gauriagain.${crpyto.randomBytes(4).toString('hex')}@example.org`, + "relationship": { + "director": true, + "executive": false + }, + "phone": { + "primary": "7474747474", + "secondary": "7474747474" + }, + "addresses": { + "residential": { + "street": "506, Koramangala 1st block", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": "560034", + "country": "IN" + } + }, + "kyc": { + "pan": "AVOPB1111K" + }, + "notes": { + "random_key_by_partner": "random_value" + } +} + +describe('STAKEHOLDERS', () => { + + it('create stakeholder account', (done) => { + + rzpInstance.accounts.create(setAccount) + .then((response) => { + accountId = response.id + console.log(`created account id: ${accountId}`) + return accountId + }) + .then((id) => { + console.log('created id',accountId) + rzpInstance.stakeholders.create(id, SetStakeholder) + .then((response)=>{ + stakeholderId = response.id + assert.ok(response.hasOwnProperty('id')) + assert.ok(response.hasOwnProperty('entity')) + done() + }).catch(err => console.log(err)) + }).catch(err => console.log(err)) + + }) + + it('fetch stakeholder by id', (done) => { + rzpInstance.stakeholders.fetch(accountId, stakeholderId).then((response) => { + assert.ok(response.hasOwnProperty('id')) + assert.ok((response.id === stakeholderId)) + done() + }).catch(err => console.log(err)) + }) + + it('fetch all stakeholders', (done) => { + rzpInstance.stakeholders.all(accountId).then((response) => { + assert.ok(response.hasOwnProperty('entity')) + assert.ok(response.hasOwnProperty('items')) + done() + }).catch(err => console.log(err)) + }) + + it('document upload', (done) => { + + rzpInstance.stakeholders.uploadStakeholderDoc(accountId, stakeholderId, { + 'file': { + 'value': fs.createReadStream(path.resolve(__dirname, `dummy.pdf`)), + 'options': { + 'filename': 'dummy.pdf', + 'contentType': null + } + }, + 'document_type': 'aadhar_front' + }) + .then(response => { + skipDoc = false + assert.ok(response.hasOwnProperty('individual_proof_of_address')) + done() + }).catch(err => { + if (err.hasOwnProperty('error')) { + if (err.error.reason == 'NA') { + console.warn('server issue') + done() + } + } + }) + + }) + + it('fetch stakeholder documents', (done) => { + rzpInstance.stakeholders.fetchStakeholderDoc(accountId, stakeholderId).then((response) => { + if (skipDoc) { + assert.ok((typeof response == 'object')) + } else { + assert.ok(response.hasOwnProperty('individual_proof_of_address')) + } + + done() + }).catch(err => console.log(err)) + }) + + it('delete account', (done) => { + rzpInstance.accounts.delete(accountId).then((response) => { + console.log(`deleted account id: ${accountId}`) + assert.ok((response.id === accountId)) + assert.ok(response.hasOwnProperty('id')) + done() + }).catch(err => console.log(err)) + }) +})