forked from EVOgeek/Vmeda.Online
		
	Merge pull request #3444 from NoelDeMartin/MOBILE-4059
MOBILE-4059: Fix issues found during testing
This commit is contained in:
		
						commit
						f172f9d8b6
					
				| @ -1934,8 +1934,10 @@ | |||||||
|   "core.login.errorqrnoscheme": "local_moodlemobileapp", |   "core.login.errorqrnoscheme": "local_moodlemobileapp", | ||||||
|   "core.login.errorupdatesite": "local_moodlemobileapp", |   "core.login.errorupdatesite": "local_moodlemobileapp", | ||||||
|   "core.login.exceededloginattempts": "local_moodlemobileapp", |   "core.login.exceededloginattempts": "local_moodlemobileapp", | ||||||
|   "core.login.exceededloginattemptsfallback": "local_moodlemobileapp", |   "core.login.exceededloginattemptsrecoverpassword": "local_moodlemobileapp", | ||||||
|   "core.login.exceededloginattemptssupportsubject": "local_moodlemobileapp", |   "core.login.exceededloginattemptssupportsubject": "local_moodlemobileapp", | ||||||
|  |   "core.login.exceededloginattemptswithoutpassword": "local_moodlemobileapp", | ||||||
|  |   "core.login.exceededloginattemptswithoutsupport": "local_moodlemobileapp", | ||||||
|   "core.login.exceededpasswordresetattempts": "local_moodlemobileapp", |   "core.login.exceededpasswordresetattempts": "local_moodlemobileapp", | ||||||
|   "core.login.exceededpasswordresetattemptssupportsubject": "local_moodlemobileapp", |   "core.login.exceededpasswordresetattemptssupportsubject": "local_moodlemobileapp", | ||||||
|   "core.login.faqcannotfindmysiteanswer": "local_moodlemobileapp", |   "core.login.faqcannotfindmysiteanswer": "local_moodlemobileapp", | ||||||
|  | |||||||
| @ -28,9 +28,11 @@ | |||||||
|     "errorexampleurl": "The URL https://campus.example.edu is only an example URL, it's not a real site. <strong>Please use the URL of your school or organization's site.</strong>", |     "errorexampleurl": "The URL https://campus.example.edu is only an example URL, it's not a real site. <strong>Please use the URL of your school or organization's site.</strong>", | ||||||
|     "errorqrnoscheme": "This URL isn't a valid login URL.", |     "errorqrnoscheme": "This URL isn't a valid login URL.", | ||||||
|     "errorupdatesite": "An error occurred while updating the site's token.", |     "errorupdatesite": "An error occurred while updating the site's token.", | ||||||
|     "exceededloginattempts": "Need help logging in? Try recovering your password or contact your site support.", |     "exceededloginattempts": "Need help logging in? Try {{recoverPassword}} or contact your site support.", | ||||||
|     "exceededloginattemptsfallback": "Need help logging in? Try recovering your password.", |     "exceededloginattemptsrecoverpassword": "recovering your password", | ||||||
|     "exceededloginattemptssupportsubject": "I can't log in", |     "exceededloginattemptssupportsubject": "I can't log in", | ||||||
|  |     "exceededloginattemptswithoutpassword": "Need help logging in? Try to contact your site support.", | ||||||
|  |     "exceededloginattemptswithoutsupport": "Need help logging in? Try {{recoverPassword}}.", | ||||||
|     "exceededpasswordresetattempts": "It seems you are having trouble accessing your account. You can contact your school or learning provider or try again later.", |     "exceededpasswordresetattempts": "It seems you are having trouble accessing your account. You can contact your school or learning provider or try again later.", | ||||||
|     "exceededpasswordresetattemptssupportsubject": "I can't reset my password", |     "exceededpasswordresetattemptssupportsubject": "I can't reset my password", | ||||||
|     "faqcannotfindmysiteanswer": "If you still can't find it, please contact your school or learning provider for help.", |     "faqcannotfindmysiteanswer": "If you still can't find it, please contact your school or learning provider for help.", | ||||||
|  | |||||||
| @ -33,14 +33,9 @@ | |||||||
|             <p class="core-siteurl">{{siteUrl}}</p> |             <p class="core-siteurl">{{siteUrl}}</p> | ||||||
|         </div> |         </div> | ||||||
| 
 | 
 | ||||||
|         <core-login-exceeded-attempts *ngIf="supportConfig && loginAttempts >= 3" [supportConfig]="supportConfig" |         <core-login-exceeded-attempts *ngIf="exceededAttemptsHTML && supportConfig && loginAttempts >= 3" [supportConfig]="supportConfig" | ||||||
|             [supportSubject]="'core.login.exceededloginattemptssupportsubject' | translate"> |             [supportSubject]="'core.login.exceededloginattemptssupportsubject' | translate"> | ||||||
|             <span *ngIf="canContactSupport"> |             <div [innerHTML]="exceededAttemptsHTML" (click)="exceededAttemptsClicked($event)"></div> | ||||||
|                 {{ 'core.login.exceededloginattempts' | translate }} |  | ||||||
|             </span> |  | ||||||
|             <span *ngIf="!canContactSupport"> |  | ||||||
|                 {{ 'core.login.exceededloginattemptsfallback' | translate }} |  | ||||||
|             </span> |  | ||||||
|         </core-login-exceeded-attempts> |         </core-login-exceeded-attempts> | ||||||
| 
 | 
 | ||||||
|         <form [formGroup]="credForm" (ngSubmit)="login($event)" class="core-login-form" #credentialsForm> |         <form [formGroup]="credForm" (ngSubmit)="login($event)" class="core-login-form" #credentialsForm> | ||||||
|  | |||||||
| @ -31,6 +31,7 @@ import { CoreForms } from '@singletons/form'; | |||||||
| import { CoreUserSupport } from '@features/user/services/support'; | import { CoreUserSupport } from '@features/user/services/support'; | ||||||
| import { CoreUserSupportConfig } from '@features/user/classes/support/support-config'; | import { CoreUserSupportConfig } from '@features/user/classes/support/support-config'; | ||||||
| import { CoreUserGuestSupportConfig } from '@features/user/classes/support/guest-support-config'; | import { CoreUserGuestSupportConfig } from '@features/user/classes/support/guest-support-config'; | ||||||
|  | import { SafeHtml } from '@angular/platform-browser'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Page to enter the user credentials. |  * Page to enter the user credentials. | ||||||
| @ -59,7 +60,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { | |||||||
|     showScanQR = false; |     showScanQR = false; | ||||||
|     loginAttempts = 0; |     loginAttempts = 0; | ||||||
|     supportConfig?: CoreUserSupportConfig; |     supportConfig?: CoreUserSupportConfig; | ||||||
|     canContactSupport?: boolean; |     exceededAttemptsHTML?: SafeHtml | string | null; | ||||||
| 
 | 
 | ||||||
|     protected siteConfig?: CoreSitePublicConfigResponse; |     protected siteConfig?: CoreSitePublicConfigResponse; | ||||||
|     protected eventThrown = false; |     protected eventThrown = false; | ||||||
| @ -83,7 +84,6 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { | |||||||
|             this.siteConfig = CoreNavigator.getRouteParam<CoreSitePublicConfigResponse>('siteConfig'); |             this.siteConfig = CoreNavigator.getRouteParam<CoreSitePublicConfigResponse>('siteConfig'); | ||||||
|             this.urlToOpen = CoreNavigator.getRouteParam('urlToOpen'); |             this.urlToOpen = CoreNavigator.getRouteParam('urlToOpen'); | ||||||
|             this.supportConfig = this.siteConfig && new CoreUserGuestSupportConfig(this.siteConfig); |             this.supportConfig = this.siteConfig && new CoreUserGuestSupportConfig(this.siteConfig); | ||||||
|             this.canContactSupport = this.supportConfig?.canContactSupport(); |  | ||||||
|         } catch (error) { |         } catch (error) { | ||||||
|             CoreDomUtils.showErrorModal(error); |             CoreDomUtils.showErrorModal(error); | ||||||
| 
 | 
 | ||||||
| @ -208,6 +208,10 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { | |||||||
|             this.canSignup = this.siteConfig.registerauth == 'email' && |             this.canSignup = this.siteConfig.registerauth == 'email' && | ||||||
|                     !CoreLoginHelper.isEmailSignupDisabled(this.siteConfig, disabledFeatures); |                     !CoreLoginHelper.isEmailSignupDisabled(this.siteConfig, disabledFeatures); | ||||||
|             this.showForgottenPassword = !CoreLoginHelper.isForgottenPasswordDisabled(this.siteConfig, disabledFeatures); |             this.showForgottenPassword = !CoreLoginHelper.isForgottenPasswordDisabled(this.siteConfig, disabledFeatures); | ||||||
|  |             this.exceededAttemptsHTML = CoreLoginHelper.buildExceededAttemptsHTML( | ||||||
|  |                 !!this.supportConfig?.canContactSupport(), | ||||||
|  |                 this.showForgottenPassword, | ||||||
|  |             ); | ||||||
| 
 | 
 | ||||||
|             if (!this.eventThrown && !this.viewLeft) { |             if (!this.eventThrown && !this.viewLeft) { | ||||||
|                 this.eventThrown = true; |                 this.eventThrown = true; | ||||||
| @ -301,6 +305,21 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Exceeded attempts message clicked. | ||||||
|  |      * | ||||||
|  |      * @param event Click event. | ||||||
|  |      */ | ||||||
|  |     exceededAttemptsClicked(event: Event): void { | ||||||
|  |         event.preventDefault(); | ||||||
|  | 
 | ||||||
|  |         if (!(event.target instanceof HTMLAnchorElement)) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this.forgottenPassword(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Forgotten password button clicked. |      * Forgotten password button clicked. | ||||||
|      */ |      */ | ||||||
|  | |||||||
| @ -43,14 +43,9 @@ | |||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                 </ion-card> |                 </ion-card> | ||||||
| 
 | 
 | ||||||
|                 <core-login-exceeded-attempts *ngIf="supportConfig && reconnectAttempts >= 3" [supportConfig]="supportConfig" |                 <core-login-exceeded-attempts *ngIf="exceededAttemptsHTML && supportConfig && reconnectAttempts >= 3" | ||||||
|                     [supportSubject]="'core.login.exceededloginattemptssupportsubject' | translate"> |                     [supportConfig]="supportConfig" [supportSubject]="'core.login.exceededloginattemptssupportsubject' | translate"> | ||||||
|                     <span *ngIf="canContactSupport"> |                     <div [innerHTML]="exceededAttemptsHTML" (click)="exceededAttemptsClicked($event)"></div> | ||||||
|                         {{ 'core.login.exceededloginattempts' | translate }} |  | ||||||
|                     </span> |  | ||||||
|                     <span *ngIf="!canContactSupport"> |  | ||||||
|                         {{ 'core.login.exceededloginattemptsfallback' | translate }} |  | ||||||
|                     </span> |  | ||||||
|                 </core-login-exceeded-attempts> |                 </core-login-exceeded-attempts> | ||||||
|             </div> |             </div> | ||||||
|             <form *ngIf="!isOAuth" [formGroup]="credForm" (ngSubmit)="login($event)" class="core-login-form" #reconnectForm> |             <form *ngIf="!isOAuth" [formGroup]="credForm" (ngSubmit)="login($event)" class="core-login-form" #reconnectForm> | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ import { CoreUserSupport } from '@features/user/services/support'; | |||||||
| import { CoreUserSupportConfig } from '@features/user/classes/support/support-config'; | import { CoreUserSupportConfig } from '@features/user/classes/support/support-config'; | ||||||
| import { CoreUserAuthenticatedSupportConfig } from '@features/user/classes/support/authenticated-support-config'; | import { CoreUserAuthenticatedSupportConfig } from '@features/user/classes/support/authenticated-support-config'; | ||||||
| import { Translate } from '@singletons'; | import { Translate } from '@singletons'; | ||||||
|  | import { SafeHtml } from '@angular/platform-browser'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Page to enter the user password to reconnect to a site. |  * Page to enter the user password to reconnect to a site. | ||||||
| @ -61,7 +62,7 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy { | |||||||
|     showLoading = true; |     showLoading = true; | ||||||
|     reconnectAttempts = 0; |     reconnectAttempts = 0; | ||||||
|     supportConfig?: CoreUserSupportConfig; |     supportConfig?: CoreUserSupportConfig; | ||||||
|     canContactSupport?: boolean; |     exceededAttemptsHTML?: SafeHtml | string | null; | ||||||
| 
 | 
 | ||||||
|     protected siteConfig?: CoreSitePublicConfigResponse; |     protected siteConfig?: CoreSitePublicConfigResponse; | ||||||
|     protected viewLeft = false; |     protected viewLeft = false; | ||||||
| @ -109,7 +110,6 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy { | |||||||
|             this.siteUrl = site.infos.siteurl; |             this.siteUrl = site.infos.siteurl; | ||||||
|             this.siteName = site.getSiteName(); |             this.siteName = site.getSiteName(); | ||||||
|             this.supportConfig = new CoreUserAuthenticatedSupportConfig(site); |             this.supportConfig = new CoreUserAuthenticatedSupportConfig(site); | ||||||
|             this.canContactSupport = this.supportConfig.canContactSupport(); |  | ||||||
| 
 | 
 | ||||||
|             // If login was OAuth we should only reach this page if the OAuth method ID has changed.
 |             // If login was OAuth we should only reach this page if the OAuth method ID has changed.
 | ||||||
|             this.isOAuth = site.isOAuth(); |             this.isOAuth = site.isOAuth(); | ||||||
| @ -168,6 +168,10 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy { | |||||||
| 
 | 
 | ||||||
|         this.identityProviders = CoreLoginHelper.getValidIdentityProviders(this.siteConfig, disabledFeatures); |         this.identityProviders = CoreLoginHelper.getValidIdentityProviders(this.siteConfig, disabledFeatures); | ||||||
|         this.showForgottenPassword = !CoreLoginHelper.isForgottenPasswordDisabled(this.siteConfig); |         this.showForgottenPassword = !CoreLoginHelper.isForgottenPasswordDisabled(this.siteConfig); | ||||||
|  |         this.exceededAttemptsHTML = CoreLoginHelper.buildExceededAttemptsHTML( | ||||||
|  |             !!this.supportConfig?.canContactSupport(), | ||||||
|  |             this.showForgottenPassword, | ||||||
|  |         ); | ||||||
| 
 | 
 | ||||||
|         if (!this.eventThrown && !this.viewLeft) { |         if (!this.eventThrown && !this.viewLeft) { | ||||||
|             this.eventThrown = true; |             this.eventThrown = true; | ||||||
| @ -270,6 +274,21 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Exceeded attempts message clicked. | ||||||
|  |      * | ||||||
|  |      * @param event Click event. | ||||||
|  |      */ | ||||||
|  |     exceededAttemptsClicked(event: Event): void { | ||||||
|  |         event.preventDefault(); | ||||||
|  | 
 | ||||||
|  |         if (!(event.target instanceof HTMLAnchorElement)) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this.forgottenPassword(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Forgotten password button clicked. |      * Forgotten password button clicked. | ||||||
|      */ |      */ | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ | |||||||
| // See the License for the specific language governing permissions and
 | // See the License for the specific language governing permissions and
 | ||||||
| // limitations under the License.
 | // limitations under the License.
 | ||||||
| 
 | 
 | ||||||
| import { Injectable } from '@angular/core'; | import { Injectable, SecurityContext } from '@angular/core'; | ||||||
| import { Params } from '@angular/router'; | import { Params } from '@angular/router'; | ||||||
| import { Md5 } from 'ts-md5/dist/md5'; | import { Md5 } from 'ts-md5/dist/md5'; | ||||||
| 
 | 
 | ||||||
| @ -29,7 +29,7 @@ import { CoreConstants } from '@/core/constants'; | |||||||
| import { CoreSite, CoreSiteIdentityProvider, CoreSitePublicConfigResponse, CoreSiteQRCodeType } from '@classes/site'; | import { CoreSite, CoreSiteIdentityProvider, CoreSitePublicConfigResponse, CoreSiteQRCodeType } from '@classes/site'; | ||||||
| import { CoreError } from '@classes/errors/error'; | import { CoreError } from '@classes/errors/error'; | ||||||
| import { CoreWSError } from '@classes/errors/wserror'; | import { CoreWSError } from '@classes/errors/wserror'; | ||||||
| import { makeSingleton, Translate } from '@singletons'; | import { DomSanitizer, makeSingleton, Translate } from '@singletons'; | ||||||
| import { CoreLogger } from '@singletons/logger'; | import { CoreLogger } from '@singletons/logger'; | ||||||
| import { CoreUrl } from '@singletons/url'; | import { CoreUrl } from '@singletons/url'; | ||||||
| import { CoreNavigator, CoreRedirectPayload } from '@services/navigator'; | import { CoreNavigator, CoreRedirectPayload } from '@services/navigator'; | ||||||
| @ -38,6 +38,8 @@ import { CoreCustomURLSchemes } from '@services/urlschemes'; | |||||||
| import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications'; | import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications'; | ||||||
| import { CoreText } from '@singletons/text'; | import { CoreText } from '@singletons/text'; | ||||||
| import { CorePromisedValue } from '@classes/promised-value'; | import { CorePromisedValue } from '@classes/promised-value'; | ||||||
|  | import { SafeHtml } from '@angular/platform-browser'; | ||||||
|  | import { CoreLoginError } from '@classes/errors/loginerror'; | ||||||
| 
 | 
 | ||||||
| const PASSWORD_RESETS_CONFIG_KEY = 'password-resets'; | const PASSWORD_RESETS_CONFIG_KEY = 'password-resets'; | ||||||
| 
 | 
 | ||||||
| @ -1025,6 +1027,13 @@ export class CoreLoginHelperProvider { | |||||||
|             (!CoreConstants.CONFIG.skipssoconfirmation || String(CoreConstants.CONFIG.skipssoconfirmation) === 'false'); |             (!CoreConstants.CONFIG.skipssoconfirmation || String(CoreConstants.CONFIG.skipssoconfirmation) === 'false'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Show a modal warning that the credentials introduced were not correct. | ||||||
|  |      */ | ||||||
|  |     protected showInvalidLoginModal(error: CoreLoginError): void { | ||||||
|  |         CoreDomUtils.showErrorModal(error.errorDetails ?? error.message); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Show a modal warning the user that he should use the Workplace app. |      * Show a modal warning the user that he should use the Workplace app. | ||||||
|      * |      * | ||||||
| @ -1166,16 +1175,25 @@ export class CoreLoginHelperProvider { | |||||||
|      * @param password User password. |      * @param password User password. | ||||||
|      */ |      */ | ||||||
|     treatUserTokenError(siteUrl: string, error: CoreWSError, username?: string, password?: string): void { |     treatUserTokenError(siteUrl: string, error: CoreWSError, username?: string, password?: string): void { | ||||||
|         if (error.errorcode == 'forcepasswordchangenotice') { |         switch (error.errorcode) { | ||||||
|             this.openChangePassword(siteUrl, CoreTextUtils.getErrorMessageFromError(error)!); |             case 'forcepasswordchangenotice': | ||||||
|         } else if (error.errorcode == 'usernotconfirmed') { |                 this.openChangePassword(siteUrl, CoreTextUtils.getErrorMessageFromError(error)!); | ||||||
|             this.showNotConfirmedModal(siteUrl, undefined, username, password); |                 break; | ||||||
|         } else if (error.errorcode == 'connecttomoodleapp') { |             case 'usernotconfirmed': | ||||||
|             this.showMoodleAppNoticeModal(CoreTextUtils.getErrorMessageFromError(error)!); |                 this.showNotConfirmedModal(siteUrl, undefined, username, password); | ||||||
|         } else if (error.errorcode == 'connecttoworkplaceapp') { |                 break; | ||||||
|             this.showWorkplaceNoticeModal(CoreTextUtils.getErrorMessageFromError(error)!); |             case 'connecttomoodleapp': | ||||||
|         } else { |                 this.showMoodleAppNoticeModal(CoreTextUtils.getErrorMessageFromError(error)!); | ||||||
|             CoreDomUtils.showErrorModal(error); |                 break; | ||||||
|  |             case 'connecttoworkplaceapp': | ||||||
|  |                 this.showWorkplaceNoticeModal(CoreTextUtils.getErrorMessageFromError(error)!); | ||||||
|  |                 break; | ||||||
|  |             case 'invalidlogin': | ||||||
|  |                 this.showInvalidLoginModal(error); | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 CoreDomUtils.showErrorModal(error); | ||||||
|  |                 break; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -1515,6 +1533,40 @@ export class CoreLoginHelperProvider { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Build the HTML message to show once login attempts have been exceeded. | ||||||
|  |      * | ||||||
|  |      * @param canContactSupport Whether contacting support is enabled in the site. | ||||||
|  |      * @param canRecoverPassword Whether recovering the password is enabled in the site. | ||||||
|  |      * @return HTML message. | ||||||
|  |      */ | ||||||
|  |     buildExceededAttemptsHTML(canContactSupport: boolean, canRecoverPassword: boolean): SafeHtml | string | null { | ||||||
|  |         const safeHTML = (html: string) => DomSanitizer.sanitize(SecurityContext.HTML, html) ?? ''; | ||||||
|  |         const recoverPasswordHTML = (messageKey: string) => { | ||||||
|  |             const placeholder = '%%RECOVER_PASSWORD%%'; | ||||||
|  |             const message = safeHTML(Translate.instant(messageKey, { recoverPassword: placeholder })); | ||||||
|  |             const recoverPassword = safeHTML(Translate.instant('core.login.exceededloginattemptsrecoverpassword')); | ||||||
|  | 
 | ||||||
|  |             return DomSanitizer.bypassSecurityTrustHtml( | ||||||
|  |                 message.replace(placeholder, `<a href="#" role="button" style="color:inherit">${recoverPassword}</a>`), | ||||||
|  |             ); | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         if (canContactSupport && canRecoverPassword) { | ||||||
|  |             return recoverPasswordHTML('core.login.exceededloginattempts'); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (canContactSupport) { | ||||||
|  |             return Translate.instant('core.login.exceededloginattemptswithoutpassword'); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (canRecoverPassword) { | ||||||
|  |             return recoverPasswordHTML('core.login.exceededloginattemptswithoutsupport'); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Get a record indexing the last time a password reset was requested for a site. |      * Get a record indexing the last time a password reset was requested for a site. | ||||||
|      * |      * | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ | |||||||
|     "roles": "Roles", |     "roles": "Roles", | ||||||
|     "sendemail": "Email", |     "sendemail": "Email", | ||||||
|     "student": "Student", |     "student": "Student", | ||||||
|     "support": "Support", |     "support": "Contact site support", | ||||||
|     "teacher": "Non-editing teacher", |     "teacher": "Non-editing teacher", | ||||||
|     "userwithid": "User with ID {{id}}", |     "userwithid": "User with ID {{id}}", | ||||||
|     "webpage": "Web page" |     "webpage": "Web page" | ||||||
|  | |||||||
| @ -10,9 +10,9 @@ Feature: Site support | |||||||
|   Scenario: Uses default support page |   Scenario: Uses default support page | ||||||
|     Given I entered the app as "student1" |     Given I entered the app as "student1" | ||||||
|     When I press the user menu button in the app |     When I press the user menu button in the app | ||||||
|     Then I should find "Support" in the app |     Then I should find "Contact site support" in the app | ||||||
| 
 | 
 | ||||||
|     When I press "Support" in the app |     When I press "Contact site support" in the app | ||||||
|     Then the app should have opened a browser tab with url ".*\/user\/contactsitesupport\.php" |     Then the app should have opened a browser tab with url ".*\/user\/contactsitesupport\.php" | ||||||
| 
 | 
 | ||||||
|   Scenario: Uses custom support page |   Scenario: Uses custom support page | ||||||
| @ -20,9 +20,9 @@ Feature: Site support | |||||||
|       | supportpage | https://campus.example.edu/support | |       | supportpage | https://campus.example.edu/support | | ||||||
|     And I entered the app as "student1" |     And I entered the app as "student1" | ||||||
|     When I press the user menu button in the app |     When I press the user menu button in the app | ||||||
|     Then I should find "Support" in the app |     Then I should find "Contact site support" in the app | ||||||
| 
 | 
 | ||||||
|     When I press "Support" in the app |     When I press "Contact site support" in the app | ||||||
|     Then the app should have opened a browser tab with url "https:\/\/campus\.example\.edu\/support" |     Then the app should have opened a browser tab with url "https:\/\/campus\.example\.edu\/support" | ||||||
| 
 | 
 | ||||||
|   Scenario: Cannot contact support |   Scenario: Cannot contact support | ||||||
| @ -31,4 +31,4 @@ Feature: Site support | |||||||
|     And I entered the app as "student1" |     And I entered the app as "student1" | ||||||
|     When I press the user menu button in the app |     When I press the user menu button in the app | ||||||
|     Then I should find "Blog entries" in the app |     Then I should find "Blog entries" in the app | ||||||
|     But I should not find "Support" in the app |     But I should not find "Contact site support" in the app | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user