Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release to beta #38

Merged
merged 8 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .cargo/config

This file was deleted.

6 changes: 6 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[alias]
runehook-install = "install --path . --locked --force"

[env]
# Run tests in one thread so we can support postgres migrations correctly.
RUST_TEST_THREADS = "1"
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,14 @@ jobs:
docker-compose -f docker/docker-compose.dev.postgres.yml up -d
docker-compose -f docker/docker-compose.dev.postgres.yml logs -t -f --no-color &> docker-compose-logs.txt &

- name: Cargo test
- name: Update Rust
run: |
rustup update
RUST_BACKTRACE=1 cargo test --all -- --test-threads=1

- name: Run tests
run: |
cargo install --force cargo-tarpaulin
cargo tarpaulin --out lcov -- --test-threads=1

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
Expand Down
23 changes: 22 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,27 @@
"TS_NODE_SKIP_IGNORE": "true"
},
"killBehavior": "polite"
}
},
{
"type": "node",
"request": "launch",
"name": "Jest",
"program": "${workspaceFolder}/api/node_modules/jest/bin/jest",
"cwd": "${workspaceFolder}/api/",
"args": [
"--testTimeout=3600000",
"--runInBand",
"--no-cache",
],
"outputCapture": "std",
"console": "integratedTerminal",
"preLaunchTask": "npm: testenv:run",
"postDebugTask": "npm: testenv:stop",
"env": {
"PGHOST": "localhost",
"PGUSER": "postgres",
"PGPASSWORD": "postgres",
},
},
]
}
43 changes: 43 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "npm: testenv:run",
"type": "shell",
"command": "npm run testenv:run -- -d",
"isBackground": true,
"options": {
"cwd": "${workspaceFolder}/api/",
},
"problemMatcher": {
"pattern": {
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
},
"background": {
"activeOnStart": true,
"beginsPattern": ".",
"endsPattern": "."
}
}
},
{
"label": "npm: testenv:stop",
"type": "shell",
"command": "npm run testenv:stop",
"options": {
"cwd": "${workspaceFolder}/api/",
},
"presentation": {
"echo": true,
"reveal": "silent",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
}
}
]
}
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ tokio-postgres = "0.7.10"
tokio = { version = "1.38.0", features = ["rt-multi-thread", "macros"] }
refinery = { version = "0.8", features = ["tokio-postgres"] }
num-traits = "0.2.14"
maplit = "1.0.2"

[dev-dependencies]
test-case = "3.1.0"
Expand Down
5 changes: 4 additions & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
"generate:vercel": "npm run generate:git-info && npm run generate:openapi && npm run generate:docs",
"lint:eslint": "eslint . --ext .ts,.tsx -f unix",
"lint:prettier": "prettier --check src/**/*.ts tests/**/*.ts",
"lint:unused-exports": "ts-unused-exports tsconfig.json --showLineNumber --excludePathsFromReport=util/*"
"lint:unused-exports": "ts-unused-exports tsconfig.json --showLineNumber --excludePathsFromReport=util/*",
"testenv:run": "docker-compose -f ../docker/docker-compose.dev.postgres.yml up",
"testenv:stop": "docker-compose -f ../docker/docker-compose.dev.postgres.yml down -v -t 0",
"testenv:logs": "docker-compose -f ../docker/docker-compose.dev.postgres.yml logs -t -f"
},
"author": "Hiro Systems PBC <[email protected]> (https://hiro.so)",
"license": "Apache 2.0",
Expand Down
5 changes: 4 additions & 1 deletion api/src/api/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ const RuneNumberSchema = Type.RegEx(/^[0-9]+$/, { title: 'Rune number' });
export const RuneNumberSchemaCType = TypeCompiler.Compile(RuneNumberSchema);
const RuneNameSchema = Type.RegEx(/^[A-Z]+$/, { title: 'Rune name' });
export const RuneNameSchemaCType = TypeCompiler.Compile(RuneNameSchema);
const RuneSpacedNameSchema = Type.RegEx(/^[A-Z](•[A-Z]+)+$/, { title: 'Rune name with spacers' });
const RuneSpacedNameSchema = Type.RegEx(/^[A-Za-z]+(•[A-Za-z]+)+$/, {
title: 'Rune name with spacers',
});
export const RuneSpacedNameSchemaCType = TypeCompiler.Compile(RuneSpacedNameSchema);

export const RuneSchema = Type.Union([
Expand Down Expand Up @@ -306,6 +308,7 @@ const RuneDetailResponseSchema = Type.Object({
rune: Type.Object(
{
id: RuneIdResponseSchema,
number: RuneNumberResponseSchema,
name: RuneNameResponseSchema,
spaced_name: RuneSpacedNameResponseSchema,
},
Expand Down
3 changes: 3 additions & 0 deletions api/src/api/util/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
const total_burns = rune.total_burns == null ? '0' : rune.total_burns;
if (
rune.terms_amount == null ||
rune.cenotaph ||
(rune.terms_cap && BigNumber(total_mints).gte(rune.terms_cap)) ||
(rune.terms_height_start && BigNumber(rune.chain_tip).lt(rune.terms_height_start)) ||
(rune.terms_height_end && BigNumber(rune.chain_tip).gt(rune.terms_height_end)) ||
Expand Down Expand Up @@ -67,6 +68,7 @@
return {
rune: {
id: entry.rune_id,
number: entry.number,
name: entry.name,
spaced_name: entry.spaced_name,
},
Expand All @@ -90,6 +92,7 @@
return {
rune: {
id: item.rune_id,
number: item.number,

Check warning on line 95 in api/src/api/util/helpers.ts

View check run for this annotation

Codecov / codecov/patch

api/src/api/util/helpers.ts#L95

Added line #L95 was not covered by tests
name: item.name,
spaced_name: item.spaced_name,
},
Expand Down
8 changes: 4 additions & 4 deletions api/src/pg/pg-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
const results = await this.sql<DbCountedQueryResult<DbItemWithRune<DbLedgerEntry>>[]>`
WITH ${cte ? cte : this.sql`none AS (SELECT NULL)`},
results AS (
SELECT l.*, r.name, r.spaced_name, r.divisibility, ${count} AS total
SELECT l.*, r.name, r.number, r.spaced_name, r.divisibility, ${count} AS total
FROM ledger AS l
INNER JOIN runes AS r ON r.id = l.rune_id
WHERE ${filter}
Expand Down Expand Up @@ -222,7 +222,7 @@
): Promise<DbPaginatedResult<DbItemWithRune<DbBalance>>> {
const results = await this.sql<DbCountedQueryResult<DbItemWithRune<DbBalance>>[]>`
WITH grouped AS (
SELECT DISTINCT ON (b.address) b.address, b.balance, b.total_operations, b.rune_id, r.name,
SELECT DISTINCT ON (b.address) b.address, b.balance, b.total_operations, b.rune_id, r.name, r.number

Check warning on line 225 in api/src/pg/pg-store.ts

View check run for this annotation

Codecov / codecov/patch

api/src/pg/pg-store.ts#L225

Added line #L225 was not covered by tests
r.spaced_name, r.divisibility, COUNT(*) OVER() AS total
FROM balance_changes AS b
INNER JOIN runes AS r ON r.id = b.rune_id
Expand All @@ -245,7 +245,7 @@
): Promise<DbItemWithRune<DbBalance> | undefined> {
const results = await this.sql<DbItemWithRune<DbBalance>[]>`
SELECT b.rune_id, b.address, b.balance, b.total_operations, r.name,
r.spaced_name, r.divisibility, COUNT(*) OVER() AS total
r.number, r.spaced_name, r.divisibility, COUNT(*) OVER() AS total

Check warning on line 248 in api/src/pg/pg-store.ts

View check run for this annotation

Codecov / codecov/patch

api/src/pg/pg-store.ts#L248

Added line #L248 was not covered by tests
FROM balance_changes AS b
INNER JOIN runes AS r ON r.id = b.rune_id
WHERE ${runeFilter(this.sql, id, 'r')} AND address = ${address}
Expand All @@ -263,7 +263,7 @@
const results = await this.sql<DbCountedQueryResult<DbItemWithRune<DbBalance>>[]>`
WITH grouped AS (
SELECT DISTINCT ON (b.rune_id) b.address, b.balance, b.total_operations, b.rune_id, r.name,
r.spaced_name, r.divisibility, COUNT(*) OVER() AS total
r.number, r.spaced_name, r.divisibility, COUNT(*) OVER() AS total

Check warning on line 266 in api/src/pg/pg-store.ts

View check run for this annotation

Codecov / codecov/patch

api/src/pg/pg-store.ts#L266

Added line #L266 was not covered by tests
FROM balance_changes AS b
INNER JOIN runes AS r ON r.id = b.rune_id
WHERE address = ${address}
Expand Down
4 changes: 3 additions & 1 deletion api/src/pg/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

export type DbCountedQueryResult<T> = T & { total: number };

type DbRune = {
export type DbRune = {

Check warning on line 8 in api/src/pg/types.ts

View check run for this annotation

Codecov / codecov/patch

api/src/pg/types.ts#L8

Added line #L8 was not covered by tests
id: string;
number: number;
name: string;
Expand All @@ -17,6 +17,7 @@
divisibility: number;
premine: string;
symbol: string;
cenotaph: boolean;

Check warning on line 20 in api/src/pg/types.ts

View check run for this annotation

Codecov / codecov/patch

api/src/pg/types.ts#L20

Added line #L20 was not covered by tests
terms_amount: string | null;
terms_cap: string | null;
terms_height_start: string | null;
Expand Down Expand Up @@ -52,6 +53,7 @@

export type DbItemWithRune<T> = T & {
name: string;
number: number;

Check warning on line 56 in api/src/pg/types.ts

View check run for this annotation

Codecov / codecov/patch

api/src/pg/types.ts#L56

Added line #L56 was not covered by tests
spaced_name: string;
divisibility: number;
total_operations: number;
Expand Down
152 changes: 150 additions & 2 deletions api/tests/api/api.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,151 @@
test('sample', () => {
expect(true);
import { ENV } from '../../src/env';
import { PgStore } from '../../src/pg/pg-store';
import {
dropDatabase,
insertDbLedgerEntry,
insertRune,
sampleRune,
runMigrations,
startTestApiServer,
TestFastifyServer,
insertSupplyChange,
sampleLedgerEntry,
} from '../helpers';

describe('Endpoints', () => {
let db: PgStore;
let fastify: TestFastifyServer;

const rune = sampleRune('1:1', 'Sample Rune');
const ledgerEntry = sampleLedgerEntry(rune.id);

beforeEach(async () => {
ENV.PGDATABASE = 'postgres';
db = await PgStore.connect();
fastify = await startTestApiServer(db);
await runMigrations(db);
await insertRune(db, rune);
const event_index = 0;
await insertDbLedgerEntry(db, ledgerEntry, event_index);
await insertSupplyChange(db, rune.id, 1);
});

afterEach(async () => {
if (fastify) {
await fastify.close();
}

await dropDatabase(db);
await db.close();
});

describe('Etchings', () => {
test('lists runes', async () => {
const expected = {
divisibility: 0,
id: '1:1',
location: {
block_hash: '0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5',
block_height: 840000,
timestamp: 0,
tx_id: '2bb85f4b004be6da54f766c17c1e855187327112c231ef2ff35ebad0ea67c69e',
tx_index: 1,
},
mint_terms: {
amount: '100',
cap: '5000000',
height_end: null,
height_start: null,
offset_end: null,
offset_start: null,
},
name: 'Sample Rune',
number: 1,
spaced_name: 'Sample•Rune',
supply: {
burned: '0',
current: '0',
mint_percentage: '0.0000',
mintable: false,
minted: '0',
premine: '0',
total_burns: '0',
total_mints: '0',
},
symbol: 'ᚠ',
turbo: false,
};
const runesResponse = await fastify.inject({
method: 'GET',
url: '/runes/v1/etchings',
});
expect(runesResponse.statusCode).toBe(200);
expect(runesResponse.json().results).not.toHaveLength(0);

const response = await fastify.inject({
method: 'GET',
url: '/runes/v1/etchings/' + ledgerEntry.rune_id,
});
expect(response.statusCode).toBe(200);
expect(response.json()).toStrictEqual(expected);
});

test('can fetch by spaced name', async () => {
const url = '/runes/v1/etchings/' + rune.spaced_name;
const response = await fastify.inject({
method: 'GET',
url: url,
});
expect(response.statusCode).toBe(200);
expect(response.json().spaced_name).toEqual(rune.spaced_name);
});

test('can not fetch by spaced name if lacking bullets', async () => {
const url = '/runes/v1/etchings/' + rune.spaced_name.replaceAll('•', '-');
const response = await fastify.inject({
method: 'GET',
url: url,
});
expect(response.statusCode).toBe(400);
});
});
describe('Transactions', () => {
test('shows details', async () => {
const expected = {
limit: 20,
offset: 0,
results: [
{
address: '0',
amount: '0',
location: {
block_hash: '0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5',
block_height: 840000,
output: '2bb85f4b004be6da54f766c17c1e855187327112c231ef2ff35ebad0ea67c69e:0',
timestamp: 0,
tx_id: '2bb85f4b004be6da54f766c17c1e855187327112c231ef2ff35ebad0ea67c69e',
tx_index: 0,
vout: 0,
},
operation: 'etching',
receiver_address: '0',
rune: {
id: '1:1',
name: 'Sample Rune',
number: 1,
spaced_name: 'Sample•Rune',
},
},
],
total: 1,
};
const txid = ledgerEntry.tx_id;
const response = await fastify.inject({
method: 'GET',
url: '/runes/v1/transactions/' + txid + '/activity',
});
expect(response.statusCode).toBe(200);
expect(response.json()).toStrictEqual(expected);
});
});
});
Loading
Loading