user = Helper::makeUser('promo.' . randomString(6), 'promo', enable: true, clearInbox: true); } public function tearDown(): void { if (isset($this->request)) { $this->request->remove(); } $this->user->remove(); } public function testUploadPromotion(): void { // if this fails locally, run again $userMan = new Manager\User(); $this->assertEquals(0, $userMan->promote(), 'promote-initial'); $this->assertEquals(0, $userMan->demote(), 'demote-initial'); // backdate user creation DB::DB()->prepared_query(" UPDATE users_main SET created = created - INTERVAL 8 DAY WHERE ID = ? ", $this->user->id ); // 11GiB to be eligible for User => Member promotion $this->user->setField('leech_upload', 11 * 1024 ** 3)->modify(); $this->assertEquals(1, $userMan->promote(), 'promote-member-promotion'); $inbox = $this->user->inbox()->setUnreadFirst(true); $this->assertEquals(1, $inbox->messageTotal(), 'promote-inbox-total'); $list = $inbox->messageList(new Manager\PM($this->user), 1, 0); $this->assertEquals('You have been promoted to Member', $list[0]->subject(), 'promote-pm-subject'); $this->user->setField('leech_upload', 9 * 1024 ** 3)->modify(); $this->assertEquals(1, $userMan->demote(), 'promote-member-demotion'); $this->assertEquals(2, $inbox->messageTotal(), 'promote-inbox-total'); $list = $inbox->messageList(new Manager\PM($this->user), 2, 0); $this->assertEquals('You have been demoted to User', $list[0]->subject(), 'demote-pm-subject'); $this->assertStringContainsString( '❌ 10.00 GiB uploaded, you have 9.00 GiB', $list[0]->postList(1, 0)[0]['body'], 'demote-user-fail', ); } public function testBountyPromotion(): void { $userMan = new Manager\User(); // backdate user creation DB::DB()->prepared_query(" UPDATE users_main SET created = created - INTERVAL 8 DAY WHERE ID = ? ", $this->user->id ); // 11GiB and create a request for 5GiB to be eligible for User => Member promotion $this->user->setField('leech_upload', 11 * 1024 ** 3)->modify(); $this->request = Helper::makeRequestMusic($this->user, 'phpunit user promote request'); $this->assertTrue( // vote for 5GiB (subtract 100MiB that makeRequestMusic() adds implicitly) $this->request->vote($this->user, 5 * 1024 ** 3 - 100 * 1024 * 1024,), 'promote-member-req-vote', ); // recompute user request stats $stats = new Stats\Users(); $stats->refresh(); $this->assertEquals( 1, $userMan->promote(), 'promote-member-req-promotion', ); $inbox = $this->user->inbox(); $this->assertEquals(1, $inbox->messageTotal(), 'promote-req-inbox-total'); $list = $inbox->messageList(new Manager\PM($this->user), 2, 0); $this->assertEquals( 'You have been promoted to Member', $list[0]->subject(), 'promote-req-pm-subject', ); $this->request->remove(); $stats->refresh(); // recompute after removal $this->user->flush(); // resync user's cache with reality $this->assertEquals( 1, $userMan->demote(), 'promote-member-req-demotion', ); $list = $inbox->messageList(new Manager\PM($this->user), 2, 0); $this->assertEquals( 'You have been demoted to User', $list[0]->subject(), 'demote-req-pm-subject', ); $this->assertStringContainsString( '❌ 10.00 GiB uploaded, you have 6.00 GiB', $list[0]->postList(1, 0)[0]['body'], 'demote-user-fail', ); } public function testNoDemotion(): void { $userMan = new Manager\User(); $db = DB::DB(); $db->prepared_query(" UPDATE users_main SET created = created - INTERVAL 8 DAY WHERE ID = ? ", $this->user->id ); $this->user->setField('leech_upload', 12 * 1024 ** 3)->modify(); $userMan->promote(); $this->assertEquals( 'Member', $this->user->flush()->userclassName(), 'promote-userclass-name' ); // drop to 0.8 ratio $this->user->setField('leech_download', 15 * 1024 ** 3)->modify(); $this->assertEquals( 0, $userMan->demote(), 'demote-ratio-no', ); // drop to 0.5 ratio $this->user->setField('leech_download', 24 * 1024 ** 3)->modify(); $this->assertEquals( 1, $userMan->demote(), 'demote-ratio-yes', ); $inbox = $this->user->inbox()->setUnreadFirst(true); $list = $inbox->messageList(new Manager\PM($this->user), 2, 0); $this->assertEquals( 'You have been demoted to User', $list[0]->subject(), 'demote-ratio-subject', ); $body = $list[0]->postList(1, 0)[0]['body']; $this->assertStringContainsString( '✅ 10.00 GiB uploaded, you have 12.00 GiB', $list[0]->postList(1, 0)[0]['body'], 'demote-ratio-upload', ); $this->assertStringContainsString( '❌ 0.6 ratio required, you have 0.5000', $list[0]->postList(1, 0)[0]['body'], 'demote-user-demote-ratio-ratio', ); $this->user->setField('leech_upload', 501 * 1024 ** 3)->modify(); $db->prepared_query(' UPDATE user_summary SET upload_total = 50 WHERE user_id = ? ', $this->user->id ); $db->prepared_query(" UPDATE users_main SET created = created - INTERVAL 4 WEEK WHERE ID = ? ", $this->user->id ); $this->user->flush(); $userMan->promote(); $list = $inbox->messageList(new Manager\PM($this->user), 1, 0); $this->assertEquals( 'You have been promoted to Elite', $list[0]->subject(), 'promote-user-elite', ); $db->prepared_query(' UPDATE user_summary SET upload_total = 501, unique_group_total = 501 WHERE user_id = ? ', $this->user->id ); $db->prepared_query(" UPDATE users_main SET created = created - INTERVAL 8 WEEK WHERE ID = ? ", $this->user->id ); $this->user->flush(); $userMan->promote(); $list = $inbox->messageList(new Manager\PM($this->user), 1, 0); $this->assertEquals( 'You have been promoted to Power TM', $list[0]->subject(), 'promote-user-power-tm', ); $db->prepared_query(' UPDATE user_summary SET unique_group_total = 499 WHERE user_id = ? ', $this->user->id ); $this->user->flush(); $userMan->demote(); $list = $inbox->messageList(new Manager\PM($this->user), 1, 0); $this->assertEquals( 'You have been demoted to Torrent Master', $list[0]->subject(), 'demote-user-tm', ); $body = $list[0]->postList(1, 0)[0]['body']; $this->assertStringContainsString( 'You have been demoted from Power TM to Torrent Master', $body, 'demote-tm-message', ); $this->assertStringContainsString( '✅ 500.00 GiB uploaded, you have 501.00 GiB', $body, 'demote-tm-upload-size', ); $this->assertStringContainsString( '✅ 0.95 ratio required, you have 20.8750', $body, 'demote-tm-ratio', ); $this->assertStringContainsString( '✅ 500 uploads required, you have 501', $body, 'demote-tm-upload-total', ); $this->assertStringContainsString( '❌ 500 Unique groups required, you have 499', $body, 'demote-tm-upload-unique', ); $db->prepared_query(' UPDATE user_summary SET upload_total = 2000, unique_group_total = 500, perfect_flac_total = 500, perfecter_flac_total = 2000 WHERE user_id = ? ', $this->user->id ); $db->prepared_query(" UPDATE users_main SET created = created - INTERVAL 12 WEEK WHERE ID = ? ", $this->user->id ); $this->user->setField('leech_upload', 2048 * 1024 ** 3)->modify(); $this->assertEquals(3, $userMan->promote(), 'promote-to-ultimate'); $this->assertEquals( $this->user->flush()->primaryClass(), ULTIMATE_TM, 'user-is-ultimate', ); $db->prepared_query(' UPDATE user_summary SET perfecter_flac_total = 1999 WHERE user_id = ? ', $this->user->id ); $this->user->flush(); $userMan->demote(); $list = $inbox->messageList(new Manager\PM($this->user), 1, 0); $this->assertEquals( 'You have been demoted to Elite TM', $list[0]->subject(), 'demote-user-utm', ); $body = $list[0]->postList(1, 0)[0]['body']; $this->assertStringContainsString( '✅ 2,000 uploads required, you have 2,000', $body, 'demote-utm-upload-total', ); $this->assertStringContainsString( '❌ 2,000 "Perfecter" FLACs required, you have 1,999', $body, 'demote-utm-upload-unique', ); } public function testUserBuffer(): void { $this->user->setField('leech_upload', 8 * 1024 ** 3)->modify(); $manager = new Manager\User(); [$ratio, $buffer] = $manager->userBuffer($this->user); $this->assertEqualsWithDelta( 0.6, $ratio, 0.0001, 'buffer-infin-ratio', ); $this->assertEqualsWithDelta( $this->user->uploadedSize() / $ratio, $buffer, 0.0001, 'buffer-infin-buffer', ); $this->user->setField('leech_download', 4 * 1024 ** 3)->modify(); [$ratio, $buffer] = $manager->userBuffer($this->user); $this->assertEqualsWithDelta( $this->user->uploadedSize() / $ratio - $this->user->downloadedSize(), $buffer, 0.01, 'buffer-down-buffer', ); } public function testNextClass(): void { $manager = new Manager\User(); $next = $manager->userNextClass($this->user); $this->assertIsArray($next, 'user-next-array'); $this->assertEquals('Member', $next['class'], 'user-next-class-is-member'); $goal = $next['goal']; $this->assertIsArray($goal, 'user-next-requirements-array'); $this->assertCount(3, $goal, 'user-next-requirements-count'); $this->assertStringContainsString('100%', $goal['Ratio']['percent'], 'user-next-ratio'); $this->assertStringContainsString('0%', $goal['Time']['percent'], 'user-next-time'); $this->assertStringContainsString('30%', $goal['Upload']['percent'], 'user-next-upload'); $this->user->setField('created', date('Y-m-d H:i:s', strtotime('-2 day')))->modify(); $next = $manager->userNextClass($this->user); $this->assertIsArray($next, 'user-next-requirements-next-array'); $this->assertStringContainsString('29%', $next['goal']['Time']['percent'], 'user-next-closer-time'); $this->user->setField('created', date('Y-m-d H:i:s', strtotime('-7 day')))->modify(); $next = $manager->userNextClass($this->user); $this->assertIsArray($next, 'user-next-requirements-next-2-array'); $this->assertStringContainsString('100%', $next['goal']['Time']['percent'], 'user-next-has-time'); $this->user->addBounty(7 * 1024 * 1024 * 1024); $this->user->stats()->flush(); $next = $manager->userNextClass($this->user); $this->assertIsArray($next, 'user-next-requirements-next-3-array'); $this->assertStringContainsString('100%', $next['goal']['Upload']['percent'], 'user-next-has-upload'); $manager->promote(); $this->assertEquals('Member', $this->user->flush()->userclassName(), 'user-promoted-to-member'); $this->user->setField('PermissionId', SYSOP)->modify(); $this->assertNull($manager->userNextClass($this->user), 'user-next-class-is-null'); } }