Skip to content
Snippets Groups Projects
Commit 5fe644f4 authored by robinwilliam.hundt's avatar robinwilliam.hundt
Browse files

Better ui for file download

parent 421a5078
Branches
Tags 2.1.0
No related merge requests found
Pipeline #99644 failed
from django.db import transaction
from rest_framework.response import Response
from rest_framework.views import APIView
......@@ -13,8 +15,10 @@ from core.serializers.tutor import TutorSerializer
words = xp.generate_wordlist(wordfile=xp.locate_wordfile(), min_length=5, max_length=8)
@transaction.atomic
def _set_student_passwords():
student_password_dict = {}
# TODO use bulk update with django makepassword function
for student in UserAccount.get_students():
password = xp.generate_xkcdpassword(words, numwords=3, delimiter='-')
student.set_password(password)
......
......@@ -12,13 +12,15 @@
"test:unit": "vue-cli-service test:unit --require mock-local-storage"
},
"dependencies": {
"@types/downloadjs": "^1.4.1",
"axios": "^0.18.0",
"downloadjs": "^1.4.7",
"highlight.js": "^9.12.0",
"v-clipboard": "^2.0.1",
"vue": "^2.5.16",
"vue-class-component": "^6.0.0",
"vue-property-decorator": "^7.3.0",
"vue-notification": "^1.3.12",
"vue-property-decorator": "^7.3.0",
"vue-router": "^3.0.1",
"vuetify": "^1.1.9",
"vuex": "^3.0.1",
......
......@@ -8,12 +8,14 @@
<div v-if="!mapFileLoaded">
If you select a mapping file, the anonymized data
will be mapped back automatically and locally on your machine.
<v-layout row align-center>
<file-select v-model="mapFile" display-text="Select map file" class="ma-3"/>
<span>Without the mapping, the data will still be obfuscated.</span>
</v-layout>
</div>
<span>
<b>NOTE:</b> Mapping / setting passwords can take some time depending on course size.
</span>
<v-layout row>
<v-flex xs4>
<v-tooltip top>
......@@ -42,7 +44,8 @@
@click="exportDialog = false"
>close</v-btn>
<v-spacer/>
<v-btn id="export-data-download-btn" flat outline @click="getExportFile('data')"
<v-progress-circular v-if="loading" indeterminate/>
<v-btn v-else id="export-data-download-btn" flat outline @click="getExportFile('data')"
>{{mapFile || mapFileLoaded ? 'Download and apply mapping' : 'Download without mapping'}}</v-btn>
</v-card-actions>
</v-card-text>
......@@ -66,6 +69,7 @@ export default class DataExport extends mixins(exportMixin) {
mapFile: File | null = null
setPasswords = false
exportType = ExportType.CSV
loading = false
get studentMap () { return getters.state.studentMap }
......@@ -84,18 +88,6 @@ export default class DataExport extends mixins(exportMixin) {
}
})
}
createDownloadPopup (content: string | StudentExportItem[], fileType: ExportType): void {
const blobProperties: BlobPropertyBag = {}
if (fileType === ExportType.JSON) {
blobProperties.type = 'application/json'
content = JSON.stringify(content)
} else {
blobProperties.type = 'text/csv'
}
const blobData = new Blob([<string> content], blobProperties)
window.open(window.URL.createObjectURL(blobData))
}
}
</script>
......
<template>
<div>
<v-menu>
<v-menu offset-y>
<v-tooltip bottom slot="activator">
<v-btn id="export-btn" :color="exportColor" slot="activator">
export
......
......@@ -8,19 +8,22 @@
<div v-if="!mapFileLoaded">
If you select a mapping file, the anonymized data
will be mapped back automatically and locally on your machine.
<v-layout row align-center>
<file-select v-model="mapFile" display-text="Select map file" class="ma-3"/>
<span>Without the mapping, the data will still be obfuscated.</span>
</v-layout>
</div>
<span>
<b>NOTE:</b> Mapping can take some time depending on course size.
</span>
<v-card-actions>
<v-btn
flat color="blue lighten-2"
@click="exportDialog = false"
>close</v-btn>
<v-spacer/>
<v-btn id="instance-export-dl" flat outline @click="getExportFile('instance')"
<v-progress-circular v-if="loading" indeterminate/>
<v-btn v-else id="instance-export-dl" flat outline @click="getExportFile('instance')"
>{{mapFile || mapFileLoaded ? 'Download and apply mapping' : 'Download without mapping'}}</v-btn>
</v-card-actions>
</v-card-text>
......@@ -43,6 +46,7 @@ export default class DataExport extends mixins(exportMixin) {
exportDialog = true
mapFile: File | null = null
exportType = ExportType.JSON // instance export is only available as JSON
loading = false
get studentMap () { return getters.state.studentMap }
......@@ -62,14 +66,6 @@ export default class DataExport extends mixins(exportMixin) {
}
})
}
createDownloadPopup (content: string | InstanceExportData): void {
const blobProperties: BlobPropertyBag = {}
blobProperties.type = 'application/json'
content = JSON.stringify(content)
const blobData = new Blob([<string> content], blobProperties)
window.open(window.URL.createObjectURL(blobData))
}
}
</script>
......
......@@ -4,10 +4,17 @@ import { fetchStudentExportData, StudentExportItem, InstanceExportData, fetchIns
import { getters } from '@/store/getters'
import { mutations as mut } from '@/store/mutations'
import parseCSVMapMixin from '@/components/mixins/parseCSVMapMixin'
import originalDownload from 'downloadjs'
let download = originalDownload;
export enum ExportType {
JSON = 'JSON',
CSV = 'CSV'
JSON = 'application/json',
CSV = 'text/csv'
}
export function mock(mockedDownload?: () => boolean) {
download = mockedDownload || originalDownload
}
@Component
......@@ -16,6 +23,7 @@ export class exportMixin extends mixins(Vue, parseCSVMapMixin) {
mapFile: File | null = null
setPasswords = false
exportType = ExportType.CSV
loading = false
get mapFileLoaded () {
return Object.keys(getters.state.studentMap).length > 0
......@@ -26,6 +34,8 @@ export class exportMixin extends mixins(Vue, parseCSVMapMixin) {
}
async getExportFile (type: string) {
this.loading = true
let studentData
if (type === 'data') {
studentData = await fetchStudentExportData({ setPasswords: this.setPasswords })
......@@ -76,10 +86,11 @@ export class exportMixin extends mixins(Vue, parseCSVMapMixin) {
optionalConvertAndCreatePopup (studentData: StudentExportItem[] | InstanceExportData) {
const convertedData = this.exportType === ExportType.CSV
? this.jsonToCSV(studentData as StudentExportItem[]) : studentData
? this.jsonToCSV(studentData as StudentExportItem[]) : JSON.stringify(studentData)
// we have a cast here because only student export may be converted to csv
this.createDownloadPopup(convertedData, this.exportType)
const filename = this.exportType === ExportType.CSV ? 'export.csv' : 'export.json'
download(convertedData, filename, this.exportType)
this.loading = false
}
async getMappedExportFile (studentData: StudentExportItem[] | InstanceExportData) {
......@@ -126,5 +137,4 @@ export class exportMixin extends mixins(Vue, parseCSVMapMixin) {
}
applyMapping (exportData: StudentExportItem[] | InstanceExportData): void { throw new Error('Not implemented.') }
createDownloadPopup (content: string | StudentExportItem[] | InstanceExportData, fileType: ExportType): void { throw new Error('Not implemented.') }
}
......@@ -8,6 +8,7 @@ import VueRouter from 'vue-router'
import testUtils from '@/../tests/utils/testUtils'
import * as api from '@/api'
import { mock } from '@/components/mixins/exportMixin';
chai.should()
let localVue = createLocalVue()
......@@ -51,11 +52,11 @@ describe('DataExport Component Unit Tests', () => {
let spy = sinon.spy()
// @ts-ignore
sinon.replace(wrapper.vm, 'jsonToCSV', spy)
// @ts-ignore
sinon.replace(wrapper.vm, 'createDownloadPopup', sinon.spy())
mock(spy)
// @ts-ignore
wrapper.vm.optionalConvertAndCreatePopup(testUtils.studentExports)
spy.called.should.equal(true)
mock()
})
it('should download JSON when selected', () => {
let wrapper = mount(DataExport, { localVue: localVue, store })
......@@ -63,11 +64,11 @@ describe('DataExport Component Unit Tests', () => {
let spy = sinon.spy()
// @ts-ignore
sinon.replace(wrapper.vm, 'jsonToCSV', spy)
// @ts-ignore
sinon.replace(wrapper.vm, 'createDownloadPopup', sinon.spy())
mock(() => { return true })
// @ts-ignore
wrapper.vm.optionalConvertAndCreatePopup(testUtils.studentExports)
spy.called.should.equal(false)
mock()
})
it('should download obfuscated data when no mapping was selected', async () => {
let wrapper = mount(DataExport, { localVue: localVue, store })
......
import { ExportType, exportMixin } from '@/components/mixins/exportMixin'
import { ExportType, exportMixin, mock } from '@/components/mixins/exportMixin'
import sinon from 'sinon'
import ax from '@/api'
import testUtils, { FakeFileReader } from '@/../tests/utils/testUtils'
......@@ -59,10 +59,11 @@ describe('Export Mixin Unit Tests', () => {
let spy = sinon.spy()
e.exportType = ExportType.CSV
sinon.replace(e, 'jsonToCSV', stub)
sinon.replace(e, 'createDownloadPopup', spy)
mock(spy)
e.optionalConvertAndCreatePopup(testUtils.studentExports)
stub.calledWith(testUtils.studentExports).should.equal(true)
spy.calledWith('students as csv', ExportType.CSV).should.equal(true)
spy.calledWith('students as csv', 'export.csv', ExportType.CSV).should.equal(true)
mock()
})
})
describe('readMapFileAndCommit', () => {
......
......@@ -140,6 +140,11 @@
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a"
integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==
"@types/downloadjs@^1.4.1":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@types/downloadjs/-/downloadjs-1.4.1.tgz#11a959c5fd09d3f1ca74c02ba17ae8f126ce57fd"
integrity sha512-Y7Ds+ne3AMvNY9TB055NCOoFewlmEpRpGGyNaPu1lw6a0reLHWESZ8KLVDBfdOvlwDUBWWQVcijkCJaoysDC4Q==
"@types/highlight.js@^9.12.3":
version "9.12.3"
resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.12.3.tgz#b672cfaac25cbbc634a0fd92c515f66faa18dbca"
......@@ -2335,6 +2340,11 @@ dot-prop@^4.1.1:
dependencies:
is-obj "^1.0.0"
downloadjs@^1.4.7:
version "1.4.7"
resolved "https://registry.yarnpkg.com/downloadjs/-/downloadjs-1.4.7.tgz#f69f96f940e0d0553dac291139865a3cd0101e3c"
integrity sha1-9p+W+UDg0FU9rCkROYZaPNAQHjw=
duplexer@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
......
export.json
export.csv
import json
import os
from django.test import LiveServerTestCase
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from core.models import UserAccount
from functional_tests.util import login, create_browser, reset_browser_after_test
from util import factory_boys as fact
def expect_file_to_be_present(path):
def condition(*args):
try:
with open(path):
pass
except FileNotFoundError:
return False
return True
return condition
JSON_EXPORT_FILE = os.path.join(os.path.dirname(__file__), 'export.json')
class ExportTestModal(LiveServerTestCase):
browser: webdriver.Firefox = None
username = None
......@@ -61,7 +77,7 @@ class ExportTestModal(LiveServerTestCase):
exports_btn = self.browser.find_element_by_id('export-btn')
self.assertIn('green', exports_btn.get_attribute('class'))
def test_export_allgood_tooltip_all_corrected(self):
def test_export_all_good_tooltip_all_corrected(self):
self._login()
tooltip_corrected = self.browser.find_element_by_id('corrected-tooltip')
self.assertNotEqual(None, tooltip_corrected)
......@@ -90,16 +106,15 @@ class ExportTestModal(LiveServerTestCase):
data_export_modal = self.browser.find_element_by_id('data-export-modal')
export_type_select = data_export_modal.find_element_by_id('type-select')
export_type_select.click()
export_type_json = data_export_modal.find_element_by_xpath("//*[contains(text(), 'JSON')]")
export_type_json = data_export_modal.find_element_by_xpath("//*[contains(text(), 'json')]")
export_type_json.click()
data_export_btn = data_export_modal.find_element_by_id('export-data-download-btn')
before_click_handles = self.browser.window_handles
data_export_btn.click()
WebDriverWait(self.browser, 10).until(ec.new_window_is_opened(before_click_handles))
tabs = self.browser.window_handles
self.assertEqual(2, len(tabs))
self.browser.switch_to.window(tabs[1])
self.assertIn('B.Inf.4242 Test Module', self.browser.find_element_by_tag_name('body').text)
WebDriverWait(self.browser, 10).until(expect_file_to_be_present(JSON_EXPORT_FILE))
with open(JSON_EXPORT_FILE) as f:
data = json.load(f)
self.assertEqual('B.Inf.4242 Test Module', data[0]['Exam'])
os.remove(JSON_EXPORT_FILE)
def test_export_instance(self):
self._login()
......@@ -110,10 +125,9 @@ class ExportTestModal(LiveServerTestCase):
export_instance.click()
instance_export_modal = self.browser.find_element_by_id('instance-export-modal')
instance_export_btn = instance_export_modal.find_element_by_id('instance-export-dl')
before_click_handles = self.browser.window_handles
instance_export_btn.click()
WebDriverWait(self.browser, 10).until(ec.new_window_is_opened(before_click_handles))
after_click_handles = self.browser.window_handles
self.assertEqual(2, len(after_click_handles))
self.browser.switch_to.window(after_click_handles[1])
self.assertIn('B.Inf.4242 Test Module', self.browser.find_element_by_tag_name('body').text)
WebDriverWait(self.browser, 10).until(expect_file_to_be_present(JSON_EXPORT_FILE))
with open(JSON_EXPORT_FILE) as f:
data = json.load(f)
self.assertEqual('B.Inf.4242 Test Module', data['examTypes'][0]['moduleReference'])
os.remove(JSON_EXPORT_FILE)
......@@ -3,6 +3,7 @@ from itertools import islice
from typing import Sequence
from selenium import webdriver
from selenium.webdriver import FirefoxProfile
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.remote.webelement import WebElement
......@@ -14,7 +15,13 @@ from selenium.common.exceptions import StaleElementReferenceException
def create_browser() -> webdriver.Firefox:
options = Options()
options.headless = bool(os.environ.get('HEADLESS_TESTS', False))
browser = webdriver.Firefox(options=options)
profile = FirefoxProfile()
profile.set_preference("browser.download.folderList", 2)
profile.set_preference("browser.download.dir", os.path.dirname(__file__))
profile.set_preference("browser.download.useDownloadDir", True)
profile.set_preference("browser.download.panel.shown", False)
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", 'application/vnd.hzn-3d-crossword;video/3gpp;video/3gpp2;application/vnd.mseq;application/vnd.3m.post-it-notes;application/vnd.3gpp.pic-bw-large;application/vnd.3gpp.pic-bw-small;application/vnd.3gpp.pic-bw-var;application/vnd.3gp2.tcap;application/x-7z-compressed;application/x-abiword;application/x-ace-compressed;application/vnd.americandynamics.acc;application/vnd.acucobol;application/vnd.acucorp;audio/adpcm;application/x-authorware-bin;application/x-athorware-map;application/x-authorware-seg;application/vnd.adobe.air-application-installer-package+zip;application/x-shockwave-flash;application/vnd.adobe.fxp;application/pdf;application/vnd.cups-ppd;application/x-director;applicaion/vnd.adobe.xdp+xml;application/vnd.adobe.xfdf;audio/x-aac;application/vnd.ahead.space;application/vnd.airzip.filesecure.azf;application/vnd.airzip.filesecure.azs;application/vnd.amazon.ebook;application/vnd.amiga.ami;applicatin/andrew-inset;application/vnd.android.package-archive;application/vnd.anser-web-certificate-issue-initiation;application/vnd.anser-web-funds-transfer-initiation;application/vnd.antix.game-component;application/vnd.apple.installe+xml;application/applixware;application/vnd.hhe.lesson-player;application/vnd.aristanetworks.swi;text/x-asm;application/atomcat+xml;application/atomsvc+xml;application/atom+xml;application/pkix-attr-cert;audio/x-aiff;video/x-msvieo;application/vnd.audiograph;image/vnd.dxf;model/vnd.dwf;text/plain-bas;application/x-bcpio;application/octet-stream;image/bmp;application/x-bittorrent;application/vnd.rim.cod;application/vnd.blueice.multipass;application/vnd.bm;application/x-sh;image/prs.btif;application/vnd.businessobjects;application/x-bzip;application/x-bzip2;application/x-csh;text/x-c;application/vnd.chemdraw+xml;text/css;chemical/x-cdx;chemical/x-cml;chemical/x-csml;application/vn.contact.cmsg;application/vnd.claymore;application/vnd.clonk.c4group;image/vnd.dvb.subtitle;application/cdmi-capability;application/cdmi-container;application/cdmi-domain;application/cdmi-object;application/cdmi-queue;applicationvnd.cluetrust.cartomobile-config;application/vnd.cluetrust.cartomobile-config-pkg;image/x-cmu-raster;model/vnd.collada+xml;text/csv;application/mac-compactpro;application/vnd.wap.wmlc;image/cgm;x-conference/x-cooltalk;image/x-cmx;application/vnd.xara;application/vnd.cosmocaller;application/x-cpio;application/vnd.crick.clicker;application/vnd.crick.clicker.keyboard;application/vnd.crick.clicker.palette;application/vnd.crick.clicker.template;application/vn.crick.clicker.wordbank;application/vnd.criticaltools.wbs+xml;application/vnd.rig.cryptonote;chemical/x-cif;chemical/x-cmdf;application/cu-seeme;application/prs.cww;text/vnd.curl;text/vnd.curl.dcurl;text/vnd.curl.mcurl;text/vnd.crl.scurl;application/vnd.curl.car;application/vnd.curl.pcurl;application/vnd.yellowriver-custom-menu;application/dssc+der;application/dssc+xml;application/x-debian-package;audio/vnd.dece.audio;image/vnd.dece.graphic;video/vnd.dec.hd;video/vnd.dece.mobile;video/vnd.uvvu.mp4;video/vnd.dece.pd;video/vnd.dece.sd;video/vnd.dece.video;application/x-dvi;application/vnd.fdsn.seed;application/x-dtbook+xml;application/x-dtbresource+xml;application/vnd.dvb.ait;applcation/vnd.dvb.service;audio/vnd.digital-winds;image/vnd.djvu;application/xml-dtd;application/vnd.dolby.mlp;application/x-doom;application/vnd.dpgraph;audio/vnd.dra;application/vnd.dreamfactory;audio/vnd.dts;audio/vnd.dts.hd;imag/vnd.dwg;application/vnd.dynageo;application/ecmascript;application/vnd.ecowin.chart;image/vnd.fujixerox.edmics-mmr;image/vnd.fujixerox.edmics-rlc;application/exi;application/vnd.proteus.magazine;application/epub+zip;message/rfc82;application/vnd.enliven;application/vnd.is-xpr;image/vnd.xiff;application/vnd.xfdl;application/emma+xml;application/vnd.ezpix-album;application/vnd.ezpix-package;image/vnd.fst;video/vnd.fvt;image/vnd.fastbidsheet;application/vn.denovo.fcselayout-link;video/x-f4v;video/x-flv;image/vnd.fpx;image/vnd.net-fpx;text/vnd.fmi.flexstor;video/x-fli;application/vnd.fluxtime.clip;application/vnd.fdf;text/x-fortran;application/vnd.mif;application/vnd.framemaker;imae/x-freehand;application/vnd.fsc.weblaunch;application/vnd.frogans.fnc;application/vnd.frogans.ltf;application/vnd.fujixerox.ddd;application/vnd.fujixerox.docuworks;application/vnd.fujixerox.docuworks.binder;application/vnd.fujitu.oasys;application/vnd.fujitsu.oasys2;application/vnd.fujitsu.oasys3;application/vnd.fujitsu.oasysgp;application/vnd.fujitsu.oasysprs;application/x-futuresplash;application/vnd.fuzzysheet;image/g3fax;application/vnd.gmx;model/vn.gtw;application/vnd.genomatix.tuxedo;application/vnd.geogebra.file;application/vnd.geogebra.tool;model/vnd.gdl;application/vnd.geometry-explorer;application/vnd.geonext;application/vnd.geoplan;application/vnd.geospace;applicatio/x-font-ghostscript;application/x-font-bdf;application/x-gtar;application/x-texinfo;application/x-gnumeric;application/vnd.google-earth.kml+xml;application/vnd.google-earth.kmz;application/vnd.grafeq;image/gif;text/vnd.graphviz;aplication/vnd.groove-account;application/vnd.groove-help;application/vnd.groove-identity-message;application/vnd.groove-injector;application/vnd.groove-tool-message;application/vnd.groove-tool-template;application/vnd.groove-vcar;video/h261;video/h263;video/h264;application/vnd.hp-hpid;application/vnd.hp-hps;application/x-hdf;audio/vnd.rip;application/vnd.hbci;application/vnd.hp-jlyt;application/vnd.hp-pcl;application/vnd.hp-hpgl;application/vnd.yamaha.h-script;application/vnd.yamaha.hv-dic;application/vnd.yamaha.hv-voice;application/vnd.hydrostatix.sof-data;application/hyperstudio;application/vnd.hal+xml;text/html;application/vnd.ibm.rights-management;application/vnd.ibm.securecontainer;text/calendar;application/vnd.iccprofile;image/x-icon;application/vnd.igloader;image/ief;application/vnd.immervision-ivp;application/vnd.immervision-ivu;application/reginfo+xml;text/vnd.in3d.3dml;text/vnd.in3d.spot;mode/iges;application/vnd.intergeo;application/vnd.cinderella;application/vnd.intercon.formnet;application/vnd.isac.fcs;application/ipfix;application/pkix-cert;application/pkixcmp;application/pkix-crl;application/pkix-pkipath;applicaion/vnd.insors.igm;application/vnd.ipunplugged.rcprofile;application/vnd.irepository.package+xml;text/vnd.sun.j2me.app-descriptor;application/java-archive;application/java-vm;application/x-java-jnlp-file;application/java-serializd-object;text/x-java-source,java;application/javascript;application/json;application/vnd.joost.joda-archive;video/jpm;image/jpeg;video/jpeg;application/vnd.kahootz;application/vnd.chipnuts.karaoke-mmd;application/vnd.kde.karbon;aplication/vnd.kde.kchart;application/vnd.kde.kformula;application/vnd.kde.kivio;application/vnd.kde.kontour;application/vnd.kde.kpresenter;application/vnd.kde.kspread;application/vnd.kde.kword;application/vnd.kenameaapp;applicatin/vnd.kidspiration;application/vnd.kinar;application/vnd.kodak-descriptor;application/vnd.las.las+xml;application/x-latex;application/vnd.llamagraphics.life-balance.desktop;application/vnd.llamagraphics.life-balance.exchange+xml;application/vnd.jam;application/vnd.lotus-1-2-3;application/vnd.lotus-approach;application/vnd.lotus-freelance;application/vnd.lotus-notes;application/vnd.lotus-organizer;application/vnd.lotus-screencam;application/vnd.lotus-wordro;audio/vnd.lucent.voice;audio/x-mpegurl;video/x-m4v;application/mac-binhex40;application/vnd.macports.portpkg;application/vnd.osgeo.mapguide.package;application/marc;application/marcxml+xml;application/mxf;application/vnd.wolfrm.player;application/mathematica;application/mathml+xml;application/mbox;application/vnd.medcalcdata;application/mediaservercontrol+xml;application/vnd.mediastation.cdkey;application/vnd.mfer;application/vnd.mfmp;model/mesh;appliation/mads+xml;application/mets+xml;application/mods+xml;application/metalink4+xml;application/vnd.ms-powerpoint.template.macroenabled.12;application/vnd.ms-word.document.macroenabled.12;application/vnd.ms-word.template.macroenabed.12;application/vnd.mcd;application/vnd.micrografx.flo;application/vnd.micrografx.igx;application/vnd.eszigno3+xml;application/x-msaccess;video/x-ms-asf;application/x-msdownload;application/vnd.ms-artgalry;application/vnd.ms-ca-compressed;application/vnd.ms-ims;application/x-ms-application;application/x-msclip;image/vnd.ms-modi;application/vnd.ms-fontobject;application/vnd.ms-excel;application/vnd.ms-excel.addin.macroenabled.12;application/vnd.ms-excelsheet.binary.macroenabled.12;application/vnd.ms-excel.template.macroenabled.12;application/vnd.ms-excel.sheet.macroenabled.12;application/vnd.ms-htmlhelp;application/x-mscardfile;application/vnd.ms-lrm;application/x-msmediaview;aplication/x-msmoney;application/vnd.openxmlformats-officedocument.presentationml.presentation;application/vnd.openxmlformats-officedocument.presentationml.slide;application/vnd.openxmlformats-officedocument.presentationml.slideshw;application/vnd.openxmlformats-officedocument.presentationml.template;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;application/vnd.openxmlformats-officedocument.spreadsheetml.template;application/vnd.openxmformats-officedocument.wordprocessingml.document;application/vnd.openxmlformats-officedocument.wordprocessingml.template;application/x-msbinder;application/vnd.ms-officetheme;application/onenote;audio/vnd.ms-playready.media.pya;vdeo/vnd.ms-playready.media.pyv;application/vnd.ms-powerpoint;application/vnd.ms-powerpoint.addin.macroenabled.12;application/vnd.ms-powerpoint.slide.macroenabled.12;application/vnd.ms-powerpoint.presentation.macroenabled.12;appliation/vnd.ms-powerpoint.slideshow.macroenabled.12;application/vnd.ms-project;application/x-mspublisher;application/x-msschedule;application/x-silverlight-app;application/vnd.ms-pki.stl;application/vnd.ms-pki.seccat;application/vn.visio;video/x-ms-wm;audio/x-ms-wma;audio/x-ms-wax;video/x-ms-wmx;application/x-ms-wmd;application/vnd.ms-wpl;application/x-ms-wmz;video/x-ms-wmv;video/x-ms-wvx;application/x-msmetafile;application/x-msterminal;application/msword;application/x-mswrite;application/vnd.ms-works;application/x-ms-xbap;application/vnd.ms-xpsdocument;audio/midi;application/vnd.ibm.minipay;application/vnd.ibm.modcap;application/vnd.jcp.javame.midlet-rms;application/vnd.tmobile-ivetv;application/x-mobipocket-ebook;application/vnd.mobius.mbk;application/vnd.mobius.dis;application/vnd.mobius.plc;application/vnd.mobius.mqy;application/vnd.mobius.msl;application/vnd.mobius.txf;application/vnd.mobius.daf;tex/vnd.fly;application/vnd.mophun.certificate;application/vnd.mophun.application;video/mj2;audio/mpeg;video/vnd.mpegurl;video/mpeg;application/mp21;audio/mp4;video/mp4;application/mp4;application/vnd.apple.mpegurl;application/vnd.msician;application/vnd.muvee.style;application/xv+xml;application/vnd.nokia.n-gage.data;application/vnd.nokia.n-gage.symbian.install;application/x-dtbncx+xml;application/x-netcdf;application/vnd.neurolanguage.nlu;application/vnd.na;application/vnd.noblenet-directory;application/vnd.noblenet-sealer;application/vnd.noblenet-web;application/vnd.nokia.radio-preset;application/vnd.nokia.radio-presets;text/n3;application/vnd.novadigm.edm;application/vnd.novadim.edx;application/vnd.novadigm.ext;application/vnd.flographit;audio/vnd.nuera.ecelp4800;audio/vnd.nuera.ecelp7470;audio/vnd.nuera.ecelp9600;application/oda;application/ogg;audio/ogg;video/ogg;application/vnd.oma.dd2+xml;applicatin/vnd.oasis.opendocument.text-web;application/oebps-package+xml;application/vnd.intu.qbo;application/vnd.openofficeorg.extension;application/vnd.yamaha.openscoreformat;audio/webm;video/webm;application/vnd.oasis.opendocument.char;application/vnd.oasis.opendocument.chart-template;application/vnd.oasis.opendocument.database;application/vnd.oasis.opendocument.formula;application/vnd.oasis.opendocument.formula-template;application/vnd.oasis.opendocument.grapics;application/vnd.oasis.opendocument.graphics-template;application/vnd.oasis.opendocument.image;application/vnd.oasis.opendocument.image-template;application/vnd.oasis.opendocument.presentation;application/vnd.oasis.opendocumen.presentation-template;application/vnd.oasis.opendocument.spreadsheet;application/vnd.oasis.opendocument.spreadsheet-template;application/vnd.oasis.opendocument.text;application/vnd.oasis.opendocument.text-master;application/vnd.asis.opendocument.text-template;image/ktx;application/vnd.sun.xml.calc;application/vnd.sun.xml.calc.template;application/vnd.sun.xml.draw;application/vnd.sun.xml.draw.template;application/vnd.sun.xml.impress;application/vnd.sun.xl.impress.template;application/vnd.sun.xml.math;application/vnd.sun.xml.writer;application/vnd.sun.xml.writer.global;application/vnd.sun.xml.writer.template;application/x-font-otf;application/vnd.yamaha.openscoreformat.osfpvg+xml;application/vnd.osgi.dp;application/vnd.palm;text/x-pascal;application/vnd.pawaafile;application/vnd.hp-pclxl;application/vnd.picsel;image/x-pcx;image/vnd.adobe.photoshop;application/pics-rules;image/x-pict;application/x-chat;aplication/pkcs10;application/x-pkcs12;application/pkcs7-mime;application/pkcs7-signature;application/x-pkcs7-certreqresp;application/x-pkcs7-certificates;application/pkcs8;application/vnd.pocketlearn;image/x-portable-anymap;image/-portable-bitmap;application/x-font-pcf;application/font-tdpfr;application/x-chess-pgn;image/x-portable-graymap;image/png;image/x-portable-pixmap;application/pskc+xml;application/vnd.ctc-posml;application/postscript;application/xfont-type1;application/vnd.powerbuilder6;application/pgp-encrypted;application/pgp-signature;application/vnd.previewsystems.box;application/vnd.pvi.ptid1;application/pls+xml;application/vnd.pg.format;application/vnd.pg.osasli;tex/prs.lines.tag;application/x-font-linux-psf;application/vnd.publishare-delta-tree;application/vnd.pmi.widget;application/vnd.quark.quarkxpress;application/vnd.epson.esf;application/vnd.epson.msf;application/vnd.epson.ssf;applicaton/vnd.epson.quickanime;application/vnd.intu.qfx;video/quicktime;application/x-rar-compressed;audio/x-pn-realaudio;audio/x-pn-realaudio-plugin;application/rsd+xml;application/vnd.rn-realmedia;application/vnd.realvnc.bed;applicatin/vnd.recordare.musicxml;application/vnd.recordare.musicxml+xml;application/relax-ng-compact-syntax;application/vnd.data-vision.rdz;application/rdf+xml;application/vnd.cloanto.rp9;application/vnd.jisp;application/rtf;text/richtex;application/vnd.route66.link66+xml;application/rss+xml;application/shf+xml;application/vnd.sailingtracker.track;image/svg+xml;application/vnd.sus-calendar;application/sru+xml;application/set-payment-initiation;application/set-reistration-initiation;application/vnd.sema;application/vnd.semd;application/vnd.semf;application/vnd.seemail;application/x-font-snf;application/scvp-vp-request;application/scvp-vp-response;application/scvp-cv-request;application/svp-cv-response;application/sdp;text/x-setext;video/x-sgi-movie;application/vnd.shana.informed.formdata;application/vnd.shana.informed.formtemplate;application/vnd.shana.informed.interchange;application/vnd.shana.informed.package;application/thraud+xml;application/x-shar;image/x-rgb;application/vnd.epson.salt;application/vnd.accpac.simply.aso;application/vnd.accpac.simply.imp;application/vnd.simtech-mindmapper;application/vnd.commonspace;application/vnd.ymaha.smaf-audio;application/vnd.smaf;application/vnd.yamaha.smaf-phrase;application/vnd.smart.teacher;application/vnd.svd;application/sparql-query;application/sparql-results+xml;application/srgs;application/srgs+xml;application/sml+xml;application/vnd.koan;text/sgml;application/vnd.stardivision.calc;application/vnd.stardivision.draw;application/vnd.stardivision.impress;application/vnd.stardivision.math;application/vnd.stardivision.writer;application/vnd.tardivision.writer-global;application/vnd.stepmania.stepchart;application/x-stuffit;application/x-stuffitx;application/vnd.solent.sdkm+xml;application/vnd.olpc-sugar;audio/basic;application/vnd.wqd;application/vnd.symbian.install;application/smil+xml;application/vnd.syncml+xml;application/vnd.syncml.dm+wbxml;application/vnd.syncml.dm+xml;application/x-sv4cpio;application/x-sv4crc;application/sbml+xml;text/tab-separated-values;image/tiff;application/vnd.to.intent-module-archive;application/x-tar;application/x-tcl;application/x-tex;application/x-tex-tfm;application/tei+xml;text/plain;application/vnd.spotfire.dxp;application/vnd.spotfire.sfs;application/timestamped-data;applicationvnd.trid.tpt;application/vnd.triscape.mxs;text/troff;application/vnd.trueapp;application/x-font-ttf;text/turtle;application/vnd.umajin;application/vnd.uoml+xml;application/vnd.unity;application/vnd.ufdl;text/uri-list;application/nd.uiq.theme;application/x-ustar;text/x-uuencode;text/x-vcalendar;text/x-vcard;application/x-cdlink;application/vnd.vsf;model/vrml;application/vnd.vcx;model/vnd.mts;model/vnd.vtu;application/vnd.visionary;video/vnd.vivo;applicatin/ccxml+xml,;application/voicexml+xml;application/x-wais-source;application/vnd.wap.wbxml;image/vnd.wap.wbmp;audio/x-wav;application/davmount+xml;application/x-font-woff;application/wspolicy+xml;image/webp;application/vnd.webturb;application/widget;application/winhlp;text/vnd.wap.wml;text/vnd.wap.wmlscript;application/vnd.wap.wmlscriptc;application/vnd.wordperfect;application/vnd.wt.stf;application/wsdl+xml;image/x-xbitmap;image/x-xpixmap;image/x-xwindowump;application/x-x509-ca-cert;application/x-xfig;application/xhtml+xml;application/xml;application/xcap-diff+xml;application/xenc+xml;application/patch-ops-error+xml;application/resource-lists+xml;application/rls-services+xml;aplication/resource-lists-diff+xml;application/xslt+xml;application/xop+xml;application/x-xpinstall;application/xspf+xml;application/vnd.mozilla.xul+xml;chemical/x-xyz;text/yaml;application/yang;application/yin+xml;application/vnd.ul;application/zip;application/vnd.handheld-entertainment+xml;application/vnd.zzazz.deck+xml') # noqa
browser = webdriver.Firefox(firefox_profile=profile, options=options)
browser.implicitly_wait(10)
browser.set_window_size(1920, 1080)
return browser
......
......@@ -36,7 +36,7 @@ class UserAccountFactory(DjangoModelFactory):
role = models.UserAccount.TUTOR
fullname = fake.name
username = fake.user_name
username = factory.Sequence(lambda n: f"{fake.user_name()}-{n}")
password = factory.PostGenerationMethodCall('set_password', 'redrum-is-murder-reversed')
......@@ -45,7 +45,7 @@ class StudentInfoFactory(DjangoModelFactory):
model = models.StudentInfo
exam = factory.SubFactory(ExamTypeFactory)
user = factory.SubFactory(UserAccountFactory)
user = factory.SubFactory(UserAccountFactory, role=models.UserAccount.STUDENT)
class TestFactory(DjangoModelFactory):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment