package org.jooby.quartz;
import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.jooby.Env;
import org.jooby.internal.quartz.JobExpander;
import org.jooby.internal.quartz.QuartzProvider;
import org.jooby.test.MockUnit;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import com.google.inject.Binder;
import com.google.inject.TypeLiteral;
import com.google.inject.binder.AnnotatedBindingBuilder;
import com.google.inject.binder.LinkedBindingBuilder;
import com.google.inject.binder.ScopedBindingBuilder;
import com.google.inject.name.Names;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
@RunWith(PowerMockRunner.class)
@PrepareForTest({Quartz.class, JobExpander.class, ConfigFactory.class })
public class QuartzTest {
@SuppressWarnings("unchecked")
MockUnit.Block scheduler = unit -> {
ScopedBindingBuilder scopeBB = unit.mock(ScopedBindingBuilder.class);
scopeBB.asEagerSingleton();
AnnotatedBindingBuilder<Scheduler> schedulerBB = unit
.mock(AnnotatedBindingBuilder.class);
expect(schedulerBB.toProvider(QuartzProvider.class)).andReturn(scopeBB);
Binder binder = unit.get(Binder.class);
expect(binder.bind(Scheduler.class)).andReturn(schedulerBB);
};
@SuppressWarnings("unchecked")
MockUnit.Block jobUnit = unit -> {
LinkedBindingBuilder<Map<JobDetail, Trigger>> namedJobsBB = unit
.get(LinkedBindingBuilder.class);
AnnotatedBindingBuilder<Map<JobDetail, Trigger>> jobsBB = unit
.mock(AnnotatedBindingBuilder.class);
expect(jobsBB.annotatedWith(Names.named("org.quartz.jobs"))).andReturn(namedJobsBB);
Binder binder = unit.get(Binder.class);
expect(binder.bind(new TypeLiteral<Map<JobDetail, Trigger>>() {
})).andReturn(jobsBB);
};
MockUnit.Block onManaged = unit -> {
Env env = unit.get(Env.class);
expect(env.lifeCycle(QuartzProvider.class)).andReturn(env);
};
@SuppressWarnings({"unchecked" })
@Test
public void defaultUse() throws Exception {
Map<JobDetail, Trigger> jobs = Collections.emptyMap();
new MockUnit(Env.class, Config.class, Binder.class, LinkedBindingBuilder.class)
.expect(unit -> {
unit.mockStatic(JobExpander.class);
expect(JobExpander.jobs(unit.get(Config.class), Arrays.asList(Job.class)))
.andReturn(jobs);
})
.expect(scheduler)
.expect(jobUnit)
.expect(unit -> {
LinkedBindingBuilder<Map<JobDetail, Trigger>> namedJobsBB = unit
.get(LinkedBindingBuilder.class);
namedJobsBB.toInstance(jobs);
})
.expect(onManaged)
.run(unit -> {
new Quartz(Job.class)
.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class));
});
}
@SuppressWarnings({"unchecked" })
@Test
public void withJob() throws Exception {
Map<JobDetail, Trigger> jobs = Collections.emptyMap();
new MockUnit(Env.class, Config.class, Binder.class, LinkedBindingBuilder.class)
.expect(unit -> {
unit.mockStatic(JobExpander.class);
expect(JobExpander.jobs(unit.get(Config.class), Arrays.asList(Job.class)))
.andReturn(jobs);
})
.expect(scheduler)
.expect(jobUnit)
.expect(unit -> {
LinkedBindingBuilder<Map<JobDetail, Trigger>> namedJobsBB = unit
.get(LinkedBindingBuilder.class);
namedJobsBB.toInstance(jobs);
})
.expect(onManaged)
.run(unit -> {
new Quartz()
.with(Job.class)
.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class));
});
}
@SuppressWarnings({"unchecked" })
@Test
public void withJobAndTrigger() throws Exception {
Map<JobDetail, Trigger> jobs = new HashMap<JobDetail, Trigger>();
new MockUnit(Env.class, Config.class, Binder.class, LinkedBindingBuilder.class,
JobDetail.class,
Trigger.class)
.expect(unit -> {
jobs.put(unit.get(JobDetail.class), unit.get(Trigger.class));
unit.mockStatic(JobExpander.class);
expect(JobExpander.jobs(unit.get(Config.class), Arrays.asList()))
.andReturn(jobs);
})
.expect(scheduler)
.expect(jobUnit)
.expect(unit -> {
LinkedBindingBuilder<Map<JobDetail, Trigger>> namedJobsBB = unit
.get(LinkedBindingBuilder.class);
namedJobsBB.toInstance(jobs);
})
.expect(onManaged)
.run(unit -> {
new Quartz()
.with(unit.get(JobDetail.class), unit.get(Trigger.class))
.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class));
});
}
@SuppressWarnings({"unchecked" })
@Test
public void withJobAndTriggerBuilder() throws Exception {
new MockUnit(Env.class, Config.class, Binder.class, LinkedBindingBuilder.class,
JobDetail.class,
Trigger.class)
.expect(unit -> {
unit.mockStatic(JobExpander.class);
expect(JobExpander.jobs(unit.get(Config.class), Arrays.asList()))
.andReturn(Collections.emptyMap());
})
.expect(scheduler)
.expect(jobUnit)
.expect(unit -> {
LinkedBindingBuilder<Map<JobDetail, Trigger>> namedJobsBB = unit
.get(LinkedBindingBuilder.class);
namedJobsBB.toInstance(unit.capture(Map.class));
})
.expect(onManaged)
.run(unit -> {
new Quartz()
.with(Job.class, trigger -> {
trigger.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMinutes(5)
);
})
.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class));
}, unit -> {
assertEquals(1, unit.captured(Map.class).iterator().next().size());
});
}
@SuppressWarnings({"unchecked" })
@Test
public void withJobBuilderAndTriggerBuilder() throws Exception {
new MockUnit(Env.class, Config.class, Binder.class, LinkedBindingBuilder.class,
JobDetail.class,
Trigger.class)
.expect(unit -> {
unit.mockStatic(JobExpander.class);
expect(JobExpander.jobs(unit.get(Config.class), Arrays.asList()))
.andReturn(Collections.emptyMap());
})
.expect(scheduler)
.expect(jobUnit)
.expect(unit -> {
LinkedBindingBuilder<Map<JobDetail, Trigger>> namedJobsBB = unit
.get(LinkedBindingBuilder.class);
namedJobsBB.toInstance(unit.capture(Map.class));
})
.expect(onManaged)
.run(unit -> {
new Quartz()
.with(Job.class, (job, trigger) -> {
trigger.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMinutes(5)
);
})
.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class));
}, unit -> {
assertEquals(1, unit.captured(Map.class).iterator().next().size());
});
}
@Test
public void config() throws Exception {
new MockUnit(Config.class)
.expect(unit -> {
unit.mockStatic(ConfigFactory.class);
Config quartzDef = unit.mock(Config.class);
Config local = unit.mock(Config.class);
expect(local.withFallback(quartzDef)).andReturn(unit.get(Config.class));
expect(ConfigFactory.parseResources(Quartz.class, "quartz.conf"))
.andReturn(local);
expect(ConfigFactory.parseResources(Job.class, "quartz.properties"))
.andReturn(quartzDef);
})
.run(unit -> {
assertEquals(unit.get(Config.class), new Quartz(Job.class).config());
});
}
}