Skip to content

Commit

Permalink
Merge branch 'develop' into feat/make-auth-class-public
Browse files Browse the repository at this point in the history
  • Loading branch information
Siddharth9890 authored Sep 27, 2024
2 parents adff7d8 + ecac826 commit 4872eb2
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 9 deletions.
58 changes: 57 additions & 1 deletion src/modules/account/account.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,48 @@
import { MediaType } from 'openapi-typescript-helpers';
import { OpenAPIClient, MyAccountResponse } from '../../common/types';
import {
OpenAPIClient,
MyAccountResponse,
AccountCreateRequest,
} from '../../common/types';
import { paths } from '../../api';
import { GTWError } from '../../helpers/custom-error';
import { CryptoService } from '../../services/crypto-service';

export class Account {
private client: OpenAPIClient<paths, MediaType>;
private cryptoService: CryptoService;

constructor(client: OpenAPIClient<paths, MediaType>) {
this.client = client;
this.cryptoService = new CryptoService();
}

/**
* The `createAccount` function in TypeScript asynchronously creates a new account by verifying a
* message, sending a POST request to an endpoint, and returning a token upon success.
* @param {AccountCreateRequest} - The `createAccount` function takes in an `AccountCreateRequest`
* object with the following parameters:
* @returns The `createAccount` function returns a token from the `data` object after successfully
* verifying the message signature and creating an account with the provided username and wallet
* address.
*/
async createAccount({
message,
signature,
username,
wallet_address,
}: AccountCreateRequest) {
await this.cryptoService.verifyMessage(signature, message, wallet_address);

const { data, error, response } = await this.client.POST('/accounts', {
body: { message, signature, username, wallet_address },
});

if (error) {
throw new GTWError(error, response);
}

return data.token;
}

/**
Expand All @@ -26,4 +61,25 @@ export class Account {

return data;
}

/**
* The function `updateAccount` asynchronously updates the profile picture and username of the current
* account using a PATCH request.
* @param - The `updateAccount` function takes in an object with two properties: `profile_picture` and
* `username`, both of type string. These values are used to update the user's account information by
* making a PATCH request to the `/accounts/me` endpoint with the provided data. If there is an error
* @returns The `updateAccount` function is returning the `data` object after making a PATCH request to
* update the account information (profile picture and username).
*/
async updateAccount(profile_picture?: string, username?: string) {
const { data, error, response } = await this.client.PATCH('/accounts/me', {
body: { profile_picture, username },
});

if (error) {
throw new GTWError(error, response);
}

return data;
}
}
95 changes: 87 additions & 8 deletions test/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import { GTWError } from '../src/helpers/custom-error';
import { Account } from '../src/modules/account/account';
import { MediaType } from 'openapi-typescript-helpers';
import {
authDetails,
errorMessage,
mockClient,
mockGet,
mockPatch,
mockPost,
successMessage,
} from './stubs/common.stub';
import { routes } from '../src/common/routes';
Expand All @@ -21,18 +24,43 @@ describe('Account', () => {
);
});

describe('create Account ', () => {
it('should return with new account with given credentials', async () => {
mockPost.mockResolvedValue(successMessage({ data: { token: 'test' } }));

const result = await account.createAccount(
authDetails({ username: 'testuser' }),
);

expect(result).toBeDefined();
expect(mockPost).toHaveBeenCalledWith(routes.CreateAccount, {
body: authDetails({ username: 'testuser' }),
});
});

it('should return error when creating account', async () => {
mockPost.mockResolvedValue(errorMessage());

await expect(
account.createAccount(authDetails({ username: 'testuser' })),
).rejects.toThrow(GTWError);
expect(mockPost).toHaveBeenCalledWith(routes.CreateAccount, {
body: authDetails({ username: 'testuser' }),
});
});
});

describe('getAccountInfo', () => {
it('should return account info when API call is successful', async () => {
const mockData: MyAccountResponse = {
const mockData = {
did: '123',
username: 'Test User',
created_at: new Date().toDateString(),
storage_size: 123,
updated_at: new Date().toDateString(),
username_updated_at: new Date().toDateString(),
wallet_addresses: [],
};
mockGet.mockResolvedValue(successMessage({ data: mockData }));
} as MyAccountResponse;
mockGet.mockResolvedValue({
data: mockData,
response: {},
error: null,
});

const result = await account.getAccountInfo();

Expand All @@ -47,4 +75,55 @@ describe('Account', () => {
expect(mockClient.GET).toHaveBeenCalledWith(routes.GetMyAccount);
});
});

describe('update Account', () => {
it('should return account with updated attributes', async () => {
const mockData = {
created_at: '2024-09-25T12:34:56Z',
did: 'did:example:123456789abcdefghi',
profile_picture: 'https://example.com/profile-picture.png',
storage_size: 1024,
updated_at: '2024-09-25T13:34:56Z',
username: 'new_username',
username_updated_at: '2024-09-25T12:35:56Z',
wallet_address: '0x123456789abcdefghi',
};

mockPatch.mockResolvedValue({
data: mockData,
response: {},
error: null,
});

const result = await account.updateAccount(
'https://example.com/profile-picture.png',
);

expect(result).toEqual(mockData);
expect(mockClient.PATCH).toHaveBeenCalledWith(routes.UpdateAccount, {
body: {
profile_picture: 'https://example.com/profile-picture.png',
username: undefined,
},
});
});

it('should throw GTWError when API call fails', async () => {
const mockResponse = { status: 401 } as Response;

mockPatch.mockResolvedValue({
data: null,
response: mockResponse,
error: { error: 'Unauthorized' },
});

await expect(account.updateAccount()).rejects.toThrow(GTWError);
expect(mockClient.PATCH).toHaveBeenCalledWith(routes.UpdateAccount, {
body: {
profile_picture: 'https://example.com/profile-picture.png',
username: undefined,
},
});
});
});
});
3 changes: 3 additions & 0 deletions test/stubs/common.stub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,14 @@ export const linksStub = (overrideLinkStub?: HelperLinks) => ({

export let mockGet: jest.Mock;
export let mockPost: jest.Mock;
export let mockPatch: jest.Mock;
export let mockPut: jest.Mock;
export let mockPatch: jest.Mock;
export let mockDelete: jest.Mock;

mockGet = jest.fn();
mockPost = jest.fn();
mockPatch = jest.fn();
mockPut = jest.fn();
mockDelete = jest.fn();
mockPatch = jest.fn();
Expand All @@ -76,6 +78,7 @@ export let mockClient: OpenAPIClient<paths, MediaType> = {
GET: mockGet,
POST: mockPost,
PUT: mockPut,
PATCH: mockPatch,
DELETE: mockDelete,
PATCH: mockPatch,
} as any as OpenAPIClient<paths, MediaType>;

0 comments on commit 4872eb2

Please sign in to comment.