Skip to content

Commit

Permalink
Merge pull request #186 from dystcz/feature/update-product-options
Browse files Browse the repository at this point in the history
Update product options
  • Loading branch information
repl6669 authored Oct 17, 2024
2 parents 4e2d238 + 8bead07 commit 593ced5
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 6 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@
- Fixed dynamic relationships
- Added configurable auth guard `/Dystcz/LunarApi/Facades/LunarApi::authGuard($guard)`
- Updated policies to grant more privileges to Filament admins
- Added `product_options` relationship for `products`

### ⚠️ Breaking changes

1. Changed relationship names.

**Relationships:**

`product_options.values``product_options.product_option_values`<br>
`product_variants.values``product_variants.product_option_values`<br>

## 1.0.0-beta.1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,12 @@ public function fields(): iterable
fn (ProductOptionValue $model, string $attribute) => $model->translate($attribute),
),

BelongsTo::make('option', 'option')
BelongsTo::make('product_option', 'option')
->readOnly()
->type(SchemaType::get(ProductOption::class)),
->type(SchemaType::get(ProductOption::class))
->serializeUsing(
static fn ($relation) => $relation->withoutLinks()
),

...parent::fields(),
];
Expand Down
8 changes: 6 additions & 2 deletions src/Domain/ProductOptions/JsonApi/V1/ProductOptionSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,13 @@ public function fields(): iterable
Str::make('handle')
->readOnly(),

HasMany::make('values', 'values')
HasMany::make('product_option_values', 'values')
->type(SchemaType::get(ProductOptionValue::class))
->readOnly(),
->canCount()
->countAs('product_option_values_count')
->serializeUsing(
static fn ($relation) => $relation->withoutLinks()
),

...parent::fields(),
];
Expand Down
8 changes: 8 additions & 0 deletions src/Domain/ProductOptions/Policies/ProductOptionPolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,12 @@ public function delete(?Authenticatable $user, ProductOptionContract $productOpt

return false;
}

/**
* Authorize a user to view variant's product option values.
*/
public function viewProductOptionValues(?Authenticatable $user, ProductOptionContract $productOption): bool
{
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public function routes(): void
$relationships->hasMany('product')->readOnly();
$relationships->hasOne('thumbnail')->readOnly();
$relationships->hasMany('urls')->readOnly();
$relationships->hasMany('product_option_values')->readOnly();
})
->only('index', 'show')
->readOnly();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,14 @@ public function fields(): array
->type(SchemaType::get(Media::class))
->canCount(),

HasMany::make('values', 'values')
HasMany::make('product_option_values', 'values')
->retainFieldName()
->type(SchemaType::get(ProductOptionValue::class))
->readOnly()
->canCount()
->countAs('product_option_values_count')
->serializeUsing(
static fn ($relation) => $relation->withoutLinks(),
static fn ($relation) => $relation->withoutLinks()
),

HasOne::make('default_url', 'defaultUrl')
Expand Down
8 changes: 8 additions & 0 deletions src/Domain/ProductVariants/Policies/ProductVariantPolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ public function viewProduct(?Authenticatable $user, ProductVariantContract $vari
return true;
}

/**
* Authorize a user to view variant's product option values.
*/
public function viewProductOptionValues(?Authenticatable $user, ProductVariantContract $variant): bool
{
return true;
}

/**
* Authorize a user to view variant's thumbnail.
*/
Expand Down
1 change: 1 addition & 0 deletions src/Domain/Products/Http/Routing/ProductRouteGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public function routes(): void
$relationships->hasOne('thumbnail')->readOnly();
$relationships->hasMany('urls')->readOnly();
$relationships->hasMany('product_variants')->readOnly();
$relationships->hasMany('product_options')->readOnly();
})
->only('index', 'show')
->readOnly();
Expand Down
6 changes: 6 additions & 0 deletions src/Domain/Products/JsonApi/V1/ProductSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ public function fields(): iterable
->canCount()
->countAs('product_variants_count'),

HasMany::make('product_options', 'productOptions')
->retainFieldName()
->type('product_options')
->canCount()
->countAs('product_options_count'),

...parent::fields(),
];
}
Expand Down
8 changes: 8 additions & 0 deletions src/Domain/Products/Policies/ProductPolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,12 @@ public function viewProductVariants(?Authenticatable $user, ProductContract $pro
{
return true;
}

/**
* Authorize a user to view product's options.
*/
public function viewProductOptions(?Authenticatable $user, ProductContract $product): bool
{
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

use Dystcz\LunarApi\Domain\Products\Models\Product;
use Dystcz\LunarApi\Domain\ProductVariants\Models\ProductVariant;
use Dystcz\LunarApi\Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Lunar\Models\ProductOption;
use Lunar\Models\ProductOptionValue;

uses(TestCase::class, RefreshDatabase::class);

it('can list product options values through relationship', function () {
/** @var TestCase $this */
$product = Product::factory()
->hasAttached(
ProductOption::factory()
->count(2)
->has(ProductOptionValue::factory()->count(3), 'values'),
['position' => 1],
)
->create();

$values = $product->productOptions->map(fn (ProductOption $option) => $option->values->first());

$variant = ProductVariant::factory()
->for($product, 'product')
->hasAttached($values, [], 'values')
->create();

$response = $this
->jsonApi()
->expects('product_option_values')
->get(serverUrl("/product_variants/{$variant->getRouteKey()}/product_option_values"));

$response
->assertSuccessful()
->assertFetchedMany($variant->values)
->assertDoesntHaveIncluded();
})->group('product-variants');

it('can count product option values', function () {
/** @var TestCase $this */
$product = Product::factory()
->hasAttached(
ProductOption::factory()
->count(2)
->has(ProductOptionValue::factory()->count(3), 'values'),
['position' => 1],
)
->create();

$values = $product->productOptions->map(fn (ProductOption $option) => $option->values->first());

$variant = ProductVariant::factory()
->for($product, 'product')
->hasAttached($values, [], 'values')
->create();

$response = $this
->jsonApi()
->expects('product_variants')
->get(serverUrl("/product_variants/{$variant->getRouteKey()}?with_count=product_option_values"));

$response
->assertSuccessful()
->assertFetchedOne($variant);

expect($response->json('data.relationships.product_option_values.meta.count'))->toBe(2);
})->group('product-variants', 'counts');
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

use Dystcz\LunarApi\Domain\Products\Models\Product;
use Dystcz\LunarApi\Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Lunar\Models\ProductOption;

uses(TestCase::class, RefreshDatabase::class);

it('can list product options through relationship', function () {
/** @var TestCase $this */
$product = Product::factory()
->hasAttached(ProductOption::factory()->count(2), ['position' => 1])
->create();

$response = $this
->jsonApi()
->expects('product_options')
->get(serverUrl("/products/{$product->getRouteKey()}/product_options"));

$response
->assertSuccessful()
->assertFetchedMany($product->productOptions)
->assertDoesntHaveIncluded();
})->group('products');

it('can count product options', function () {
/** @var TestCase $this */
$product = Product::factory()
->hasAttached(ProductOption::factory()->count(4), ['position' => 1])
->create();

$response = $this
->jsonApi()
->expects('products')
->get(serverUrl("/products/{$product->getRouteKey()}?with_count=product_options"));

$response
->assertSuccessful()
->assertFetchedOne($product);

expect($response->json('data.relationships.product_options.meta.count'))->toBe(4);
})->group('products', 'counts');

0 comments on commit 593ced5

Please sign in to comment.