create consent request service

This commit is contained in:
Nemo Godebski-Pedersen 2025-03-10 17:53:47 +00:00
parent f8b313a130
commit 01090f85b4
3 changed files with 107 additions and 19 deletions

View File

@ -1,12 +1,12 @@
import { Service } from 'typedi'
import { Configuration, ConsentApi} from 'obp-api-typescript'
import { Configuration, ConsentApi, ConsumerConsentrequestsBody, InlineResponse20151} from 'obp-api-typescript'
import OBPClientService from './OBPClientService'
import { AxiosResponse } from 'axios'
@Service()
export default class OBPConsentsService {
private consentApiConfig: Configuration
public obpClientService: OBPClientService
public consentsClient: ConsentApi // This needs to be changed once we migrate away from the old OBP SDK
public obpClientService: OBPClientService // This needs to be changed once we migrate away from the old OBP SDK
constructor() {
this.obpClientService = new OBPClientService()
}
@ -19,9 +19,12 @@ export default class OBPConsentsService {
* @param as_client
* @returns
*/
async createConsentClient(path: string, method: string, as_consumer: "logged_in_user" | "API_Explorer"): Promise<ConsentApi | undefined> {
async createConsentClient(as_consumer: "logged_in_user" | "API_Explorer", path?: string, method?: string): Promise<ConsentApi | undefined> {
// This function creates a Consents API client as the logged in user, using their OAuth1 headers
if (as_consumer === "logged_in_user") {
if (!path || !method) {
throw new Error("Path and method are required when creating a Consents API client for a logged in user")
}
try {
// Get the OAuth1 headers for the logged in user to use in the API call
@ -34,8 +37,7 @@ export default class OBPConsentsService {
})
// Create the Consents API client
this.consentsClient = new ConsentApi(this.consentApiConfig)
return this.consentsClient
return new ConsentApi(this.consentApiConfig)
} catch (error) {
console.error(error)
@ -54,8 +56,7 @@ export default class OBPConsentsService {
accessToken: directLoginHeader
})
this.consentsClient = new ConsentApi(this.consentApiConfig)
return this.consentsClient
return new ConsentApi(this.consentApiConfig)
} catch (error) {
console.error(error)
@ -67,7 +68,36 @@ export default class OBPConsentsService {
}
async createConsentRequest(): Promise<any> {
async createConsentRequest(): Promise<InlineResponse20151 | undefined> {
// this should be done as API Explorer II, so set client on instance for that
const client = await this.createConsentClient('API_Explorer')
if (!client) {
throw new Error('Could not create Consents API client')
}
// Create a consent request
// Parameters in body to be changed later to fit our needs, or match parameters given to this function
try {
const consentRequestResponse = await client.oBPv500CreateConsentRequest(
{
accountAccess: [],
everything: false,
entitlements: [],
consumerId: '',
} as unknown as ConsumerConsentrequestsBody,
{
headers: {
'Content-Type': 'application/json',
},
}
)
return consentRequestResponse.data
} catch (error) {
console.error(error)
throw new Error(`Could not create consent request, ${error}`)
}
}
}

View File

@ -1,5 +1,6 @@
import {describe, beforeAll, it, vi, Mock } from 'vitest'
import { ConsentApi } from 'obp-api-typescript'
import {describe, beforeAll, it, vi, Mock, MockInstance } from 'vitest'
import { ConsentApi, InlineResponse20151 } from 'obp-api-typescript'
import { AxiosResponse } from 'axios'
const mockGetOAuthHeader = vi.fn(async () => (`OAuth oauth_consumer_key="jgaawf2fnj4yixqdsfaq4gipt4v1wvgsxgre",oauth_nonce="JiGDBWA3MAyKtsd9qkfWCxfju36bMjsA",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1741364123",oauth_version="1.0",oauth_signature="sa%2FRylnsdfLK8VPZI%2F2WkGFlTKs%3D"`));
const mockGetDirectLoginToken = vi.fn(async () => {
@ -20,6 +21,7 @@ vi.mock('../services/OBPClientService', () => {
})
import OBPConsentsService from '../services/OBPConsentsService';
import { before } from 'node:test';
describe('OBPConsentsService.createConsentClient', () => {
let obpConsentsService: OBPConsentsService;
@ -35,21 +37,19 @@ describe('OBPConsentsService.createConsentClient', () => {
});
it('should return a ConsentApi client for logged in user', async () => {
const consentClient = await obpConsentsService.createConsentClient('/consents', 'POST', 'logged_in_user');
const consentClient = await obpConsentsService.createConsentClient('logged_in_user', '/consents', 'POST');
expect(consentClient).toBeDefined();
expect(obpConsentsService.consentsClient).toBe(consentClient);
expect(consentClient).toBeInstanceOf(ConsentApi);
})
it('should return a ConsentApi client for API Explorer', async () => {
const consentClient = await obpConsentsService.createConsentClient('/consents', 'POST', 'API_Explorer');
const consentClient = await obpConsentsService.createConsentClient('API_Explorer');
expect(consentClient).toBeDefined();
expect(obpConsentsService.consentsClient).toBe(consentClient);
expect(consentClient).toBeInstanceOf(ConsentApi);
})
it('should throw an error if the client type is not recognized', async () => {
await expect(obpConsentsService.createConsentClient('/consents', 'POST', 'unknown')).rejects.toThrow();
await expect(obpConsentsService.createConsentClient('unknown', '/consents', 'POST')).rejects.toThrow();
})
it('should throw correct error if OBPClientService.getOAuthHeader fails for logged in user', async () => {
@ -58,7 +58,7 @@ describe('OBPConsentsService.createConsentClient', () => {
throw new Error('OAuth header error');
});
await expect(obpConsentsService.createConsentClient('/consents', 'POST', 'logged_in_user'))
await expect(obpConsentsService.createConsentClient('logged_in_user', '/consents', 'POST'))
.rejects.toThrow(`Could not create Consents API client for logged in user, Error: OAuth header error`);
})
@ -68,7 +68,64 @@ describe('OBPConsentsService.createConsentClient', () => {
throw new Error('Direct login token error');
});
await expect(obpConsentsService.createConsentClient('/consents', 'POST', 'API_Explorer'))
await expect(obpConsentsService.createConsentClient('API_Explorer', '/consents', 'POST'))
.rejects.toThrow(`Could not create Consents API client for API Explorer, Error: Direct login token error`);
})
})
it('should throw an error if as_consumer is logged_in_user and path or method is missing', async () => {
await expect(obpConsentsService.createConsentClient('logged_in_user'))
.rejects.toThrow('Path and method are required when creating a Consents API client for a logged in user');
})
})
describe('OBPConsentsService.createConsentRequest', () => {
let obpConsentsService: OBPConsentsService;
let mockOBPv500CreateConsentRequest: Mock
let mockConsentApi: ConsentApi;
beforeEach(() => {
// reset mocks
vi.clearAllMocks();
// Create mock response function
mockOBPv500CreateConsentRequest = vi.fn().mockResolvedValue({
data: {
consent_request_id: '12345678',
payload: {},
consumer_id: '87654321',
},
} as AxiosResponse<InlineResponse20151>);
mockConsentApi = {
oBPv500CreateConsentRequest: mockOBPv500CreateConsentRequest,
} as unknown as ConsentApi;
// Create service instance
obpConsentsService = new OBPConsentsService();
// Mock the createConsentClient method
vi.spyOn(obpConsentsService, 'createConsentClient').mockResolvedValue(mockConsentApi);
})
it('should call the createConsentClient method as the API_Explorer user', async () => {
//
await obpConsentsService.createConsentRequest();
expect(obpConsentsService.createConsentClient).toHaveBeenCalledWith('API_Explorer');
});
it('should return a consent request response object with valid fields', async () => {
// Call the method
const consentRequest = await obpConsentsService.createConsentRequest();
console.log('Response: ', consentRequest);
// Verify the result
expect(consentRequest).toBeDefined();
expect(consentRequest).toHaveProperty('consent_request_id', '12345678');
expect(consentRequest).toHaveProperty('consumer_id', '87654321');
expect(consentRequest).toHaveProperty('payload');
// Verify the mock was called
expect(mockOBPv500CreateConsentRequest).toHaveBeenCalled();
});
});

View File

@ -133,6 +133,7 @@ describe('OpeyController consents flow', () => {
let opeyController: OpeyController
beforeAll(() => {
mockOBPClientService = {
get: vi.fn(async () => {
Promise.resolve({})