Introducing Reputation System0:00
Alright, I want to get started on our first feature. So you'll see I've added Reputation support here. So the basic idea is, as you participate in the forum, you accrue reputation points. And these points can serve any purpose, but most specifically, to give some indication as to your skill level, or at the very least, your trustability. If one person has 2 million points and the other has 12, you kind of know who to trust a bit more. But also it can be used for a number of things. So these point values I have here will almost certainly change, but to get us started, they're
Creating Feature Test0:51
for that as well. Okay, so that'll get us started. We'll begin with a feature test. php artisan make:test. We'll call it ReputationTest. And we'll now find that in my Feature directory. All right, so let's use RefreshDatabase, and then we'll set up our first test. So here's where we describe what should it do. Well, we've already seen it here. A User earns reputation as they participate in the forum.
Well, we've already seen it here. A User earns reputation as they participate in the forum. So the first example is, when a User creates a Thread, they gain points. Okay, a User earns points when they create a Thread. So maybe I'll say create, create is just, by the way, it's just a little wrapper around factory::create. Anyways, if I were to say create a Thread, well, maybe that alone should trigger an event that awards points to the User. So I could grab the User by saying Thread, give me the User associated with that Thread. Let me have that relationship right.
So I could grab the User by saying thread, give me the User associated with that thread. Let me have that relationship right. Hmm, have we never created that in all this time? Ah, creator, we called it creator, okay. So I could say thread, creator, and we could say points there. So we have to decide, do we just want a single column called points, and then whenever activities take place, you just increment that column. That might be okay, or maybe you want to track all of the various points they received. That way they could almost see a timeline, oh, this person liked your thread, you get 10 points, and then this person liked something else, you got another 4 points.
Adding Reputation Column2:54
Yep, at the moment you get 10 points for creating a thread. Okay, so I'm going to give this a run, and of course it fails, because at the moment reputation doesn't even exist. So let's go to our create_users_table, and you have a couple choices. You can update your original migration, or if things are already in production, you would create a new migration that everyone would run. At this point, the form software isn't intended to be used in production by anyone. We're still in the pre-alpha stage, so I'm okay updating this directly. So we'll say, how about right here, table unsignedInteger for your reputation_points. Okay, so now let's go and give that another run, and we changed the error, which means
So we'll say, how about right here, table unsignedInteger for your reputation points. Okay, so now let's go and give that another run, and we changed the error, which means we have made progress. It looks like we're trying to insert into the users table, but we have a constraint related to reputation. Okay, that makes sense. Default to 0. Okay, let's run the test again, and we've changed the error. So we're making progress. Right now, of course, we're getting 0, because at no point do we actually accrue
Awarding Thread Creation Points3:56
So we're making progress. Right now, of course, we're getting zero, because at no point do we actually accrue that reputation. So let's see, what's the easiest way to get this to green? Well, hmm, let's go to Thread at the top, and we do have these. We may even want to extract this to a dedicated class at some point to handle some of these model events. But we do have one that says, when a Thread is created, we'll just update and set the slug. But maybe also as part of that, we could say threadCreator, and we're going to increment.
slug. But maybe also as part of that, we could say thread creator, and we're going to increment the reputation by 10 points. All right, so if I give that a run, now we do in fact get green. So let's give this a shot in real life. Now we'll go to council.test, but we have changed our migration. So let's say php artisan migrate --refresh. All right, so that rolls everything back and reruns them, and then I will have to clear the cache. Okay, give it a refresh.
the cache. Okay, give it a refresh. So now if we want some dummy data, we could use that Seeder that was provided for us. And oh, we're getting a reflection exception. You know what that may be? These classes aren't namespaced, so we may have to do a composer dump-autoload to repopulate that list of files. Okay, so if we give it another run, yeah, there it goes. So if we come back and give that a refresh, we've seeded the database, thanks to that migration.
So if we come back and give that a refresh, we've seeded the database, thanks to that migration. All right, but anyways, John Doe is going to create a new thread here, and whoops, we got to clear the cache again. I need to fix that. But anyways, we add something here, and what we should see now, if we switch back to our John Doe account, is that his reputation should increase to 10. Refresh, and now his reputation is 10. If we were to add yet another one, his reputation should now be 20. So what else?
Awarding Reply Creation Points5:46
If we were to add yet another one, his reputation should now be 20. So what else? Why don't we just fill this out? A User earns points when they reply to a Thread. All right, so we're going to say, given we have a Thread, and I'm going to add a Reply here. So let's say the userId of the Reply we're adding will be just some new User. Then the body will be, here is a reply. Okay, so we have a Thread, so by doing that, the owner of that Thread just got 10 points. But now we're adding a Reply, so the creator of the Reply should now get, at this point,
Okay, so we have a Thread, so by doing that, the owner of that Thread just got 10 points. But now we're adding a reply, so the creator of the Reply should now get, at this point, two points. So we could say right down here, let's grab our assertion, two. And that would be reply, and what's our relationship here? Is it owner? Yeah, the owner of the Reply. All right, let's give this a run, and of course it fails. Undefined variable reply, yeah. Give it a run.
Undefined variable reply, yeah. Give it a run. Failed asserting that zero matches the expected two, right? Because at no point do we add reputation as part of that action. So let's see. Do we want to use model events again? Do we want to put it on the addReply method? These are all things to think about. Once again, though, we have a couple automatic model events. So when a reply is created, we increment the replies count on the associated thread.
Once again, though, we have a couple automatic model events. So when a Reply is created, we increment the replies count on the associated Thread. But we could also say, and also find the reply's owner and increment their reputation by two points. And we do get green. So this is good. One thing, though, is if I ever need to review the outline for reputation, like if somebody says, what are all the things I can do that earn me reputation? Well, right now, I could point them to the test, and they could see, okay, ten points, two points.
Well, right now, I could point them to the test, and they could see, okay, ten points, two points. Otherwise, they would have to go to all these model classes and just kind of parse it and see, okay, at this point, you get two. At that point, you get ten. So if all of these are connected, we might want to create, in the next video, a dedicated class that can handle all of this. And that way, at any point, if we need to increment your reputation, it is taken care of within that single class. Anyways, that'll be part of our refactor.
Awarding Best Reply Points8:06
of within that single class. Anyways, that'll be part of our refactor. So a User earns points when they create a Thread. They earn points when they reply to a Thread. Why don't we do, we're running high on time, how many more? When a Reply is marked as best, and a Reply was liked. Let's do one more, and then we'll call it a day. A User earns points when their Reply is marked as best. Okay, so once again, let's see, let's grab this. So given we have a Thread, and given a person replies to that Thread, next I want to say,
Okay, so once again, let's see, let's grab this. So given we have a Thread, and given a Person replies to that Thread, next I want to say, well, also, given that Reply is then marked as best. Let's figure out how we do that. I've already forgotten. Let's see, do we have, yeah. So if you hit this end point here, we hit a BestRepliesController, let's take a look at this, and we authorize the request, and then we say reply.thread.markBestReply. So as part of that action, like this, we need to make sure that this User who created that Reply receives the necessary points.
So as part of that action, like this, we need to make sure that this User who created that reply receives the necessary points. So if we come up, assertEquals, how many do you get? You get 50 points. Once again, these numbers will very likely change. They're very fast and dirty. But anyways, reply, owner, reputation, yeah. Okay, let's give it a run. It fails. Right now, they were given two, but we expected 50.
It fails. Right now, they were given two, but we expected 50. Actually, yeah, you know what? If they add a reply, just by doing that, they get two points. But then if they are marked as best, they get another 50. So at the moment, it should be 52. But of course, at no point do we award those 50 points, so the test fails. Okay. So let's go into this markBestReply. All right, so here is where we update the thread.
They're going to have to hunt around all of these files to figure out, okay, where do we add 2 points? Where do we add 50 points? Where do we add 10 points? It's confusing. So maybe we can put that all under a single class during the refactoring stage. But yeah, if I give this another run, we do get green. So I'm going to stick with these three tests to start. We'll tackle liking a reply in a little bit. But this gets us going.
