Skip to content

Commit

Permalink
[Feature] Add support for General Supply Documentation MRV submission (
Browse files Browse the repository at this point in the history
…#19)

* Add support for General Supply Documentation

* Add full tests for General Supply Documentation MRV

* Renam file

* Use KGs for the test mint

* Add validation for KGs in the General Supply Documentation MRV

* OCD
  • Loading branch information
justynspooner authored Feb 14, 2023
1 parent d8de0fb commit 7b81880
Show file tree
Hide file tree
Showing 9 changed files with 451 additions and 4 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
TEST_AUTH_URL: ${{ secrets.TEST_AUTH_URL }}
TEST_COOL_FARM_POLICY_ID: ${{ secrets.TEST_COOL_FARM_POLICY_ID }}
TEST_AGRECALC_POLICY_ID: ${{ secrets.TEST_AGRECALC_POLICY_ID }}
TEST_GENERAL_SUPPLY_DOCUMENTATION_POLICY_ID: ${{ secrets.TEST_GENERAL_SUPPLY_DOCUMENTATION_POLICY_ID }}

steps:
- uses: actions/checkout@v2
Expand Down
286 changes: 286 additions & 0 deletions __tests__/e2e/fullGeneralSupplyDocumentationPolicy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
import StatusCode from 'src/constants/status'
import hmacAxios from 'src/apiClient/hmacApiClient'
import config from 'src/config'

const SECONDS = 1000
const TEN_SECONDS = 10 * SECONDS
const ONE_MINUTE = 60 * SECONDS

const loginResponseData = async (username, password) => {
const data = { username, password }

const response = await hmacAxios.post(
`${config.apiUrl}/api/accounts/login`,
data
)

return response.data.data
}

describe('Test General Supply Documentation policy flow', () => {
const isoDate = new Date().toISOString()
const registrant = `ci_registrant_${isoDate}`
const verifier = `ci_verifier_${isoDate}`
const password = 'secret'
const policyId = config.testGeneralSupplyDocumentationPolicyId
const { registryUsername, registryPassword } = config

it('should have the correct environment variables', () => {
const {
apiUrl,
testGeneralSupplyDocumentationPolicyId,
hmacAuthKey,
hmacEnabled,
network,
registryUsername,
registryPassword,
guardianApiUrl,
} = config

expect(apiUrl).toBeDefined()
expect(testGeneralSupplyDocumentationPolicyId).toBeDefined()
expect(hmacAuthKey).toBeDefined()
expect(hmacEnabled).toBeDefined()
expect(network).toBeDefined()
expect(registryUsername).toBeDefined()
expect(registryPassword).toBeDefined()
expect(guardianApiUrl).toBeDefined()
})
it(
'creates a new registrant account',
async () => {
const data = { username: registrant, password }

const response = await hmacAxios.post(
`${config.apiUrl}/api/accounts`,
data
)

expect(response.status).toBe(StatusCode.OK)
},
ONE_MINUTE
)
it(
'creates a new verifier account',
async () => {
const data = { username: verifier, password }

const response = await hmacAxios.post(
`${config.apiUrl}/api/accounts`,
data
)

expect(response.status).toBe(StatusCode.OK)
},
ONE_MINUTE
)
it(
'assigns the policy REGISTRANT role to the registrant account',
async () => {
const { accessToken } = await loginResponseData(
registrant,
password
)

const response = await hmacAxios.post(
`${config.apiUrl}/api/policies/${policyId}/role/registrant`,
{},
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
)

expect(response.status).toBe(StatusCode.OK)
},
ONE_MINUTE
)
it(
'assigns the policy VERIFIER role to the verifier account',
async () => {
const { accessToken } = await loginResponseData(verifier, password)

const response = await hmacAxios.post(
`${config.apiUrl}/api/policies/${policyId}/role/verifier`,
{},
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
)

expect(response.status).toBe(StatusCode.OK)
},
ONE_MINUTE
)
it(
'submits a new application',
async () => {
const { accessToken } = await loginResponseData(
registrant,
password
)

const data = {
field0: `Matt Farm ${isoDate}`,
field1: 'Paignton',
field2: 420,
field3: 'Fancy Soil',
field4: 'A Cat',
field5: 'We grow grass',
field6: 'No we do not',
field7: 'No, we do not...',
field8: 'No',
}

const response = await hmacAxios.post(
`${config.apiUrl}/api/policies/${policyId}/register`,
data,
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
)
expect(response.status).toBe(StatusCode.OK)
},
ONE_MINUTE
)
it(
'approves the application',
async () => {
await new Promise((r) => setTimeout(r, TEN_SECONDS))
const { did } = await loginResponseData(registrant, password)
const { accessToken } = await loginResponseData(
registryUsername,
registryPassword
)

const response = await hmacAxios.put(
`${config.apiUrl}/api/policies/${policyId}/approve/application/${did}`,
{},
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
)
expect(response.status).toBe(StatusCode.OK)
},
ONE_MINUTE
)
it(
'submits an ecological project',
async () => {
await new Promise((r) => setTimeout(r, TEN_SECONDS))
const { accessToken } = await loginResponseData(
registrant,
password
)

const data = {
field0: '1234',
field1: `Matt's Farm ${isoDate}`,
field2: "This is a description about Matt's farm",
field3: 'Matt Smithies',
field4: 'Ecological Project Info - Link to Project Data',
field5: 'Ecological Project Info - Country: The host country for the project',
field6: 'Ecological Project Info - Project Scale: One from the list of - Micro, Small, Medium, or Large',
field7: 'Modular Benefit Project - Unique identifier ',
field8: 'Modular Benefit Project - Geographic Location',
field9: 'Modular Benefit Project - Targeted Benefit Type',
field10: 'Modular Benefit Project - Developer(s)',
field11: 'Modular Benefit Project - Sponsor(s)',
field12: 'Modular Benefit Project - Claim Tokens',
}

const response = await hmacAxios.post(
`${config.apiUrl}/api/policies/${policyId}/project`,
data,
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
)
expect(response.status).toBe(StatusCode.OK)
},
ONE_MINUTE
)
it(
'approves the ecological project',
async () => {
await new Promise((r) => setTimeout(r, TEN_SECONDS))
const { did } = await loginResponseData(registrant, password)
const { accessToken } = await loginResponseData(
registryUsername,
registryPassword
)

const response = await hmacAxios.put(
`${config.apiUrl}/api/policies/${policyId}/approve/project/${did}`,
{},
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
)
expect(response.status).toBe(StatusCode.OK)
},
ONE_MINUTE
)
it(
'submits an MRV request',
async () => {
await new Promise((r) => setTimeout(r, TEN_SECONDS))
const { accessToken } = await loginResponseData(
registrant,
password
)

const data = {
field0: `Field 0 ${isoDate}`,
field1: 'Field 1',
field2: 'Field 2',
field3: '10000',
field4: 'Field 4',
}

const response = await hmacAxios.post(
`${config.apiUrl}/api/policies/${policyId}/mrv/general-supply-documentation`,
data,
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
)

expect(response.status).toBe(StatusCode.OK)
},
ONE_MINUTE
)
it(
'approves the MRV request',
async () => {
await new Promise((r) => setTimeout(r, TEN_SECONDS))
const { did } = await loginResponseData(registrant, password)
const { accessToken } = await loginResponseData(verifier, password)

const response = await hmacAxios.put(
`${config.apiUrl}/api/policies/${policyId}/approve/mrv/${did}`,
{},
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
)
expect(response.status).toBe(StatusCode.OK)
},
ONE_MINUTE
)
})
78 changes: 78 additions & 0 deletions __tests__/unit/validators/validateMrvDocumentSubmission.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { MRV } from 'src/config/guardianTags'
import validate from 'src/validators/validateMrvDocumentSubmission'

describe(`Validate Measurement Reporting Verification Document Submission`, () => {
describe('General Supply Documentation', () => {
it(`should return an error if the payload is not complete`, () => {
const payload = {
field0: 'field0',
field1: 'field1',
field2: 'field2',
field3: '1000',
field4: 'field4',
}

const result = validate('BAD_TYPE', payload)

expect(result).toEqual([
`The policy can only process MRV types of "${MRV.AGRECALC}", "${MRV.COOL_FARM_TOOL}" or "${MRV.GENERAL_SUPPLY_DOCUMENTATION}". Please update your request.`,
])
})
it(`should return no errors if the payload is complete`, () => {
const payload = {
field0: 'field0',
field1: 'field1',
field2: 'field2',
field3: '1000',
field4: 'field4',
}

const result = validate(MRV.GENERAL_SUPPLY_DOCUMENTATION, payload)

expect(result).toEqual(null)
})
it(`should return error if KGs are not divisible by 1000`, () => {
const payload = {
field0: 'field0',
field1: 'field1',
field2: 'field2',
field3: '1500',
field4: 'field4',
}

const result = validate(MRV.GENERAL_SUPPLY_DOCUMENTATION, payload)

expect(result).toEqual([
'Must be a string representing a positive integer divisible by 1,000',
])
})
it(`should return error if KGs are a fraction`, () => {
const payload = {
field0: 'field0',
field1: 'field1',
field2: 'field2',
field3: '1000.1000',
field4: 'field4',
}

const result = validate(MRV.GENERAL_SUPPLY_DOCUMENTATION, payload)

expect(result).toEqual([
'Must be a string representing a positive integer divisible by 1,000',
])
})
it(`should return error if KGs are empty`, () => {
const payload = {
field0: 'field0',
field1: 'field1',
field2: 'field2',
field3: '',
field4: 'field4',
}

const result = validate(MRV.GENERAL_SUPPLY_DOCUMENTATION, payload)

expect(result).toEqual(['"field3" is not allowed to be empty'])
})
})
})
3 changes: 2 additions & 1 deletion env.example
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ PUBLIC_TRUST_CHAIN_ACCESS=TRUE

# These are used for end to end tests of the API. Make sure to add these to your .env.test.local file
TEST_COOL_FARM_POLICY_ID=62f2365b7fe3fa7b888e846d
TEST_AGRECALC_POLICY_ID=62f27a007fe3fa7b888e8496
TEST_AGRECALC_POLICY_ID=62f27a007fe3fa7b888e8496
TEST_GENERAL_SUPPLY_DOCUMENTATION_POLICY_ID=62f27a007fe3fa7b888e8497
1 change: 1 addition & 0 deletions src/config/guardianTags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,5 @@ export enum Role {
export enum MRV {
AGRECALC = 'agrecalc',
COOL_FARM_TOOL = 'cool-farm-tool',
GENERAL_SUPPLY_DOCUMENTATION = 'general-supply-documentation',
}
Loading

0 comments on commit 7b81880

Please sign in to comment.