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..44caced --- /dev/null +++ b/Modules/Exercise03/Tests/Feature/Http/Controllers/ProductControllerTest.php @@ -0,0 +1,49 @@ +productService = $this->mock(ProductService::class); + $this->controller = new ProductController($this->productService); + } + + public function test_index_return_view_success() + { + $products = ['name' => 'name']; + $this->productService->shouldReceive('getAllProducts') + ->andReturn($products); + $response = $this->controller->index(); + + $this->assertEquals('exercise03::index', $response->getName()); + $this->assertEquals(compact('products'), $response->getData()); + } + + public function test_checkout_return_view_success() + { + $inputs = [ + 'total_products' => 1, + ]; + + $request = CheckoutRequest::create('', 'post', $inputs); + $this->productService->shouldReceive('calculateDiscount') + ->with($inputs['total_products']) + ->andReturn(1); + $response = $this->controller->checkout($request); + + $this->assertEquals(['discount' => 1], $response->getOriginalContent()); + $this->assertEquals(200, $response->status()); + } +} 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..5fda2c3 --- /dev/null +++ b/Modules/Exercise03/Tests/Feature/Http/Requests/CheckoutRequestTest.php @@ -0,0 +1,41 @@ +checkoutRequest = new CheckoutRequest(); + } + + public function test_validate_success() + { + $input = [ + 'total_products' => [ + 1 => null, + 2 => 2, + 3 => 3, + ], + ]; + + $validator = Validator::make($input, $this->checkoutRequest->rules()); + $this->assertTrue($validator->passes()); + } + + public function test_validate_with_totals_product_error() + { + $input = ['total_product' => 'fail']; + $validator = Validator::make($input, $this->checkoutRequest->rules()); + + $this->assertFalse($validator->passes()); + } +} diff --git a/Modules/Exercise03/Tests/Feature/Models/ProductModelTest.php b/Modules/Exercise03/Tests/Feature/Models/ProductModelTest.php new file mode 100644 index 0000000..36d2bab --- /dev/null +++ b/Modules/Exercise03/Tests/Feature/Models/ProductModelTest.php @@ -0,0 +1,20 @@ +make(); + + $this->assertInstanceOf(Product::class, $product); + } +} diff --git a/Modules/Exercise03/Tests/Unit/Models/ProductTest.php b/Modules/Exercise03/Tests/Unit/Models/ProductTest.php new file mode 100644 index 0000000..92ada7b --- /dev/null +++ b/Modules/Exercise03/Tests/Unit/Models/ProductTest.php @@ -0,0 +1,31 @@ + 'name', + 'type' => Product::CRAVAT_TYPE, + ]; + + $product = Product::create($inputs); + + $this->assertEquals($inputs['name'], $product->name); + $this->assertEquals($inputs['type'], $product->type); + } +} diff --git a/Modules/Exercise03/Tests/Unit/Repositories/ProductRepositoryTest.php b/Modules/Exercise03/Tests/Unit/Repositories/ProductRepositoryTest.php new file mode 100644 index 0000000..afd8821 --- /dev/null +++ b/Modules/Exercise03/Tests/Unit/Repositories/ProductRepositoryTest.php @@ -0,0 +1,29 @@ +productModel = new Product(); + $this->repository = new ProductRepository($this->productModel); + } + + public function test_all() + { + $response = $this->repository->all(); + + $this->assertInstanceOf(Collection::class, $response); + } +} diff --git a/Modules/Exercise03/Tests/Unit/Services/ProductServiceTest.php b/Modules/Exercise03/Tests/Unit/Services/ProductServiceTest.php new file mode 100644 index 0000000..99f6ce0 --- /dev/null +++ b/Modules/Exercise03/Tests/Unit/Services/ProductServiceTest.php @@ -0,0 +1,74 @@ +productRepository = $this->mock(ProductRepository::class); + $this->service = new ProductService($this->productRepository); + + } + + public function test_get_all_products() + { + $this->productRepository->shouldReceive('all') + ->andReturn([]); + $products = $this->service->getAllProducts(); + + $this->assertEquals($products, []); + } + + /** + * @param $totalProducts + * @param $expectedValue + * @dataProvider provide_total_products_data + * */ + public function test_calculate_discount_with_valid_data($totalProducts, $expectedValue) + { + $discount = $this->service->calculateDiscount($totalProducts); + $this->assertEquals($expectedValue, $discount); + } + + public function provide_total_products_data() + { + return [ + [ + [ + Product::CRAVAT_TYPE => 1, + Product::WHITE_SHIRT_TYPE => 2, + Product::OTHER_TYPE => 0, + ], ProductService::CRAVAT_WHITE_SHIRT_DISCOUNT + ], + [ + [ + Product::CRAVAT_TYPE => 2, + Product::WHITE_SHIRT_TYPE => 3, + Product::OTHER_TYPE => 5, + ], 12 + ], + ]; + } + + public function test_calculate_discount_throw_exception() + { + $this->expectException(InvalidArgumentException::class); + $this->service->calculateDiscount([ + Product::CRAVAT_TYPE => -1, + Product::WHITE_SHIRT_TYPE => -2, + Product::OTHER_TYPE => -3, + ]); + } +} 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..eead686 --- /dev/null +++ b/Modules/Exercise04/Tests/Feature/Http/Controllers/CalendarControllerTest.php @@ -0,0 +1,31 @@ +calendarService = $this->mock(CalendarService::class); + $this->controller = new CalendarController($this->calendarService); + } + + public function test_index() + { + $this->calendarService->shouldReceive('getDateClass') + ->andReturn(CalendarService::COLOR_BLACK); + $response = $this->controller->index(); + + $this->assertEquals('exercise04::calendar', $response->getName()); + $this->assertArrayHasKey('calendars', $response->getData()); + } +} diff --git a/Modules/Exercise04/Tests/Unit/Services/CalendarServiceTest.php b/Modules/Exercise04/Tests/Unit/Services/CalendarServiceTest.php new file mode 100644 index 0000000..dd4b6a0 --- /dev/null +++ b/Modules/Exercise04/Tests/Unit/Services/CalendarServiceTest.php @@ -0,0 +1,51 @@ +calendarService = new CalendarService(); + } + + /** + * @dataProvider provider_date_input_data + */ + public function test_get_date_class($date, $expected) + { + $response = $this->calendarService->getDateClass($date, ['2021-04-30']); + + $this->assertEquals($expected, $response); + } + + public function provider_date_input_data() + { + return [ + [ + Carbon::createFromDate(2021, 5, 5), + CalendarService::COLOR_BLACK + ], + [ + Carbon::createFromDate(2021, 5, 23), + CalendarService::COLOR_RED + ], + [ + Carbon::createFromDate(2021, 5, 22), + CalendarService::COLOR_BLUE + ], + [ + Carbon::createFromDate(2021, 4, 30), + CalendarService::COLOR_RED + ], + ]; + } +} 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..831be63 --- /dev/null +++ b/Modules/Exercise05/Tests/Feature/Http/Controllers/Exercise05ControllerTest.php @@ -0,0 +1,51 @@ +orderService = $this->mock(OrderService::class); + $this->controller = new Exercise05Controller($this->orderService); + } + + public function test_index_return_view_success() + { + $response = $this->controller->index(); + + $this->assertEquals('exercise05::index', $response->getName()); + $this->assertArrayHasKey('optionCoupons', $response->getData()); + $this->assertArrayHasKey('optionReceives', $response->getData()); + } + + public function test_store_success() + { + $inputs = [ + 'price' => 1, + 'option_receive' => 1, + 'option_coupon' => 1 + ]; + + $request = OrderRequest::create('', 'post', $inputs); + $this->orderService->shouldReceive('handleDiscount') + ->with($inputs) + ->andReturn(1); + $response = $this->controller->store($request); + $data = $response->getData(); + + $this->assertEquals('exercise05::detail', $response->getName()); + $this->assertEquals(1, $data['resultOrder']); + $this->assertEquals($inputs, $data['detailOrder']); + } +} 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..62c1e2e --- /dev/null +++ b/Modules/Exercise05/Tests/Feature/Http/Requests/OrderRequestTest.php @@ -0,0 +1,71 @@ +request = new OrderRequest(); + } + + /** + * @dataProvider provider_input_fail + * @param $input + */ + public function test_validation_fails($input) + { + $validator = Validator::make($input, $this->request->rules()); + + $this->assertTrue($validator->fails()); + } + + public function provider_input_fail() + { + return [ + [ + [ + 'price' => '', + 'option_receive' => 1, + 'option_coupon' => 1 + ], + [ + 'price' => '!@!#!', + 'option_receive' => 1, + 'option_coupon' => 1 + ], + [ + 'price' => 1, + 'option_receive' => 0, + 'option_coupon' => 1 + ], + [ + 'price' => 1, + 'option_receive' => 1, + 'option_coupon' => 0 + ] + ], + ]; + } + + public function test_validation_success() + { + $request = new OrderRequest(); + $validator = Validator::make([ + 'price' => 1, + 'option_receive' => config('exercise05.receive_at_store'), + 'option_coupon' => config('exercise05.no_coupon') + ], $request->rules()); + + $this->assertTrue($validator->passes()); + } +} diff --git a/Modules/Exercise05/Tests/Unit/Services/OrderServiceTest.php b/Modules/Exercise05/Tests/Unit/Services/OrderServiceTest.php new file mode 100644 index 0000000..ac2c753 --- /dev/null +++ b/Modules/Exercise05/Tests/Unit/Services/OrderServiceTest.php @@ -0,0 +1,84 @@ +service = new OrderService(); + } + + /** + * @dataProvider provide_detail_order_data + * @param $detailOrder + * @param $expected + */ + public function test_handle_discount($detailOrder, $expected) + { + $response = $this->service->handleDiscount($detailOrder); + + $this->assertEquals($expected, $response); + } + + public function provide_detail_order_data() + { + return [ + [ + [ + 'price' => 1000, + 'option_receive' => 2, + 'option_coupon' => 1 + ], + [ + 'price' => 800, + 'discount_pizza' => null, + 'discount_potato' => null + ], + ], + [ + [ + 'price' => 10000, + 'option_receive' => 2, + 'option_coupon' => 2, + ], + [ + 'price' => 10000, + 'discount_pizza' => null, + 'discount_potato' => 'Miễn phí khoai tây', + ] + ], + [ + [ + 'price' => 10000, + 'option_receive' => 2, + 'option_coupon' => 1, + ], + [ + 'price' => 8000, + 'discount_pizza' => null, + 'discount_potato' => 'Miễn phí khoai tây', + ] + ], + [ + [ + 'price' => 10000, + 'option_receive' => 1, + 'option_coupon' => 1, + ], + [ + 'price' => 10000, + 'discount_pizza' => 'Khuyến mại pizza thứ 2', + 'discount_potato' => 'Miễn phí khoai tây', + ] + ], + ]; + } +} 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..f55813e --- /dev/null +++ b/Modules/Exercise06/Tests/Feature/Http/Controllers/Exercise06ControllerTest.php @@ -0,0 +1,57 @@ +calculateService = $this->mock(CalculateService::class); + $this->controller = new Exercise06Controller($this->calculateService); + } + + public function test_index_return_view_success() + { + $expected = [ + 'case1' => CalculateService::CASE_1, + 'case2' => CalculateService::CASE_2, + 'freeTimeForMovie' => CalculateService::FREE_TIME_FOR_MOVIE, + ]; + $response = $this->controller->index(); + + $this->assertEquals('exercise06::index', $response->getName()); + $this->assertEquals($expected, $response->getData()); + } + + public function test_calculate_return_success() + { + $inputs = [ + 'bill' => 1, + 'has_watch' => 1 + ]; + $request = $this->mock(Exercise06Request::class); + $request->shouldReceive('validated') + ->once() + ->andReturn($inputs); + + $this->calculateService->shouldReceive('calculate') + ->with($inputs['bill'], isset($inputs['has_watch'])) + ->andReturn(1); + + $response = $this->controller->calculate($request); + + $this->assertInstanceOf(RedirectResponse::class, $response); + $this->assertEquals(['time' => 1], $response->getSession()->get('result')); + } +} 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..a6cdd92 --- /dev/null +++ b/Modules/Exercise06/Tests/Feature/Http/Requests/Exercise06RequestTest.php @@ -0,0 +1,60 @@ +request = new Exercise06Request(); + } + + public function test_validate_success() + { + $input = [ + 'bill' => 1, + 'has_watch' => false, + ]; + + $validator = Validator::make($input, $this->request->rules()); + $this->assertTrue($validator->passes()); + } + + /** + * @dataProvider provider_input + * @param $input + */ + public function test_validation_failed($input) + { + $validator = Validator::make($input, $this->request->rules()); + + $this->assertTrue($validator->fails()); + } + + public function provider_input() + { + return [ + [ + [], + [ + 'has_watch' => true, + ], + [ + 'bill' => 1.2, + ], + [ + 'bill' => 1200, + 'has_watch' => 'test', + ], + ] + ]; + } +} diff --git a/Modules/Exercise06/Tests/Unit/Services/CalculateServiceTest.php b/Modules/Exercise06/Tests/Unit/Services/CalculateServiceTest.php new file mode 100644 index 0000000..332c750 --- /dev/null +++ b/Modules/Exercise06/Tests/Unit/Services/CalculateServiceTest.php @@ -0,0 +1,85 @@ +service = new CalculateService(); + } + + public function test_calculate_throw_exception() + { + $this->expectException(InvalidArgumentException::class); + $this->service->calculate(0, false); + } + + /** + * @param $data + * @param $expected + * @dataProvider provide_input_data + * */ + public function test_calculate_return_data($data, $expected) + { + $time = $this->service->calculate($data['bill'], $data['has_watch']); + + $this->assertEquals($expected, $time); + } + + public function provide_input_data() + { + return [ + [ + [ + 'bill' => 1, + 'has_watch' => false, + ], + 'time' => 0 + ], + [ + [ + 'bill' => 1, + 'has_watch' => true, + ], + 'time' => 180 + ], + [ + [ + 'bill' => 10000, + 'has_watch' => false, + ], + 'time' => 120 + ], + [ + [ + 'bill' => 3000, + 'has_watch' => false, + ], + 'time' => 60 + ], + [ + [ + 'bill' => 3000, + 'has_watch' => true, + ], + 'time' => 240 + ], + [ + [ + 'bill' => 10000, + 'has_watch' => true, + ], + 'time' => 300 + ], + ]; + } +} 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..e54a1b5 --- /dev/null +++ b/Modules/Exercise07/Tests/Feature/Http/Controllers/CheckoutControllerTest.php @@ -0,0 +1,54 @@ +checkoutService = $this->mock(CheckoutService::class); + $this->controller = new CheckoutController($this->checkoutService); + } + + public function test_index() + { + $response = $this->controller->index(); + + $this->assertEquals('exercise07::checkout.index', $response->getName()); + } + + public function test_store() + { + $inputs = [ + 'amount' => 99, + ]; + $expected = ['shipping_fee' => 10]; + + $request = CheckoutRequest::create('', 'post', $inputs); + + $this->checkoutService->shouldReceive('calculateShippingFee') + ->with($inputs) + ->once() + ->andReturn($expected); + + $response = $this->controller->store($request); + + $this->assertInstanceOf(RedirectResponse::class, $response); + $this->assertEquals($expected, $response->getSession()->get('order')); + } +} 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..f4381b4 --- /dev/null +++ b/Modules/Exercise07/Tests/Feature/Http/Requests/CheckoutRequestTest.php @@ -0,0 +1,60 @@ +request = new CheckoutRequest(); + } + + /** + * @dataProvider provider_input_fail + * @param $input + */ + public function test_validation_fails($input) + { + $validator = Validator::make($input, $this->request->rules()); + + $this->assertTrue($validator->fails()); + } + + public function provider_input_fail() + { + return [ + [ + [ + 'amount' => 0, + ], + [], + [ + 'amount' => 1,2, + ], + [ + 'amount' => '', + ], + [ + 'amount' => '#@$@#', + ], + ], + ]; + } + + public function test_validation_success() + { + $validator = Validator::make([ + 'amount' => 1, + ], $this->request->rules()); + + $this->assertTrue($validator->passes()); + } +} diff --git a/Modules/Exercise07/Tests/Unit/Services/CheckoutServiceTest.php b/Modules/Exercise07/Tests/Unit/Services/CheckoutServiceTest.php new file mode 100644 index 0000000..991d170 --- /dev/null +++ b/Modules/Exercise07/Tests/Unit/Services/CheckoutServiceTest.php @@ -0,0 +1,65 @@ +checkoutService = new CheckoutService(); + } + + /** + * @param $order + * @param $expected + * @dataProvider provide_order_data + * */ + public function test_calculate_shipping_fee($order, $expected) + { + $response = $this->checkoutService->calculateShippingFee($order); + + $this->assertEquals($expected, $response); + } + + public function provide_order_data() + { + return [ + [ + [ + 'amount' => 10000, + ], + [ + 'shipping_fee' => 0, + 'amount' => 10000, + ] + ], + [ + [ + 'amount' => 1000, + ], + [ + 'shipping_fee' => 500, + 'amount' => 1000, + ] + ], + [ + [ + 'amount' => 1000, + 'premium_member' => 1, + ], + [ + 'shipping_fee' => 0, + 'amount' => 1000, + 'premium_member' => 1, + ] + ], + ]; + } +} diff --git a/infection.json b/infection.json index e93241b..bb88daa 100644 --- a/infection.json +++ b/infection.json @@ -1,7 +1,12 @@ { "source": { "directories": [ - "Modules/" + "Modules/Exercise02/", + "Modules/Exercise03/", + "Modules/Exercise04/", + "Modules/Exercise05/", + "Modules/Exercise06/", + "Modules/Exercise07/" ], "excludes": [ "Config", diff --git a/phpunit.xml b/phpunit.xml index 77442f0..25d222f 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -6,9 +6,12 @@ > - ./tests/Unit - ./tests/Feature - ./Modules/**/Tests + ./Modules/Exercise02/Tests + ./Modules/Exercise03/Tests + ./Modules/Exercise04/Tests + ./Modules/Exercise05/Tests + ./Modules/Exercise06/Tests + ./Modules/Exercise07/Tests ./Modules/Exercise01/Tests @@ -43,8 +46,11 @@ - ./app - ./Modules + ./Modules/Exercise03 + ./Modules/Exercise04 + ./Modules/Exercise05 + ./Modules/Exercise06 + ./Modules/Exercise07 ./Modules/**/Config