Skip to content

Commit

Permalink
Add Avatar module (#243)
Browse files Browse the repository at this point in the history
* Add Avatar module

* Add tests with mocked api for avatar module

* Update dependencies to minor

* Remove async/await

* Add more gas to execTransaction
  • Loading branch information
llunaCreixent authored Oct 17, 2023
1 parent 0d4870f commit aa78099
Show file tree
Hide file tree
Showing 7 changed files with 34,415 additions and 22,664 deletions.
56,903 changes: 34,258 additions & 22,645 deletions package-lock.json

Large diffs are not rendered by default.

38 changes: 20 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,35 +31,37 @@
"test:watch": "npm run test -- --watch"
},
"devDependencies": {
"@babel/core": "^7.22.5",
"@babel/eslint-parser": "^7.22.5",
"@babel/core": "^7.23.2",
"@babel/eslint-parser": "^7.22.15",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
"@babel/plugin-transform-runtime": "^7.22.5",
"@babel/preset-env": "^7.22.5",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-commonjs": "^25.0.1",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.1.0",
"@rollup/plugin-terser": "^0.4.3",
"@babel/plugin-transform-runtime": "^7.23.2",
"@babel/preset-env": "^7.23.2",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.0.1",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-terser": "^0.4.4",
"babel-plugin-add-module-exports": "^1.0.4",
"babel-plugin-module-resolver": "^5.0.0",
"documentation": "^14.0.2",
"dotenv": "^16.1.4",
"eslint": "^8.42.0",
"eslint-config-prettier": "^8.8.0",
"dotenv": "^16.3.1",
"eslint": "^8.51.0",
"eslint-config-prettier": "^8.10.0",
"eslint-plugin-prettier": "^4.2.1",
"http-status": "^1.7.0",
"husky": "^8.0.3",
"isomorphic-fetch": "^3.0.0",
"jest": "^29.5.0",
"lint-staged": "^13.2.2",
"jest": "^29.7.0",
"lint-staged": "^13.3.0",
"nock": "^13.3.4",
"prettier": "^2.8.8",
"rimraf": "^5.0.1",
"rollup": "^3.25.1",
"rimraf": "^5.0.5",
"rollup": "^3.29.4",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-node-builtins": "^2.1.2",
"truffle": "^5.9.4",
"web3": "^1.10.0"
"truffle": "^5.11.5",
"web3": "^1.10.2"
},
"dependencies": {
"@circles/circles-contracts": "^3.3.2",
Expand Down
78 changes: 78 additions & 0 deletions src/avatar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import checkAccount from '~/common/checkAccount';
import checkOptions from '~/common/checkOptions';

/**
* Avatar submodule to upload and delete images from storage.
*
* @access private
*
* @param {Web3} web3 - Web3 instance
* @param {Object} utils - utils module instance
*
* @return {Object} - avatar module instance
*/
export default function createAvatarModule(web3, utils) {
return {
/**
* Upload an avatar image to storage.
*
* @namespace core.avatar.upload
*
* @param {Object} account - web3 account instance
* @param {Object} userOptions - options
* @param {object} userOptions.data - avatar image file
*
* @return {object} - Returns url, file name and file type of the uploaded image
*/
upload: (account, userOptions) => {
checkAccount(web3, account);

const options = checkOptions(userOptions, {
data: {
type: 'object',
},
});

const { data } = options;

return utils.requestAPI({
path: ['uploads', 'avatar'],
method: 'POST',
data,
});
},

/**
* Delete from storage an avatar image whose url is not connected to any user entry.
*
* @namespace core.avatar.delete
*
* @param {Object} account - web3 account instance
* @param {Object} userOptions - options
* @param {string} userOptions.url - url of the avatar image
*
* @return {boolean} - Returns true when successful
*/
delete: async (account, userOptions) => {
checkAccount(web3, account);

const options = checkOptions(userOptions, {
url: {
type: 'string',
},
});

const { url } = options;

await utils.requestAPI({
path: ['uploads', 'avatar'],
method: 'DELETE',
data: {
url,
},
});

return true;
},
};
}
3 changes: 3 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import checkOptions from '~/common/checkOptions';
import getContracts from '~/common/getContracts';

import createActivityModule from '~/activity';
import createAvatarModule from '~/avatar';
import createNewsModule from '~/news';
import createOrganizationModule from '~/organization';
import createSafeModule from '~/safe';
Expand Down Expand Up @@ -141,5 +142,7 @@ export default class CirclesCore {
this.trust = createTrustModule(web3, this.contracts, this.utils);
/** @type {Object} - user module */
this.user = createUserModule(web3, this.contracts, this.utils);
/** @type {Object} - avatar module */
this.avatar = createAvatarModule(web3, this.utils);
}
}
35 changes: 35 additions & 0 deletions test/avatar.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import createCore from './helpers/core';
import getAccount from './helpers/account';
import { deploySafeAndToken } from './helpers/transactions';
import { mockApiAvatarUpload, mockApiAvatarDelete } from './helpers/mocks';

let account;
let core;

beforeAll(async () => {
core = createCore();
});

describe('Avatar - upload and delete', () => {
beforeAll(async () => {
account = getAccount(1);
// The Safe must be deployed and signedup to the Hub before trying to delete the user entry
await deploySafeAndToken(core, account);
});

describe('when a user wants to upload an image, and then remove it', () => {
it('should return a success response', async () => {
const data = {};
mockApiAvatarUpload(data);
const result = await core.avatar.upload(account, { data });
expect(result.data.url).toEqual(expect.stringContaining('https://'));

mockApiAvatarDelete(result.data.url);
expect(
await core.avatar.delete(account, {
url: result.data.url,
}),
).toBe(true);
});
});
});
20 changes: 20 additions & 0 deletions test/helpers/mocks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import httpStatus from 'http-status';
import nock from 'nock';

export function mockApiAvatarUpload(data) {
nock(process.env.API_SERVICE_ENDPOINT)
.post(`/api/uploads/avatar/`, data)
.reply(httpStatus.OK, {
data: {
url: 'https://circles-ubi-development.s3.amazonaws.com/uploads/avatars/e38d4d9365b9a48cd0f2a3e1cddb1c5cc1da5a8282cbc61fe949dbb017c4d52d.jpg',
},
});
}

export function mockApiAvatarDelete(url) {
nock(process.env.API_SERVICE_ENDPOINT)
.delete(`/api/uploads/avatar/`, {
url,
})
.reply(httpStatus.OK);
}
2 changes: 1 addition & 1 deletion test/helpers/transactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ async function execTransaction(
refundReceiver,
signatures,
)
.send({ from, gas: '10000000' }); // @TODO: '1266349' ? Need to change gas, safeTxGase, baseGas
.send({ from, gas: '100000000' }); // @TODO: '1266349' ? Need to change gas, safeTxGase, baseGas
}

export async function deployCRCVersionToken(web3, account, safe, hub) {
Expand Down

0 comments on commit aa78099

Please sign in to comment.