diff --git a/.editorconfig b/.editorconfig index 3f4517ba0..aed3cd2d7 100644 --- a/.editorconfig +++ b/.editorconfig @@ -51,7 +51,8 @@ max_line_length = unset [*.{yml,yaml}] indent_size = 2 -[*.mo] +# Ignore for +[{*.mo,LICENSE}] charset = unset end_of_line = unset indent_style = unset diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bbd4b55f3..4914f5155 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -297,8 +297,8 @@ release-image: --dockerfile /dev/stdin --destination "${RELEASE_IMAGE}" --cache=true - only: - - main + rules: + - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH .deploy_template: &deploy_definition stage: release @@ -344,8 +344,8 @@ pages: expire_in: 1 week paths: - public - only: - - main + rules: + - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH variables: GIT_STRATEGY: none @@ -370,8 +370,8 @@ deploy: environment: name: rsync-staging deployment_tier: development - only: - - main + rules: + - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH script: # Check if deployment variables where set - |- @@ -498,8 +498,8 @@ deploy-production: name: rsync-production deployment_tier: production when: manual - only: - - main + rules: + - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH script: # Check if deployment variables where set - |- @@ -522,14 +522,14 @@ deploy-k8s-production: name: production on_stop: stop-k8s-production when: manual - only: - - main + rules: + - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH stop-k8s-production: <<: *deploy_k8s_stop needs: [ deploy-k8s-production ] - only: - - main + rules: + - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH environment: name: production action: stop diff --git a/config/config.default.php b/config/config.default.php index 4fc737250..e659d6e49 100644 --- a/config/config.default.php +++ b/config/config.default.php @@ -2,12 +2,12 @@ declare(strict_types=1); -// To change settings create a config.php +// To change or overwrite some settings, create a config.php return [ // MySQL-Connection Settings 'database' => [ - 'host' => env('MYSQL_HOST', (env('CI', false) ? 'mariadb' : 'localhost')), + 'host' => env('MYSQL_HOST', 'localhost'), 'database' => env('MYSQL_DATABASE', 'engelsystem'), 'username' => env('MYSQL_USER', 'root'), 'password' => env('MYSQL_PASSWORD', ''), @@ -16,7 +16,7 @@ // For accessing /metrics (and /stats) 'api_key' => env('API_KEY', ''), - // Enable maintenance mode (show a static page) + // Enable maintenance mode (show a static page to all users) 'maintenance' => (bool) env('MAINTENANCE', false), // Application name (not the event name) @@ -30,23 +30,23 @@ // Header links // Available link placeholders: %lang% - // To disable a header_item in the config.php, you can set its value to null + // To disable a header_item in config.php, you can set its value to null 'header_items' => [ - // Name can be a translation string, permission is a engelsystem privilege + // Name can be a translation string, permission is an engelsystem privilege // 'Name' => 'URL', - // 'Name' => ['URL', 'permission'], + // 'some.key' => ['URL', 'permission'], //'Foo' => ['https://foo.bar/batz-%lang%.html', 'logout'], // Permission: for logged-in users ], // Footer links - // To disable a footer item in the config.php, you can set its value to null + // To disable a footer item in config.php, you can set its value to null 'footer_items' => [ // Name can be a translation string, permission is a engelsystem privilege // 'Name' => 'URL', - // 'Name' => ['URL', 'permission'], + // 'some.key' => ['URL', 'permission'], - // URL to the angel faq and job description + // URL to faq page 'faq.faq' => [env('FAQ_URL', '/faq'), 'faq.view'], // Contact email address, linked on every page @@ -60,7 +60,7 @@ 'general.email' => env('CONTACT_EMAIL', 'mailto:ticket@c3heaven.de'), ], - // Text displayed on the FAQ page, rendered as markdown + // Additional text displayed on the FAQ page, rendered as markdown 'faq_text' => env('FAQ_TEXT'), // Link to documentation/help @@ -68,7 +68,7 @@ // Email config 'email' => [ - // Can be mail, smtp, sendmail or log or an symfony mailer dsn string like smtps://[usr]:[pass]@smtp.foo.bar:465 + // Can be mail, smtp, sendmail, log or an symfony mailer dsn string like smtps://[usr]:[pass]@smtp.foo.bar:465 'driver' => env('MAIL_DRIVER', 'mail'), 'from' => [ // From address of all emails @@ -78,7 +78,7 @@ 'host' => env('MAIL_HOST', 'localhost'), 'port' => env('MAIL_PORT', 587), - // If tls transport encryption should be used + // If tls transport encryption should be enabled 'tls' => env('MAIL_TLS'), 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), @@ -88,12 +88,13 @@ // Your privacy@ contact address 'privacy_email' => env('PRIVACY_EMAIL'), - // Show opt in to save some personal data after the event on user profile and registration pages - 'enable_email_goodie' => (bool) env('ENABLE_EMAIL_GOODIE', true), + // Show opt-in on user profile and registration pages to save some personal data after the event + 'enable_email_goodie' => (bool) env('ENABLE_EMAIL_GOODIE', false), - // Initial admin password + // Initial admin password, configured on first migration 'setup_admin_password' => env('SETUP_ADMIN_PASSWORD'), + // Setup external authentication providers 'oauth' => [ // '[name]' => [config] /* @@ -141,18 +142,18 @@ 'groups' => 'groups', // Groups to team (angeltype) mapping (optional) 'teams' => [ - '/Lorem' => 4, // 4 being the ID of the angeltype - '/Foo Mod' => ['id' => 5, 'supporter' => true], // 5 being the ID of the angeltype + '/Lorem' => 4, // 4 being the ID of the team (angeltype) + '/Foo Mod' => ['id' => 5, 'supporter' => true], // 5 being the ID of the team (angeltype) ], ], */ ], - // Default theme, 1=style1.css + // Default theme, 1 = theme1.scss etc. 'theme' => env('THEME', 1), // Supported themes - // To disable a theme in the config.php, you can set its value to null + // To disable a theme in config.php, you can set its value to null 'themes' => [ 17 => [ 'name' => 'Engelsystem 37c3 (2023)', @@ -246,7 +247,7 @@ ], ], - // Redirect to this site after logging in or when pressing the top-left button + // Redirect to this site after logging in or when clicking the page name // Must be one of news, meetings, user_shifts, angeltypes, questions 'home_site' => env('HOME_SITE', 'news'), @@ -256,7 +257,7 @@ // Users are able to sign up 'registration_enabled' => (bool) env('REGISTRATION_ENABLED', true), - // URL to external registration page, used on login page + // URL to external registration page, linked from login page 'external_registration_url' => env('EXTERNAL_REGISTRATION_URL'), // Required user fields @@ -269,13 +270,13 @@ 'dect' => (bool) env('DECT_REQUIRED', false), ], - // Only arrived angels can sign up for shifts + // Only arrived users can sign up for shifts 'signup_requires_arrival' => (bool) env('SIGNUP_REQUIRES_ARRIVAL', false), - // Whether newly-registered user should automatically be marked as arrived - 'autoarrive' => (bool) env('ANGEL_AUTOARRIVE', false), + // Whether newly-registered users should automatically be marked as arrived + 'autoarrive' => (bool) env('AUTOARRIVE', false), - // Supporters of an angeltype can promote other angels of the angeltype to supporter + // Supporters of a team (angeltype) can promote other users of the team (angeltype) to supporter 'supporters_can_promote' => (bool) env('SUPPORTERS_CAN_PROMOTE', false), // Only allow shift signup this number of hours in advance @@ -283,51 +284,51 @@ 'signup_advance_hours' => env('SIGNUP_ADVANCE_HOURS', 0), // Allow signup this many minutes after the start of the shift. - // If signup_post_fraction is set, first applies that before adding the number of minutes specified by this. + // If signup_post_fraction is set, it's first applied before adding the number of minutes specified here. 'signup_post_minutes' => env('SIGNUP_POST_MINUTES', 0), // Allow signup this fraction of the shift length after the start of the shift. - // Example: If this is set to 1, signup is allowed until the end of a shift - // If this is set to 0.5, signup is allowd for the first half of a shift - // If signup_post_minutes is set, first applies this and then adds the signup_post_minutes on top. + // Example: If it is set to 1, signup is allowed until the end of a shift + // If it is set to 0.5, signup is allowed for the first half of a shift + // If signup_post_minutes is set, this is first applied and then the signup_post_minutes added on top. 'signup_post_fraction' => env('SIGNUP_POST_FRACTION', 0), - // Number of hours that an angel has to sign out own shifts + // Number of hours that a user can sign out of own shifts beforehand 'last_unsubscribe' => env('LAST_UNSUBSCRIBE', 3), // Define the algorithm to use for `password_verify()` - // If the user uses an old algorithm the password will be converted to the new format + // If a user password is hashed with an old algorithm, the password will be converted to the new format on login // See https://secure.php.net/manual/en/password.constants.php for a complete list 'password_algorithm' => env('PASSWORD_ALGORITHM', PASSWORD_DEFAULT), // The minimum length for passwords - 'min_password_length' => env('PASSWORD_MINIMUM_LENGTH', 8), + 'password_min_length' => env('PASSWORD_MIN_LENGTH', 8), - // Whether the login and registration via password should be enabled (login will be hidden) + // Whether the login and registration via password should be enabled (login will be hidden if false) // This is useful when using oauth, disabling it also disables normal registration without oauth 'enable_password' => (bool) env('ENABLE_PASSWORD', true), // Whether the DECT field should be enabled 'enable_dect' => (bool) env('ENABLE_DECT', true), - // Whether the mobile number can be shown to other users + // Whether the mobile number will be shown to other users 'enable_mobile_show' => (bool) env('ENABLE_MOBILE_SHOW', false), // Regular expression describing a FALSE username. // Per default usernames must only contain alphanumeric chars, "-", "_" or ".". 'username_regex' => (string) env('USERNAME_REGEX', '/([^\p{L}\p{N}_.-]+)/ui'), - // Enables first name and last name - 'enable_user_name' => (bool) env('ENABLE_USER_NAME', false), + // Enable first name and last name + 'enable_full_name' => (bool) env('ENABLE_FULL_NAME', false), // Show a users first name and last name instead of username 'display_full_name' => env('DISPLAY_FULL_NAME', false) - && env('ENABLE_USER_NAME', false), + && env('ENABLE_FULL_NAME', false), // Enable displaying the pronoun fields 'enable_pronoun' => (bool) env('ENABLE_PRONOUN', true), - // Enables the planned arrival/leave date + // Enable the planned arrival/leave date 'enable_planned_arrival' => (bool) env('ENABLE_PLANNED_ARRIVAL', true), // Whether force active should be enabled @@ -339,10 +340,10 @@ // 'tshirt' => goodie that is called tshirt and has sizing options 'goodie_type' => env('GOODIE_TYPE', 'goodie'), - // Enables the food voucher in the user profile + // Enable (food) vouchers 'enable_voucher' => (bool) env('ENABLE_VOUCHER', true), - // Number of shifts to freeload until angel is locked for shift signup. + // Number of shifts to freeload until a user is locked from shift signup. 'max_freeloadable_shifts' => env('MAX_FREELOADABLE_SHIFTS', 2), // Hide columns in backend user view. Possible values are any sortable parameters of the table. @@ -369,7 +370,7 @@ 'voucher_start' => env('VOUCHER_START') ?: null, ], - // Enables Driving License + // Enable Driving License 'driving_license_enabled' => (bool) env('DRIVING_LICENSE_ENABLED', true), # Instruction in accordance with ยง 43 Para. 1 of the German Infection Protection Act (IfSG) @@ -379,7 +380,7 @@ 'ifsg_light_enabled' => env('IFSG_LIGHT_ENABLED', false) && env('IFSG_ENABLED', false), // Available locales in /resources/lang/ - // To disable a locale in the config.php, you can set its value to null + // To disable a locale in config.php, you can set its value to null 'locales' => [ 'de_DE' => 'Deutsch', 'en_US' => 'English', @@ -389,7 +390,7 @@ 'default_locale' => env('DEFAULT_LOCALE', 'en_US'), // Available T-Shirt sizes - // To disable a t-shirt size in the config.php, you can set its value to null + // To disable a t-shirt size in config.php, you can set its value to null 'tshirt_sizes' => [ 'S' => 'Small Straight-Cut', 'S-F' => 'Small Fitted-Cut', @@ -442,7 +443,7 @@ // Add additional headers 'add_headers' => (bool) env('ADD_HEADERS', true), // Predefined headers - // To disable a header in the config.php, you can set its value to null + // To disable a header in config.php, you can set its value to null 'headers' => [ 'X-Content-Type-Options' => 'nosniff', 'X-Frame-Options' => 'sameorigin', diff --git a/config/routes.php b/config/routes.php index 3639c660a..97597797e 100644 --- a/config/routes.php +++ b/config/routes.php @@ -146,6 +146,9 @@ function (RouteCollector $route): void { $route->get('/news', 'Api\NewsController@index'); + $route->get('/shifttypes', 'Api\ShiftTypeController@index'); + $route->get('/shifttypes/{shifttype_id:\d+}/shifts', 'Api\ShiftsController@entriesByShiftType'); + $route->get('/users/{user_id:(?:\d+|self)}', 'Api\UsersController@user'); $route->get('/users/{user_id:(?:\d+|self)}/angeltypes', 'Api\AngelTypeController@ofUser'); $route->get('/users/{user_id:(?:\d+|self)}/shifts', 'Api\ShiftsController@entriesByUser'); diff --git a/includes/pages/admin_user.php b/includes/pages/admin_user.php index dd359252b..cf757a9fe 100644 --- a/includes/pages/admin_user.php +++ b/includes/pages/admin_user.php @@ -68,7 +68,7 @@ function admin_user() $html .= ' ' . __('Last login') . '

' . ($user_source->last_login_at ? $user_source->last_login_at->format(__('general.datetime')) : '-') . '

' . "\n"; - if (config('enable_user_name')) { + if (config('enable_full_name')) { $html .= ' ' . __('settings.profile.firstname') . '' . '' . '' . "\n"; @@ -173,7 +173,7 @@ function admin_user() $html .= '' . "\n"; $html .= ' ' . "\n"; @@ -313,7 +313,7 @@ function admin_user() } $user_source->save(); - if (config('enable_user_name')) { + if (config('enable_full_name')) { $user_source->personalData->first_name = $request->postData('eVorname'); $user_source->personalData->last_name = $request->postData('eName'); } diff --git a/includes/sys_form.php b/includes/sys_form.php index 8db8c856d..eb8c9898a 100644 --- a/includes/sys_form.php +++ b/includes/sys_form.php @@ -222,7 +222,7 @@ function form_password($name, $label, $autocomplete, $disabled = false) sprintf( '', $name, - config('min_password_length'), + config('password_min_length'), $autocomplete, $disabled ), diff --git a/includes/view/User_view.php b/includes/view/User_view.php index b768250ce..c44bf4277 100644 --- a/includes/view/User_view.php +++ b/includes/view/User_view.php @@ -145,7 +145,7 @@ function Users_view( if (!config('display_full_name')) { $user_table_headers['name'] = Users_table_header_link('name', __('general.nick'), $order_by); } - if (config('enable_user_name')) { + if (config('enable_full_name')) { $user_table_headers['first_name'] = Users_table_header_link('first_name', __('settings.profile.firstname'), $order_by); $user_table_headers['last_name'] = Users_table_header_link('last_name', __('settings.profile.lastname'), $order_by); } @@ -639,7 +639,7 @@ function User_view( return page_with_title( ' ' . htmlspecialchars($user_source->name) - . (config('enable_user_name') ? ' ' . $user_name . '' : '') + . (config('enable_full_name') ? ' ' . $user_name . '' : '') . ((config('enable_pronoun') && $user_source->personalData->pronoun) ? ' (' . htmlspecialchars($user_source->personalData->pronoun) . ') ' : '') @@ -1113,7 +1113,7 @@ function render_user_pronoun_hint() function render_user_firstname_hint() { $user = auth()->user(); - if (config('required_user_fields')['firstname'] && config('enable_user_name') && !$user->personalData->first_name) { + if (config('required_user_fields')['firstname'] && config('enable_full_name') && !$user->personalData->first_name) { $text = __('firstname.required.hint'); return render_profile_link($text); } @@ -1127,7 +1127,7 @@ function render_user_firstname_hint() function render_user_lastname_hint() { $user = auth()->user(); - if (config('required_user_fields')['lastname'] && config('enable_user_name') && !$user->personalData->last_name) { + if (config('required_user_fields')['lastname'] && config('enable_full_name') && !$user->personalData->last_name) { $text = __('lastname.required.hint'); return render_profile_link($text); } diff --git a/resources/api/openapi.yml b/resources/api/openapi.yml index 5669114e1..57ff80703 100644 --- a/resources/api/openapi.yml +++ b/resources/api/openapi.yml @@ -1,7 +1,7 @@ openapi: 3.0.3 info: - version: 0.0.1-beta + version: 0.1.0-beta title: Engelsystem description: > This API is as stable as a **beta** version might be. @@ -17,14 +17,17 @@ info: servers: - url: /api/v0-beta description: This server - - url: http://localhost:5080/api/v0-beta - description: Your local dev instance + - url: '{host}/api/v0-beta' + description: Engelsystem instance to use + variables: + host: + default: http://localhost:5080 tags: - name: api description: API related - - name: angeltype - description: Angeltypes + - name: angel type + description: Angel types - name: event description: Event information - name: location @@ -33,8 +36,10 @@ tags: description: News and meeting announcements - name: shift description: Event shifts + - name: shift type + description: Shift types - name: user - description: User information + description: Users security: - bearer-auth: [ ] @@ -89,11 +94,15 @@ components: example: Angel description: type: string - example: Meta-Group of all registered Angels + example: Standard angel type, without further requirements + restricted: + type: boolean + example: false + description: True if the angel type requires an introduction url: type: string example: https://example.com/angeltype/42 - description: Link to the page of the given angeltype. + description: Link to the page of the given angel type. required: - id - name @@ -109,11 +118,11 @@ components: example: true description: > If the user is confirmed - (either by the angeltype not requiring confirmation, being a supporter or being confirmed by one). + (either by the angel type not requiring confirmation, being a supporter or being confirmed by one). supporter: type: boolean example: false - description: If the user is a supporter of the angeltype. + description: If the user is a supporter of the angel type. required: - confirmed - supporter @@ -123,9 +132,10 @@ components: id: type: integer example: 42 - title: + name: type: string example: First helper introduction + description: Title of the news text: type: string example: | @@ -156,7 +166,7 @@ components: description: Direct link to the news page required: - id - - title + - name - text - is_meeting - is_pinned @@ -173,6 +183,10 @@ components: name: type: string example: Heaven + description: + type: string + example: Located behind room 42 + description: Description of the room url: type: string example: https://example.com/location/42 @@ -180,16 +194,38 @@ components: required: - id - name + - description - url + NeededAngelType: + type: object + properties: + entries: + type: array + items: + $ref: '#/components/schemas/ShiftEntry' + angel_type: + $ref: '#/components/schemas/Reference' + needs: + type: integer + description: > + Number of users needed for the shift of the given angel type. + Will be greater than users count when not full, less when overbooked + or 0 when only additional users with given type have been added. + example: 3 + required: + - entries + - angel_type + - needs Shift: type: object properties: id: type: integer example: 42 - title: + name: type: string example: Cleanup the venue + description: Title of the shift description: type: string example: You clean up the venue after the event. Its fun, we promise! @@ -201,25 +237,25 @@ components: ends_at: $ref: '#/components/schemas/DateTime' location: - $ref: '#/components/schemas/Location' + $ref: '#/components/schemas/Reference' shift_type: - $ref: '#/components/schemas/ShiftType' + $ref: '#/components/schemas/Reference' created_at: $ref: '#/components/schemas/DateTimeOptional' updated_at: $ref: '#/components/schemas/DateTimeOptional' - entries: + needed_angel_types: type: array - description: Can be empty (for example on Schedule import of unused room) + description: Needed angel types and user entries, can be empty (for example on Schedule import of unused room) items: - $ref: '#/components/schemas/ShiftEntry' + $ref: '#/components/schemas/NeededAngelType' url: type: string example: https://example.com/shifts/42 description: Direct link to the shift required: - id - - title + - name - description - starts_at - ends_at @@ -227,28 +263,20 @@ components: - shift_type - created_at - updated_at - - entries + - needed_angel_types - url ShiftEntry: type: object properties: - users: - type: array - items: - $ref: '#/components/schemas/User' - type: - $ref: '#/components/schemas/AngelType' - needs: - type: integer - description: > - Number of users needed for the shift of the given type. - Will be more than users count when not full, less when overbooked - or 0 when only additional users with given type have been added. - example: 3 + user: + $ref: '#/components/schemas/Reference' + freeloaded: + type: boolean + example: false + description: True if the user was marked as freeloaded for not arriving to the shift required: - - users - - type - - needs + - user + - freeloaded ShiftType: type: object properties: @@ -319,7 +347,7 @@ components: email: type: string example: user@example.com - tshirt: + tshirt_size: type: string nullable: true example: XL @@ -348,7 +376,7 @@ components: example: true required: - email - - tshirt + - tshirt_size - dates - language - arrived @@ -428,13 +456,28 @@ components: - buildup - event - teardown + Reference: + type: object + description: Reference to other resources + properties: + id: + type: integer + example: 42 + description: The ID of the related resource + name: + type: string + nullable: true + example: Foo + description: A name of the related resource, should only be used for reference + required: + - id paths: /angeltypes: get: tags: - - angeltype - summary: Get a list of angeltypes + - angel type + summary: Get a list of angel types responses: '200': description: Ok @@ -457,15 +500,15 @@ paths: - name: id in: path required: true - description: The angeltype identifier + description: The angel type identifier example: 42 schema: type: integer get: tags: - - angeltype + - angel type - shift - summary: Get all shifts of the requested angeltype + summary: Get all shifts of the requested angel type responses: '200': description: Ok @@ -556,6 +599,61 @@ paths: '404': $ref: '#/components/responses/NotFoundError' + /shifttypes: + get: + tags: + - shift type + summary: Get a list of shift types + responses: + '200': + description: Ok + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/ShiftType' + '401': + $ref: '#/components/responses/UnauthorizedError' + '403': + $ref: '#/components/responses/ForbiddenError' + + /shifttypes/{id}/shifts: + parameters: + - name: id + in: path + required: true + description: The shift types identifier + example: 42 + schema: + type: integer + get: + tags: + - shift type + - shift + summary: Get all shifts of the requested shift type + responses: + '200': + description: Ok + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Shift' + '401': + $ref: '#/components/responses/UnauthorizedError' + '403': + $ref: '#/components/responses/ForbiddenError' + '404': + $ref: '#/components/responses/NotFoundError' + /users/{id}: parameters: - name: id @@ -603,7 +701,7 @@ paths: - type: integer get: tags: - - angeltype + - angel type - user summary: Get the users angel types responses: diff --git a/resources/lang/de_DE/additional.po b/resources/lang/de_DE/additional.po index d8266521b..dcdcc4fc8 100644 --- a/resources/lang/de_DE/additional.po +++ b/resources/lang/de_DE/additional.po @@ -293,6 +293,9 @@ msgstr "Der Name wird bereits verwendet." msgid "registration.disabled" msgstr "Die Registrierung ist deaktiviert." +msgid "registration.successful.supporter" +msgstr "Registrierung erfolgreich." + msgid "registration.successful" msgstr "Registrierung erfolgreich. Du kannst dich jetzt anmelden!" diff --git a/resources/lang/en_US/additional.po b/resources/lang/en_US/additional.po index 66dcc2846..4fe14cc0a 100644 --- a/resources/lang/en_US/additional.po +++ b/resources/lang/en_US/additional.po @@ -292,6 +292,9 @@ msgstr "The name is already used." msgid "registration.disabled" msgstr "The registration is disabled." +msgid "registration.successful.supporter" +msgstr "Registration successful." + msgid "registration.successful" msgstr "Registration successful. You can now log in!" diff --git a/resources/views/pages/faq/overview.twig b/resources/views/pages/faq/index.twig similarity index 100% rename from resources/views/pages/faq/overview.twig rename to resources/views/pages/faq/index.twig diff --git a/resources/views/pages/messages/overview.twig b/resources/views/pages/messages/index.twig similarity index 100% rename from resources/views/pages/messages/overview.twig rename to resources/views/pages/messages/index.twig diff --git a/resources/views/pages/news/overview.twig b/resources/views/pages/news/index.twig similarity index 100% rename from resources/views/pages/news/overview.twig rename to resources/views/pages/news/index.twig diff --git a/resources/views/pages/news/news.twig b/resources/views/pages/news/news.twig index 0215b578f..529d44f2e 100644 --- a/resources/views/pages/news/news.twig +++ b/resources/views/pages/news/news.twig @@ -1,4 +1,4 @@ -{% extends 'pages/news/overview.twig' %} +{% extends 'pages/news/index.twig' %} {% import 'macros/base.twig' as m %} {% import 'macros/form.twig' as f %} diff --git a/resources/views/pages/password/reset-form.twig b/resources/views/pages/password/reset-form.twig index 85d4ee0c6..794980b17 100644 --- a/resources/views/pages/password/reset-form.twig +++ b/resources/views/pages/password/reset-form.twig @@ -11,7 +11,7 @@ 'type': 'password', 'min_length': min_length, 'required': true, - 'info': __('password.minimal_length', [config('min_password_length')]), + 'info': __('password.minimal_length', [config('password_min_length')]), }) }} {{ f.input('password_confirmation', __('password.reset.confirm'), { 'type': 'password', diff --git a/resources/views/pages/questions/overview.twig b/resources/views/pages/questions/index.twig similarity index 100% rename from resources/views/pages/questions/overview.twig rename to resources/views/pages/questions/index.twig diff --git a/resources/views/pages/settings/profile.twig b/resources/views/pages/settings/profile.twig index ced28751a..b666f13fd 100644 --- a/resources/views/pages/settings/profile.twig +++ b/resources/views/pages/settings/profile.twig @@ -36,7 +36,7 @@ {% endif %} - {% if config('enable_user_name') %} + {% if config('enable_full_name') %}
{{ f.input('first_name', __('settings.profile.firstname'), { diff --git a/src/Controllers/Admin/QuestionsController.php b/src/Controllers/Admin/QuestionsController.php index cf6d7be90..890c98724 100644 --- a/src/Controllers/Admin/QuestionsController.php +++ b/src/Controllers/Admin/QuestionsController.php @@ -42,7 +42,7 @@ public function index(): Response ->load(['user.state', 'answerer.state']); return $this->response->withView( - 'pages/questions/overview.twig', + 'pages/questions/index.twig', ['questions' => $questions, 'is_admin' => true] ); } diff --git a/src/Controllers/Api/Resources/AngelTypeResource.php b/src/Controllers/Api/Resources/AngelTypeResource.php index 2b37f9f35..bcfd81f90 100644 --- a/src/Controllers/Api/Resources/AngelTypeResource.php +++ b/src/Controllers/Api/Resources/AngelTypeResource.php @@ -4,14 +4,21 @@ namespace Engelsystem\Controllers\Api\Resources; +use Engelsystem\Models\AngelType; +use Engelsystem\Models\BaseModel; +use Illuminate\Support\Collection; + class AngelTypeResource extends BasicResource { + protected Collection | BaseModel | AngelType $model; + public function toArray(): array { return [ 'id' => $this->model->id, 'name' => $this->model->name, 'description' => $this->model->description, + 'restricted' => $this->model->restricted, 'url' => url('/angeltypes', ['action' => 'view', 'angeltype_id' => $this->model->id]), ]; } diff --git a/src/Controllers/Api/Resources/BasicResource.php b/src/Controllers/Api/Resources/BasicResource.php index b801a86c6..de0a43d80 100644 --- a/src/Controllers/Api/Resources/BasicResource.php +++ b/src/Controllers/Api/Resources/BasicResource.php @@ -13,7 +13,7 @@ /** @phpstan-consistent-constructor */ abstract class BasicResource implements Arrayable, Jsonable, Stringable { - public function __construct(protected BaseModel|Collection $model) + public function __construct(protected BaseModel | Collection $model) { } @@ -34,6 +34,16 @@ public function toArray(): array return $this->model->toArray(); } + public static function toIdentifierArray(array | Arrayable $data): array + { + $data = $data instanceof Arrayable ? $data->toArray() : $data; + $identifier = ['id' => $data['id']]; + if (array_key_exists('name', $data)) { + $identifier['name'] = $data['name']; + } + return $identifier; + } + /** * @param int $options */ diff --git a/src/Controllers/Api/Resources/LocationResource.php b/src/Controllers/Api/Resources/LocationResource.php index e05bcc249..cf1028c85 100644 --- a/src/Controllers/Api/Resources/LocationResource.php +++ b/src/Controllers/Api/Resources/LocationResource.php @@ -4,13 +4,20 @@ namespace Engelsystem\Controllers\Api\Resources; +use Engelsystem\Models\BaseModel; +use Engelsystem\Models\Location; +use Illuminate\Support\Collection; + class LocationResource extends BasicResource { + protected Collection | BaseModel | Location $model; + public function toArray(): array { return [ 'id' => $this->model->id, 'name' => $this->model->name, + 'description' => $this->model->description ?: '', 'url' => url('/locations', ['action' => 'view', 'location_id' => $this->model->id]), ]; } diff --git a/src/Controllers/Api/Resources/NewsResource.php b/src/Controllers/Api/Resources/NewsResource.php index ef2a6d24c..63a31f170 100644 --- a/src/Controllers/Api/Resources/NewsResource.php +++ b/src/Controllers/Api/Resources/NewsResource.php @@ -4,13 +4,19 @@ namespace Engelsystem\Controllers\Api\Resources; +use Engelsystem\Models\BaseModel; +use Engelsystem\Models\News; +use Illuminate\Support\Collection; + class NewsResource extends BasicResource { + protected Collection | BaseModel | News $model; + public function toArray(): array { return [ 'id' => $this->model->id, - 'title' => $this->model->title, + 'name' => $this->model->title, 'text' => $this->model->text, 'is_meeting' => $this->model->is_meeting, 'is_pinned' => $this->model->is_pinned, diff --git a/src/Controllers/Api/Resources/ShiftResource.php b/src/Controllers/Api/Resources/ShiftResource.php index 2087d4153..4d8aafb97 100644 --- a/src/Controllers/Api/Resources/ShiftResource.php +++ b/src/Controllers/Api/Resources/ShiftResource.php @@ -4,20 +4,25 @@ namespace Engelsystem\Controllers\Api\Resources; +use Engelsystem\Models\BaseModel; +use Engelsystem\Models\Shifts\Shift; use Illuminate\Contracts\Support\Arrayable; +use Illuminate\Support\Collection; class ShiftResource extends BasicResource { - public function toArray(array|Arrayable $location = []): array + protected Collection | BaseModel | Shift $model; + + public function toArray(array | Arrayable $location = []): array { return [ 'id' => $this->model->id, - 'title' => $this->model->title, + 'name' => $this->model->title, 'description' => $this->model->description, 'starts_at' => $this->model->start, 'ends_at' => $this->model->end, - 'location' => $location instanceof Arrayable ? $location->toArray() : $location, - 'shift_type' => (new ShiftTypeResource($this->model->shiftType))->toArray(), + 'location' => LocationResource::toIdentifierArray($location), + 'shift_type' => ShiftTypeResource::toIdentifierArray($this->model->shiftType), 'created_at' => $this->model->created_at, 'updated_at' => $this->model->updated_at, 'url' => url('/shifts', ['action' => 'view', 'shift_id' => $this->model->id]), diff --git a/src/Controllers/Api/Resources/ShiftTypeResource.php b/src/Controllers/Api/Resources/ShiftTypeResource.php index b336a0567..cd1b26ed0 100644 --- a/src/Controllers/Api/Resources/ShiftTypeResource.php +++ b/src/Controllers/Api/Resources/ShiftTypeResource.php @@ -4,8 +4,14 @@ namespace Engelsystem\Controllers\Api\Resources; +use Engelsystem\Models\BaseModel; +use Engelsystem\Models\Shifts\ShiftType; +use Illuminate\Support\Collection; + class ShiftTypeResource extends BasicResource { + protected Collection | BaseModel | ShiftType $model; + public function toArray(): array { return [ diff --git a/src/Controllers/Api/Resources/ShiftWithEntriesResource.php b/src/Controllers/Api/Resources/ShiftWithEntriesResource.php index 1bd78c712..a4c77bcd6 100644 --- a/src/Controllers/Api/Resources/ShiftWithEntriesResource.php +++ b/src/Controllers/Api/Resources/ShiftWithEntriesResource.php @@ -8,11 +8,11 @@ class ShiftWithEntriesResource extends ShiftResource { - public function toArray(array|Arrayable $location = [], array|Arrayable $entries = []): array + public function toArray(array | Arrayable $location = [], array | Arrayable $angelTypes = []): array { return [ ...parent::toArray($location), - 'entries' => $entries instanceof Arrayable ? $entries->toArray() : $entries, + 'needed_angel_types' => $angelTypes instanceof Arrayable ? $angelTypes->toArray() : $angelTypes, ]; } } diff --git a/src/Controllers/Api/Resources/UserDetailResource.php b/src/Controllers/Api/Resources/UserDetailResource.php index 010c2e293..dc04e705d 100644 --- a/src/Controllers/Api/Resources/UserDetailResource.php +++ b/src/Controllers/Api/Resources/UserDetailResource.php @@ -10,7 +10,7 @@ public function toArray(): array { return array_merge(parent::toArray(), [ 'email' => $this->model->contact->email ?: $this->model->email, - 'tshirt' => $this->model->personalData->shirt_size, + 'tshirt_size' => $this->model->personalData->shirt_size, 'language' => $this->model->settings->language, 'arrived' => $this->model->state->arrived, 'dates' => [ diff --git a/src/Controllers/Api/Resources/UserResource.php b/src/Controllers/Api/Resources/UserResource.php index 8a89406ca..2793cc8c9 100644 --- a/src/Controllers/Api/Resources/UserResource.php +++ b/src/Controllers/Api/Resources/UserResource.php @@ -4,8 +4,14 @@ namespace Engelsystem\Controllers\Api\Resources; +use Engelsystem\Models\BaseModel; +use Engelsystem\Models\User\User; +use Illuminate\Support\Collection; + class UserResource extends BasicResource { + protected Collection | BaseModel | User $model; + public function toArray(): array { return [ diff --git a/src/Controllers/Api/ShiftTypeController.php b/src/Controllers/Api/ShiftTypeController.php new file mode 100644 index 000000000..d39aa82c0 --- /dev/null +++ b/src/Controllers/Api/ShiftTypeController.php @@ -0,0 +1,25 @@ +orderBy('name') + ->get(); + + $data = ['data' => ShiftTypeResource::collection($models)]; + return $this->response + ->withContent(json_encode($data)); + } +} diff --git a/src/Controllers/Api/ShiftsController.php b/src/Controllers/Api/ShiftsController.php index 5493c8210..71679ecdc 100644 --- a/src/Controllers/Api/ShiftsController.php +++ b/src/Controllers/Api/ShiftsController.php @@ -15,6 +15,7 @@ use Engelsystem\Models\Shifts\NeededAngelType; use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\ShiftEntry; +use Engelsystem\Models\Shifts\ShiftType; use Illuminate\Database\Eloquent\Collection; class ShiftsController extends ApiController @@ -71,6 +72,28 @@ public function entriesByLocation(Request $request): Response return $this->shiftEntriesResponse($shifts); } + public function entriesByShiftType(Request $request): Response + { + $shiftTypeId = (int) $request->getAttribute('shifttype_id'); + /** @var ShiftType $shiftType */ + $shiftType = ShiftType::findOrFail($shiftTypeId); + /** @var Shift[]|Collection $shifts */ + $shifts = $shiftType->shifts() + ->with([ + 'neededAngelTypes.angelType', + 'location.neededAngelTypes.angelType', + 'shiftEntries.angelType', + 'shiftEntries.user.contact', + 'shiftEntries.user.personalData', + 'shiftType', + 'schedule.shiftType.neededAngelTypes.angelType', + ]) + ->orderBy('start') + ->get(); + + return $this->shiftEntriesResponse($shifts); + } + public function entriesByUser(Request $request): Response { $id = $request->getAttribute('user_id'); @@ -106,27 +129,32 @@ protected function shiftEntriesResponse(Collection $shifts): Response // Blob of not-optimized mediocre pseudo-serialization foreach ($shifts as $shift) { // Get all needed/used angel types + /** @var Collection|NeededAngelType[] $neededAngelTypes */ $neededAngelTypes = $this->getNeededAngelTypes($shift); - $entries = new Collection(); + $angelTypes = new Collection(); foreach ($neededAngelTypes as $neededAngelType) { - $users = UserResource::collection($neededAngelType->users ?? []); + $entries = $neededAngelType->entries ?: new Collection(); // Skip empty entries - if ($neededAngelType->count <= 0 && $users->isEmpty()) { + if ($neededAngelType->count <= 0 && $entries->isEmpty()) { continue; } - $angelTypeData = new AngelTypeResource($neededAngelType->angelType); - $entries[] = new Collection([ - 'users' => $users, - 'type' => $angelTypeData, + $entries = $entries->map(fn(ShiftEntry $entry) => [ + 'user' => UserResource::toIdentifierArray($entry->user), + 'freeloaded' => $entry->freeloaded, + ]); + $angelTypeData = AngelTypeResource::toIdentifierArray($neededAngelType->angelType); + $angelTypes[] = new Collection([ + 'angel_type' => $angelTypeData, 'needs' => $neededAngelType->count, + 'entries' => $entries, ]); } $locationData = new LocationResource($shift->location); - $shiftEntries[] = (new ShiftWithEntriesResource($shift))->toArray($locationData, $entries); + $shiftEntries[] = (new ShiftWithEntriesResource($shift))->toArray($locationData, $angelTypes); } $data = ['data' => $shiftEntries]; @@ -135,7 +163,7 @@ protected function shiftEntriesResponse(Collection $shifts): Response } /** - * Collect all needed angeltypes + * Collect all needed angel types */ protected function getNeededAngelTypes(Shift $shift): Collection { @@ -151,7 +179,7 @@ protected function getNeededAngelTypes(Shift $shift): Collection $neededAngelTypes = $shift->location->neededAngelTypes; } - // Add needed angeltypes from additionally added users + // Add needed angel types from additionally added users foreach ($shift->shiftEntries as $entry) { $neededAngelType = $neededAngelTypes->where('angel_type_id', $entry->angelType->id)->first(); if (!$neededAngelType) { @@ -163,11 +191,11 @@ protected function getNeededAngelTypes(Shift $shift): Collection $neededAngelTypes[] = $neededAngelType; } - // Add users to entries - $neededAngelType->users = isset($neededAngelType->users) - ? $neededAngelType->users + // Add entries to needed angel type + $neededAngelType->entries = isset($neededAngelType->entries) + ? $neededAngelType->entries : new Collection(); - $neededAngelType->users[] = $entry->user; + $neededAngelType->entries[] = $entry; } return $neededAngelTypes; diff --git a/src/Controllers/FaqController.php b/src/Controllers/FaqController.php index 1278a891b..990a5d2a1 100644 --- a/src/Controllers/FaqController.php +++ b/src/Controllers/FaqController.php @@ -31,7 +31,7 @@ public function index(): Response $faq = $this->faq->orderBy('question')->get(); return $this->response->withView( - 'pages/faq/overview.twig', + 'pages/faq/index.twig', ['text' => $text, 'items' => $faq] ); } diff --git a/src/Controllers/MessagesController.php b/src/Controllers/MessagesController.php index c562b6b5c..72eb5b203 100644 --- a/src/Controllers/MessagesController.php +++ b/src/Controllers/MessagesController.php @@ -75,7 +75,7 @@ public function listConversations(): Response $users->prepend($currentUser->displayName, $currentUser->id); return $this->response->withView( - 'pages/messages/overview.twig', + 'pages/messages/index.twig', [ 'conversations' => $conversations, 'users' => $users, diff --git a/src/Controllers/NewsController.php b/src/Controllers/NewsController.php index feb8c6fef..0c2d51ded 100644 --- a/src/Controllers/NewsController.php +++ b/src/Controllers/NewsController.php @@ -144,7 +144,7 @@ protected function showOverview(bool $onlyMeetings = false): Response ->get(); return $this->renderView( - 'pages/news/overview.twig', + 'pages/news/index.twig', [ 'news' => $news, 'pages' => $pagesCount, diff --git a/src/Controllers/PasswordResetController.php b/src/Controllers/PasswordResetController.php index 70a53d00a..ec601acce 100644 --- a/src/Controllers/PasswordResetController.php +++ b/src/Controllers/PasswordResetController.php @@ -74,7 +74,7 @@ public function resetPassword(Request $request): Response return $this->showView( 'pages/password/reset-form', - ['min_length' => config('min_password_length')] + ['min_length' => config('password_min_length')] ); } @@ -83,7 +83,7 @@ public function postResetPassword(Request $request): Response $reset = $this->requireToken($request); $data = $this->validate($request, [ - 'password' => 'required|min:' . config('min_password_length'), + 'password' => 'required|min:' . config('password_min_length'), 'password_confirmation' => 'required', ]); diff --git a/src/Controllers/QuestionsController.php b/src/Controllers/QuestionsController.php index f336686d6..644bbdb58 100644 --- a/src/Controllers/QuestionsController.php +++ b/src/Controllers/QuestionsController.php @@ -40,7 +40,7 @@ public function index(): Response ->load(['user.state', 'answerer.state']); return $this->response->withView( - 'pages/questions/overview.twig', + 'pages/questions/index.twig', ['questions' => $questions] ); } diff --git a/src/Controllers/RegistrationController.php b/src/Controllers/RegistrationController.php index a5b22677e..31b2d81d4 100644 --- a/src/Controllers/RegistrationController.php +++ b/src/Controllers/RegistrationController.php @@ -48,7 +48,11 @@ public function save(Request $request): Response $rawData = $request->getParsedBody(); $user = $this->userFactory->createFromData($rawData); - $this->addNotification('registration.successful'); + if (!$this->auth->user()) { + $this->addNotification('registration.successful'); + } else { + $this->addNotification('registration.successful.supporter'); + } if ($this->config->get('welcome_msg')) { // Set a session marker to display the welcome message on the next page @@ -89,7 +93,7 @@ private function renderSignUpPage(): Response return $this->response->withView( 'pages/registration', [ - 'minPasswordLength' => $this->config->get('min_password_length'), + 'minPasswordLength' => $this->config->get('password_min_length'), 'tShirtSizes' => $this->config->get('tshirt_sizes'), 'tShirtLink' => $this->config->get('tshirt_link'), 'angelTypes' => AngelType::whereHideRegister(false)->get(), @@ -102,7 +106,7 @@ private function renderSignUpPage(): Response 'isGoodieEnabled' => $goodieType !== GoodieType::None && config('enable_email_goodie'), 'isGoodieTShirt' => $goodieType === GoodieType::Tshirt, 'isPronounEnabled' => $this->config->get('enable_pronoun'), - 'isFullNameEnabled' => $this->config->get('enable_user_name'), + 'isFullNameEnabled' => $this->config->get('enable_full_name'), 'isPlannedArrivalDateEnabled' => $this->config->get('enable_planned_arrival'), 'isPronounRequired' => $requiredFields['pronoun'], 'isFirstnameRequired' => $requiredFields['firstname'], diff --git a/src/Controllers/SettingsController.php b/src/Controllers/SettingsController.php index bb11ec199..4e7ef5a99 100644 --- a/src/Controllers/SettingsController.php +++ b/src/Controllers/SettingsController.php @@ -72,7 +72,7 @@ public function saveProfile(Request $request): Response $user->personalData->pronoun = $data['pronoun']; } - if (config('enable_user_name')) { + if (config('enable_full_name')) { $user->personalData->first_name = $data['first_name']; $user->personalData->last_name = $data['last_name']; } @@ -134,7 +134,7 @@ public function password(): Response 'pages/settings/password', [ 'settings_menu' => $this->settingsMenu(), - 'min_length' => config('min_password_length'), + 'min_length' => config('password_min_length'), ] ); } @@ -143,7 +143,7 @@ public function savePassword(Request $request): Response { $user = $this->auth->user(); - $minLength = config('min_password_length'); + $minLength = config('password_min_length'); $data = $this->validate($request, [ 'password' => 'required' . (empty($user->password) ? '|optional' : ''), 'new_password' => 'required|min:' . $minLength, diff --git a/src/Factories/User.php b/src/Factories/User.php index c1ea11c7b..f8e3daf78 100644 --- a/src/Factories/User.php +++ b/src/Factories/User.php @@ -94,12 +94,12 @@ private function validateUser(array $rawData): array $isPasswordEnabled = $this->determineIsPasswordEnabled(); if ($isPasswordEnabled) { - $minPasswordLength = $this->config->get('min_password_length'); + $minPasswordLength = $this->config->get('password_min_length'); $validationRules['password'] = 'required|length:' . $minPasswordLength; $validationRules['password_confirmation'] = 'required'; } - $isFullNameEnabled = $this->config->get('enable_user_name'); + $isFullNameEnabled = $this->config->get('enable_full_name'); if ($isFullNameEnabled) { $validationRules['firstname'] = $this->isRequired('firstname') . '|length:0:64'; diff --git a/src/Models/AngelType.php b/src/Models/AngelType.php index 1db06014a..a6dd0d137 100644 --- a/src/Models/AngelType.php +++ b/src/Models/AngelType.php @@ -53,12 +53,17 @@ class AngelType extends BaseModel /** @var array Default attributes */ protected $attributes = [ // phpcs:ignore + 'description' => '', + 'contact_name' => '', + 'contact_dect' => '', + 'contact_email' => '', 'restricted' => false, 'requires_driver_license' => false, 'requires_ifsg_certificate' => false, - 'shift_self_signup' => true, - 'show_on_dashboard' => false, + 'shift_self_signup' => false, + 'show_on_dashboard' => true, 'hide_register' => false, + 'hide_on_shift_view' => false, ]; /** diff --git a/src/Models/EventConfig.php b/src/Models/EventConfig.php index 3ec39a56a..b5d349f4c 100644 --- a/src/Models/EventConfig.php +++ b/src/Models/EventConfig.php @@ -11,8 +11,8 @@ /** * @property string $name * @property string $value - * @property Carbon $created_at - * @property Carbon $updated_at + * @property Carbon|null $created_at + * @property Carbon|null $updated_at * * @method static QueryBuilder|EventConfig[] whereName($value) * @method static QueryBuilder|EventConfig[] whereValue($value) diff --git a/src/Models/Location.php b/src/Models/Location.php index e155f87d5..c9fe03093 100644 --- a/src/Models/Location.php +++ b/src/Models/Location.php @@ -17,9 +17,9 @@ /** * @property int $id * @property string $name - * @property string $map_url - * @property string $description - * @property string $dect + * @property string|null $map_url + * @property string|null $description + * @property string|null $dect * @property Carbon|null $created_at * @property Carbon|null $updated_at * diff --git a/src/Models/LogEntry.php b/src/Models/LogEntry.php index ae2df0364..5cbb06b5a 100644 --- a/src/Models/LogEntry.php +++ b/src/Models/LogEntry.php @@ -14,10 +14,13 @@ /** * @property int $id + * @property int|null $user_id * @property string $level * @property string $message * @property Carbon|null $created_at * + * @property-read User|null $user + * * @method static QueryBuilder|LogEntry[] whereId($value) * @method static QueryBuilder|LogEntry[] whereLevel($value) * @method static QueryBuilder|LogEntry[] whereMessage($value) @@ -33,6 +36,11 @@ class LogEntry extends BaseModel /** @var null Disable updated_at */ public const UPDATED_AT = null; + /** @var array Default attributes */ + protected $attributes = [ // phpcs:ignore + 'user_id' => null, + ]; + /** @var array */ protected $casts = [ // phpcs:ignore 'user_id' => 'integer', diff --git a/src/Models/Message.php b/src/Models/Message.php index 555538829..f7101a793 100644 --- a/src/Models/Message.php +++ b/src/Models/Message.php @@ -20,8 +20,10 @@ * @property string $text * @property Carbon|null $created_at * @property Carbon|null $updated_at + * * @property-read User $sender * @property-read User $receiver + * * @method static Builder|Message whereId($value) * @method static Builder|Message whereUserId($value) * @method static Builder|Message whereReceiverId($value) diff --git a/src/Models/OAuth.php b/src/Models/OAuth.php index 0b94f98c1..6db4532c3 100644 --- a/src/Models/OAuth.php +++ b/src/Models/OAuth.php @@ -13,8 +13,8 @@ * @property int $id * @property string $provider * @property string $identifier - * @property string $access_token - * @property string $refresh_token + * @property string|null $access_token + * @property string|null $refresh_token * @property Carbon|null $expires_at * @property Carbon|null $created_at * @property Carbon|null $updated_at diff --git a/src/Models/Question.php b/src/Models/Question.php index bb956c021..c599c51f1 100644 --- a/src/Models/Question.php +++ b/src/Models/Question.php @@ -15,13 +15,13 @@ /** * @property int $id * @property string $text - * @property string $answer - * @property int $answerer_id + * @property string|null $answer + * @property int|null $answerer_id * @property Carbon|null $answered_at * @property Carbon|null $created_at * @property Carbon|null $updated_at * - * @property-read User $answerer + * @property-read User|null $answerer * * @method static Builder|Question whereAnswer($value) * @method static Builder|Question whereAnswererId($value) diff --git a/src/Models/Shifts/NeededAngelType.php b/src/Models/Shifts/NeededAngelType.php index 4241f7673..9e3f28a48 100644 --- a/src/Models/Shifts/NeededAngelType.php +++ b/src/Models/Shifts/NeededAngelType.php @@ -51,6 +51,15 @@ class NeededAngelType extends BaseModel 'count', ]; + /** @var array */ + protected $casts = [ // phpcs:ignore + 'location_id' => 'integer', + 'shift_id' => 'integer', + 'shift_type_id' => 'integer', + 'angel_type_id' => 'integer', + 'count' => 'integer', + ]; + public function location(): BelongsTo { return $this->belongsTo(Location::class); diff --git a/src/Models/Shifts/Schedule.php b/src/Models/Shifts/Schedule.php index 3688f522e..2b4e274b6 100644 --- a/src/Models/Shifts/Schedule.php +++ b/src/Models/Shifts/Schedule.php @@ -23,8 +23,8 @@ * @property bool $needed_from_shift_type * @property int $minutes_before * @property int $minutes_after - * @property Carbon $created_at - * @property Carbon $updated_at + * @property Carbon|null $created_at + * @property Carbon|null $updated_at * * @property-read QueryBuilder|Location[] $activeLocations * @property-read QueryBuilder|Collection|Shift[] $shifts @@ -48,6 +48,11 @@ class Schedule extends BaseModel /** @var bool enable timestamps */ public $timestamps = true; // phpcs:ignore + /** @var array Default attributes */ + protected $attributes = [ // phpcs:ignore + 'needed_from_shift_type' => false, + ]; + /** @var array */ protected $casts = [ // phpcs:ignore 'shift_type' => 'integer', diff --git a/src/Models/Shifts/Shift.php b/src/Models/Shifts/Shift.php index 42e90f13e..cbe96b02b 100644 --- a/src/Models/Shifts/Shift.php +++ b/src/Models/Shifts/Shift.php @@ -24,7 +24,7 @@ * @property Carbon $end * @property int $shift_type_id * @property int $location_id - * @property string $transaction_id + * @property string|null $transaction_id * @property int $created_by * @property int|null $updated_by * @property Carbon|null $created_at diff --git a/src/Models/Shifts/ShiftEntry.php b/src/Models/Shifts/ShiftEntry.php index 1ba40148d..5d13821d1 100644 --- a/src/Models/Shifts/ShiftEntry.php +++ b/src/Models/Shifts/ShiftEntry.php @@ -53,6 +53,9 @@ class ShiftEntry extends BaseModel /** @var array */ protected $casts = [ // phpcs:ignore + 'shift_id' => 'integer', + 'angel_type_id' => 'integer', + 'user_id' => 'integer', 'freeloaded' => 'bool', ]; diff --git a/src/Models/User/License.php b/src/Models/User/License.php index 17b5bac0f..864702383 100644 --- a/src/Models/User/License.php +++ b/src/Models/User/License.php @@ -72,6 +72,7 @@ class License extends HasUserModel /** @var array */ protected $casts = [ // phpcs:ignore + 'user_id' => 'integer', 'has_car' => 'boolean', 'drive_forklift' => 'boolean', 'drive_car' => 'boolean', diff --git a/src/Models/User/PersonalData.php b/src/Models/User/PersonalData.php index 0c735bdaf..e6d4df25c 100644 --- a/src/Models/User/PersonalData.php +++ b/src/Models/User/PersonalData.php @@ -42,6 +42,7 @@ class PersonalData extends HasUserModel /** @var array */ protected $casts = [ // phpcs:ignore + 'user_id' => 'integer', 'planned_arrival_date' => 'datetime', 'planned_departure_date' => 'datetime', ]; diff --git a/src/Models/User/Settings.php b/src/Models/User/Settings.php index 9546336ab..ca93d288d 100644 --- a/src/Models/User/Settings.php +++ b/src/Models/User/Settings.php @@ -37,7 +37,7 @@ class Settings extends HasUserModel protected $attributes = [ // phpcs:ignore 'email_human' => false, 'email_messages' => false, - 'email_goodie' => false, + 'email_goodie' => false, 'email_shiftinfo' => false, 'email_news' => false, 'mobile_show' => false, @@ -66,7 +66,7 @@ class Settings extends HasUserModel 'theme' => 'integer', 'email_human' => 'boolean', 'email_messages' => 'boolean', - 'email_goodie' => 'boolean', + 'email_goodie' => 'boolean', 'email_shiftinfo' => 'boolean', 'email_news' => 'boolean', 'mobile_show' => 'boolean', diff --git a/src/Models/User/State.php b/src/Models/User/State.php index e3000a58e..c43e9fc63 100644 --- a/src/Models/User/State.php +++ b/src/Models/User/State.php @@ -47,11 +47,11 @@ class State extends HasUserModel protected $casts = [ // phpcs:ignore 'user_id' => 'integer', 'arrived' => 'boolean', + 'arrival_date' => 'datetime', 'active' => 'boolean', 'force_active' => 'boolean', 'got_goodie' => 'boolean', 'got_voucher' => 'integer', - 'arrival_date' => 'datetime', ]; /** diff --git a/src/Models/User/User.php b/src/Models/User/User.php index 71e4a8e1a..0d5501bf3 100644 --- a/src/Models/User/User.php +++ b/src/Models/User/User.php @@ -35,8 +35,8 @@ * @property string $password * @property string $api_key * @property Carbon|null $last_login_at - * @property Carbon $created_at - * @property Carbon $updated_at + * @property Carbon|null $created_at + * @property Carbon|null $updated_at * * @property-read QueryBuilder|Contact $contact * @property-read QueryBuilder|License $license diff --git a/src/Models/UserAngelType.php b/src/Models/UserAngelType.php index 0a37b9188..764a9f688 100644 --- a/src/Models/UserAngelType.php +++ b/src/Models/UserAngelType.php @@ -17,11 +17,11 @@ * * @property int $id * @property int $angel_type_id - * @property int $confirm_user_id + * @property int|null $confirm_user_id * @property bool $supporter * * @property-read AngelType $angelType - * @property-read User $confirmUser + * @property-read User|null $confirmUser * * @method static QueryBuilder|UserAngelType[] whereId($value) * @method static QueryBuilder|UserAngelType[] whereAngelTypeId($value) diff --git a/tests/Unit/Controllers/Admin/QuestionsControllerTest.php b/tests/Unit/Controllers/Admin/QuestionsControllerTest.php index 344f44d21..480c47126 100644 --- a/tests/Unit/Controllers/Admin/QuestionsControllerTest.php +++ b/tests/Unit/Controllers/Admin/QuestionsControllerTest.php @@ -32,7 +32,7 @@ public function testIndex(): void $this->response->expects($this->once()) ->method('withView') ->willReturnCallback(function (string $view, array $data) { - $this->assertEquals('pages/questions/overview.twig', $view); + $this->assertEquals('pages/questions/index.twig', $view); $this->assertArrayHasKey('questions', $data); $this->assertArrayHasKey('is_admin', $data); diff --git a/tests/Unit/Controllers/Api/AngelTypeControllerTest.php b/tests/Unit/Controllers/Api/AngelTypeControllerTest.php index a4e7f63dd..12a1f4865 100644 --- a/tests/Unit/Controllers/Api/AngelTypeControllerTest.php +++ b/tests/Unit/Controllers/Api/AngelTypeControllerTest.php @@ -17,6 +17,7 @@ class AngelTypeControllerTest extends ApiBaseControllerTest { /** * @covers \Engelsystem\Controllers\Api\AngelTypeController::index + * @covers \Engelsystem\Controllers\Api\Resources\AngelTypeResource::toArray */ public function testIndex(): void { @@ -34,9 +35,13 @@ public function testIndex(): void $this->assertArrayHasKey('data', $data); $this->assertCount(3, $data['data']); $this->assertCount(1, collect($data['data'])->filter(function ($item) use ($items) { - return $item['name'] == $items->first()->getAttribute('name'); + $first = $items->first(); + return $item['name'] == $first->getAttribute('name') + && $item['description'] == $first->getAttribute('description') + && $item['restricted'] == $first->getAttribute('restricted'); })); } + /** * @covers \Engelsystem\Controllers\Api\AngelTypeController::ofUser * @covers \Engelsystem\Controllers\Api\Resources\UserAngelTypeResource::toArray diff --git a/tests/Unit/Controllers/Api/ApiBaseControllerTest.php b/tests/Unit/Controllers/Api/ApiBaseControllerTest.php index b24479b96..96c705a67 100644 --- a/tests/Unit/Controllers/Api/ApiBaseControllerTest.php +++ b/tests/Unit/Controllers/Api/ApiBaseControllerTest.php @@ -6,6 +6,8 @@ use Engelsystem\Http\UrlGeneratorInterface; use Engelsystem\Test\Unit\Controllers\ControllerTest as TestCase; +use League\OpenAPIValidation\PSR7\Exception\Validation\InvalidBody; +use League\OpenAPIValidation\PSR7\Exception\ValidationFailed; use League\OpenAPIValidation\PSR7\OperationAddress as OpenApiAddress; use League\OpenAPIValidation\PSR7\ResponseValidator as OpenApiResponseValidator; use League\OpenAPIValidation\PSR7\ValidatorBuilder as OpenApiValidatorBuilder; @@ -19,7 +21,12 @@ abstract class ApiBaseControllerTest extends TestCase protected function validateApiResponse(string $path, string $method, ResponseInterface $response): void { $operation = new OpenApiAddress($path, $method); - $this->validator->validate($operation, $response); + try { + $this->validator->validate($operation, $response); + } catch (InvalidBody $e) { + $newMessage = $e->getMessage() . ': ' . $e->getPrevious()?->getMessage(); + throw new ValidationFailed($newMessage, $e->getCode(), $e); + } } public function setUp(): void diff --git a/tests/Unit/Controllers/Api/NewsControllerTest.php b/tests/Unit/Controllers/Api/NewsControllerTest.php index b7ee50bd7..e5fd96b9c 100644 --- a/tests/Unit/Controllers/Api/NewsControllerTest.php +++ b/tests/Unit/Controllers/Api/NewsControllerTest.php @@ -31,7 +31,7 @@ public function testIndex(): void $this->assertCount(3, $data['data']); $this->assertCount(1, collect($data['data'])->filter(function ($item) use ($items) { - return $item['title'] == $items->first()->getAttribute('title'); + return $item['name'] == $items->first()->getAttribute('title'); })); } } diff --git a/tests/Unit/Controllers/Api/Resources/BasicResourceTest.php b/tests/Unit/Controllers/Api/Resources/BasicResourceTest.php index a1580f524..ee8c8b8d4 100644 --- a/tests/Unit/Controllers/Api/Resources/BasicResourceTest.php +++ b/tests/Unit/Controllers/Api/Resources/BasicResourceTest.php @@ -27,6 +27,22 @@ public function testToArray(): void $this->assertEquals(['test' => 'value'], $resource->toArray()); } + /** + * @covers \Engelsystem\Controllers\Api\Resources\BasicResource::toIdentifierArray + */ + public function testToIdentifierArray(): void + { + $model = $this->getModel()->setAttribute('id', 42); + $resource = $this->getResource($model); + + $this->assertEquals(['id' => 42], $resource->toIdentifierArray($model)); + + $model = $model->setAttribute('name', 'test'); + $resource = $this->getResource($model); + + $this->assertEquals(['id' => 42, 'name' => 'test'], $resource->toIdentifierArray($model)); + } + /** * @covers \Engelsystem\Controllers\Api\Resources\BasicResource::toJson */ diff --git a/tests/Unit/Controllers/Api/ShiftTypeControllerTest.php b/tests/Unit/Controllers/Api/ShiftTypeControllerTest.php new file mode 100644 index 000000000..5e4446ed1 --- /dev/null +++ b/tests/Unit/Controllers/Api/ShiftTypeControllerTest.php @@ -0,0 +1,36 @@ +create(); + + $controller = new ShiftTypeController(new Response()); + + $response = $controller->index(); + $this->validateApiResponse('/shifttypes', 'get', $response); + + $this->assertEquals(['application/json'], $response->getHeader('content-type')); + $this->assertJson($response->getContent()); + + $data = json_decode($response->getContent(), true); + $this->assertArrayHasKey('data', $data); + $this->assertCount(3, $data['data']); + $this->assertCount(1, collect($data['data'])->filter(function ($item) use ($items) { + return $item['name'] == $items->first()->getAttribute('name'); + })); + } +} diff --git a/tests/Unit/Controllers/Api/ShiftsControllerTest.php b/tests/Unit/Controllers/Api/ShiftsControllerTest.php index 5a07856aa..0b9593533 100644 --- a/tests/Unit/Controllers/Api/ShiftsControllerTest.php +++ b/tests/Unit/Controllers/Api/ShiftsControllerTest.php @@ -33,8 +33,6 @@ class ShiftsControllerTest extends ApiBaseControllerTest * @covers \Engelsystem\Controllers\Api\Resources\ShiftResource::toArray * @covers \Engelsystem\Controllers\Api\Resources\ShiftTypeResource::toArray * @covers \Engelsystem\Controllers\Api\Resources\ShiftWithEntriesResource::toArray - * @covers \Engelsystem\Controllers\Api\Resources\UserResource::toArray - * @covers \Engelsystem\Controllers\Api\Resources\AngelTypeResource::toArray * @covers \Engelsystem\Controllers\Api\ShiftsController::getNeededAngelTypes */ public function testEntriesByLocation(): void @@ -56,37 +54,39 @@ public function testEntriesByLocation(): void // First shift $shiftAData = $data['data'][0]; - $this->assertEquals($this->shiftA->title, $shiftAData['title'], 'Title is equal'); + $this->assertEquals($this->shiftA->title, $shiftAData['name'], 'Title is equal'); $this->assertEquals($this->location->id, $shiftAData['location']['id'], 'Same location'); $this->assertEquals($this->shiftA->shiftType->id, $shiftAData['shift_type']['id'], 'Shift type equals'); - $this->assertCount(4, $shiftAData['entries']); + $this->assertCount(4, $shiftAData['needed_angel_types']); // Has users - $entriesA = collect($shiftAData['entries'])->sortBy('type.id'); + $entriesA = collect($shiftAData['needed_angel_types'])->sortBy('angeltype.id'); $entry = $entriesA[0]; - $this->assertCount(2, $entry['users']); + $this->assertCount(2, $entry['entries']); $this->assertEquals(2, $entry['needs']); - $user = $entry['users'][0]; - $this->assertEquals('/users?action=view&user_id=' . $user['id'], $user['url']); - $this->assertCount(0, $entriesA[1]['users']); - $this->assertCount(1, $entriesA[2]['users']); - $this->assertCount(1, $entriesA[3]['users']); + $user = $entry['entries'][0]['user']; + $this->assertArrayHasKey('id', $user); + $this->assertArrayHasKey('name', $user); + $this->assertArrayNotHasKey('email', $user); + $this->assertCount(0, $entriesA[1]['entries']); + $this->assertCount(1, $entriesA[2]['entries']); + $this->assertCount(1, $entriesA[3]['entries']); // Second (empty) shift $shiftBData = $data['data'][1]; - $this->assertEquals($this->shiftB->title, $shiftBData['title'], 'Title is equal'); + $this->assertEquals($this->shiftB->title, $shiftBData['name'], 'Title is equal'); $this->assertEquals($this->location->id, $shiftBData['location']['id'], 'Same location'); $this->assertEquals($this->shiftB->shiftType->id, $shiftBData['shift_type']['id'], 'Shift type equals'); - $this->assertCount(3, $shiftBData['entries']); + $this->assertCount(3, $shiftBData['needed_angel_types']); // No users - $entriesB = collect($shiftBData['entries'])->sortBy('type.id'); - $this->assertCount(0, $entriesB[0]['users']); + $entriesB = collect($shiftBData['needed_angel_types'])->sortBy('angeltype.id'); + $this->assertCount(0, $entriesB[0]['entries']); } /** * @covers \Engelsystem\Controllers\Api\ShiftsController::entriesByAngeltype * @covers \Engelsystem\Controllers\Api\ShiftsController::getNeededAngelTypes */ - public function testEntriesViaShiftType(): void + public function testEntriesByAngelType(): void { $this->schedule->needed_from_shift_type = true; $this->schedule->save(); @@ -110,34 +110,34 @@ public function testEntriesViaShiftType(): void $this->assertCount(5, $data['data']); $shift = $data['data'][0]; - $this->assertTrue(count($shift['entries']) >= 1); + $this->assertTrue(count($shift['needed_angel_types']) >= 1); } /** - * @covers \Engelsystem\Controllers\Api\ShiftsController::entriesByAngeltype + * @covers \Engelsystem\Controllers\Api\ShiftsController::entriesByShiftType */ - public function testEntriesByAngeltype(): void + public function testEntriesByShiftType(): void { /** @var ShiftEntry $firstEntry */ $firstEntry = $this->shiftA->shiftEntries->first(); $request = new Request(); - $request = $request->withAttribute('angeltype_id', $firstEntry->angelType->id); + $request = $request->withAttribute('shifttype_id', $firstEntry->shift->shift_type_id); $controller = new ShiftsController(new Response()); - $response = $controller->entriesByAngeltype($request); - $this->validateApiResponse('/angeltypes/{id}/shifts', 'get', $response); + $response = $controller->entriesByShiftType($request); + $this->validateApiResponse('/shifttypes/{id}/shifts', 'get', $response); $this->assertEquals(['application/json'], $response->getHeader('content-type')); $this->assertJson($response->getContent()); $data = json_decode($response->getContent(), true); $this->assertArrayHasKey('data', $data); - $this->assertCount(2, $data['data']); + $this->assertCount(1, $data['data']); $shift = $data['data'][0]; - $this->assertTrue(count($shift['entries']) >= 1); + $this->assertTrue(count($shift['needed_angel_types']) >= 1); } /** @@ -164,7 +164,7 @@ public function testEntriesByUser(): void $this->assertCount(1, $data['data']); $shift = $data['data'][0]; - $this->assertTrue(count($shift['entries']) >= 1); + $this->assertTrue(count($shift['needed_angel_types']) >= 1); } /** diff --git a/tests/Unit/Controllers/Api/UsersControllerTest.php b/tests/Unit/Controllers/Api/UsersControllerTest.php index 65371ed57..b5a6554f7 100644 --- a/tests/Unit/Controllers/Api/UsersControllerTest.php +++ b/tests/Unit/Controllers/Api/UsersControllerTest.php @@ -20,6 +20,7 @@ class UsersControllerTest extends ApiBaseControllerTest /** * @covers \Engelsystem\Controllers\Api\UsersController::user * @covers \Engelsystem\Controllers\Api\Resources\UserDetailResource::toArray + * @covers \Engelsystem\Controllers\Api\Resources\UserResource::toArray */ public function testUser(): void { @@ -50,7 +51,11 @@ public function testUser(): void $this->assertArrayHasKey('data', $data); $this->assertArrayHasKey('id', $data['data']); $this->assertEquals($user->id, $data['data']['id']); + $this->assertArrayHasKey('name', $data['data']); + $this->assertEquals($user->name, $data['data']['name']); + $this->assertArrayHasKey('email', $data['data']); $this->assertArrayHasKey('dates', $data['data']); + $this->assertArrayHasKey('contact', $data['data']); } /** diff --git a/tests/Unit/Controllers/FaqControllerTest.php b/tests/Unit/Controllers/FaqControllerTest.php index f7866a3a7..3af9fd28e 100644 --- a/tests/Unit/Controllers/FaqControllerTest.php +++ b/tests/Unit/Controllers/FaqControllerTest.php @@ -35,7 +35,7 @@ public function testIndex(): void $response->expects($this->once()) ->method('withView') ->willReturnCallback(function (string $view, array $data) use ($response) { - $this->assertEquals('pages/faq/overview.twig', $view); + $this->assertEquals('pages/faq/index.twig', $view); $this->assertEquals('Some Text', $data['text']); $this->assertEquals('Nah!', $data['items'][0]->text); diff --git a/tests/Unit/Controllers/MessagesControllerTest.php b/tests/Unit/Controllers/MessagesControllerTest.php index 0da5cc67d..a09c32db5 100644 --- a/tests/Unit/Controllers/MessagesControllerTest.php +++ b/tests/Unit/Controllers/MessagesControllerTest.php @@ -51,7 +51,7 @@ public function testIndexUnderNormalConditionsReturnsCorrectViewAndData(): void $this->response->expects($this->once()) ->method('withView') ->willReturnCallback(function (string $view, array $data) { - $this->assertEquals('pages/messages/overview.twig', $view); + $this->assertEquals('pages/messages/index.twig', $view); $this->assertArrayHasKey('conversations', $data); $this->assertArrayHasKey('users', $data); $this->assertArrayOrCollection($data['conversations']); diff --git a/tests/Unit/Controllers/NewsControllerTest.php b/tests/Unit/Controllers/NewsControllerTest.php index 9ebfdc8dc..94ec79a67 100644 --- a/tests/Unit/Controllers/NewsControllerTest.php +++ b/tests/Unit/Controllers/NewsControllerTest.php @@ -87,7 +87,7 @@ public function testIndex(): void ->method('withView') ->willReturnCallback( function (string $page, array $data) use (&$n) { - $this->assertEquals('pages/news/overview.twig', $page); + $this->assertEquals('pages/news/index.twig', $page); /** @var Collection $news */ $news = $data['news']; diff --git a/tests/Unit/Controllers/PasswordResetControllerTest.php b/tests/Unit/Controllers/PasswordResetControllerTest.php index 9628d370e..95272f5ed 100644 --- a/tests/Unit/Controllers/PasswordResetControllerTest.php +++ b/tests/Unit/Controllers/PasswordResetControllerTest.php @@ -108,7 +108,7 @@ public function testResetPassword(): void { $this->initDatabase(); - $this->app->instance('config', new Config(['min_password_length' => 3])); + $this->app->instance('config', new Config(['password_min_length' => 3])); $user = $this->createUser(); $token = $this->createToken($user); $request = new Request([], [], ['token' => $token->token]); @@ -138,7 +138,7 @@ public function testPostResetPassword(): void { $this->initDatabase(); - $this->app->instance('config', new Config(['min_password_length' => 3])); + $this->app->instance('config', new Config(['password_min_length' => 3])); $user = $this->createUser(); $token = $this->createToken($user); $password = 'SomeRandomPasswordForAmazingSecurity'; @@ -180,7 +180,7 @@ public function testPostResetPasswordNotMatching(): void { $this->initDatabase(); - $this->app->instance('config', new Config(['min_password_length' => 3])); + $this->app->instance('config', new Config(['password_min_length' => 3])); $user = $this->createUser(); $token = $this->createToken($user); $password = 'SomeRandomPasswordForAmazingSecurity'; diff --git a/tests/Unit/Controllers/QuestionsControllerTest.php b/tests/Unit/Controllers/QuestionsControllerTest.php index a8d327c9e..4b153ed98 100644 --- a/tests/Unit/Controllers/QuestionsControllerTest.php +++ b/tests/Unit/Controllers/QuestionsControllerTest.php @@ -32,7 +32,7 @@ public function testIndex(): void $this->response->expects($this->once()) ->method('withView') ->willReturnCallback(function (string $view, array $data) { - $this->assertEquals('pages/questions/overview.twig', $view); + $this->assertEquals('pages/questions/index.twig', $view); $this->assertArrayHasKey('questions', $data); $this->assertEquals('Foo?', $data['questions'][0]->text); diff --git a/tests/Unit/Controllers/SettingsControllerTest.php b/tests/Unit/Controllers/SettingsControllerTest.php index 92a63e4ba..a3dc306b0 100644 --- a/tests/Unit/Controllers/SettingsControllerTest.php +++ b/tests/Unit/Controllers/SettingsControllerTest.php @@ -70,7 +70,7 @@ protected function setUpProfileTest(): array config([ 'enable_pronoun' => true, - 'enable_user_name' => true, + 'enable_full_name' => true, 'enable_planned_arrival' => true, 'enable_dect' => true, 'enable_mobile_show' => true, @@ -178,7 +178,7 @@ public function testSaveProfileIgnoresPronounIfDisabled(): void public function testSaveProfileIgnoresFirstAndLastnameIfDisabled(): void { $this->setUpProfileTest(); - config(['enable_user_name' => false]); + config(['enable_full_name' => false]); $this->controller->saveProfile($this->request); $this->assertEquals('', $this->user->personalData->first_name); $this->assertEquals('', $this->user->personalData->last_name); @@ -1105,7 +1105,7 @@ public function setUp(): void 'dect' => false, ]; $this->config = new Config([ - 'min_password_length' => 6, + 'password_min_length' => 6, 'themes' => $themes, 'locales' => $languages, 'tshirt_sizes' => $tshirt_sizes, diff --git a/tests/Utils/SignUpConfig.php b/tests/Utils/SignUpConfig.php index 55900be89..c141955a0 100644 --- a/tests/Utils/SignUpConfig.php +++ b/tests/Utils/SignUpConfig.php @@ -29,13 +29,14 @@ public static function setMaximumConfig(Config $config): void ]); // disallow numeric values in username for tests $config->set('username_regex', '/\d+/'); - $config->set('min_password_length', 3); + $config->set('password_min_length', 3); $config->set('theme', 0); $config->set('enable_planned_arrival', true); - $config->set('enable_user_name', true); + $config->set('enable_full_name', true); $config->set('enable_mobile_show', true); $config->set('enable_dect', true); $config->set('required_user_fields', $requiredFields); + $config->set('enable_email_goodie', true); } public static function setMinimumConfig(Config $config): void @@ -54,10 +55,10 @@ public static function setMinimumConfig(Config $config): void $config->set('goodie_type', GoodieType::None->value); // disallow numeric values in username for tests $config->set('username_regex', '/\d+/'); - $config->set('min_password_length', 3); + $config->set('password_min_length', 3); $config->set('theme', 0); $config->set('enable_planned_arrival', false); - $config->set('enable_user_name', false); + $config->set('enable_full_name', false); $config->set('enable_mobile_show', false); $config->set('enable_dect', false); $config->set('required_user_fields', $requiredFields);
' . __('settings.password') . ' ' + . __('password.minimal_length', [config('password_min_length')]) . '">' . '' . '' . '