Add Vue mixin for delayed job timers
This commit is contained in:
parent
390abbf054
commit
74f22d26a9
|
@ -0,0 +1,50 @@
|
|||
import { calculateRemainingMilliseconds, formatTime } from '~/lib/utils/datetime_utility';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
remainingTime: formatTime(0),
|
||||
remainingTimeIntervalId: null,
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.startRemainingTimeInterval();
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
if (this.remainingTimeIntervalId) {
|
||||
clearInterval(this.remainingTimeIntervalId);
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isDelayedJob() {
|
||||
return this.job && this.job.scheduled;
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
isDelayedJob() {
|
||||
this.startRemainingTimeInterval();
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
startRemainingTimeInterval() {
|
||||
if (this.remainingTimeIntervalId) {
|
||||
clearInterval(this.remainingTimeIntervalId);
|
||||
}
|
||||
|
||||
if (this.isDelayedJob) {
|
||||
this.updateRemainingTime();
|
||||
this.remainingTimeIntervalId = setInterval(() => this.updateRemainingTime(), 1000);
|
||||
}
|
||||
},
|
||||
|
||||
updateRemainingTime() {
|
||||
const remainingMilliseconds = calculateRemainingMilliseconds(this.job.scheduled_at);
|
||||
this.remainingTime = formatTime(remainingMilliseconds);
|
||||
},
|
||||
},
|
||||
};
|
|
@ -5,16 +5,24 @@ describe Projects::JobsController, '(JavaScript fixtures)', type: :controller do
|
|||
|
||||
let(:admin) { create(:admin) }
|
||||
let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
|
||||
let(:project) { create(:project_empty_repo, namespace: namespace, path: 'builds-project') }
|
||||
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
|
||||
let(:project) { create(:project, :repository, namespace: namespace, path: 'builds-project') }
|
||||
let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.id) }
|
||||
let!(:build_with_artifacts) { create(:ci_build, :success, :artifacts, :trace_artifact, pipeline: pipeline, stage: 'test', artifacts_expire_at: Time.now + 18.months) }
|
||||
let!(:failed_build) { create(:ci_build, :failed, pipeline: pipeline, stage: 'build') }
|
||||
let!(:pending_build) { create(:ci_build, :pending, pipeline: pipeline, stage: 'deploy') }
|
||||
let!(:delayed_job) do
|
||||
create(:ci_build, :scheduled,
|
||||
pipeline: pipeline,
|
||||
name: 'delayed job',
|
||||
stage: 'test',
|
||||
commands: 'test')
|
||||
end
|
||||
|
||||
render_views
|
||||
|
||||
before(:all) do
|
||||
clean_frontend_fixtures('builds/')
|
||||
clean_frontend_fixtures('jobs/')
|
||||
end
|
||||
|
||||
before do
|
||||
|
@ -34,4 +42,15 @@ describe Projects::JobsController, '(JavaScript fixtures)', type: :controller do
|
|||
expect(response).to be_success
|
||||
store_frontend_fixture(response, example.description)
|
||||
end
|
||||
|
||||
it 'jobs/delayed.json' do |example|
|
||||
get :show,
|
||||
namespace_id: project.namespace.to_param,
|
||||
project_id: project,
|
||||
id: delayed_job.to_param,
|
||||
format: :json
|
||||
|
||||
expect(response).to be_success
|
||||
store_frontend_fixture(response, example.description)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
import Vue from 'vue';
|
||||
import delayedJobMixin from '~/jobs/mixins/delayed_job_mixin';
|
||||
import mountComponent from 'spec/helpers/vue_mount_component_helper';
|
||||
|
||||
describe('DelayedJobMixin', () => {
|
||||
const delayedJobFixture = getJSONFixture('jobs/delayed.json');
|
||||
const dummyComponent = Vue.extend({
|
||||
mixins: [delayedJobMixin],
|
||||
props: {
|
||||
job: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
template: '<div>{{ remainingTime }}</div>',
|
||||
});
|
||||
|
||||
let vm;
|
||||
|
||||
beforeEach(() => {
|
||||
jasmine.clock().install();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
describe('if job is empty object', () => {
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(dummyComponent, {
|
||||
job: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('sets remaining time to 00:00:00', () => {
|
||||
expect(vm.$el.innerText).toBe('00:00:00');
|
||||
});
|
||||
|
||||
describe('after mounting', () => {
|
||||
beforeEach(done => {
|
||||
Vue.nextTick()
|
||||
.then(done)
|
||||
.catch(done.fail);
|
||||
});
|
||||
|
||||
it('doe not update remaining time', () => {
|
||||
expect(vm.$el.innerText).toBe('00:00:00');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('if job is delayed job', () => {
|
||||
let remainingTimeInMilliseconds = 42000;
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(Date, 'now').and.callFake(
|
||||
() => new Date(delayedJobFixture.scheduled_at).getTime() - remainingTimeInMilliseconds,
|
||||
);
|
||||
vm = mountComponent(dummyComponent, {
|
||||
job: delayedJobFixture,
|
||||
});
|
||||
});
|
||||
|
||||
it('sets remaining time to 00:00:00', () => {
|
||||
expect(vm.$el.innerText).toBe('00:00:00');
|
||||
});
|
||||
|
||||
describe('after mounting', () => {
|
||||
beforeEach(done => {
|
||||
Vue.nextTick()
|
||||
.then(done)
|
||||
.catch(done.fail);
|
||||
});
|
||||
|
||||
it('sets remaining time', () => {
|
||||
expect(vm.$el.innerText).toBe('00:00:42');
|
||||
});
|
||||
|
||||
it('updates remaining time', done => {
|
||||
remainingTimeInMilliseconds = 41000;
|
||||
jasmine.clock().tick(1000);
|
||||
|
||||
Vue.nextTick()
|
||||
.then(() => {
|
||||
expect(vm.$el.innerText).toBe('00:00:41');
|
||||
})
|
||||
.then(done)
|
||||
.catch(done.fail);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue