mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-16 20:22:15 +01:00
Merge branch 'main' of github.com:solidtime-io/solidtime
This commit is contained in:
20
.github/workflows/build-private.yml
vendored
20
.github/workflows/build-private.yml
vendored
@@ -5,7 +5,7 @@ on:
|
|||||||
- develop
|
- develop
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'workflows/build-private.yml'
|
- '.github/workflows/build-private.yml'
|
||||||
- 'docker/prod/**'
|
- 'docker/prod/**'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
@@ -37,6 +37,21 @@ jobs:
|
|||||||
only_args: --no-dev --no-ansi --no-interaction --prefer-dist --ignore-platform-reqs --classmap-authoritative
|
only_args: --no-dev --no-ansi --no-interaction --prefer-dist --ignore-platform-reqs --classmap-authoritative
|
||||||
php_version: 8.3
|
php_version: 8.3
|
||||||
|
|
||||||
|
- name: "Checkout services extension"
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: solidtime-io/extension-services
|
||||||
|
path: extensions/Services
|
||||||
|
ssh-key: ${{ secrets.SSH_PRIVATE_KEY_SERVICES_EXTENSION }}
|
||||||
|
|
||||||
|
- name: "Install dependencies in services extension"
|
||||||
|
uses: php-actions/composer@v6
|
||||||
|
with:
|
||||||
|
working_dir: "extensions/Services"
|
||||||
|
command: install
|
||||||
|
only_args: --no-dev --no-ansi --no-interaction --prefer-dist --ignore-platform-reqs --classmap-authoritative
|
||||||
|
php_version: 8.3
|
||||||
|
|
||||||
- name: "Setup PHP with PECL extension"
|
- name: "Setup PHP with PECL extension"
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
@@ -65,6 +80,9 @@ jobs:
|
|||||||
- name: "Activate billing extension"
|
- name: "Activate billing extension"
|
||||||
run: php artisan module:enable Billing
|
run: php artisan module:enable Billing
|
||||||
|
|
||||||
|
- name: "Activate services extension"
|
||||||
|
run: php artisan module:enable Services
|
||||||
|
|
||||||
- name: "Login to GitHub Container Registry"
|
- name: "Login to GitHub Container Registry"
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
2
.github/workflows/build-public.yml
vendored
2
.github/workflows/build-public.yml
vendored
@@ -5,7 +5,7 @@ on:
|
|||||||
- develop
|
- develop
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'workflows/build-public.yml'
|
- '.github/workflows/build-public.yml'
|
||||||
- 'docker/prod/**'
|
- 'docker/prod/**'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/phpunit.yml
vendored
4
.github/workflows/phpunit.yml
vendored
@@ -50,8 +50,8 @@ jobs:
|
|||||||
php artisan key:generate
|
php artisan key:generate
|
||||||
php artisan passport:keys
|
php artisan passport:keys
|
||||||
|
|
||||||
- name: "Run PHPUnit in parallel"
|
- name: "Run PHPUnit"
|
||||||
run: php artisan test --parallel --stop-on-failure --coverage-text --coverage-clover=coverage.xml
|
run: php artisan test --stop-on-failure --coverage-text --coverage-clover=coverage.xml
|
||||||
|
|
||||||
- name: "Upload coverage reports to Codecov"
|
- name: "Upload coverage reports to Codecov"
|
||||||
uses: codecov/codecov-action@v4.3.0
|
uses: codecov/codecov-action@v4.3.0
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace App\Service\Import\Importers;
|
|||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Spatie\TemporaryDirectory\TemporaryDirectory;
|
use Spatie\TemporaryDirectory\TemporaryDirectory;
|
||||||
|
use ValueError;
|
||||||
use ZipArchive;
|
use ZipArchive;
|
||||||
|
|
||||||
class TogglDataImporter extends DefaultImporter
|
class TogglDataImporter extends DefaultImporter
|
||||||
@@ -20,7 +21,10 @@ class TogglDataImporter extends DefaultImporter
|
|||||||
$zip = new ZipArchive();
|
$zip = new ZipArchive();
|
||||||
$temporaryDirectory = TemporaryDirectory::make();
|
$temporaryDirectory = TemporaryDirectory::make();
|
||||||
file_put_contents($temporaryDirectory->path('import.zip'), $data);
|
file_put_contents($temporaryDirectory->path('import.zip'), $data);
|
||||||
$zip->open($temporaryDirectory->path('import.zip'), ZipArchive::RDONLY);
|
$res = $zip->open($temporaryDirectory->path('import.zip'), ZipArchive::RDONLY);
|
||||||
|
if ($res !== true) {
|
||||||
|
throw new ImportException('Invalid ZIP, error code: '.$res);
|
||||||
|
}
|
||||||
$temporaryDirectory = TemporaryDirectory::make();
|
$temporaryDirectory = TemporaryDirectory::make();
|
||||||
$zip->extractTo($temporaryDirectory->path());
|
$zip->extractTo($temporaryDirectory->path());
|
||||||
$zip->close();
|
$zip->close();
|
||||||
@@ -107,6 +111,8 @@ class TogglDataImporter extends DefaultImporter
|
|||||||
], [], (string) $task->id);
|
], [], (string) $task->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (ValueError $exception) {
|
||||||
|
|
||||||
} catch (ImportException $exception) {
|
} catch (ImportException $exception) {
|
||||||
throw $exception;
|
throw $exception;
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ return [
|
|||||||
|
|
||||||
'stack_production' => [
|
'stack_production' => [
|
||||||
'driver' => 'stack',
|
'driver' => 'stack',
|
||||||
'channels' => ['single', 'sentry'],
|
'channels' => ['stderr', 'sentry'],
|
||||||
],
|
],
|
||||||
|
|
||||||
'daily' => [
|
'daily' => [
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
<CardTitle :title="title" :icon="icon"></CardTitle>
|
<CardTitle :title="title" :icon="icon"></CardTitle>
|
||||||
<div
|
<div
|
||||||
class="rounded-lg bg-card-background border border-card-border flex-1 flex items-stretch">
|
class="rounded-lg bg-card-background border border-card-border flex-1 flex items-stretch">
|
||||||
<div
|
<div class="w-full flex flex-col">
|
||||||
class="w-full flex flex-col">
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -88,9 +88,7 @@ const switchToTeam = (team: Organization) => {
|
|||||||
Organization Settings
|
Organization Settings
|
||||||
</DropdownLink>
|
</DropdownLink>
|
||||||
|
|
||||||
<DropdownLink
|
<DropdownLink v-if="isBillingActivated()" href="/billing">
|
||||||
v-if="isBillingActivated()"
|
|
||||||
href="/billing">
|
|
||||||
Billing
|
Billing
|
||||||
</DropdownLink>
|
</DropdownLink>
|
||||||
|
|
||||||
|
|||||||
@@ -28,14 +28,16 @@ const deleteTeam = () => {
|
|||||||
<ActionSection>
|
<ActionSection>
|
||||||
<template #title> Delete Organization </template>
|
<template #title> Delete Organization </template>
|
||||||
|
|
||||||
<template #description> Permanently delete this organization. </template>
|
<template #description>
|
||||||
|
Permanently delete this organization.
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="max-w-xl text-sm text-muted">
|
<div class="max-w-xl text-sm text-muted">
|
||||||
Once a organization is deleted, all of its resources and data will be
|
Once a organization is deleted, all of its resources and data
|
||||||
permanently deleted. Before deleting this organization, please download
|
will be permanently deleted. Before deleting this organization,
|
||||||
any data or information regarding this organization that you wish to
|
please download any data or information regarding this
|
||||||
retain.
|
organization that you wish to retain.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
|
|||||||
@@ -257,9 +257,9 @@ const displayableRole = (role: string) => {
|
|||||||
<template #title> Pending Team Invitations</template>
|
<template #title> Pending Team Invitations</template>
|
||||||
|
|
||||||
<template #description>
|
<template #description>
|
||||||
These people have been invited to your organization and have been
|
These people have been invited to your organization and have
|
||||||
sent an invitation email. They may join the organization by
|
been sent an invitation email. They may join the
|
||||||
accepting the email invitation.
|
organization by accepting the email invitation.
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- Pending Organization Member Invitation List -->
|
<!-- Pending Organization Member Invitation List -->
|
||||||
@@ -471,7 +471,8 @@ const displayableRole = (role: string) => {
|
|||||||
<template #title> Remove Team Member</template>
|
<template #title> Remove Team Member</template>
|
||||||
|
|
||||||
<template #content>
|
<template #content>
|
||||||
Are you sure you would like to remove this person from the organization?
|
Are you sure you would like to remove this person from the
|
||||||
|
organization?
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ declare(strict_types=1);
|
|||||||
namespace Tests\Unit\Service\Import\Importer;
|
namespace Tests\Unit\Service\Import\Importer;
|
||||||
|
|
||||||
use App\Models\Organization;
|
use App\Models\Organization;
|
||||||
|
use App\Service\Import\Importers\ImportException;
|
||||||
use App\Service\Import\Importers\TogglDataImporter;
|
use App\Service\Import\Importers\TogglDataImporter;
|
||||||
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Spatie\TemporaryDirectory\TemporaryDirectory;
|
use Spatie\TemporaryDirectory\TemporaryDirectory;
|
||||||
@@ -27,6 +29,25 @@ class TogglDataImporterTest extends ImporterTestAbstract
|
|||||||
return $zipPath;
|
return $zipPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_import_throws_exception_if_data_is_not_zip(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$organization = Organization::factory()->create();
|
||||||
|
$importer = new TogglDataImporter();
|
||||||
|
$importer->init($organization);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
try {
|
||||||
|
$importer->importData('not a zip');
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->assertInstanceOf(ImportException::class, $e);
|
||||||
|
$this->assertSame('Invalid ZIP, error code: 19', $e->getMessage());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->fail();
|
||||||
|
}
|
||||||
|
|
||||||
public function test_import_of_test_file_succeeds(): void
|
public function test_import_of_test_file_succeeds(): void
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
@@ -48,7 +69,6 @@ class TogglDataImporterTest extends ImporterTestAbstract
|
|||||||
$this->assertSame(1, $report->usersCreated);
|
$this->assertSame(1, $report->usersCreated);
|
||||||
$this->assertSame(2, $report->projectsCreated);
|
$this->assertSame(2, $report->projectsCreated);
|
||||||
$this->assertSame(1, $report->clientsCreated);
|
$this->assertSame(1, $report->clientsCreated);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_import_of_test_file_twice_succeeds(): void
|
public function test_import_of_test_file_twice_succeeds(): void
|
||||||
|
|||||||
Reference in New Issue
Block a user