Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: add features to create billing plan #599

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,20 @@ public function removeUser(Request $request, $org_id, $user_id)
{
$organisation = Organisation::findOrFail($org_id);

if (!$organisation) {
return response()->json([
'data' => null,
'error' => 'Not Found',
'message' => 'Organization not found',
'status_code' => 404
], 404);
}

// Use $request->auth instead of Auth::user()
if (!$request->user()->can('removeUser', $organisation)) {
return response()->json([
'status' => 'Forbidden',
'data' => null,
'error' => 'Unauthorized',
'message' => 'Only admin can remove users',
'status_code' => 403
], 403);
Expand All @@ -183,8 +193,9 @@ public function removeUser(Request $request, $org_id, $user_id)

if (!$user || !$organisation->users()->detach($user)) {
return response()->json([
'status' => 'forbidden',
'message' => 'user not found',
'data' => null,
'error' => 'Not Found',
'message' => 'User not found',
'status_code' => 404
], 404);
}
Expand Down
55 changes: 54 additions & 1 deletion app/Http/Controllers/BillingPlanController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Models\SubscriptionPlan;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Validator;

class BillingPlanController extends Controller
{
Expand Down Expand Up @@ -42,7 +43,59 @@ public function create()
*/
public function store(Request $request)
{
//
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255',
'frequency' => 'required|string|in:Monthly,Yearly',
'is_active' => 'boolean',
'amount' => 'required|numeric|min:0',
'description' => 'nullable|string|max:1000',
]);

// If validation fails, return a 400 Bad Request response
if ($validator->fails()) {
return response()->json([
'data' => null,
'error' => 'Bad Request',
'message' => $validator->errors()->first(),
'status_code' => Response::HTTP_BAD_REQUEST
], Response::HTTP_BAD_REQUEST);
}

try {
// Create a new billing plan
$billingPlan = SubscriptionPlan::create([
'name' => $request->input('name'),
'duration' => $request->input('frequency'),
// 'is_active' => $request->input('is_active'),
'price' => $request->input('amount'),
'description' => $request->input('description'),
]);

// Return a 201 Created response with the billing plan data
return response()->json([
'data' => [
'id' => $billingPlan->id,
'name' => $billingPlan->name,
'frequency' => $billingPlan->duration,
// 'is_active' => $billingPlan->is_active,
'amount' => $billingPlan->price,
'description' => $billingPlan->description,
'created_at' => $billingPlan->created_at->toIso8601String(),
'updated_at' => $billingPlan->updated_at->toIso8601String(),
],
'message' => 'Billing plan created successfully',
'status_code' => Response::HTTP_CREATED
], Response::HTTP_CREATED);

} catch (\Exception $e) {
// If an unexpected error occurs, return a 500 Internal Server Error response
return response()->json([
'data' => null,
'error' => 'Internal Server Error',
'message' => 'An unexpected error occurred',
'status_code' => Response::HTTP_INTERNAL_SERVER_ERROR
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}

/**
Expand Down
2 changes: 2 additions & 0 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@
Route::patch('/comments/edit/{commentId}', [CommentController::class, 'editComment']);
Route::delete('/comments/{commentId}', [CommentController::class, 'deleteComment']);
Route::get('/blogs/{blogId}/comments', [CommentController::class, 'getBlogComments']);

Route::post('/billing-plans', [BillingPlanController::class, 'store']);
});

Route::middleware('throttle:10,1')->get('/help-center/topics/search', [ArticleController::class, 'search']);
Expand Down
112 changes: 112 additions & 0 deletions tests/Feature/BillingPlanControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

namespace Tests\Feature;

use App\Models\SubscriptionPlan;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Http\Response;
use Tests\TestCase;

class BillingPlanControllerTest extends TestCase
{
use RefreshDatabase, WithFaker;

protected $user;
protected $organisation;

protected function setUp(): void
{
parent::setUp();

// Create a user and log them in
$this->user = User::factory()->create();
$this->actingAs($this->user);
}

/** @test */
public function it_creates_a_billing_plan_successfully()
{
// Prepare the data to be sent in the request
$data = [
'name' => 'Basic Plan',
'frequency' => 'Monthly',
'is_active' => true,
'amount' => 1000, // Assuming this is in kobo
'description' => 'This is a basic plan',
];

// Send the POST request to create the billing plan
$response = $this->postJson('/api/v1/billing-plans', $data);

// Assert that the response status is 201 Created
$response->assertStatus(Response::HTTP_CREATED);

// Assert that the response JSON structure is as expected
$response->assertJsonStructure([
'data' => [
'id',
'name',
'frequency',
'amount',
'description',
'created_at',
'updated_at',
],
'message',
'status_code',
]);

// Assert that the response contains the correct data
$response->assertJson([
'data' => [
'name' => 'Basic Plan',
'frequency' => 'Monthly',
'amount' => 1000,
'description' => 'This is a basic plan',
],
'message' => 'Billing plan created successfully',
'status_code' => Response::HTTP_CREATED,
]);

// Assert that the billing plan was created in the database
$this->assertDatabaseHas('subscription_plans', [
'name' => 'Basic Plan',
'duration' => 'Monthly',
'price' => 1000,
'description' => 'This is a basic plan',
]);
}

/** @test */
public function it_fails_to_create_a_billing_plan_due_to_validation_error()
{
// Prepare invalid data (missing required fields)
$data = [
'name' => '',
'frequency' => 'Weekly', // Invalid frequency
'is_active' => 'yes', // Invalid boolean value
'amount' => -100, // Negative amount
];

// Send the POST request to create the billing plan
$response = $this->postJson('/api/v1/billing-plans', $data);

// Assert that the response status is 400 Bad Request
$response->assertStatus(Response::HTTP_BAD_REQUEST);

// Assert that the response JSON contains the validation errors
$response->assertJsonStructure([
'data',
'error',
'message',
'status_code',
]);

// Ensure no billing plan was created in the database
$this->assertDatabaseMissing('subscription_plans', [
'name' => $data['name'],
]);
}
}
2 changes: 1 addition & 1 deletion tests/Feature/OrganisationRemoveUserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function it_test_unauthorized_user_cannot_remove_user()

$response->assertStatus(403)
->assertJson([
'status' => 'Forbidden',
'error' => 'Unauthorized',
'message' => 'Only admin can remove users',
'status_code' => 403,
]);
Expand Down
Loading