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

APP-1928: create release entity + metadata #319

Merged
merged 3 commits into from
Mar 6, 2023
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
12 changes: 12 additions & 0 deletions packages/subgraph/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [UPCOMING]

### Added

- Added `PluginRelease`.
- Added `metadata` to `PluginVersion`.

### Changed

- Changed `release: Int!` to `release: PluginRelease!` in `PluginVersion`
- Changed `versions` to `releases` in `PluginRepo`.

## [1.0.1]

### Added
Expand Down
4 changes: 3 additions & 1 deletion packages/subgraph/manifest/subgraph.placeholder.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -303,4 +303,6 @@ templates:
file: $ARAGON_OSX_MODULE/artifacts/src/framework/plugin/repo/PluginRepo.sol/PluginRepo.json
eventHandlers:
- event: VersionCreated(uint8,uint16,indexed address,bytes)
handler: handleVersionCreated
handler: handleVersionCreated
- event: ReleaseMetadataUpdated(uint8,bytes)
handler: handleReleaseMetadataUpdated
16 changes: 13 additions & 3 deletions packages/subgraph/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ type Dao @entity {
type PluginRepo @entity(immutable: true) {
id: ID! # address
subdomain: String!
versions: [PluginVersion!]! @derivedFrom(field: "pluginRepo")
releases: [PluginRelease!]! @derivedFrom(field: "pluginRepo")
# Holds all preparations. Also applied ones.
preparations: [PluginPreparation!]! @derivedFrom(field: "pluginRepo")
# Holds all installed and uninstalled installations.
Expand All @@ -188,13 +188,23 @@ type PluginSetup @entity(immutable: true) {
versions: [PluginVersion!]! @derivedFrom(field: "pluginSetup")
}

type PluginRelease @entity {
id: ID! # pluginRepo + release
pluginRepo: PluginRepo!
release: Int!
metadata: String! # release metadata
builds: [PluginVersion!]! @derivedFrom(field: "release")
}

type PluginVersion @entity(immutable: true) {
id: ID! # pluginRepo + release + build
pluginRepo: PluginRepo!
pluginSetup: PluginSetup
release: Int!

release: PluginRelease!
build: Int!
metadata: Bytes!

metadata: String! # build metadata
# Holds all preparations. Also applied ones.
preparations: [PluginPreparation!]! @derivedFrom(field: "pluginVersion")
# Holds all installed and uninstalled installations.
Expand Down
60 changes: 50 additions & 10 deletions packages/subgraph/src/plugin/pluginRepo.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,60 @@
import {VersionCreated} from '../../generated/templates/PluginRepoTemplate/PluginRepo';
import {PluginVersion, PluginSetup} from '../../generated/schema';
import {
ReleaseMetadataUpdated,
VersionCreated
} from '../../generated/templates/PluginRepoTemplate/PluginRepo';
import {
PluginVersion,
PluginSetup,
PluginRelease
} from '../../generated/schema';

export function handleVersionCreated(event: VersionCreated): void {
let id = `${event.address.toHexString()}_${event.params.release.toString()}_${event.params.build.toString()}`;
// PluginSetup
let pluginSetupId = event.params.pluginSetup.toHexString();
let entity = new PluginVersion(id);
entity.pluginRepo = event.address.toHexString();
entity.release = event.params.release;
entity.build = event.params.build;
entity.pluginSetup = pluginSetupId;
entity.metadata = event.params.buildMetadata;
entity.save();

let pluginSetupEntity = PluginSetup.load(pluginSetupId);
if (!pluginSetupEntity) {
pluginSetupEntity = new PluginSetup(pluginSetupId);
pluginSetupEntity.save();
}

// PluginVersion
let pluginRepoId = event.address.toHexString();
let pluginRelease = event.params.release.toString();
let pluginReleaseId = pluginRepoId.concat('_').concat(pluginRelease);
let pluginVersionId = pluginReleaseId
.concat('_')
.concat(event.params.build.toString());

let entity = new PluginVersion(pluginVersionId);
entity.pluginRepo = event.address.toHexString();
entity.pluginSetup = pluginSetupId;

entity.release = pluginReleaseId;
entity.build = event.params.build;

entity.metadata = event.params.buildMetadata.toString();
Rekard0 marked this conversation as resolved.
Show resolved Hide resolved
entity.save();
}

export function handleReleaseMetadataUpdated(
event: ReleaseMetadataUpdated
): void {
let pluginRepoId = event.address.toHexString();
let pluginRelease = event.params.release;
let releaseMetadata = event.params.releaseMetadata.toString();
Rekard0 marked this conversation as resolved.
Show resolved Hide resolved

let pluginReleaseEntityId = pluginRepoId
.concat('_')
.concat(pluginRelease.toString());

let pluginReleaseEntity = PluginRelease.load(pluginReleaseEntityId);
Rekard0 marked this conversation as resolved.
Show resolved Hide resolved
if (!pluginReleaseEntity) {
pluginReleaseEntity = new PluginRelease(pluginReleaseEntityId);
novaknole marked this conversation as resolved.
Show resolved Hide resolved
pluginReleaseEntity.pluginRepo = pluginRepoId;
pluginReleaseEntity.release = pluginRelease;
}

pluginReleaseEntity.metadata = releaseMetadata;
pluginReleaseEntity.save();
}
124 changes: 108 additions & 16 deletions packages/subgraph/tests/plugin/pluginRepo.test.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,126 @@
import {assert, clearStore, test} from 'matchstick-as/assembly/index';
import {ADDRESS_ONE} from '../constants';
import {createVersionCreated} from './utils';
import {handleVersionCreated} from '../../src/plugin/pluginRepo';
import {ADDRESS_ONE, ONE} from '../constants';
import {createReleaseMetadataUpdatedEvent, createVersionCreated} from './utils';
import {
handleReleaseMetadataUpdated,
handleVersionCreated
} from '../../src/plugin/pluginRepo';
import {Bytes} from '@graphprotocol/graph-ts';

test('versionCreated event', () => {
test('PluginRepo (handleVersionCreated) mappings with mock event', () => {
let release = ONE;
let build = ONE;
let pluginSetup = ADDRESS_ONE;
let buildMetadata = 'Qm1234';

let event = createVersionCreated(
'1',
'1',
ADDRESS_ONE,
Bytes.fromHexString('0x1234')
release,
build,
pluginSetup,
Bytes.fromUTF8(buildMetadata)
);

handleVersionCreated(event);
let id = `${event.address.toHexString()}_1_1`;

let pluginRepoId = event.address.toHexString();

let pluginVersionId = pluginRepoId
.concat('_')
.concat(release)
.concat('_')
.concat(build);

let pluginReleaseId = pluginRepoId.concat('_').concat(release);

assert.entityCount('PluginVersion', 1);
assert.fieldEquals('PluginVersion', id, 'id', id);
assert.fieldEquals('PluginVersion', pluginVersionId, 'id', pluginVersionId);
assert.fieldEquals(
'PluginVersion',
id,
pluginVersionId,
'pluginRepo',
event.address.toHexString()
);
assert.fieldEquals('PluginVersion', id, 'release', '1');
assert.fieldEquals('PluginVersion', id, 'build', '1');
assert.fieldEquals('PluginVersion', id, 'pluginSetup', ADDRESS_ONE);
assert.fieldEquals('PluginVersion', id, 'metadata', '0x1234');
assert.fieldEquals(
'PluginVersion',
pluginVersionId,
'release',
pluginReleaseId
);
assert.fieldEquals('PluginVersion', pluginVersionId, 'build', build);
assert.fieldEquals(
'PluginVersion',
pluginVersionId,
'pluginSetup',
pluginSetup
);
assert.fieldEquals(
'PluginVersion',
pluginVersionId,
'metadata',
buildMetadata
);

assert.entityCount('PluginSetup', 1);
assert.fieldEquals('PluginSetup', ADDRESS_ONE, 'id', ADDRESS_ONE);
assert.fieldEquals('PluginSetup', pluginSetup, 'id', pluginSetup);

clearStore();
});

test('PluginRepo (handleReleaseMetadataUpdated) mappings with mock event', () => {
let release = ONE;
let releaseMetadata = 'Qm1234';

let event = createReleaseMetadataUpdatedEvent(
release,
Bytes.fromUTF8(releaseMetadata)
);

handleReleaseMetadataUpdated(event);

assert.entityCount('PluginRelease', 1);

let pluginRepoId = event.address.toHexString();
let pluginReleaseEntityId = pluginRepoId.concat('_').concat(release);

assert.fieldEquals(
'PluginRelease',
pluginReleaseEntityId,
'id',
pluginReleaseEntityId
);
assert.fieldEquals(
'PluginRelease',
pluginReleaseEntityId,
'pluginRepo',
pluginRepoId
);
assert.fieldEquals(
'PluginRelease',
pluginReleaseEntityId,
'release',
release
);
assert.fieldEquals(
'PluginRelease',
pluginReleaseEntityId,
'metadata',
releaseMetadata
);

// simulated update of release metadata
let updatedMetadata = 'Qm5678';
let updatingMetadataEvent = createReleaseMetadataUpdatedEvent(
release,
Bytes.fromUTF8(updatedMetadata)
);
handleReleaseMetadataUpdated(updatingMetadataEvent);

assert.entityCount('PluginRelease', 1);

assert.fieldEquals(
'PluginRelease',
pluginReleaseEntityId,
'metadata',
updatedMetadata
);
});
28 changes: 27 additions & 1 deletion packages/subgraph/tests/plugin/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import {Address, BigInt, Bytes, ethereum} from '@graphprotocol/graph-ts';
import {newMockEvent} from 'matchstick-as';
import {VersionCreated} from '../../generated/templates/PluginRepoTemplate/PluginRepo';
import {
ReleaseMetadataUpdated,
VersionCreated
} from '../../generated/templates/PluginRepoTemplate/PluginRepo';
import {
InstallationApplied,
InstallationPrepared,
Expand All @@ -13,6 +16,29 @@ import {
UpdatePreparedSetupPayloadStruct
} from '../../generated/PluginSetupProcessor/PluginSetupProcessor';

export function createReleaseMetadataUpdatedEvent(
release: string,
buildMetadata: Bytes
): ReleaseMetadataUpdated {
let newEvent = changetype<ReleaseMetadataUpdated>(newMockEvent());

newEvent.parameters = [];

let releaseParam = new ethereum.EventParam(
'release',
ethereum.Value.fromUnsignedBigInt(BigInt.fromString(release))
);
let buildMetadataParam = new ethereum.EventParam(
'buildMetadata',
ethereum.Value.fromBytes(buildMetadata)
);

newEvent.parameters.push(releaseParam);
newEvent.parameters.push(buildMetadataParam);

return newEvent;
}

export function createVersionCreated(
release: string,
build: string,
Expand Down