Commit 0aebb5d92ebefd9d0659d7341bf929a20df8b0b0
Exists in
master
and in
1 other branch
Merge branch 'registration_errors'
Showing
9 changed files
with
155 additions
and
47 deletions
Show diff stats
src/app/account/register-component.html
| @@ -3,6 +3,14 @@ | @@ -3,6 +3,14 @@ | ||
| 3 | <h1>{{"account.register.welcomeMessageTitle" | translate }}</h1> | 3 | <h1>{{"account.register.welcomeMessageTitle" | translate }}</h1> |
| 4 | <div class="environment-signup-intro" ng-bind-html="ctrl.environment.signup_intro"></div> | 4 | <div class="environment-signup-intro" ng-bind-html="ctrl.environment.signup_intro"></div> |
| 5 | </div> | 5 | </div> |
| 6 | + | ||
| 7 | + <div class="error-messages" ng-if="ctrl.errorMessages"> | ||
| 8 | + <p>{{ "account.register.errorMessagesTitle" | translate }}</p> | ||
| 9 | + <ul> | ||
| 10 | + <li ng-repeat="error in ctrl.errorMessages">{{ error.fieldName | translate }} {{ error.message | translate }}</li> | ||
| 11 | + </ul> | ||
| 12 | + </div> | ||
| 13 | + | ||
| 6 | <form name="signupForm"> | 14 | <form name="signupForm"> |
| 7 | <div class="row"> | 15 | <div class="row"> |
| 8 | <div class="col-md-12 register-field"> | 16 | <div class="col-md-12 register-field"> |
| @@ -17,10 +25,12 @@ | @@ -17,10 +25,12 @@ | ||
| 17 | <span class="input-group-addon" style="font-weight: bold;"><i class="fa fa-globe"></i> {{ ctrl.environment.host }}</span> | 25 | <span class="input-group-addon" style="font-weight: bold;"><i class="fa fa-globe"></i> {{ ctrl.environment.host }}</span> |
| 18 | <input type="text" id="username" name="username" class="form-control" placeholder="{{'account.register.usernameLabel' | translate }}" ng-model="ctrl.account.login" required> | 26 | <input type="text" id="username" name="username" class="form-control" placeholder="{{'account.register.usernameLabel' | translate }}" ng-model="ctrl.account.login" required> |
| 19 | </div> | 27 | </div> |
| 20 | - <div class="help-block" ng-show="signupForm.username.$touched" ng-messages="signupForm.username.$error"> | ||
| 21 | - <ul class="list-unstyled"> | ||
| 22 | - <li ng-messages-include="languages/messages.html"></li> | ||
| 23 | - </ul> | 28 | + <div class="help-block" ng-messages="signupForm.username.$error"> |
| 29 | + <div ng-if="signupForm.username.$touched && !signupForm.username.$empty"> | ||
| 30 | + <ul class="list-unstyled"> | ||
| 31 | + <li ng-messages-include="app/shared/messages/form-errors.html"></li> | ||
| 32 | + </ul> | ||
| 33 | + </div> | ||
| 24 | </div> | 34 | </div> |
| 25 | </div> | 35 | </div> |
| 26 | 36 | ||
| @@ -29,22 +39,26 @@ | @@ -29,22 +39,26 @@ | ||
| 29 | <span class="input-group-addon"><i class="fa fa-envelope"></i></span> | 39 | <span class="input-group-addon"><i class="fa fa-envelope"></i></span> |
| 30 | <input type="email" class="form-control" id="email" name="email" placeholder="{{'account.register.emailLabel' | translate }}" ng-model="ctrl.account.email" required> | 40 | <input type="email" class="form-control" id="email" name="email" placeholder="{{'account.register.emailLabel' | translate }}" ng-model="ctrl.account.email" required> |
| 31 | </div> | 41 | </div> |
| 32 | - <div class="help-block" ng-show="signupForm.email.$touched" ng-messages="signupForm.email.$error"> | ||
| 33 | - <ul class="list-unstyled"> | ||
| 34 | - <li ng-messages-include="languages/messages.html"></li> | ||
| 35 | - </ul> | 42 | + <div class="help-block" ng-messages="signupForm.email.$error"> |
| 43 | + <div ng-if="signupForm.email.$touched && !signupForm.email.$empty"> | ||
| 44 | + <ul class="list-unstyled"> | ||
| 45 | + <li ng-messages-include="app/shared/messages/form-errors.html"></li> | ||
| 46 | + </ul> | ||
| 47 | + </div> | ||
| 36 | </div> | 48 | </div> |
| 37 | </div> | 49 | </div> |
| 38 | 50 | ||
| 39 | <div class="form-group col-md-6 register-field" ng-class="ctrl.isInvalid(signupForm.password)"> | 51 | <div class="form-group col-md-6 register-field" ng-class="ctrl.isInvalid(signupForm.password)"> |
| 40 | <div class="input-group"> | 52 | <div class="input-group"> |
| 41 | <span class="input-group-addon"><i class="fa fa-lock"></i></span> | 53 | <span class="input-group-addon"><i class="fa fa-lock"></i></span> |
| 42 | - <input type="password" class="form-control" id="password" name="password" placeholder="{{'account.register.passwordLabel' | translate }}" ng-model="ctrl.account.password" required> | 54 | + <input type="password" class="form-control" id="password" name="password" placeholder="{{'account.register.passwordLabel' | translate }}" ng-model="ctrl.account.password" required minlength="4"> |
| 43 | </div> | 55 | </div> |
| 44 | - <div class="help-block" ng-show="signupForm.password.$touched" ng-messages="signupForm.password.$error"> | ||
| 45 | - <ul class="list-unstyled"> | ||
| 46 | - <li ng-messages-include="languages/messages.html"></li> | ||
| 47 | - </ul> | 56 | + <div class="help-block" ng-messages="signupForm.password.$error"> |
| 57 | + <div ng-if="signupForm.password.$touched && !signupForm.password.$empty"> | ||
| 58 | + <ul class="list-unstyled"> | ||
| 59 | + <li ng-messages-include="app/shared/messages/form-errors.html"></li> | ||
| 60 | + </ul> | ||
| 61 | + </div> | ||
| 48 | </div> | 62 | </div> |
| 49 | </div> | 63 | </div> |
| 50 | 64 | ||
| @@ -55,7 +69,7 @@ | @@ -55,7 +69,7 @@ | ||
| 55 | </div> | 69 | </div> |
| 56 | <div class="help-block" ng-show="signupForm.passwordConfirm.$touched" ng-messages="signupForm.passwordConfirm.$error"> | 70 | <div class="help-block" ng-show="signupForm.passwordConfirm.$touched" ng-messages="signupForm.passwordConfirm.$error"> |
| 57 | <ul class="list-unstyled"> | 71 | <ul class="list-unstyled"> |
| 58 | - <li ng-messages-include="languages/messages.html"></li> | 72 | + <li ng-messages-include="app/shared/messages/form-errors.html"></li> |
| 59 | <li ng-message="passwordMatch" translate="messages.invalid.passwordMatch"></li> | 73 | <li ng-message="passwordMatch" translate="messages.invalid.passwordMatch"></li> |
| 60 | </ul> | 74 | </ul> |
| 61 | </div> | 75 | </div> |
| @@ -72,6 +86,5 @@ | @@ -72,6 +86,5 @@ | ||
| 72 | </div> | 86 | </div> |
| 73 | </form> | 87 | </form> |
| 74 | 88 | ||
| 75 | - <p class="already-registered-message">{{"account.register.haveAccountMessage" | translate}}</p> | ||
| 76 | - | 89 | + <a class="already-registered-message" ng-href="#" ng-click="ctrl.openLogin()">{{"account.register.haveAccountMessage" | translate}}</a> |
| 77 | </div> | 90 | </div> |
src/app/account/register-terms.html
| 1 | <div class="modal-header"> | 1 | <div class="modal-header"> |
| 2 | - <h3 class="modal-title">Register terms</h3> | 2 | + <h3 class="modal-title">{{ "account.register.termsOfUseTitle" | translate }} - {{ ctrl.environment.name }}</h3> |
| 3 | </div> | 3 | </div> |
| 4 | <div class="modal-body modal-body-overflow" ng-bind-html="ctrl.environment.terms_of_use"></div> | 4 | <div class="modal-body modal-body-overflow" ng-bind-html="ctrl.environment.terms_of_use"></div> |
| 5 | <div class="modal-footer"> | 5 | <div class="modal-footer"> |
src/app/account/register.component.spec.ts
| 1 | import { ComponentTestHelper, createClass } from "../../spec/component-test-helper"; | 1 | import { ComponentTestHelper, createClass } from "../../spec/component-test-helper"; |
| 2 | import * as helpers from "../../spec/helpers"; | 2 | import * as helpers from "../../spec/helpers"; |
| 3 | import { RegisterComponent } from "./register.component"; | 3 | import { RegisterComponent } from "./register.component"; |
| 4 | -// import {RegisterService} from "../../lib/ng-noosfero-api/http/register.service" | ||
| 5 | - | ||
| 6 | 4 | ||
| 7 | describe("Register Component", () => { | 5 | describe("Register Component", () => { |
| 8 | const htmlTemplate: string = '<noosfero-register></noosfero-register>'; | 6 | const htmlTemplate: string = '<noosfero-register></noosfero-register>'; |
| 9 | 7 | ||
| 10 | let helper: ComponentTestHelper<RegisterComponent>; | 8 | let helper: ComponentTestHelper<RegisterComponent>; |
| 11 | let registerService = helpers.mocks.registerService; | 9 | let registerService = helpers.mocks.registerService; |
| 12 | - let stateService = jasmine.createSpyObj("$state", ["transitionTo"]); | 10 | + let stateService: angular.ui.IStateService; |
| 13 | let notificationService = helpers.mocks.notificationService; | 11 | let notificationService = helpers.mocks.notificationService; |
| 14 | notificationService.success = jasmine.createSpy('success'); | 12 | notificationService.success = jasmine.createSpy('success'); |
| 15 | notificationService.error = jasmine.createSpy('error'); | 13 | notificationService.error = jasmine.createSpy('error'); |
| 16 | - | ||
| 17 | - | ||
| 18 | - let account: any = { | ||
| 19 | - id: 1, | ||
| 20 | - login: 'test', | ||
| 21 | - email: 'test@email.com', | ||
| 22 | - password: 'xxx', | ||
| 23 | - passwordConfirmation: 'xxx' | ||
| 24 | - }; | 14 | + let user_data: any; |
| 15 | + let response: any; | ||
| 16 | + let deferred: any; | ||
| 17 | + let $rootScope: ng.IRootScopeService; | ||
| 18 | + let $q: ng.IQService; | ||
| 25 | 19 | ||
| 26 | beforeEach(() => { | 20 | beforeEach(() => { |
| 21 | + stateService = jasmine.createSpyObj("$state", ["transitionTo"]); | ||
| 22 | + | ||
| 27 | angular.mock.module('templates'); | 23 | angular.mock.module('templates'); |
| 28 | angular.mock.module('ngSanitize'); | 24 | angular.mock.module('ngSanitize'); |
| 29 | angular.mock.module('ngMessages'); | 25 | angular.mock.module('ngMessages'); |
| @@ -45,8 +41,53 @@ describe("Register Component", () => { | @@ -45,8 +41,53 @@ describe("Register Component", () => { | ||
| 45 | helper = new ComponentTestHelper<RegisterComponent>(cls, done); | 41 | helper = new ComponentTestHelper<RegisterComponent>(cls, done); |
| 46 | }); | 42 | }); |
| 47 | 43 | ||
| 44 | + beforeEach(inject((_$rootScope_: ng.IRootScopeService, _$q_: ng.IQService) => { | ||
| 45 | + $rootScope = _$rootScope_; | ||
| 46 | + $q = _$q_; | ||
| 47 | + })); | ||
| 48 | + | ||
| 48 | it('register page was rendered', () => { | 49 | it('register page was rendered', () => { |
| 49 | expect(helper.debugElement.query('div.register-page').length).toEqual(1); | 50 | expect(helper.debugElement.query('div.register-page').length).toEqual(1); |
| 50 | }); | 51 | }); |
| 51 | 52 | ||
| 53 | + it("registers a new user", done => { | ||
| 54 | + user_data = { username: "username", password: "password", password_confirmation: "password", email: "user@company.com" }; | ||
| 55 | + response = {}; | ||
| 56 | + | ||
| 57 | + helper.component.account = user_data; | ||
| 58 | + | ||
| 59 | + deferred = $q.defer(); | ||
| 60 | + deferred.resolve({ data: response }); | ||
| 61 | + registerService.createAccount = jasmine.createSpy("createAccount").and.returnValue(deferred.promise); | ||
| 62 | + | ||
| 63 | + helper.component.signup(); | ||
| 64 | + helper.detectChanges(); | ||
| 65 | + | ||
| 66 | + expect(registerService.createAccount).toHaveBeenCalledWith(user_data); | ||
| 67 | + expect(stateService.transitionTo).toHaveBeenCalledWith("main.environment"); | ||
| 68 | + expect(notificationService.success).toHaveBeenCalled(); | ||
| 69 | + | ||
| 70 | + done(); | ||
| 71 | + }); | ||
| 72 | + | ||
| 73 | + it("gives error when registration fails", done => { | ||
| 74 | + user_data = { password: "pas" }; | ||
| 75 | + response = { data: { message: '{ "password": ["is too short"] }' } }; | ||
| 76 | + | ||
| 77 | + helper.component.account = user_data; | ||
| 78 | + | ||
| 79 | + deferred = $q.defer(); | ||
| 80 | + deferred.reject(response); | ||
| 81 | + registerService.createAccount = jasmine.createSpy("createAccount").and.returnValue(deferred.promise); | ||
| 82 | + | ||
| 83 | + helper.component.signup(); | ||
| 84 | + helper.detectChanges(); | ||
| 85 | + | ||
| 86 | + expect(registerService.createAccount).toHaveBeenCalledWith(user_data); | ||
| 87 | + | ||
| 88 | + expect(stateService.transitionTo).not.toHaveBeenCalledWith("main.environment"); | ||
| 89 | + expect(notificationService.error).toHaveBeenCalled(); | ||
| 90 | + | ||
| 91 | + done(); | ||
| 92 | + }); | ||
| 52 | }); | 93 | }); |
src/app/account/register.component.ts
| @@ -3,6 +3,7 @@ import { RegisterService } from "./../../lib/ng-noosfero-api/http/register.servi | @@ -3,6 +3,7 @@ import { RegisterService } from "./../../lib/ng-noosfero-api/http/register.servi | ||
| 3 | import { NotificationService } from "./../shared/services/notification.service"; | 3 | import { NotificationService } from "./../shared/services/notification.service"; |
| 4 | import { EnvironmentService } from "../../lib/ng-noosfero-api/http/environment.service"; | 4 | import { EnvironmentService } from "../../lib/ng-noosfero-api/http/environment.service"; |
| 5 | import { RegisterController } from "./register.controller"; | 5 | import { RegisterController } from "./register.controller"; |
| 6 | +import { AuthController } from "./../login"; | ||
| 6 | import { IModalComponent } from "../shared/components/interfaces"; | 7 | import { IModalComponent } from "../shared/components/interfaces"; |
| 7 | 8 | ||
| 8 | @Component({ | 9 | @Component({ |
| @@ -20,6 +21,8 @@ export class RegisterComponent { | @@ -20,6 +21,8 @@ export class RegisterComponent { | ||
| 20 | 21 | ||
| 21 | modalInstance: ng.ui.bootstrap.IModalServiceInstance; | 22 | modalInstance: ng.ui.bootstrap.IModalServiceInstance; |
| 22 | 23 | ||
| 24 | + errorMessages: any[]; | ||
| 25 | + | ||
| 23 | constructor( | 26 | constructor( |
| 24 | private $state: ng.ui.IStateService, | 27 | private $state: ng.ui.IStateService, |
| 25 | private $uibModal: ng.ui.bootstrap.IModalService, | 28 | private $uibModal: ng.ui.bootstrap.IModalService, |
| @@ -33,19 +36,27 @@ export class RegisterComponent { | @@ -33,19 +36,27 @@ export class RegisterComponent { | ||
| 33 | } | 36 | } |
| 34 | 37 | ||
| 35 | signup() { | 38 | signup() { |
| 36 | - if (this.account.password === this.account.passwordConfirmation) { | ||
| 37 | - this.registerService.createAccount(this.account).then((response) => { | ||
| 38 | - | ||
| 39 | - if (response.status === 201) { | ||
| 40 | - this.$state.transitionTo('main.environment'); | ||
| 41 | - this.notificationService.success({ title: "account.register.success.title", message: "account.register.success.message" }); | ||
| 42 | - } else { | ||
| 43 | - throw new Error('Invalid attributes'); | 39 | + let error = ''; |
| 40 | + let errors: any; | ||
| 41 | + let field = ''; | ||
| 42 | + this.errorMessages = []; | ||
| 43 | + this.registerService.createAccount(this.account).then((response) => { | ||
| 44 | + this.$state.transitionTo('main.environment'); | ||
| 45 | + this.notificationService.success({ title: "account.register.success.title", message: "account.register.success.message" }); | ||
| 46 | + }).catch((response) => { | ||
| 47 | + if (response.data.error) { | ||
| 48 | + errors = response.data['error'].split(', '); | ||
| 49 | + for (error in errors) { | ||
| 50 | + this.errorMessages.push({ message: errors[error] }); | ||
| 51 | + } | ||
| 52 | + } else if (response.data.message) { | ||
| 53 | + errors = JSON.parse(response.data.message); | ||
| 54 | + for (field in errors) { | ||
| 55 | + this.errorMessages.push({ fieldName: field, message: errors[field][0] }); | ||
| 44 | } | 56 | } |
| 45 | - }); | ||
| 46 | - } else { | ||
| 47 | - this.notificationService.error({ message: "account.register.passwordConfirmation.failed" }); | ||
| 48 | - } | 57 | + } |
| 58 | + this.notificationService.error({ title: "account.register.save.failed" }); | ||
| 59 | + }); | ||
| 49 | } | 60 | } |
| 50 | 61 | ||
| 51 | isInvalid(field: any): any { | 62 | isInvalid(field: any): any { |
| @@ -63,4 +74,14 @@ export class RegisterComponent { | @@ -63,4 +74,14 @@ export class RegisterComponent { | ||
| 63 | scope: this.$scope | 74 | scope: this.$scope |
| 64 | }); | 75 | }); |
| 65 | } | 76 | } |
| 77 | + | ||
| 78 | + openLogin() { | ||
| 79 | + this.modalInstance = this.$uibModal.open({ | ||
| 80 | + templateUrl: 'app/login/login.html', | ||
| 81 | + controller: AuthController, | ||
| 82 | + controllerAs: 'vm', | ||
| 83 | + bindToController: true | ||
| 84 | + }); | ||
| 85 | + } | ||
| 86 | + | ||
| 66 | } | 87 | } |
src/app/account/scss/register.scss
| @@ -29,6 +29,7 @@ | @@ -29,6 +29,7 @@ | ||
| 29 | .register-page .already-registered-message { | 29 | .register-page .already-registered-message { |
| 30 | margin-top: 60px; | 30 | margin-top: 60px; |
| 31 | text-align: center; | 31 | text-align: center; |
| 32 | + display: block; | ||
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | .register-page input { | 35 | .register-page input { |
| @@ -0,0 +1,4 @@ | @@ -0,0 +1,4 @@ | ||
| 1 | +<li ng-message="required" translate="messages.invalid.required"></li> | ||
| 2 | +<li ng-message="minlength" translate="messages.invalid.minlength"></li> | ||
| 3 | +<li ng-message="maxlength" translate="messages.invalid.maxlength"></li> | ||
| 4 | +<li ng-message="email" translate="messages.invalid.email"></li> |
src/languages/en.json
| @@ -120,6 +120,7 @@ | @@ -120,6 +120,7 @@ | ||
| 120 | "account.register.signupMessage": "Register", | 120 | "account.register.signupMessage": "Register", |
| 121 | "account.register.haveAccountMessage": "Already have an account?", | 121 | "account.register.haveAccountMessage": "Already have an account?", |
| 122 | "account.register.termsOfUseMessage": "terms of use", | 122 | "account.register.termsOfUseMessage": "terms of use", |
| 123 | + "account.register.termsOfUseTitle": "Terms of use", | ||
| 123 | "account.register.success.title": "Good job!", | 124 | "account.register.success.title": "Good job!", |
| 124 | "account.register.success.message": "Account created!", | 125 | "account.register.success.message": "Account created!", |
| 125 | "account.register.passwordConfirmation.failed": "Wrong password confirmation", | 126 | "account.register.passwordConfirmation.failed": "Wrong password confirmation", |
| @@ -148,5 +149,20 @@ | @@ -148,5 +149,20 @@ | ||
| 148 | "tasks.add_friend.message": "wants to be friend of", | 149 | "tasks.add_friend.message": "wants to be friend of", |
| 149 | "tasks.add_member.message": "wants to join", | 150 | "tasks.add_member.message": "wants to join", |
| 150 | "tasks.create_community.message": "wants to create a new community:", | 151 | "tasks.create_community.message": "wants to create a new community:", |
| 151 | - "tasks.suggest_article.message": "suggested a new article:" | 152 | + "tasks.suggest_article.message": "suggested a new article:", |
| 153 | + "account.register.save.failed": "This account could not be created", | ||
| 154 | + "account.register.mandatoryField": "This field is mandatory", | ||
| 155 | + "account.register.invalidEmail": "This field must be a valid email address.", | ||
| 156 | + "account.register.shortPassword": "The password must have at least 4 characters)", | ||
| 157 | + "account.register.errorMessagesTitle": "There were problems with the following fields:", | ||
| 158 | + "email is missing": "email can't be blank", | ||
| 159 | + "login is missing": "username can't be blank", | ||
| 160 | + "password is missing": "password can't be blank", | ||
| 161 | + "login": "username", | ||
| 162 | + "has already been taken": "has already been taken", | ||
| 163 | + "email": "email", | ||
| 164 | + "identifier": "identifier", | ||
| 165 | + "is not available.": "is not available", | ||
| 166 | + "user": "user", | ||
| 167 | + "is invalid": "is invalid" | ||
| 152 | } | 168 | } |
src/languages/messages.html
| @@ -1,4 +0,0 @@ | @@ -1,4 +0,0 @@ | ||
| 1 | -<li ng-message="required" translate="messages.invalid.required"></li> | ||
| 2 | -<li ng-message="minlength" translate="messages.invalid.minlength"></li> | ||
| 3 | -<li ng-message="maxlength" translate="messages.invalid.maxlength"></li> | ||
| 4 | -<li ng-message="email" translate="messages.invalid.email"></li> |
src/languages/pt.json
| @@ -121,6 +121,7 @@ | @@ -121,6 +121,7 @@ | ||
| 121 | "account.register.passwordConfirmationLabel": "Confirmar senha", | 121 | "account.register.passwordConfirmationLabel": "Confirmar senha", |
| 122 | "account.register.accountCreatingMessage": "Ao criar uma conta, você está concordando com os ", | 122 | "account.register.accountCreatingMessage": "Ao criar uma conta, você está concordando com os ", |
| 123 | "account.register.termsOfUseMessage": "termos de uso", | 123 | "account.register.termsOfUseMessage": "termos de uso", |
| 124 | + "account.register.termsOfUseTitle": "Termos de uso", | ||
| 124 | "account.register.signupMessage": "Criar Conta", | 125 | "account.register.signupMessage": "Criar Conta", |
| 125 | "account.register.haveAccountMessage": "Já possui uma conta?", | 126 | "account.register.haveAccountMessage": "Já possui uma conta?", |
| 126 | "account.register.success.title": "Bom trabalho!", | 127 | "account.register.success.title": "Bom trabalho!", |
| @@ -151,5 +152,20 @@ | @@ -151,5 +152,20 @@ | ||
| 151 | "tasks.add_friend.message": "quer ser amigo de", | 152 | "tasks.add_friend.message": "quer ser amigo de", |
| 152 | "tasks.add_member.message": "quer entrar em", | 153 | "tasks.add_member.message": "quer entrar em", |
| 153 | "tasks.create_community.message": "quer criar uma nova comunidade:", | 154 | "tasks.create_community.message": "quer criar uma nova comunidade:", |
| 154 | - "tasks.suggest_article.message": "sugeriu um novo artigo:" | 155 | + "tasks.suggest_article.message": "sugeriu um novo artigo:", |
| 156 | + "account.register.save.failed": "A conta não pode ser criada", | ||
| 157 | + "account.register.mandatoryField": "Este campo é obrigatório", | ||
| 158 | + "account.register.invalidEmail": "Este campo deve ser um endereço de e-mail válido.", | ||
| 159 | + "account.register.shortPassword": "A senha deve ter no mínimo 4 caracteres", | ||
| 160 | + "account.register.errorMessagesTitle": "Houve erros com os seguintes campos:", | ||
| 161 | + "email is missing": "email não pode ficar em branco", | ||
| 162 | + "login is missing": "nome de usuário não pode ficar em branco", | ||
| 163 | + "password is missing": "senha não pode ficar em branco", | ||
| 164 | + "login": "nome de usuário", | ||
| 165 | + "has already been taken": "já está sendo usado", | ||
| 166 | + "email": "email", | ||
| 167 | + "identifier": "identificador", | ||
| 168 | + "is not available.": "não está disponível", | ||
| 169 | + "user": "usuário", | ||
| 170 | + "is invalid": "é inválido" | ||
| 155 | } | 171 | } |