diff --git a/Modules/Exercise03/Tests/Feature/Http/Controllers/ProductControllerTest.php b/Modules/Exercise03/Tests/Feature/Http/Controllers/ProductControllerTest.php new file mode 100644 index 0000000..d215839 --- /dev/null +++ b/Modules/Exercise03/Tests/Feature/Http/Controllers/ProductControllerTest.php @@ -0,0 +1,60 @@ +productService = \Mockery::mock(ProductService::class); + $this->productController = new ProductController( + $this->productService + ); + } + + /** + * A basic feature test example. + * + * @return void + */ + public function testIndex() + { + $products = [ + 'name' => 'name', + 'status' => 1 + ]; + + $this->productService->shouldReceive('getAllProducts') + ->andReturn($products); + $response = $this->productController->index(); + $this->assertInstanceOf(View::class, $response); + $this->assertEquals('exercise03::index', $response->getName()); + } + + public function testCheckout() { + $input['total_products'] = [ + 1 => 1, + 2 => 2, + 3 => 3 + ]; + + $this->productService->shouldReceive('calculateDiscount') + ->with($input) + ->andReturn(5); + $mockRequest = \Mockery::mock(CheckoutRequest::class); + $mockRequest->shouldReceive('input')->andReturn($input); + $response = $this->productController->checkout($mockRequest); + $this->assertEquals(['discount' => 5], $response->getOriginalContent()); + } +} diff --git a/Modules/Exercise03/Tests/Feature/Http/Requests/CheckoutRequestTest.php b/Modules/Exercise03/Tests/Feature/Http/Requests/CheckoutRequestTest.php new file mode 100644 index 0000000..b0be8c3 --- /dev/null +++ b/Modules/Exercise03/Tests/Feature/Http/Requests/CheckoutRequestTest.php @@ -0,0 +1,45 @@ +request = new CheckoutRequest(); + } + + public function testRules() + { + $this->assertEquals([ + 'total_products' => 'required|array', + 'total_products.*' => 'nullable|integer|min:0', + ], + $this->request->rules() + ); + } + + public function testInvalidData() + { + $validator = Validator::make([], $this->request->rules()); + $this->assertTrue($validator->fails()); + } + + public function testValidData() + { + $data = [ + 'total_products' => [0, 1, 2, 3], + ]; + + $validator = Validator::make($data, $this->request->rules()); + $this->assertTrue($validator->passes()); + } +} diff --git a/Modules/Exercise03/Tests/Feature/Models/ProductTest.php b/Modules/Exercise03/Tests/Feature/Models/ProductTest.php new file mode 100644 index 0000000..eb5f957 --- /dev/null +++ b/Modules/Exercise03/Tests/Feature/Models/ProductTest.php @@ -0,0 +1,20 @@ +make(); + $this->assertInstanceOf(Product::class, $product); + } +} diff --git a/Modules/Exercise03/Tests/Feature/Repositories/ProductRepositoryTest.php b/Modules/Exercise03/Tests/Feature/Repositories/ProductRepositoryTest.php new file mode 100644 index 0000000..e79e041 --- /dev/null +++ b/Modules/Exercise03/Tests/Feature/Repositories/ProductRepositoryTest.php @@ -0,0 +1,23 @@ +all(); + $this->assertInstanceOf(Collection::class, $getAll); + } +} diff --git a/Modules/Exercise03/Tests/Feature/Services/ProductServiceTest.php b/Modules/Exercise03/Tests/Feature/Services/ProductServiceTest.php new file mode 100644 index 0000000..2951fc0 --- /dev/null +++ b/Modules/Exercise03/Tests/Feature/Services/ProductServiceTest.php @@ -0,0 +1,104 @@ +mockProductRepository = $this->mock(ProductRepository::class); + $this->productService = new ProductService($this->mockProductRepository); + } + + /** + * @dataProvider provideData + */ + + public function testCalculateDiscount($totalProducts, $expectValue, $testCase = 'OK') + { + if ($testCase === 'NG') { + $this->expectException(InvalidArgumentException::class); + } + + $response = $this->productService->calculateDiscount($totalProducts); + $this->assertEquals($response, $expectValue); + } + + public function provideData() + { + return [ + [ + [ + 1 => 0, + 2 => 0, + 3 => 0 + ], + 0 + ], + [ + [ + 1 => 1, + 2 => 2, + 3 => 2 + ], + 5 + ], + [ + [ + 1 => 1, + 2 => 0, + 3 => 7 + ], + 7 + ], + [ + [ + 1 => 1, + 2 => 2, + 3 => 5 + ], + 12 + ], + [ + [ + 1 => -1, + 2 => 2, + 3 => 9 + ], + 0, + 'NG' + ], + [ + [ + 1 => 1, + 2 => -2, + 3 => 2 + ], + 0, + 'NG' + ], + ]; + } + + public function testGetAllProducts() + { + $this->mockProductRepository + ->shouldReceive('all') + ->andReturn([]); + + $this->assertEquals($this->productService->getAllProducts(), []); + } + +} diff --git a/Modules/Exercise04/Tests/Feature/Http/Controllers/CalendarControllerTest.php b/Modules/Exercise04/Tests/Feature/Http/Controllers/CalendarControllerTest.php new file mode 100644 index 0000000..4c1067f --- /dev/null +++ b/Modules/Exercise04/Tests/Feature/Http/Controllers/CalendarControllerTest.php @@ -0,0 +1,33 @@ +mockCalendarService = $this->mock(CalendarService::class); + $this->calendarController = new CalendarController($this->mockCalendarService); + } + + public function testIndex() + { + $this->mockCalendarService + ->shouldReceive('getDateClass') + ->andReturn(CalendarService::COLOR_BLUE); + + $response = $this->calendarController->index(); + $this->assertInstanceOf(View::class, $response); + $this->assertEquals('exercise04::calendar', $response->getName()); + } + +} diff --git a/Modules/Exercise04/Tests/Feature/Http/Services/CalendarServiceTest.php b/Modules/Exercise04/Tests/Feature/Http/Services/CalendarServiceTest.php new file mode 100644 index 0000000..3125720 --- /dev/null +++ b/Modules/Exercise04/Tests/Feature/Http/Services/CalendarServiceTest.php @@ -0,0 +1,53 @@ +calendarService = new CalendarService(); + } + + /** + * @param $date + * @dataProvider provideData + */ + public function testGetDateClass($date, $expectValue) + { + $holiday = ['2021-05-30']; + + $class = $this->calendarService->getDateClass($date, $holiday); + $this->assertEquals($class, $expectValue); + } + + public function provideData() + { + return [ + [ + Carbon::createFromDate(2021, 5, 23), + CalendarService::COLOR_RED, + ], + [ + Carbon::createFromDate(2021, 5, 29), + CalendarService::COLOR_BLUE, + ], + [ + Carbon::createFromDate(2021, 5, 30), + CalendarService::COLOR_RED, + ], + [ + Carbon::createFromDate(2021, 6, 30), + CalendarService::COLOR_BLACK, + ], + + ]; + } +} diff --git a/Modules/Exercise05/Tests/Feature/Http/Controllers/Exercise05ControllerTest.php b/Modules/Exercise05/Tests/Feature/Http/Controllers/Exercise05ControllerTest.php new file mode 100644 index 0000000..818313f --- /dev/null +++ b/Modules/Exercise05/Tests/Feature/Http/Controllers/Exercise05ControllerTest.php @@ -0,0 +1,50 @@ +mockOrderService = $this->mock(OrderService::class); + $this->controller = new Exercise05Controller($this->mockOrderService); + } + + public function testIndex() + { + $response = $this->controller->index(); + $this->assertInstanceOf(View::class, $response); + $this->assertEquals('exercise05::index', $response->getName()); + } + + public function testStore() + { + $detailOrder = [ + 'price' => 100, + 'option_receive' => 1, + 'option_coupon' => 1 + ]; + + $mockRequest = $this->mock(OrderRequest::class); + $mockRequest->shouldReceive('only') + ->andReturn($detailOrder); + + $this->mockOrderService + ->shouldReceive('handleDiscount') + ->andReturn(1); + + $res = $this->controller->store($mockRequest); + $this->assertEquals('exercise05::detail', $res->getName()); + } +} diff --git a/Modules/Exercise05/Tests/Feature/Http/Requests/OrderRequestTest.php b/Modules/Exercise05/Tests/Feature/Http/Requests/OrderRequestTest.php new file mode 100644 index 0000000..4fb39aa --- /dev/null +++ b/Modules/Exercise05/Tests/Feature/Http/Requests/OrderRequestTest.php @@ -0,0 +1,67 @@ +request = new OrderRequest(); + } + + /** + * @dataProvider providerData + */ + public function testRules($data, $testCase = 'NG') + { + $validator = Validator::make($data, $this->request->rules()); + + if ($testCase === 'OK') { + $this->assertTrue($validator->passes()); + } else { + $this->assertTrue($validator->fails()); + } + } + + public function providerData() + { + return [ + // Invalid data + [$this->makeData()], + // price: invalid + [$this->makeData('String', 1, 1)], + [$this->makeData('100,000', 1, 1)], + // option_receive: invalid + [$this->makeData(100, null, 1)], + [$this->makeData(100, 0, 1)], + [$this->makeData(100, 3, 1)], + //option_coupon: invalid + [$this->makeData(100, null, 0)], + [$this->makeData(100, 1, 0)], + [$this->makeData(100, 1, 3)], + + // Valid data + [$this->makeData(100, 1, 1), 'OK'], + [$this->makeData(100, 2, 1), 'OK'], + [$this->makeData(100, 1, 1), 'OK'], + [$this->makeData(100.000, 1, 2), 'OK'], + ]; + } + + public function makeData($price = null, $optionReceive = null, $optionCoupon = null) + { + return [ + 'price' => $price, + 'option_receive' => $optionReceive, + 'option_coupon' => $optionCoupon + ]; + } +} diff --git a/Modules/Exercise05/Tests/Feature/Http/Services/OrderServiceTest.php b/Modules/Exercise05/Tests/Feature/Http/Services/OrderServiceTest.php new file mode 100644 index 0000000..1cd8c42 --- /dev/null +++ b/Modules/Exercise05/Tests/Feature/Http/Services/OrderServiceTest.php @@ -0,0 +1,67 @@ +orderService = new OrderService(); + } + + /** + * @dataProvider provideData + */ + public function testHandleDiscount($detailOrder, $expectValue) + { + $response = $this->orderService->handleDiscount($detailOrder); + + $this->assertEquals($response, $expectValue); + } + + public function provideData() + { + return [ + [ + $this->makeData(1501, 1, 2), + $this->makeBill(1501, 'Khuyến mại pizza thứ 2', 'Miễn phí khoai tây') + ], + [ + $this->makeData(1600, 2, 1), + $this->makeBill(1280, null, 'Miễn phí khoai tây') + ], + [ + $this->makeData(1400, 2, 2), + $this->makeBill(1400, null, null) + ], + [ + $this->makeData(1400, 1, 3), + $this->makeBill(1400, 'Khuyến mại pizza thứ 2', null) + ], + ]; + } + + public function makeData($price = null, $optionReceive = null, $optionCoupon = null) + { + return [ + 'price' => $price, + 'option_receive' => $optionReceive, + 'option_coupon' => $optionCoupon, + ]; + } + + public function makeBill($price = null, $discountPizza = null, $discountCoupon = null) + { + return [ + 'price' => $price, + 'discount_pizza' => $discountPizza, + 'discount_potato' => $discountCoupon, + ]; + } +} diff --git a/Modules/Exercise06/Tests/Feature/Http/Controllers/Exercise06ControllerTest.php b/Modules/Exercise06/Tests/Feature/Http/Controllers/Exercise06ControllerTest.php new file mode 100644 index 0000000..01dea60 --- /dev/null +++ b/Modules/Exercise06/Tests/Feature/Http/Controllers/Exercise06ControllerTest.php @@ -0,0 +1,50 @@ +mockCalculateService = $this->mock(CalculateService::class); + $this->controller = new Exercise06Controller($this->mockCalculateService); + } + + public function testIndex() + { + $response = $this->controller->index(); + $this->assertInstanceOf(View::class, $response); + $this->assertEquals('exercise06::index', $response->getName()); + } + + public function testCalculate() + { + $input = [ + 'bill' => 2021, + 'has_watch' => true, + ]; + + $mockRequest = $this->mock(Exercise06Request::class); + $mockRequest->shouldReceive('validated') + ->andReturn($input); + + $this->mockCalculateService->shouldReceive('calculate') + ->with($input['bill'], $input['has_watch']) + ->andReturn(60); + + $res = $this->controller->calculate($mockRequest); + $this->assertInstanceOf(RedirectResponse::class, $res); + } +} diff --git a/Modules/Exercise06/Tests/Feature/Http/Requests/Exercise06RequestTest.php b/Modules/Exercise06/Tests/Feature/Http/Requests/Exercise06RequestTest.php new file mode 100644 index 0000000..95b6552 --- /dev/null +++ b/Modules/Exercise06/Tests/Feature/Http/Requests/Exercise06RequestTest.php @@ -0,0 +1,44 @@ +request = new Exercise06Request(); + } + + /** + * @dataProvider providerData + */ + public function testRules($data, $testCase = 'NG') + { + $validator = Validator::make($data, $this->request->rules()); + + if ($testCase == 'OK') { + $this->assertTrue($validator->passes()); + } else { + $this->assertTrue($validator->fails()); + } + } + + public function providerData() + { + return [ + [['bill' => null, 'has_watch' => null]], + [['bill' => -1, 'has_watch' => null]], + [['bill' => 1, 'has_watch' => 123]], + [['bill' => 'string', 'has_watch' => true]], + [['bill' => 1, 'has_watch' => true], 'OK'], + ]; + } +} diff --git a/Modules/Exercise06/Tests/Feature/Services/CalculateServiceTest.php b/Modules/Exercise06/Tests/Feature/Services/CalculateServiceTest.php new file mode 100644 index 0000000..a96b2f7 --- /dev/null +++ b/Modules/Exercise06/Tests/Feature/Services/CalculateServiceTest.php @@ -0,0 +1,50 @@ +calculateService = new CalculateService(); + } + + /** + * @dataProvider provideData + */ + public function testCalculate($params, $expectValue, $testCase = 'OK') + { + if ($testCase == 'NG') { + $this->expectException(InvalidArgumentException::class); + } + + $response = $this->calculateService->calculate($params['bill'], $params['hasWatch']); + $this->assertEquals($response, $expectValue); + } + + public function provideData() + { + return [ + [$this->makeData(2021, false), 60], + [$this->makeData(5001, false), 120], + [$this->makeData(2021, true), 240], + [$this->makeData(5001, true), 300], + [$this->makeData(-1, true), 0, 'NG'], + ]; + } + + public function makeData($bill = null, $hasWatch = null) + { + return [ + 'bill' => $bill, + 'hasWatch' => $hasWatch, + ]; + } +} diff --git a/Modules/Exercise07/Tests/Feature/Http/Controllers/CheckoutControllerTest.php b/Modules/Exercise07/Tests/Feature/Http/Controllers/CheckoutControllerTest.php new file mode 100644 index 0000000..3d1be87 --- /dev/null +++ b/Modules/Exercise07/Tests/Feature/Http/Controllers/CheckoutControllerTest.php @@ -0,0 +1,50 @@ +mockCheckoutService = $this->mock(CheckoutService::class); + $this->controller = new CheckoutController($this->mockCheckoutService); + } + + public function testIndex() + { + $response = $this->controller->index(); + $this->assertInstanceOf(View::class, $response); + $this->assertEquals('exercise07::checkout.index', $response->getName()); + } + + public function testStore() + { + $order = [ + 'amount' => 1000, + 'shipping_express' => true, + ]; + + $mockRequest = $this->mock(CheckoutRequest::class); + $mockRequest->shouldReceive('all') + ->andReturn($order); + + $this->mockCheckoutService->shouldReceive('calculateShippingFee') + ->with($order) + ->andReturn([]); + + $res = $this->controller->store($mockRequest); + $this->assertInstanceOf(RedirectResponse::class, $res); + } +} diff --git a/Modules/Exercise07/Tests/Feature/Http/Requests/CheckoutRequestTest.php b/Modules/Exercise07/Tests/Feature/Http/Requests/CheckoutRequestTest.php new file mode 100644 index 0000000..63ec6af --- /dev/null +++ b/Modules/Exercise07/Tests/Feature/Http/Requests/CheckoutRequestTest.php @@ -0,0 +1,45 @@ +request = new CheckoutRequest(); + } + + /** + * @dataProvider providerData + */ + public function testRules($data, $testCase = 'NG') + { + $validator = Validator::make([ + 'amount' => $data['amount'], + ], $this->request->rules()); + + if ($testCase == 'OK') { + $this->assertTrue($validator->passes()); + } else { + $this->assertTrue($validator->fails()); + } + } + + public function providerData() + { + return [ + [['amount' => null]], + [['amount' => 0]], + [['amount' => -1]], + [['amount' => 100], 'OK'], + ]; + } +} diff --git a/Modules/Exercise07/Tests/Feature/Services/CheckoutServiceTest.php b/Modules/Exercise07/Tests/Feature/Services/CheckoutServiceTest.php new file mode 100644 index 0000000..fe0bd08 --- /dev/null +++ b/Modules/Exercise07/Tests/Feature/Services/CheckoutServiceTest.php @@ -0,0 +1,55 @@ +checkoutService = new CheckoutService(); + } + + /** + * @dataProvider provideData + */ + public function testCalculateShippingFee($order, $expectValue, $testCase = 'OK') + { + $response = $this->checkoutService->calculateShippingFee($order); + $this->assertEquals($response, $expectValue); + } + + public function provideData() + { + return [ + [ + $this->makeOrder(5000, null), + $this->makeOrder(5000, null, 0) + ], + [ + $this->makeOrder(5001, null), + $this->makeOrder(5001, null, 0) + ], + [ + $this->makeOrder(4999, null, null, 'premium_member'), + $this->makeOrder(4999, null, 0, 'premium_member') + ], + ]; + } + + public function makeOrder($amount, $express, $fee = null, $premiumMember = null) + { + return [ + 'amount' => $amount, + 'shipping_express' => $express, + 'shipping_fee' => $fee, + 'premium_member' => $premiumMember + ]; + } +} diff --git a/infection.json b/infection.json index 0c8fa89..b436b48 100644 --- a/infection.json +++ b/infection.json @@ -1,7 +1,11 @@ { "source": { "directories": [ - "Modules/" + "Modules/Exercise03/", + "Modules/Exercise04/", + "Modules/Exercise05/", + "Modules/Exercise06/", + "Modules/Exercise07/" ], "excludes": [ "Config", diff --git a/phpunit.xml b/phpunit.xml index 77442f0..9242f5c 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -6,9 +6,11 @@ > - ./tests/Unit - ./tests/Feature - ./Modules/**/Tests + ./Modules/Exercise03/Tests + ./Modules/Exercise04/Tests + ./Modules/Exercise05/Tests + ./Modules/Exercise06/Tests + ./Modules/Exercise07/Tests ./Modules/Exercise01/Tests @@ -43,8 +45,11 @@ - ./app - ./Modules + ./Modules/Exercise03 + ./Modules/Exercise04 + ./Modules/Exercise05 + ./Modules/Exercise06 + ./Modules/Exercise07 ./Modules/**/Config