Gitlab Community Edition Instance

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • j.michal/grady
1 result
Select Git revision
Show changes
Commits on Source (3)
import axios, { AxiosInstance, AxiosResponse } from 'axios'
import { errorInterceptor } from '@/util/interceptor'
import { Credentials } from '@/store/modules/authentication'
import {
Assignment,
......@@ -233,4 +234,6 @@ export async function fetchInstanceExportData (): Promise<InstanceExportData> {
return (await ax.get('/api/instance/export')).data
}
ax.interceptors.response.use(undefined, errorInterceptor);
export default ax
......@@ -135,6 +135,10 @@ export default {
SubmissionNotes.SET_ORIG_FEEDBACK(feedback)
this.$emit('feedbackCreated')
}).catch(err => {
// ignore trivial errors as those are handled
// by an interceptor
if (err.message.includes("Request failed")) return
this.$notify({
title: 'Feedback creation Error!',
text: err.message,
......
......@@ -72,12 +72,17 @@ export default {
submit () {
this.loading = true
Auth.getJWT(this.credentials).then(() => {
Auth.getUser().then(() => {
this.$router.push({ name: 'home' })
})
Auth.getJWTTimeDelta()
return Promise.all([
Auth.getUser(),
Auth.getJWTTimeDelta()
])
}).then(() => {
this.$router.push({ name: 'home' })
this.loading = false
}).catch(() => { this.loading = false })
}).catch((er) => {
Auth.SET_MESSAGE("Login failed. Please try again.")
this.loading = false
})
},
registered (credentials) {
this.registerDialog = false
......
import { AxiosError } from 'axios'
import { AxiosError, AxiosResponse } from 'axios'
import { Dispatch } from 'vuex'
import { MutationHandler } from 'vuex-typex'
......@@ -139,3 +139,35 @@ export function syntaxPostProcess (code: string): string {
})
return code
}
export function parseBlacklist (blacklist: Array<string>): string {
return blacklist.reduce((acc, curr) => {
return acc + "|" + curr
})
}
export function parseErrorNotification (response: AxiosResponse): string {
if (!response.data || Object.keys(response.data).length === 0) {
return 'There is no useful error data. Please ask the staff for help.'
} else {
let msg = "<ul>";
function pickRecursive(obj: any) {
if (obj instanceof Object) {
for (let k of Object.keys(obj)) {
pickRecursive(obj[k])
}
} else {
msg += "<li>" + obj + "</li>"
}
}
pickRecursive(response.data)
msg += "</ul>"
if (response.status === 404) {
msg += "<br/>If you experience unusual behaviour, finish all unfinished work and relog." +
" If not, this is probably not a critical error."
}
return msg
}
}
import instance from '@/main'
import { parseErrorNotification, parseBlacklist } from '@/util/helpers'
const errorUrlBlacklist = [
"/api/get-token/",
]
const blackListRegExp = new RegExp(parseBlacklist(errorUrlBlacklist), "g")
export function errorInterceptor (error: any): any {
// TODO: log errors and store them somewhere
if (error.response.request.responseURL.match(blackListRegExp)) {
return
}
instance.$notify({
title: 'Request failed.',
text: parseErrorNotification(error.response),
type: 'error',
duration: -1
})
return Promise.reject(error)
}
\ No newline at end of file
import * as helpers from "@/util/helpers"
import * as chai from "chai"
import { AxiosResponse } from 'axios';
chai.should();
describe("# Helpers Unit Tests", () => {
describe("# praseBlacklist", () => {
it("should correclty parse the blacklist object into a string that can be used for regex", () => {
const blacklist = ["test", "another", "final"]
const parsed = helpers.parseBlacklist(blacklist)
const testUrl = "https:somehost:someport/api/feedback/final"
const isMatched = testUrl.match(new RegExp(parsed, "g"))
// @ts-ignore
isMatched.should.not.be.null
parsed.should.equal("test|another|final")
})
})
describe("# parseErrorNotification", () => {
it("should return html parsed information about the error if existing", () => {
const response = { data: { someKey: "this is an error message" } }
const parsed = helpers.parseErrorNotification(response as AxiosResponse)
parsed.should.equal("<ul><li>this is an error message</li></ul>")
})
it("should return html parsed list of all values of data object if existing", () => {
const response = {
data: {
someKey: "some debug information",
someOtherKey: "some error information",
someFinalKey: "some response stuff"
}
}
const parsed = helpers.parseErrorNotification(response as AxiosResponse)
const expected = "<ul><li>some debug information</li><li>some error information</li>" +
"<li>some response stuff</li></ul>"
parsed.should.equal(expected)
})
it("should return default message when no error information exists", () => {
const response = { data: {}, someKey: "test" }
const parsed = helpers.parseErrorNotification(response as unknown as AxiosResponse)
parsed.should.equal("There is no useful error data. Please ask the staff for help.")
})
it("should give additional information for 404 requests", () => {
const response = { status: 404, data: { someKey: "Not found." } }
const parsed = helpers.parseErrorNotification(response as AxiosResponse)
parsed.should.include("Not found.")
parsed.should.include("If you experience unusual behaviour, finish all unfinished work and relog." +
" If not, this is probably not a critical error.")
})
})
})
\ No newline at end of file
......@@ -54,8 +54,8 @@ class UntestedParent:
# stage can be 'initial', 'validate', or 'conflict'
def _go_to_subscription(self, stage='initial', sub_type=None):
WebDriverWait(self.browser, 10).until(subscriptions_loaded_cond(self.browser))
tasks = self.browser.find_element_by_name('subscription-list')
WebDriverWait(self.browser, 10).until(subscriptions_loaded_cond(tasks))
tab = tasks.find_element_by_xpath(f'//*[contains(text(), "{stage}")]')
tab.click()
sub_type = sub_type if sub_type is not None else self.sub_type
......
......@@ -47,10 +47,10 @@ class UntestedParent:
def test_available_tasks_are_shown(self):
self._login()
WebDriverWait(self.browser, 10).until(subscriptions_loaded_cond(self.browser))
tasks = self.browser.find_element_by_name('subscription-list')
title = tasks.find_element_by_class_name('v-toolbar__title')
self.assertEqual('Tasks', title.text)
WebDriverWait(self.browser, 10).until(subscriptions_loaded_cond(tasks))
subscription_links = extract_hrefs_hashes(
tasks.find_elements_by_tag_name('a')
)
......
......@@ -8,6 +8,7 @@ from selenium.webdriver.firefox.options import Options
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import StaleElementReferenceException
def create_browser() -> webdriver.Firefox:
......@@ -47,11 +48,17 @@ def extract_hrefs_hashes(web_elements: Sequence[WebElement]):
for el in web_elements if el.get_attribute('href')]
# A function that takes the element corresponding to the tasks
# component and return a function that can be used as a condition for
# A function that takes the a browser client
# and returns a function that can be used as a condition for
# WebDriverWait
def subscriptions_loaded_cond(tasks_el):
def subscriptions_loaded_cond(browser):
def loaded(*args):
sub_links = tasks_el.find_elements_by_tag_name('a')
return any((link != '/home' for link in extract_hrefs_hashes(sub_links)))
for i in range(2):
try:
tasks_el = browser.find_element_by_name('subscription-list')
sub_links = tasks_el.find_elements_by_tag_name('a')
return any((link != '/home' for link in extract_hrefs_hashes(sub_links)))
except StaleElementReferenceException:
pass
return False
return loaded