Skip to content

Commit

Permalink
Contract improvements and new features
Browse files Browse the repository at this point in the history
  - exposed voting for extra options
  - added editing question description capability

Closes #48
Closes #50
  • Loading branch information
vexy committed Nov 21, 2022
1 parent 37ec3ce commit 0098ac8
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ build/
cache/
artifacts/
typechain-types/
/typechain-types/

# node modules
node_modules/
Expand Down
73 changes: 47 additions & 26 deletions contracts/MainPlatform.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ struct QuestionInfo {
uint id;
address owner;
string title;
string description;
string[] labels;
uint[] scores;
uint[3] extras;
Expand Down Expand Up @@ -100,27 +101,41 @@ contract MainPlatform {
}

///@notice Lists all the question of the platform (output: QuestionInfo[])
function getPlatformQuestions() public view returns (QuestionInfo[] memory){
function getPlatformQuestions() public view
returns (QuestionInfo[] memory){
QuestionInfo[] memory output = new QuestionInfo[](platformQuestions.length);

//cycle through all questions and format output
for(uint i = 0; i < platformQuestions.length; i++ ) {
output[i] = QuestionInfo(
i, //as ID of the question
platformQuestions[i].getOwner(),
platformQuestions[i].getTitle(),
platformQuestions[i].getLabels(),
platformQuestions[i].getScores(),
platformQuestions[i].getExtras(),
platformQuestions[i].totalVoters(),
platformQuestions[i].hasVoted()
);
output[i] = fabricateQuestionInfo(i);
}

return output;
}

//@ -- Scoring and scoring intel
function getQuestionInfo(uint questionID) public view
validAddress validQuestionIndex(questionID) registeredUsersOnly
returns(QuestionInfo memory) {
return fabricateQuestionInfo(questionID);
}

// private helper function
function fabricateQuestionInfo(uint _id) private view
returns(QuestionInfo memory) {
return QuestionInfo(
_id, //as ID of the question
platformQuestions[_id].getOwner(),
platformQuestions[_id].getTitle(),
platformQuestions[_id].getDescription(),
platformQuestions[_id].getLabels(),
platformQuestions[_id].getScores(),
platformQuestions[_id].getExtras(),
platformQuestions[_id].totalVoters(),
platformQuestions[_id].hasVoted()
);
}

//@ -- Scoring and extras reporting

function vote(uint questionID, uint voteOption)
validAddress validQuestionIndex(questionID)
Expand All @@ -130,20 +145,20 @@ contract MainPlatform {
platformQuestions[questionID].accept(voteOption);
}

function getQuestionInfo(uint questionID)
validAddress validQuestionIndex(questionID) registeredUsersOnly
public view
returns(QuestionInfo memory) {
return QuestionInfo(
questionID, //as ID of the question
platformQuestions[questionID].getOwner(),
platformQuestions[questionID].getTitle(),
platformQuestions[questionID].getLabels(),
platformQuestions[questionID].getScores(),
platformQuestions[questionID].getExtras(),
platformQuestions[questionID].totalVoters(),
platformQuestions[questionID].hasVoted()
);
function extraVote(uint questionID, uint extraOption)
validAddress validQuestionIndex(questionID)
registeredUsersOnly // pointsDeducible ?
public {
require(extraOption < 3, "Illegal 'extra option' argument. Must be between 0 and 2.");
if (extraOption == 0) {
platformQuestions[questionID].none();
} else {
if (extraOption == 1) {
platformQuestions[questionID].malformed();
} else {
platformQuestions[questionID].report();
}
}
}

//@ -- Stats (add more later)
Expand All @@ -163,4 +178,10 @@ contract MainPlatform {
function owner() public view returns (address) {
return platformOwner;
}

function editDescription(uint questionID, string calldata newDescription)
validAddress registeredUsersOnly validQuestionIndex(questionID)
payable public {
platformQuestions[questionID].editDescription(newDescription);
}
}
2 changes: 1 addition & 1 deletion contracts/QuestionFrame.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ contract QuestionFrame {
questionFrame.extras[uint(EXTRAS.ju_gospode_boze)] += 1;
}

/* ---- SCORES AND EXTRAS GETTERS ---- */
/* ---- SCORES AND EXTRAS GETTERS ---- */
function score(uint element) public view returns (uint) {
return questionFrame.question.score(element);
}
Expand Down
61 changes: 57 additions & 4 deletions test/main_platform_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ describe("Testing Suite :: [MainPlatform contract]", async function () {
} else {
platformResponse = await platformContract.addQuestion(testTitle, testLabels);
}

// console.log("\t-- New Question created:");
// console.log("\t-- Owner: ", platformResponse.from);
// console.log("\t-- ID value: ", platformResponse.value.toNumber());

const newQuestionID = platformResponse.value.toNumber(); //this is attached method by NigNumber
return Promise.resolve(newQuestionID);
Expand All @@ -64,6 +60,7 @@ describe("Testing Suite :: [MainPlatform contract]", async function () {
// perform signer1 registration and perform check
await registerUsers(signer1);
expect(await platformContract.connect(signer1).isRegisteredUser()).to.equal(true);
expect(await platformContract.connect(signer1).userBalance(signer1.address)).to.equal(startingPoints);
});

it("Can recognize non-registered users", async function() {
Expand Down Expand Up @@ -178,6 +175,42 @@ describe("Testing Suite :: [MainPlatform contract]", async function () {
expect(qInfoResponse.totalVoters).to.equal(ethers.BigNumber.from(1));
expect(qInfoResponse.hasVoted).to.equal(true);
});

it("Registered user can provide extra:none", async function() {
// register signer1 and create a question
await registerUsers(signer1);
const qID = await createTestQuestion(signer1);
expect(await platformContract.connect(signer1).totalQuestions()).to.equal(1);

await platformContract.connect(signer1).extraVote(qID, 0);
const qiResp = await platformContract.connect(signer1).getQuestionInfo(qID);

expect(qiResp.extras[0]).to.equal(1);
});

it("Registered user can provide extra:malformed", async function() {
// register signer1 and create a question
await registerUsers(signer1);
const qID = await createTestQuestion(signer1);
expect(await platformContract.connect(signer1).totalQuestions()).to.equal(1);

await platformContract.connect(signer1).extraVote(qID, 1);
const qiResp = await platformContract.connect(signer1).getQuestionInfo(qID);

expect(qiResp.extras[1]).to.equal(1);
});

it("Registered user can provide extra:report", async function() {
// register signer1 and create a question
await registerUsers(signer1);
const qID = await createTestQuestion(signer1);
expect(await platformContract.connect(signer1).totalQuestions()).to.equal(1);

await platformContract.connect(signer1).extraVote(qID, 2);
const qiResp = await platformContract.connect(signer1).getQuestionInfo(qID);

expect(qiResp.extras[2]).to.equal(1);
});
});

context("Questions visibility and correctness", async function() {
Expand All @@ -194,6 +227,7 @@ describe("Testing Suite :: [MainPlatform contract]", async function () {
expect(qInfoResponse.id).to.equal(0);
expect(qInfoResponse.owner).to.equal(signer1.address);
expect(qInfoResponse.title).to.equal("New Question");
expect(qInfoResponse.description).to.equal('');
expect(qInfoResponse.labels[0]).to.equal('one');
expect(qInfoResponse.labels[1]).to.equal('two');
expect(qInfoResponse.labels[2]).to.equal('three');
Expand All @@ -206,5 +240,24 @@ describe("Testing Suite :: [MainPlatform contract]", async function () {
expect(qInfoResponse.totalVoters).to.equal(0);
expect(qInfoResponse.hasVoted).to.equal(false);
});

it("Question description can be edited", async function() {
const expectedID = 0;
const expectedTotalQuestions = 1;

const id = await createTestQuestion(); // this returns number
expect(id).to.equal(expectedID);
expect(await platformContract.totalQuestions()).to.equal(expectedTotalQuestions);

// mark intial state
const qInfoStart = await platformContract.getQuestionInfo(id);
// perform description edit
await platformContract.editDescription(id, 'New description');
// mark ending state
const qInfoAfter = await platformContract.getQuestionInfo(id);

expect(qInfoStart.description).to.equal("");
expect(qInfoAfter.description).to.equal('New description');
});
});
});
81 changes: 81 additions & 0 deletions typechain-types/MainPlatform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
CallOverrides,
ContractTransaction,
Overrides,
PayableOverrides,
PopulatedTransaction,
Signer,
utils,
Expand All @@ -27,6 +28,7 @@ export type QuestionInfoStruct = {
id: PromiseOrValue<BigNumberish>;
owner: PromiseOrValue<string>;
title: PromiseOrValue<string>;
description: PromiseOrValue<string>;
labels: PromiseOrValue<string>[];
scores: PromiseOrValue<BigNumberish>[];
extras: [
Expand All @@ -42,6 +44,7 @@ export type QuestionInfoStructOutput = [
BigNumber,
string,
string,
string,
string[],
BigNumber[],
[BigNumber, BigNumber, BigNumber],
Expand All @@ -51,6 +54,7 @@ export type QuestionInfoStructOutput = [
id: BigNumber;
owner: string;
title: string;
description: string;
labels: string[];
scores: BigNumber[];
extras: [BigNumber, BigNumber, BigNumber];
Expand All @@ -61,6 +65,8 @@ export type QuestionInfoStructOutput = [
export interface MainPlatformInterface extends utils.Interface {
functions: {
"addQuestion(string,string[])": FunctionFragment;
"editDescription(uint256,string)": FunctionFragment;
"extraVote(uint256,uint256)": FunctionFragment;
"getPlatformQuestions()": FunctionFragment;
"getQuestionInfo(uint256)": FunctionFragment;
"isRegisteredUser()": FunctionFragment;
Expand All @@ -75,6 +81,8 @@ export interface MainPlatformInterface extends utils.Interface {
getFunction(
nameOrSignatureOrTopic:
| "addQuestion"
| "editDescription"
| "extraVote"
| "getPlatformQuestions"
| "getQuestionInfo"
| "isRegisteredUser"
Expand All @@ -90,6 +98,14 @@ export interface MainPlatformInterface extends utils.Interface {
functionFragment: "addQuestion",
values: [PromiseOrValue<string>, PromiseOrValue<string>[]]
): string;
encodeFunctionData(
functionFragment: "editDescription",
values: [PromiseOrValue<BigNumberish>, PromiseOrValue<string>]
): string;
encodeFunctionData(
functionFragment: "extraVote",
values: [PromiseOrValue<BigNumberish>, PromiseOrValue<BigNumberish>]
): string;
encodeFunctionData(
functionFragment: "getPlatformQuestions",
values?: undefined
Expand Down Expand Up @@ -125,6 +141,11 @@ export interface MainPlatformInterface extends utils.Interface {
functionFragment: "addQuestion",
data: BytesLike
): Result;
decodeFunctionResult(
functionFragment: "editDescription",
data: BytesLike
): Result;
decodeFunctionResult(functionFragment: "extraVote", data: BytesLike): Result;
decodeFunctionResult(
functionFragment: "getPlatformQuestions",
data: BytesLike
Expand Down Expand Up @@ -186,6 +207,18 @@ export interface MainPlatform extends BaseContract {
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>;

editDescription(
questionID: PromiseOrValue<BigNumberish>,
newDescription: PromiseOrValue<string>,
overrides?: PayableOverrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>;

extraVote(
questionID: PromiseOrValue<BigNumberish>,
extraOption: PromiseOrValue<BigNumberish>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>;

getPlatformQuestions(
overrides?: CallOverrides
): Promise<[QuestionInfoStructOutput[]]>;
Expand Down Expand Up @@ -225,6 +258,18 @@ export interface MainPlatform extends BaseContract {
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>;

editDescription(
questionID: PromiseOrValue<BigNumberish>,
newDescription: PromiseOrValue<string>,
overrides?: PayableOverrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>;

extraVote(
questionID: PromiseOrValue<BigNumberish>,
extraOption: PromiseOrValue<BigNumberish>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>;

getPlatformQuestions(
overrides?: CallOverrides
): Promise<QuestionInfoStructOutput[]>;
Expand Down Expand Up @@ -264,6 +309,18 @@ export interface MainPlatform extends BaseContract {
overrides?: CallOverrides
): Promise<BigNumber>;

editDescription(
questionID: PromiseOrValue<BigNumberish>,
newDescription: PromiseOrValue<string>,
overrides?: CallOverrides
): Promise<void>;

extraVote(
questionID: PromiseOrValue<BigNumberish>,
extraOption: PromiseOrValue<BigNumberish>,
overrides?: CallOverrides
): Promise<void>;

getPlatformQuestions(
overrides?: CallOverrides
): Promise<QuestionInfoStructOutput[]>;
Expand Down Expand Up @@ -304,6 +361,18 @@ export interface MainPlatform extends BaseContract {
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<BigNumber>;

editDescription(
questionID: PromiseOrValue<BigNumberish>,
newDescription: PromiseOrValue<string>,
overrides?: PayableOverrides & { from?: PromiseOrValue<string> }
): Promise<BigNumber>;

extraVote(
questionID: PromiseOrValue<BigNumberish>,
extraOption: PromiseOrValue<BigNumberish>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<BigNumber>;

getPlatformQuestions(overrides?: CallOverrides): Promise<BigNumber>;

getQuestionInfo(
Expand Down Expand Up @@ -342,6 +411,18 @@ export interface MainPlatform extends BaseContract {
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<PopulatedTransaction>;

editDescription(
questionID: PromiseOrValue<BigNumberish>,
newDescription: PromiseOrValue<string>,
overrides?: PayableOverrides & { from?: PromiseOrValue<string> }
): Promise<PopulatedTransaction>;

extraVote(
questionID: PromiseOrValue<BigNumberish>,
extraOption: PromiseOrValue<BigNumberish>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<PopulatedTransaction>;

getPlatformQuestions(
overrides?: CallOverrides
): Promise<PopulatedTransaction>;
Expand Down
Loading

0 comments on commit 0098ac8

Please sign in to comment.