Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Add credential API tests [DEV-3238] #442

Merged
merged 19 commits into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 57 additions & 57 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,81 +4,81 @@ import { defineConfig, devices } from '@playwright/test';
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
// Directory where all tests are located
testDir: './tests',

// Start local dev server before starting the tests
webServer: {
command: 'npm run start',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},
// Shared settings for all the projects below.
// Docs: https://playwright.dev/docs/api/class-testoptions
use: {
// Base URL to use in actions like `await page.goto('/')`
baseURL: 'http://localhost:3000',

// Set whether to record traces
// Directory where all tests are located
testDir: './tests',

// Start local dev server before starting the tests
webServer: {
command: 'npm run start',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},

// Shared settings for all the projects below.
// Docs: https://playwright.dev/docs/api/class-testoptions
use: {
// Base URL to use in actions like `await page.goto('/')`
baseURL: 'http://localhost:3000',

// Set whether to record traces
// Docs: https://playwright.dev/docs/api/class-testoptions#test-options-trace
trace: 'retain-on-failure',

// Set whether to record screenshots
// Set whether to record screenshots
// Docs: https://playwright.dev/docs/api/class-testoptions#test-options-screenshot
screenshot: 'off',

// Set whether to record videos
// Set whether to record videos
// Docs: https://playwright.dev/docs/api/class-testoptions#test-options-video
video: 'off',
},
},

// Reporter to use for test results
// Reporter to use for test results
// Uses GitHub Actions reporter on CI, otherwise uses HTML reporter
// Docs: https://playwright.dev/docs/test-reporters
reporter: process.env.CI ? 'github' : 'html',

// Fail the build on CI if you accidentally left test.only in the source code
// Fail the build on CI if you accidentally left test.only in the source code
// Docs: https://playwright.dev/docs/api/class-testconfig#test-config-forbid-only
forbidOnly: !!process.env.CI,
// The maximum number of retry attempts given to failed tests
forbidOnly: !!process.env.CI,

// The maximum number of retry attempts given to failed tests
// Docs: https://playwright.dev/docs/api/class-testconfig#test-config-retries
retries: process.env.CI ? 2 : 0,
retries: process.env.CI ? 2 : 0,

// Whether to run tests in parallel
// Docs: https://playwright.dev/docs/api/class-testconfig#test-config-fully-parallel
fullyParallel: false,

// Whether to run tests in parallel
// Docs: https://playwright.dev/docs/api/class-testconfig#test-config-fully-parallel
fullyParallel: false,

// Number of parallel workers OR %age of logical CPUs to use
// Number of parallel workers OR %age of logical CPUs to use
// Github Actions runners have 2 logical CPU cores
// Defaults to half of the logical CPU cores available
// Defaults to half of the logical CPU cores available
// Docs: https://playwright.dev/docs/api/class-testconfig#test-config-workers
workers: process.env.CI ? 2 : undefined,

// Limit the numbers of failures to set a fail-fast strategy on CI
// Docs: https://playwright.dev/docs/api/class-testconfig#test-config-max-failures
maxFailures: process.env.CI ? 5 : undefined,

// Configure project specific settings
// Docs: https://playwright.dev/docs/test-projects
projects: [
{
name: 'setup',
testMatch: /.*\.setup\.ts/
},
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
// Use prepared auth state.
storageState: 'playwright/.auth/user.json',
},
dependencies: ['setup'],
},
],

// Timeout for each test in milliseconds
workers: process.env.CI ? 1 : undefined,

// Limit the numbers of failures to set a fail-fast strategy on CI
// Docs: https://playwright.dev/docs/api/class-testconfig#test-config-max-failures
maxFailures: process.env.CI ? 5 : undefined,

// Configure project specific settings
// Docs: https://playwright.dev/docs/test-projects
projects: [
{
name: 'setup',
testMatch: /.*\.setup\.ts/,
},
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
// Use prepared auth state.
storageState: 'playwright/.auth/user.json',
},
dependencies: ['setup'],
},
],

// Timeout for each test in milliseconds
// Docs: https://playwright.dev/docs/test-timeouts
timeout: 60 * 1000,

Expand Down
2 changes: 1 addition & 1 deletion src/static/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1495,7 +1495,7 @@
"type": "string",
"enum": [
"jwt",
"lds"
"jsonld"
],
"example": "jwt"
},
Expand Down
2 changes: 1 addition & 1 deletion src/types/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export type CheckStatusListUnsuccessfulResponseBody = {
export type VerifyPresentationResponseBody = {
verified: false;
error: string;
}
};

export type SearchStatusListQuery = {
did: string;
Expand Down
2 changes: 1 addition & 1 deletion src/types/swagger-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
* type: string
* enum:
* - jwt
* - lds
* - jsonld
* example: jwt
* credentialStatus:
* description: Optional `credentialStatus` properties for VC revocation or suspension. Takes `statusListName` and `statusListPurpose` as inputs.
Expand Down
82 changes: 82 additions & 0 deletions tests/credential/issue-verify-flow.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import type { VerifiableCredential } from '@veramo/core';

import { test, expect } from '@playwright/test';
import { StatusCodes } from 'http-status-codes';
import * as fs from 'fs';

test.use({ storageState: 'playwright/.auth/user.json' });

const PAYLOADS_BASE_PATH = './tests/payloads/credential';

let jwtCredential: VerifiableCredential, jsonldCredential: VerifiableCredential;

test(' Issue a jwt credential', async ({ request }) => {
const credentialData = JSON.parse(fs.readFileSync(`${PAYLOADS_BASE_PATH}/credential-issue-jwt.json`, 'utf-8'));
const response = await request.post(`/credential/issue`, {
data: JSON.stringify(credentialData),
headers: {
'Content-Type': 'application/json',
},
});
jwtCredential = await response.json();
expect(response).toBeOK();
expect(response.status()).toBe(StatusCodes.OK);
expect(jwtCredential.proof.type).toBe('JwtProof2020');
});

test(' Verify a jwt credential', async ({ request }) => {
const response = await request.post(`/credential/verify`, {
data: JSON.stringify({
credential: jwtCredential.proof.jwt,
}),
headers: {
'Content-Type': 'application/json',
},
});
const result = await response.json();
expect(response).toBeOK();
expect(response.status()).toBe(StatusCodes.OK);
expect(result.verified).toBe(true);
});

test(' Issue a jwt credential with a deactivated DID', async ({ request }) => {
const credentialData = JSON.parse(fs.readFileSync(`${PAYLOADS_BASE_PATH}/credential-issue-jwt.json`, 'utf-8'));
credentialData.issuerDid = 'did:cheqd:testnet:edce6dfb-b59c-493b-a4b8-1d16a6184349';
const response = await request.post(`/credential/issue`, {
data: JSON.stringify(credentialData),
headers: {
'Content-Type': 'application/json',
},
});
expect(response.status()).toBe(StatusCodes.BAD_REQUEST);
});

test(' Issue a jsonLD credential', async ({ request }) => {
const credentialData = JSON.parse(fs.readFileSync(`${PAYLOADS_BASE_PATH}/credential-issue-jsonld.json`, 'utf-8'));
const response = await request.post(`/credential/issue`, {
data: JSON.stringify(credentialData),
headers: {
'Content-Type': 'application/json',
},
});
jsonldCredential = await response.json();
expect(response).toBeOK();
expect(response.status()).toBe(StatusCodes.OK);
expect(jsonldCredential.proof.type).toBe('Ed25519Signature2018');
});

test(' Verify a jsonld credential', async ({ request }) => {
const response = await request.post(`/credential/verify`, {
data: JSON.stringify({
credential: jsonldCredential,
fetchRemoteContexts: true,
}),
headers: {
'Content-Type': 'application/json',
},
});
const result = await response.json();
expect(response).toBeOK();
expect(response.status()).toBe(StatusCodes.OK);
expect(result.verified).toBe(true);
});
73 changes: 73 additions & 0 deletions tests/credential/revocation-flow.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import type { VerifiableCredential } from '@veramo/core';

import { test, expect } from '@playwright/test';
import { StatusCodes } from 'http-status-codes';
import * as fs from 'fs';

test.use({ storageState: 'playwright/.auth/user.json' });

const PAYLOADS_BASE_PATH = './tests/payloads/credential';

let jwtCredential: VerifiableCredential;

test(' Issue a jwt credential with revocation statuslist', async ({ request }) => {
const credentialData = JSON.parse(
fs.readFileSync(`${PAYLOADS_BASE_PATH}/credential-issue-jwt-revocation.json`, 'utf-8')
);
const response = await request.post(`/credential/issue`, {
data: JSON.stringify(credentialData),
headers: {
'Content-Type': 'application/json',
},
});
jwtCredential = await response.json();
expect(response).toBeOK();
expect(response.status()).toBe(StatusCodes.OK);
expect(jwtCredential.proof.type).toBe('JwtProof2020');
});

test(" Verify a credential's revocation status", async ({ request }) => {
const response = await request.post(`/credential/verify?verifyStatus=true`, {
data: JSON.stringify({
credential: jwtCredential,
}),
headers: {
'Content-Type': 'application/json',
},
});
const result = await response.json();
expect(response).toBeOK();
expect(response.status()).toBe(StatusCodes.OK);
expect(result.verified).toBe(true);
expect(result.revoked).toBe(false);
});

test(' Verify a credential status after revocation', async ({ request }) => {
const response = await request.post(`/credential/revoke?publish=true`, {
data: JSON.stringify({
credential: jwtCredential,
}),
headers: {
'Content-Type': 'application/json',
},
});
const result = await response.json();
expect(response).toBeOK();
expect(response.status()).toBe(StatusCodes.OK);
expect(result.revoked).toBe(true);
expect(result.published).toBe(true);

const verificationResponse = await request.post(`/credential/verify?verifyStatus=true`, {
data: JSON.stringify({
credential: jwtCredential,
}),
headers: {
'Content-Type': 'application/json',
},
});
const verificationResult = await verificationResponse.json();
expect(verificationResponse).toBeOK();
expect(verificationResponse.status()).toBe(StatusCodes.OK);
expect(verificationResult.verified).toBe(true);
expect(verificationResult.revoked).toBe(true);
});
Loading
Loading