Skip to content

Commit

Permalink
Merge branch 'master' into fix-714
Browse files Browse the repository at this point in the history
  • Loading branch information
wa0x6e committed Oct 28, 2023
2 parents ff5d41c + cf26dfe commit 5ed64e0
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 117 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@graphql-tools/schema": "^10.0.0",
"@snapshot-labs/keycard": "^0.4.0",
"@snapshot-labs/snapshot-metrics": "^1.3.1",
"@snapshot-labs/snapshot-sentry": "^1.5.1",
"@snapshot-labs/snapshot-sentry": "^1.5.2",
"@snapshot-labs/snapshot.js": "^0.7.8",
"bluebird": "^3.7.2",
"connection-string": "^1.0.1",
Expand Down Expand Up @@ -55,10 +55,10 @@
"eslint": "^8.28.0",
"jest": "^29.6.1",
"jest-environment-node-single-context": "^29.1.0",
"node-fetch": "^2.7",
"nodemon": "^2.0.19",
"prettier": "^3.0.3",
"start-server-and-test": "^2.0.0",
"supertest": "^6.3.3",
"ts-jest": "^29.1.1"
},
"engines": {
Expand Down
17 changes: 11 additions & 6 deletions src/api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import express from 'express';
import { spaces } from './helpers/spaces';
import { capture } from '@snapshot-labs/snapshot-sentry';
import { getSpace } from './helpers/spaces';
import { name, version } from '../package.json';
import { sendError } from './helpers/utils';

Expand All @@ -25,14 +26,18 @@ router.get('/', (req, res) => {
});
});

router.get('/spaces/:key', (req, res) => {
router.get('/spaces/:key', async (req, res) => {
const { key } = req.params;

if (!spaces[key]) {
return sendError(res, 'space not found', 404);
try {
return res.json(await getSpace(key));
} catch (e: any) {
if (e.message !== 'NOT_FOUND') {
capture(e);
return sendError(res, 'server_error', 500);
}
return sendError(res, 'not_found', 404);
}

return res.json(spaces[key]);
});

router.get('/spaces/:key/poke', async (req, res) => {
Expand Down
15 changes: 14 additions & 1 deletion src/graphql/operations/vp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@ import db from '../../helpers/mysql';
const scoreAPIUrl = process.env.SCORE_API_URL || 'https://score.snapshot.org';

export default async function (_parent, { voter, space, proposal }) {
if (voter === '0x0000000000000000000000000000000000000000' || voter === '') {
return Promise.reject(new Error('invalid address'));
}

if (proposal) {
const query = `SELECT * FROM proposals WHERE id = ?`;
const query = `SELECT * FROM proposals WHERE id = ? LIMIT 1`;
const [p] = await db.queryAsync(query, [proposal]);

if (!p) {
return Promise.reject(new Error('proposal not found'));
}

return await snapshot.utils.getVp(
voter,
p.network,
Expand All @@ -20,6 +28,11 @@ export default async function (_parent, { voter, space, proposal }) {
} else if (space) {
const query = `SELECT settings FROM spaces WHERE id = ? AND deleted = 0 LIMIT 1`;
let [s] = await db.queryAsync(query, [space]);

if (!s) {
return Promise.reject(new Error('space not found'));
}

s = JSON.parse(s.settings);

return await snapshot.utils.getVp(voter, s.network, s.strategies, 'latest', space, false, {
Expand Down
7 changes: 0 additions & 7 deletions src/helpers/alias.ts

This file was deleted.

12 changes: 9 additions & 3 deletions src/helpers/metrics.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import init, { client } from '@snapshot-labs/snapshot-metrics';
import { capture } from '@snapshot-labs/snapshot-sentry';
import { Express, type Request, type Response } from 'express';
import { parse } from 'graphql';
import { GraphQLError, parse } from 'graphql';
import { spacesMetadata } from './spaces';
import { strategies } from './strategies';
import db from './mysql';
Expand Down Expand Up @@ -58,9 +58,13 @@ export default function initMetrics(app: Express) {
if (query && operationName) {
const definition = parse(query).definitions.find(
// @ts-ignore
def => def.name.value === operationName
def => def.name?.value === operationName
);

if (!definition) {
return;
}

// @ts-ignore
const types = definition.selectionSet.selections.map(sel => sel.name.value);

Expand All @@ -71,7 +75,9 @@ export default function initMetrics(app: Express) {
}
}
} catch (e: any) {
capture(e);
if (!(e instanceof GraphQLError)) {
capture(e);
}
}
});
}
Expand Down
4 changes: 1 addition & 3 deletions src/helpers/moderation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ async function loadModerationData() {
flaggedLinks = res?.flaggedLinks;
}

async function run() {
export default async function run() {
try {
await loadModerationData();
consecutiveFailsCount = 0;
Expand All @@ -28,5 +28,3 @@ async function run() {
await snapshot.utils.sleep(5e3);
run();
}

run();
22 changes: 19 additions & 3 deletions src/helpers/spaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,25 @@ async function loadSpacesMetrics() {
mapSpaces();
}

async function run() {
export async function getSpace(id: string) {
const query = `
SELECT settings, flagged, verified
FROM spaces
WHERE deleted = 0 AND id = ?
LIMIT 1`;

const [space] = await db.queryAsync(query, [id]);

if (!space) return Promise.reject(new Error('NOT_FOUND'));

return {
...JSON.parse(space.settings),
flagged: space.flagged === 1,
verified: space.verified === 1
};
}

export default async function run() {
try {
await loadSpaces();
await loadSpacesMetrics();
Expand All @@ -169,5 +187,3 @@ async function run() {
await snapshot.utils.sleep(360e3);
run();
}

run();
5 changes: 4 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@ import rateLimit from './helpers/rateLimit';
import log from './helpers/log';
import initMetrics from './helpers/metrics';
import { checkKeycard } from './helpers/keycard';
import './helpers/moderation';
import refreshModerationData from './helpers/moderation';
import refreshSpacesCache from './helpers/spaces';
import './helpers/strategies';

const app = express();
const PORT = process.env.PORT || 3000;

initLogger(app);
initMetrics(app);
refreshModerationData();
refreshSpacesCache();

app.disable('x-powered-by');
app.use(express.json({ limit: '20mb' }));
Expand Down
1 change: 1 addition & 0 deletions test/.env.test
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
HUB_DATABASE_URL=mysql://root:[email protected]:3306/hub_test
SEQ_DATABASE_URL=mysql://root:[email protected]:3306/hub_test
NODE_ENV=test
55 changes: 53 additions & 2 deletions test/e2e/space.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,60 @@
import fetch from 'node-fetch';
import db from '../../src/helpers/mysql';
import fixtures from '../fixtures/spaces';

const HOST = `http://localhost:${process.env.PORT || 3030}`;

describe('GET /api/space/:key', () => {
beforeAll(async () => {
await db.queryAsync('DELETE from spaces');
await Promise.all(
fixtures.map(f => {
return db.queryAsync('INSERT INTO spaces SET ?', {
...f,
settings: JSON.stringify(f.settings)
});
})
);
});

afterAll(async () => {
await db.queryAsync('DELETE from spaces');
await db.endAsync();
});

describe('when the space exists', () => {
it.todo('returns a space object');
let response;
beforeAll(async () => {
response = await fetch(`${HOST}/api/spaces/fabien.eth`);
});

it('returns the correct HTTP response', () => {
expect(response.status);
expect(response.headers.get('content-type')).toContain('application/json');
});

it('returns the space data', async () => {
const space = fixtures[0];
const expectedSpace = {
flagged: space.flagged,
verified: space.verified,
...space.settings
};

expect(response.json()).resolves.toEqual(expectedSpace);
});
});

describe('when the space does not exist', () => {
it.todo('returns a 404 error');
it('returns a 404 error', async () => {
const response = await fetch(`${HOST}/api/spaces/null.eth`);

expect(response.status).toBe(404);
expect(response.headers.get('content-type')).toContain('application/json');
expect(response.json()).resolves.toEqual({
error: 'unauthorized',
error_description: 'not_found'
});
});
});
});
13 changes: 13 additions & 0 deletions test/fixtures/spaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const fixtures: Record<string, any>[] = [
{
id: 'fabien.eth',
name: 'Fabien.eth',
flagged: false,
verified: true,
settings: { network: 1 },
created_at: Math.floor(Date.now() / 1e3),
updated_at: Math.floor(Date.now() / 1e3)
}
];

export default fixtures;
10 changes: 10 additions & 0 deletions test/setup.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { default as db, sequencerDB } from '../src/helpers/mysql';

export const TEST_DATABASE_SUFFIX = '_test';

const setup = async () => {
try {
await db.queryAsync('SELECT 1 + 1');
await sequencerDB.queryAsync('SELECT 1 + 1');

if (db.config.connectionConfig.database.endsWith(TEST_DATABASE_SUFFIX)) {
throw new Error(`Hub database name is not ending by ${TEST_DATABASE_SUFFIX}`);
}

if (sequencerDB.config.connectionConfig.database.endsWith(TEST_DATABASE_SUFFIX)) {
throw new Error(`Sequencer database name is not ending by ${TEST_DATABASE_SUFFIX}`);
}
} catch (e: any) {
if (e.code === 'ER_BAD_DB_ERROR') {
console.error('Test database not setup, please run `yarn test:setup`');
Expand Down
5 changes: 3 additions & 2 deletions test/setupDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Connection from 'mysql/lib/Connection';
import bluebird from 'bluebird';
import parse from 'connection-string';
import fs from 'fs';
import { TEST_DATABASE_SUFFIX } from './setup';

// @ts-ignore
const config = parse(process.env.HUB_DATABASE_URL);
Expand All @@ -14,8 +15,8 @@ bluebird.promisifyAll([Pool, Connection]);
const db = mysql.createPool(config);
const dbName = config.path[0];

if (!dbName.endsWith('_test')) {
console.error('Invalid test database name. Must end with _test');
if (!dbName.endsWith(TEST_DATABASE_SUFFIX)) {
console.error(`Invalid test database name. Must end with ${TEST_DATABASE_SUFFIX}`);
process.exit(1);
}

Expand Down
Loading

0 comments on commit 5ed64e0

Please sign in to comment.