From da56c151fe56e3b99053e13fc8c5641636e721ce Mon Sep 17 00:00:00 2001 From: Allan Kong Date: Mon, 28 Apr 2025 20:55:59 -0600 Subject: [PATCH 1/3] Good enough review updates, with test --- .../Controllers/ResourceReviewController.php | 45 ++- app/Listeners/UpdateResourceReviewSummary.php | 49 +-- .../Reviews/CreateResourceReview.vue | 343 +++++++++--------- .../Resources/Reviews/ResourceReview.vue | 203 ++++++++--- .../Reviews/UpdateResourceReview.vue | 217 +++++++++++ routes/web.php | 1 + tests/Feature/ResourceReviewsTest.php | 39 ++ 7 files changed, 641 insertions(+), 256 deletions(-) create mode 100644 resources/js/Components/Resources/Reviews/UpdateResourceReview.vue diff --git a/app/Http/Controllers/ResourceReviewController.php b/app/Http/Controllers/ResourceReviewController.php index 2c768db9..ad28779c 100644 --- a/app/Http/Controllers/ResourceReviewController.php +++ b/app/Http/Controllers/ResourceReviewController.php @@ -49,8 +49,51 @@ public function store(StoreResourceReview $request, ComputerScienceResource $com ResourceReviewProcessed::dispatch($computerScienceResource->id, null, $review->attributesToArray()); - // Json with success return to_route('resources.show', ['computerScienceResource' => $review->computer_science_resource_id]) ->with('success', 'Review created successfully!'); } + + public function update(StoreResourceReview $request, ComputerScienceResource $computerScienceResource) + { + // Validate the request data + $validatedData = $request->validated(); + + $existingReview = ResourceReview::where([ + 'user_id' => Auth::id(), + 'computer_science_resource_id' => $computerScienceResource->id, + ])->first(); + + if (!$existingReview) { + Log::debug("User has not already posted a review"); + // TODO: Make it a json with errors instead + return back()->with('warning', 'You need to have a review posted before editing one.'); + } + + Log::debug("Updating resource review: " . json_encode($validatedData)); + + // Update the existing review + $oldAttributes = $existingReview->attributesToArray(); // Save old attributes + + $existingReview->update([ + 'title' => $validatedData['title'], + 'description' => $validatedData['description'], + 'community' => $validatedData['community'], + 'teaching_clarity' => $validatedData['teaching_clarity'], + 'engagement' => $validatedData['engagement'], + 'practicality' => $validatedData['practicality'], + 'user_friendliness' => $validatedData['user_friendliness'], + 'updates' => $validatedData['updates'], + 'pros' => $validatedData['pros'], + 'cons' => $validatedData['cons'], + ]); + + // Dispatch event with old and new data + ResourceReviewProcessed::dispatch( + $computerScienceResource->id, + $oldAttributes, + $existingReview->attributesToArray() + ); + + return response()->json(); + } } diff --git a/app/Listeners/UpdateResourceReviewSummary.php b/app/Listeners/UpdateResourceReviewSummary.php index d7b3eaa6..74a973fc 100644 --- a/app/Listeners/UpdateResourceReviewSummary.php +++ b/app/Listeners/UpdateResourceReviewSummary.php @@ -26,31 +26,34 @@ public function handle(ResourceReviewProcessed $event): void Log::debug("Handling ResourceReviewProcessed: " . json_encode($event)); if ($event->oldReview == null && $event->newReview == null) { - Log::critical("Update Resource Review Summary Listener reached impossible condition, null oldReview and null newReview"); + Log::critical("Update Resource Review Summary Listener reached impossible condition: null oldReview and null newReview"); return; } - - // We are creating a review - else if ($event->oldReview == null && $event->newReview) { - $review_summary = ResourceReviewSummary::firstOrNew( - ['computer_science_resource_id' => $event->resource], - ); - - $review_summary->community = $review_summary->community + $event->newReview['community']; - $review_summary->teaching_clarity = $review_summary->teaching_clarity + $event->newReview['teaching_clarity']; - $review_summary->engagement = $review_summary->engagement + $event->newReview['engagement']; - $review_summary->practicality = $review_summary->practicality + $event->newReview['practicality']; - $review_summary->user_friendliness = $review_summary->user_friendliness + $event->newReview['user_friendliness']; - $review_summary->updates = $review_summary->updates + $event->newReview['updates']; - - $review_summary->review_count = $review_summary->review_count + 1; - $review_summary->save(); - - Log::debug("Saved the update for the review summary: " . json_encode($review_summary)); - return; + + $review_summary = ResourceReviewSummary::firstOrNew( + ['computer_science_resource_id' => $event->resource], + ); + + $fields = [ + 'community', + 'teaching_clarity', + 'engagement', + 'practicality', + 'user_friendliness', + 'updates', + ]; + + foreach ($fields as $field) { + $old = $event->oldReview[$field] ?? 0; + $new = $event->newReview[$field] ?? 0; + $review_summary->$field += ($new - $old); } - - // Implement more logic when needed - + + if ($event->oldReview === null) { + // It's a new review, so increase the count + $review_summary->review_count += 1; + } + + $review_summary->save(); } } diff --git a/resources/js/Components/Resources/Reviews/CreateResourceReview.vue b/resources/js/Components/Resources/Reviews/CreateResourceReview.vue index 24bc73c7..f95b3136 100644 --- a/resources/js/Components/Resources/Reviews/CreateResourceReview.vue +++ b/resources/js/Components/Resources/Reviews/CreateResourceReview.vue @@ -6,8 +6,9 @@ import { Form, FormField } from "@primevue/forms"; import PrimeVueFormError from "@/Components/Form/PrimeVueFormError.vue"; import InputText from "primevue/inputtext"; import InputTextarea from "primevue/textarea"; -import Button from "primevue/button"; +import Rating from "primevue/rating"; import ListInput from "@/Components/ListInput.vue"; +import Button from "primevue/button"; import { yupResolver } from "@primevue/forms/resolvers/yup"; import { resourceReviewFields } from "@/Helpers/validation"; @@ -20,31 +21,24 @@ const props = defineProps({ }); const form = useForm({ - title: "1", - description: "1", - community: "1", - teaching_clarity: "1", - engagement: "1", - practicality: "1", - user_friendliness: "1", - updates: "1", + title: "", + description: "", + community: null, + teaching_clarity: null, + engagement: null, + practicality: null, + user_friendliness: null, + updates: null, pros: [], cons: [], }); -// Define the Yup schema. -const schema = resourceReviewFields; +const resolver = ref(yupResolver(resourceReviewFields)); -// Create the Yup resolver instance. -const resolver = ref(yupResolver(schema)); - -// On submission, validate using the schema and then submit via Inertia. const submitReview = () => { - console.log(form); - schema + resourceReviewFields .validate(form.data, { abortEarly: false }) .then(() => { - console.log("posted"); form.post( route("reviews.store", { computerScienceResource: props.resourceId, @@ -59,161 +53,162 @@ const submitReview = () => { diff --git a/resources/js/Components/Resources/Reviews/ResourceReview.vue b/resources/js/Components/Resources/Reviews/ResourceReview.vue index e2beaec3..9e2f7a22 100644 --- a/resources/js/Components/Resources/Reviews/ResourceReview.vue +++ b/resources/js/Components/Resources/Reviews/ResourceReview.vue @@ -1,15 +1,45 @@ diff --git a/resources/js/Components/Resources/Reviews/UpdateResourceReview.vue b/resources/js/Components/Resources/Reviews/UpdateResourceReview.vue new file mode 100644 index 00000000..965c9afe --- /dev/null +++ b/resources/js/Components/Resources/Reviews/UpdateResourceReview.vue @@ -0,0 +1,217 @@ + + + diff --git a/routes/web.php b/routes/web.php index 938cd1c0..d457da88 100644 --- a/routes/web.php +++ b/routes/web.php @@ -45,6 +45,7 @@ // CompSci Resource Reviews Route::controller(ResourceReviewController::class)->group(function () { Route::post('/reviews/{computerScienceResource}', 'store')->name('reviews.store'); + Route::put('/reviews/{computerScienceResource}', 'update')->name('reviews.update'); }); // Resource Edits diff --git a/tests/Feature/ResourceReviewsTest.php b/tests/Feature/ResourceReviewsTest.php index bc751d0a..fc6c9b82 100644 --- a/tests/Feature/ResourceReviewsTest.php +++ b/tests/Feature/ResourceReviewsTest.php @@ -153,4 +153,43 @@ public function test_resource_review_average_updates_correctly(): void 'review_count' => $reviewCount, ], $total)); } + + public function test_resource_review_can_be_updated(): void + { + $resource = ComputerScienceResource::factory()->create(); + $user = User::factory()->create(); + $total = [ + 'community' => 0, + 'teaching_clarity' => 0, + 'engagement' => 0, + 'practicality' => 0, + 'user_friendliness' => 0, + 'updates' => 0, + ]; + + $data = ResourceReviewTestResource::fake(); + foreach (array_keys($total) as $key) { + $total[$key] = $data[$key]; + } + + $this->actingAs($user)->post(route('reviews.store', $resource), $data); + + $this->assertDatabaseHas('resource_review_summaries', array_merge([ + 'computer_science_resource_id' => $resource->id, + 'review_count' => 1, + ], $total)); + + // Update to new review + $newData = ResourceReviewTestResource::fake(); + foreach (array_keys($total) as $key) { + $total[$key] = $newData[$key]; + } + + $this->actingAs($user)->put(route('reviews.update', $resource), $newData); + + $this->assertDatabaseHas('resource_review_summaries', array_merge([ + 'computer_science_resource_id' => $resource->id, + 'review_count' => 1, + ], $total)); + } } From 8affbe0b80667a13ccd1a2dde02caadd49251b77 Mon Sep 17 00:00:00 2001 From: Allan Kong Date: Wed, 30 Apr 2025 13:45:55 -0600 Subject: [PATCH 2/3] Added debugger support with xdebug --- docker-compose.yml | 4 +- docker/8.0/Dockerfile | 70 ++++++++++++++++++++++ docker/8.0/php.ini | 5 ++ docker/8.0/start-container | 26 +++++++++ docker/8.0/supervisord.conf | 14 +++++ docker/8.1/Dockerfile | 69 ++++++++++++++++++++++ docker/8.1/php.ini | 5 ++ docker/8.1/start-container | 26 +++++++++ docker/8.1/supervisord.conf | 14 +++++ docker/8.2/Dockerfile | 70 ++++++++++++++++++++++ docker/8.2/php.ini | 5 ++ docker/8.2/start-container | 26 +++++++++ docker/8.2/supervisord.conf | 14 +++++ docker/8.3/Dockerfile | 71 +++++++++++++++++++++++ docker/8.3/php.ini | 5 ++ docker/8.3/start-container | 26 +++++++++ docker/8.3/supervisord.conf | 14 +++++ docker/8.4/Dockerfile | 71 +++++++++++++++++++++++ docker/8.4/php.ini | 10 ++++ docker/8.4/start-container | 26 +++++++++ docker/8.4/supervisord.conf | 14 +++++ docker/mariadb/create-testing-database.sh | 6 ++ docker/mysql/create-testing-database.sh | 6 ++ docker/pgsql/create-testing-database.sql | 2 + 24 files changed, 597 insertions(+), 2 deletions(-) create mode 100644 docker/8.0/Dockerfile create mode 100644 docker/8.0/php.ini create mode 100644 docker/8.0/start-container create mode 100644 docker/8.0/supervisord.conf create mode 100644 docker/8.1/Dockerfile create mode 100644 docker/8.1/php.ini create mode 100644 docker/8.1/start-container create mode 100644 docker/8.1/supervisord.conf create mode 100644 docker/8.2/Dockerfile create mode 100644 docker/8.2/php.ini create mode 100644 docker/8.2/start-container create mode 100644 docker/8.2/supervisord.conf create mode 100644 docker/8.3/Dockerfile create mode 100644 docker/8.3/php.ini create mode 100644 docker/8.3/start-container create mode 100644 docker/8.3/supervisord.conf create mode 100644 docker/8.4/Dockerfile create mode 100644 docker/8.4/php.ini create mode 100644 docker/8.4/start-container create mode 100644 docker/8.4/supervisord.conf create mode 100644 docker/mariadb/create-testing-database.sh create mode 100644 docker/mysql/create-testing-database.sh create mode 100644 docker/pgsql/create-testing-database.sql diff --git a/docker-compose.yml b/docker-compose.yml index 406ec2fd..f6295c06 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ services: laravel.test: build: - context: './vendor/laravel/sail/runtimes/8.4' + context: './docker/8.4' dockerfile: Dockerfile args: WWWGROUP: '${WWWGROUP}' @@ -37,7 +37,7 @@ services: MYSQL_ALLOW_EMPTY_PASSWORD: 1 volumes: - 'sail-mysql:/var/lib/mysql' - - './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh' + - './docker/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh' networks: - sail healthcheck: diff --git a/docker/8.0/Dockerfile b/docker/8.0/Dockerfile new file mode 100644 index 00000000..b7b34e27 --- /dev/null +++ b/docker/8.0/Dockerfile @@ -0,0 +1,70 @@ +FROM ubuntu:24.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=22 +ARG POSTGRES_VERSION=17 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80" +ENV SUPERVISOR_PHP_USER="sail" + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom + +RUN apt-get update && apt-get upgrade -y \ + && mkdir -p /etc/apt/keyrings \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \ + && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /usr/share/keyrings/ppa_ondrej_php.gpg > /dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y php8.0-cli php8.0-dev \ + php8.0-pgsql php8.0-sqlite3 php8.0-gd php8.0-imagick \ + php8.0-curl php8.0-memcached php8.0-mongodb \ + php8.0-imap php8.0-mysql php8.0-mbstring \ + php8.0-xml php8.0-zip php8.0-bcmath php8.0-soap \ + php8.0-intl php8.0-readline php8.0-pcov \ + php8.0-msgpack php8.0-igbinary php8.0-ldap \ + php8.0-redis php8.0-swoole php8.0-xdebug \ + && curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && npm install -g bun \ + && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarnkey.gpg >/dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y yarn \ + && apt-get install -y mysql-client \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN update-alternatives --set php /usr/bin/php8.0 + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.0 + +RUN userdel -r ubuntu +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.0/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 80/tcp + +ENTRYPOINT ["start-container"] diff --git a/docker/8.0/php.ini b/docker/8.0/php.ini new file mode 100644 index 00000000..0d8ce9e2 --- /dev/null +++ b/docker/8.0/php.ini @@ -0,0 +1,5 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS +pcov.directory = . diff --git a/docker/8.0/start-container b/docker/8.0/start-container new file mode 100644 index 00000000..40c55dfe --- /dev/null +++ b/docker/8.0/start-container @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then + echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'." + exit 1 +fi + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + if [ "$SUPERVISOR_PHP_USER" = "root" ]; then + exec "$@" + else + exec gosu $WWWUSER "$@" + fi +else + exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/8.0/supervisord.conf b/docker/8.0/supervisord.conf new file mode 100644 index 00000000..656da8a9 --- /dev/null +++ b/docker/8.0/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=%(ENV_SUPERVISOR_PHP_COMMAND)s +user=%(ENV_SUPERVISOR_PHP_USER)s +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/8.1/Dockerfile b/docker/8.1/Dockerfile new file mode 100644 index 00000000..cc5c6114 --- /dev/null +++ b/docker/8.1/Dockerfile @@ -0,0 +1,69 @@ +FROM ubuntu:24.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=22 +ARG POSTGRES_VERSION=17 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80" +ENV SUPERVISOR_PHP_USER="sail" + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom + +RUN apt-get update && apt-get upgrade -y \ + && mkdir -p /etc/apt/keyrings \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \ + && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /usr/share/keyrings/ppa_ondrej_php.gpg > /dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y php8.1-cli php8.1-dev \ + php8.1-pgsql php8.1-sqlite3 php8.1-gd php8.1-imagick \ + php8.1-curl php8.1-mongodb \ + php8.1-imap php8.1-mysql php8.1-mbstring \ + php8.1-xml php8.1-zip php8.1-bcmath php8.1-soap \ + php8.1-intl php8.1-readline \ + php8.1-ldap \ + php8.1-msgpack php8.1-igbinary php8.1-redis php8.1-swoole \ + php8.1-memcached php8.1-pcov php8.1-xdebug \ + && curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && npm install -g bun \ + && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarn.gpg >/dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /usr/share/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/usr/share/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y yarn \ + && apt-get install -y mysql-client \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.1 + +RUN userdel -r ubuntu +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.1/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 80/tcp + +ENTRYPOINT ["start-container"] diff --git a/docker/8.1/php.ini b/docker/8.1/php.ini new file mode 100644 index 00000000..0d8ce9e2 --- /dev/null +++ b/docker/8.1/php.ini @@ -0,0 +1,5 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS +pcov.directory = . diff --git a/docker/8.1/start-container b/docker/8.1/start-container new file mode 100644 index 00000000..40c55dfe --- /dev/null +++ b/docker/8.1/start-container @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then + echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'." + exit 1 +fi + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + if [ "$SUPERVISOR_PHP_USER" = "root" ]; then + exec "$@" + else + exec gosu $WWWUSER "$@" + fi +else + exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/8.1/supervisord.conf b/docker/8.1/supervisord.conf new file mode 100644 index 00000000..656da8a9 --- /dev/null +++ b/docker/8.1/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=%(ENV_SUPERVISOR_PHP_COMMAND)s +user=%(ENV_SUPERVISOR_PHP_USER)s +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/8.2/Dockerfile b/docker/8.2/Dockerfile new file mode 100644 index 00000000..536dffe1 --- /dev/null +++ b/docker/8.2/Dockerfile @@ -0,0 +1,70 @@ +FROM ubuntu:24.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=22 +ARG POSTGRES_VERSION=17 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80" +ENV SUPERVISOR_PHP_USER="sail" + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom + +RUN apt-get update && apt-get upgrade -y \ + && mkdir -p /etc/apt/keyrings \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \ + && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y php8.2-cli php8.2-dev \ + php8.2-pgsql php8.2-sqlite3 php8.2-gd php8.2-imagick \ + php8.2-curl php8.2-mongodb \ + php8.2-imap php8.2-mysql php8.2-mbstring \ + php8.2-xml php8.2-zip php8.2-bcmath php8.2-soap \ + php8.2-intl php8.2-readline \ + php8.2-ldap \ + php8.2-msgpack php8.2-igbinary php8.2-redis php8.2-swoole \ + php8.2-memcached php8.2-pcov php8.2-xdebug \ + && curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && npm install -g pnpm \ + && npm install -g bun \ + && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /etc/apt/keyrings/yarn.gpg >/dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y yarn \ + && apt-get install -y mysql-client \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.2 + +RUN userdel -r ubuntu +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.2/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 80/tcp + +ENTRYPOINT ["start-container"] diff --git a/docker/8.2/php.ini b/docker/8.2/php.ini new file mode 100644 index 00000000..0d8ce9e2 --- /dev/null +++ b/docker/8.2/php.ini @@ -0,0 +1,5 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS +pcov.directory = . diff --git a/docker/8.2/start-container b/docker/8.2/start-container new file mode 100644 index 00000000..40c55dfe --- /dev/null +++ b/docker/8.2/start-container @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then + echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'." + exit 1 +fi + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + if [ "$SUPERVISOR_PHP_USER" = "root" ]; then + exec "$@" + else + exec gosu $WWWUSER "$@" + fi +else + exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/8.2/supervisord.conf b/docker/8.2/supervisord.conf new file mode 100644 index 00000000..656da8a9 --- /dev/null +++ b/docker/8.2/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=%(ENV_SUPERVISOR_PHP_COMMAND)s +user=%(ENV_SUPERVISOR_PHP_USER)s +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/8.3/Dockerfile b/docker/8.3/Dockerfile new file mode 100644 index 00000000..ef5904bb --- /dev/null +++ b/docker/8.3/Dockerfile @@ -0,0 +1,71 @@ +FROM ubuntu:24.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=22 +ARG MYSQL_CLIENT="mysql-client" +ARG POSTGRES_VERSION=17 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80" +ENV SUPERVISOR_PHP_USER="sail" + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom + +RUN apt-get update && apt-get upgrade -y \ + && mkdir -p /etc/apt/keyrings \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \ + && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y php8.3-cli php8.3-dev \ + php8.3-pgsql php8.3-sqlite3 php8.3-gd \ + php8.3-curl php8.3-mongodb \ + php8.3-imap php8.3-mysql php8.3-mbstring \ + php8.3-xml php8.3-zip php8.3-bcmath php8.3-soap \ + php8.3-intl php8.3-readline \ + php8.3-ldap \ + php8.3-msgpack php8.3-igbinary php8.3-redis \ + php8.3-memcached php8.3-pcov php8.3-imagick php8.3-xdebug php8.3-swoole \ + && curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && npm install -g pnpm \ + && npm install -g bun \ + && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /etc/apt/keyrings/yarn.gpg >/dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y yarn \ + && apt-get install -y $MYSQL_CLIENT \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.3 + +RUN userdel -r ubuntu +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.3/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 80/tcp + +ENTRYPOINT ["start-container"] diff --git a/docker/8.3/php.ini b/docker/8.3/php.ini new file mode 100644 index 00000000..0d8ce9e2 --- /dev/null +++ b/docker/8.3/php.ini @@ -0,0 +1,5 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS +pcov.directory = . diff --git a/docker/8.3/start-container b/docker/8.3/start-container new file mode 100644 index 00000000..40c55dfe --- /dev/null +++ b/docker/8.3/start-container @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then + echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'." + exit 1 +fi + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + if [ "$SUPERVISOR_PHP_USER" = "root" ]; then + exec "$@" + else + exec gosu $WWWUSER "$@" + fi +else + exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/8.3/supervisord.conf b/docker/8.3/supervisord.conf new file mode 100644 index 00000000..656da8a9 --- /dev/null +++ b/docker/8.3/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=%(ENV_SUPERVISOR_PHP_COMMAND)s +user=%(ENV_SUPERVISOR_PHP_USER)s +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/8.4/Dockerfile b/docker/8.4/Dockerfile new file mode 100644 index 00000000..cb0fbdc1 --- /dev/null +++ b/docker/8.4/Dockerfile @@ -0,0 +1,71 @@ +FROM ubuntu:24.04 + +LABEL maintainer="Taylor Otwell" + +ARG WWWGROUP +ARG NODE_VERSION=22 +ARG MYSQL_CLIENT="mysql-client" +ARG POSTGRES_VERSION=17 + +WORKDIR /var/www/html + +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV SUPERVISOR_PHP_COMMAND="/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80" +ENV SUPERVISOR_PHP_USER="sail" + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \ + echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom + +RUN apt-get update && apt-get upgrade -y \ + && mkdir -p /etc/apt/keyrings \ + && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python3 dnsutils librsvg2-bin fswatch ffmpeg nano \ + && curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xb8dc7e53946656efbce4c1dd71daeaab4ad4cab6' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg > /dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble main" > /etc/apt/sources.list.d/ppa_ondrej_php.list \ + && apt-get update \ + && apt-get install -y php8.4-cli php8.4-dev \ + php8.4-pgsql php8.4-sqlite3 php8.4-gd \ + php8.4-curl php8.4-mongodb \ + php8.4-imap php8.4-mysql php8.4-mbstring \ + php8.4-xml php8.4-zip php8.4-bcmath php8.4-soap \ + php8.4-intl php8.4-readline \ + php8.4-ldap \ + php8.4-msgpack php8.4-igbinary php8.4-redis php8.4-swoole \ + php8.4-memcached php8.4-pcov php8.4-imagick php8.4-xdebug \ + && curl -sLS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ + && apt-get update \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && npm install -g pnpm \ + && npm install -g bun \ + && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /etc/apt/keyrings/yarn.gpg >/dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && curl -sS https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/keyrings/pgdg.gpg >/dev/null \ + && echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] http://apt.postgresql.org/pub/repos/apt noble-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && apt-get install -y yarn \ + && apt-get install -y $MYSQL_CLIENT \ + && apt-get install -y postgresql-client-$POSTGRES_VERSION \ + && apt-get -y autoremove \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN setcap "cap_net_bind_service=+ep" /usr/bin/php8.4 + +RUN userdel -r ubuntu +RUN groupadd --force -g $WWWGROUP sail +RUN useradd -ms /bin/bash --no-user-group -g $WWWGROUP -u 1337 sail + +COPY start-container /usr/local/bin/start-container +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY php.ini /etc/php/8.4/cli/conf.d/99-sail.ini +RUN chmod +x /usr/local/bin/start-container + +EXPOSE 80/tcp + +ENTRYPOINT ["start-container"] diff --git a/docker/8.4/php.ini b/docker/8.4/php.ini new file mode 100644 index 00000000..387b5be7 --- /dev/null +++ b/docker/8.4/php.ini @@ -0,0 +1,10 @@ +[PHP] +post_max_size = 100M +upload_max_filesize = 100M +variables_order = EGPCS +pcov.directory = . +[xdebug] +xdebug.mode=develop,debug +xdebug.start_with_request=yes +xdebug.client_host=host.docker.internal +xdebug.client_port=9003 diff --git a/docker/8.4/start-container b/docker/8.4/start-container new file mode 100644 index 00000000..40c55dfe --- /dev/null +++ b/docker/8.4/start-container @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +if [ "$SUPERVISOR_PHP_USER" != "root" ] && [ "$SUPERVISOR_PHP_USER" != "sail" ]; then + echo "You should set SUPERVISOR_PHP_USER to either 'sail' or 'root'." + exit 1 +fi + +if [ ! -z "$WWWUSER" ]; then + usermod -u $WWWUSER sail +fi + +if [ ! -d /.composer ]; then + mkdir /.composer +fi + +chmod -R ugo+rw /.composer + +if [ $# -gt 0 ]; then + if [ "$SUPERVISOR_PHP_USER" = "root" ]; then + exec "$@" + else + exec gosu $WWWUSER "$@" + fi +else + exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/docker/8.4/supervisord.conf b/docker/8.4/supervisord.conf new file mode 100644 index 00000000..656da8a9 --- /dev/null +++ b/docker/8.4/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:php] +command=%(ENV_SUPERVISOR_PHP_COMMAND)s +user=%(ENV_SUPERVISOR_PHP_USER)s +environment=LARAVEL_SAIL="1" +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/mariadb/create-testing-database.sh b/docker/mariadb/create-testing-database.sh new file mode 100644 index 00000000..d3b19d90 --- /dev/null +++ b/docker/mariadb/create-testing-database.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +/usr/bin/mariadb --user=root --password="$MYSQL_ROOT_PASSWORD" <<-EOSQL + CREATE DATABASE IF NOT EXISTS testing; + GRANT ALL PRIVILEGES ON \`testing%\`.* TO '$MYSQL_USER'@'%'; +EOSQL diff --git a/docker/mysql/create-testing-database.sh b/docker/mysql/create-testing-database.sh new file mode 100644 index 00000000..aeb1826f --- /dev/null +++ b/docker/mysql/create-testing-database.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +mysql --user=root --password="$MYSQL_ROOT_PASSWORD" <<-EOSQL + CREATE DATABASE IF NOT EXISTS testing; + GRANT ALL PRIVILEGES ON \`testing%\`.* TO '$MYSQL_USER'@'%'; +EOSQL diff --git a/docker/pgsql/create-testing-database.sql b/docker/pgsql/create-testing-database.sql new file mode 100644 index 00000000..d84dc07b --- /dev/null +++ b/docker/pgsql/create-testing-database.sql @@ -0,0 +1,2 @@ +SELECT 'CREATE DATABASE testing' +WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'testing')\gexec From ef387b8bd24bfe1d7f6d6748bc58ad7e34092782 Mon Sep 17 00:00:00 2001 From: Allan Kong Date: Wed, 30 Apr 2025 14:18:26 -0600 Subject: [PATCH 3/3] Better test --- tests/Feature/ResourceReviewsTest.php | 45 ++++++++++++++++++--------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/tests/Feature/ResourceReviewsTest.php b/tests/Feature/ResourceReviewsTest.php index fc6c9b82..e43fa700 100644 --- a/tests/Feature/ResourceReviewsTest.php +++ b/tests/Feature/ResourceReviewsTest.php @@ -93,7 +93,7 @@ public function test_resource_review_cannot_be_posted_twice(): void $data2 = ResourceReviewTestResource::fake(); $this->actingAs($user) ->post(route('reviews.store', $resource), $data2); - + $this->assertDatabaseMissing('resource_reviews', [ 'computer_science_resource_id' => $resource->id, 'title' => $data2['title'] @@ -156,8 +156,10 @@ public function test_resource_review_average_updates_correctly(): void public function test_resource_review_can_be_updated(): void { + $times = 10; + $resource = ComputerScienceResource::factory()->create(); - $user = User::factory()->create(); + $users = User::factory($times)->create(); $total = [ 'community' => 0, 'teaching_clarity' => 0, @@ -167,29 +169,42 @@ public function test_resource_review_can_be_updated(): void 'updates' => 0, ]; - $data = ResourceReviewTestResource::fake(); - foreach (array_keys($total) as $key) { - $total[$key] = $data[$key]; - } + foreach ($users as $user) { + $data = ResourceReviewTestResource::fake(); + foreach (array_keys($total) as $key) { + $total[$key] += $data[$key]; + } - $this->actingAs($user)->post(route('reviews.store', $resource), $data); + $this->actingAs($user)->post(route('reviews.store', $resource), $data); + } $this->assertDatabaseHas('resource_review_summaries', array_merge([ 'computer_science_resource_id' => $resource->id, - 'review_count' => 1, + 'review_count' => $times, ], $total)); - // Update to new review - $newData = ResourceReviewTestResource::fake(); - foreach (array_keys($total) as $key) { - $total[$key] = $newData[$key]; - } + $total = [ + 'community' => 0, + 'teaching_clarity' => 0, + 'engagement' => 0, + 'practicality' => 0, + 'user_friendliness' => 0, + 'updates' => 0, + ]; + + foreach ($users as $user) { + // Update to new review + $newData = ResourceReviewTestResource::fake(); + foreach (array_keys($total) as $key) { + $total[$key] += $newData[$key]; + } - $this->actingAs($user)->put(route('reviews.update', $resource), $newData); + $this->actingAs($user)->put(route('reviews.update', $resource), $newData); + } $this->assertDatabaseHas('resource_review_summaries', array_merge([ 'computer_science_resource_id' => $resource->id, - 'review_count' => 1, + 'review_count' => $times, ], $total)); } }