Skip to content

Instantly share code, notes, and snippets.

@logical-and
Created September 17, 2013 14:55
Show Gist options
  • Save logical-and/6595461 to your computer and use it in GitHub Desktop.
Save logical-and/6595461 to your computer and use it in GitHub Desktop.

Revisions

  1. logical-and created this gist Sep 17, 2013.
    578 changes: 578 additions & 0 deletions InvoiceManagerSubscriberTest.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,578 @@
    <?php

    class InvoiceManagerSubscriberTest extends KernelTestCase {

    public function testGetInvoiceForAccountLogic()
    {
    $userRepository = $this->getUserRepository();
    $user = (new User())->addQualification(1);

    $userSys = $userRepository->findSysUser();
    $userEvil = $userRepository->findEvilUser();
    $userAct = (new User())->setId(18)->setRole(User::ROLE_ACT)->addQualification(1);
    $userRef = (new User())->setId(19)->setRole(User::ROLE_REF)->addQualification(1)->setParent($userAct);

    // sys > act > ref > ref > user, just a logic test
    $userRef2 = (new User())->setId(20)->setRole(User::ROLE_REF)->setParent($userRef);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount(
    $user->setParent($userRef2), $userRepository), [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 5, 'user' => $userRef2],
    ]);

    // sys > act > act > user
    $userAct2 = (new User())->setId(21)->setRole(User::ROLE_ACT)->setParent($userAct)->addQualification(1);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount(
    $user->setParent($userAct2), $userRepository), [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 30, 'user' => $userAct2],
    ]);

    $userAct->setQualifications([1, 2, 3]);
    $userAct2->setQualifications([1, 2]);
    $userRef->setParent($userAct2)->setQualifications([1, 2, 3]);
    $user->setParent($userRef)->setQualifications([1, 2, 3]);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount($user, $userRepository), [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 250, 'user' => $userAct2],
    ['amount' => 100, 'user' => $userRef],
    ['amount' => 250, 'user' => $userAct],
    ]
    );

    // A bit changes
    $userAct->removeQualification(3)->setParent($userEvil);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount($user, $userRepository), [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 250, 'user' => $userAct2],
    ['amount' => 100, 'user' => $userRef],
    ['amount' => 250, 'user' => $userEvil],
    ]
    );
    }

    public function testGetInvoiceForAccountWith1Qualification()
    {
    $userRepository = $this->getUserRepository();
    $user = (new User())->addQualification(1);

    // sys > user
    $userSys = $userRepository->findSysUser();
    $userEvil = $userRepository->findEvilUser();
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount(
    $user->setParent($userSys), $userRepository), [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 30, 'user' => $userEvil],
    ]);

    // sys > evil > user
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount(
    $user->setParent($userEvil), $userRepository), [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 30, 'user' => $userEvil],
    ]);

    // sys > act > user
    $userAct = (new User())->setId(18)->setRole(User::ROLE_ACT)->addQualification(1);
    $user->setParent($userAct);
    foreach ([
    [
    'act' => [1], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 30, 'user' => $userAct],
    ]
    ],
    [
    'act' => [1, 2], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 30, 'user' => $userAct],
    ]
    ],
    [
    'act' => [1, 2, 3], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 30, 'user' => $userAct],
    ]
    ],
    ] as $data)
    {
    $userAct->setQualifications($data[ 'act' ]);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount($user, $userRepository), $data[ 'result' ]
    );
    }
    $userAct->removeQualification(3)->removeQualification(2);

    // sys > act > ref > user
    $userRef = (new User())->setId(19)->setRole(User::ROLE_REF)->addQualification(1)->setParent($userAct);
    $user->setParent($userRef);
    foreach ([
    ['act' => [1], 'ref' => [1], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 5, 'user' => $userRef]
    ]
    ],
    ['act' => [1], 'ref' => [1, 2], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 5, 'user' => $userRef]
    ]
    ],
    ['act' => [1], 'ref' => [1, 2, 3], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 5, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2], 'ref' => [1], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 5, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2], 'ref' => [1, 2], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 5, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2], 'ref' => [1, 2, 3], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 5, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2, 3], 'ref' => [1], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 5, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2, 3], 'ref' => [1, 2], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 5, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2, 3], 'ref' => [1, 2, 3], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 5, 'user' => $userRef]
    ]
    ],
    ] as $data)
    {
    $userAct->setQualifications($data[ 'act' ]);
    $userRef->setQualifications($data[ 'ref' ]);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount($user, $userRepository), $data[ 'result' ]
    );
    }
    $userAct->setQualifications([1]);
    $userRef->setQualifications([1]);

    // evil > ref > user
    $userRef->setParent($userEvil);
    foreach ([
    [
    'ref' => [1], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userEvil],
    ['amount' => 5, 'user' => $userRef],
    ]
    ],
    [
    'ref' => [1, 2], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userEvil],
    ['amount' => 5, 'user' => $userRef],
    ]
    ],
    [
    'ref' => [1, 2, 3], 'result' => [
    ['amount' => 20, 'user' => $userSys],
    ['amount' => 25, 'user' => $userEvil],
    ['amount' => 5, 'user' => $userRef],
    ]
    ],
    ] as $data)
    {
    $userRef->setQualifications($data[ 'ref' ]);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount($user, $userRepository), $data[ 'result' ]
    );
    }
    $userRef->removeQualification(3)->removeQualification(2);
    }

    public function testGetInvoiceForAccountWith2Qualification()
    {
    $userRepository = $this->getUserRepository();
    $user = (new User())->setQualifications([1, 2]);

    // sys > user
    $userSys = $userRepository->findSysUser();
    $userEvil = $userRepository->findEvilUser();
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount(
    $user->setParent($userSys), $userRepository), [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 300, 'user' => $userEvil],
    ]);

    // sys > evil > user
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount(
    $user->setParent($userEvil), $userRepository), [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 300, 'user' => $userEvil],
    ]);

    // sys > act > user
    $userAct = (new User())->setId(18)->setRole(User::ROLE_ACT)->addQualification(1)->setParent($userEvil);
    $user->setParent($userAct);
    foreach ([
    [
    'act' => [1], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 30 + 50, 'user' => $userAct],
    ['amount' => 220, 'user' => $userEvil],
    ]
    ],
    [
    'act' => [1, 2], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 300, 'user' => $userAct],
    ]
    ],
    [
    'act' => [1, 2, 3], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 300, 'user' => $userAct],
    ]
    ],
    ] as $data)
    {
    $userAct->setQualifications($data[ 'act' ]);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount($user, $userRepository), $data[ 'result' ]
    );
    }
    $userAct->removeQualification(3)->removeQualification(2);

    // sys > act > ref > user
    $userRef = (new User())->setId(19)->setRole(User::ROLE_REF)->addQualification(1)->setParent($userAct);
    $user->setParent($userRef);
    foreach ([
    ['act' => [1], 'ref' => [1], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 50, 'user' => $userRef],
    ['amount' => 225, 'user' => $userEvil],
    ]
    ],
    ['act' => [1], 'ref' => [1, 2], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 50, 'user' => $userRef],
    ['amount' => 225, 'user' => $userEvil],
    ]
    ],
    ['act' => [1], 'ref' => [1, 2, 3], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 50, 'user' => $userRef],
    ['amount' => 225, 'user' => $userEvil],
    ]
    ],
    ['act' => [1, 2], 'ref' => [1], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 250, 'user' => $userAct],
    ['amount' => 50, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2], 'ref' => [1, 2], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 250, 'user' => $userAct],
    ['amount' => 50, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2], 'ref' => [1, 2, 3], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 250, 'user' => $userAct],
    ['amount' => 50, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2, 3], 'ref' => [1], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 250, 'user' => $userAct],
    ['amount' => 50, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2, 3], 'ref' => [1, 2], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 250, 'user' => $userAct],
    ['amount' => 50, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2, 3], 'ref' => [1, 2, 3], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 250, 'user' => $userAct],
    ['amount' => 50, 'user' => $userRef]
    ]
    ],
    ] as $data)
    {
    $userAct->setQualifications($data[ 'act' ]);
    $userRef->setQualifications($data[ 'ref' ]);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount($user, $userRepository), $data[ 'result' ]
    );
    }
    $userAct->setQualifications([1]);
    $userRef->setQualifications([1]);

    // evil > ref > user
    $userRef->setParent($userEvil);
    foreach ([
    [
    'ref' => [1], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 250, 'user' => $userEvil],
    ['amount' => 50, 'user' => $userRef],
    ]
    ],
    [
    'ref' => [1, 2], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 250, 'user' => $userEvil],
    ['amount' => 50, 'user' => $userRef],
    ]
    ],
    [
    'ref' => [1, 2, 3], 'result' => [
    ['amount' => 200, 'user' => $userSys],
    ['amount' => 250, 'user' => $userEvil],
    ['amount' => 50, 'user' => $userRef],
    ]
    ],
    ] as $data)
    {
    $userRef->setQualifications($data[ 'ref' ]);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount($user, $userRepository), $data[ 'result' ]
    );
    }
    $userRef->removeQualification(3)->removeQualification(2);
    }

    public function testGetInvoiceForAccountWith3Qualification()
    {
    $userRepository = $this->getUserRepository();
    $user = (new User())->setQualifications([1, 2, 3]);

    // sys > user
    $userSys = $userRepository->findSysUser();
    $userEvil = $userRepository->findEvilUser();
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount(
    $user->setParent($userSys), $userRepository), [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 600, 'user' => $userEvil],
    ]);

    // sys > evil > user
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount(
    $user->setParent($userEvil), $userRepository), [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 600, 'user' => $userEvil],
    ]);

    // sys > act > user
    $userAct = (new User())->setId(18)->setRole(User::ROLE_ACT)->addQualification(1)->setParent($userEvil);
    $user->setParent($userAct);
    foreach ([
    [
    'act' => [1], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 30 + 100, 'user' => $userAct],
    ['amount' => 470, 'user' => $userEvil],
    ]
    ],
    [
    'act' => [1, 2], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 300 + 100, 'user' => $userAct],
    ['amount' => 200, 'user' => $userEvil],
    ]
    ],
    [
    'act' => [1, 2, 3], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 600, 'user' => $userAct],
    ]
    ],
    ] as $data)
    {
    $userAct->setQualifications($data[ 'act' ]);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount($user, $userRepository), $data[ 'result' ]
    );
    }
    $userAct->removeQualification(3)->removeQualification(2);

    // sys > act > ref > user
    $userRef = (new User())->setId(19)->setRole(User::ROLE_REF)->addQualification(1)->setParent($userAct);
    $user->setParent($userRef);
    foreach ([
    ['act' => [1], 'ref' => [1], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 100, 'user' => $userRef],
    ['amount' => 475, 'user' => $userEvil],
    ]
    ],
    ['act' => [1], 'ref' => [1, 2], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 100, 'user' => $userRef],
    ['amount' => 475, 'user' => $userEvil],
    ]
    ],
    ['act' => [1], 'ref' => [1, 2, 3], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 25, 'user' => $userAct],
    ['amount' => 100, 'user' => $userRef],
    ['amount' => 475, 'user' => $userEvil],
    ]
    ],
    ['act' => [1, 2], 'ref' => [1], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 250, 'user' => $userAct],
    ['amount' => 100, 'user' => $userRef],
    ['amount' => 250, 'user' => $userEvil],
    ]
    ],
    ['act' => [1, 2], 'ref' => [1, 2], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 250, 'user' => $userAct],
    ['amount' => 100, 'user' => $userRef],
    ['amount' => 250, 'user' => $userEvil],
    ]
    ],
    ['act' => [1, 2], 'ref' => [1, 2, 3], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 250, 'user' => $userAct],
    ['amount' => 100, 'user' => $userRef],
    ['amount' => 250, 'user' => $userEvil],
    ]
    ],
    ['act' => [1, 2, 3], 'ref' => [1], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 500, 'user' => $userAct],
    ['amount' => 100, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2, 3], 'ref' => [1, 2], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 500, 'user' => $userAct],
    ['amount' => 100, 'user' => $userRef]
    ]
    ],
    ['act' => [1, 2, 3], 'ref' => [1, 2, 3], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 500, 'user' => $userAct],
    ['amount' => 100, 'user' => $userRef]
    ]
    ],
    ] as $data)
    {
    $userAct->setQualifications($data[ 'act' ]);
    $userRef->setQualifications($data[ 'ref' ]);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount($user, $userRepository), $data[ 'result' ]
    );
    }
    $userAct->setQualifications([1]);
    $userRef->setQualifications([1]);

    // evil > ref > user
    $userRef->setParent($userEvil);
    foreach ([
    [
    'ref' => [1], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 500, 'user' => $userEvil],
    ['amount' => 100, 'user' => $userRef],
    ]
    ],
    [
    'ref' => [1, 2], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 500, 'user' => $userEvil],
    ['amount' => 100, 'user' => $userRef],
    ]
    ],
    [
    'ref' => [1, 2, 3], 'result' => [
    ['amount' => 400, 'user' => $userSys],
    ['amount' => 500, 'user' => $userEvil],
    ['amount' => 100, 'user' => $userRef],
    ]
    ],
    ] as $data)
    {
    $userRef->setQualifications($data[ 'ref' ]);
    $this->assertInvoiceFor(
    $this->subscriber->getInvoiceForNewAccount($user, $userRepository), $data[ 'result' ]
    );
    }
    $userRef->removeQualification(3)->removeQualification(2);

    }

    public function testRegularPayment()
    {
    $user = $this->buildUser(User::ROLE_ACT, [1]);
    $sysUser = $this->getUserRepository()->findSysUser();

    // Dont bill if already billed
    $existentRegularInvoice = new Invoice(Invoice::TYPE_REGULAR, $user);
    $existentRegularInvoice->addInvoiceDetail(new InvoiceDetail($sysUser, 50));
    $this->assertEquals(1,
    $user->getUnpaidInvoices()->matching(new Criteria(Criteria::expr()->eq('type', Invoice::TYPE_REGULAR)))->count(),
    'User has only 1 regular invoice now');
    $this->subscriber->billOnRegularBasis($this->createUserEvent($user));
    $this->assertEquals(1,
    $user->getUnpaidInvoices()->matching(new Criteria(Criteria::expr()->eq('type', Invoice::TYPE_REGULAR)))->count(),
    'User has only 1 regular invoice now and never will be rebilled second time');

    // 1 qualification
    $user->getInvoices()->removeElement($existentRegularInvoice);
    $this->assertFalse($user->hasUnpaidInvoices(), 'User has no any unpaid invoices');
    $this->subscriber->billOnRegularBasis($this->createUserEvent($user));
    $this->assertEquals(1,
    $user->getUnpaidInvoices()->matching(new Criteria(Criteria::expr()->eq('type', Invoice::TYPE_REGULAR)))->count(),
    'User has 1 regular invoice now, when he`s billed');
    $this->assertInvoiceFor($user->getUnpaidInvoices()->first(), [['user' => $sysUser, 'amount' => 20 ]]);

    // 2 qualification
    $user->addQualification(2)->getInvoices()->clear();
    $this->subscriber->billOnRegularBasis($this->createUserEvent($user));
    $this->assertInvoiceFor($user->getUnpaidInvoices()->first(), [['user' => $sysUser, 'amount' => 200 ]]);

    // 3 qualification
    $user->addQualification(3)->getInvoices()->clear();
    $this->subscriber->billOnRegularBasis($this->createUserEvent($user));
    $this->assertInvoiceFor($user->getUnpaidInvoices()->first(), [['user' => $sysUser, 'amount' => 400 ]]);
    }
    }