Skip to content
Snippets Groups Projects
Verified Commit b44cd868 authored by Konstantin Tsabolov's avatar Konstantin Tsabolov
Browse files

feat: add offer creation methods

parent 9a631184
No related branches found
No related tags found
1 merge request!35Credentials
import type { TestingModule } from '@nestjs/testing';
import type {
EventDidcommAnonCredsCredentialsOfferInput,
EventDidcommAnonCredsCredentialsOfferToSelfInput,
} from '@ocm/shared';
import { Test } from '@nestjs/testing';
import {
EventAnonCredsCredentialOfferGetAll,
EventAnonCredsCredentialOfferGetById,
EventDidcommAnonCredsCredentialsOffer,
EventDidcommAnonCredsCredentialsOfferToSelf,
} from '@ocm/shared';
import { Subject, of, takeUntil } from 'rxjs';
......@@ -88,4 +94,85 @@ describe('CredentialOffersService', () => {
});
});
});
describe('createCredentialOffer', () => {
it('should call natsClient.send with the correct arguments', (done) => {
const unsubscribe$ = new Subject<void>();
const tenantId = 'tenantId';
const connectionId = 'connectionId';
const credentialDefinitionId = 'credentialDefinitionId';
const attributes: EventDidcommAnonCredsCredentialsOfferInput['attributes'] =
[];
const expectedResult =
{} as EventDidcommAnonCredsCredentialsOffer['data'];
natsClientMock.send.mockReturnValueOnce(
of(new EventDidcommAnonCredsCredentialsOffer(expectedResult, tenantId)),
);
service
.offer(tenantId, connectionId, credentialDefinitionId, attributes)
.pipe(takeUntil(unsubscribe$))
.subscribe((result) => {
expect(natsClientMock.send).toHaveBeenCalledWith(
EventDidcommAnonCredsCredentialsOffer.token,
{
tenantId,
connectionId,
credentialDefinitionId,
attributes,
},
);
expect(result).toStrictEqual(expectedResult);
unsubscribe$.next();
unsubscribe$.complete();
done();
});
});
});
describe('createCredentialOfferToSelf', () => {
it('should call natsClient.send with the correct arguments', (done) => {
const unsubscribe$ = new Subject<void>();
const tenantId = 'tenantId';
const credentialDefinitionId = 'credentialDefinitionId';
const attributes: EventDidcommAnonCredsCredentialsOfferToSelfInput['attributes'] =
[];
const expectedResult =
{} as EventDidcommAnonCredsCredentialsOfferToSelf['data'];
natsClientMock.send.mockReturnValueOnce(
of(
new EventDidcommAnonCredsCredentialsOfferToSelf(
expectedResult,
tenantId,
),
),
);
service
.offerToSelf(tenantId, credentialDefinitionId, attributes)
.pipe(takeUntil(unsubscribe$))
.subscribe((result) => {
expect(natsClientMock.send).toHaveBeenCalledWith(
EventDidcommAnonCredsCredentialsOfferToSelf.token,
{
tenantId,
credentialDefinitionId,
attributes,
},
);
expect(result).toStrictEqual(expectedResult);
unsubscribe$.next();
unsubscribe$.complete();
done();
});
});
});
});
import {
Body,
Controller,
Get,
HttpStatus,
Param,
Post,
Query,
UseInterceptors,
UsePipes,
......@@ -13,6 +15,7 @@ import { MultitenancyParams, ResponseFormatInterceptor } from '@ocm/shared';
import { CredentialOffersService } from './credential-offers.service.js';
import { GetByIdParams } from './dto/get-by-id.dto.js';
import { OfferPayload } from './dto/offer.dto.js';
@Controller()
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
......@@ -168,4 +171,178 @@ export class CredentialOffersController {
) {
return this.service.getCredentialOfferById(tenantId, credentialOfferId);
}
@Post()
@ApiOperation({
summary: 'Create a credential offer',
description:
'This call creates a credential offer for a given connection ID and credential definition ID',
})
@ApiResponse({
status: HttpStatus.OK,
description: 'Credential offer created successfully',
content: {
'application/json': {
schema: {},
examples: {
'Credential offer created successfully': {
value: {
statusCode: 200,
message: 'Credential offer created successfully',
data: {
id: '71b784a3',
},
},
},
},
},
},
})
@ApiResponse({
status: HttpStatus.NOT_FOUND,
content: {
'application/json': {
schema: {},
examples: {
'Credential offer not found': {
value: {
statusCode: 404,
message: 'Credential offer not found',
data: null,
},
},
'Tenant not found': {
value: {
statusCode: 404,
message: 'Tenant not found',
data: null,
},
},
'Credential definition not found': {
value: {
statusCode: 404,
message: 'Credential definition not found',
data: null,
},
},
},
},
},
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: 'Something went wrong',
content: {
'application/json': {
schema: {},
examples: {
'Something went wrong': {
value: {
statusCode: 500,
message: 'Something went wrong',
error: 'Internal Server Error',
},
},
},
},
},
})
public offer(
@Query() { tenantId }: MultitenancyParams,
@Body() { connectionId, credentialDefinitionId, attributes }: OfferPayload,
) {
return this.service.offer(
tenantId,
connectionId,
credentialDefinitionId,
attributes,
);
}
@Post('self')
@ApiOperation({
summary: 'Create a credential offer to self',
description:
'This call creates a credential offer for a given credential definition ID',
})
@ApiResponse({
status: HttpStatus.OK,
description: 'Credential offer created successfully',
content: {
'application/json': {
schema: {},
examples: {
'Credential offer created successfully': {
value: {
statusCode: 200,
message: 'Credential offer created successfully',
data: {
id: '71b784a3',
},
},
},
},
},
},
})
@ApiResponse({
status: HttpStatus.NOT_FOUND,
content: {
'application/json': {
schema: {},
examples: {
'Credential offer not found': {
value: {
statusCode: 404,
message: 'Credential offer not found',
data: null,
},
},
'Tenant not found': {
value: {
statusCode: 404,
message: 'Tenant not found',
data: null,
},
},
'Credential definition not found': {
value: {
statusCode: 404,
message: 'Credential definition not found',
data: null,
},
},
},
},
},
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: 'Something went wrong',
content: {
'application/json': {
schema: {},
examples: {
'Something went wrong': {
value: {
statusCode: 500,
message: 'Something went wrong',
error: 'Internal Server Error',
},
},
},
},
},
})
public offerToSelf(
@Query() { tenantId }: MultitenancyParams,
@Body()
{ credentialDefinitionId, attributes }: Omit<OfferPayload, 'connectionId'>,
) {
return this.service.offerToSelf(
tenantId,
credentialDefinitionId,
attributes,
);
}
}
import type {
EventAnonCredsCredentialOfferGetAllInput,
EventAnonCredsCredentialOfferGetByIdInput,
EventDidcommAnonCredsCredentialsOfferInput,
EventDidcommAnonCredsCredentialsOfferToSelfInput,
} from '@ocm/shared';
import type { Observable } from 'rxjs';
import { Inject, Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import {
EventDidcommAnonCredsCredentialsOffer,
EventDidcommAnonCredsCredentialsOfferToSelf,
EventAnonCredsCredentialOfferGetAll,
EventAnonCredsCredentialOfferGetById,
} from '@ocm/shared';
......@@ -39,4 +44,40 @@ export class CredentialOffersService {
})
.pipe(map(({ data }) => data));
}
public offer(
tenantId: string,
connectionId: string,
credentialDefinitionId: string,
attributes: EventDidcommAnonCredsCredentialsOfferInput['attributes'],
): Observable<EventDidcommAnonCredsCredentialsOffer['data']> {
return this.natsClient
.send<
EventDidcommAnonCredsCredentialsOffer,
EventDidcommAnonCredsCredentialsOfferInput
>(EventDidcommAnonCredsCredentialsOffer.token, {
tenantId,
connectionId,
credentialDefinitionId,
attributes,
})
.pipe(map(({ data }) => data));
}
public offerToSelf(
tenantId: string,
credentialDefinitionId: string,
attributes: EventDidcommAnonCredsCredentialsOfferToSelfInput['attributes'],
): Observable<EventDidcommAnonCredsCredentialsOfferToSelf['data']> {
return this.natsClient
.send<
EventDidcommAnonCredsCredentialsOfferToSelf,
EventDidcommAnonCredsCredentialsOfferToSelfInput
>(EventDidcommAnonCredsCredentialsOfferToSelf.token, {
tenantId,
credentialDefinitionId,
attributes,
})
.pipe(map(({ data }) => data));
}
}
export class OfferPayload {
public connectionId: string;
public credentialDefinitionId: string;
public attributes: Array<{
name: string;
value: string;
mimeType?: string;
}>;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment