-
Notifications
You must be signed in to change notification settings - Fork 11
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
Badge trading #231
base: badge-trading
Are you sure you want to change the base?
Badge trading #231
Conversation
int amount = amountOpt.Map(i => i.Number).OrElse(1); | ||
int form = PkmnForms.pokemonHasForms(species) ? 0 : 1; // default to the first listed form if form is unspecified | ||
bool shiny = shinyOpt.IsPresent ? shinyOpt.Value : false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be condensed to shinyOpt.OrElse(false)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very neat so far! You have written few TODOs, but I also don't mind merging an intermediate state as long the commands aren't hooked up yet and therefore aren't part of production code
@@ -64,26 +68,55 @@ private void InitIndexes() | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(above here, can't comment on the correct line).
Please add indexes for the new filterable fields.
Nitpick: Also this is fine for now, but I suspect filtering for "!= true" for the shiny field might not work properly for the index. Maybe it does, but it's something you can test if you're still motivated. E.g. by enabling profiling level 2, issuing a query, and looking at the execution plan.
Badge.BadgeSource? source = sourceOpt.IsPresent ? sourceOpt.Value : null; | ||
string? form = formOpt.IsPresent ? formOpt.Value.Name : null; | ||
bool? shiny = shinyOpt.IsPresent ? shinyOpt.Value : false; | ||
return (source, form, shiny); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks equivalent to
return (sourceOpt.OrElse(null), formOpt.OrElse(null), shinyOpt.OrElse(false));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also is defaulting to shiny=false correct? It's still nullable, which indicates to me you wanted it to be kind of a tri-state of "yes", "no" and "don't care whether shiny or not"
public async Task<List<BadgeBuyOffer>> FindAllBuyOffers(string? userId, PkmnSpecies species, string? form, Badge.BadgeSource? source, bool? shiny) | ||
{ | ||
FilterDefinition<BadgeBuyOffer> filter = Builders<BadgeBuyOffer>.Filter.Empty; | ||
if (userId != null) | ||
filter &= Builders<BadgeBuyOffer>.Filter.Eq(b => b.UserId, userId); | ||
if (species != null) | ||
filter &= Builders<BadgeBuyOffer>.Filter.Eq(b => b.Species, species); | ||
if (form != null) | ||
filter &= Builders<BadgeBuyOffer>.Filter.Eq(b => b.Form, form); | ||
if (source != null) | ||
filter &= Builders<BadgeBuyOffer>.Filter.Eq(b => b.Source, source); | ||
if (shiny == true) | ||
filter &= Builders<BadgeBuyOffer>.Filter.Eq(b => b.Shiny, true); | ||
else | ||
filter &= Builders<BadgeBuyOffer>.Filter.Ne(b => b.Shiny, true); | ||
|
||
return await BuyOfferCollection.Find(filter).ToListAsync(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm not sure how I feel about this duplicate code. Especially since it is a bit finnicky in regards to the shiny filter requiring to filter for "!= true". If this is equal to the variant in BadgeRepo, can it be extracted as a utility method somewhere that builds a FilterDefinition<T>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is something like a static method in Badge class what you had in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like that, yeah. Just somewhere where it's namespaced somewhat sensibly
Badge badgeBForSale = new Badge("B", userId, species, source, after, form, shiny) { SellPrice = price }; | ||
List<Badge> notForSale = new List<Badge> { badgeA, badgeB }; | ||
|
||
_mockBadgeRepo.Setup(m => m.FindAllNotForSaleByCustom(userId, species, form, source, shiny)).Returns(Task.FromResult(notForSale)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iirc there's a ReturnsAsync
that removes the need to wrap the result in Task.FromResult(...)
internal class MockClock : IClock | ||
{ | ||
public Instant FixedCurrentInstant = Instant.FromUnixTimeSeconds(1234567890); | ||
public Instant GetCurrentInstant() => FixedCurrentInstant; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why I used this class somewhere in the first place. I believe it is redundant because Moq mocks should work fine
new Transaction<User>(buyer, -1 * offer.Price, "BadgePurchase"), | ||
new Transaction<User>(seller, offer.Price, "BadgeSale") | ||
} | ||
); | ||
await _badgeRepo.TransferBadges(new List<Badge> { badge }.ToImmutableList(), buyer.Id, "BadgeSale", new Dictionary<string, object?>() { }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please put these transaction types in TransactionType
/// Sorts badges according to the priority in which they should be sold. | ||
/// Current sorting rule: prioritize keeping 1 of each form, then sell newer badges first. Top priority badge will be selected for sale when fufilling offers. | ||
/// </summary> | ||
private static List<Badge> SortBySpecialness(IEnumerable<Badge> toSort) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a bunch of stuff, including this, probably needs more unit tests. Maybe you'll even have to make this sorter its own thing for that to be easier
WIP pull request for badge trading and updates to badges in general.