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

Boosted http-client code coverage to 100% + minor updates #234

Merged
merged 3 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions packages/http-client/.c8rc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
],
"reporter": [
"cobertura",
"html",
"text"
]
}
14 changes: 7 additions & 7 deletions packages/http-client/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export class TbdexHttpClient {
throw new RequestError({ message: `Failed to get offerings from ${pfiDid}`, recipientDid: pfiDid, url: apiRoute, cause: e })
}

const data: Offering[] = []
const offerings: Offering[] = []

if (!response.ok) {
const errorDetails = await response.json() as ErrorDetail[]
Expand All @@ -159,10 +159,10 @@ export class TbdexHttpClient {
const jsonOfferings = responseBody.data as any[]
for (let jsonOffering of jsonOfferings) {
const offering = await Offering.parse(jsonOffering)
data.push(offering)
offerings.push(offering)
}

return data
return offerings
}

/**
Expand Down Expand Up @@ -221,7 +221,7 @@ export class TbdexHttpClient {
throw new RequestError({ message: `Failed to get exchange from ${pfiDid}`, recipientDid: pfiDid, url: apiRoute, cause: e })
}

const data: Message[] = []
const messages: Message[] = []

if (!response.ok) {
const errorDetails = await response.json() as ErrorDetail[]
Expand All @@ -231,17 +231,17 @@ export class TbdexHttpClient {
const responseBody = await response.json() as { data: MessageModel[] }
for (let jsonMessage of responseBody.data) {
const message = await Parser.parseMessage(jsonMessage)
data.push(message)
messages.push(message)
}

return data
return messages

}

// TODO: Wrap Message[] in Exchange object and verify each message
/**
* returns all exchanges created by requester
* @param _opts - options
* @param opts - options
*/
static async getExchanges(opts: GetExchangesOptions): Promise<Message[][]> {
const { pfiDid, filter, did } = opts
Expand Down
2 changes: 0 additions & 2 deletions packages/http-client/src/errors/request-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,5 @@ export class RequestError extends Error {
this.name = this.constructor.name
this.recipientDid = params.recipientDid
this.url = params.url

Object.setPrototypeOf(this, RequestError.prototype)
}
}
42 changes: 5 additions & 37 deletions packages/http-client/src/errors/request-token-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,67 +18,35 @@ export class RequestTokenError extends Error {
super(params.message, { cause: params.cause })

this.name = this.constructor.name

Object.setPrototypeOf(this, RequestTokenError.prototype)
}
}

/**
* Error thrown when a request token cannot be signed
* @beta
*/
export class RequestTokenSigningError extends RequestTokenError {
constructor(params: RequestTokenErrorParams) {
super(params)

Object.setPrototypeOf(this, RequestTokenSigningError.prototype)
}
}
export class RequestTokenSigningError extends RequestTokenError { }

/**
* Error thrown when a request token cannot be verified
* @beta
*/
export class RequestTokenVerificationError extends RequestTokenError {
constructor(params: RequestTokenErrorParams) {
super(params)

Object.setPrototypeOf(this, RequestTokenVerificationError.prototype)
}
}
export class RequestTokenVerificationError extends RequestTokenError { }

/**
* Error thrown when a request token is missing required claims
* @beta
*/
export class RequestTokenMissingClaimsError extends RequestTokenError {
constructor(params: RequestTokenErrorParams) {
super(params)

Object.setPrototypeOf(this, RequestTokenMissingClaimsError.prototype)
}
}
export class RequestTokenMissingClaimsError extends RequestTokenError { }

/**
* Error thrown when a request token aud does not match the PFI did for which its intended
* @beta
*/
export class RequestTokenAudienceMismatchError extends RequestTokenError {
constructor(params: RequestTokenErrorParams) {
super(params)

Object.setPrototypeOf(this, RequestTokenAudienceMismatchError.prototype)
}
}
export class RequestTokenAudienceMismatchError extends RequestTokenError { }

/**
* Error thrown when a request token payload iss does not match request token header kid
* @beta
*/
export class RequestTokenIssuerSignerMismatchError extends RequestTokenError {
constructor(params: RequestTokenErrorParams) {
super(params)

Object.setPrototypeOf(this, RequestTokenIssuerSignerMismatchError.prototype)
}
}
export class RequestTokenIssuerSignerMismatchError extends RequestTokenError { }
2 changes: 0 additions & 2 deletions packages/http-client/src/errors/response-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,5 @@ export class ResponseError extends Error {
this.details = params.details
this.recipientDid = params.recipientDid
this.url = params.url

Object.setPrototypeOf(this, ResponseError.prototype)
}
}
18 changes: 2 additions & 16 deletions packages/http-client/src/errors/validation-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,17 @@ export class ValidationError extends Error {
super(message)

this.name = this.constructor.name

Object.setPrototypeOf(this, ValidationError.prototype)
}
}

/**
* Error thrown when a DID is invalid
* @beta
*/
export class InvalidDidError extends ValidationError {
constructor(message: string) {
super(message)

Object.setPrototypeOf(this, InvalidDidError.prototype)
}
}
export class InvalidDidError extends ValidationError { }

/**
* Error thrown when a PFI's service endpoint can't be found
* @beta
*/
export class MissingServiceEndpointError extends ValidationError {
constructor(message: string) {
super(message)

Object.setPrototypeOf(this, MissingServiceEndpointError.prototype)
}
}
export class MissingServiceEndpointError extends ValidationError { }
44 changes: 34 additions & 10 deletions packages/http-client/tests/client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
RequestTokenSigningError,
RequestTokenIssuerSignerMismatchError
} from '../src/errors/index.js'
import { DevTools } from '@tbdex/protocol'
import { DevTools, Offering } from '@tbdex/protocol'
import * as sinon from 'sinon'
import { JwtHeaderParams, JwtPayload } from '@web5/crypto'
import { Convert } from '@web5/common'
Expand Down Expand Up @@ -326,13 +326,17 @@ describe('client', () => {
})

it('returns offerings array if response is ok', async () => {
const pfiDid = await DidJwk.create()
const stubbedOffering = DevTools.createOffering({ from: pfiDid.uri })
await stubbedOffering.sign(pfiDid)
const stubbedOfferings = [stubbedOffering.toJSON()]
fetchStub.resolves({
ok : true,
json : () => Promise.resolve({ data: [] })
json : () => Promise.resolve({ data: stubbedOfferings })
} as Response)

const offerings = await TbdexHttpClient.getOfferings({ pfiDid: pfiDid.uri })
expect(offerings).to.have.length(0)
expect(offerings).to.have.length(1)
})
})

Expand Down Expand Up @@ -426,13 +430,17 @@ describe('client', () => {
})

it('returns exchange array if response is ok', async () => {
const alice = await DidJwk.create()
const stubbedRfq = await DevTools.createRfq({ sender: alice })
await stubbedRfq.sign(alice)
const messages = [stubbedRfq.toJSON()]
fetchStub.resolves({
ok : true,
json : () => Promise.resolve({ data: [] })
json : () => Promise.resolve({ data: messages })
} as Response)

const exchanges = await TbdexHttpClient.getExchange({ pfiDid: pfiDid.uri, exchangeId: '123', did: pfiDid })
expect(exchanges).to.have.length(0)
expect(exchanges).to.have.length(1)
})
})

Expand Down Expand Up @@ -475,14 +483,30 @@ describe('client', () => {
}
})

it('returns empty exchanges array if response is ok and body is empty array', async () => {

it('returns array of message exchanges given a list of exchange IDs', async () => {
const alice = await DidJwk.create()
const aliceRfq = await DevTools.createRfq({ sender: alice })
await aliceRfq.sign(alice)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const aliceRfq = await DevTools.createRfq({ sender: alice })
await aliceRfq.sign(alice)
const aliceRfq1 = await DevTools.createRfq({ sender: alice })
await aliceRfq1.sign(alice)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


const bob = await DidJwk.create()
const bobRfq = await DevTools.createRfq({ sender: bob })
await bobRfq.sign(bob)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe what would make more sense naming wise is to say aliceRfq1 and aliceRfq2, since the GET /exchanges call would be returning all exchanges for a given did? so maybe something like

Suggested change
const bob = await DidJwk.create()
const bobRfq = await DevTools.createRfq({ sender: bob })
await bobRfq.sign(bob)
const aliceRfq2 = await DevTools.createRfq({ sender: alice })
await aliceRfq2.sign(alice)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks @jiyoontbd for the knowledge, makes sense, didn't realize the did property was meant to be for the caller, I've updated that too, let me know if I misunderstood again!


fetchStub.resolves({
ok : true,
json : () => Promise.resolve({ data: [] })
json : () => Promise.resolve({ data: [
[aliceRfq.toJSON()],
[bobRfq.toJSON()]
] })
} as Response)

const exchanges = await TbdexHttpClient.getExchanges({ pfiDid: pfiDid.uri, did: pfiDid })
expect(exchanges).to.have.length(0)
const exchanges = await TbdexHttpClient.getExchanges({
pfiDid: pfiDid.uri,
did: pfiDid,
filter: { id: [aliceRfq.metadata.id, bobRfq.metadata.id]}
})
expect(exchanges).to.have.length(2)
})
})

Expand Down Expand Up @@ -571,7 +595,7 @@ describe('client', () => {
aud : pfiBearerDid.uri,
iss : aliceBearerDid.uri,
exp : Math.floor(Date.now() / 1000 + 60),
jti : 'randomnonce'
jti : 'random-nonce'
}
})

Expand Down
16 changes: 16 additions & 0 deletions packages/http-client/tests/error.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { expect } from 'chai'
import {
RequestTokenMissingClaimsError,
RequestTokenSigningError,
RequestTokenError
} from '../src/main.js'

describe('Custom error class', () => {
it('has expected inheritance prototype chain', async () => {
const error = new RequestTokenSigningError({ message: 'any message' })
expect(error).to.be.instanceOf(Error)
expect(error).to.be.instanceOf(RequestTokenError)
expect(error).to.be.instanceOf(RequestTokenSigningError)
expect(error).to.not.be.instanceOf(RequestTokenMissingClaimsError)
})
})
1 change: 1 addition & 0 deletions packages/http-server/.c8rc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
],
"reporter": [
"cobertura",
"html",
"text"
]
}
2 changes: 0 additions & 2 deletions packages/http-server/src/callback-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,5 @@ export class CallbackError extends Error {
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor)
}

Object.setPrototypeOf(this, CallbackError.prototype)
}
}
1 change: 1 addition & 0 deletions packages/protocol/.c8rc.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
],
"reporter": [
"cobertura",
"html",
"text"
]
}
Loading