Skip to content

Commit 4dfe72d

Browse files
authored
fix login form submission (#622)
2 parents a720262 + a5452b2 commit 4dfe72d

File tree

8 files changed

+1850
-507
lines changed

8 files changed

+1850
-507
lines changed

cypress.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module.exports = defineConfig({
1010
},
1111
},
1212
// increase the default timeout for slower operations
13-
defaultCommandTimeout: 30000,
13+
defaultCommandTimeout: 10000,
1414
// Viewport configuration
1515
viewportWidth: 1280,
1616
viewportHeight: 800,
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// vue-skuilder/cypress/e2e/user-registration.cy.js
2+
describe('User Registration', () => {
3+
it('should allow a new user to register', () => {
4+
// Generate a unique username using timestamp to avoid conflicts
5+
cy.registerUser().then((username) => {
6+
// Wait for the registration process to complete
7+
// You may need to adjust the assertion based on what indicates successful registration in your app
8+
cy.url().should('include', `/u/${username}/new`);
9+
10+
// Additional assertions to verify that the user is logged in
11+
// For example, check if a profile element or welcome message is visible
12+
cy.contains(`Welcome, ${username}`).should('be.visible');
13+
14+
// Navigate to the home page and verify that the user's username is displayed
15+
cy.visit('/');
16+
cy.reload();
17+
cy.contains('.v-chip', username);
18+
});
19+
});
20+
21+
it('should prevent registration with an existing username', () => {
22+
cy.visit('/');
23+
cy.contains('Sign Up').click();
24+
25+
// Use a username that you know already exists
26+
const existingUsername = 'Colin'; // Replace with a username that exists in your system
27+
const password = 'password123';
28+
29+
// Fill out the registration form with an existing username
30+
cy.get('input[name="username"]').type(existingUsername);
31+
cy.get('input[name="password"]').type(password);
32+
cy.get('input[name="retypedPassword"]').type(password);
33+
34+
// Submit the form
35+
cy.contains('button', 'Create Account').click();
36+
37+
// Assert that an error message is displayed
38+
cy.contains('The name ' + existingUsername + ' is taken!').should('be.visible');
39+
40+
// Assert that we're still on the registration page
41+
cy.url().should('not.include', `/u/${existingUsername}`);
42+
});
43+
44+
it('should validate that passwords match', () => {
45+
cy.visit('/');
46+
cy.contains('Sign Up').click();
47+
48+
const username = `testuser${Date.now()}`;
49+
const password = 'password123';
50+
const differentPassword = 'different123';
51+
52+
// Fill out the form with non-matching passwords
53+
cy.get('input[name="username"]').type(username);
54+
cy.get('input[name="password"]').type(password);
55+
cy.get('input[name="retypedPassword"]').type(differentPassword);
56+
57+
// Submit the form
58+
cy.contains('button', 'Create Account').click();
59+
60+
// Assert that we're still on the registration page
61+
cy.url().should('not.include', `/u/${username}`);
62+
63+
// Assert that an error message about password mismatch is displayed
64+
cy.contains('Passwords do not match').should('be.visible');
65+
});
66+
67+
it('should not render Signup form if logged in', () => {
68+
cy.registerUser().then(() => {
69+
cy.visit('/signup');
70+
cy.url().should('include', '/signup');
71+
72+
// Check that the signup form is not displayed
73+
cy.get('input[name="username"]').should('not.exist');
74+
cy.get('input[name="password"]').should('not.exist');
75+
cy.get('input[name="retypedPassword"]').should('not.exist');
76+
77+
// Alternative approach - check for any input field
78+
cy.get('form input').should('not.exist');
79+
80+
// Check that some logged-in state indicator is present instead
81+
cy.contains('Already logged in').should('be.visible');
82+
});
83+
});
84+
});

cypress/support/commands.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,26 @@
1313

1414
// You can read more about custom commands here:
1515
// https://on.cypress.io/custom-commands
16+
17+
Cypress.Commands.add('registerUser', (username = null, password = 'securePassword123') => {
18+
// Generate a unique username if none provided
19+
const finalUsername = username || `testuser${Date.now()}`;
20+
21+
// Visit the signup page
22+
cy.visit('/');
23+
cy.contains('Sign Up').click();
24+
25+
// Fill out the registration form
26+
cy.get('input[name="username"]').type(finalUsername);
27+
cy.get('input[name="password"]').type(password);
28+
cy.get('input[name="retypedPassword"]').type(password);
29+
30+
// Submit the form
31+
cy.contains('button', 'Create Account').click();
32+
33+
// Wait for registration to complete
34+
cy.url().should('include', `/u/${finalUsername}/new`);
35+
36+
// Return the created username so it can be used in tests
37+
return cy.wrap(finalUsername);
38+
});

packages/vue/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
"@vitest/ui": "3.0.5",
7171
"@vue/eslint-config-typescript": "^14.4.0",
7272
"@vue/runtime-dom": "^3.5.13",
73-
"@vue/test-utils": "^2.0.0",
73+
"@vue/test-utils": "^2.4.6",
7474
"@vue/vue3-jest": "^29.2.6",
7575
"@vuetify/loader-shared": "^2.1.0",
7676
"assert": "^2.1.0",

packages/vue/src/components/UserRegistration.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
<v-card-title v-if="!registrationRoute" class="text-h5 bg-grey-lighten-2"> Create an Account </v-card-title>
44

55
<v-card-text>
6-
<v-form onsubmit="return false;">
6+
<v-form @submit.prevent="createUser">
77
<v-text-field
88
id=""
99
ref="userNameTextField"
1010
v-model="username"
1111
autofocus
12-
name="name"
12+
name="username"
1313
label="Choose a Username"
1414
prepend-icon="mdi-account-circle"
1515
:error="usernameError"
@@ -19,7 +19,7 @@
1919
<v-text-field
2020
v-model="password"
2121
prepend-icon="mdi-lock"
22-
name="name"
22+
name="password"
2323
hover="Show password"
2424
label="Create a password"
2525
hint=""
@@ -31,7 +31,7 @@
3131
<v-text-field
3232
v-model="retypedPassword"
3333
prepend-icon="mdi-lock"
34-
name="name"
34+
name="retypedPassword"
3535
hover="Show password"
3636
label="Retype your password"
3737
hint=""
@@ -47,7 +47,7 @@
4747
Username or password was incorrect.
4848
<v-btn color="pink" variant="text" @click="badLoginAttempt = false"> Close </v-btn>
4949
</v-snackbar>
50-
<v-btn class="mr-2" type="submit" :loading="awaitingResponse" :color="buttonStatus.color" @click="createUser">
50+
<v-btn class="mr-2" type="submit" :loading="awaitingResponse" :color="buttonStatus.color">
5151
<v-icon start>mdi-lock-open</v-icon>
5252
Create Account
5353
</v-btn>
@@ -169,7 +169,7 @@ Author: ${this.author}
169169
this.awaitingResponse = false;
170170
} else {
171171
alertUser({
172-
text: 'Secret join code is not correct.',
172+
text: 'Passwords do not match.',
173173
status: Status.error,
174174
});
175175
this.awaitingResponse = false;

packages/vue/src/views/SignUp.vue

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
<template>
22
<v-container class="d-flex align-center maxWidth">
3-
<user-registration />
3+
<user-registration v-if="!isUserLoggedIn" />
4+
<div v-else>Already logged in! Welcome back!</div>
45
</v-container>
56
</template>
67

78
<script lang="ts">
89
import { defineComponent } from 'vue';
910
import UserRegistration from '@/components/UserRegistration.vue';
11+
import { useAuthStore } from '@/stores/useAuthStore';
1012
1113
export default defineComponent({
1214
name: 'LoginRoute',
1315
1416
components: {
1517
UserRegistration,
1618
},
19+
20+
computed: {
21+
isUserLoggedIn(): boolean {
22+
const authStore = useAuthStore();
23+
return authStore.isLoggedIn;
24+
},
25+
},
1726
});
1827
</script>
1928

packages/vue/src/views/User.vue

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { defineComponent, PropType } from 'vue';
3333
import { User } from '@/db/userDB';
3434
import { useConfigStore } from '@/stores/useConfigStore';
3535
import { getCurrentUser } from '@/stores/useAuthStore';
36+
import { useRoute } from 'vue-router';
3637
3738
interface Language {
3839
name: string;
@@ -51,11 +52,14 @@ export default defineComponent({
5152
5253
setup() {
5354
const configStore = useConfigStore();
55+
const route = useRoute();
5456
5557
const darkMode = configStore.config.darkMode;
5658
const likesConfetti = configStore.config.likesConfetti;
5759
58-
return { configStore, darkMode, likesConfetti };
60+
const isNewUser = route.path.endsWith('new');
61+
62+
return { configStore, darkMode, likesConfetti, route, isNewUser };
5963
},
6064
6165
data() {
@@ -75,15 +79,6 @@ export default defineComponent({
7579
};
7680
},
7781
78-
computed: {
79-
isNewUser(): boolean {
80-
console.error(`Not implemented: User.isNewUser`);
81-
return false;
82-
// [ ] #vue3 - $route not available.
83-
// return this.$route.path.endsWith('new');
84-
},
85-
},
86-
8782
async created() {
8883
this.u = await getCurrentUser();
8984
this.configLanguages.forEach((l) => {

0 commit comments

Comments
 (0)