Skip to content

Commit

Permalink
✨ Ephemeral trophies
Browse files Browse the repository at this point in the history
  • Loading branch information
bal7hazar committed Nov 7, 2024
1 parent d6e13c6 commit 47eb7c1
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 27 deletions.
18 changes: 17 additions & 1 deletion packages/trophy/src/components/achievable.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ mod AchievableComponent {
hidden: bool,
index: u8,
points: u16,
start: u64,
end: u64,
group: felt252,
icon: felt252,
title: felt252,
Expand All @@ -54,7 +56,21 @@ mod AchievableComponent {
let store: Store = StoreTrait::new(world);

// [Event] Emit achievement creation
store.create(id, hidden, index, points, group, icon, title, description, tasks, data);
store
.create(
id,
hidden,
index,
points,
start,
end,
group,
icon,
title,
description,
tasks,
data
);
}

fn progress(
Expand Down
2 changes: 2 additions & 0 deletions packages/trophy/src/events/index.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub struct TrophyCreation {
hidden: bool,
index: u8,
points: u16,
start: u64,
end: u64,
group: felt252,
icon: felt252,
title: felt252,
Expand Down
72 changes: 60 additions & 12 deletions packages/trophy/src/events/trophy.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ use bushido_trophy::types::task::{Task, TaskTrait};
// Errors

pub mod errors {
pub const TROPHY_INVALID_ID: felt252 = 'TrophyCreation: invalid id';
pub const TROPHY_INVALID_TITLE: felt252 = 'TrophyCreation: invalid title';
pub const TROPHY_INVALID_DESCRIPTION: felt252 = 'TrophyCreation: invalid desc.';
pub const TROPHY_INVALID_TASKS: felt252 = 'TrophyCreation: invalid tasks.';
pub const TROPHY_INVALID_ID: felt252 = 'Trophy: invalid id';
pub const TROPHY_INVALID_TITLE: felt252 = 'Trophy: invalid title';
pub const TROPHY_INVALID_DESCRIPTION: felt252 = 'Trophy: invalid desc.';
pub const TROPHY_INVALID_TASKS: felt252 = 'Trophy: invalid tasks.';
pub const TROPHY_INVALID_DURATION: felt252 = 'Trophy: invalid duration.';
}

// Implementations
Expand All @@ -22,6 +23,8 @@ impl TrophyImpl of TrophyTrait {
hidden: bool,
index: u8,
points: u16,
start: u64,
end: u64,
group: felt252,
icon: felt252,
title: felt252,
Expand All @@ -34,8 +37,11 @@ impl TrophyImpl of TrophyTrait {
TrophyAssert::assert_valid_id(id);
TrophyAssert::assert_valid_title(title);
TrophyAssert::assert_valid_description(@description);
TrophyAssert::assert_valid_duration(start, end);
// [Return] TrophyCreation
TrophyCreation { id, hidden, index, points, group, icon, title, description, tasks, data }
TrophyCreation {
id, hidden, index, points, start, end, group, icon, title, description, tasks, data
}
}
}

Expand All @@ -60,6 +66,11 @@ impl TrophyAssert of AssertTrait {
fn assert_valid_tasks(tasks: Span<Task>) {
assert(tasks.len() > 0, errors::TROPHY_INVALID_TASKS);
}

#[inline]
fn assert_valid_duration(start: u64, end: u64) {
assert(end >= start, errors::TROPHY_INVALID_DURATION);
}
}

#[cfg(test)]
Expand All @@ -80,17 +91,32 @@ mod tests {
const TITLE: felt252 = 'TITLE';
const ICON: felt252 = 'ICON';
const TASK_ID: felt252 = 'TASK';
const START: u64 = 100;
const END: u64 = 200;

#[test]
fn test_achievement_creation_new() {
let tasks: Array<Task> = array![TaskTrait::new(TASK_ID, TOTAL, "TASK DESCRIPTION"),];
let achievement = TrophyTrait::new(
ID, HIDDEN, INDEX, POINTS, GROUP, ICON, TITLE, "DESCRIPTION", tasks.span(), "DATA"
ID,
HIDDEN,
INDEX,
POINTS,
START,
END,
GROUP,
ICON,
TITLE,
"DESCRIPTION",
tasks.span(),
"DATA"
);
assert_eq!(achievement.id, ID);
assert_eq!(achievement.hidden, HIDDEN);
assert_eq!(achievement.index, INDEX);
assert_eq!(achievement.points, POINTS);
assert_eq!(achievement.start, START);
assert_eq!(achievement.end, END);
assert_eq!(achievement.group, GROUP);
assert_eq!(achievement.icon, ICON);
assert_eq!(achievement.title, TITLE);
Expand All @@ -100,28 +126,50 @@ mod tests {
}

#[test]
#[should_panic(expected: ('TrophyCreation: invalid id',))]
#[should_panic(expected: ('Trophy: invalid id',))]
fn test_achievement_creation_new_invalid_id() {
let tasks: Array<Task> = array![TaskTrait::new(TASK_ID, TOTAL, "TASK DESCRIPTION"),];
TrophyTrait::new(
0, HIDDEN, INDEX, POINTS, GROUP, ICON, TITLE, "DESCRIPTION", tasks.span(), ""
0,
HIDDEN,
INDEX,
POINTS,
START,
END,
GROUP,
ICON,
TITLE,
"DESCRIPTION",
tasks.span(),
""
);
}

#[test]
#[should_panic(expected: ('TrophyCreation: invalid title',))]
#[should_panic(expected: ('Trophy: invalid title',))]
fn test_achievement_creation_new_invalid_title() {
let tasks: Array<Task> = array![TaskTrait::new(TASK_ID, TOTAL, "TASK DESCRIPTION"),];
TrophyTrait::new(
ID, HIDDEN, INDEX, POINTS, GROUP, ICON, 0, "DESCRIPTION", tasks.span(), ""
ID, HIDDEN, INDEX, POINTS, START, END, GROUP, ICON, 0, "DESCRIPTION", tasks.span(), ""
);
}

#[test]
#[should_panic(expected: ('TrophyCreation: invalid desc.',))]
#[should_panic(expected: ('Trophy: invalid desc.',))]
fn test_achievement_creation_new_invalid_description() {
let tasks: Array<Task> = array![TaskTrait::new(TASK_ID, TOTAL, "TASK DESCRIPTION"),];
TrophyTrait::new(ID, HIDDEN, INDEX, POINTS, GROUP, ICON, TITLE, "", tasks.span(), "");
TrophyTrait::new(
ID, HIDDEN, INDEX, POINTS, START, END, GROUP, ICON, TITLE, "", tasks.span(), ""
);
}

#[test]
#[should_panic(expected: ('Trophy: invalid duration.',))]
fn test_achievement_creation_new_invalid_duration() {
let tasks: Array<Task> = array![TaskTrait::new(TASK_ID, TOTAL, "TASK DESCRIPTION"),];
TrophyTrait::new(
ID, HIDDEN, INDEX, POINTS, START, 0, GROUP, ICON, TITLE, "DESCRIPTION", tasks.span(), ""
);
}
}

4 changes: 3 additions & 1 deletion packages/trophy/src/store.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ impl StoreImpl of StoreTrait {
hidden: bool,
index: u8,
points: u16,
start: u64,
end: u64,
group: felt252,
icon: felt252,
title: felt252,
Expand All @@ -49,7 +51,7 @@ impl StoreImpl of StoreTrait {
data: ByteArray,
) {
let event: TrophyCreation = TrophyTrait::new(
id, hidden, index, points, group, icon, title, description, tasks, data
id, hidden, index, points, start, end, group, icon, title, description, tasks, data
);
self.world.emit_event(@event);
}
Expand Down
6 changes: 6 additions & 0 deletions packages/trophy/src/tests/mocks/achiever.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ trait IAchiever<TContractState> {
hidden: bool,
index: u8,
points: u16,
start: u64,
end: u64,
group: felt252,
icon: felt252,
title: felt252,
Expand Down Expand Up @@ -66,6 +68,8 @@ pub mod Achiever {
hidden: bool,
index: u8,
points: u16,
start: u64,
end: u64,
group: felt252,
icon: felt252,
title: felt252,
Expand All @@ -81,6 +85,8 @@ pub mod Achiever {
hidden,
index,
points,
start,
end,
group,
icon,
title,
Expand Down
44 changes: 31 additions & 13 deletions packages/trophy/src/tests/test_achievable.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@ const TASK_ID: felt252 = 'TASK';
const HIDDEN: bool = false;
const INDEX: u8 = 0;
const POINTS: u16 = 10;
const START: u64 = 100;
const END: u64 = 200;
const TOTAL: u32 = 100;
const COUNT: u32 = 1;
const GROUP: felt252 = 'Group';
const ICON: felt252 = 'fa-khanda';
const TITLE: felt252 = 'Title';

// Tests

#[test]
Expand All @@ -44,7 +47,20 @@ fn test_achievable_create() {
let tasks = array![TaskTrait::new(TASK_ID, TOTAL, "Description")].span();
systems
.achiever
.create(TROPHY_ID, HIDDEN, INDEX, POINTS, GROUP, ICON, TITLE, "Description", tasks, "");
.create(
TROPHY_ID,
HIDDEN,
INDEX,
POINTS,
START,
END,
GROUP,
ICON,
TITLE,
"Description",
tasks,
""
);
let contract_event = starknet::testing::pop_log::<Event>(world.dispatcher.contract_address)
.unwrap();
match contract_event {
Expand All @@ -53,18 +69,20 @@ fn test_achievable_create() {
assert_eq!(*event.values.at(0), 0);
assert_eq!(*event.values.at(1), INDEX.into());
assert_eq!(*event.values.at(2), POINTS.into());
assert_eq!(*event.values.at(3), GROUP.into());
assert_eq!(*event.values.at(4), ICON.into());
assert_eq!(*event.values.at(5), TITLE.into());
assert_eq!(*event.values.at(6), 0);
assert_eq!(*event.values.at(7), 'Description');
assert_eq!(*event.values.at(8), 11);
assert_eq!(*event.values.at(9), 1);
assert_eq!(*event.values.at(10), TASK_ID);
assert_eq!(*event.values.at(11), TOTAL.into());
assert_eq!(*event.values.at(12), 0);
assert_eq!(*event.values.at(13), 'Description');
assert_eq!(*event.values.at(14), 11);
assert_eq!(*event.values.at(3), START.into());
assert_eq!(*event.values.at(4), END.into());
assert_eq!(*event.values.at(5), GROUP.into());
assert_eq!(*event.values.at(6), ICON.into());
assert_eq!(*event.values.at(7), TITLE.into());
assert_eq!(*event.values.at(8), 0);
assert_eq!(*event.values.at(9), 'Description');
assert_eq!(*event.values.at(10), 11);
assert_eq!(*event.values.at(11), 1);
assert_eq!(*event.values.at(12), TASK_ID);
assert_eq!(*event.values.at(13), TOTAL.into());
assert_eq!(*event.values.at(14), 0);
assert_eq!(*event.values.at(15), 'Description');
assert_eq!(*event.values.at(16), 11);
},
_ => {},
}
Expand Down

0 comments on commit 47eb7c1

Please sign in to comment.