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

Zone registry tests #50

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
16 changes: 14 additions & 2 deletions sdk/src/common/ao/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,24 @@ export async function aoDryRun(args: APIDryRunType): Promise<any> {
try {
const tags = [{ name: 'Action', value: args.action }];
if (args.tags) tags.push(...args.tags);
let data = JSON.stringify(args.data || {});
let dataPayload;
if (typeof(args.data) === "object") {
dataPayload = JSON.stringify(args.data || {});
} else if (typeof(args.data) === "string") {
// try to parse json and throw an error if it can't
try {
const jsonresult = JSON.parse(args.data)
} catch (e) {
console.error(e);
throw new Error("Invalid JSON data");
}
dataPayload = args.data;
}

const response = await dryrun({
process: args.processId,
tags: tags,
data: data,
data: dataPayload,
});

if (response.Messages && response.Messages.length) {
Expand Down
4 changes: 3 additions & 1 deletion sdk/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from './common';
export * from './common';
export * from './types';
export * from './zone';
2 changes: 1 addition & 1 deletion sdk/src/types/ao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export type APIDryRunType = {
processId: string;
action: string;
tags?: TagType[] | null;
data?: string | null;
data?: string | object;
};

export type APICreateProcessType = {
Expand Down
2 changes: 2 additions & 0 deletions sdk/src/zone/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './profile';
export * from './zone';
4 changes: 0 additions & 4 deletions sdk/src/zone/types.ts

This file was deleted.

3 changes: 2 additions & 1 deletion sdk/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"lib": ["dom", "dom.iterable", "esnext"],
"paths": {
"types/*": ["types/*"],
"common/*": ["common/*"]
"common/*": ["common/*"],
"zone/*": ["zone/*"]
}
},
"include": ["src"],
Expand Down
131 changes: 128 additions & 3 deletions services/profiles/registry.lua
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,131 @@ local function is_authorized(profile_id, user_id, roles)
return authorized
end


local function handle_prepare_db(msg)
if msg.From ~= Owner and msg.From ~= ao.id then
ao.send({
Target = msg.From,
Action = 'Authorization-Error',
Tags = {
Status = 'Error',
Message = 'Unauthorized to access this handler'
}
})
return
end

Db:exec [[
CREATE TABLE IF NOT EXISTS zone_auth (
zone_id TEXT NOT NULL,
user_id TEXT NOT NULL,
role TEXT NOT NULL,
PRIMARY KEY (zone_id, user_id)
);
]]

ao.send({
Target = Owner,
Action = 'DB-Init-Success',
Tags = {
Status = 'Success',
Message = 'Created DB'
}
})
end

local function handle_update_role(msg)
local decode_check, data = decode_message_data(msg.Data)
local zone_id = msg.Target
local user_id = msg.From
if decode_check and data then
if not data.Id or not data.Op then
ao.send({
Target = zone_id,
Action = 'Input-Error',
Tags = {
Status = 'Error',
Message = 'Invalid arguments, required { Id, Op, Role }'
}
})
return
end
end

if not is_authorized(zone_id, user_id, HandlerRoles['Zone.Update-Role']) then
ao.send({
Target = zone_id,
Action = 'Authorization-Error',
Tags = {
Status = 'Error',
Message = 'Unauthorized to access this handler'
}
})
return
end

local Id = data.Id or msg.Tags.Id
local Role = data.Role or msg.Tags.Role
local Op = data.Op or msg.Tags.Op

if not Id or not Op then
ao.send({
Target = zone_id,
Action = 'Input-Error',
Tags = {
Status = 'Error',
Message =
'Invalid arguments, required { Id, Op } in data or tags'
}
})
return
end
-- handle add, update, or remove Ops
local stmt
if data.Op == 'Add' then
stmt = Db:prepare(
'INSERT INTO zone_auth (zone_id, user_id, role) VALUES (?, ?, ?)')
stmt:bind_values(zone_id, Id, Role)

elseif data.Op == 'Update' then
stmt = Db:prepare(
'UPDATE zone_auth SET role = ? WHERE zone_id = ? AND user_id = ?')
stmt:bind_values(Role, zone_id, Id)

elseif data.Op == 'Delete' then
stmt = Db:prepare(
'DELETE FROM zone_auth WHERE zone_id = ? AND user_id = ?')
stmt:bind_values(zone_id, Id)
end

local step_status = stmt:step()
stmt:finalize()
if step_status ~= sqlite3.OK and step_status ~= sqlite3.DONE and step_status ~= sqlite3.ROW then
print("Error: " .. Db:errmsg())
ao.send({
Target = zone_id,
Action = 'DB_STEP_CODE',
Tags = {
Status = 'ERROR',
Message = 'sqlite step error'
},
Data = { DB_STEP_MSG = step_status }
})
return json.encode({ Code = step_status })
end

ao.send({
Target = zone_id,
Action = 'Success',
Tags = {
Status = 'Success',
Message = 'Auth Record Success'
},
Data = json.encode({ ProfileId = zone_id, DelegateAddress = Id, Role = Role })
})
end


local function process_profile_action(msg)

local reply_to = msg.From
Expand Down Expand Up @@ -274,10 +399,10 @@ Handlers.add('Prepare-Database', Handlers.utils.hasMatchingTag('Action', 'Prepar

Db:exec [[
CREATE TABLE IF NOT EXISTS ao_profile_authorization (
profile_id TEXT NOT NULL,
delegate_address TEXT NOT NULL,
zone_id TEXT NOT NULL,
user_id TEXT NOT NULL,
role TEXT NOT NULL,
PRIMARY KEY (profile_id, delegate_address),
PRIMARY KEY (zone_id, user_id)
FOREIGN KEY (profile_id) REFERENCES ao_profile_metadata (id) ON DELETE CASCADE
);
]]
Expand Down
15 changes: 4 additions & 11 deletions services/tests/unit/profileRegistry/profileRegistry.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,10 @@ test("should return no records if profile does not exist", async () => {
assert.equal(getTag(result?.Messages[0], "Status"), "Error")
})

test("should update profile in registry from old profile code", async () => {
const inputData = { DisplayName: "Who", DateUpdated: 126666, DateCreated: 125555}
const result = await Send({ Target: PROFILE_REGISTRY_ID, From: STEVE_PROFILE_ID, Owner: STEVE_PROFILE_ID, AuthorizedAddress: STEVE_WALLET, Action: "Update-Profile", Data: JSON.stringify(inputData) })
logSendResult(result, 'Update-Profile-1');
assert.equal(getTag(result?.Messages[0], "Status"), "Success")
})

test("should update profile in registry v001", async () => {
const inputData = { DisplayName: "Who Else", DateUpdated: 126666 }
const result = await Send({ From: STEVE_WALLET, Owner: STEVE_WALLET, Target: STEVE_PROFILE_ID, Action: "Update-Profile", Data: JSON.stringify(inputData) })
logSendResult(result, 'Update-Profile-1');
test("should test profile for delegate", async () => {
const inputData = { Address: STEVE_WALLET }
const result = await Send({Action: 'Get-Profiles-By-Delegate', Data: JSON.stringify(inputData)})
logSendResult(result, "Get-Profiles")
assert.equal(getTag(result?.Messages[0], "Status"), "Success")
})

Expand Down
78 changes: 78 additions & 0 deletions services/tests/unit/zoneRegistry/zoneMetaRegistry.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { test } from 'node:test'
import * as assert from 'node:assert'
import { SendFactory } from '../../utils/aos.helper.js'
import fs from 'node:fs'
import path from 'node:path'


import {getTag, logSendResult} from "../../utils/message.js";
const registryLuaPath = path.resolve('../zone-registries/zone-metadata-registry.lua');


const PROFILE_REGISTRY_ID = 'dWdBohXUJ22rfb8sSChdFh6oXJzbAtGe4tC6__52Zk4';
const REGISTRY_OWNER = "ADDRESS_R_CZLr2EkkwzIXP5A64QmtME6Bxa8bGmbzI";
const ANON_WALLET = "ADDRESS_ANON_r2EkkwzIXP5A64QmtME6Bxa8bGmbzI";
const PROFILE_A_USERNAME = "Steve";
const PROFILE_B_USERNAME = "Bob";
const PROFILE_B_HANDLE = "Bobbie";
const PROFILE_BOB_ID = "PROFILE_B_CZLr2EkkwzIXP5A64QmtME6Bxa8bGmbzI";
const STEVE_PROFILE_ID = "PROFILE_A_CZLr2EkkwzIXP5A64QmtME6Bxa8bGmbzI";
const STEVE_WALLET = "ADDRESS_A_CZLr2EkkwzIXP5A64QmtME6Bxa8bGmbzI";
const BOB_WALLET = "ADDRESS_B_CZLr2EkkwzIXP5A64QmtME6Bxa8bGmbzI";

const {Send} = SendFactory({processId: PROFILE_REGISTRY_ID, moduleId: '5555', defaultOwner: ANON_WALLET, defaultFrom: ANON_WALLET});
test("------------------------------BEGIN TEST------------------------------")
test("meta zone: load profileRegistry source", async () => {
try {
const code = fs.readFileSync(registryLuaPath, 'utf-8')
const result = await Send({ From: REGISTRY_OWNER,
Owner: REGISTRY_OWNER, Target: PROFILE_REGISTRY_ID, Action: "Eval", Data: code })
logSendResult(result, "Load Source")
} catch (error) {
console.log(error)
}
})

test("meta zone: should prepare database", async () => {
const preparedDb = await Send({
From: REGISTRY_OWNER,
Owner: REGISTRY_OWNER,
Target: PROFILE_REGISTRY_ID,
Id: "1111",
Tags: {
Action: "Prepare-Database"
}
})
logSendResult(preparedDb, "Prepare-Database")
})

test("meta zone: should find no zone at missing wallet address", async () => {
const inputData = { Address: STEVE_WALLET }
const result = await Send({Action: "Get-Zones-For-User", Data: JSON.stringify(inputData)})
logSendResult(result, "Find-No-Zones")
assert.equal(getTag(result?.Messages[0], "Status"), "Error")
})

test("meta zone: Bob should create zone in registry", async () => {
// read the assigned create/update profile methods from user spawn
const inputData = { DisplayName: PROFILE_B_HANDLE, UserName: PROFILE_B_USERNAME, DateCreated: 125555, DateUpdated: 125555 }
// simulate the assignement from the spawn tx
const result = await Send({ Target: PROFILE_BOB_ID, From: BOB_WALLET, Owner: BOB_WALLET, Action: "Create-Zone", Data: JSON.stringify(inputData) }, { messageId: PROFILE_BOB_ID})
logSendResult(result, 'Create-Profile-B');
assert.equal(getTag(result?.Messages[0], "Status"), "Success")
})

test("meta zone: should find Bob's zone roles", async () => {
const inputData = { Address: BOB_WALLET }
const result = await Send({Action: "Get-Zones-For-User", Data: JSON.stringify(inputData)})
logSendResult(result, "Find-Bob-Zone")
assert.equal(getTag(result?.Messages[0], "Status"), "Success")
})

test("meta zone: should find Bob's metadata", async () => {
const inputData = { ZoneIds: [PROFILE_BOB_ID] }
const result = await Send({Action: "Get-Zones-Metadata", Data: JSON.stringify(inputData)})
logSendResult(result, "Get-Zones")
assert.equal(getTag(result?.Messages[0], "Status"), "Success")
})

Loading