diff --git a/assets/js/AdminVacancyPage.jsx b/assets/js/AdminVacancyPage.jsx index c9cabc858b9e2579cee32a4461998d253bb5305b..9d9db5f8b7bd38ede410d22bd56f26118ea58f4c 100755 --- a/assets/js/AdminVacancyPage.jsx +++ b/assets/js/AdminVacancyPage.jsx @@ -1,8 +1,8 @@ import React from 'react'; +import { Item } from 'semantic-ui-react'; import Tabs from './components/Tabs'; import Pane from './components/Pane'; import AdminVacancy from './components/AdminVacancy'; -import { Item } from 'semantic-ui-react'; export default class AdminVacancyPage extends React.Component { render() { diff --git a/assets/js/ApplicantPage.jsx b/assets/js/ApplicantPage.jsx index 50c444fb8e04f4645a1424bb10c8828ce7844dbd..21bc0545f4ddb151fdd84228276e162f7c2d47d0 100755 --- a/assets/js/ApplicantPage.jsx +++ b/assets/js/ApplicantPage.jsx @@ -29,45 +29,43 @@ export default class ApplicantPage extends React.Component { this.getVacancyList(); } - getVacancyList = () => - Server.get( - `/companies/${this.props.user.data.company.id}/vacancies/`, - false, - ).then( - (data) => { - const results = data.results; - const urls = [ - { - key: 0, - value: `/companies/${this.props.user.data.company.id}/applications/`, - text: 'Semua Lowongan', - }, - ]; - results.map((vacancy) => { - names.push(vacancy.name); - const url = `/companies/${this.props.user.data.company.id}/applications/${vacancy.id}/by_vacancy/`; - const info = { - key: vacancy.id, - value: url, - text: vacancy.name, - }; - urls.push(info); - return urls; - }); - this.setState({ urls }); - }, - (error) => - error.then((r) => { - this.modalAlert.open('Gagal mendapatkan daftar lowongan', r.detail); - }), - ); + getVacancyList = () => Server.get( + `/companies/${this.props.user.data.company.id}/vacancies/`, + false, + ).then( + (data) => { + const { results } = data; + const urls = [ + { + key: 0, + value: `/companies/${this.props.user.data.company.id}/applications/`, + text: 'Semua Lowongan', + }, + ]; + results.map((vacancy) => { + names.push(vacancy.name); + const url = `/companies/${this.props.user.data.company.id}/applications/${vacancy.id}/by_vacancy/`; + const info = { + key: vacancy.id, + value: url, + text: vacancy.name, + }; + urls.push(info); + return urls; + }); + this.setState({ urls }); + }, + (error) => error.then((r) => { + this.modalAlert.open('Gagal mendapatkan daftar lowongan', r.detail); + }), + ); handleChange = (e, data) => { this.setState({ selected: data.value, refresh: this.state.refresh + 6 }); }; render() { - const company = this.props.user.data.company; + const { company } = this.props.user.data; return ( <div> <div className="dropdownApplicant"> @@ -84,78 +82,78 @@ export default class ApplicantPage extends React.Component { key={0 + this.state.refresh} url={`${this.state.selected}`} label="Semua Lamaran" - child={ + child={( <ApplicantList companyId={company.id} status={Applicant.APPLICATION_STATUS.ALL} /> - } + )} /> <Pagination key={1 + this.state.refresh} url={`${this.state.selected}?status=${Applicant.APPLICATION_STATUS.NEW}`} label="Lamaran Baru" - child={ + child={( <ApplicantList companyId={company.id} status={Applicant.APPLICATION_STATUS.NEW} /> - } + )} /> <Pagination key={2 + this.state.refresh} url={`${this.state.selected}?status=${Applicant.APPLICATION_STATUS.READ}`} label="Lamaran Dibaca" - child={ + child={( <ApplicantList companyId={company.id} status={Applicant.APPLICATION_STATUS.READ} /> - } + )} /> <Pagination key={3 + this.state.refresh} url={`${this.state.selected}?status=${Applicant.APPLICATION_STATUS.BOOKMARKED}`} label="Lamaran Ditandai" - child={ + child={( <ApplicantList companyId={company.id} status={Applicant.APPLICATION_STATUS.BOOKMARKED} /> - } + )} /> <Pagination key={4 + this.state.refresh} url={`${this.state.selected}?status=${Applicant.APPLICATION_STATUS.ACCEPTED}`} label="Lamaran Diterima" - child={ + child={( <ApplicantList companyId={company.id} status={Applicant.APPLICATION_STATUS.ACCEPTED} /> - } + )} /> <Pagination key={5 + this.state.refresh} url={`${this.state.selected}?status=${Applicant.APPLICATION_STATUS.REJECTED}`} label="Lamaran Ditolak" - child={ + child={( <ApplicantList companyId={company.id} status={Applicant.APPLICATION_STATUS.REJECTED} /> - } + )} /> <Pagination key={6 + this.state.refresh} url={`${this.state.selected}?status=${Applicant.APPLICATION_STATUS.FINISHED}`} label="Lamaran Selesai" - child={ + child={( <ApplicantList companyId={company.id} status={Applicant.APPLICATION_STATUS.FINISHED} /> - } + )} /> </Tabs> </div> diff --git a/assets/js/CompanyPage.jsx b/assets/js/CompanyPage.jsx index aaf9ce706257bdce9d0e29f30a8c968ccd6b163e..509aeef5b434dc7125ebdd8ebee3e015ee294013 100755 --- a/assets/js/CompanyPage.jsx +++ b/assets/js/CompanyPage.jsx @@ -47,7 +47,7 @@ export default class CompanyPage extends React.Component { /> <Pagination key={4} - url={'/companies/'} + url="/companies/" label="Semua Perusahaan" child={<CompanyList status={Company.COMPANY_STATUS.ALL} />} /> diff --git a/assets/js/CompanyProfile.jsx b/assets/js/CompanyProfile.jsx index bf2c94a7cfb4e9f18efc9bb9029b30d91e823a48..794c6b96f22e5649cf0bd1920e4698a39d13a758 100755 --- a/assets/js/CompanyProfile.jsx +++ b/assets/js/CompanyProfile.jsx @@ -25,8 +25,8 @@ export default class CompanyProfile extends React.Component { constructor(props) { super(props); - let data = TopMenu.getInfo(this.props.user); - console.log("ASdasdadasda"); + const data = TopMenu.getInfo(this.props.user); + console.log('ASdasdadasda'); console.log(data); this.state = { id: this.props.user.data.company.id, @@ -54,12 +54,12 @@ export default class CompanyProfile extends React.Component { this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); Server.get( - `/companies/${this.state.id}/` + `/companies/${this.state.id}/`, ).then( (result) => { - console.log("ASDADS"); - this.setState({ linkedin_url : result.linkedin_url}) - } + console.log('ASDADS'); + this.setState({ linkedin_url: result.linkedin_url }); + }, ); Server.get( `/companies/${this.props.user.data.company.id}/vacancies/`, @@ -94,10 +94,9 @@ export default class CompanyProfile extends React.Component { this.setState({ logo: result.logo }); } }, - (error) => - error.then(() => { - this.state.name = 'Gagal mendapatkan informasi'; - }), + (error) => error.then(() => { + this.state.name = 'Gagal mendapatkan informasi'; + }), ); } @@ -124,30 +123,27 @@ export default class CompanyProfile extends React.Component { this.getProfile, ); }, - (error) => - error.then((r) => { - this.setState({ loading: false }); - this.modalAlert.open('Pembaharuan profil gagal', Dumper.dump(r)); - }), + (error) => error.then((r) => { + this.setState({ loading: false }); + this.modalAlert.open('Pembaharuan profil gagal', Dumper.dump(r)); + }), ); }; handleChange = (e) => { - const form = this.state.form; + const { form } = this.state; form[e.target.name] = e.target.value; this.setState({ form }); }; render() { - const defaultLogo = - 'https://semantic-ui.com/images/wireframe/square-image.png'; + const defaultLogo = 'https://semantic-ui.com/images/wireframe/square-image.png'; const { applications } = this.state; const rejectedApplications = applications.filter((apl) => apl.status === 3) .length; const acceptedApplications = applications.filter((apl) => apl.status === 4) .length; - const sisaApplications = - applications.length - rejectedApplications - acceptedApplications; + const sisaApplications = applications.length - rejectedApplications - acceptedApplications; const chartData = { labels: ['Lamaran Ditolak', 'Lamaran Diterima', 'Lamaran Pending'], @@ -174,14 +170,22 @@ export default class CompanyProfile extends React.Component { <h2>{this.state.name}</h2> <h3>{this.state.address}</h3> <p> - {this.state.category} - {this.state.description} + {this.state.category} + {' '} +- + {this.state.description} </p> <p>{this.state.website}</p> - <p>{this.state.size} karyawan</p> + <p> + {this.state.size} + {' '} +karyawan + </p> {this.state.linkedin_url ? ( <a href={this.state.linkedin_url}> {' '} - {this.state.linkedin_url}{' '} + {this.state.linkedin_url} + {' '} </a> ) : ( <p> Belum ada link LinkedIn</p> @@ -254,7 +258,7 @@ export default class CompanyProfile extends React.Component { size="small" onChange={this.handleChange} defaultValue={ - this.state.size === null ? "0" : this.state.size + this.state.size === null ? '0' : this.state.size } /> </Form.Field> diff --git a/assets/js/CreateVacancy.jsx b/assets/js/CreateVacancy.jsx index 484289f36be688554d8362c454cf175f197541d4..ba6574733634efd40e447020927a2b2a2f06d387 100755 --- a/assets/js/CreateVacancy.jsx +++ b/assets/js/CreateVacancy.jsx @@ -1,6 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Segment, Button, Form, Header, Icon, Input } from 'semantic-ui-react'; +import { + Segment, Button, Form, Header, Icon, Input, +} from 'semantic-ui-react'; import { browserHistory } from 'react-router'; import DatePicker from 'react-datepicker'; import moment from 'moment'; @@ -118,11 +120,10 @@ export default class CreateVacancy extends React.Component { () => { browserHistory.push('/lowongan'); }, - (error) => - error.then((r) => { - this.modalAlert.open('Gagal Membuat Lowongan', r.error); - this.setState({ formLoading: false }); - }), + (error) => error.then((r) => { + this.modalAlert.open('Gagal Membuat Lowongan', r.error); + this.setState({ formLoading: false }); + }), ); }; @@ -149,7 +150,8 @@ export default class CreateVacancy extends React.Component { /> <label htmlFor="description"> {' '} - <b> Deskripsi Lowongan </b>{' '} + <b> Deskripsi Lowongan </b> + {' '} </label> {!this.state.loading && ( <CKEditor @@ -167,7 +169,8 @@ export default class CreateVacancy extends React.Component { /> <label htmlFor="responsibilities"> {' '} - <b> Tanggung Jawab Lowongan </b>{' '} + <b> Tanggung Jawab Lowongan </b> + {' '} </label> {!this.state.loading && ( <CKEditor @@ -189,7 +192,8 @@ export default class CreateVacancy extends React.Component { /> <label htmlFor="benefits"> {' '} - <b> Keuntungan </b>{' '} + <b> Keuntungan </b> + {' '} </label> {!this.state.loading && ( <CKEditor @@ -201,7 +205,8 @@ export default class CreateVacancy extends React.Component { <br /> <label htmlFor="requirements"> {' '} - <b> Persyaratan </b>{' '} + <b> Persyaratan </b> + {' '} </label> {!this.state.loading && ( <CKEditor diff --git a/assets/js/EditProfile.jsx b/assets/js/EditProfile.jsx index 795b7837065b5ac156607751d1d8fde4e8e938cf..289ecdaa54d7ab99ea77d04901017fec288ad39a 100644 --- a/assets/js/EditProfile.jsx +++ b/assets/js/EditProfile.jsx @@ -158,15 +158,14 @@ export default class EditProfile extends React.Component { window.scrollTo(0, 0); } }, - (error) => - error.then(() => { - this.state.name = 'Gagal mendapatkan informasi'; - }), + (error) => error.then(() => { + this.state.name = 'Gagal mendapatkan informasi'; + }), ); } isFromGithubLinkValid = () => { - var github_link = this.state.form.github_url; + const github_link = this.state.form.github_url; if (github_link == null) return; return github_link.includes('https://github.com/'); }; @@ -182,9 +181,9 @@ export default class EditProfile extends React.Component { '07': 'Juli', '08': 'Agustus', '09': 'September', - '10': 'Oktober', - '11': 'November', - '12': 'Desember', + 10: 'Oktober', + 11: 'November', + 12: 'Desember', }; const dateIndexArray = dateIndex.split('-'); @@ -198,10 +197,10 @@ export default class EditProfile extends React.Component { if (!this.isFromGithubLinkValid()) { this.modalAlert.open( 'Pembaharuan profil gagal', - 'Pastikan link github yang anda tulis benar.(Berpola : https://github.com/<username>' + 'Pastikan link github yang anda tulis benar.(Berpola : https://github.com/<username>', ); } else { - var submitForm = {}; + const submitForm = {}; Object.keys(this.state.form).forEach((key) => { if (this.state.form[key] !== '') { submitForm[key] = this.state.form[key]; @@ -221,41 +220,40 @@ export default class EditProfile extends React.Component { this.getProfile, ); }, - (error) => - error.then((r) => { - this.setState({ loading: false }); - this.modalAlert.open('Pembaharuan profil gagal', Dumper.dump(r)); - }), + (error) => error.then((r) => { + this.setState({ loading: false }); + this.modalAlert.open('Pembaharuan profil gagal', Dumper.dump(r)); + }), ); } }; handleFile = (e) => { - const form = this.state.form; + const { form } = this.state; form[e.target.name] = e.target.files[0]; this.setState({ form }); }; handleChange = (e) => { - const form = this.state.form; + const { form } = this.state; form[e.target.name] = e.target.value; this.setState({ form }); }; handleCheckbox = (e, d) => { - const form = this.state.form; + const { form } = this.state; form[d.name] = d.checked; this.setState({ form, show_transcript: d.checked }); }; handleRadioGender = (e, { value }) => { - const form = this.state.form; + const { form } = this.state; form.gender = value; this.setState({ form }); }; handleRadio = (e, { value }) => { - const form = this.state.form; + const { form } = this.state; form.job_seeking_status = value; this.setState({ form }); }; @@ -424,11 +422,11 @@ export default class EditProfile extends React.Component { </Form.Field> <Form.Field> <label htmlFor="github_url">URL Profile Github</label> - <input - onChange={this.handleChange} - placeholder={this.state.github_url === null ? "https://github.com/bob" : this.state.github_url} + <input + onChange={this.handleChange} + placeholder={this.state.github_url === null ? 'https://github.com/bob' : this.state.github_url} defaultValue={this.state.github_url === null ? null : this.state.github_url} - name="github_url" + name="github_url" /> </Form.Field> <Form.Field> @@ -461,9 +459,9 @@ export default class EditProfile extends React.Component { </Form.Field> <Form.Field> <label htmlFor="skills">Skills</label> - <input - onChange={this.handleChange} - placeholder="Isi sesuai dengan keahlian anda" + <input + onChange={this.handleChange} + placeholder="Isi sesuai dengan keahlian anda" defaultValue={this.state.skills === null ? 'Competitive Programming' : this.state.skills} name="skills" /> diff --git a/assets/js/Login.jsx b/assets/js/Login.jsx index 9b8dfd06eb42c887057bd7f59953f3fae9b3309d..5fac1fdcff72e96412c394dc11c86b86971cd1a0 100755 --- a/assets/js/Login.jsx +++ b/assets/js/Login.jsx @@ -1,6 +1,8 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; -import { Grid, Segment, Header, Card, Image, Button } from 'semantic-ui-react'; +import { + Grid, Segment, Header, Card, Image, Button, +} from 'semantic-ui-react'; import LoginForm from './components/LoginForm'; import CompanyRegisterModal from './components/CompanyRegisterModal'; import Footer from './components/Footer'; @@ -26,7 +28,8 @@ const CompanyForm = ({ children, onChange }) => ( > <Button primary onClick={() => onChange('user')}> {' '} - Login as User{' '} + Login as User + {' '} </Button> </div> </Segment> @@ -51,7 +54,8 @@ const UserForm = ({ children, onChange }) => ( > <Button primary onClick={() => onChange('company')}> {' '} - Login as Company{' '} + Login as Company + {' '} </Button> </div> </Segment> diff --git a/assets/js/ProfilePage.jsx b/assets/js/ProfilePage.jsx index c976e353aef3539d00394e176f9a1e04fb02857d..820fb3a905aeb920e53695bd89693f3c4e2aec0a 100755 --- a/assets/js/ProfilePage.jsx +++ b/assets/js/ProfilePage.jsx @@ -69,7 +69,7 @@ export default class ProfilePage extends React.Component { github_url: '', gitlab_url: '', awards: '', - sertifikat:'', + sertifikat: '', projects: '', certification: '', languages: '', @@ -91,7 +91,7 @@ export default class ProfilePage extends React.Component { github_url: '', gitlab_url: '', awards: '', - sertifikat:'', + sertifikat: '', projects: '', certification: '', languages: '', @@ -173,22 +173,21 @@ export default class ProfilePage extends React.Component { window.scrollTo(0, 0); } }, - (error) => - error.then(() => { - this.state.name = 'Gagal mendapatkan informasi'; - }), + (error) => error.then(() => { + this.state.name = 'Gagal mendapatkan informasi'; + }), ); } isFromGithubLinkValid = () => { - var github_link = this.state.form.github_url; + const github_link = this.state.form.github_url; if (github_link == null) return; return github_link.includes('https://github.com/'); }; gitlabURL_is_valid = () => { if (this.state.form.gitlab_url != null) { - return this.state.form.gitlab_url.includes("https://gitlab.com/"); + return this.state.form.gitlab_url.includes('https://gitlab.com/'); } } @@ -203,14 +202,14 @@ export default class ProfilePage extends React.Component { '07': 'Juli', '08': 'Agustus', '09': 'September', - '10': 'Oktober', - '11': 'November', - '12': 'Desember', + 10: 'Oktober', + 11: 'November', + 12: 'Desember', }; - let timeSt = dateTime.split('T'); - let dayMonthYear = timeSt[0].split('-'); - let newTime = `${dayMonthYear[2]} ${monthNameIndex[dayMonthYear[1]]} ${dayMonthYear[0]} | ${timeSt[1].substr(0, 5)}`; + const timeSt = dateTime.split('T'); + const dayMonthYear = timeSt[0].split('-'); + const newTime = `${dayMonthYear[2]} ${monthNameIndex[dayMonthYear[1]]} ${dayMonthYear[0]} | ${timeSt[1].substr(0, 5)}`; console.log(newTime); return newTime; }; @@ -226,9 +225,9 @@ export default class ProfilePage extends React.Component { '07': 'Juli', '08': 'Agustus', '09': 'September', - '10': 'Oktober', - '11': 'November', - '12': 'Desember', + 10: 'Oktober', + 11: 'November', + 12: 'Desember', }; const dateIndexArray = dateIndex.split('-'); @@ -246,7 +245,7 @@ export default class ProfilePage extends React.Component { ); } else if (!this.gitlabURL_is_valid()) { this.modalAlert.open( - "Link gitlab tidak sesuai. Contoh : https://gitlab.com/<your-username>", + 'Link gitlab tidak sesuai. Contoh : https://gitlab.com/<your-username>', ); return; } @@ -271,41 +270,40 @@ export default class ProfilePage extends React.Component { this.getProfile, ); }, - (error) => - error.then((r) => { - this.setState({ loading: false }); - this.modalAlert.open('Pembaharuan profil gagal', Dumper.dump(r)); - }), + (error) => error.then((r) => { + this.setState({ loading: false }); + this.modalAlert.open('Pembaharuan profil gagal', Dumper.dump(r)); + }), ); } }; handleFile = (e) => { - const form = this.state.form; + const { form } = this.state; form[e.target.name] = e.target.files[0]; this.setState({ form }); }; handleChange = (e) => { - const form = this.state.form; + const { form } = this.state; form[e.target.name] = e.target.value; this.setState({ form }); }; handleCheckbox = (e, d) => { - const form = this.state.form; + const { form } = this.state; form[d.name] = d.checked; this.setState({ form, show_transcript: d.checked }); }; handleRadioGender = (e, { value }) => { - const form = this.state.form; + const { form } = this.state; form.gender = value; this.setState({ form }); }; handleRadio = (e, { value }) => { - const form = this.state.form; + const { form } = this.state; form.job_seeking_status = value; this.setState({ form }); }; @@ -400,7 +398,7 @@ export default class ProfilePage extends React.Component { </Form.Field> <Form.Field> <label htmlFor="self_description">Deskripsi Diri</label> - <input onChange={this.handleChange} maxlength="500" placeholder="Saya suka belajar" name="self_description" /> + <input onChange={this.handleChange} maxLength="500" placeholder="Saya suka belajar" name="self_description" /> </Form.Field> <Form.Field> <label htmlFor="linkedin_url">URL Profile LinkedIn</label> @@ -440,8 +438,8 @@ export default class ProfilePage extends React.Component { <label htmlFor="portfolio_link">Portfolio Link</label> <input onChange={this.handleChange} - placeholder={this.state.portfolio_link === null ? 'https://www.example.com/myproject/' : - this.state.portfolio_link} + placeholder={this.state.portfolio_link === null ? 'https://www.example.com/myproject/' + : this.state.portfolio_link} defaultValue={this.state.portfolio_link === null ? null : this.state.portfolio_link} placeholder={ this.state.portfolio_link === null @@ -539,7 +537,7 @@ export default class ProfilePage extends React.Component { <Form.Field> <label htmlFor="latest_work_desc"> Latest Working Experience Description - </label> + </label> <input onChange={this.handleChange} placeholder={ @@ -728,7 +726,7 @@ export default class ProfilePage extends React.Component { floated="right" > Submit - </Button> + </Button> </Form> </Form.Field> </Segment> @@ -741,13 +739,12 @@ export default class ProfilePage extends React.Component { render() { const sertifikat_exists = this.state.sertifikat; let sertifikat_state; - if(sertifikat_exists){ + if (sertifikat_exists) { sertifikat_state = <p>Sertifikat sudah ada</p>; - } else{ + } else { sertifikat_state = <p>Sertifikat belum ada</p>; } - const defaultPicture = - 'https://semantic-ui.com/images/wireframe/square-image.png'; + const defaultPicture = 'https://semantic-ui.com/images/wireframe/square-image.png'; return ( <div className="profilePage"> <Segment className="biodata-section"> @@ -763,7 +760,11 @@ export default class ProfilePage extends React.Component { <Container textAlign="left" className="profile-biodata"> <div className="biodata"> <Segment basic textAlign="center"> - <h1> {this.state.name} </h1> + <h1> + {' '} + {this.state.name} + {' '} + </h1> </Segment> <Segment basic vertical> @@ -774,8 +775,11 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <p> {' '} - {this.state.major || 'N/A'},{' '} - {this.state.batch || 'N/A'}{' '} + {this.state.major || 'N/A'} +, + {' '} + {this.state.batch || 'N/A'} + {' '} </p> </Grid.Column> </Grid> @@ -787,7 +791,11 @@ export default class ProfilePage extends React.Component { <Icon name="mail" size="big" /> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.email || 'N/A'} </p> + <p> + {' '} + {this.state.email || 'N/A'} + {' '} + </p> </Grid.Column> </Grid> </Segment> @@ -798,7 +806,10 @@ export default class ProfilePage extends React.Component { <Icon name="phone" size="big" /> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.phone_number || 'Nomor Telepon belum ditambahkan'}</p> + <p> + {' '} + {this.state.phone_number || 'Nomor Telepon belum ditambahkan'} + </p> </Grid.Column> </Grid> </Segment> @@ -811,7 +822,8 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <a href={this.state.portfolio_link}> {' '} - {this.state.portfolio_link || 'Portofolio belum ditambahkan'}{' '} + {this.state.portfolio_link || 'Portofolio belum ditambahkan'} + {' '} </a> </Grid.Column> </Grid> @@ -823,7 +835,10 @@ export default class ProfilePage extends React.Component { <Icon name="venus mars" size="big" /> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.gender || 'Gender belum ditambahkan'}</p> + <p> + {' '} + {this.state.gender || 'Gender belum ditambahkan'} + </p> </Grid.Column> </Grid> </Segment> @@ -836,8 +851,11 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <p> {' '} - {this.state.cityOfBirth || 'N/A'},{' '} - {this.state.dateOfBirth || 'N/A'}{' '} + {this.state.cityOfBirth || 'N/A'} +, + {' '} + {this.state.dateOfBirth || 'N/A'} + {' '} </p> </Grid.Column> </Grid> @@ -849,7 +867,10 @@ export default class ProfilePage extends React.Component { <Icon name="user" size="big" /> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.self_description || 'N/A'}</p> + <p> + {' '} + {this.state.self_description || 'N/A'} + </p> </Grid.Column> </Grid> </Segment> @@ -862,7 +883,8 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <a href={this.state.linkedin_url}> {' '} - {this.state.linkedin_url || 'N/A'}{' '} + {this.state.linkedin_url || 'N/A'} + {' '} </a> </Grid.Column> </Grid> @@ -876,7 +898,8 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <a href={this.state.hackerrank_url}> {' '} - {this.state.hackerrank_url || 'N/A'}{' '} + {this.state.hackerrank_url || 'N/A'} + {' '} </a> </Grid.Column> </Grid> @@ -890,7 +913,8 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <a href={this.state.student_gpa}> {' '} - {this.state.student_gpa || 'null'}{' '} + {this.state.student_gpa || 'null'} + {' '} </a> </Grid.Column> </Grid> @@ -904,7 +928,8 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <a href={this.state.dependants}> {' '} - {this.state.dependants || 'null'}{' '} + {this.state.dependants || 'null'} + {' '} </a> </Grid.Column> </Grid> @@ -918,7 +943,8 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <a href={this.state.website_url}> {' '} - {this.state.website_url || 'N/A'}{' '} + {this.state.website_url || 'N/A'} + {' '} </a> </Grid.Column> </Grid> @@ -932,11 +958,12 @@ export default class ProfilePage extends React.Component { {this.state.github_url ? ( <a href={this.state.github_url}> {' '} - {this.state.github_url}{' '} + {this.state.github_url} + {' '} </a> ) : ( - <p> N/A </p> - )} + <p> N/A </p> + )} </Grid.Column> </Grid> </Segment> @@ -947,9 +974,15 @@ export default class ProfilePage extends React.Component { </Grid.Column> <Grid.Column width={13}> { - this.state.gitlab_url ? - <a href={ this.state.gitlab_url }> { this.state.gitlab_url } </a> : - <p> N/A </p> + this.state.gitlab_url + ? ( + <a href={this.state.gitlab_url}> + {' '} + { this.state.gitlab_url } + {' '} + </a> + ) + : <p> N/A </p> } </Grid.Column> </Grid> @@ -962,7 +995,11 @@ export default class ProfilePage extends React.Component { <Icon name="address book" size="big" /> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.alamat || 'N/A'} </p> + <p> + {' '} + {this.state.alamat || 'N/A'} + {' '} + </p> </Grid.Column> </Grid> </Segment> @@ -974,7 +1011,11 @@ export default class ProfilePage extends React.Component { <Icon name="map pin" size="big" /> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.region || 'N/A'} </p> + <p> + {' '} + {this.state.region || 'N/A'} + {' '} + </p> </Grid.Column> </Grid> </Segment> @@ -986,7 +1027,8 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <p> {' '} - {this.state.skills || 'Skills belum ditambahkan'}{' '} + {this.state.skills || 'Skills belum ditambahkan'} + {' '} </p> </Grid.Column> </Grid> @@ -998,14 +1040,24 @@ export default class ProfilePage extends React.Component { </Grid.Column> <Grid.Column width={13}> <p> - Latest working experience as:{' '} + Latest working experience as: + {' '} <span> - <b> {this.state.latest_work || 'N/A'} </b> + <b> + {' '} + {this.state.latest_work || 'N/A'} + {' '} + </b> </span> </p> <p> - Description:{' '} - <span> {this.state.latest_work_desc || 'N/A'} </span> + Description: + {' '} + <span> + {' '} + {this.state.latest_work_desc || 'N/A'} + {' '} + </span> </p> </Grid.Column> </Grid> @@ -1017,7 +1069,11 @@ export default class ProfilePage extends React.Component { <Icon name="money bill alternate" size="big" /> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.expected_salary || 'N/A'} </p> + <p> + {' '} + {this.state.expected_salary || 'N/A'} + {' '} + </p> </Grid.Column> </Grid> </Segment> @@ -1028,7 +1084,11 @@ export default class ProfilePage extends React.Component { <Icon name="hand peace outline" size="big" /> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.volunteer || 'N/A'} </p> + <p> + {' '} + {this.state.volunteer || 'N/A'} + {' '} + </p> </Grid.Column> </Grid> </Segment> @@ -1041,7 +1101,8 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <p> {' '} - {this.state.awards || 'Awards belum ditambahkan'}{' '} + {this.state.awards || 'Awards belum ditambahkan'} + {' '} </p> </Grid.Column> </Grid> @@ -1055,7 +1116,8 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> {sertifikat_state} </Grid.Column> - </Grid>x + </Grid> +x </Segment> <Segment basic vertical> @@ -1066,8 +1128,9 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <p> {' '} - {this.state.projects || - 'Projects belum ditambahkan'}{' '} + {this.state.projects + || 'Projects belum ditambahkan'} + {' '} </p> </Grid.Column> </Grid> @@ -1079,7 +1142,11 @@ export default class ProfilePage extends React.Component { <Icon name="certificate" size="big" /> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.certification || 'N/A'} </p> + <p> + {' '} + {this.state.certification || 'N/A'} + {' '} + </p> </Grid.Column> </Grid> </Segment> @@ -1090,7 +1157,11 @@ export default class ProfilePage extends React.Component { <Icon name="comment" size="big" /> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.languages || 'N/A'} </p> + <p> + {' '} + {this.state.languages || 'N/A'} + {' '} + </p> </Grid.Column> </Grid> </Segment> @@ -1103,8 +1174,9 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <p> {' '} - {this.state.seminar || - 'Seminar dan Training kosong'}{' '} + {this.state.seminar + || 'Seminar dan Training kosong'} + {' '} </p> </Grid.Column> </Grid> @@ -1118,8 +1190,9 @@ export default class ProfilePage extends React.Component { <Grid.Column width={13}> <p> {' '} - {this.state.interests || - 'Interests belum ditambahkan'}{' '} + {this.state.interests + || 'Interests belum ditambahkan'} + {' '} </p> </Grid.Column> </Grid> @@ -1130,7 +1203,11 @@ export default class ProfilePage extends React.Component { <h3 className="lastSeen">Last Seen</h3> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.lastLoggedIn} </p> + <p> + {' '} + {this.state.lastLoggedIn} + {' '} + </p> </Grid.Column> </Grid> </Segment> @@ -1140,7 +1217,11 @@ export default class ProfilePage extends React.Component { <Icon name="time" size="big" /> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.age + ' years' || 'N/A'} </p> + <p> + {' '} + {`${this.state.age} years` || 'N/A'} + {' '} + </p> </Grid.Column> </Grid> </Segment> @@ -1152,11 +1233,19 @@ export default class ProfilePage extends React.Component { <Icon name="map pin" size="big" /> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.region || 'N/A'} </p> + <p> + {' '} + {this.state.region || 'N/A'} + {' '} + </p> <h3>Intro</h3> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.intro || 'N/A'} </p> + <p> + {' '} + {this.state.intro || 'N/A'} + {' '} + </p> </Grid.Column> </Grid> </Segment> @@ -1167,17 +1256,24 @@ export default class ProfilePage extends React.Component { <h3>Intro</h3> </Grid.Column> <Grid.Column width={13}> - <p> {this.state.intro || 'N/A'} </p> + <p> + {' '} + {this.state.intro || 'N/A'} + {' '} + </p> </Grid.Column> <p className="jumlahLamaran"> {' '} - Jumlah lamaran diterima: {this.state.acceptedNo || '0'} + Jumlah lamaran diterima: + {' '} + {this.state.acceptedNo || '0'} </p> </Grid> <Grid> <p className="jumlahLamaran"> {' '} - Jumlah lamaran dibaca perusahaan:{' '} + Jumlah lamaran dibaca perusahaan: + {' '} {this.state.readNo || '0'} </p> </Grid> @@ -1204,7 +1300,8 @@ export default class ProfilePage extends React.Component { <div> <h4> {' '} - Bagikan Transkrip :{' '} + Bagikan Transkrip : + {' '} {this.state.bagikanTranskrip ? 'Ya' : 'Tidak'} </h4> </div> @@ -1231,14 +1328,14 @@ export default class ProfilePage extends React.Component { </p> </Message> ) : ( - <Message negative> - <Message.Header>Tidak mencari pekerjaan</Message.Header> - <p> + <Message negative> + <Message.Header>Tidak mencari pekerjaan</Message.Header> + <p> Saya sedang tidak mencari pekerjaan. Mohon jangan kirimkan informasi mengenai lowongan pekerjaan. </p> - </Message> - )} + </Message> + )} </h4> </div> </Segment> diff --git a/assets/js/SupervisorPage.jsx b/assets/js/SupervisorPage.jsx index 2dc8aa176f0d37a7fafd7ea87f2ff07b15b45a63..e33b0a29c66fbbb79d0bec6b4cf7616f6e321dea 100755 --- a/assets/js/SupervisorPage.jsx +++ b/assets/js/SupervisorPage.jsx @@ -30,27 +30,25 @@ export default class SupervisorPage extends React.Component { }); } - render = () => { - return ( - <Grid container columns="eleven" doubling> - <Grid.Row> - <br /> - </Grid.Row> - <Grid.Row> - <Header as="h2"> - <Icon name="list" /> + render = () => ( + <Grid container columns="eleven" doubling> + <Grid.Row> + <br /> + </Grid.Row> + <Grid.Row> + <Header as="h2"> + <Icon name="list" /> Daftar Mahasiswa - </Header> - </Grid.Row> - <Grid.Row> - <div id="layout-content" className="layout-content-wrapper"> - <Pagination - url={'/applications/'} - child={<ApplicationList cols={cols} />} - /> - </div> - </Grid.Row> - </Grid> - ); - }; + </Header> + </Grid.Row> + <Grid.Row> + <div id="layout-content" className="layout-content-wrapper"> + <Pagination + url="/applications/" + child={<ApplicationList cols={cols} />} + /> + </div> + </Grid.Row> + </Grid> + ); } diff --git a/assets/js/TranscriptPage.jsx b/assets/js/TranscriptPage.jsx index 9be78002f4172f16916169aaaf44f7f0e0ac8f12..5cc1337ea91ce89efdb25da65f41a0cabb3a4aae 100755 --- a/assets/js/TranscriptPage.jsx +++ b/assets/js/TranscriptPage.jsx @@ -13,16 +13,14 @@ export default class TranscriptPage extends React.Component { super(props); /* istanbul ignore next */ this.state = { text: 'Mohon Tunggu..' }; - const url = - this.props.user.role === 'student' - ? `/students/${this.props.params.id}/transcript/` - : `/applications/${this.props.params.id}/transcript/`; + const url = this.props.user.role === 'student' + ? `/students/${this.props.params.id}/transcript/` + : `/applications/${this.props.params.id}/transcript/`; Server.get(url).then( (response) => this.setState({ data: response }), - () => - this.setState({ - text: 'Anda tidak berhak untuk melihat transkrip ini', - }), + () => this.setState({ + text: 'Anda tidak berhak untuk melihat transkrip ini', + }), ); } @@ -30,7 +28,11 @@ export default class TranscriptPage extends React.Component { return this.state.data ? ( <CourseList data={this.state.data} /> ) : ( - <h5 style={{ textAlign: 'center' }}> {this.state.text} </h5> + <h5 style={{ textAlign: 'center' }}> + {' '} + {this.state.text} + {' '} + </h5> ); } } diff --git a/assets/js/VacancyPage.jsx b/assets/js/VacancyPage.jsx index 96fee2dc32709926b567b2147494356aea83caad..2f18490f55e2a3132eb35b59fc1809785925ea5e 100755 --- a/assets/js/VacancyPage.jsx +++ b/assets/js/VacancyPage.jsx @@ -1,6 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Segment, Button, Dropdown, Container } from 'semantic-ui-react'; +import { + Segment, Button, Dropdown, Container, +} from 'semantic-ui-react'; import { Link } from 'react-router'; import Tabs from './components/Tabs'; import Pane from './components/Pane'; @@ -14,17 +16,17 @@ export default class VacancyPage extends React.Component { }; static getId(user) { - const role = user.role; + const { role } = user; if (role === 'student') { return user.data.student.id; - } else if ( - role === 'company' || - (role === 'admin' && user.data.company != null) + } if ( + role === 'company' + || (role === 'admin' && user.data.company != null) ) { return user.data.company.id; - } else if ( - role === 'supervisor' || - (role === 'admin' && user.data.supervisor != null) + } if ( + role === 'supervisor' + || (role === 'admin' && user.data.supervisor != null) ) { return user.data.supervisor.id; } @@ -58,81 +60,81 @@ export default class VacancyPage extends React.Component { <Pagination key={1} url="/vacancies/" - child={ + child={( <VacancyList user={this.props.user} key={1} userId={this.state.id} sort={this.state.sort} /> - } + )} /> </Pane> <Pane label="Lamaran Saya"> <Pagination key={2} url={`/students/${this.state.id}/applied-vacancies/`} - child={ + child={( <VacancyList user={this.props.user} key={2} userId={this.state.id} /> - } + )} /> </Pane> <Pane label="Ditandai"> <Pagination key={3} url={`/students/${this.state.id}/bookmarked-vacancies/`} - child={ + child={( <VacancyList key={3} user={this.props.user} userId={this.state.id} /> - } + )} /> </Pane> <Pane label="Lowongan Tersedia"> <Pagination key={4} url="/vacancies/opened_only=1" - child={ + child={( <VacancyList user={this.props.user} key={4} userId={this.state.id} /> - } + )} /> </Pane> </Tabs> ); - } else if ( - (this.props.user.role === 'admin' && - this.props.user.data.company != null) || - this.props.user.role === 'company' + } if ( + (this.props.user.role === 'admin' + && this.props.user.data.company != null) + || this.props.user.role === 'company' ) { return ( <Segment className="paginationCompany"> <Pagination key={1} url={`/companies/${this.state.id}/vacancies/`} - child={ + child={( <VacancyList key={1} user={this.props.user} userId={this.state.id} /> - } + )} error="Akun anda belum terverifikasi. Harap hubungi pihak administrasi" /> </Segment> ); - } else if ( - this.props.user.role === 'admin' || - this.props.user.role === 'supervisor' + } if ( + this.props.user.role === 'admin' + || this.props.user.role === 'supervisor' ) { return ( <Tabs selected={0}> @@ -140,26 +142,26 @@ export default class VacancyPage extends React.Component { <Pagination key={1} url="/vacancies/?verified=false" - child={ + child={( <VacancyList user={this.props.user} key={1} userId={this.state.id} /> - } + )} /> </Pane> <Pane label="Lowongan Terverifikasi"> <Pagination key={2} url="/vacancies/?verified=true" - child={ + child={( <VacancyList user={this.props.user} key={2} userId={this.state.id} /> - } + )} /> </Pane> </Tabs> @@ -178,9 +180,9 @@ export default class VacancyPage extends React.Component { companyHeader() { if ( - (this.props.user.role === 'admin' && - this.props.user.data.company != null) || - this.props.user.role === 'company' + (this.props.user.role === 'admin' + && this.props.user.data.company != null) + || this.props.user.role === 'company' ) { return ( <div style={{ float: 'left' }}> @@ -231,8 +233,8 @@ export default class VacancyPage extends React.Component { style={{ display: 'inline-block' }} > {this.companyHeader()} - {(this.props.user.role === 'admin' || - this.props.user.role === 'supervisor') && ( + {(this.props.user.role === 'admin' + || this.props.user.role === 'supervisor') && ( <Button as={Link} to="/rekap" diff --git a/assets/js/__test__/components/AdminVacancy-test.jsx b/assets/js/__test__/components/AdminVacancy-test.jsx index 0072cdd523e2ce2b11334ffa9bae4205a4c1493b..626adb585ddb258babf271191b41cd05a23bd643 100755 --- a/assets/js/__test__/components/AdminVacancy-test.jsx +++ b/assets/js/__test__/components/AdminVacancy-test.jsx @@ -2,26 +2,27 @@ import React from 'react'; import ReactTestUtils from 'react-dom/test-utils'; import AdminVacancy from '../../components/AdminVacancy'; -import Storage from '../../lib/Storage'; import { response, response2 } from '../../object/Response'; describe('AdminVacancy', () => { - it('renders for verified without problem', () => { const lowongan = ReactTestUtils.renderIntoDocument( - <AdminVacancy status={4} data={response} />); + <AdminVacancy status={4} data={response} />, + ); expect(lowongan).to.exist; }); it('renders for unverified without problem', () => { const lowongan = ReactTestUtils.renderIntoDocument( - <AdminVacancy status={3} data={response2} />); + <AdminVacancy status={3} data={response2} />, + ); expect(lowongan).to.exist; }); it('generate button without problem', () => { const lowongan = ReactTestUtils.renderIntoDocument( - <AdminVacancy status={3} data={response2} />); + <AdminVacancy status={3} data={response2} />, + ); expect(lowongan.generateButton()).to.exist; }); }); diff --git a/assets/js/__test__/components/AdminVerificationModal-test.jsx b/assets/js/__test__/components/AdminVerificationModal-test.jsx index ec5ad8406c1fa9890f3fb6b363c02412f9b724b8..aecbeeea4d53e38540fe0268d89a4537bbf7b01f 100755 --- a/assets/js/__test__/components/AdminVerificationModal-test.jsx +++ b/assets/js/__test__/components/AdminVerificationModal-test.jsx @@ -5,24 +5,24 @@ import AdminVerificationModal from '../../components/AdminVerificationModal'; describe('AdminVerificationModal', () => { it('renders without problem', () => { const modalAdmin = ReactTestUtils.renderIntoDocument( - <AdminVerificationModal />); + <AdminVerificationModal />, + ); expect(modalAdmin).to.exist; }); it('close without problem', () => { const modalAdmin = ReactTestUtils.renderIntoDocument( - <AdminVerificationModal />); + <AdminVerificationModal />, + ); modalAdmin.handleClose(); expect(modalAdmin.state.modalOpen).to.equal(false); }); it('open without problem', () => { - const modalAdmin = ReactTestUtils.renderIntoDocument( - <AdminVerificationModal />); - modalAdmin.handleOpen(); - expect(modalAdmin.state.modalOpen).to.equal(true); -}); - + const modalAdmin = ReactTestUtils.renderIntoDocument( + <AdminVerificationModal />, + ); + modalAdmin.handleOpen(); + expect(modalAdmin.state.modalOpen).to.equal(true); + }); }); - - diff --git a/assets/js/__test__/components/Applicant-test.jsx b/assets/js/__test__/components/Applicant-test.jsx index a775379261899ef474c32a506ce3d50fa3ba3447..962a545ad467e5f6b2d23f9670afe1591bae157b 100755 --- a/assets/js/__test__/components/Applicant-test.jsx +++ b/assets/js/__test__/components/Applicant-test.jsx @@ -1,7 +1,7 @@ import React from 'react'; import ReactTestUtils from 'react-dom/test-utils'; -import Applicant from '../../components/Applicant'; import fetchMock from 'fetch-mock'; +import Applicant from '../../components/Applicant'; describe('Applicant', () => { const stub = { diff --git a/assets/js/__test__/components/ApplicantList-test.jsx b/assets/js/__test__/components/ApplicantList-test.jsx index ea6625be4d415024a4ce5ecd0dd514d212d86bb0..00fde2d1ee450a18286b2621ef1369aac896f60c 100755 --- a/assets/js/__test__/components/ApplicantList-test.jsx +++ b/assets/js/__test__/components/ApplicantList-test.jsx @@ -5,7 +5,6 @@ import ApplicantList from '../../components/ApplicantList'; import Applicant from '../../components/Applicant'; describe('ApplicantList', () => { - const vacancy = { close_time: '2019-03-28T05:55:42Z', company: { @@ -21,7 +20,7 @@ describe('ApplicantList', () => { open_time: '2017-03-28T05:55:38Z', updated: '2017-03-28T07:34:13.122093Z', verified: true, - } + }; const student = { role: 'student', @@ -58,10 +57,18 @@ describe('ApplicantList', () => { }; const response = [ - { id: 1, status: Applicant.APPLICATION_STATUS.ACCEPTED, student, vacancy }, - { id: 2, status: Applicant.APPLICATION_STATUS.BOOKMARKED, student, vacancy }, - { id: 3, status: Applicant.APPLICATION_STATUS.NEW, student, vacancy }, - { id: 4, status: Applicant.APPLICATION_STATUS.REJECTED, student, vacancy }, + { + id: 1, status: Applicant.APPLICATION_STATUS.ACCEPTED, student, vacancy, + }, + { + id: 2, status: Applicant.APPLICATION_STATUS.BOOKMARKED, student, vacancy, + }, + { + id: 3, status: Applicant.APPLICATION_STATUS.NEW, student, vacancy, + }, + { + id: 4, status: Applicant.APPLICATION_STATUS.REJECTED, student, vacancy, + }, ]; fetchMock.restore(); @@ -69,14 +76,16 @@ describe('ApplicantList', () => { it('renders without problem', () => { const applicantList = ReactTestUtils.renderIntoDocument( - <ApplicantList status={Applicant.APPLICATION_STATUS.ACCEPTED} />); + <ApplicantList status={Applicant.APPLICATION_STATUS.ACCEPTED} />, + ); expect(applicantList).to.exist; }); it('can update status', () => { const applicantList = ReactTestUtils.renderIntoDocument( - <ApplicantList status={Applicant.APPLICATION_STATUS.ACCEPTED} />); - applicantList.setState({applications: response }); + <ApplicantList status={Applicant.APPLICATION_STATUS.ACCEPTED} />, + ); + applicantList.setState({ applications: response }); expect(applicantList.state).to.not.equal(response); applicantList.updateStatus(1, Applicant.APPLICATION_STATUS.BOOKMARKED); @@ -85,9 +94,9 @@ describe('ApplicantList', () => { it('can show all applicant', () => { const applicantList = ReactTestUtils.renderIntoDocument( - <ApplicantList status={Applicant.APPLICATION_STATUS.ALL} />); + <ApplicantList status={Applicant.APPLICATION_STATUS.ALL} />, + ); // eslint-disable-next-line no-unused-expressions expect(applicantList).to.exist; }); }); - diff --git a/assets/js/__test__/components/ApplyModal-test.jsx b/assets/js/__test__/components/ApplyModal-test.jsx index b9201a44cd55873c0492cf18d67a4cfecdad3615..bc88affc93cba4b4a40fd9972554952ca33e5716 100755 --- a/assets/js/__test__/components/ApplyModal-test.jsx +++ b/assets/js/__test__/components/ApplyModal-test.jsx @@ -1,20 +1,22 @@ /* eslint-disable no-unused-expressions */ import React from 'react'; import ReactTestUtils from 'react-dom/test-utils'; -import ApplyModal from '../../components/ApplyModal'; import fetchMock from 'fetch-mock'; +import ApplyModal from '../../components/ApplyModal'; describe('ApplyModal', () => { it('renders without problem', () => { const modalPendaftaran = ReactTestUtils.renderIntoDocument( - <ApplyModal id={4} data={{ key: 'value' }} buttonTitle="submit" />); + <ApplyModal id={4} data={{ key: 'value' }} buttonTitle="submit" />, + ); expect(modalPendaftaran).to.exist; }); it('open without problem', () => { fetchMock.post('*', {}); const modalPendaftaran = ReactTestUtils.renderIntoDocument( - <ApplyModal id={4} data={{ key: 'value' }} buttonTitle="submit" apply={() => {}} resume="ada" />); + <ApplyModal id={4} data={{ key: 'value' }} buttonTitle="submit" apply={() => {}} resume="ada" />, + ); const modal = ReactTestUtils.findRenderedDOMComponentWithTag(modalPendaftaran, 'Button'); modalPendaftaran.handleApply(); ReactTestUtils.Simulate.click(modal); @@ -25,7 +27,8 @@ describe('ApplyModal', () => { it('open with problem', () => { fetchMock.post('*', 404); const modalPendaftaran = ReactTestUtils.renderIntoDocument( - <ApplyModal id={4} data={{ key: 'value' }} buttonTitle="submit" apply={() => {}} resume="ada" />); + <ApplyModal id={4} data={{ key: 'value' }} buttonTitle="submit" apply={() => {}} resume="ada" />, + ); const modal = ReactTestUtils.findRenderedDOMComponentWithTag(modalPendaftaran, 'Button'); modalPendaftaran.handleApply(); ReactTestUtils.Simulate.click(modal); @@ -35,7 +38,8 @@ describe('ApplyModal', () => { it('change without problem', () => { const modalPendaftaran = ReactTestUtils.renderIntoDocument( - <ApplyModal id={4} data={{ key: 'value' }} buttonTitle="submit" />); + <ApplyModal id={4} data={{ key: 'value' }} buttonTitle="submit" />, + ); modalPendaftaran.handleChange({ target: { value: 'duar' } }); expect(modalPendaftaran.state.coverLetter).to.equal('duar'); @@ -43,7 +47,8 @@ describe('ApplyModal', () => { it('close without problem', () => { const modalPendaftaran = ReactTestUtils.renderIntoDocument( - <ApplyModal id={4} data={{ key: 'value' }} buttonTitle="submit" />); + <ApplyModal id={4} data={{ key: 'value' }} buttonTitle="submit" />, + ); modalPendaftaran.handleClose(); expect(modalPendaftaran.state.modalOpen).to.equal(false); @@ -51,19 +56,10 @@ describe('ApplyModal', () => { it('shows company description', () => { const modalPendaftaran = ReactTestUtils.renderIntoDocument( - <ApplyModal id={4} data={{ key: 'value', companydescription: 'compdesc' }} buttonTitle="submit" />); + <ApplyModal id={4} data={{ key: 'value', companydescription: 'compdesc' }} buttonTitle="submit" />, + ); modalPendaftaran.handleChange({ target: { value: 'duar' } }); expect(modalPendaftaran.props.data.companydescription).to.equal('compdesc'); }); - - // it('apply without resume', () => { - // const modalPendaftaran = ReactTestUtils.renderIntoDocument( - // <ApplyModal id={4} data={{ key: 'value', companydescription: 'compdesc' }} buttonTitle="submit" />); - // const modal = ReactTestUtils.findRenderedDOMComponentWithTag(modalPendaftaran, 'Button'); - // modalPendaftaran.handleApply(); - // ReactTestUtils.Simulate.click(modal); - // expect(modalPendaftaran).to.exist; - // fetchMock.restore(); - // }); }); diff --git a/assets/js/__test__/components/Company-test.jsx b/assets/js/__test__/components/Company-test.jsx index dbaeb1d28b151d43f5ecc5981b10f6705e316d23..fe078dc97a0bf66c9a9a57ecba480ae2f75367e0 100755 --- a/assets/js/__test__/components/Company-test.jsx +++ b/assets/js/__test__/components/Company-test.jsx @@ -1,7 +1,7 @@ import React from 'react'; import ReactTestUtils from 'react-dom/test-utils'; -import Company from '../../components/Company'; import fetchMock from 'fetch-mock'; +import Company from '../../components/Company'; describe('Company', () => { const stub = { diff --git a/assets/js/__test__/components/CompanyList-test.jsx b/assets/js/__test__/components/CompanyList-test.jsx index 3b6e1aa85962dd78891ff1e642a9ba23014cc0a3..046f0387033cdcec6accd13429c9cfcc2a4883f0 100755 --- a/assets/js/__test__/components/CompanyList-test.jsx +++ b/assets/js/__test__/components/CompanyList-test.jsx @@ -38,13 +38,15 @@ describe('CompanyList', () => { it('renders without problem', () => { const companyList = ReactTestUtils.renderIntoDocument( - <CompanyList status={Company.COMPANY_STATUS.VERIFIED} items={response} />); + <CompanyList status={Company.COMPANY_STATUS.VERIFIED} items={response} />, + ); expect(companyList).to.exist; }); it('can update status', () => { const companyList = ReactTestUtils.renderIntoDocument( - <CompanyList status={Company.COMPANY_STATUS.VERIFIED} items={response} />); + <CompanyList status={Company.COMPANY_STATUS.VERIFIED} items={response} />, + ); companyList.setState({ companies: response }); companyList.generateCompanies(); @@ -53,4 +55,3 @@ describe('CompanyList', () => { expect(companyList.state).to.not.equal(response); }); }); - diff --git a/assets/js/__test__/components/CompanyRegisterModal-test.jsx b/assets/js/__test__/components/CompanyRegisterModal-test.jsx index 7290f0b0e38947caeb3960ed742368226f8d1c14..9300a93492eab2750eea4a3af5494104567cf81b 100755 --- a/assets/js/__test__/components/CompanyRegisterModal-test.jsx +++ b/assets/js/__test__/components/CompanyRegisterModal-test.jsx @@ -3,56 +3,59 @@ import ReactTestUtils from 'react-dom/test-utils'; import CompanyRegisterModal from '../../components/CompanyRegisterModal'; describe('CompanyRegisterModal', () => { - function validatePassword(password) { - const lowerCaseLetters = /[a-z]/g; - const upperCaseLetters = /[A-Z]/g; - const numbers = /[0-9]/g; - if(password.length < 8) { - return "Password less than 8"; - } else { - if(!lowerCaseLetters.test(password)) { - return "Password at least one lowercase letter"; - } - - if(!upperCaseLetters.test(password)) { - return "Password at least one uppercase letter"; - } - - if(!numbers.test(password)) { - return "Password at least one number"; - } - - return true - } + function validatePassword(password) { + const lowerCaseLetters = /[a-z]/g; + const upperCaseLetters = /[A-Z]/g; + const numbers = /[0-9]/g; + if (password.length < 8) { + return 'Password less than 8'; + } + if (!lowerCaseLetters.test(password)) { + return 'Password at least one lowercase letter'; + } + + if (!upperCaseLetters.test(password)) { + return 'Password at least one uppercase letter'; + } + + if (!numbers.test(password)) { + return 'Password at least one number'; } - it('renders without problem', () => { - const companyRegister = ReactTestUtils.renderIntoDocument( - <CompanyRegisterModal />); - expect(companyRegister).to.exist; - }); - - it('renders form without problem', () => { - const companyRegister = ReactTestUtils.renderIntoDocument( - <CompanyRegisterModal />); - const registerForm = ReactTestUtils.scryRenderedDOMComponentsWithTag(companyRegister, 'Form'); - expect(registerForm).to.exist; - }); - - it('renders category options without problem', () => { - const companyRegister = ReactTestUtils.renderIntoDocument( - <CompanyRegisterModal />); - expect(companyRegister.categoryOptions).to.exist; - }); - - it('handle password validation', () => { - const password = '3s24Aasd'; - expect(validatePassword(password)).to.equal(true); - }); - - it('Register modals state contain benefits', () => { - const companyRegister = ReactTestUtils.renderIntoDocument( - <CompanyRegisterModal />); - expect(companyRegister.state.benefits).to.exist; - }); + return true; + } + + it('renders without problem', () => { + const companyRegister = ReactTestUtils.renderIntoDocument( + <CompanyRegisterModal />, + ); + expect(companyRegister).to.exist; + }); + + it('renders form without problem', () => { + const companyRegister = ReactTestUtils.renderIntoDocument( + <CompanyRegisterModal />, + ); + const registerForm = ReactTestUtils.scryRenderedDOMComponentsWithTag(companyRegister, 'Form'); + expect(registerForm).to.exist; + }); + + it('renders category options without problem', () => { + const companyRegister = ReactTestUtils.renderIntoDocument( + <CompanyRegisterModal />, + ); + expect(companyRegister.categoryOptions).to.exist; + }); + + it('handle password validation', () => { + const password = '3s24Aasd'; + expect(validatePassword(password)).to.equal(true); + }); + + it('Register modals state contain benefits', () => { + const companyRegister = ReactTestUtils.renderIntoDocument( + <CompanyRegisterModal />, + ); + expect(companyRegister.state.benefits).to.exist; + }); }); diff --git a/assets/js/__test__/components/CompanyVacancy-test.jsx b/assets/js/__test__/components/CompanyVacancy-test.jsx index 0ac81371cfbb749740304405e7e28f04cfd9a8a5..f5b862d9db139a0651aa0bca88fb62dc1e889a7a 100755 --- a/assets/js/__test__/components/CompanyVacancy-test.jsx +++ b/assets/js/__test__/components/CompanyVacancy-test.jsx @@ -55,26 +55,30 @@ describe('CompanyVacancy', () => { }; it('renders with logo without problem', () => { - const companyVacancy = ReactTestUtils.renderIntoDocument( - <CompanyVacancy data={response2} />); - expect(companyVacancy).to.exist; + const companyVacancy = ReactTestUtils.renderIntoDocument( + <CompanyVacancy data={response2} />, + ); + expect(companyVacancy).to.exist; }); it('renders without logo without problem', () => { const companyVacancy = ReactTestUtils.renderIntoDocument( - <CompanyVacancy data={response} />); + <CompanyVacancy data={response} />, + ); expect(companyVacancy).to.exist; }); it('renders without logo for unverified company without problem', () => { const companyVacancy = ReactTestUtils.renderIntoDocument( - <CompanyVacancy data={response3} />); + <CompanyVacancy data={response3} />, + ); expect(companyVacancy).to.exist; }); it('loads when delete button clicked', () => { const companyVacancy = ReactTestUtils.renderIntoDocument( - <CompanyVacancy data={response} />); + <CompanyVacancy data={response} />, + ); const button = ReactTestUtils.findRenderedDOMComponentWithTag(companyVacancy, 'Button'); ReactTestUtils.Simulate.click(button); expect(companyVacancy.state.deleteLoading).to.equal(true); diff --git a/assets/js/__test__/components/ConfirmationModal-test.jsx b/assets/js/__test__/components/ConfirmationModal-test.jsx index 1f2f65e3109f118e7a055f275d8e9b764d97522c..c7e42229a1ef9eb38186cd23e5c942c1e75c8081 100755 --- a/assets/js/__test__/components/ConfirmationModal-test.jsx +++ b/assets/js/__test__/components/ConfirmationModal-test.jsx @@ -1,11 +1,10 @@ import React from 'react'; import ReactTestUtils from 'react-dom/test-utils'; -import ConfirmationModal from '../../components/ConfirmationModal'; import fetchMock from 'fetch-mock'; +import ConfirmationModal from '../../components/ConfirmationModal'; import Storage from '../../lib/Storage'; describe('ConfirmationModal', () => { - it('renders without problem', () => { const applyModal = ReactTestUtils.renderIntoDocument( <ConfirmationModal />, diff --git a/assets/js/__test__/components/Footer-test.jsx b/assets/js/__test__/components/Footer-test.jsx index 183ae7dd77a309fc9a410e4da439f8b28482f344..8f9600b0c6a2df635fd99444db260910a71f442a 100755 --- a/assets/js/__test__/components/Footer-test.jsx +++ b/assets/js/__test__/components/Footer-test.jsx @@ -3,10 +3,10 @@ import ReactTestUtils from 'react-dom/test-utils'; import Footer from '../../components/Footer'; describe('Footer', () => { - it('renders without problem', () => { const footer = ReactTestUtils.renderIntoDocument( - <Footer params={{ id: 1 }} />); + <Footer params={{ id: 1 }} />, + ); expect(footer).to.exist; }); }); diff --git a/assets/js/__test__/components/InfoLowonganModal-test.jsx b/assets/js/__test__/components/InfoLowonganModal-test.jsx index 3d86f8b190942ff4388ca8bd0423da370a6596a4..6a5f52d3e0fb5cc68162d938a199721d32c6fa03 100644 --- a/assets/js/__test__/components/InfoLowonganModal-test.jsx +++ b/assets/js/__test__/components/InfoLowonganModal-test.jsx @@ -6,18 +6,18 @@ import InfoLowonganModal from '../../components/InfoLowonganModal'; describe('InfoLowonganModal', () => { it('renders without problem', () => { const modalInfo = ReactTestUtils.renderIntoDocument( - <InfoLowonganModal buttonTitle="submit" /> + <InfoLowonganModal buttonTitle="submit" />, ); expect(modalInfo).to.exist; }); it('open without problem', () => { const modalInfo = ReactTestUtils.renderIntoDocument( - <InfoLowonganModal buttonTitle="submit" /> + <InfoLowonganModal buttonTitle="submit" />, ); const modal = ReactTestUtils.findRenderedDOMComponentWithTag( modalInfo, - 'Button' + 'Button', ); modalInfo.handleApply(); ReactTestUtils.Simulate.click(modal); @@ -26,11 +26,11 @@ describe('InfoLowonganModal', () => { it('open with problem', () => { const modalInfo = ReactTestUtils.renderIntoDocument( - <InfoLowonganModal buttonTitle="submit" /> + <InfoLowonganModal buttonTitle="submit" />, ); const modal = ReactTestUtils.findRenderedDOMComponentWithTag( modalInfo, - 'Button' + 'Button', ); ReactTestUtils.Simulate.click(modal); expect(modalInfo).to.exist; diff --git a/assets/js/__test__/components/LoginForm-test.jsx b/assets/js/__test__/components/LoginForm-test.jsx index 984f82e103e8c6b44d5ea4f6ba37eb2fa2de9090..de5e90900e582437625b94aead13ad70696af2ec 100755 --- a/assets/js/__test__/components/LoginForm-test.jsx +++ b/assets/js/__test__/components/LoginForm-test.jsx @@ -12,21 +12,25 @@ describe('LoginForm', () => { it('renders without problem', () => { const formLogin = ReactTestUtils.renderIntoDocument( - <LoginForm url="" />); + <LoginForm url="" />, + ); expect(formLogin).to.exist; const formDiv = ReactTestUtils.findRenderedDOMComponentWithClass( - formLogin, 'formLogin'); + formLogin, 'formLogin', + ); expect(formDiv).to.exist; const form = ReactTestUtils.findRenderedDOMComponentWithTag( - formLogin, 'form'); + formLogin, 'form', + ); expect(form).to.exist; }); it('handle email input without problem', () => { const formLogin = ReactTestUtils.renderIntoDocument( - <LoginForm type="sso-ui" />); + <LoginForm type="sso-ui" />, + ); expect(formLogin.state.username).to.equal(''); const emailNode = ReactTestUtils.scryRenderedDOMComponentsWithTag(formLogin, 'Input')[0]; // const emailNode = ReactDOM.findDOMNode(formLogin.refs.email); @@ -40,7 +44,8 @@ describe('LoginForm', () => { it('handle password input without problem', () => { const formLogin = ReactTestUtils.renderIntoDocument( - <LoginForm type="sso-ui" />); + <LoginForm type="sso-ui" />, + ); const passwordNode = ReactTestUtils.scryRenderedDOMComponentsWithTag(formLogin, 'Input')[1]; // const passwordNode = ReactDOM.findDOMNode(formLogin.refs.password); @@ -55,7 +60,8 @@ describe('LoginForm', () => { it('submit form without problem', () => { fetchMock.post('*', { data: 'value' }); const formLogin = ReactTestUtils.renderIntoDocument( - <LoginForm url="" />); + <LoginForm url="" />, + ); const submitButton = ReactTestUtils.findRenderedDOMComponentWithTag(formLogin, 'Button'); ReactTestUtils.Simulate.click(submitButton); @@ -68,7 +74,8 @@ describe('LoginForm', () => { it('submit form with problem', () => { fetchMock.post('*', 404); const formLogin = ReactTestUtils.renderIntoDocument( - <LoginForm url="" />); + <LoginForm url="" />, + ); const submitButton = ReactTestUtils.findRenderedDOMComponentWithTag(formLogin, 'Button'); ReactTestUtils.Simulate.click(submitButton); diff --git a/assets/js/__test__/components/Pagination-test.jsx b/assets/js/__test__/components/Pagination-test.jsx index b6c98ca220c5ce2b69d7148385a7c6f8b955b507..e0a6bf9c1eb672cedd035ae2248902de0e71f359 100755 --- a/assets/js/__test__/components/Pagination-test.jsx +++ b/assets/js/__test__/components/Pagination-test.jsx @@ -84,7 +84,8 @@ describe('Pagination', () => { it('renders without problem', () => { fetchMock.get('*', response); const pagination = ReactTestUtils.renderIntoDocument( - <Pagination child={<div />} url="test" />); + <Pagination child={<div />} url="test" />, + ); expect(pagination).to.exist; fetchMock.restore(); }); @@ -92,7 +93,8 @@ describe('Pagination', () => { it('renders without problem when it is the first or last page', () => { fetchMock.get('*', response2); const pagination = ReactTestUtils.renderIntoDocument( - <Pagination child={<div />} url="test" />); + <Pagination child={<div />} url="test" />, + ); expect(pagination).to.exist; fetchMock.restore(); }); @@ -100,7 +102,8 @@ describe('Pagination', () => { it('get items without problem', () => { fetchMock.get('*', response); const pagination = ReactTestUtils.renderIntoDocument( - <Pagination child={<div />} url="test" />); + <Pagination child={<div />} url="test" />, + ); pagination.getItemsData().then(() => { expect(JSON.stringify(pagination.state.items)).to.equal(JSON.stringify(response.items)); }); @@ -110,7 +113,8 @@ describe('Pagination', () => { it('renders without problem when failed getting data', () => { fetchMock.get('*', 404); const pagination = ReactTestUtils.renderIntoDocument( - <Pagination child={<div />} url="test" />); + <Pagination child={<div />} url="test" />, + ); expect(pagination).to.exist; fetchMock.restore(); }); @@ -119,7 +123,8 @@ describe('Pagination', () => { fetchMock.restore(); fetchMock.get('*', response); const pagination = ReactTestUtils.renderIntoDocument( - <Pagination child={<div />} url="test" />); + <Pagination child={<div />} url="test" />, + ); pagination.getItemsData().then(() => { const prev = ReactTestUtils.scryRenderedDOMComponentsWithTag(pagination, 'Menu.Item')[0]; ReactTestUtils.Simulate.click(prev); @@ -131,7 +136,8 @@ describe('Pagination', () => { it('can refresh without problem', () => { fetchMock.get('*', response); const pagination = ReactTestUtils.renderIntoDocument( - <Pagination child={<div />} url="test" />); + <Pagination child={<div />} url="test" />, + ); pagination.getItemsData().then(() => { const next = ReactTestUtils.scryRenderedDOMComponentsWithTag(pagination, 'Menu.Item')[1]; ReactTestUtils.Simulate.click(next); @@ -143,7 +149,8 @@ describe('Pagination', () => { it('can go next without problem', () => { fetchMock.get('*', response); const pagination = ReactTestUtils.renderIntoDocument( - <Pagination child={<div />} url="test" />); + <Pagination child={<div />} url="test" />, + ); pagination.getItemsData().then(() => { const next = ReactTestUtils.scryRenderedDOMComponentsWithTag(pagination, 'Menu.Item')[2]; ReactTestUtils.Simulate.click(next); @@ -155,7 +162,8 @@ describe('Pagination', () => { it('cannot go next or prev without problem', () => { fetchMock.get('*', response2); const pagination = ReactTestUtils.renderIntoDocument( - <Pagination child={<div />} url="test" />); + <Pagination child={<div />} url="test" />, + ); pagination.getItemsData().then(() => { const next = ReactTestUtils.scryRenderedDOMComponentsWithTag(pagination, 'Menu.Item')[2]; ReactTestUtils.Simulate.click(next); @@ -167,4 +175,3 @@ describe('Pagination', () => { fetchMock.restore(); }); }); - diff --git a/assets/js/__test__/components/TopMenu-test.jsx b/assets/js/__test__/components/TopMenu-test.jsx index 29d29e85d96fc0e8062a7b902035c4542605ec9a..fc18a4d23290fd16686f992d100a89343210fd5e 100755 --- a/assets/js/__test__/components/TopMenu-test.jsx +++ b/assets/js/__test__/components/TopMenu-test.jsx @@ -2,8 +2,8 @@ import React from 'react'; import ReactTestUtils from 'react-dom/test-utils'; import fetchMock from 'fetch-mock'; -import TopMenu from '../../components/TopMenu'; import moment from 'moment'; +import TopMenu from '../../components/TopMenu'; describe('TopMenu', () => { fetchMock.restore(); @@ -161,7 +161,8 @@ describe('TopMenu', () => { it('renders for company without problem', () => { const topmenu = ReactTestUtils.renderIntoDocument( - <TopMenu user={companyUser} />); + <TopMenu user={companyUser} />, + ); expect(topmenu).to.exist; }); @@ -169,7 +170,8 @@ describe('TopMenu', () => { const topmenu = ReactTestUtils.renderIntoDocument( <TopMenu user={supervisorUser}> <div> test </div> - </TopMenu>); + </TopMenu>, + ); expect(topmenu).to.exist; }); @@ -177,7 +179,8 @@ describe('TopMenu', () => { const topmenu = ReactTestUtils.renderIntoDocument( <TopMenu user={adminUser1}> <div> test </div> - </TopMenu>); + </TopMenu>, + ); expect(topmenu).to.exist; }); @@ -185,7 +188,8 @@ describe('TopMenu', () => { const topmenu = ReactTestUtils.renderIntoDocument( <TopMenu user={studentUser}> <div> test </div> - </TopMenu>); + </TopMenu>, + ); expect(topmenu).to.exist; }); @@ -193,7 +197,8 @@ describe('TopMenu', () => { const topmenu = ReactTestUtils.renderIntoDocument( <TopMenu user={errorUser}> <div> test </div> - </TopMenu>); + </TopMenu>, + ); expect(topmenu).to.exist; }); @@ -202,7 +207,8 @@ describe('TopMenu', () => { const topmenu = ReactTestUtils.renderIntoDocument( <TopMenu user={adminUser1}> <div> test </div> - </TopMenu>); + </TopMenu>, + ); topmenu.logout(new Event('click')); expect(topmenu).to.exist; }); @@ -211,7 +217,8 @@ describe('TopMenu', () => { const topmenu = ReactTestUtils.renderIntoDocument( <TopMenu user={adminUser2}> <div> test </div> - </TopMenu>); + </TopMenu>, + ); topmenu.handleItemClick(new Event('click'), 'undefined'); expect(topmenu.state.activeItem).to.equal(undefined); }); @@ -220,36 +227,40 @@ describe('TopMenu', () => { const topmenu = ReactTestUtils.renderIntoDocument( <TopMenu user={adminUser2}> <div> test </div> - </TopMenu>); + </TopMenu>, + ); expect(topmenu.state.todayQuote).to.not.equal(undefined); - }); + }); - it('check popup is open', () => { + it('check popup is open', () => { const topmenu = ReactTestUtils.renderIntoDocument( <TopMenu user={adminUser2}> <div> test </div> - </TopMenu>); - topmenu.handleOpen(); - expect(topmenu.state.isOpen).to.equal(true); - }); + </TopMenu>, + ); + topmenu.handleOpen(); + expect(topmenu.state.isOpen).to.equal(true); + }); - it('check popup is close', () => { + it('check popup is close', () => { const topmenu = ReactTestUtils.renderIntoDocument( <TopMenu user={adminUser2}> <div> test </div> - </TopMenu>); - topmenu.handleClose(); - expect(topmenu.state.isOpen).to.equal(false); - }); + </TopMenu>, + ); + topmenu.handleClose(); + expect(topmenu.state.isOpen).to.equal(false); + }); it('TopMenu state contain right current date time', () => { moment.locale('id'); const date = new Date(); - const expectedDate = moment(date).format('dddd') + ', ' + moment(date).format('LL'); + const expectedDate = `${moment(date).format('dddd')}, ${moment(date).format('LL')}`; const topMenu = ReactTestUtils.renderIntoDocument( <TopMenu user={adminUser2}> <div> test </div> - </TopMenu>); + </TopMenu>, + ); expect(topMenu.state.currentDate).to.equal(expectedDate); }); @@ -257,7 +268,7 @@ describe('TopMenu', () => { const topMenu = ReactTestUtils.renderIntoDocument( <TopMenu user={studentUser}> <div> test </div> - </TopMenu> + </TopMenu>, ); expect(topMenu.state.applianceInformation).to.exist; }); @@ -266,10 +277,8 @@ describe('TopMenu', () => { const topMenu = ReactTestUtils.renderIntoDocument( <TopMenu user={studentUser}> <div> test </div> - </TopMenu> + </TopMenu>, ); expect(topMenu.state.kapeDescription).to.exist; }); - }); - diff --git a/assets/js/__test__/components/Vacancy-test.jsx b/assets/js/__test__/components/Vacancy-test.jsx index 10792bcc6ab9815adce6b3864aee65e4b85d43bf..fe55e025526fbdbecc08552bf0652d3dcd5152a1 100755 --- a/assets/js/__test__/components/Vacancy-test.jsx +++ b/assets/js/__test__/components/Vacancy-test.jsx @@ -94,44 +94,51 @@ describe('Vacancy', () => { it('renders with null picture and apply button without problem', () => { const lowongan = ReactTestUtils.renderIntoDocument( - <Vacancy status={0} user={studentUser} data={response} />); + <Vacancy status={0} user={studentUser} data={response} />, + ); expect(lowongan).to.exist; }); it('renders with null picture and cancel button without problem', () => { const lowongan = ReactTestUtils.renderIntoDocument( - <Vacancy status={1} user={studentUser} data={response} />); + <Vacancy status={1} user={studentUser} data={response} />, + ); expect(lowongan).to.exist; }); it('renders with picture and apply button without problem', () => { const lowongan = ReactTestUtils.renderIntoDocument( - <Vacancy status={0} user={studentUser} data={response2} />); + <Vacancy status={0} user={studentUser} data={response2} />, + ); expect(lowongan).to.exist; }); it('renders with picture and cancel button without problem', () => { const lowongan = ReactTestUtils.renderIntoDocument( - <Vacancy status={2} user={studentUser} data={response2} />); + <Vacancy status={2} user={studentUser} data={response2} />, + ); expect(lowongan).to.exist; }); it('renders for accepted without problem', () => { const lowongan = ReactTestUtils.renderIntoDocument( - <Vacancy status={4} user={studentUser} data={response2} />); + <Vacancy status={4} user={studentUser} data={response2} />, + ); expect(lowongan).to.exist; }); it('renders for rejected without problem', () => { const lowongan = ReactTestUtils.renderIntoDocument( - <Vacancy status={3} user={studentUser} data={response2} />); + <Vacancy status={3} user={studentUser} data={response2} />, + ); expect(lowongan).to.exist; }); it('bookmarks without problem', () => { fetchMock.post('*', response); const lowongan = ReactTestUtils.renderIntoDocument( - <Vacancy status="Daftar" user={studentUser} data={response2} />); + <Vacancy status="Daftar" user={studentUser} data={response2} />, + ); const response3 = { student: { id: 1, name: 2 } }; expect(lowongan.props.data.id).to.equal(3); Storage.set('user-data', response3); @@ -143,7 +150,8 @@ describe('Vacancy', () => { fetchMock.delete('*', { data: 'value' }); fetchMock.get('*', { count: 'value' }); const lowongan = ReactTestUtils.renderIntoDocument( - <Vacancy status="Daftar" user={studentUser} data={response2} bookmarked={1} />); + <Vacancy status="Daftar" user={studentUser} data={response2} bookmarked={1} />, + ); const response3 = { student: { id: 1, name: 2 } }; lowongan.removeVacancyApplication(); lowongan.openConfirmationModal(); @@ -158,7 +166,8 @@ describe('Vacancy', () => { fetchMock.delete('*', 404); fetchMock.get('*', { count: 'value' }); const lowongan = ReactTestUtils.renderIntoDocument( - <Vacancy status="Daftar" user={studentUser} data={response2} bookmarked={1} />); + <Vacancy status="Daftar" user={studentUser} data={response2} bookmarked={1} />, + ); const response3 = { student: { id: 1, name: 2 } }; lowongan.removeVacancyApplication(); expect(lowongan.props.data.id).to.equal(3); diff --git a/assets/js/__test__/components/VacancyList-test.jsx b/assets/js/__test__/components/VacancyList-test.jsx index 53c2592fc37d3e70d66d8269bc2adf30a903b1fa..5a340a3aa246d76a494047985e4d54fe40e5394d 100755 --- a/assets/js/__test__/components/VacancyList-test.jsx +++ b/assets/js/__test__/components/VacancyList-test.jsx @@ -5,7 +5,6 @@ import fetchMock from 'fetch-mock'; import VacancyList from '../../components/VacancyList'; describe('VacancyList', () => { - const companyUser = { role: 'company', data: { @@ -299,7 +298,7 @@ describe('VacancyList', () => { ]; const response = [{ - salary: '1', + salary: '1', close_time: '2019-03-28T05:55:42Z', company: { address: 'kebayoran baru', @@ -320,7 +319,7 @@ describe('VacancyList', () => { total_accepted_applicants: 0, working_period: 'Juli-Agustus', }, { - salary: '1', + salary: '1', close_time: '2019-03-28T05:55:42Z', company: { address: 'kebayoran baru', @@ -343,7 +342,7 @@ describe('VacancyList', () => { }]; const response2 = [{ - salary: '1', + salary: '1', close_time: '2019-03-28T05:55:42Z', company: { address: 'kebayoran baru', @@ -367,14 +366,16 @@ describe('VacancyList', () => { it('renders without problem', () => { const vacancyList = ReactTestUtils.renderIntoDocument( - <VacancyList items={newResponse} userId={1} user={studentUser} />); + <VacancyList items={newResponse} userId={1} user={studentUser} />, + ); vacancyList.generateVacancies(); expect(vacancyList).to.exist; }); it('renders without problem for company', () => { const vacancyList = ReactTestUtils.renderIntoDocument( - <VacancyList items={newResponse} userId={1} user={companyUser} />); + <VacancyList items={newResponse} userId={1} user={companyUser} />, + ); vacancyList.generateVacancies(); vacancyList.state.vacancies = newResponse; expect(vacancyList.generateVacancies()).to.exist; @@ -382,14 +383,16 @@ describe('VacancyList', () => { it('renders without problem for supervisor', () => { const vacancyList = ReactTestUtils.renderIntoDocument( - <VacancyList items={newResponse} userId={3} user={supervisorUser} />); + <VacancyList items={newResponse} userId={3} user={supervisorUser} />, + ); vacancyList.state.vacancies = newResponse; expect(vacancyList.generateVacancies()).to.exist; }); it('update status without problem', () => { const vacancyList = ReactTestUtils.renderIntoDocument( - <VacancyList items={newResponse} userId={3} user={supervisorUser} />); + <VacancyList items={newResponse} userId={3} user={supervisorUser} />, + ); vacancyList.state.vacancies = newResponse; vacancyList.updateStatus(4, 1); }); @@ -399,7 +402,8 @@ describe('VacancyList', () => { fetchMock.delete('*', response2); fetchMock.get('*', newResponse); const vacancyList = ReactTestUtils.renderIntoDocument( - <VacancyList items={newResponse} userId={1} deleteCallback={() => {}} user={companyUser} />); + <VacancyList items={newResponse} userId={1} deleteCallback={() => {}} user={companyUser} />, + ); vacancyList.state.vacancies = newResponse; vacancyList.deleteVacancy(1).then(() => { expect(JSON.stringify(vacancyList.state.vacancies)).to.equal(JSON.stringify(newResponse)); @@ -427,4 +431,3 @@ describe('VacancyList', () => { }); }); }); - diff --git a/assets/js/__test__/components/VerifyAdminModal-test.jsx b/assets/js/__test__/components/VerifyAdminModal-test.jsx index 2ba07091316a6b878af9d760ba8ca9e45ceae328..a481f885399c152aefe044aa12544678f3eb6c74 100755 --- a/assets/js/__test__/components/VerifyAdminModal-test.jsx +++ b/assets/js/__test__/components/VerifyAdminModal-test.jsx @@ -3,7 +3,6 @@ import ReactTestUtils from 'react-dom/test-utils'; import VerifyAdminModal from '../../components/VerifyAdminModal'; describe('VerifyAdminModal', () => { - it('renders without problem', () => { const verifyModal = ReactTestUtils.renderIntoDocument( <VerifyAdminModal />, @@ -12,19 +11,21 @@ describe('VerifyAdminModal', () => { }); it('open without problem', () => { - const verifyModal = ReactTestUtils.renderIntoDocument( - <VerifyAdminModal id={4} />); + const verifyModal = ReactTestUtils.renderIntoDocument( + <VerifyAdminModal id={4} />, + ); - const modal = ReactTestUtils.findRenderedDOMComponentWithTag(verifyModal, 'Button'); - ReactTestUtils.Simulate.click(modal); - expect(verifyModal.state.modalOpen).to.equal(true); - }); + const modal = ReactTestUtils.findRenderedDOMComponentWithTag(verifyModal, 'Button'); + ReactTestUtils.Simulate.click(modal); + expect(verifyModal.state.modalOpen).to.equal(true); + }); - it('close without problem', () => { - const verifyModal = ReactTestUtils.renderIntoDocument( - <VerifyAdminModal id={4} />); + it('close without problem', () => { + const verifyModal = ReactTestUtils.renderIntoDocument( + <VerifyAdminModal id={4} />, + ); - verifyModal.handleClose(); - expect(verifyModal.state.modalOpen).to.equal(false); - }); + verifyModal.handleClose(); + expect(verifyModal.state.modalOpen).to.equal(false); + }); }); diff --git a/assets/js/components/AdminVacancy.jsx b/assets/js/components/AdminVacancy.jsx index 419f5abe348770ad67c728119fb9c0fdedf5377d..bb7ad896693b07b3a8f99889efc316f5a694e3ce 100755 --- a/assets/js/components/AdminVacancy.jsx +++ b/assets/js/components/AdminVacancy.jsx @@ -65,7 +65,10 @@ export default class AdminVacancy extends React.Component { <Item.Header as="a">{this.props.data.name}</Item.Header> <Grid.Row> <Grid.Column floated="left"> - <h4>{this.props.data.company.name} </h4> + <h4> + {this.props.data.company.name} + {' '} + </h4> {this.props.data.company.address} </Grid.Column> <Grid.Column floated="right">{this.generateButton()}</Grid.Column> diff --git a/assets/js/components/AdminVerificationModal.jsx b/assets/js/components/AdminVerificationModal.jsx index 487ce7de76f382385549039a7b2012d634982060..de5da867adc622cd0be62b02023d5b2c56fa7332 100755 --- a/assets/js/components/AdminVerificationModal.jsx +++ b/assets/js/components/AdminVerificationModal.jsx @@ -1,8 +1,9 @@ import React from 'react'; -import { Button, Header, Modal, Grid } from 'semantic-ui-react'; +import { + Button, Header, Modal, Grid, +} from 'semantic-ui-react'; export default class AdminVerificationModal extends React.Component { - state = { modalOpen: false } componentWillUpdate() { @@ -38,7 +39,7 @@ export default class AdminVerificationModal extends React.Component { onClose={this.handleClose} > <Modal.Header>Software Engineer</Modal.Header> - <Modal.Content > + <Modal.Content> <Modal.Description> <Header>Deskripsi Lowongan</Header> Lorem ipsum dolor sit amet, consectetur adipiscing elit, @@ -49,9 +50,9 @@ export default class AdminVerificationModal extends React.Component { </Modal.Content> <Modal.Actions> - <Grid columns={2} > + <Grid columns={2}> <Grid.Column> - <Button color="red" floated="left" onClick={this.handleClose} >Hapus</Button> + <Button color="red" floated="left" onClick={this.handleClose}>Hapus</Button> </Grid.Column> <Grid.Column> <Button color="blue" floated="right" onClick={this.handleClose}>Ubah</Button> diff --git a/assets/js/components/Applicant.jsx b/assets/js/components/Applicant.jsx index 16383832366941e6d1b598b3c530a71fd9f8837f..e28a852ef1870094f6a415be8bd2e754a8410eb8 100755 --- a/assets/js/components/Applicant.jsx +++ b/assets/js/components/Applicant.jsx @@ -85,8 +85,14 @@ export default class Applicant extends React.Component { <Item.Extra> <Grid.Row> <Grid.Column floated="left"> - <h4> {this.props.data.student.name} </h4> - {this.props.data.vacancy.name} <br /> + <h4> + {' '} + {this.props.data.student.name} + {' '} + </h4> + {this.props.data.vacancy.name} + {' '} + <br /> {this.props.data.student.major} </Grid.Column> <Grid.Column floated="right" textAlign="center"> @@ -95,8 +101,8 @@ export default class Applicant extends React.Component { icon="star" size="massive" defaultRating={ - this.props.data.status === - Applicant.APPLICATION_STATUS.BOOKMARKED + this.props.data.status + === Applicant.APPLICATION_STATUS.BOOKMARKED ? 1 : 0 } diff --git a/assets/js/components/ApplicantList.jsx b/assets/js/components/ApplicantList.jsx index 3b694ad3a6ea29b21840e9af95a2920a866db4b4..c4d5002fe3c47935e54de680030ff66f2446a483 100755 --- a/assets/js/components/ApplicantList.jsx +++ b/assets/js/components/ApplicantList.jsx @@ -46,16 +46,15 @@ export default class ApplicantList extends React.Component { ); } return this.state.applications.map( - (application) => - (application.status === this.props.status || - this.props.status === Applicant.APPLICATION_STATUS.ALL) && ( + (application) => (application.status === this.props.status + || this.props.status === Applicant.APPLICATION_STATUS.ALL) && ( <Applicant key={application.id} data={application} updateStatus={this.updateStatus} isAll={this.props.status === Applicant.APPLICATION_STATUS.ALL} /> - ), + ), ); } diff --git a/assets/js/components/ApplicationList.jsx b/assets/js/components/ApplicationList.jsx index 09fd215bae65e9da4fc0196661460ff40b34569a..4e904b81a361f3088df0a063e94e2ef41aef01ca 100755 --- a/assets/js/components/ApplicationList.jsx +++ b/assets/js/components/ApplicationList.jsx @@ -19,7 +19,8 @@ export default class ApplicationList extends React.Component { return cols2.map((colData) => ( <Table.HeaderCell singleLine key={colData.key}> {' '} - {colData.label}{' '} + {colData.label} + {' '} </Table.HeaderCell> )); } @@ -29,9 +30,21 @@ export default class ApplicationList extends React.Component { <Table.Row key={`${item.npm}_${item.major}_${item.company}_${item.position}_${item.status}_row`} > - <Table.Cell key={`${item.name}_name`}> {item.name} </Table.Cell> - <Table.Cell key={`${item.name}_npm`}> {item.npm} </Table.Cell> - <Table.Cell key={`${item.name}_major`}> {item.major} </Table.Cell> + <Table.Cell key={`${item.name}_name`}> + {' '} + {item.name} + {' '} + </Table.Cell> + <Table.Cell key={`${item.name}_npm`}> + {' '} + {item.npm} + {' '} + </Table.Cell> + <Table.Cell key={`${item.name}_major`}> + {' '} + {item.major} + {' '} + </Table.Cell> <Table.Cell key={`${item.name}_company`}> {item.company_name} </Table.Cell> diff --git a/assets/js/components/ApplyModal.jsx b/assets/js/components/ApplyModal.jsx index dd32c9c3887d61bfef22457274aa24f590b75fb4..df415169d44cd528a0dcc72da4e6a4eb7b907c42 100755 --- a/assets/js/components/ApplyModal.jsx +++ b/assets/js/components/ApplyModal.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import moment from 'moment'; import { Icon, @@ -9,12 +8,11 @@ import { Form, Message, } from 'semantic-ui-react'; -import ModalAlert from './../components/ModalAlert'; -import Server from './../lib/Server'; +import ModalAlert from './ModalAlert'; +import Server from '../lib/Server'; import GeneralModal from './GeneralModal'; export default class ApplyModal extends GeneralModal { - handleApply = () => { if (this.props.resume) { this.setState({ load: true }); @@ -34,11 +32,11 @@ export default class ApplyModal extends GeneralModal { const isApplicationClosed = moment(this.props.data.close_time) < moment.now(); return ( <Modal - trigger={ + trigger={( <Button primary onClick={this.handleOpen} floated="right"> {this.props.buttonTitle} </Button> - } + )} closeIcon="close" open={this.state.modalOpen} onClose={this.handleClose} @@ -55,24 +53,20 @@ export default class ApplyModal extends GeneralModal { {' '} <h3> Deskripsi Lowongan </h3> </Modal.Header> - { - <div - dangerouslySetInnerHTML={{ - __html: this.props.data.description, - }} - /> - } + <div + dangerouslySetInnerHTML={{ + __html: this.props.data.description, + }} + /> <Modal.Header> {' '} <h3> Deskripsi Perusahaan </h3> </Modal.Header> - { - <div - dangerouslySetInnerHTML={{ - __html: this.props.data.companydescription, - }} - /> - } + <div + dangerouslySetInnerHTML={{ + __html: this.props.data.companydescription, + }} + /> </Modal.Description> <br /> <Modal.Description> @@ -80,13 +74,11 @@ export default class ApplyModal extends GeneralModal { {' '} <h3> Tanggung Jawab Lowongan </h3> </Modal.Header> - { - <div - dangerouslySetInnerHTML={{ - __html: this.props.data.responsibilities, - }} - /> - } + <div + dangerouslySetInnerHTML={{ + __html: this.props.data.responsibilities, + }} + /> </Modal.Description> <br /> <Modal.Description> @@ -94,11 +86,9 @@ export default class ApplyModal extends GeneralModal { {' '} <h3> Keuntungan </h3> </Modal.Header> - { - <div - dangerouslySetInnerHTML={{ __html: this.props.data.benefits }} - /> - } + <div + dangerouslySetInnerHTML={{ __html: this.props.data.benefits }} + /> </Modal.Description> <br /> <Modal.Description> @@ -106,13 +96,11 @@ export default class ApplyModal extends GeneralModal { {' '} <h3> Persyaratan </h3> </Modal.Header> - { - <div - dangerouslySetInnerHTML={{ - __html: this.props.data.requirements, - }} - /> - } + <div + dangerouslySetInnerHTML={{ + __html: this.props.data.requirements, + }} + /> </Modal.Description> <br /> {this.props.active && ( @@ -158,7 +146,8 @@ export default class ApplyModal extends GeneralModal { disabled={!this.props.active || isApplicationClosed} onClick={this.handleApply} > - {this.props.active ? 'Daftar' : 'Sudah Terdaftar'}{' '} + {this.props.active ? 'Daftar' : 'Sudah Terdaftar'} + {' '} <Icon name="right chevron" /> </Button> </Modal.Actions> diff --git a/assets/js/components/ApproveModal.jsx b/assets/js/components/ApproveModal.jsx index e44665920a0957feb8cad4c66eb5ac56e8a8f38a..aa577fe5387b5eed4fa46b6295f0136dacaa9124 100755 --- a/assets/js/components/ApproveModal.jsx +++ b/assets/js/components/ApproveModal.jsx @@ -1,9 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Modal, Button, Icon, Segment } from 'semantic-ui-react'; -import Server from './../lib/Server'; -import ConfirmationModal from './../components/ConfirmationModal'; -import Applicant from './../components/Applicant'; +import { + Modal, Button, Icon, Segment, +} from 'semantic-ui-react'; +import Server from '../lib/Server'; +import ConfirmationModal from './ConfirmationModal'; +import Applicant from './Applicant'; export default class ApproveModal extends React.Component { static propTypes = { @@ -42,11 +44,11 @@ export default class ApproveModal extends React.Component { fixBody = () => { const anotherModal = document.getElementsByClassName('ui page modals') .length; - if (anotherModal > 0) - document.body.classList.add('scrolling', 'dimmable', 'dimmed'); + if (anotherModal > 0) document.body.classList.add('scrolling', 'dimmable', 'dimmed'); }; handleOpen = () => this.setState({ modalOpen: true }); + handleClose = () => { this.readApplication(); this.setState({ modalOpen: false }); @@ -59,8 +61,8 @@ export default class ApproveModal extends React.Component { readApplication = () => { const data = { status: Applicant.APPLICATION_STATUS.READ }; return ( - this.props.data.status === Applicant.APPLICATION_STATUS.NEW && - Server.patch(`/applications/${this.props.data.id}/`, data).then( + this.props.data.status === Applicant.APPLICATION_STATUS.NEW + && Server.patch(`/applications/${this.props.data.id}/`, data).then( (status) => { this.props.updateStatus(this.props.data.id, status.status); }, @@ -118,11 +120,9 @@ export default class ApproveModal extends React.Component { gotoStudentResume = () => this.gotoLink(this.props.data.student.resume); - gotoStudentTranscript = () => - this.gotoLink(`/transkrip/${this.props.data.id}`); + gotoStudentTranscript = () => this.gotoLink(`/transkrip/${this.props.data.id}`); - gotoStudentProfile = () => - this.gotoLink(`/mahasiswa/${this.props.data.student.id}`); + gotoStudentProfile = () => this.gotoLink(`/mahasiswa/${this.props.data.student.id}`); accept = () => { this.modal.open( @@ -145,11 +145,11 @@ export default class ApproveModal extends React.Component { render = () => ( <Modal - trigger={ + trigger={( <Button primary onClick={this.handleOpen} floated="right"> Detail </Button> - } + )} closeIcon="close" open={this.state.modalOpen} onClose={this.handleClose} @@ -175,7 +175,8 @@ export default class ApproveModal extends React.Component { <b> {this.props.data.student.resume ? ( <a onClick={this.gotoStudentResume} href="#"> - CV Pelamar{' '} + CV Pelamar + {' '} </a> ) : ( 'Pelamar tidak memiliki CV' @@ -198,11 +199,15 @@ export default class ApproveModal extends React.Component { onClick={this.gotoStudentProfile} floated="left" > - <Icon name="user outline" /> Lihat Profil + <Icon name="user outline" /> + {' '} +Lihat Profil </Button> {this.props.data.status >= 4 ? ( <Button color="green" onClick={this.finish}> - <Icon name="check" /> Selesai KP + <Icon name="check" /> + {' '} +Selesai KP </Button> ) : ( <Button.Group> diff --git a/assets/js/components/Company.jsx b/assets/js/components/Company.jsx index 8aaa8e04ab313b0739e8235676511c5016b263f2..916c85b00b62a1aa8cbf0bcf1fe81eaa1e367e0b 100755 --- a/assets/js/components/Company.jsx +++ b/assets/js/components/Company.jsx @@ -1,9 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Item, Button, Grid, Icon } from 'semantic-ui-react'; +import { + Item, Button, Grid, Icon, +} from 'semantic-ui-react'; import Server from '../lib/Server'; import ModalAlert from './ModalAlert'; -import Storage from './../lib/Storage'; +import Storage from '../lib/Storage'; const defaultImage = 'https://semantic-ui.com/images/wireframe/image.png'; @@ -83,13 +85,17 @@ export default class Company extends React.Component { <Item.Extra> <Grid.Row> <Grid.Column floated="left" style={{ width: '100%' }}> - <h4> {this.props.data.name} </h4> + <h4> + {' '} + {this.props.data.name} + {' '} + </h4> {this.props.data.address} </Grid.Column> <Grid.Column floated="right" textAlign="center"> <div> - {this.props.data.status === - Company.COMPANY_STATUS.VERIFIED || ( + {this.props.data.status + === Company.COMPANY_STATUS.VERIFIED || ( <Button loading={this.state.acceptLoading} onClick={this.accept} @@ -100,8 +106,8 @@ export default class Company extends React.Component { Terima </Button> )} - {this.props.data.status === - Company.COMPANY_STATUS.UNVERIFIED || ( + {this.props.data.status + === Company.COMPANY_STATUS.UNVERIFIED || ( <Button loading={this.state.rejectLoading} onClick={this.reject} diff --git a/assets/js/components/CompanyList.jsx b/assets/js/components/CompanyList.jsx index a0ce801b68f2083ad9ec84a17d37a0981bcd6081..165d0e98c723222942ce7147b63a1819adbacf42 100755 --- a/assets/js/components/CompanyList.jsx +++ b/assets/js/components/CompanyList.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Item, Grid, Container } from 'semantic-ui-react'; -import Company from '../components/Company'; +import Company from './Company'; export default class CompanyList extends React.Component { static propTypes = { @@ -47,15 +47,14 @@ export default class CompanyList extends React.Component { ); } return this.state.companies.map( - (company) => - (company.status === this.props.status || - Company.COMPANY_STATUS.ALL === this.props.status) && ( + (company) => (company.status === this.props.status + || Company.COMPANY_STATUS.ALL === this.props.status) && ( <Company key={company.id} data={company} updateStatus={this.updateStatus} /> - ), + ), ); } diff --git a/assets/js/components/CompanyRegisterModal.jsx b/assets/js/components/CompanyRegisterModal.jsx index 0408440a049b1239aed8c676c11f210a6777cb6a..f149976246c6a161704c0645d06a4cc879176595 100755 --- a/assets/js/components/CompanyRegisterModal.jsx +++ b/assets/js/components/CompanyRegisterModal.jsx @@ -1,23 +1,24 @@ import React from 'react'; import { browserHistory } from 'react-router'; -import { Modal, Button, Form, Input, TextArea, Header, Icon, Dropdown } from 'semantic-ui-react'; -import ModalAlert from './../components/ModalAlert'; -import Server from './../lib/Server'; -import Storage from './../lib/Storage'; -import Dumper from './../lib/Dumper'; +import { + Modal, Button, Form, Input, TextArea, Header, Icon, Dropdown, +} from 'semantic-ui-react'; +import ModalAlert from './ModalAlert'; +import Server from '../lib/Server'; +import Storage from '../lib/Storage'; +import Dumper from '../lib/Dumper'; export default class CompanyRegisterModal extends React.Component { - constructor(props) { super(props); /* istanbul ignore next */ this.state = { loading: false, benefits: [ - {"text": "Mendapatkan peserta magang dari lulusan universitas terbaik di Indonesia"}, - {"text": "Mempermudah mencari calon peserta magang"}, - {"text": "Dan banyak keuntungan lainnya"} - ] + { text: 'Mendapatkan peserta magang dari lulusan universitas terbaik di Indonesia' }, + { text: 'Mempermudah mencari calon peserta magang' }, + { text: 'Dan banyak keuntungan lainnya' }, + ], }; this.handleChange = this.handleChange.bind(this); this.handleFile = this.handleFile.bind(this); @@ -41,7 +42,7 @@ export default class CompanyRegisterModal extends React.Component { { value: 'Perusahaan Perangkat Keras', text: 'Perusahaan Perangkat Keras' }, { value: 'Perusahaan Perangkat Lunak', text: 'Perusahaan Perangkat Lunak' }, { value: 'Perusahaan Teknologi', text: 'Perusahaan Teknologi' }, - { value: 'Perusahaan Telekomunikasi', text: 'Perusahaan Telekomunikasi' }, + { value: 'Perusahaan Telekomunikasi', text: 'Perusahaan Telekomunikasi' }, ] componentWillUpdate() { @@ -76,17 +77,17 @@ export default class CompanyRegisterModal extends React.Component { } else if (e.target.name === 'password-confirm') { this.passwordConfirmField = e.target; } - + const validatePassword = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}/g; - - if(!validatePassword.test(this.passwordField.value)) { - this.passwordField.setCustomValidity("Must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters"); + + if (!validatePassword.test(this.passwordField.value)) { + this.passwordField.setCustomValidity('Must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters'); } else { - this.passwordField.setCustomValidity(""); + this.passwordField.setCustomValidity(''); } - + const isExist = this.passwordField && this.passwordConfirmField; - + if (isExist) { if (this.passwordField.value !== this.passwordConfirmField.value) { this.passwordConfirmField.setCustomValidity("Passwords Don't Match"); @@ -102,104 +103,123 @@ export default class CompanyRegisterModal extends React.Component { Server.submit('/register/', this.state).then((response) => { Storage.set('user-data', response); browserHistory.push('/home'); - }, error => error.then((r) => { + }, (error) => error.then((r) => { this.setState({ loading: false }); this.modalAlert.open('Gagal Membuat Akun', Dumper.dump(r)); })); }; - render(){ + render() { const benefitViews = []; this.state.benefits.map((benefit, idx) => { const benefitView = ( <li key={idx}>{benefit.text}</li> - ) + ); benefitViews.push(benefitView); }); - return ( - <Modal trigger={<Button primary floated="right">Register</Button>} closeIcon="close"> - <Header icon="archive" content="Register for More Benefits" /> - <ul>{benefitViews}</ul> - <Modal.Content> - <ModalAlert ref={(modal) => { this.modalAlert = modal; }} /> - <Form onSubmit={this.handleSubmit}> - <Header as="h2" icon textAlign="center"> - <Icon name="signup" circular /> - <Header.Content> + return ( + <Modal trigger={<Button primary floated="right">Register</Button>} closeIcon="close"> + <Header icon="archive" content="Register for More Benefits" /> + <ul>{benefitViews}</ul> + <Modal.Content> + <ModalAlert ref={(modal) => { this.modalAlert = modal; }} /> + <Form onSubmit={this.handleSubmit}> + <Header as="h2" icon textAlign="center"> + <Icon name="signup" circular /> + <Header.Content> Register - </Header.Content> - </Header> - <Form.Field required> - <label htmlFor="email">Email</label> - <Input onChange={this.handleChange} type="email" name="email" icon="user" iconPosition="left" placeholder="email" required /> - </Form.Field> - <Form.Field required> - <label htmlFor="password">Password</label> - <Input - onChange={(e) => { this.handleChange(e); this.handlePassword(e); }} - type="password" id="password" name="password" icon="key" iconPosition="left" placeholder="password" required - /> - </Form.Field> - <Form.Field required> - <label htmlFor="password-confirm">Konfirmasi Password</label> - <Input - onChange={(e) => { this.handleChange(e); this.handlePassword(e); }} - type="password" id="password-confirm" name="password-confirm" icon="key" iconPosition="left" placeholder="password" required - /> - </Form.Field> - - <Form.Field required> - <label htmlFor="name">Nama Perusahaan</label> - <Input onChange={this.handleChange} placeholder="Nama Perusahaan" name="name" required /> - </Form.Field> - <Form.Field required> - <label htmlFor="name">Kategori Perusahaan</label> - <Dropdown - placeholder='Kategori Perusahaan' - fluid - name="category" - onChange={this.handleSelectChange} - search - selection - options={this.categoryOptions} - /> - </Form.Field> - <Form.Field required></Form.Field> - <Form.Field required> - <label htmlFor="logo">Logo</label> - <Input - onChange={this.handleFile} - name="logo" - icon={{ name: 'attach', circular: true, link: true }} - placeholder="attach logo" - type="File" - required - /> - </Form.Field> - <Form.Field required> - <label htmlFor="description">Deskripsi</label> - <TextArea onChange={this.handleChange} placeholder="Tell us more" name="description" autoHeight required /> - </Form.Field> - <Form.Field required> - <label htmlFor="address">Alamat</label> - <Input onChange={this.handleChange} placeholder="Alamat" name="address" required /> - </Form.Field> - <Form.Field required> - <label htmlFor="size">Jumlah karyawan (contoh: 1000)</label> - <Input onChange={this.handleChange} placeholder="Jumlah karyawan" name="size" required/> - </Form.Field> - <Form.Field required> - <label htmlFor="address">Website</label> - <Input onChange={this.handleChange} placeholder="Website perusahaan anda" name="website" required /> - </Form.Field> - <Modal.Actions style={{ textAlign: 'right' }}> - <Button type="reset" color="red"><Icon name="remove" />Reset</Button> - <Button loading={this.state.loading} type="submit" color="blue"> <Icon name="checkmark" />Submit</Button> - </Modal.Actions> - - </Form> - </Modal.Content> - </Modal> - )} -} + </Header.Content> + </Header> + <Form.Field required> + <label htmlFor="email">Email</label> + <Input onChange={this.handleChange} type="email" name="email" icon="user" iconPosition="left" placeholder="email" required /> + </Form.Field> + <Form.Field required> + <label htmlFor="password">Password</label> + <Input + onChange={(e) => { this.handleChange(e); this.handlePassword(e); }} + type="password" + id="password" + name="password" + icon="key" + iconPosition="left" + placeholder="password" + required + /> + </Form.Field> + <Form.Field required> + <label htmlFor="password-confirm">Konfirmasi Password</label> + <Input + onChange={(e) => { this.handleChange(e); this.handlePassword(e); }} + type="password" + id="password-confirm" + name="password-confirm" + icon="key" + iconPosition="left" + placeholder="password" + required + /> + </Form.Field> + + <Form.Field required> + <label htmlFor="name">Nama Perusahaan</label> + <Input onChange={this.handleChange} placeholder="Nama Perusahaan" name="name" required /> + </Form.Field> + <Form.Field required> + <label htmlFor="name">Kategori Perusahaan</label> + <Dropdown + placeholder="Kategori Perusahaan" + fluid + name="category" + onChange={this.handleSelectChange} + search + selection + options={this.categoryOptions} + /> + </Form.Field> + <Form.Field required></Form.Field> + <Form.Field required> + <label htmlFor="logo">Logo</label> + <Input + onChange={this.handleFile} + name="logo" + icon={{ name: 'attach', circular: true, link: true }} + placeholder="attach logo" + type="File" + required + /> + </Form.Field> + <Form.Field required> + <label htmlFor="description">Deskripsi</label> + <TextArea onChange={this.handleChange} placeholder="Tell us more" name="description" autoHeight required /> + </Form.Field> + <Form.Field required> + <label htmlFor="address">Alamat</label> + <Input onChange={this.handleChange} placeholder="Alamat" name="address" required /> + </Form.Field> + <Form.Field required> + <label htmlFor="size">Jumlah karyawan (contoh: 1000)</label> + <Input onChange={this.handleChange} placeholder="Jumlah karyawan" name="size" required /> + </Form.Field> + <Form.Field required> + <label htmlFor="address">Website</label> + <Input onChange={this.handleChange} placeholder="Website perusahaan anda" name="website" required /> + </Form.Field> + <Modal.Actions style={{ textAlign: 'right' }}> + <Button type="reset" color="red"> + <Icon name="remove" /> +Reset + </Button> + <Button loading={this.state.loading} type="submit" color="blue"> + {' '} + <Icon name="checkmark" /> +Submit + </Button> + </Modal.Actions> + </Form> + </Modal.Content> + </Modal> + ); + } +} diff --git a/assets/js/components/CompanyVacancy.jsx b/assets/js/components/CompanyVacancy.jsx index 260f8b81c95d5c082a0dc7ea0dd1598087c46d80..11d3594392cf44519e4c2fe94837b71a6f0ebb0e 100755 --- a/assets/js/components/CompanyVacancy.jsx +++ b/assets/js/components/CompanyVacancy.jsx @@ -1,7 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import moment from 'moment'; -import { Button, Icon, Item, Grid } from 'semantic-ui-react'; +import { + Button, Icon, Item, Grid, +} from 'semantic-ui-react'; import { Link } from 'react-router'; import Server from '../lib/Server'; @@ -48,33 +50,51 @@ export default class CompanyVacancy extends React.Component { <Grid.Row> <Grid.Column floated="left"> <p> - {this.state.count} Pendaftar + {this.state.count} + {' '} +Pendaftar <br /> - {this.state.countNew} Pendaftar Baru + {this.state.countNew} + {' '} +Pendaftar Baru <br /> <br /> - {this.props.data.total_accepted_applicants} /{' '} - {this.props.data.max_accepted_applicants} Diterima + {this.props.data.total_accepted_applicants} + {' '} +/ + {' '} + {this.props.data.max_accepted_applicants} + {' '} +Diterima <br /> - Ditutup {moment(moment(this.props.data.close_time)).fromNow()} + Ditutup + {' '} + {moment(moment(this.props.data.close_time)).fromNow()} </p> </Grid.Column> <Grid.Column floated="right"> {this.props.data.verified ? ( <h4> {' '} - <Icon name="checkmark box" size="large" color="green" />{' '} - Terverifikasi{' '} + <Icon name="checkmark box" size="large" color="green" /> + {' '} + Terverifikasi + {' '} </h4> ) : ( <h4> {' '} - <Icon name="remove circle" size="large" color="red" /> Belum - Terverifikasi{' '} + <Icon name="remove circle" size="large" color="red" /> + {' '} +Belum + Terverifikasi + {' '} </h4> )} <Button color="blue" floated="right" as={Link} to={this.getLink}> - Ubah <Icon name="right chevron" /> + Ubah + {' '} + <Icon name="right chevron" /> </Button> <Button loading={this.state.deleteLoading} @@ -85,7 +105,9 @@ export default class CompanyVacancy extends React.Component { this.props.deleteCallback(); }} > - Hapus <Icon name="delete" /> + Hapus + {' '} + <Icon name="delete" /> </Button> </Grid.Column> </Grid.Row> diff --git a/assets/js/components/ConfirmationModal.jsx b/assets/js/components/ConfirmationModal.jsx index 75357a654c9dcf0f64a006b049a6677ad35ec04f..23c880f6669cf7648b3e6f8fd1e46fe7a734f5c1 100755 --- a/assets/js/components/ConfirmationModal.jsx +++ b/assets/js/components/ConfirmationModal.jsx @@ -1,8 +1,9 @@ import React from 'react'; -import { Modal, Button, Icon, Header, Form } from 'semantic-ui-react'; +import { + Modal, Button, Icon, Header, Form, +} from 'semantic-ui-react'; export default class ConfirmationModal extends React.Component { - constructor(props) { super(props); /* istanbul ignore next */ @@ -47,29 +48,38 @@ export default class ConfirmationModal extends React.Component { open = ( header = this.state.header, content = this.state.content, icon = this.state.icon, - callback = this.state.callback(), isForm = this.state.isForm) => { - this.setState({ modalOpen: true, header, content, callback, icon, isForm }); + callback = this.state.callback(), isForm = this.state.isForm, + ) => { + this.setState({ + modalOpen: true, header, content, callback, icon, isForm, + }); }; render = () => ( <Modal - basic size="small" open={this.state.modalOpen} + basic + size="small" + open={this.state.modalOpen} onOpen={this.open} > <Header icon={this.state.icon} content={this.state.header} /> <Modal.Content> <p>{this.state.content}</p> - {this.state.isForm ? - <Form.Input style={{ width: '650px', height: '100px' }} type="text" placeholder={this.state.formPlaceholder} value={this.state.value} onChange={this.handleChange} /> : null } + {this.state.isForm + ? <Form.Input style={{ width: '650px', height: '100px' }} type="text" placeholder={this.state.formPlaceholder} value={this.state.value} onChange={this.handleChange} /> : null } </Modal.Content> <Modal.Actions> <Button onClick={this.handleClose} basic color="red" inverted> - <Icon name="remove" /> Tidak + <Icon name="remove" /> + {' '} +Tidak </Button> <Button onClick={this.handleYes} basic color="green" inverted> - <Icon name="checkmark" /> Ya + <Icon name="checkmark" /> + {' '} +Ya </Button> </Modal.Actions> </Modal> - ); + ); } diff --git a/assets/js/components/CourseList.jsx b/assets/js/components/CourseList.jsx index 21cafa412e0d7b9f1df61749285cbf82a645511f..32822c12030494cb4fbc2272283d66012ed27118 100755 --- a/assets/js/components/CourseList.jsx +++ b/assets/js/components/CourseList.jsx @@ -1,6 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Grid, Segment, Table, Image, Container } from 'semantic-ui-react'; +import { + Grid, Segment, Table, Image, Container, +} from 'semantic-ui-react'; import Course from './Course'; export default class CourseList extends React.Component { @@ -15,15 +17,13 @@ export default class CourseList extends React.Component { } generateCourse() { - return this.state.course.map((course, index) => - course.kelas ? ( - <Course - key={index} - grade={course.nilai} - courseName={course.kelas.nm_mk_cl.nm_mk} - /> - ) : null, - ); + return this.state.course.map((course, index) => (course.kelas ? ( + <Course + key={index} + grade={course.nilai} + courseName={course.kelas.nm_mk_cl.nm_mk} + /> + ) : null)); } render = () => ( @@ -47,7 +47,10 @@ export default class CourseList extends React.Component { <Container fluid textAlign="center"> <h2> Riwayat Akademik Mahasiswa </h2> </Container> - <h3>Nama : {this.props.data.name}</h3> + <h3> +Nama : + {this.props.data.name} + </h3> <Table unstackable> <Table.Header> <Table.Row> diff --git a/assets/js/components/GeneralModal.jsx b/assets/js/components/GeneralModal.jsx index de77b992a58959bb1a3800fc4a805f02995ebb5b..29b2ab0f8c32da66f709e9ecf448c471e65fbbfb 100644 --- a/assets/js/components/GeneralModal.jsx +++ b/assets/js/components/GeneralModal.jsx @@ -1,6 +1,5 @@ -import React from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; -import ModalAlert from './../components/ModalAlert'; export default class GeneralModal extends React.Component { static propTypes = { @@ -36,8 +35,7 @@ export default class GeneralModal extends React.Component { fixBody = () => { const anotherModal = document.getElementsByClassName('ui page modals') .length; - if (anotherModal > 0) - document.body.classList.add('scrolling', 'dimmable', 'dimmed'); + if (anotherModal > 0) document.body.classList.add('scrolling', 'dimmable', 'dimmed'); }; handleChange(event) { @@ -48,14 +46,12 @@ export default class GeneralModal extends React.Component { this.setState({ modalOpen: true }); } - handleClose = () => - this.setState({ - modalOpen: false, - load: false, + handleClose = () => this.setState({ + modalOpen: false, + load: false, }); handleApply = () => { this.setState({ load: true }); }; } - diff --git a/assets/js/components/InfoLowonganModal.jsx b/assets/js/components/InfoLowonganModal.jsx index cd568a1d9b667a55c6b03b35502b2e8bd0935557..20dcc7975fc3d2defe1a3b7151bc4a886db40230 100644 --- a/assets/js/components/InfoLowonganModal.jsx +++ b/assets/js/components/InfoLowonganModal.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Modal, Button } from 'semantic-ui-react'; -import ModalAlert from './../components/ModalAlert'; +import ModalAlert from './ModalAlert'; export default class InfoLowonganModal extends React.Component { static propTypes = { @@ -37,8 +37,7 @@ export default class InfoLowonganModal extends React.Component { fixBody = () => { const anotherModal = document.getElementsByClassName('ui page modals') .length; - if (anotherModal > 0) - document.body.classList.add('scrolling', 'dimmable', 'dimmed'); + if (anotherModal > 0) document.body.classList.add('scrolling', 'dimmable', 'dimmed'); }; handleChange(event) { @@ -49,11 +48,10 @@ export default class InfoLowonganModal extends React.Component { this.setState({ modalOpen: true }); } - handleClose = () => - this.setState({ - modalOpen: false, - load: false, - }); + handleClose = () => this.setState({ + modalOpen: false, + load: false, + }); handleApply = () => { this.setState({ load: true }); @@ -62,11 +60,11 @@ export default class InfoLowonganModal extends React.Component { render() { return ( <Modal - trigger={ + trigger={( <Button primary onClick={this.handleOpen} floated="center"> INFORMASI </Button> - } + )} closeIcon="close" open={this.state.modalOpen} onClose={this.handleClose} diff --git a/assets/js/components/InfoModal.jsx b/assets/js/components/InfoModal.jsx index 228223a2c559df569c1c60c726214abba81d7f17..41a1a9c0bceb06438907a2236303280742ee671f 100644 --- a/assets/js/components/InfoModal.jsx +++ b/assets/js/components/InfoModal.jsx @@ -1,19 +1,17 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { Modal, Button } from 'semantic-ui-react'; -import ModalAlert from './../components/ModalAlert'; +import ModalAlert from './ModalAlert'; import GeneralModal from './GeneralModal'; export default class InfoModal extends GeneralModal { - render() { return ( <Modal - trigger={ + trigger={( <Button primary onClick={this.handleOpen} floated="center"> INFO TENTANG KAPE </Button> - } + )} closeIcon="close" open={this.state.modalOpen} onClose={this.handleClose} diff --git a/assets/js/components/LoginForm.jsx b/assets/js/components/LoginForm.jsx index 2cbf8b184f97e00857554b3bd17b77c81dba5c56..1fe53436fa67cc70ce0037197270bf624b50273e 100755 --- a/assets/js/components/LoginForm.jsx +++ b/assets/js/components/LoginForm.jsx @@ -70,7 +70,8 @@ export default class LoginForm extends React.Component { <Image src={`./assets/img/${this.props.imgSrc}`} verticalAlign="middle" - />{' '} + /> + {' '} <span>{this.props.header}</span> </Segment> @@ -82,7 +83,11 @@ export default class LoginForm extends React.Component { > <Form.Group widths="equal"> <Form.Field> - <label htmlFor="id"> {this.props.usernameLabel} </label> + <label htmlFor="id"> + {' '} + {this.props.usernameLabel} + {' '} + </label> <Input type="text" id="email" diff --git a/assets/js/components/ModalAlert.jsx b/assets/js/components/ModalAlert.jsx index 9009276224770866275fa18c93b5b4e43116355c..af4b095f9caea14bf28ee26faba33f2b771eba14 100755 --- a/assets/js/components/ModalAlert.jsx +++ b/assets/js/components/ModalAlert.jsx @@ -1,11 +1,15 @@ import React from 'react'; -import { Button, Header, Icon, Modal } from 'semantic-ui-react'; +import { + Button, Header, Icon, Modal, +} from 'semantic-ui-react'; export default class ModalAlert extends React.Component { constructor(props) { super(props); /* istanbul ignore next */ - this.state = { open: false, header: '', content: '', callback: () => {} }; + this.state = { + open: false, header: '', content: '', callback: () => {}, + }; this.open = this.open.bind(this); this.close = this.close.bind(this); } @@ -21,8 +25,7 @@ export default class ModalAlert extends React.Component { fixBody = () => { const anotherModal = document.getElementsByClassName('ui page modals') .length; - if (anotherModal > 0) - document.body.classList.add('scrolling', 'dimmable', 'dimmed'); + if (anotherModal > 0) document.body.classList.add('scrolling', 'dimmable', 'dimmed'); }; open = ( @@ -30,7 +33,9 @@ export default class ModalAlert extends React.Component { content = this.state.content, callback = this.state.callback, ) => { - this.setState({ open: true, header, content, callback }); + this.setState({ + open: true, header, content, callback, + }); }; close = () => { @@ -48,7 +53,9 @@ export default class ModalAlert extends React.Component { </Modal.Content> <Modal.Actions> <Button color="green" inverted onClick={this.close}> - <Icon name="checkmark" /> OK + <Icon name="checkmark" /> + {' '} +OK </Button> </Modal.Actions> </Modal> diff --git a/assets/js/components/Notification.jsx b/assets/js/components/Notification.jsx index 5f310a13127e3b76f4a93772269c3e532a87edf1..6d796b3e6bb6d37d479e058ae91f83bdf142488b 100644 --- a/assets/js/components/Notification.jsx +++ b/assets/js/components/Notification.jsx @@ -1,9 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Segment, Image, Button, Grid } from 'semantic-ui-react'; +import { + Segment, Image, Button, Grid, +} from 'semantic-ui-react'; -const defaultThumbnail = - 'https://semantic-ui.com/images/wireframe/square-image.png'; +const defaultThumbnail = 'https://semantic-ui.com/images/wireframe/square-image.png'; export default class Notification extends React.Component { static propTypes = { @@ -18,18 +19,18 @@ export default class Notification extends React.Component { } getElapsedTime(dateNow) { - var oldtime = new Date(this.props.timestamp); - var newtime = new Date(dateNow); - var elapsed = Math.floor((newtime - oldtime)/1000); - var divider = [60, 60, 24, 30, 12] - var timeUnit = ["seconds", "minutes", "hours", "days", "months", "years"]; - var i = 0; - while(i < divider.length) { - if(Math.floor(elapsed/divider[i]) === 0) { break; } - elapsed = Math.floor(elapsed/divider[i]); + const oldtime = new Date(this.props.timestamp); + const newtime = new Date(dateNow); + let elapsed = Math.floor((newtime - oldtime) / 1000); + const divider = [60, 60, 24, 30, 12]; + const timeUnit = ['seconds', 'minutes', 'hours', 'days', 'months', 'years']; + let i = 0; + while (i < divider.length) { + if (Math.floor(elapsed / divider[i]) === 0) { break; } + elapsed = Math.floor(elapsed / divider[i]); i++; } - return (elapsed + " " + timeUnit[i] + " ago"); + return (`${elapsed} ${timeUnit[i]} ago`); } render() { diff --git a/assets/js/components/Pagination.jsx b/assets/js/components/Pagination.jsx index 0f5e78b78e14681471ee2ff71c11872f03cafd0f..055111ea5ef8f3e759cc45fd271bb86749832837 100755 --- a/assets/js/components/Pagination.jsx +++ b/assets/js/components/Pagination.jsx @@ -1,8 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Menu, Container, Icon, Loader } from 'semantic-ui-react'; +import { + Menu, Container, Icon, Loader, +} from 'semantic-ui-react'; import Server from '../lib/Server'; -import ModalAlert from '../components/ModalAlert'; +import ModalAlert from './ModalAlert'; export default class Pagination extends React.Component { static propTypes = { @@ -45,8 +47,7 @@ export default class Pagination extends React.Component { getItemsData = () => { const prefix = this.state.dir === 0 ? '?' : '&'; const searchPrefix = this.state.search !== '' ? prefix : ''; - const searchValue = - this.state.search !== '' ? `search=${this.state.search}` : ''; + const searchValue = this.state.search !== '' ? `search=${this.state.search}` : ''; return Server.get( `${this.state.url}${searchPrefix}${searchValue}`, false, @@ -72,11 +73,10 @@ export default class Pagination extends React.Component { } this.setState({ first, last }); }, - (error) => - error.then((r) => { - this.modalAlert.open(this.props.error, r.detail); - this.setState({ loading: false }); - }), + (error) => error.then((r) => { + this.modalAlert.open(this.props.error, r.detail); + this.setState({ loading: false }); + }), ); }; @@ -95,7 +95,7 @@ export default class Pagination extends React.Component { start: true, finish: false, }, - function() { + function () { this.getItemsData(); }, ); @@ -115,7 +115,7 @@ export default class Pagination extends React.Component { start: true, finish: false, }, - function() { + function () { this.getItemsData(); }, ); @@ -127,14 +127,14 @@ export default class Pagination extends React.Component { handleMovement(dir) { const newUrl = this.state[dir]; - this.setState({ url: newUrl, loading: true }, function() { + this.setState({ url: newUrl, loading: true }, function () { this.getItemsData(); }); } handlePrev() { if (!this.state.first) { - this.setState({ dir: -1 }, function() { + this.setState({ dir: -1 }, function () { this.handleMovement('prev'); }); } @@ -142,7 +142,7 @@ export default class Pagination extends React.Component { handleNext = () => { if (!this.state.last) { - this.setState({ dir: 1 }, function() { + this.setState({ dir: 1 }, function () { this.handleMovement('next'); }); } diff --git a/assets/js/components/Tabs.jsx b/assets/js/components/Tabs.jsx index bdc575306cf09dfc827654cce1a7088b185d4221..5aeebb2e70f39cedf30bd106fdaa436ca4ba099c 100755 --- a/assets/js/components/Tabs.jsx +++ b/assets/js/components/Tabs.jsx @@ -17,8 +17,7 @@ export default class Tabs extends React.Component { }; } - shouldComponentUpdate = (nextProps, nextState) => - this.props !== nextProps || this.state !== nextState; + shouldComponentUpdate = (nextProps, nextState) => this.props !== nextProps || this.state !== nextState; handleClick = (index, event) => { event.preventDefault(); diff --git a/assets/js/components/TopMenu.jsx b/assets/js/components/TopMenu.jsx index 42c319868a96d17041f963e14a7cc9d3ea4da87c..07fb0e44ae3a4d6ae78071968fc22634dcc1e35f 100755 --- a/assets/js/components/TopMenu.jsx +++ b/assets/js/components/TopMenu.jsx @@ -1,13 +1,16 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Menu, Image, Popup, Card, Button } from 'semantic-ui-react'; +import { + Menu, Image, Popup, Card, Button, +} from 'semantic-ui-react'; import { Link, browserHistory } from 'react-router'; +import moment from 'moment'; import Server from '../lib/Server'; import Storage from '../lib/Storage'; -import moment from 'moment'; import ModalAlert from './ModalAlert'; -var quotes = require('starwars'); +const quotes = require('starwars'); + const defaultPicture = 'https://semantic-ui.com/images/avatar/small/elliot.jpg'; export default class TopMenu extends React.Component { @@ -19,12 +22,12 @@ export default class TopMenu extends React.Component { }, photo: null, }; - const role = user.role; + const { role } = user; if (role === 'student') { return user.data.student; - } else if (role === 'company') { + } if (role === 'company') { return user.data.company; - } else if (role === 'supervisor') { + } if (role === 'supervisor') { return user.data.supervisor; } @@ -44,19 +47,19 @@ export default class TopMenu extends React.Component { activeItem: this.menuActiveState(), logoutLoading: false, currentDate: - moment(new Date()).format('dddd') + - ', ' + - moment(new Date()).format('LL'), + `${moment(new Date()).format('dddd') + }, ${ + moment(new Date()).format('LL')}`, todayQuote: quotes(), isOpen: false, applianceInformation: - "1. Pastikan anda sudah mengupdate profile anda\n" + - "2. Cari lowongan internship yang ada di tab lowongan\n" + - "3. Klik tombol 'Detail'\n" + - "4. Pastikan persyaratan sudah terpenuhi\n" + - "5. Jelaskan mengapa anda ingin mengikuti lowongan internship tersebut di 'Cover Letter'\n"+ - "6. Klik tombol 'Daftar'\n", - kapeDescription: "Kanal Akses Pendaftaran KP Elektronik" + '1. Pastikan anda sudah mengupdate profile anda\n' + + '2. Cari lowongan internship yang ada di tab lowongan\n' + + "3. Klik tombol 'Detail'\n" + + '4. Pastikan persyaratan sudah terpenuhi\n' + + "5. Jelaskan mengapa anda ingin mengikuti lowongan internship tersebut di 'Cover Letter'\n" + + "6. Klik tombol 'Daftar'\n", + kapeDescription: 'Kanal Akses Pendaftaran KP Elektronik', }; @@ -68,7 +71,7 @@ export default class TopMenu extends React.Component { } handleItemClick = (e, { name }) => { - if(name === 'Logo') { + if (name === 'Logo') { this.setState({ activeItem: 'Beranda' }); } else { this.setState({ activeItem: name }); @@ -76,18 +79,16 @@ export default class TopMenu extends React.Component { } handleOpen = () => { - this.setState({ - isOpen: true + isOpen: true, }); - - }; + }; handleClose = () => { this.setState({ - isOpen: false + isOpen: false, }); - clearTimeout(this.timeout) + clearTimeout(this.timeout); }; @@ -149,9 +150,16 @@ export default class TopMenu extends React.Component { <div className="admin-bar"> <p> Anda login sebagai perusahaan: - <b> {this.props.user.data.company.name}</b> (# - {this.props.user.data.company.id}). Untuk kembali menjadi admin, - klik{' '} + <b> + {' '} + {this.props.user.data.company.name} + </b> + {' '} +(# + {this.props.user.data.company.id} +). Untuk kembali menjadi admin, + klik + {' '} <a href="#" onClick={this.logoutCompany}> {' '} link ini @@ -166,43 +174,44 @@ export default class TopMenu extends React.Component { /> <Menu color="blue" pointing secondary> <Menu.Menu position="left"> - <Menu.Item style={{ padding: '0px' }} as={Link} to="/home" name="Logo" onClick={this.handleItemClick}> - <Image size="small" src="/assets/img/logo.png" /> - {this.state.kapeDescription} - </Menu.Item> + <Menu.Item style={{ padding: '0px' }} as={Link} to="/home" name="Logo" onClick={this.handleItemClick}> + <Image size="small" src="/assets/img/logo.png" /> + {this.state.kapeDescription} + </Menu.Item> </Menu.Menu> <Menu.Menu position="right"> - {this.props.user.role === 'student' && ( + {this.props.user.role === 'student' && ( <Menu.Item>{btn}</Menu.Item> - )} + )} <Menu.Item style={{ margin: '3px' }}> {this.state.currentDate} </Menu.Item> <Menu.Item as={Link} to="/home" name="Beranda" active={activeItem === 'Beranda'} onClick={this.handleItemClick} /> - { this.props.user.role === 'company' && - <Menu.Item as={Link} to="/profil-perusahaan" name="Profil" active={activeItem === 'Profil'} onClick={this.handleItemClick} /> } - { this.props.user.data.is_staff && - <Menu.Item as={Link} to="/lowongan" name="Lowongan" active={activeItem === 'Lowongan'} onClick={this.handleItemClick} /> } + { this.props.user.role === 'company' + && <Menu.Item as={Link} to="/profil-perusahaan" name="Profil" active={activeItem === 'Profil'} onClick={this.handleItemClick} /> } + { this.props.user.data.is_staff + && <Menu.Item as={Link} to="/lowongan" name="Lowongan" active={activeItem === 'Lowongan'} onClick={this.handleItemClick} /> } <Menu.Item as={Link} to="/notifikasi" name="Notifikasi" active={activeItem === 'Notifikasi'} onClick={this.handleItemClick} /> <Menu.Item style={{ padding: '10px 0' }}> <Popup trigger={<Image src={(this.props.user.role === 'company' ? data.logo : data.photo) || defaultPicture} avatar />} open={this.state.isOpen} - on='click' - onClose={this.handleClose} - onOpen={this.handleOpen} + on="click" + onClose={this.handleClose} + onOpen={this.handleOpen} > <Card header={data.name} description={data.user.email} /> - { this.props.user.role === 'student' && - <Menu.Item as={Link} to="/profil-mahasiswa" style={{ margin: '10px' }} name="Profil" active={activeItem === 'Profil'} onClick={this.handleItemClick} /> } - <Menu.Item as={Link} to="/edit-profil-mahasiswa" style={{ margin: '10px' }} name="Edit Profil" active={activeItem === 'EditProfil'} onClick={this.handleItemClick} /> - <Button.Group floated="right"> - <Button as={Link} onClick={this.logout} loading={this.state.logoutLoading} name="logout" color="blue" size="tiny">Keluar</Button></Button.Group> + { this.props.user.role === 'student' + && <Menu.Item as={Link} to="/profil-mahasiswa" style={{ margin: '10px' }} name="Profil" active={activeItem === 'Profil'} onClick={this.handleItemClick} /> } + <Menu.Item as={Link} to="/edit-profil-mahasiswa" style={{ margin: '10px' }} name="Edit Profil" active={activeItem === 'EditProfil'} onClick={this.handleItemClick} /> + <Button.Group floated="right"> + <Button as={Link} onClick={this.logout} loading={this.state.logoutLoading} name="logout" color="blue" size="tiny">Keluar</Button> + </Button.Group> </Popup> </Menu.Item> </Menu.Menu> diff --git a/assets/js/components/Vacancy.jsx b/assets/js/components/Vacancy.jsx index 25323bdc327795eafa5f96faeecb67e3a5ab7112..f56b081cd7edeb339c734292ada72250c20eeb11 100755 --- a/assets/js/components/Vacancy.jsx +++ b/assets/js/components/Vacancy.jsx @@ -1,6 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Item, Rating, Button, Grid } from 'semantic-ui-react'; +import { + Item, Rating, Button, Grid, +} from 'semantic-ui-react'; import moment from 'moment'; import ApplyModal from './ApplyModal'; import Server from '../lib/Server'; @@ -45,7 +47,7 @@ export default class Vacancy extends React.Component { this.state = { bookmarked: this.props.bookmarked, registeredStatus: this.props.status, - reason: " ", + reason: ' ', deleteLoading: false, }; moment.locale('id'); @@ -81,8 +83,7 @@ export default class Vacancy extends React.Component { this.state.bookmarked = 1 - this.state.bookmarked; } - updateStatus = (registeredStatus = null) => - this.setState({ registeredStatus }); + updateStatus = (registeredStatus = null) => this.setState({ registeredStatus }); removeVacancyApplication() { this.setState({ deleteLoading: true }); @@ -159,11 +160,11 @@ export default class Vacancy extends React.Component { if (this.state.registeredStatus == null) { return applyModal; - } else if ( + } if ( this.state.registeredStatus === Vacancy.APPLICATION_STATUS.REJECTED ) { return rejectedButton; - } else if ( + } if ( this.state.registeredStatus === Vacancy.APPLICATION_STATUS.ACCEPTED ) { return acceptedButton; @@ -173,41 +174,56 @@ export default class Vacancy extends React.Component { generateContent() { if (this.state.registeredStatus == Vacancy.APPLICATION_STATUS.REJECTED) { - Server.get(`/students/${this.props.user.data.student.id}/applied-vacancies/${this.props.data.id}/reason/`, - false).then( + Server.get(`/students/${this.props.user.data.student.id}/applied-vacancies/${this.props.data.id}/reason/`, + false).then( (data) => { - this.setState({reason: data.reason}); + this.setState({ reason: data.reason }); }, ); return ( - <p><br/><b>Alasan ditolak:</b> {this.state.reason} </p> + <p> + <br /> + <b>Alasan ditolak:</b> + {' '} + {this.state.reason} + {' '} + </p> ); - - } else { - return ( + } + return ( <p> - {this.props.data.company.address} - <br /> - {this.props.data.working_period} - <br /> - {this.state.count} orang telah mendaftar! - <br /> - <b> - {this.props.data.total_accepted_applicants}/{' '} - {this.props.data.max_accepted_applicants} - diterima{' '} - </b> - <br /> - <b>{`Ditutup ${moment( - moment(this.props.data.close_time), - ).fromNow()}`}</b> - <br /> - Rp. {this.props.data.salary} <br /> - <b>{this.props.data.apply_before}</b> + {this.props.data.company.address} + <br /> + {this.props.data.working_period} + <br /> + {this.state.count} + {' '} +orang telah mendaftar! + <br /> + <b> + {this.props.data.total_accepted_applicants} +/ + {' '} + {this.props.data.max_accepted_applicants} + diterima + {' '} + </b> + <br /> + <b> + {`Ditutup ${moment( + moment(this.props.data.close_time), + ).fromNow()}`} + </b> + <br /> + Rp. + {' '} + {this.props.data.salary} + {' '} + <br /> + <b>{this.props.data.apply_before}</b> </p> - ); - } + ); } render() { @@ -254,7 +270,8 @@ export default class Vacancy extends React.Component { /> </Grid.Row> <Grid.Row> - {this.generateAction()}</Grid.Row> + {this.generateAction()} + </Grid.Row> </Grid.Column> </Grid.Row> </Item.Extra> diff --git a/assets/js/components/VacancyList.jsx b/assets/js/components/VacancyList.jsx index 819b8191eb28de424922da6bb4b42006d834f5cd..c00965d123907a685a6726712e84b4ae61352f8e 100755 --- a/assets/js/components/VacancyList.jsx +++ b/assets/js/components/VacancyList.jsx @@ -1,11 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Item, Grid, Container, Dropdown } from 'semantic-ui-react'; +import { + Item, Grid, Container, Dropdown, +} from 'semantic-ui-react'; +import moment from 'moment'; import Vacancy from './Vacancy'; import CompanyVacancy from './CompanyVacancy'; import AdminVacancy from './AdminVacancy'; import Server from '../lib/Server'; -import moment from 'moment'; export default class VacancyList extends React.Component { static propTypes = { @@ -59,24 +61,22 @@ export default class VacancyList extends React.Component { this.setState({ vacancies: obj }); } - deleteVacancy = (id) => - Server.delete(`/vacancies/${id}/`, this.state).then( - () => { - this.modalAlert.open('Hapus Lowongan', 'Lowongan berhasil dihapus'); - const newVacancies = []; - this.state.vacancies.map( - (vacancy) => vacancy.id !== id && newVacancies.push(vacancy), - ); - this.setState({ vacancies: newVacancies }); - }, - (error) => - error.then((r) => { - this.modalAlert.open('Gagal Menghapus Lowongan', r.error); - }), - ); + deleteVacancy = (id) => Server.delete(`/vacancies/${id}/`, this.state).then( + () => { + this.modalAlert.open('Hapus Lowongan', 'Lowongan berhasil dihapus'); + const newVacancies = []; + this.state.vacancies.map( + (vacancy) => vacancy.id !== id && newVacancies.push(vacancy), + ); + this.setState({ vacancies: newVacancies }); + }, + (error) => error.then((r) => { + this.modalAlert.open('Gagal Menghapus Lowongan', r.error); + }), + ); filterVacanciesBasedOnSalary = (vacancies) => { - const salaryFilter = this.state.salaryFilter; + const { salaryFilter } = this.state; let filteredVacancies = vacancies; if (salaryFilter === 1) { filteredVacancies = filteredVacancies.filter( @@ -84,15 +84,13 @@ export default class VacancyList extends React.Component { ); } else if (salaryFilter === 2) { filteredVacancies = filteredVacancies.filter( - (vacancy) => - vacancy.props.data.salary >= 1000000 && - vacancy.props.data.salary < 3000000, + (vacancy) => vacancy.props.data.salary >= 1000000 + && vacancy.props.data.salary < 3000000, ); } else if (salaryFilter === 3) { filteredVacancies = filteredVacancies.filter( - (vacancy) => - vacancy.props.data.salary >= 3000000 && - vacancy.props.data.salary < 5000000, + (vacancy) => vacancy.props.data.salary >= 3000000 + && vacancy.props.data.salary < 5000000, ); } else if (salaryFilter === 4) { filteredVacancies = filteredVacancies.filter( @@ -104,7 +102,7 @@ export default class VacancyList extends React.Component { }; filterVacanciesBasedOnVacancyStatus = (vacancies) => { - const vacancyStateFilter = this.state.vacancyStateFilter; + const { vacancyStateFilter } = this.state; let filteredVacancies = vacancies; if (vacancyStateFilter === 1) { filteredVacancies = filteredVacancies.filter( @@ -153,21 +151,17 @@ export default class VacancyList extends React.Component { /> )); if (this.props.sort === 'ASC') { - return vacancies.sort((vac1, vac2) => { - return vac1.props.data.name.localeCompare(vac2.props.data.name); - }); - } else if (this.props.sort === 'DESC') { - return vacancies.sort((vac1, vac2) => { - return vac2.props.data.name.localeCompare(vac1.props.data.name); - }); + return vacancies.sort((vac1, vac2) => vac1.props.data.name.localeCompare(vac2.props.data.name)); + } if (this.props.sort === 'DESC') { + return vacancies.sort((vac1, vac2) => vac2.props.data.name.localeCompare(vac1.props.data.name)); } vacancies = this.filterVacanciesBasedOnSalary(vacancies); vacancies = this.filterVacanciesBasedOnVacancyStatus(vacancies); return vacancies; - } else if ( - (this.props.user.role === 'admin' && - this.props.user.data.company != null) || - this.props.user.role === 'company' + } if ( + (this.props.user.role === 'admin' + && this.props.user.data.company != null) + || this.props.user.role === 'company' ) { return this.state.vacancies.map((vacancy) => ( <Item.Group key={vacancy.id} relaxed style={{ width: '100%' }}> diff --git a/assets/js/components/VerifyAdminModal.jsx b/assets/js/components/VerifyAdminModal.jsx index 873ca031b640bc41f969c8a83eec46cdfbac301b..8af608c2632f44d6ece637547206bc56e44c82be 100755 --- a/assets/js/components/VerifyAdminModal.jsx +++ b/assets/js/components/VerifyAdminModal.jsx @@ -2,7 +2,6 @@ import React from 'react'; import { Button, Header, Modal } from 'semantic-ui-react'; export default class VerifyAdminModal extends React.Component { - state = { modalOpen: false } componentWillUpdate() { @@ -38,7 +37,7 @@ export default class VerifyAdminModal extends React.Component { onClose={this.handleClose} > <Modal.Header>Software Engineer</Modal.Header> - <Modal.Content > + <Modal.Content> <Modal.Description> <Header>Deskripsi Lowongan</Header> Lorem ipsum dolor sit amet, consectetur adipiscing elit, diff --git a/assets/js/index.jsx b/assets/js/index.jsx index 5645ac5c7db4bc3eadd20fb48263851fcd67fc0b..e1961af6239233e98d91ac6fb7257a3a988a1cc6 100644 --- a/assets/js/index.jsx +++ b/assets/js/index.jsx @@ -1,6 +1,8 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { Router, Route, browserHistory, Redirect } from 'react-router'; +import { + Router, Route, browserHistory, Redirect, +} from 'react-router'; import Dashboard from './Dashboard'; import Login from './Login'; import VacancyPage from './VacancyPage'; @@ -69,7 +71,13 @@ export default class App extends React.Component { if (allowedRoles.includes(role)) { return <WrappedComponent {...this.props} {...this.state} />; } - return <div> {browserHistory.push('/home')} </div>; + return ( + <div> + {' '} + {browserHistory.push('/home')} + {' '} + </div> + ); } }; @@ -81,9 +89,9 @@ export default class App extends React.Component { handleHome = (nextState, replace, cb) => { if (Server.isLoggedIn()) { if ( - App.getRole() === 'student' || - App.getRole() === 'company' || - App.getRole() === 'supervisor' + App.getRole() === 'student' + || App.getRole() === 'company' + || App.getRole() === 'supervisor' ) { replace({ pathname: '/lowongan' }); cb(); diff --git a/assets/js/lib/Server.jsx b/assets/js/lib/Server.jsx index 6100dcc427252b020d105807c8d3265ba5d72c0b..c5de24513df7b7bb541f017feb76bb315b49892b 100755 --- a/assets/js/lib/Server.jsx +++ b/assets/js/lib/Server.jsx @@ -19,7 +19,7 @@ export default class Server { static submit(path, data, method = 'POST', useCache = false) { const form = new FormData(); - Object.keys(data).map(k => { + Object.keys(data).map((k) => { form.append(k, data[k]); }); @@ -78,8 +78,8 @@ export default class Server { } static get(path, useCache = false) { - return (useCache && Storage.get(path)) ? - Promise.resolve(Storage.get(path)) : this.sendRequest(path, 'GET', null, useCache); + return (useCache && Storage.get(path)) + ? Promise.resolve(Storage.get(path)) : this.sendRequest(path, 'GET', null, useCache); } static post(path, data) { diff --git a/assets/js/lib/Storage.jsx b/assets/js/lib/Storage.jsx index cb2a24ce8e57aab7758e2d4dfe2425fdca4c6ede..007a6362322052b09e79f1de4c97c181f20d311f 100755 --- a/assets/js/lib/Storage.jsx +++ b/assets/js/lib/Storage.jsx @@ -1,144 +1,143 @@ -import Server from './../lib/Server'; - -/** Session Storage Polyfill */ - -/* eslint-disable */ -var isStorageAvailable = function (storage) { - /* istanbul ignore next */ - if (typeof storage === 'undefined') return false; - try { // hack for safari incognito - storage.setItem('storage', ''); - storage.getItem('storage'); - storage.removeItem('storage'); - return true; - } - catch (err) { - /* istanbul ignore next */ - return false; - } -}; - - -if (!isStorageAvailable(window.localStorage) || isStorageAvailable(window.sessionStorage)) (/* istanbul ignore next */function () { - -var Storage = function (type) { - function createCookie(name, value, days) { - var date, expires; - - if (days) { - date = new Date(); - date.setTime(date.getTime()+(days*24*60*60*1000)); - expires = "; expires="+date.toGMTString(); - } else { - expires = ""; - } - document.cookie = name+"="+value+expires+"; path=/"; - } - - function readCookie(name) { - var nameEQ = name + "=", - ca = document.cookie.split(';'), - i, c; - - for (i=0; i < ca.length; i++) { - c = ca[i]; - while (c.charAt(0)==' ') { - c = c.substring(1,c.length); - } - - if (c.indexOf(nameEQ) == 0) { - return c.substring(nameEQ.length,c.length); - } - } - return null; - } - - function setData(data) { - data = JSON.stringify(data); - if (type == 'session') { - window.name = data; - } else { - createCookie('localStorage', data, 365); - } - } - - function clearData() { - if (type == 'session') { - window.name = ''; - } else { - createCookie('localStorage', '', 365); - } - } - - function getData() { - var data = type == 'session' ? window.name : readCookie('localStorage'); - return data ? JSON.parse(data) : {}; - } - - - // initialise if there's already data - var data = getData(); - - return { - length: 0, - clear: function () { - data = {}; - this.length = 0; - clearData(); - }, - getItem: function (key) { - return data[key] === undefined ? null : data[key]; - }, - key: function (i) { - // not perfect, but works - var ctr = 0; - for (var k in data) { - if (ctr == i) return k; - else ctr++; - } - return null; - }, - removeItem: function (key) { - if (data[key] === undefined) this.length--; - delete data[key]; - setData(data); - }, - setItem: function (key, value) { - if (data[key] === undefined) this.length++; - data[key] = value+''; // forces the value to a string - setData(data); - } - }; -}; -/* istanbul ignore next */ -let polyfil = () => { - if (!isStorageAvailable(window.localStorage)) window.localStorage = new Storage('local'); - if (!isStorageAvailable(window.sessionStorage)) window.sessionStorage = new Storage('session'); -}; -polyfil(); - -})(); -/*eslint-enable */ - -export default class Storage { - static get(key) { - return JSON.parse(localStorage.getItem(key)); - } - - static set(key, value) { - return localStorage.setItem(key, JSON.stringify(value)); - } - - static clear() { - return localStorage.clear(); - } - - static getUserData() { - const data = Storage.get('user-data'); - /* istanbul ignore next */ - return (data != null) ? Promise.resolve(data) : Server.get('/users/me/').then((response) => { - Storage.set(('user-data'), response); - return response; - }); - } -} +import Server from './Server'; + +/** Session Storage Polyfill */ + +/* eslint-disable */ +const isStorageAvailable = function (storage) { + /* istanbul ignore next */ + if (typeof storage === 'undefined') return false; + try { // hack for safari incognito + storage.setItem('storage', ''); + storage.getItem('storage'); + storage.removeItem('storage'); + return true; + } catch (err) { + /* istanbul ignore next */ + return false; + } +}; + + +if (!isStorageAvailable(window.localStorage) || isStorageAvailable(window.sessionStorage)) (/* istanbul ignore next */function () { + + const Storage = function (type) { + function createCookie(name, value, days) { + let date, expires; + + if (days) { + date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = "; expires=" + date.toGMTString(); + } else { + expires = ""; + } + document.cookie = name + "=" + value + expires + "; path=/"; + } + + function readCookie(name) { + var nameEQ = name + "=", + ca = document.cookie.split(';'), + i, c; + + for (i = 0; i < ca.length; i++) { + c = ca[i]; + while (c.charAt(0) === ' ') { + c = c.substring(1, c.length); + } + + if (c.indexOf(nameEQ) === 0) { + return c.substring(nameEQ.length, c.length); + } + } + return null; + } + + function setData(data) { + data = JSON.stringify(data); + if (type === 'session') { + window.name = data; + } else { + createCookie('localStorage', data, 365); + } + } + + function clearData() { + if (type === 'session') { + window.name = ''; + } else { + createCookie('localStorage', '', 365); + } + } + + function getData() { + const data = type === 'session' ? window.name : readCookie('localStorage'); + return data ? JSON.parse(data) : {}; + } + + + // initialise if there's already data + let data = getData(); + + return { + length: 0, + clear: function () { + data = {}; + this.length = 0; + clearData(); + }, + getItem: function (key) { + return data[key] === undefined ? null : data[key]; + }, + key: function (i) { + // not perfect, but works + let ctr = 0; + for (let k in data) { + if (ctr === i) return k; + else ctr++; + } + return null; + }, + removeItem: function (key) { + if (data[key] === undefined) this.length--; + delete data[key]; + setData(data); + }, + setItem: function (key, value) { + if (data[key] === undefined) this.length++; + data[key] = value + ''; // forces the value to a string + setData(data); + } + }; + }; + /* istanbul ignore next */ +let polyfil = () => { + if (!isStorageAvailable(window.localStorage)) window.localStorage = new Storage('local'); + if (!isStorageAvailable(window.sessionStorage)) window.sessionStorage = new Storage('session'); +}; +polyfil(); + +})(); +/* eslint-enable */ + +export default class Storage { + static get(key) { + return JSON.parse(localStorage.getItem(key)); + } + + static set(key, value) { + return localStorage.setItem(key, JSON.stringify(value)); + } + + static clear() { + return localStorage.clear(); + } + + static getUserData() { + const data = Storage.get('user-data'); + /* istanbul ignore next */ + return (data != null) ? Promise.resolve(data) : Server.get('/users/me/').then((response) => { + Storage.set(('user-data'), response); + return response; + }); + } +} diff --git a/core/lib/mixins.py b/core/lib/mixins.py index 69555547426abc1a78ba865c4f691a819933b1df..4abd20cc54899e289e6648c3243b8b5d062a4031 100755 --- a/core/lib/mixins.py +++ b/core/lib/mixins.py @@ -3,4 +3,4 @@ class MultiSerializerViewSetMixin(object): try: return self.serializer_action_classes[self.action] except (KeyError, AttributeError): - return super(MultiSerializerViewSetMixin, self).get_serializer_class() \ No newline at end of file + return super(MultiSerializerViewSetMixin, self).get_serializer_class() diff --git a/core/lib/permissions.py b/core/lib/permissions.py index a4f7b829ac3be010fa0ea6bac81bbab6e2d81852..6407e3907e48ea35fa3e3c7f91176bc852f6c745 100755 --- a/core/lib/permissions.py +++ b/core/lib/permissions.py @@ -1,10 +1,10 @@ from rest_framework import permissions from rest_framework.exceptions import PermissionDenied +from core.models import Application from core.models import Company from core.models import Student from core.models import Supervisor -from core.models import Application from core.models import Vacancy from core.models import VacancyMilestone @@ -161,6 +161,7 @@ class VacancyApprovalPermission(permissions.BasePermission): def has_object_permission(self, request, view, obj): return isinstance(obj, Vacancy) + class IsAdminOrVacancyOwnerOrAuthenticatedReadOnly(permissions.IsAuthenticated): def has_permission(self, request, view): is_authenticated = super(IsAdminOrVacancyOwnerOrAuthenticatedReadOnly, self).has_permission(request, view) diff --git a/core/lib/validators.py b/core/lib/validators.py index 228d6d41bf5c72e729d14968b3e99a62e5488b97..ac5a1766c0c7072a58bdd5f34c7c5f097bedc223 100755 --- a/core/lib/validators.py +++ b/core/lib/validators.py @@ -1,6 +1,8 @@ -import os import math +import os + from django.core.exceptions import ValidationError + from kape.settings import MAX_UPLOAD_SIZE @@ -20,12 +22,14 @@ def validate_document_file_extension(value): def validate_image_file_extension(value): validate_file(value, ['.jpeg', '.jpg', '.png', '.JPG', '.JPEG']) + def validate_student_gpa(value): - if (value<0 or value>4): + if value < 0 or value > 4: raise ValidationError(u"GPA harus merupakan angka antara 0-4") + def validate_npm(value): - ''' + """ NPM UI terdiri dari 10 digit, misalnya: 1234567894. Digit terakhir (disebut checksum) dapat dihitung dari sembilan digit pertama. Checksum dipakai untuk deteksi error pada nomor ID seperti NPM. @@ -42,9 +46,9 @@ def validate_npm(value): yang memang ternyata benar. Source: Lim Yohanes Stefanus, Drs., M.Math., Ph.D - ''' - if math.ceil(math.log(value+1, 10)) != 10: + """ + if math.ceil(math.log(value + 1, 10)) != 10: raise ValidationError(u"NPM must be 10 digits") val_string = str(value) - if sum([3*int(a) for a in val_string[:-1:2]]+[int(a) for a in val_string[1:-1:2]]) % 7 != int(val_string[-1]): + if sum([3 * int(a) for a in val_string[:-1:2]] + [int(a) for a in val_string[1:-1:2]]) % 7 != int(val_string[-1]): raise ValidationError(u"NPM {} has invalid checksum".format(value)) diff --git a/core/models/accounts.py b/core/models/accounts.py index fece731bfd63f9a0c3ec37c63552bccd7a392320..a6bfae515a642fcac61be6e13f19cbb8ebf805ad 100755 --- a/core/models/accounts.py +++ b/core/models/accounts.py @@ -1,13 +1,13 @@ import os import uuid - from datetime import date -from django.utils import timezone + from django.contrib.auth.models import User from django.core.validators import MinValueValidator, MaxValueValidator, RegexValidator, FileExtensionValidator from django.db import models -from core.lib.validators import validate_document_file_extension, validate_image_file_extension, validate_npm, validate_student_gpa +from core.lib.validators import validate_document_file_extension, validate_image_file_extension, validate_npm, \ + validate_student_gpa def get_student_resume_file_path(instance, filename): @@ -27,9 +27,12 @@ def get_company_logo_file_path(instance, filename): filename = "%s.%s" % (uuid.uuid4(), extension) return os.path.join("company-logo/", filename) + def get_current_age(born): today = date.today() return today.year - born.year - ((today.month, today.day) < (born.month, born.day)) + + def get_student_ui_ux_portofolio_file_path(instance, filename): extension = filename.split('.')[-1].lower() filename = "%s.%s" % (uuid.uuid4(), extension) @@ -55,6 +58,7 @@ def get_display_name(user, full_name=False): return name.strip() + def get_student_sertifikat_file_path(instance, filename): extension = filename.split('.')[-1].lower() filename = "%s.%s" % (uuid.uuid4(), extension) @@ -69,9 +73,12 @@ class Student(models.Model): updated = models.DateTimeField(auto_now=True) user = models.OneToOneField(User) npm = models.IntegerField(validators=[validate_npm], unique=True) - resume = models.FileField(upload_to=get_student_resume_file_path, null=True, blank=True, validators=[FileExtensionValidator(['pdf'])]) - sertifikat = models.FileField(upload_to=get_student_sertifikat_file_path, null=True, blank=True, validators=[validate_document_file_extension]) - phone_number = models.CharField(max_length=100, blank=True, db_index=True, null=True, validators=[RegexValidator(r'^0\d{1,11}$')]) + resume = models.FileField(upload_to=get_student_resume_file_path, null=True, blank=True, + validators=[FileExtensionValidator(['pdf'])]) + sertifikat = models.FileField(upload_to=get_student_sertifikat_file_path, null=True, blank=True, + validators=[validate_document_file_extension]) + phone_number = models.CharField(max_length=100, blank=True, db_index=True, null=True, + validators=[RegexValidator(r'^0\d{1,11}$')]) gender = models.CharField(max_length=30, blank=True, null=True) bookmarked_vacancies = models.ManyToManyField('core.Vacancy', related_name="bookmarked_vacancies", blank=True) applied_vacancies = models.ManyToManyField('core.Vacancy', related_name="applied_vacancies", @@ -81,31 +88,34 @@ class Student(models.Model): major = models.CharField(max_length=30, blank=True, null=True) batch = models.CharField(max_length=4, blank=True, null=True) show_transcript = models.BooleanField(default=False) - photo = models.FileField(upload_to=get_student_photo_file_path, null=True, blank=True, validators=[FileExtensionValidator(['jpg', 'jpeg', 'png'])]) + photo = models.FileField(upload_to=get_student_photo_file_path, null=True, blank=True, + validators=[FileExtensionValidator(['jpg', 'jpeg', 'png'])]) self_description = models.CharField(max_length=500, blank=True, db_index=True, null=True) portfolio_link = models.URLField(blank=True, null=True) - linkedin_url = models.URLField(max_length=200,blank=True, null=True) - hackerrank_url = models.URLField(max_length=200,blank=True, null=True) - website_url = models.URLField(max_length=200,blank=True, null=True) + linkedin_url = models.URLField(max_length=200, blank=True, null=True) + hackerrank_url = models.URLField(max_length=200, blank=True, null=True) + website_url = models.URLField(max_length=200, blank=True, null=True) work_experience = models.CharField(max_length=500, blank=True, null=True) region = models.CharField(max_length=30, blank=True, null=True) alamat = models.CharField(max_length=50, blank=True, null=True) skills = models.CharField(max_length=50, blank=True, null=True) recommendations = models.ManyToManyField('core.Recommendation', related_name="recommendations", blank=True) - ui_ux_portofolio = models.FileField(upload_to=get_student_ui_ux_portofolio_file_path, null=True, blank=True, validators=[validate_document_file_extension]) + ui_ux_portofolio = models.FileField(upload_to=get_student_ui_ux_portofolio_file_path, null=True, blank=True, + validators=[validate_document_file_extension]) latest_work = models.CharField(max_length=100, blank=True, null=True) latest_work_desc = models.TextField(blank=True, null=True) - github_url = models.URLField(max_length=200,blank=True, null=True) - gitlab_url = models.URLField(max_length=200,blank=True, null=True) + github_url = models.URLField(max_length=200, blank=True, null=True) + gitlab_url = models.URLField(max_length=200, blank=True, null=True) intro = models.CharField(max_length=50, blank=True, null=True) expected_salary = models.CharField(max_length=10, blank=True, null=True, validators=[RegexValidator(r'^\d{0,10}$')]) job_seeking_status = models.CharField(max_length=30, blank=True, null=True) - student_gpa = models.FloatField(db_column='student_gpa', default=1.0, blank=True, null=True, validators=[validate_student_gpa]) + student_gpa = models.FloatField(db_column='student_gpa', default=1.0, blank=True, null=True, + validators=[validate_student_gpa]) volunteer = models.CharField(max_length=100, blank=True, null=True) awards = models.CharField(max_length=100, blank=True, null=True) projects = models.CharField(max_length=100, blank=True, null=True) certification = models.CharField(max_length=100, blank=True, null=True) - languages = models.CharField(max_length= 100, blank=True, null=True) + languages = models.CharField(max_length=100, blank=True, null=True) seminar = models.CharField(max_length=100, blank=True, null=True) interests = models.CharField(max_length=100, blank=True, null=True) dependants = models.IntegerField(db_column='dependants', default=0, blank=True, null=True) @@ -142,12 +152,13 @@ class Company(models.Model): user = models.OneToOneField(User) description = models.TextField() status = models.IntegerField(default=NEW, validators=[MaxValueValidator(2), MinValueValidator(0)]) - logo = models.FileField(upload_to=get_company_logo_file_path, null=True, blank=True, validators=[validate_image_file_extension]) + logo = models.FileField(upload_to=get_company_logo_file_path, null=True, blank=True, + validators=[validate_image_file_extension]) address = models.CharField(max_length=1000, blank=True, null=True) category = models.CharField(max_length=140, default="Belum ada kategori perusahaan") size = models.CharField(max_length=10, default=0, null=True, blank=True) website = models.CharField(max_length=100, default="Belum ada link website") - linkedin_url = models.URLField(max_length=200,blank=True, null=True) + linkedin_url = models.URLField(max_length=200, blank=True, null=True) @property def name(self): diff --git a/core/models/feedbacks.py b/core/models/feedbacks.py index 1b9293b0fef4caaece30a40eb89911eb36cefe75..69cca2699908304d004e8113256d615b00079328 100755 --- a/core/models/feedbacks.py +++ b/core/models/feedbacks.py @@ -1,12 +1,13 @@ from django.db import models from core.models.accounts import Student, Company + class Feedback(models.Model): created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=100, blank=True, default='') content = models.TextField() studentId = models.ForeignKey(Student, on_delete=models.CASCADE, null=True) - companyId = models.ForeignKey (Company, on_delete=models.CASCADE, null=True) + companyId = models.ForeignKey(Company, on_delete=models.CASCADE, null=True) class Meta: ordering = ['created'] diff --git a/core/models/recommendations.py b/core/models/recommendations.py index 14540c87077f59f7ae4750a7b90544742517f7ec..40225ef6adccc5a450a32f2895d7f9461cd3d846 100644 --- a/core/models/recommendations.py +++ b/core/models/recommendations.py @@ -1,6 +1,6 @@ from django.db import models + from core.models.accounts import get_display_name -from core.models.accounts import Student class Recommendation(models.Model): diff --git a/core/models/vacancies.py b/core/models/vacancies.py index 6c28602fb1e054a6b6377b85e0434dc613fafb74..d5ca7fb0a91a4cbaed90585bfed76d5e1fe0436e 100755 --- a/core/models/vacancies.py +++ b/core/models/vacancies.py @@ -25,7 +25,7 @@ class Vacancy(models.Model): @property def apply_before(self): - if (self.close_time < timezone.now()): + if self.close_time < timezone.now(): return "Pendaftaran ditutup" return "Daftar sebelum " + self.close_time.strftime('%d') + " " + self.close_time.strftime( '%B') + " " + self.close_time.strftime('%Y') diff --git a/core/serializers/accounts.py b/core/serializers/accounts.py index 501ed583230c11fd348f80890b557fe21c1d987c..85a64b166203fefea36b1af36fd6e0fc1d24dcbd 100755 --- a/core/serializers/accounts.py +++ b/core/serializers/accounts.py @@ -19,17 +19,23 @@ class StudentSerializer(serializers.ModelSerializer): class Meta: model = Student - fields = ['id', 'name', 'full_name', 'user', 'npm', 'resume', 'phone_number', 'gender', 'birth_place', 'birth_date', 'major', 'batch', - 'show_transcript', 'photo', 'accepted_no', 'linkedin_url', 'hackerrank_url', 'region', 'intro', 'portfolio_link', 'website_url', 'student_gpa', 'age', - 'work_experience', 'latest_work', 'latest_work_desc', 'read_no', 'volunteer', 'job_seeking_status', 'skills', 'expected_salary', - 'self_description', 'github_url', 'gitlab_url', 'awards', 'certification', 'languages', 'seminar', 'interests', 'alamat', 'projects', 'dependants'] - - def get_accepted_no(self, obj): + fields = ['id', 'name', 'full_name', 'user', 'npm', 'resume', 'phone_number', 'gender', 'birth_place', + 'birth_date', 'major', 'batch', + 'show_transcript', 'photo', 'accepted_no', 'linkedin_url', 'hackerrank_url', 'region', 'intro', + 'portfolio_link', 'website_url', 'student_gpa', 'age', + 'work_experience', 'latest_work', 'latest_work_desc', 'read_no', 'volunteer', 'job_seeking_status', + 'skills', 'expected_salary', + 'self_description', 'github_url', 'gitlab_url', 'awards', 'certification', 'languages', 'seminar', + 'interests', 'alamat', 'projects', 'dependants'] + + @staticmethod + def get_accepted_no(obj): apps = Application.objects.filter(student=obj, status=4) companies = apps.values('vacancy__company').distinct() return companies.count() - def get_read_no(self, obj): + @staticmethod + def get_read_no(obj): apps = Application.objects.filter(student=obj, status=1) companies = apps.values('vacancy__company').distinct() return companies.count() @@ -69,14 +75,14 @@ class StudentUpdateSerializer(serializers.ModelSerializer): 'alamat': instance.alamat, 'skills': instance.skills, 'github_url': instance.github_url, - 'gitlab_url' : instance.gitlab_url, - 'awards' : instance.awards, - 'projects' : instance.projects, - 'certification' : instance.certification, - 'languages' : instance.languages, - 'seminar' : instance.seminar, - 'interests' : instance.interests, - 'dependants' : instance.dependants, + 'gitlab_url': instance.gitlab_url, + 'awards': instance.awards, + 'projects': instance.projects, + 'certification': instance.certification, + 'languages': instance.languages, + 'seminar': instance.seminar, + 'interests': instance.interests, + 'dependants': instance.dependants, } def update(self, instance, validated_data): @@ -144,9 +150,12 @@ class StudentUpdateSerializer(serializers.ModelSerializer): class Meta: model = Student - fields = ['resume', 'email', 'phone_number', 'gender', 'photo', 'show_transcript', 'linkedin_url', 'hackerrank_url', 'region', 'intro', 'portfolio_link', 'website_url', 'student_gpa', - 'work_experience', 'latest_work', 'latest_work_desc', 'volunteer', 'job_seeking_status', 'skills', 'expected_salary', - 'self_description', 'github_url', 'gitlab_url', 'awards', 'certification', 'languages', 'seminar', 'interests', 'alamat', 'projects', 'dependants'] + fields = ['resume', 'email', 'phone_number', 'gender', 'photo', 'show_transcript', 'linkedin_url', + 'hackerrank_url', 'region', 'intro', 'portfolio_link', 'website_url', 'student_gpa', + 'work_experience', 'latest_work', 'latest_work_desc', 'volunteer', 'job_seeking_status', 'skills', + 'expected_salary', + 'self_description', 'github_url', 'gitlab_url', 'awards', 'certification', 'languages', 'seminar', + 'interests', 'alamat', 'projects', 'dependants'] class CompanyUpdateSerializer(serializers.ModelSerializer): @@ -155,9 +164,9 @@ class CompanyUpdateSerializer(serializers.ModelSerializer): 'address': instance.address, 'description': instance.description, 'name': instance.user.first_name, - 'website' : instance.website, - 'linkedin_url' : instance.linkedin_url, - 'size' : instance.size, + 'website': instance.website, + 'linkedin_url': instance.linkedin_url, + 'size': instance.size, } def update(self, instance, validated_data): @@ -175,7 +184,7 @@ class CompanyUpdateSerializer(serializers.ModelSerializer): class Meta: model = Company - fields = ['address', 'description', 'name' , 'website', 'linkedin_url', 'size'] + fields = ['address', 'description', 'name', 'website', 'linkedin_url', 'size'] class CompanySerializer(serializers.ModelSerializer): diff --git a/core/serializers/vacancies.py b/core/serializers/vacancies.py index ab292fdc4e09bc309f3cc173384c565cd4fbaa3c..d5982b8097c1d90e877de6e693055b4dd8634e24 100755 --- a/core/serializers/vacancies.py +++ b/core/serializers/vacancies.py @@ -12,8 +12,8 @@ class VacancySerializer(serializers.ModelSerializer): total_accepted_applicants = serializers.SerializerMethodField('_get_total_accepted_applicants') def _get_total_accepted_applicants(self, instance): - return len(Application.objects.filter(vacancy = instance, status = 4)) - + return len(Application.objects.filter(vacancy=instance, status=4)) + def _get_app_status(self, instance): try: request = self.context.get("request") @@ -36,8 +36,10 @@ class VacancySerializer(serializers.ModelSerializer): class Meta: model = Vacancy - fields = ['company', 'verified', 'open_time', 'description', 'close_time', 'created','apply_before', 'updated', 'name', \ - 'status', 'bookmarked', 'id', 'salary', 'responsibilities', 'requirements','working_period', 'benefits', 'max_accepted_applicants', 'total_accepted_applicants'] + fields = ['company', 'verified', 'open_time', 'description', 'close_time', 'created', 'apply_before', 'updated', + 'name', 'status', 'bookmarked', 'id', 'salary', 'responsibilities', 'requirements', 'working_period', + 'benefits', 'max_accepted_applicants', 'total_accepted_applicants'] + def name_position_validator(names): for name in names.split(" "): @@ -45,6 +47,7 @@ def name_position_validator(names): raise serializers.ValidationError("Name must alphabets only") return name + class PostVacancySerializer(serializers.ModelSerializer): company = serializers.PrimaryKeyRelatedField(queryset=Company.objects.all()) name = serializers.CharField(validators=[name_position_validator], max_length=100, allow_null=False) @@ -64,21 +67,21 @@ class ApplicationSerializer(serializers.ModelSerializer): class ApplicationStatusSerializer(serializers.ModelSerializer): - class Meta: model = Application fields = ['status'] + class SupervisorStudentApplicationSerializer(serializers.ModelSerializer): def to_representation(self, instance): - status_map = ["new", "read", "bookmarked", "rejected", "accepted","aborted" ] + status_map = ["new", "read", "bookmarked", "rejected", "accepted", "aborted"] return { - 'name' : instance.student.full_name, - 'npm' : instance.student.npm, - 'major' : instance.student.major, - 'vacancy_name' : instance.vacancy.name, - 'company_name' : instance.vacancy.company.name, - 'status' : status_map[instance.status] + 'name': instance.student.full_name, + 'npm': instance.student.npm, + 'major': instance.student.major, + 'vacancy_name': instance.vacancy.name, + 'company_name': instance.vacancy.company.name, + 'status': status_map[instance.status] } class Meta: @@ -86,6 +89,7 @@ class SupervisorStudentApplicationSerializer(serializers.ModelSerializer): fields = ['name', 'npm', 'major', 'vacancy_name', 'company_name', 'status'] read_only_fields = ['name', 'npm', 'major', 'vacancy_name', 'company_name', 'status'] + class VacancyApplicationSerializer(serializers.ModelSerializer): vacancy = VacancySerializer() @@ -95,7 +99,6 @@ class VacancyApplicationSerializer(serializers.ModelSerializer): class VacancyVerifiedSerializer(serializers.ModelSerializer): - class Meta: model = Vacancy fields = ['verified'] diff --git a/core/tests/test_accounts.py b/core/tests/test_accounts.py index 4c7d975b446aca229cb1d07afdbf538cdedb42b5..f3987e831004650b1beeb7f60051e233a9dbb28d 100755 --- a/core/tests/test_accounts.py +++ b/core/tests/test_accounts.py @@ -1,14 +1,16 @@ -import requests_mock from datetime import date, timedelta -from rest_framework import status -from rest_framework.test import APIClient, APITestCase + +import requests_mock from django.contrib.auth.models import User from django.core.exceptions import ValidationError +from rest_framework import status +from rest_framework.test import APITestCase + try: - from StringIO import StringIO ## for Python 2 + from StringIO import StringIO ## for Python 2 except ImportError: - from io import StringIO ## for Python 3 -from core.models.accounts import Company, Supervisor, Student, get_current_age + from io import StringIO ## for Python 3 +from core.models.accounts import Company, Student, get_current_age from core.tests.mocks import (mock_csui_oauth_verify, mock_csui_ldap_student, mock_csui_ldap_lecturer, mock_csui_ldap_fail, mock_csui_siak_student) @@ -22,10 +24,12 @@ class LoginTests(APITestCase): url = '/api/login/' - response = self.client.post(url, { 'username' : 'dummy.mahasiswa', 'password' : 'lalala', 'login-type' : 'sso-ui'}, format='json') + response = self.client.post(url, {'username': 'dummy.mahasiswa', 'password': 'lalala', 'login-type': 'sso-ui'}, + format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED) - response = self.client.post(url, {'username': 'dummy.mahasiswa', 'password': 'lalala', 'login-type': 'sso-ui'}, format='json') + response = self.client.post(url, {'username': 'dummy.mahasiswa', 'password': 'lalala', 'login-type': 'sso-ui'}, + format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) @requests_mock.Mocker() @@ -34,10 +38,12 @@ class LoginTests(APITestCase): mock_csui_ldap_lecturer(m) url = '/api/login/' - response = self.client.post(url, {'username': 'dummy.dosen', 'password': 'lalala', 'login-type': 'sso-ui'}, format='json') + response = self.client.post(url, {'username': 'dummy.dosen', 'password': 'lalala', 'login-type': 'sso-ui'}, + format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED) - response = self.client.post(url, {'username': 'dummy.dosen', 'password': 'lalala', 'login-type': 'sso-ui'}, format='json') + response = self.client.post(url, {'username': 'dummy.dosen', 'password': 'lalala', 'login-type': 'sso-ui'}, + format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) @requests_mock.Mocker() @@ -45,12 +51,15 @@ class LoginTests(APITestCase): mock_csui_ldap_fail(m) url = '/api/login/' - response = self.client.post(url, {'username': 'dummy.salah', 'password': 'lalala', 'login-type': 'sso-ui'}, format='json') + response = self.client.post(url, {'username': 'dummy.salah', 'password': 'lalala', 'login-type': 'sso-ui'}, + format='json') self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) def test_failed_company_login(self): url = '/api/login/' - response = self.client.post(url, {'username': 'dummy.company.failed', 'password': 'lalala', 'login-type': 'company'}, format='json') + response = self.client.post(url, + {'username': 'dummy.company.failed', 'password': 'lalala', 'login-type': 'company'}, + format='json') self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) def test_success_company_login(self): @@ -58,7 +67,8 @@ class LoginTests(APITestCase): Company.objects.create(user=new_user, description="lalalala", status=Company.VERIFIED, logo=None, address=None) url = '/api/login/' - response = self.client.post(url, {'username': 'dummy.login.company', 'password': 'lalala123', 'login-type': 'company'}, format='json') + response = self.client.post(url, {'username': 'dummy.login.company', 'password': 'lalala123', + 'login-type': 'company'}, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) def test_bad_request_1(self): @@ -68,20 +78,22 @@ class LoginTests(APITestCase): def test_bad_request_2(self): url = '/api/login/' - response = self.client.post(url, {'username': 'lalala', 'password': 'lalalala', 'login-type' : 'lalala'}, format='json') + response = self.client.post(url, {'username': 'lalala', 'password': 'lalalala', 'login-type': 'lalala'}, + format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_return_age(self): - birth_day = (date.today() -timedelta(days = 700)) + birth_day = (date.today() - timedelta(days=700)) self.assertEqual(1, get_current_age(birth_day)) - class RegisterTests(APITestCase): def test_create_and_recreate(self): url = '/api/register/' - tc_post = {'password': 'corporatepass', 'name':'tutuplapak', 'description':'menutup lapak', 'email': 'email@email.com', - 'logo':'lalala', 'address':'alamat', 'category':'Perusahaan Jasa', 'website':'www.tutuplapak.com', 'size':'1000'} + tc_post = {'password': 'corporatepass', 'name': 'tutuplapak', 'description': 'menutup lapak', + 'email': 'email@email.com', + 'logo': 'lalala', 'address': 'alamat', 'category': 'Perusahaan Jasa', + 'website': 'www.tutuplapak.com', 'size': '1000'} response = self.client.post(url, tc_post, format='multipart') self.assertEqual(response.status_code, status.HTTP_201_CREATED) @@ -105,8 +117,8 @@ class RegisterTests(APITestCase): class ProfileUpdateTests(APITestCase): def _create_test_file_pdf(self, path): - file = open(path, 'rb') - return {'pdf_sertifikat':file} + file = open(path, 'rb') + return {'pdf_sertifikat': file} @requests_mock.Mocker() def test_student_profile_update_validator(self, m): @@ -125,42 +137,49 @@ class ProfileUpdateTests(APITestCase): self.assertEqual(response.data.get('self_description'), 'I am very happy') url = '/api/students/' + str(student_id) + "/profile/" - response = self.client.patch(url, {'linkedin_url': 'https://www.linkedin.com/in/jojo/'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'linkedin_url': 'https://www.linkedin.com/in/jojo/'}, format='multipart', + encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(response.data.get('linkedin_url'), 'https://www.linkedin.com/in/jojo/') url = '/api/students/' + str(student_id) + "/profile/" - response = self.client.patch(url, {'linkedin_url': 'https://linkedin.com/in/jojo/'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'linkedin_url': 'https://linkedin.com/in/jojo/'}, format='multipart', + encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(response.data.get('linkedin_url'), 'https://linkedin.com/in/jojo/') url = '/api/students/' + str(student_id) + "/profile/" - response = self.client.patch(url, {'linkedin_url': 'https://id.linkedin.com/in/jojo/'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'linkedin_url': 'https://id.linkedin.com/in/jojo/'}, format='multipart', + encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(response.data.get('linkedin_url'), 'https://id.linkedin.com/in/jojo/') url = '/api/students/' + str(student_id) + "/profile/" - response = self.client.patch(url, {'linkedin_url': 'https://www.linkedin.com/jojo/'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'linkedin_url': 'https://www.linkedin.com/jojo/'}, format='multipart', + encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data.get('linkedin_url'), None) - response = self.client.patch(url, {'hackerrank_url': 'https://www.hackerrank.com/james'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'hackerrank_url': 'https://www.hackerrank.com/james'}, format='multipart', + encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(response.data.get('hackerrank_url'), 'https://www.hackerrank.com/james') - response = self.client.patch(url, {'hackerrank_url': 'https://www.hackerank.com/james'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'hackerrank_url': 'https://www.hackerank.com/james'}, format='multipart', + encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data.get('hackerrank_url'), None) - response = self.client.patch(url, {'github_url': 'https://github.com/bob'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'github_url': 'https://github.com/bob'}, format='multipart', + encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(response.data.get('github_url'), 'https://github.com/bob') - response = self.client.patch(url, {'github_url': 'https://gitlab.com/bob'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'github_url': 'https://gitlab.com/bob'}, format='multipart', + encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data.get('github_url'), None) - @requests_mock.Mocker() def test_student_profile_update(self, m): mock_csui_oauth_verify(m) @@ -259,27 +278,32 @@ class ProfileUpdateTests(APITestCase): self.assertEqual(response.status_code, status.HTTP_415_UNSUPPORTED_MEDIA_TYPE) url = '/api/students/' + str(student_id) + "/profile/" - response = self.client.patch(url, {'latest_work': 'Teaching assistant at Fasilkom UI'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'latest_work': 'Teaching assistant at Fasilkom UI'}, format='multipart', + encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(response.data.get('latest_work'), 'Teaching assistant at Fasilkom UI') url = '/api/students/' + str(student_id) + "/profile/" - response = self.client.patch(url, {'latest_work_desc': 'Evaluate weekly assignment for 15 students'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'latest_work_desc': 'Evaluate weekly assignment for 15 students'}, + format='multipart', encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(response.data.get('latest_work_desc'), 'Evaluate weekly assignment for 15 students') url = '/api/students/' + str(student_id) + '/profile/' - response = self.client.patch(url, {'intro': 'Saya tertarik dengan dunia front-end development'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'intro': 'Saya tertarik dengan dunia front-end development'}, + format='multipart', encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(response.data.get('intro'), 'Saya tertarik dengan dunia front-end development') url = '/api/students/' + str(student_id) + "/profile/" - response = self.client.patch(url, {'awards': 'Juara 2 UIUX Gemastik 2019'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'awards': 'Juara 2 UIUX Gemastik 2019'}, format='multipart', + encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(response.data.get('awards'), 'Juara 2 UIUX Gemastik 2019') url = '/api/students/' + str(student_id) + "/profile/" - response = self.client.patch(url, {'projects': 'Ow-Jek - Android Mobile Project'}, format='multipart', encoding='utf-8') + response = self.client.patch(url, {'projects': 'Ow-Jek - Android Mobile Project'}, format='multipart', + encoding='utf-8') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(response.data.get('projects'), 'Ow-Jek - Android Mobile Project') @@ -337,7 +361,7 @@ class ProfileUpdateTests(APITestCase): url = '/api/students/' + str(student_id) + '/profile/' imgfile = StringIO('JPG\x01\x00\x01\x00\x80\x01\x00\x00\x00\x00ccc,\x00' - '\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;') + '\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;') imgfile.name = 'test_img_file.jpg' response = self.client.patch(url, {'photo': imgfile}, format='multipart') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) @@ -355,7 +379,6 @@ class ProfileUpdateTests(APITestCase): response = self.client.patch(url, data, format='multipart') self.assertEqual(response.status_code, status.HTTP_200_OK) - response = self.client.patch(url, {'expected_salary': '4000000'}, format='multipart') self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertEqual(response.data.get('expected_salary'), '4000000') @@ -408,7 +431,7 @@ class ProfileUpdateTests(APITestCase): response = self.client.patch(url, {'dependants': 'this is not valid dependants input'}, format='multipart') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - def _create_test_file(self,path): + def _create_test_file(self, path): f = open(path, 'r') return {'pdf_file': f} @@ -417,8 +440,9 @@ class ProfileUpdateTests(APITestCase): Company.objects.create(user=new_user, description="lalalala", status=Company.VERIFIED, logo=None, address=None) url = '/api/login/' - response = self.client.post(url, {'username': 'dummy.login.company', 'password': 'lalala123', 'login-type': 'company'}, - format='json') + response = self.client.post(url, {'username': 'dummy.login.company', 'password': 'lalala123', + 'login-type': 'company'}, + format='json') company_id = response.data.get('company').get('id') url = '/api/companies/' + str(company_id) + "/profile/" @@ -444,6 +468,7 @@ class ProfileUpdateTests(APITestCase): response = self.client.patch(url, {'linkedin_url': 'this is not valid url'}, format='multipart') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + class ResponseApiLoginCompany(APITestCase): def setUp(self): self.username = "fesbuk" @@ -457,8 +482,8 @@ class ResponseApiLoginCompany(APITestCase): response = self.client.post( '/api/login/', { - "login-type" : "company", - "password" : self.password, + "login-type": "company", + "password": self.password, "username": self.username, }, format="json" diff --git a/core/tests/test_admin.py b/core/tests/test_admin.py index c387dc6d9803766a60615a163127b37a276d2c3f..3f1751d8fa823c953f3faa0604e79a4cb90c461a 100644 --- a/core/tests/test_admin.py +++ b/core/tests/test_admin.py @@ -1,9 +1,10 @@ -from django.test import TestCase -from django.contrib.auth.models import User from django.contrib.admin.sites import AdminSite +from django.contrib.auth.models import User +from django.test import TestCase -from core.models import Company from core.admin import CompanyAdmin +from core.models import Company + class CompanyAdminTest(TestCase): diff --git a/core/tests/test_create_vacancies.py b/core/tests/test_create_vacancies.py index db80fcba7922882070ae2006d48d2123b164684f..30de1a6083fb798bc33e7666967b76e6d1f72843 100755 --- a/core/tests/test_create_vacancies.py +++ b/core/tests/test_create_vacancies.py @@ -4,11 +4,8 @@ from django.contrib.auth.models import User from rest_framework import status from rest_framework.test import APITestCase -from core.models.accounts import Company, Student, Supervisor -from core.models.vacancies import Vacancy, Application - -import json -import requests_mock +from core.models.accounts import Company +from core.models.vacancies import Vacancy class CreateAndUpdateVacancyTest(APITestCase): diff --git a/core/tests/test_feedbacks.py b/core/tests/test_feedbacks.py index 0c09bdf320a6bb1e0c5e3da06cdf2ba6844a7303..49d5132f0467e09093cacff85ef2664b1e0be4c4 100755 --- a/core/tests/test_feedbacks.py +++ b/core/tests/test_feedbacks.py @@ -251,7 +251,7 @@ class FeedbacksTests(APITestCase): feedbacks_url = '/api/feedbacks/' + str(feedback_id) + '/' response = self.client.put(feedbacks_url, - {"content": "updated content", "title": "updated title"}) + {"content": "updated content", "title": "updated title"}) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data["title"], "updated title") @@ -270,7 +270,7 @@ class FeedbacksTests(APITestCase): feedbacks_url = '/api/feedbacks/' + str(feedback_id) + '/' response = self.client.put(feedbacks_url, - {"content": "updated content", "title": "updated title"}) + {"content": "updated content", "title": "updated title"}) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.data["detail"], "Feedback with id {} doesn't exist".format(feedback_id)) @@ -282,6 +282,6 @@ class FeedbacksTests(APITestCase): # test_feedbacks_delete_without_data_id feedbacks_url = '/api/feedbacks/' response = self.client.put(feedbacks_url, - {"content": "updated content", "title": "updated title"}) + {"content": "updated content", "title": "updated title"}) self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) diff --git a/core/tests/test_profile_accounts.py b/core/tests/test_profile_accounts.py index c79daf28b1043d704f293f5c3729fc34b0368922..bbfbcc346c95b485c199ee4b4c966d3552baa2c7 100644 --- a/core/tests/test_profile_accounts.py +++ b/core/tests/test_profile_accounts.py @@ -9,54 +9,54 @@ from core.views.accounts.utils import determine_first_name_last_name class ProfileAccountsTests(APITestCase): - def create_first_last_name(self): - user = User.objects.create_user('dummy.student2', 'dummy.student@student.com', 'lalala123') - user.first_name = 'Riansyah' - user.last_name = 'Tohamba' - return user - - def test_display_full_name(self): - self.assertEqual('Riansyah Tohamba', - get_display_name(self.create_first_last_name(),full_name=True) - ) - - def test_display_last_name_shortened(self): - self.assertEqual('Riansyah T.', - get_display_name(self.create_first_last_name(),full_name=False) - ) - - def test_display_first_name(self): - user = User.objects.create_user('dummy.student2', 'dummy.student@student.com', 'lalala123') - user.first_name = 'Riansyah' - self.assertEqual('Riansyah', get_display_name(user)) - - def test_display_last_name(self): - user = User.objects.create_user('dummy.student2', 'dummy.student@student.com', 'lalala123') - user.last_name = 'Tohamba' - self.assertEqual('Tohamba', get_display_name(user)) - - def test_display_username(self): - user = User.objects.create_user('dummy.student2', 'dummy.student@student.com', 'lalala123') - self.assertEqual('dummy.student2', get_display_name(user)) - - def test_return_age(self): - birth_day = (date.today() -timedelta(days = 700)) - self.assertEqual(1, get_current_age(birth_day)) - - def test_determine_first_name_last_name_if_singluar_name(self): - name = "Benny" - self.assertEqual(("Benny", ""), determine_first_name_last_name(name)) - - def test_determine_first_name_last_name_if_name_lte_3_words(self): - name = "Fadhlan Hazmi" - self.assertEqual(("Fadhlan", "Hazmi"), determine_first_name_last_name(name)) - - name = "Benny William Pardede" - self.assertEqual(("Benny William", "Pardede"), determine_first_name_last_name(name)) - - def test_determine_first_name_last_name_if_name_gt_3_words(self): - name = "Kevin Frankly Samuel Pardede" - self.assertEqual(("Kevin Frankly", "Pardede"), determine_first_name_last_name(name)) - - name = "Sergio Leonel Aguero del Castillo" - self.assertEqual(("Sergio Leonel", "Castillo"), determine_first_name_last_name(name)) + def create_first_last_name(self): + user = User.objects.create_user('dummy.student2', 'dummy.student@student.com', 'lalala123') + user.first_name = 'Riansyah' + user.last_name = 'Tohamba' + return user + + def test_display_full_name(self): + self.assertEqual('Riansyah Tohamba', + get_display_name(self.create_first_last_name(), full_name=True) + ) + + def test_display_last_name_shortened(self): + self.assertEqual('Riansyah T.', + get_display_name(self.create_first_last_name(), full_name=False) + ) + + def test_display_first_name(self): + user = User.objects.create_user('dummy.student2', 'dummy.student@student.com', 'lalala123') + user.first_name = 'Riansyah' + self.assertEqual('Riansyah', get_display_name(user)) + + def test_display_last_name(self): + user = User.objects.create_user('dummy.student2', 'dummy.student@student.com', 'lalala123') + user.last_name = 'Tohamba' + self.assertEqual('Tohamba', get_display_name(user)) + + def test_display_username(self): + user = User.objects.create_user('dummy.student2', 'dummy.student@student.com', 'lalala123') + self.assertEqual('dummy.student2', get_display_name(user)) + + def test_return_age(self): + birth_day = (date.today() - timedelta(days=700)) + self.assertEqual(1, get_current_age(birth_day)) + + def test_determine_first_name_last_name_if_singluar_name(self): + name = "Benny" + self.assertEqual(("Benny", ""), determine_first_name_last_name(name)) + + def test_determine_first_name_last_name_if_name_lte_3_words(self): + name = "Fadhlan Hazmi" + self.assertEqual(("Fadhlan", "Hazmi"), determine_first_name_last_name(name)) + + name = "Benny William Pardede" + self.assertEqual(("Benny William", "Pardede"), determine_first_name_last_name(name)) + + def test_determine_first_name_last_name_if_name_gt_3_words(self): + name = "Kevin Frankly Samuel Pardede" + self.assertEqual(("Kevin Frankly", "Pardede"), determine_first_name_last_name(name)) + + name = "Sergio Leonel Aguero del Castillo" + self.assertEqual(("Sergio Leonel", "Castillo"), determine_first_name_last_name(name)) diff --git a/core/tests/test_vacancies.py b/core/tests/test_vacancies.py index 04a7e64cf28c5203dcebed42e9e594c043efda92..9c87d52cf96f0c539c8828d2ff9297d5ff29ab05 100755 --- a/core/tests/test_vacancies.py +++ b/core/tests/test_vacancies.py @@ -1,18 +1,18 @@ -from datetime import datetime, timedelta -from django.utils import timezone import json +from datetime import datetime, timedelta + import requests_mock -from django.core.exceptions import ValidationError from django.contrib.auth.models import User +from django.core.exceptions import ValidationError +from django.utils import timezone from rest_framework import status from rest_framework.test import APITestCase, APIRequestFactory -from rest_framework.response import Response from core.models.accounts import Company, Student, Supervisor from core.models.vacancies import Vacancy, Application, VacancyMilestone -from core.views.vacancies import date_validator from core.serializers.vacancies import VacancySerializer from core.tests.mocks import mock_csui_oauth_verify, mock_csui_ldap_student, mock_csui_siak_student +from core.views.vacancies import date_validator class ApplicationTests(APITestCase): @@ -21,7 +21,8 @@ class ApplicationTests(APITestCase): mock_csui_ldap_student(mock_obj) mock_csui_siak_student(mock_obj) login_url = '/api/login/' - response = self.client.post(login_url, {'username': 'dummy.mahasiswa', 'password': 'lalala', 'login-type': 'sso-ui'}, + response = self.client.post(login_url, + {'username': 'dummy.mahasiswa', 'password': 'lalala', 'login-type': 'sso-ui'}, format='json') return response.data.get('student').get('id') @@ -47,8 +48,11 @@ class ApplicationTests(APITestCase): new_user = User.objects.create_user('dummy.company', 'dummy.company@company.com', 'lalala123') new_company = Company.objects.create(user=new_user, description="lalala", status=Company.VERIFIED, logo=None, address=None) - new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(1541319300.0), - description="lalala", max_accepted_applicants=3, working_period="3 Bulan", requirements= "requirements", close_time=(timezone.now() + timedelta(days=1))) + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, + open_time=datetime.fromtimestamp(1541319300.0), + description="lalala", max_accepted_applicants=3, working_period="3 Bulan", + requirements="requirements", + close_time=(timezone.now() + timedelta(days=1))) url = '/api/students/' + str(student_id) + '/applied-vacancies/' response = self.client.post(url, {'vacancy_id': new_vacancy.pk, 'cover_letter': 'this is a cover letter.'}, @@ -71,7 +75,8 @@ class ApplicationTests(APITestCase): new_student = Student.objects.create(user=new_user2, npm=1234123412) new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(0), - description="lalala", close_time=datetime.today(), max_accepted_applicants=3, working_period="3 Bulan") + description="lalala", close_time=datetime.today(), + max_accepted_applicants=3, working_period="3 Bulan") Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="lorem ipsum") @@ -93,7 +98,8 @@ class ApplicationTests(APITestCase): address=None) Student.objects.create(user=new_user2, npm=1234123412) new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(0), - description="lalala", close_time=datetime.today(), max_accepted_applicants=3, working_period="3 Bulan") + description="lalala", close_time=datetime.today(), + max_accepted_applicants=3, working_period="3 Bulan") url = '/api/applications/' + str(new_vacancy.pk) + '/count/' @@ -109,12 +115,14 @@ class ApplicationTests(APITestCase): new_company = Company.objects.create(user=new_user, description="lalala", status=Company.VERIFIED, logo=None, address=None) new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(0), - description="lalala", close_time=(timezone.now() - timedelta(days=1)), max_accepted_applicants=3, working_period="3 Bulan") + description="lalala", close_time=(timezone.now() - timedelta(days=1)), + max_accepted_applicants=3, working_period="3 Bulan") url = '/api/students/' + str(student_id) + '/applied-vacancies/' response = self.client.post(url, {'vacancy_id': new_vacancy.pk, 'cover_letter': 'this is a cover letter.'}, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + class BookmarkApplicationTests(APITestCase): @requests_mock.Mocker() def setUp(self, m): @@ -122,7 +130,8 @@ class BookmarkApplicationTests(APITestCase): mock_csui_ldap_student(m) mock_csui_siak_student(m) login_url = '/api/login/' - response = self.client.post(login_url, {'username': 'dummy.mahasiswa', 'password': 'lalala', 'login-type': 'sso-ui'}, + response = self.client.post(login_url, + {'username': 'dummy.mahasiswa', 'password': 'lalala', 'login-type': 'sso-ui'}, format='json') self.student_id = response.data.get('student').get('id') @@ -142,8 +151,10 @@ class BookmarkApplicationTests(APITestCase): new_user = User.objects.create_user('dummy.company2', 'dummy.compan2y@company.com', 'lalala123') new_company = Company.objects.create(user=new_user, description="lalala", status=Company.VERIFIED, logo=None, address=None) - new_vacancy = Vacancy.objects.create(company=new_company, verified=True, requirements= "requirements", open_time=datetime.fromtimestamp(1541319300.0), - description="lalala", close_time=timezone.now(), max_accepted_applicants=3, working_period="3 Bulan") + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, requirements="requirements", + open_time=datetime.fromtimestamp(1541319300.0), + description="lalala", close_time=timezone.now(), max_accepted_applicants=3, + working_period="3 Bulan") url = '/api/students/' + str(self.student_id) + '/bookmarked-vacancies/' response = self.client.post(url, {'vacancy_id': new_vacancy.pk}, format='json') @@ -160,7 +171,8 @@ class VacancyTest(APITestCase): mock_csui_ldap_student(mock_obj) mock_csui_siak_student(mock_obj) login_url = '/api/login/' - self.client.post(login_url, {'username': 'dummy.mahasiswa', 'password': 'lalala', 'login-type': 'sso-ui'}, format='json') + self.client.post(login_url, {'username': 'dummy.mahasiswa', 'password': 'lalala', 'login-type': 'sso-ui'}, + format='json') def test_verified_vacancy_list(self): superuser = User.objects.create_superuser('dummy.company', 'dummy.company@company.com', 'lalala123') @@ -174,8 +186,10 @@ class VacancyTest(APITestCase): def test_search_vacancy(self, m): superuser = User.objects.create_user('dummy.company', 'dummy.company@company.com', 'lalala123') company = Company.objects.create(user=superuser, description="This is a test company") - Vacancy.objects.create(company=company, open_time=datetime.now(), close_time=datetime.now(), name="Software Engineer", max_accepted_applicants=3, working_period="3 Bulan") - Vacancy.objects.create(company=company, open_time=datetime.now(), close_time=datetime.now(), name="Data Engineer", max_accepted_applicants=3, working_period="3 Bulan") + Vacancy.objects.create(company=company, open_time=datetime.now(), close_time=datetime.now(), + name="Software Engineer", max_accepted_applicants=3, working_period="3 Bulan") + Vacancy.objects.create(company=company, open_time=datetime.now(), close_time=datetime.now(), + name="Data Engineer", max_accepted_applicants=3, working_period="3 Bulan") self.login(m) url = '/api/vacancies/?search=software' @@ -207,15 +221,17 @@ class VacancyTest(APITestCase): open_time = datetime(2019, 10, 20) close_time = datetime(2019, 12, 20) Vacancy.objects.create(company=new_company, verified=True, open_time=open_time, - description='', close_time=close_time, name='vacancy1', max_accepted_applicants=3, working_period="3 Bulan") + description='', close_time=close_time, name='vacancy1', max_accepted_applicants=3, + working_period="3 Bulan") Vacancy.objects.create(company=new_company2, verified=True, open_time=open_time, - description='', close_time=close_time, name='vacancy2', max_accepted_applicants=3, working_period="3 Bulan") + description='', close_time=close_time, name='vacancy2', max_accepted_applicants=3, + working_period="3 Bulan") url = '/api/vacancies/?company={}&company={}'.format(new_company.id, new_company2.id) response = self.client.get(url, format='json') Vacancy.objects.filter(company__id__in=[new_company.id, new_company2.id]) self.assertEqual(dict(response.data)['count'], Vacancy.objects.count()) self.assertEqual(response.status_code, status.HTTP_200_OK) - + def test_sort_vacancies(self): superuser = User.objects.create_superuser('dummy.company', 'dummy.company@company.com', 'lalala123') self.client.force_authenticate(user=superuser) @@ -226,29 +242,37 @@ class VacancyTest(APITestCase): open_time = datetime(2019, 10, 20) close_time = datetime(2019, 12, 20) Vacancy.objects.create(company=new_company, verified=True, open_time=open_time, salary=3000000, - description='', close_time=close_time, name='vacancy1', max_accepted_applicants=3, working_period="3 Bulan") + description='', close_time=close_time, name='vacancy1', max_accepted_applicants=3, + working_period="3 Bulan") Vacancy.objects.create(company=new_company, verified=True, open_time=open_time, salary=3500000, - description='', close_time=close_time, name='vacancy2', max_accepted_applicants=3, working_period="3 Bulan") + description='', close_time=close_time, name='vacancy2', max_accepted_applicants=3, + working_period="3 Bulan") factory = APIRequestFactory() url_name_asc = '/api/vacancies/?sort=name&order=ascending' request = factory.get(url_name_asc) response = self.client.get(url_name_asc, format='json') - self.assertEqual(dict(response.data)['results'], VacancySerializer(Vacancy.objects.order_by('name'), many=True, context={'request': request}).data) + self.assertEqual(dict(response.data)['results'], VacancySerializer(Vacancy.objects.order_by('name'), many=True, + context={'request': request}).data) url_salary_asc = '/api/vacancies/?sort=salary' response = self.client.get(url_salary_asc) request = factory.get(url_salary_asc) - self.assertEqual(dict(response.data)['results'], VacancySerializer(Vacancy.objects.order_by('salary'), many=True, context={'request': request}).data) + self.assertEqual(dict(response.data)['results'], + VacancySerializer(Vacancy.objects.order_by('salary'), many=True, + context={'request': request}).data) url_name_desc = '/api/vacancies/?sort=name&order=descending' response = self.client.get(url_name_desc) request = factory.get(url_name_desc) - self.assertEqual(dict(response.data)['results'], VacancySerializer(Vacancy.objects.order_by('-name'), many=True, context={'request': request}).data) + self.assertEqual(dict(response.data)['results'], VacancySerializer(Vacancy.objects.order_by('-name'), many=True, + context={'request': request}).data) url_salary_desc = '/api/vacancies/?sort=salary&order=descending' response = self.client.get(url_salary_desc) request = factory.get(url_salary_desc) - self.assertEqual(dict(response.data)['results'], VacancySerializer(Vacancy.objects.order_by('-salary'), many=True, context={'request': request}).data) + self.assertEqual(dict(response.data)['results'], + VacancySerializer(Vacancy.objects.order_by('-salary'), many=True, + context={'request': request}).data) def test_fail_on_unverified_user_vacancy_list(self): url = '/api/vacancies/' @@ -278,7 +302,8 @@ class VacancyTest(APITestCase): new_company = Company.objects.create(user=new_user, description="lalala", status=Company.VERIFIED, logo=None, address=None) Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(1541319300.0), - description="expired vacancy", close_time=datetime.fromtimestamp(1541319301.0), max_accepted_applicants=3, working_period="3 Bulan") + description="expired vacancy", close_time=datetime.fromtimestamp(1541319301.0), + max_accepted_applicants=3, working_period="3 Bulan") url = '/api/vacancies/?opened_only=true' response = self.client.get(url, format='json') @@ -290,7 +315,8 @@ class VacancyTest(APITestCase): address=None) new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(0), - description="lalala", close_time=timezone.now() - timedelta(minutes = 10),working_period="3 Bulan") + description="lalala", close_time=timezone.now() - timedelta(minutes=10), + working_period="3 Bulan") self.client.force_authenticate(user=superuser) response = new_vacancy.apply_before @@ -303,7 +329,7 @@ class VacancyTest(APITestCase): address=None) new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(0), - description="lalala", close_time=timezone.now() + timedelta(minutes = 10), + description="lalala", close_time=timezone.now() + timedelta(minutes=10), max_accepted_applicants=3, working_period="3 Bulan") self.client.force_authenticate(user=superuser) @@ -312,7 +338,8 @@ class VacancyTest(APITestCase): self.assertNotEqual(response, "Pendaftaran ditutup") def test_vacancy_valid_date(self): - self.assertEqual(True, date_validator(str(datetime.today() + timedelta(days=1)), str(datetime.today() + timedelta(days=2)))['is_valid']) + self.assertEqual(True, date_validator(str(datetime.today() + timedelta(days=1)), + str(datetime.today() + timedelta(days=2)))['is_valid']) def test_vacancy_invalid_date(self): self.assertEqual( @@ -345,8 +372,8 @@ class CompanyListsTests(APITestCase): new_user2 = User.objects.create_user('dummy.companyzxc', 'dummy.companyzxc@company.com', 'lalala123') Company.objects.create(user=new_user2, description="lalalaasdsad", status=Company.VERIFIED, - logo=None, - address=None) + logo=None, + address=None) self.client.force_authenticate(new_user2) @@ -383,8 +410,8 @@ class CompanyListsTests(APITestCase): new_user2 = User.objects.create_user('dummy.companyzxc', 'dummy.companyzxc@company.com', 'lalala123') Company.objects.create(user=new_user2, description="lalalaasdsad", status=Company.VERIFIED, - logo=None, - address=None) + logo=None, + address=None) self.client.force_authenticate(new_user2) @@ -400,8 +427,11 @@ class CompanyListsTests(APITestCase): new_user2 = User.objects.create_user('dummy.company4', 'dummy.company4@company.com', 'lalala123') new_student = Student.objects.create(user=new_user2, npm=1234123412) - new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(1541319300.0), - description="lalala", requirements= "requirements", close_time=timezone.now(), max_accepted_applicants=3, working_period="3 Bulan") + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, + open_time=datetime.fromtimestamp(1541319300.0), + description="lalala", requirements="requirements", + close_time=timezone.now(), max_accepted_applicants=3, + working_period="3 Bulan") Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") self.client.force_authenticate(new_user) @@ -418,13 +448,16 @@ class CompanyListsTests(APITestCase): new_user2 = User.objects.create_user('dummy.student', 'dummy.company3@company.com', 'lalala123') new_student = Student.objects.create(user=new_user2, npm=1234123412) - new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(1541319300.0), - description="lalala", requirements= "requirements", close_time=timezone.now(), max_accepted_applicants=3, working_period="3 Bulan") + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, + open_time=datetime.fromtimestamp(1541319300.0), + description="lalala", requirements="requirements", + close_time=timezone.now(), max_accepted_applicants=3, + working_period="3 Bulan") Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") new_user3 = User.objects.create_user('dummy.company4', 'dummy.company4@company.com', 'lalala123') Company.objects.create(user=new_user3, description="lalala", status=Company.VERIFIED, logo=None, - address=None) + address=None) self.client.force_authenticate(new_user3) @@ -440,8 +473,11 @@ class CompanyListsTests(APITestCase): new_user2 = User.objects.create_user('dummy.student', 'dummy.company3@company.com', 'lalala123') new_student = Student.objects.create(user=new_user2, npm=1234123412) - new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(1541319300.0), - description="lalala", requirements= "requirements", close_time=timezone.now(), max_accepted_applicants=3, working_period="3 Bulan") + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, + open_time=datetime.fromtimestamp(1541319300.0), + description="lalala", requirements="requirements", + close_time=timezone.now(), max_accepted_applicants=3, + working_period="3 Bulan") Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") new_user3 = User.objects.create_user('dummy.company4', 'dummy.company4@company.com', 'lalala123') @@ -462,8 +498,11 @@ class CompanyListsTests(APITestCase): new_user2 = User.objects.create_user('dummy.company4', 'dummy.company4@company.com', 'lalala123') new_student = Student.objects.create(user=new_user2, npm=1234123412) - new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(1541319300.0), - description="lalala", requirements= "requirements", close_time=timezone.now(), max_accepted_applicants=3, working_period="3 Bulan") + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, + open_time=datetime.fromtimestamp(1541319300.0), + description="lalala", requirements="requirements", + close_time=timezone.now(), max_accepted_applicants=3, + working_period="3 Bulan") Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") self.client.force_authenticate(new_user) @@ -480,8 +519,11 @@ class CompanyListsTests(APITestCase): new_user2 = User.objects.create_user('dummy.company4', 'dummy.company4@company.com', 'lalala123') new_student = Student.objects.create(user=new_user2, npm=1234123412) - new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(1541319300.0), - description="lalala", requirements= "requirements", close_time=timezone.now(), max_accepted_applicants=3, working_period="3 Bulan") + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, + open_time=datetime.fromtimestamp(1541319300.0), + description="lalala", requirements="requirements", + close_time=timezone.now(), max_accepted_applicants=3, + working_period="3 Bulan") Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") self.client.force_authenticate(new_user) @@ -499,8 +541,11 @@ class CompanyListsTests(APITestCase): new_user2 = User.objects.create_user('dummy.company4', 'dummy.company4@company.com', 'lalala123') new_student = Student.objects.create(user=new_user2, npm=1234123412) - new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(1541319300.0), - description="lalala", requirements= "requirements", close_time=timezone.now(), max_accepted_applicants=3, working_period="3 Bulan") + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, + open_time=datetime.fromtimestamp(1541319300.0), + description="lalala", requirements="requirements", + close_time=timezone.now(), max_accepted_applicants=3, + working_period="3 Bulan") Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") self.client.force_authenticate(new_user) @@ -518,8 +563,11 @@ class CompanyListsTests(APITestCase): new_user2 = User.objects.create_user('dummy.company4', 'dummy.company4@company.com', 'lalala123') new_student = Student.objects.create(user=new_user2, npm=1234123412) - new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(1541319300.0), - description="lalala", requirements= "requirements", close_time=timezone.now(), max_accepted_applicants=3, working_period="3 Bulan") + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, + open_time=datetime.fromtimestamp(1541319300.0), + description="lalala", requirements="requirements", + close_time=timezone.now(), max_accepted_applicants=3, + working_period="3 Bulan") Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") self.client.force_authenticate(new_user) @@ -568,8 +616,10 @@ class SupervisorApprovalTests(APITestCase): new_user2 = User.objects.create_user('dummy.company2', 'dummy.compan2y@company.com', 'lalala123') new_company2 = Company.objects.create(user=new_user2, description="lalala", status=Company.VERIFIED, logo=None, address=None) - new_vacancy2 = Vacancy.objects.create(company=new_company2, verified=False, open_time=datetime.fromtimestamp(1541319300.0), - description="lalala", requirements= "requirements", close_time=timezone.now(), max_accepted_applicants=3) + new_vacancy2 = Vacancy.objects.create(company=new_company2, verified=False, + open_time=datetime.fromtimestamp(1541319300.0), + description="lalala", requirements="requirements", + close_time=timezone.now(), max_accepted_applicants=3) url = '/api/vacancies/' + str(new_vacancy2.pk) + '/verify/' response = self.client.patch(url, {'verified': True}, format='json') @@ -584,14 +634,17 @@ class SupervisorApprovalTests(APITestCase): address=None) self.client.force_authenticate(user=new_user) - new_vacancy = Vacancy.objects.create(company=new_company, verified=False, open_time=datetime.fromtimestamp(1541319300.0), - description="lalala", requirements= "requirements", close_time=timezone.now(), max_accepted_applicants=3) + new_vacancy = Vacancy.objects.create(company=new_company, verified=False, + open_time=datetime.fromtimestamp(1541319300.0), + description="lalala", requirements="requirements", + close_time=timezone.now(), max_accepted_applicants=3) url = '/api/vacancies/' + str(new_vacancy.pk) + '/verify/' response = self.client.patch(url, format='json') self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.assertEqual(new_vacancy.verified, False) + class ValidationPositionNameinCreateLowonganKP(APITestCase): def setUp(self): user = User.objects.create_user('dummy', 'dummy@dummy.com', 'dummy') @@ -606,10 +659,10 @@ class ValidationPositionNameinCreateLowonganKP(APITestCase): self.url = '/api/vacancies/' self.payload = { "name": "dummy", - "company" : self.company.id, - "open_time" : datetime.today(), - "close_time" : datetime.today() + timedelta(days=10), - "description" : "dummy", + "company": self.company.id, + "open_time": datetime.today(), + "close_time": datetime.today() + timedelta(days=10), + "description": "dummy", "working_period": "Summer 2019", "max_accepted_applicants": 10, } @@ -617,7 +670,7 @@ class ValidationPositionNameinCreateLowonganKP(APITestCase): def test_name_contains_only_alphabets(self): self.payload["name"] = "Engineer" - self.payload["requirements" ] = "lalala" + self.payload["requirements"] = "lalala" response = self.client.post( self.url, @@ -631,7 +684,7 @@ class ValidationPositionNameinCreateLowonganKP(APITestCase): def test_name_contains_only_alphabets_and_spaces(self): self.payload["name"] = "Software Engineer" - self.payload["requirements" ] = "lala la" + self.payload["requirements"] = "lala la" response = self.client.post( self.url, @@ -738,7 +791,7 @@ class ValidationPositionNameinCreateLowonganKP(APITestCase): response_status_code = response.status_code self.assertEqual(response_status_code, 400) - + def test_max_accepted_applicants_contains_number_and_alphabet(self): self.payload["max_accepted_applicants"] = "a1r1" @@ -768,8 +821,9 @@ class VacancyMilestoneTests(APITestCase): def setUp(self): super(VacancyMilestoneTests, self).setUp() self.user = User.objects.create_user('dummy.student', 'dummy.student@home.com', 'lalala123') - self.company_user = User.objects.create_user('dummy.company2', 'dummy.compan2y@company.com', 'lalala123') - self.company = Company.objects.create(user=self.company_user, description="lalala", status=Company.VERIFIED, logo=None, + self.company_user = User.objects.create_user('dummy.company2', 'dummy.compan2y@company.com', 'lalala123') + self.company = Company.objects.create(user=self.company_user, description="lalala", status=Company.VERIFIED, + logo=None, address=None) self.vacancy = Vacancy.objects.create(company=self.company, verified=True, open_time=datetime.fromtimestamp(0), description="lalala", close_time=datetime.today()) @@ -785,7 +839,7 @@ class VacancyMilestoneTests(APITestCase): expected_finish=datetime.fromtimestamp(86400)) milestone1.full_clean() - milestone2 = VacancyMilestone(vacancy=self.vacancy, name="a"*101, detail="install things", + milestone2 = VacancyMilestone(vacancy=self.vacancy, name="a" * 101, detail="install things", expected_start=datetime.fromtimestamp(0), expected_finish=datetime.fromtimestamp(86400)) with self.assertRaises(ValidationError, msg="Name with more than 100 character should raise ValidationError"): @@ -932,10 +986,12 @@ class AcceptOneOfferTests(APITestCase): address=None) new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(0), - description="lalala", requirements= "requirements", close_time=datetime.today(), max_accepted_applicants=3) + description="lalala", requirements="requirements", + close_time=datetime.today(), max_accepted_applicants=3) new_vacancy2 = Vacancy.objects.create(company=new_company2, verified=True, open_time=datetime.fromtimestamp(0), - description="lalala", requirements= "requirements", close_time=datetime.today(), max_accepted_applicants=3) + description="lalala", requirements="requirements", + close_time=datetime.today(), max_accepted_applicants=3) new_user3 = User.objects.create_user('dummy.student', 'dummy.student@company.com', 'lalala123') new_student = Student.objects.create(user=new_user3, npm=1234123412) @@ -943,7 +999,6 @@ class AcceptOneOfferTests(APITestCase): return new_user3, new_vacancy, new_vacancy2, new_student def test_number_of_content_response_object_given_id_auth(self): - new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() self.client.force_authenticate(new_user3) @@ -1009,5 +1064,4 @@ class AcceptOneOfferTests(APITestCase): response = self.client.patch(url, format='json') - self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) diff --git a/core/views/accounts/company.py b/core/views/accounts/company.py index c4abca1aa0b5ddab75c1e02a43c5f17e4cc3fa48..e1279ba9d04653016337302f5517115b9ce91c85 100644 --- a/core/views/accounts/company.py +++ b/core/views/accounts/company.py @@ -1,11 +1,13 @@ from rest_framework import viewsets, status from rest_framework.decorators import detail_route -from rest_framework.response import Response from rest_framework.parsers import FormParser, MultiPartParser +from rest_framework.response import Response + from core.lib.permissions import IsAdminOrSelfOrReadOnly, IsAdminOrCompany from core.models.accounts import Company from core.serializers.accounts import CompanySerializer, CompanyUpdateSerializer + class CompanyViewSet(viewsets.ModelViewSet): queryset = Company.objects.all() serializer_class = CompanySerializer @@ -26,4 +28,4 @@ class CompanyViewSet(viewsets.ModelViewSet): serializer.save() return Response(serializer.data, status=status.HTTP_202_ACCEPTED) else: - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) \ No newline at end of file + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) diff --git a/core/views/accounts/login.py b/core/views/accounts/login.py index deabd3193e2b7548ef22d2486449ef7230f6b4ac..fdcef3f32d47de74e10ce6b7034edcf395d4ac97 100644 --- a/core/views/accounts/login.py +++ b/core/views/accounts/login.py @@ -1,17 +1,18 @@ import requests - from django.contrib.auth import authenticate, login from django.contrib.auth.models import User from rest_framework import viewsets, status from rest_framework.permissions import AllowAny from rest_framework.response import Response -from core.views.sso_login import get_access_token, verify_user, get_riwayat_user, get_summary_user -from .utils import determine_first_name_last_name + from core.models.accounts import Student, Supervisor from core.serializers.accounts import UserSerializer +from core.views.sso_login import get_access_token, verify_user, get_summary_user +from .utils import determine_first_name_last_name + class LoginViewSet(viewsets.GenericViewSet): - permission_classes = (AllowAny, ) + permission_classes = (AllowAny,) serializer_class = UserSerializer queryset = User.objects.all() diff --git a/core/views/accounts/registration.py b/core/views/accounts/registration.py index 5562e0332fcc22f19a7c2d3d77af1aa250ef6211..b8d5f237fcf73e5f3c070866452b480998fccdda 100644 --- a/core/views/accounts/registration.py +++ b/core/views/accounts/registration.py @@ -1,12 +1,14 @@ -from django.contrib.auth.models import User from django.contrib.auth import login +from django.contrib.auth.models import User from rest_framework import viewsets, status from rest_framework.parsers import FormParser, MultiPartParser from rest_framework.permissions import AllowAny from rest_framework.response import Response + from core.models.accounts import Company from core.serializers.accounts import RegisterSerializer + class CompanyRegisterViewSet(viewsets.GenericViewSet): permission_classes = (AllowAny,) serializer_class = RegisterSerializer @@ -48,10 +50,10 @@ class CompanyRegisterViewSet(viewsets.GenericViewSet): type: string """ data = {} - for attr in ['password', 'email', 'name', 'description', 'logo', 'address', 'category', 'size','website']: + for attr in ['password', 'email', 'name', 'description', 'logo', 'address', 'category', 'size', 'website']: data[attr] = request.data.get(attr) if data[attr] is None: - return Response({'error': attr+' is required'}, status=status.HTTP_400_BAD_REQUEST) + return Response({'error': attr + ' is required'}, status=status.HTTP_400_BAD_REQUEST) user, created = User.objects.get_or_create( username=data['email'], @@ -77,4 +79,5 @@ class CompanyRegisterViewSet(viewsets.GenericViewSet): login(request, user) return Response(serializer.data, status=status.HTTP_201_CREATED) else: - return Response({'error': 'Company with email '+data['email']+' already exist'}, status=status.HTTP_409_CONFLICT) \ No newline at end of file + return Response({'error': 'Company with email ' + data['email'] + ' already exist'}, + status=status.HTTP_409_CONFLICT) diff --git a/core/views/accounts/student.py b/core/views/accounts/student.py index ed575f3b827c19786ffbb992c7c64690e1fba0ce..029b03acaef7351d69c046665a4ac3837b56a5c5 100644 --- a/core/views/accounts/student.py +++ b/core/views/accounts/student.py @@ -7,10 +7,10 @@ from rest_framework.generics import get_object_or_404 from rest_framework.parsers import FormParser, MultiPartParser from rest_framework.permissions import IsAdminUser, IsAuthenticated from rest_framework.response import Response -from core.lib.permissions import IsAdminOrStudent -from core.models.accounts import Student + from core.lib.permissions import IsAdminOrStudent, IsAdminOrSelfOrReadOnly, IsAdminOrSupervisor, \ IsAdminOrSupervisorOrCompanyOrSelf +from core.models.accounts import Student from core.serializers.accounts import StudentSerializer, StudentUpdateSerializer from core.views.sso_login import get_access_token, verify_user, get_riwayat_user @@ -50,21 +50,36 @@ class StudentViewSet(viewsets.ModelViewSet): elif 'pdf_file' in request.data.keys(): return self.__profile_helper('pdf_file', request, user) - - - if 'github_url' in request.data.keys() and not re.search(github_url_pattern, request.data['github_url']): - return Response({'Error': "Pastikan link github yang anda tulis benar. (Berpola : https://github.com/<username>"}, status=status.HTTP_400_BAD_REQUEST) - - if 'linkedin_url' in request.data.keys() and not re.search(linkedin_url_pattern, request.data['linkedin_url']): - return Response({'Error': "Pastikan link linkedin yang anda tulis benar. (Berpola : https://linkedin.com/in/<username>"}, status=status.HTTP_400_BAD_REQUEST) - - if 'hackerrank_url' in request.data.keys() and not re.search(hackerrank_url_pattern, request.data['hackerrank_url']): - return Response({'Error': "Pastikan link hackerrank yang anda tulis benar. (Berpola : https://hackerrank.com/<username>"}, status=status.HTTP_400_BAD_REQUEST) - + if 'github_url' in request.data.keys(): + if not re.search(github_url_pattern, request.data['github_url']): + return Response( + {'Error': "Pastikan link github yang anda tulis benar. (Berpola : https://github.com/<username>"}, + status=status.HTTP_400_BAD_REQUEST) + + if 'linkedin_url' in request.data.keys(): + if not re.search(linkedin_url_pattern, request.data['linkedin_url']): + return Response({ + 'Error': "Pastikan link linkedin yang anda tulis benar. (Berpola : " + "https://linkedin.com/in/<username>"}, + status=status.HTTP_400_BAD_REQUEST) + + if 'hackerrank_url' in request.data.keys(): + if not re.search(hackerrank_url_pattern, + request.data['hackerrank_url']): + return Response({ + 'Error': "Pastikan link hackerrank yang anda tulis benar. (Berpola : " + "https://hackerrank.com/<username>"}, + status=status.HTTP_400_BAD_REQUEST) + + return self.profile_serialize(request, user) + + def profile_serialize(self, request, user): serializer = self.serializer_class(user, data=request.data, partial=True) if serializer.is_valid(): - if serializer.validated_data.get('skills') is not None and serializer.validated_data.get('skills').isdigit(): - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + if serializer.validated_data.get('skills') is not None: + if serializer.validated_data.get( + 'skills').isdigit(): + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) serializer.save() return Response(serializer.data, status=status.HTTP_202_ACCEPTED) else: @@ -84,9 +99,6 @@ class StudentViewSet(viewsets.ModelViewSet): else: return Response({}, status=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE) - - - @detail_route(methods=['get'], permission_classes=[IsAdminOrStudent]) def transcript(self, request, pk): """ diff --git a/core/views/accounts/supervisor.py b/core/views/accounts/supervisor.py index da9b65a0618b16e0750e44f6d910afffad943f74..5ebe1858a9ad22df9ab02e0f3107fb466740dc9d 100644 --- a/core/views/accounts/supervisor.py +++ b/core/views/accounts/supervisor.py @@ -1,8 +1,10 @@ from rest_framework import viewsets + from core.lib.permissions import IsAdminOrSelfOrReadOnly, IsAdminOrSupervisor from core.models.accounts import Supervisor from core.serializers.accounts import SupervisorSerializer + class SupervisorViewSet(viewsets.ModelViewSet): queryset = Supervisor.objects.all() serializer_class = SupervisorSerializer diff --git a/core/views/accounts/user.py b/core/views/accounts/user.py index 1262b8b60b943ea316d54e0da8662e3b64a107b5..6536207b4e224b3c3476524199144fc99c59991d 100644 --- a/core/views/accounts/user.py +++ b/core/views/accounts/user.py @@ -1,10 +1,12 @@ from django.contrib.auth.models import User from rest_framework import viewsets from rest_framework.decorators import list_route -from rest_framework.response import Response from rest_framework.permissions import IsAdminUser, IsAuthenticated +from rest_framework.response import Response + from core.serializers.accounts import UserSerializer, BasicUserSerializer + class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer diff --git a/core/views/accounts/utils.py b/core/views/accounts/utils.py index 430939c11cbe5bdfd6575cc1abec61ed5e2bf08b..a774d330843b90d78961ef11d8a1d94430c19368 100644 --- a/core/views/accounts/utils.py +++ b/core/views/accounts/utils.py @@ -7,4 +7,4 @@ def determine_first_name_last_name(name): return " ".join(name[0:2]), name[-1] else: - return " ".join(name[0:-1]), name[-1] \ No newline at end of file + return " ".join(name[0:-1]), name[-1] diff --git a/core/views/recommendations.py b/core/views/recommendations.py index e2f64fe90341a3350f9a596eae4d960287a072ae..583cc4bf990b3591eddbf302adaf5bd95d9807a2 100644 --- a/core/views/recommendations.py +++ b/core/views/recommendations.py @@ -77,7 +77,8 @@ class RecommendationViewSet(viewsets.GenericViewSet): update_recommendation.update(content=request.data['content']) update_recommendation = Recommendation.objects.get(id=pk) - update_recommendation_serialized = RecommendationSerializer(update_recommendation, context={'request': request}) + update_recommendation_serialized = RecommendationSerializer(update_recommendation, + context={'request': request}) update_recommendation_serialized_data = update_recommendation_serialized.data message = { diff --git a/core/views/sso_login.py b/core/views/sso_login.py index 7a7cf00dc9ff9423543354e640b1caa04eff2ca6..e78e87a03da099fbe164b8b4e6c82a04808c8fa3 100755 --- a/core/views/sso_login.py +++ b/core/views/sso_login.py @@ -1,6 +1,7 @@ import requests from django.conf import settings + def get_access_token(username, password): try: url = "https://akun.cs.ui.ac.id/oauth/token/" @@ -17,10 +18,12 @@ def get_access_token(username, password): except Exception as e: return None + def get_client_id(): client_id = 'X3zNkFmepkdA47ASNMDZRX3Z9gqSU1Lwywu5WepG' return client_id + def verify_user(access_token): print ("#get identity number") parameters = {"access_token": access_token, "client_id": get_client_id()} @@ -28,14 +31,16 @@ def verify_user(access_token): print ("response => ", response.json()) return response.json() + def get_summary_user(access_token, npm): print ("#get summary user => ", npm) parameters = {"access_token": access_token, "client_id": get_client_id()} - response = requests.get(settings.API_MAHASISWA+str(npm), params=parameters) + response = requests.get(settings.API_MAHASISWA + str(npm), params=parameters) print ("response => ", response.text) print ("response => ", response.json()) return response.json() + def get_riwayat_user(access_token, npm): print ("#get riwayat user => ", npm) parameters = {"access_token": access_token, "client_id": get_client_id()} diff --git a/core/views/vacancies.py b/core/views/vacancies.py index 6c967d6efcf72d53086e9c3b37065a16cea48c3b..455c1867f7611757a9d868dad1020ed615de561c 100755 --- a/core/views/vacancies.py +++ b/core/views/vacancies.py @@ -1,5 +1,7 @@ -from django.utils import timezone +from datetime import datetime, time + from django.db.models import Q +from django.utils import timezone from rest_framework import viewsets, status from rest_framework.decorators import detail_route from rest_framework.exceptions import ValidationError @@ -18,9 +20,6 @@ from core.serializers.vacancies import VacancySerializer, ApplicationSerializer, VacancyMilestoneSerializer from core.views.accounts import StudentViewSet -from datetime import datetime, time -from rest_framework import serializers - def date_validator(open_time, close_time): if open_time < str(datetime.today()): @@ -124,8 +123,8 @@ class VacancyViewSet(MultiSerializerViewSetMixin, viewsets.ModelViewSet): enum_recruiter_activity = ['Selalu', 'Sering', 'Kadang', 'Jarang', 'Tidak Pernah'] if (not isinstance(recruiter_activity, basestring)) or (recruiter_activity not in enum_recruiter_activity): raise ValidationError('Tingkat Respons Perekrut harus salah ' - 'satu dari Selalu, Sering, Kadang, ' - 'Jarang, dan Tidak Pernah!') + 'satu dari Selalu, Sering, Kadang, ' + 'Jarang, dan Tidak Pernah!') def date_range_validator(self, open_time, close_time): validity = date_validator(open_time, close_time)