Skip to content
Snippets Groups Projects
Commit e8a8d9de authored by Erik Borgeteien Hansen's avatar Erik Borgeteien Hansen
Browse files

Merge branch 'main' into register-view

parents 6ac7ec5b 35d96b78
No related branches found
No related tags found
1 merge request!1Register view
Pipeline #174551 passed
# This file is a template, and might need editing before it works on your project.
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
# This is a sample GitLab CI/CD configuration file that should run without any modifications.
# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts,
# it uses echo commands to simulate the pipeline execution.
#
# A pipeline is composed of independent jobs that run scripts, grouped into stages.
# Stages run in sequential order, but jobs within stages run in parallel.
#
# For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages
stages: # List of stages for jobs, and their order of execution
- build
- test
- deploy
build-job: # This job runs in the build stage, which runs first.
stage: build
script:
- echo "Compiling the code..."
- echo "Compile complete."
unit-test-job: # This job runs in the test stage.
stage: test # It only starts when the job in the build stage completes successfully.
script:
- echo "Running unit tests... This will take about 60 seconds."
- sleep 60
- echo "Code coverage is 90%"
lint-test-job: # This job also runs in the test stage.
stage: test # It can run at the same time as unit-test-job (in parallel).
script:
- echo "Linting code... This will take about 10 seconds."
- sleep 10
- echo "No lint issues found."
deploy-job: # This job runs in the deploy stage.
stage: deploy # It only runs when *both* jobs in the test stage complete successfully.
script:
- echo "Deploying application..."
- echo "Application successfully deployed."
<template> <template>
<div class="loginForm"> <div>
<v-img :src="require('../assets/logo3.svg')" class="image" contain /> <v-col
<form @submit.prevent="onSubmit"> align="center"
<div class="inputFields"> justify="space-around"
<div :class="{ error: v$.user.email.$errors.length }"> >
<br /><label class="label" id="emailLabelId">E-post </label><br /> <v-img
<input max-width="45%"
class="loginInputs" :src="require('../assets/logo3.svg')"
type="email" align="center"
v-model="v$.user.email.$model" ></v-img>
/> </v-col>
<!-- error message --> <v-form
<div ref="form"
class="input-errors" v-model="valid"
v-for="(error, index) of v$.user.email.$errors" lazy-validation
:key="index" >
> <v-col>
<div class="error-msg" v-show="showError" id="emailErrorId"> <v-text-field
{{ error.$message }} v-model="user.email"
</div> :rules="emailRules"
</div> label="E-mail"
</div> required
></v-text-field>
<!-- password --> </v-col>
<div :class="{ error: v$.user.password.$errors.length }">
<br /><label class="label" id="passwordLabelId">Passord </label><br />
<input <v-col
class="loginInputs" align="right"
type="password" >
v-model="v$.user.password.$model" <v-text-field
/> v-model="user.password"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
<!-- error message --> :rules="[rules.required, rules.min]"
<div :type="showPassword ? 'text' : 'password'"
class="input-errors" name="input-10-1"
v-for="(error, index) of v$.user.password.$errors" label="Password"
:key="index" counter
> @click:append="showPassword = !showPassword"
<div class="error-msg" v-show="showError" id="passwordErrorId"> ></v-text-field>
{{ error.$message }}
</div> <div class="text-decoration-underline mt-n4 mr-10">
</div> Glemt passord
</div>
<!-- Link to forgot password page will be added here --> </v-col>
<br /><a href="url" id="forgottenPasswordLink">Glemt passord</a>
</div>
</div>
<v-col
<div class="buttonLink"> align="center"
<!-- Submit Button --> justify="space-around"
<div class="buttons-w"> >
<br /><br /><button v-on:click="loginClicked" class="loginButton"> <v-btn
Logg inn :disabled="!valid"
</button> color="success"
class="mb-4 mt-4"
<!-- Link to register new user page will be added here --> width="50%"
<br /><a id="newUserLink" href="url">Ny bruker</a> height="40px"
@click="loginClicked"
<p id="messageUser">{{ message }}</p> >
</div> Logg inn
</div> </v-btn>
</form>
</div> <div>
</template> <a
href="/"
<script> class="text-decoration-none"
import useVuelidate from "@vuelidate/core"; >Ny bruker</a>
import { required, email, minLength, helpers } from "@vuelidate/validators"; </div>
import { doLogin } from "@/utils/apiutil"; </v-col>
import { mapState } from "vuex";
export default {
name: "LoginForm.vue", </v-form>
</div>
setup() {
return { v$: useVuelidate() }; </template>
},
<script>
validations() { import useVuelidate from "@vuelidate/core";
return { import { required, email, minLength, helpers } from "@vuelidate/validators";
user: { import { doLogin } from "@/utils/apiutil";
email: { import { mapState } from "vuex";
required,
email: helpers.withMessage(`E-posten er ugyldig`, email), export default {
}, name: "LoginForm.vue",
password: {
required, setup() {
min: helpers.withMessage( return { v$: useVuelidate() };
({ $params }) => `Passordet må inneholde minst ${$params.min} tegn`, },
minLength(8)
), validations() {
}, return {
}, user: {
}; email: {
}, required,
email: helpers.withMessage(`E-posten er ugyldig`, email),
computed: mapState({ },
token: (state) => state.user.token, password: {
}), required,
min: helpers.withMessage(
data() { ({ $params }) => `Passordet må inneholde minst ${$params.min} tegn`,
return { minLength(8)
message: "", ),
user: { },
email: "", },
password: "", };
}, },
showError: false,
}; computed: mapState({
}, token: (state) => state.user.token,
}),
methods: {
async loginClicked() { data() {
this.showError = true; return {
const loginRequest = { message: "",
email: this.user.email, user: {
password: this.user.password, email: "",
}; password: "",
const loginResponse = await doLogin(loginRequest); },
if (loginResponse === "Failed login") { showPassword: false,
this.message = "kunne ikke logge inn"; valid : true,
this.$store.commit('logout'); emailRules: [
return; v => !!v || 'E-mail is required',
} v => /.+@.+\..+/.test(v) || 'E-mail must be valid',
],
this.$store.commit("saveToken", loginResponse); rules: {
console.log(loginResponse); required: value => !!value || 'Required.',
}, min: v => v.length >= 8 || 'Min 8 characters',
}, },
}; };
</script> },
<style scoped> methods: {
.loginForm { async loginClicked() {
background-color: white; console.log(this.user.email + " " + this.user.password);
border-radius: 10px; this.showError = true;
margin: auto; const loginRequest = {
width: 80%; email: this.user.email,
margin-top: 20%; password: this.user.password,
justify-content: center; };
padding: 10px; const loginResponse = await doLogin(loginRequest);
font-size: 18px;
} if (loginResponse === "Failed login") {
.label { this.message = "kunne ikke logge inn";
float: left; this.$store.commit('logout');
margin-left: 5%; return;
} }
.loginInputs {
background-color: #c4c4c4; this.$store.commit("saveToken", loginResponse);
border-radius: 5px; console.log(loginResponse);
width: 90%; },
height: 40px;
padding: 5px;
} validate () {
.loginButton { this.$refs.form.validate()
width: 55%; },
height: 50px; },
background-color: #1071b8; };
color: white; </script>
border-radius: 10px;
justify-content: center;
text-align: center;
margin: auto;
font-size: 25px;
margin-bottom: 20px;
}
.loginButton:disabled {
opacity: 50%;
cursor: not-allowed;
}
.buttonLink {
margin: auto;
text-align: center;
margin-bottom: 40px;
}
.image {
width: 45%;
margin: auto;
margin-top: 20px;
}
#forgottenPasswordLink {
float: right;
margin: 10px 5% 0 0;
}
#newUserLink {
text-decoration: none;
margin-bottom: 40px;
}
.inputFields {
margin: auto;
text-align: center;
}
.input-errors {
color: red;
}
</style>
import { createRouter, createWebHistory } from "vue-router"; import { createRouter, createWebHistory } from "vue-router";
import HomeView from "../views/HomeView.vue"; import HomeView from "../views/HomeView.vue";
import LoginView from "../views/LoginView.vue";
const routes = [ const routes = [
{ {
...@@ -17,7 +19,6 @@ const routes = [ ...@@ -17,7 +19,6 @@ const routes = [
import(/* webpackChunkName: "about" */ "../views/AboutView.vue"), import(/* webpackChunkName: "about" */ "../views/AboutView.vue"),
}, },
{ {
<<<<<<< HEAD
path: "/register", path: "/register",
name: "register", name: "register",
// route level code-splitting // route level code-splitting
...@@ -25,12 +26,13 @@ const routes = [ ...@@ -25,12 +26,13 @@ const routes = [
// which is lazy-loaded when the route is visited. // which is lazy-loaded when the route is visited.
component: () => component: () =>
import(/* webpackChunkName: "register" */ "../views/RegisterView.vue"), import(/* webpackChunkName: "register" */ "../views/RegisterView.vue"),
=======
path: "/",
name: "loginView",
component: () => import("../views/LoginView.vue"),
>>>>>>> main
}, },
{
path: "/",
name: "login",
component: LoginView,
}
]; ];
const router = createRouter({ const router = createRouter({
......
import { shallowMount } from "@vue/test-utils";
import LoginForm from "@/components/LoginForm";
describe("Tests labels in LoginForm component", () => {
it("checks the E-post label", () => {
const wrapper = shallowMount(LoginForm);
expect(wrapper.find('#emailLabelId').text()).toMatch("E-post");
});
it("checks the password label", () => {
const wrapper = shallowMount(LoginForm);
expect(wrapper.find('#passwordLabelId').text()).toMatch("Passord");
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment