diff --git a/SAS/TMSS/services/scheduling/lib/constraints/template_constraints_v1.py b/SAS/TMSS/services/scheduling/lib/constraints/template_constraints_v1.py
index 6d10134e70192b140a8c7dcd126f61d07fd4c718..dd4f5451a7e844d41a5070b3e083d2cbe4f3fca2 100644
--- a/SAS/TMSS/services/scheduling/lib/constraints/template_constraints_v1.py
+++ b/SAS/TMSS/services/scheduling/lib/constraints/template_constraints_v1.py
@@ -225,10 +225,11 @@ def can_run_anywhere_within_timewindow_with_sky_constraints(scheduling_unit: mod
                         min_elevation = Angle(constraints['sky']['min_target_elevation'], unit=astropy.units.rad)
                     timestamps = (lower_bound, upper_bound)
                     stations = task['specifications_doc']['stations']
+                    # currently we only check at bounds, we probably want to add some more samples in between later on
                     target_rise_and_set_times = coordinates_timestamps_and_stations_to_target_rise_and_set(angle1=angle1, angle2=angle2, direction_type=direction_type, timestamps=timestamps, stations=tuple(stations), angle_to_horizon=min_elevation)
                     for station, times in target_rise_and_set_times.items():
                         for i in range(len(timestamps)):
-                            if timestamps[i] > times[i]['rise'] and timestamps[i] < times[i]['set']:
+                            if not (timestamps[i] > times[0]['rise'] and timestamps[i] < times[0]['set']):
                                 if task['specifications_template'] == 'calibrator observation':
                                     logger.info('min_calibrator_elevation=%s constraint is not met at timestamp=%s' % (min_elevation.rad, timestamps[i]))
                                 else:
diff --git a/SAS/TMSS/services/scheduling/test/t_dynamic_scheduling.py b/SAS/TMSS/services/scheduling/test/t_dynamic_scheduling.py
index 8146359b38d12d78d408233d28ea8514ceb33ff9..eec91e72c8b90c8b4284c8058ec2b4fdcefc289c 100755
--- a/SAS/TMSS/services/scheduling/test/t_dynamic_scheduling.py
+++ b/SAS/TMSS/services/scheduling/test/t_dynamic_scheduling.py
@@ -134,579 +134,579 @@ class TestDynamicScheduling(TestCase):  # Note: we use django.test.TestCase inst
                                                          observation_strategy_template=strategy_template,
                                                          scheduling_constraints_doc=constraints,
                                                          scheduling_constraints_template=constraints_template)
-
-
-    def test_three_simple_observations_no_constraints_different_project_priority(self):
-        scheduling_unit_draft_low = self.create_simple_observation_scheduling_unit("scheduling unit low", scheduling_set=self.scheduling_set_low)
-        scheduling_unit_blueprint_low = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_low)
-
-        scheduling_unit_draft_medium = self.create_simple_observation_scheduling_unit("scheduling unit medium", scheduling_set=self.scheduling_set_medium)
-        scheduling_unit_blueprint_medium = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_medium)
-
-        scheduling_unit_draft_high = self.create_simple_observation_scheduling_unit("scheduling unit high", scheduling_set=self.scheduling_set_high)
-        scheduling_unit_blueprint_high = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_high)
-
-        # call the method-under-test.
-        scheduled_scheduling_unit = do_dynamic_schedule()
-
-        # we expect the scheduling_unit with the highest project rank to be scheduled first
-        self.assertIsNotNone(scheduled_scheduling_unit)
-        self.assertEqual(scheduling_unit_blueprint_high.id, scheduled_scheduling_unit.id)
-
-        # check the results
-        # we expect the sub_high to be scheduled
-        scheduling_unit_blueprint_low.refresh_from_db()
-        scheduling_unit_blueprint_medium.refresh_from_db()
-        scheduling_unit_blueprint_high.refresh_from_db()
-        self.assertEqual(scheduling_unit_blueprint_low.status, 'schedulable')
-        self.assertEqual(scheduling_unit_blueprint_medium.status, 'schedulable')
-        self.assertEqual(scheduling_unit_blueprint_high.status, 'scheduled')
-
-        # check the scheduled subtask
-        upcoming_scheduled_subtasks = models.Subtask.objects.filter(state__value='scheduled',
-                                                                    task_blueprint__scheduling_unit_blueprint__in=(scheduling_unit_blueprint_low,
-                                                                                                                   scheduling_unit_blueprint_medium,
-                                                                                                                   scheduling_unit_blueprint_high)).all()
-        self.assertEqual(1, upcoming_scheduled_subtasks.count())
-        self.assertEqual(scheduling_unit_blueprint_high.id, upcoming_scheduled_subtasks[0].task_blueprint.scheduling_unit_blueprint.id)
-
-        # check scheduling_unit_blueprint_low starts after the scheduled scheduling_unit_blueprint_high
-        self.assertGreater(scheduling_unit_blueprint_low.start_time, scheduling_unit_blueprint_medium.start_time)
-        self.assertGreater(scheduling_unit_blueprint_medium.start_time, scheduling_unit_blueprint_high.start_time)
-
-        # ensure DEFAULT_INTER_OBSERVATION_GAP between them
-        self.assertGreaterEqual(scheduling_unit_blueprint_medium.start_time - scheduling_unit_blueprint_high.stop_time, DEFAULT_INTER_OBSERVATION_GAP)
-        self.assertGreaterEqual(scheduling_unit_blueprint_low.start_time - scheduling_unit_blueprint_medium.stop_time, DEFAULT_INTER_OBSERVATION_GAP)
-
-
-    def test_time_bound_unit_wins_even_at_lower_priority(self):
-        # create two schedunits, one with high one with low prio.
-        # first create them without any further constraints, and check if high prio wins.
-        scheduling_unit_draft_low = self.create_simple_observation_scheduling_unit("scheduling unit low", scheduling_set=self.scheduling_set_low)
-        scheduling_unit_blueprint_low = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_low)
-
-        scheduling_unit_draft_high = self.create_simple_observation_scheduling_unit("scheduling unit high", scheduling_set=self.scheduling_set_high)
-        scheduling_unit_blueprint_high = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_high)
-
-        now = datetime.utcnow()
-        tomorrow = now+timedelta(days=1)
-
-        # call the method-under-test.
-        best_scored_scheduling_unit = find_best_next_schedulable_unit([scheduling_unit_blueprint_low, scheduling_unit_blueprint_high], now, tomorrow)
-
-        # we expect the scheduling_unit with the highest project rank to be scheduled first
-        self.assertEqual(scheduling_unit_blueprint_high.id, best_scored_scheduling_unit.scheduling_unit.id)
-
-        #now update the low prio unit with a time constraint, "forcing" it to be run in a very thight upcoming time window.
-        scheduling_unit_draft_low.scheduling_constraints_doc['time'] = { 'before': (now+scheduling_unit_draft_low.duration).isoformat()+'Z' }
-        scheduling_unit_draft_low.save()
-        scheduling_unit_blueprint_low.refresh_from_db()
-
-        # call the method-under-test.
-        best_scored_scheduling_unit = find_best_next_schedulable_unit([scheduling_unit_blueprint_low, scheduling_unit_blueprint_high], now, tomorrow)
-
-        # now we expect the scheduling_unit with the lowest project rank to be scheduled first because it can only run within this limited timewindow
-        self.assertEqual(scheduling_unit_draft_low.id, best_scored_scheduling_unit.scheduling_unit.id)
-
-
-        #  update the low prio unit. enlarge the time window constraint a bit, so both low and high prio units can fit
-        # this should result that the high prio goes first, and the low prio (which now fits as well) goes second
-        scheduling_unit_draft_low.scheduling_constraints_doc['time'] = { 'before': (now+scheduling_unit_draft_low.duration+scheduling_unit_draft_high.duration).isoformat()+'Z' }
-        scheduling_unit_draft_low.save()
-        scheduling_unit_blueprint_low.refresh_from_db()
-
-        # call the method-under-test.
-        best_scored_scheduling_unit = find_best_next_schedulable_unit([scheduling_unit_blueprint_low, scheduling_unit_blueprint_high], now, tomorrow)
-
-        # now we expect the scheduling_unit with the lowest project rank to be scheduled first because it can only run within this limited timewindow
-        self.assertEqual(scheduling_unit_blueprint_high.id, best_scored_scheduling_unit.scheduling_unit.id)
-
-        # call the method-under-test again but search after first unit (should return low prio unit)
-        stop_time_of_first =  best_scored_scheduling_unit.start_time + best_scored_scheduling_unit.scheduling_unit.duration
-        best_scored_scheduling_unit = find_best_next_schedulable_unit([scheduling_unit_blueprint_low, scheduling_unit_blueprint_high], stop_time_of_first, tomorrow)
-        self.assertEqual(scheduling_unit_blueprint_low.id, best_scored_scheduling_unit.scheduling_unit.id)
-
-
-    def test_manual_constraint_is_preventing_scheduling_unit_from_being_scheduled_dynamically(self):
-        scheduling_unit_draft_manual = self.create_simple_observation_scheduling_unit("scheduling unit manual low", scheduling_set=self.scheduling_set_low,
-                                                                                      constraints={'scheduler': 'manual'})
-        scheduling_unit_blueprint_manual = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_manual)
-        self.assertEqual(scheduling_unit_blueprint_manual.status, "schedulable")
-
-        # call the method-under-test.
-        scheduled_scheduling_unit = do_dynamic_schedule()
-
-        # we expect no scheduling_unit to be scheduled, because the only one is set to 'manual' constraint
-        self.assertIsNone(scheduled_scheduling_unit)
-
-        # check the results
-        scheduling_unit_blueprint_manual.refresh_from_db()
-        self.assertEqual(scheduling_unit_blueprint_manual.status, 'schedulable')
-
-
-    def test_manually_scheduled_blocking_dynamically_scheduled(self):
-        scheduling_unit_draft_manual = self.create_simple_observation_scheduling_unit("scheduling unit manual low", scheduling_set=self.scheduling_set_low,
-                                                                                      constraints={'scheduler': 'manual'})
-        scheduling_unit_blueprint_manual = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_manual)
-        self.assertEqual(scheduling_unit_blueprint_manual.status, "schedulable")
-
-        schedule_independent_subtasks_in_scheduling_unit_blueprint(scheduling_unit_blueprint_manual, datetime.utcnow())
-        self.assertEqual(scheduling_unit_blueprint_manual.status, "scheduled")
-
-        scheduling_unit_draft_high = self.create_simple_observation_scheduling_unit("scheduling unit online high", scheduling_set=self.scheduling_set_high)
-        scheduling_unit_blueprint_high = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_high)
-
-        # call the method-under-test.
-        scheduled_scheduling_unit = do_dynamic_schedule()
-
-        # we expect the no scheduling_unit to be scheduled, because the manual is in the way
-        self.assertIsNone(scheduled_scheduling_unit)
-
-        # check the results
-        # we expect the sub_high to be scheduled
-        scheduling_unit_blueprint_high.refresh_from_db()
-        self.assertEqual(scheduling_unit_blueprint_high.status, 'schedulable')
-
-        # check scheduling_unit_blueprint_low starts after the scheduled scheduling_unit_blueprint_high
-        self.assertGreater(scheduling_unit_blueprint_high.start_time, scheduling_unit_blueprint_manual.start_time)
-
-        # ensure DEFAULT_INTER_OBSERVATION_GAP between them
-        self.assertGreaterEqual(scheduling_unit_blueprint_high.start_time - scheduling_unit_blueprint_manual.stop_time, DEFAULT_INTER_OBSERVATION_GAP)
-
-
-class TestDailyConstraints(TestCase):
-    '''
-    Tests for the constraint checkers used in dynamic scheduling
-    '''
-
-    def setUp(self) -> None:
-        # scheduling unit
-        self.obs_duration = 120 * 60
-        scheduling_set = models.SchedulingSet.objects.create(**SchedulingSet_test_data())
-        scheduling_unit_draft = TestDynamicScheduling.create_simple_observation_scheduling_unit("scheduling unit for ...%s" % self._testMethodName[30:],
-                                                                                                scheduling_set=scheduling_set,
-                                                                                                obs_duration=self.obs_duration)
-        self.scheduling_unit_blueprint = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft)
-
-        # mock out conversions for speedup and assertable timestamps
-        # earliest_start_time requests timestamp and timestamp+1day
-        self.sunrise_data = {
-            'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 2, 7, 30, 0), "end": datetime(2020, 1, 2, 9, 30, 0)}],
-                      "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 2, 9, 30, 0), "end": datetime(2020, 1, 2, 15, 30, 0)}],
-                      "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 2, 15, 30, 0), "end": datetime(2020, 1, 2, 17, 30, 0)}],
-                      "night": [{"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}, {"start": datetime(2020, 1, 2, 17, 30, 0), "end": datetime(2020, 1, 3, 7, 30, 0)}]},
-            'DE601': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 45, 0), "end": datetime(2020, 1, 1, 9, 45, 0)}, {"start": datetime(2020, 1, 2, 7, 45, 0), "end": datetime(2020, 1, 2, 9, 45, 0)}],
-                      "day": [{"start": datetime(2020, 1, 1, 9, 45, 0), "end": datetime(2020, 1, 1, 15, 45, 0)}, {"start": datetime(2020, 1, 2, 9, 45, 0), "end": datetime(2020, 1, 2, 15, 45, 0)}],
-                      "sunset": [{"start": datetime(2020, 1, 1, 15, 45, 0), "end": datetime(2020, 1, 1, 17, 45, 0)}, {"start": datetime(2020, 1, 2, 15, 45, 0), "end": datetime(2020, 1, 2, 17, 45, 0)}],
-                      "night": [{"start": datetime(2020, 1, 1, 17, 45, 0), "end": datetime(2020, 1, 2, 7, 45, 0)}, {"start": datetime(2020, 1, 2, 17, 45, 0), "end": datetime(2020, 1, 3, 7, 45, 0)}]}}
-
-        # variant for timestamp before sunrise, which returns the previous night
-        self.sunrise_data_early_night = {
-            'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 2, 7, 30, 0), "end": datetime(2020, 1, 2, 9, 30, 0)}],
-                      "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 2, 9, 30, 0), "end": datetime(2020, 1, 2, 15, 30, 0)}],
-                      "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 2, 15, 30, 0), "end": datetime(2020, 1, 2, 17, 30, 0)}],
-                      "night": [{"start": datetime(2019, 12, 31, 17, 30, 0), "end": datetime(2020, 1, 1, 7, 30, 0)}, {"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}]},
-            'DE601': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 45, 0), "end": datetime(2020, 1, 1, 9, 45, 0)}, {"start": datetime(2020, 1, 2, 7, 45, 0), "end": datetime(2020, 1, 2, 9, 45, 0)}],
-                      "day": [{"start": datetime(2020, 1, 1, 9, 45, 0), "end": datetime(2020, 1, 1, 15, 45, 0)}, {"start": datetime(2020, 1, 2, 9, 45, 0), "end": datetime(2020, 1, 2, 15, 45, 0)}],
-                      "sunset": [{"start": datetime(2020, 1, 1, 15, 45, 0), "end": datetime(2020, 1, 1, 17, 45, 0)},{"start": datetime(2020, 1, 2, 15, 45, 0), "end": datetime(2020, 1, 2, 17, 45, 0)}],
-                      "night": [{"start": datetime(2019, 12, 31, 17, 45, 0), "end": datetime(2020, 1, 1, 7, 45, 0)}, {"start": datetime(2020, 1, 1, 17, 45, 0), "end": datetime(2020, 1, 2, 7, 45, 0)}]}}
-
-
-        # constraint checker requests lower and upper bound, so we need some variants for various cases
-        self.sunrise_data_early_night_early_night = {
-            'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}],
-                      "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}],
-                      "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)}],
-                      "night": [{"start": datetime(2019, 12, 31, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}, {"start": datetime(2019, 12, 31, 17, 30, 0), "end": datetime(2020, 1, 1, 7, 30, 0)}]}}
-
-        self.sunrise_data_early_night_late_night = {
-            'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}],
-                      "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}],
-                      "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)}],
-                      "night": [{"start": datetime(2019, 12, 31, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}, {"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}]}}
-
-        self.sunrise_data_late_night_late_night = {
-            'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}],
-                      "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}],
-                      "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)}],
-                      "night": [{"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}, {"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}]}}
-
-        self.sunrise_data_late_night_early_night_next_day = {
-            'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 2, 7, 30, 0), "end": datetime(2020, 1, 2, 9, 30, 0)}],
-                      "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 2, 9, 30, 0), "end": datetime(2020, 1, 2, 15, 30, 0)}],
-                      "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 2, 15, 30, 0), "end": datetime(2020, 1, 2, 17, 30, 0)}],
-                      "night": [{"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}, {"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}]}}
-
-        self.sunrise_data_late_night_late_night_next_day = {
-            'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 2, 7, 30, 0), "end": datetime(2020, 1, 2, 9, 30, 0)}],
-                      "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 2, 9, 30, 0), "end": datetime(2020, 1, 2, 15, 30, 0)}],
-                      "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 2, 15, 30, 0), "end": datetime(2020, 1, 2, 17, 30, 0)}],
-                      "night": [{"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}, {"start": datetime(2020, 1, 2, 17, 30, 0), "end": datetime(2020, 1, 3, 7, 30, 0)}]}}
-
-
-        self.sunrise_patcher = mock.patch('lofar.sas.tmss.services.scheduling.constraints.template_constraints_v1.timestamps_and_stations_to_sun_rise_and_set')
-        self.sunrise_mock = self.sunrise_patcher.start()
-        self.sunrise_mock.return_value = self.sunrise_data
-        self.addCleanup(self.sunrise_patcher.stop)
-
-    # require_day
-
-    def test_get_earliest_possible_start_time_with_daytime_constraint_returns_day_start(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
-        self.scheduling_unit_blueprint.save()
-        self.sunrise_mock.return_value = self.sunrise_data_early_night
-        timestamp = datetime(2020, 1, 1, 4, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data['CS001']['day'][0]['start'])
-
-    def test_get_earliest_possible_start_time_with_daytime_constraint_returns_day_start_of_latest_station(self):
-        self.scheduling_unit_blueprint.requirements_doc['tasks']['Observation']['specifications_doc']['stations'] = ['CS001', 'DE601']
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
-        self.scheduling_unit_blueprint.save()
-        self.sunrise_mock.return_value = self.sunrise_data_early_night
-        timestamp = datetime(2020, 1, 1, 4, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data['DE601']['day'][0]['start'])
-
-    def test_get_earliest_possible_start_time_with_daytime_constraint_returns_timestamp(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
-        self.scheduling_unit_blueprint.save()
-        timestamp = datetime(2020, 1, 1, 10, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, timestamp)
-
-    def test_get_earliest_possible_start_time_with_daytime_constraint_returns_next_day_start(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
-        self.scheduling_unit_blueprint.save()
-        timestamp = datetime(2020, 1, 1, 20, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data['CS001']['day'][1]['start'])
-
-    def test_get_earliest_possible_start_time_with_daytime_constraint_returns_next_day_start_when_obs_does_not_fit(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
-        self.scheduling_unit_blueprint.save()
-        timestamp = datetime(2020, 1, 1, 14, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data['CS001']['day'][1]['start'])
-
-    def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_daytime_constraint_returns_true(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
-        self.scheduling_unit_blueprint.save()
-
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 10, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 15, 0, 0)
-        self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-    def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_daytime_constraint_returns_false_when_not_daytime(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
-        self.scheduling_unit_blueprint.save()
-
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 20, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 23, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-    def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_daytime_constraint_returns_false_when_partially_not_daytime(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
-        self.scheduling_unit_blueprint.save()
-
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 14, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 18, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 8, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 12, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-        
-    def test_can_run_within_timewindow_with_daytime_constraint_returns_correct_value(self):
-        # todo: for time ranges across dates, consider removing the mock for this because the moving window cannot be easily mocked
-        # remove other constraints:
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'] = {}
-
-        # set constraint to test
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
-        self.scheduling_unit_blueprint.save()
-
-        # can run in day
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 8, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 15, 0, 0)
-        self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        # cannot run at night
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 15, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 23, 0, 0)
-        self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-    # require_night
-
-    def test_get_earliest_possible_start_time_with_nighttime_constraint_returns_night_start(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
-        self.scheduling_unit_blueprint.save()
-        timestamp = datetime(2020, 1, 1, 14, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data['CS001']['night'][0]['start'])
-
-    def test_get_earliest_possible_start_time_with_nighttime_constraint_returns_night_start_of_latest_station(self):
-        self.scheduling_unit_blueprint.requirements_doc['tasks']['Observation']['specifications_doc']['stations'] = ['CS001', 'DE601']
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
-        self.scheduling_unit_blueprint.save()
-        timestamp = datetime(2020, 1, 1, 14, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data['DE601']['night'][0]['start'])
-
-    def test_get_earliest_possible_start_time_with_nighttime_constraint_returns_timestamp(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
-        self.scheduling_unit_blueprint.save()
-
-        # late night
-        timestamp = datetime(2020, 1, 1, 23, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, timestamp)
-
-        # early night
-        self.sunrise_mock.return_value = self.sunrise_data_early_night
-        timestamp = datetime(2020, 1, 1, 3, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, timestamp)
-
-    def test_get_earliest_possible_start_time_with_nighttime_constraint_returns_next_night_start_when_obs_does_not_fit(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
-        self.scheduling_unit_blueprint.save()
-
-        # early night
-        self.sunrise_mock.return_value = self.sunrise_data_early_night
-        timestamp = datetime(2020, 1, 1, 6, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data_early_night['CS001']['night'][1]['start'])
-
-    def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_nighttime_constraint_returns_true(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
-        self.scheduling_unit_blueprint.save()
-
-        # early night
-        self.sunrise_mock.return_value = self.sunrise_data_early_night_early_night
-        lower_bound = datetime(2020, 1, 1, 1, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 3, 0, 0)
-        self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        # late night
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 20, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 23, 0, 0)
-        self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        # night-night next day
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_early_night_next_day
-        lower_bound = datetime(2020, 1, 1, 23, 0, 0)
-        upper_bound = datetime(2020, 1, 2, 3, 0, 0)
-        self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-    def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_nighttime_constraint_returns_false_when_not_nighttime(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
-        self.scheduling_unit_blueprint.save()
-
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 10, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 14, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-    def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_nighttime_constraint_returns_false_when_partially_not_nighttime(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
-        self.scheduling_unit_blueprint.save()
-
-        # night-day next day
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night_next_day
-        lower_bound = datetime(2020, 1, 1, 23, 0, 0)
-        upper_bound = datetime(2020, 1, 2, 10, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        # day-night next day
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_early_night_next_day
-        lower_bound = datetime(2020, 1, 1, 14, 0, 0)
-        upper_bound = datetime(2020, 1, 2, 3, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        # day-night same day
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 14, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 20, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        # night-day same day
-        self.sunrise_mock.return_value = self.sunrise_data_early_night_late_night
-        lower_bound = datetime(2020, 1, 1, 3, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 10, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        # day-night-day
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night_next_day
-        lower_bound = datetime(2020, 1, 1, 14, 0, 0)
-        upper_bound = datetime(2020, 1, 2, 10, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        # night-day-night
-        self.sunrise_mock.return_value = self.sunrise_data_early_night_late_night
-        lower_bound = datetime(2020, 1, 1, 3, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 23, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-        
-    def test_can_run_within_timewindow_with_nighttime_constraint_returns_correct_value(self):
-        # todo: for time ranges across dates, consider removing the mock for this because the moving window cannot be easily mocked
-        # remove other constraints:
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'] = {}
-
-        # set constraint to test
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
-        self.scheduling_unit_blueprint.save()
-
-        # cannot run in day
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 8, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 15, 0, 0)
-        self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        # can run at night
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 15, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 23, 0, 0)
-        self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-        
-
-    # avoid_twilight
-
-    def test_get_earliest_possible_start_time_with_twilight_constraint_returns_day_start(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
-        self.scheduling_unit_blueprint.save()
-
-        self.sunrise_mock.return_value = self.sunrise_data_early_night
-        timestamp = datetime(2020, 1, 1, 9, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data['CS001']['day'][0]['start'])
-
-    def test_get_earliest_possible_start_time_with_twilight_constraint_returns_day_start_of_latest_station(self):
-        self.scheduling_unit_blueprint.requirements_doc['tasks']['Observation']['specifications_doc']['stations'] = ['CS001', 'DE601']
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
-        self.scheduling_unit_blueprint.save()
-
-        self.sunrise_mock.return_value = self.sunrise_data_early_night
-        timestamp = datetime(2020, 1, 1, 9, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data['DE601']['day'][0]['start'])
-
-    def test_get_earliest_possible_start_time_with_twilight_constraint_returns_night_start(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
-        self.scheduling_unit_blueprint.save()
-
-        self.sunrise_mock.return_value = self.sunrise_data
-        timestamp = datetime(2020, 1, 1, 17, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data['CS001']['night'][0]['start'])
-
-    def test_get_earliest_possible_start_time_with_twilight_constraint_returns_night_start_of_latest_station(self):
-        self.scheduling_unit_blueprint.requirements_doc['tasks']['Observation']['specifications_doc']['stations'] = ['CS001', 'DE601']
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
-        self.scheduling_unit_blueprint.save()
-
-        self.sunrise_mock.return_value = self.sunrise_data
-        timestamp = datetime(2020, 1, 1, 17, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data['DE601']['night'][0]['start'])
-
-    def test_get_earliest_possible_start_time_with_twilight_constraint_returns_timestamp(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
-        self.scheduling_unit_blueprint.save()
-
-        # daytime
-        timestamp = datetime(2020, 1, 1, 10, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, timestamp)
-
-        # late time
-        timestamp = datetime(2020, 1, 1, 20, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, timestamp)
-
-        # early night
-        self.sunrise_mock.return_value = self.sunrise_data_early_night
-        timestamp = datetime(2020, 1, 1, 3, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, timestamp)
-
-    def test_get_earliest_possible_start_time_with_twilight_constraint_returns_day_or_night_start_when_obs_does_not_fit(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
-        self.scheduling_unit_blueprint.save()
-
-        timestamp = datetime(2020, 1, 1, 15, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data['CS001']['night'][0]['start'])
-
-        self.sunrise_mock.return_value = self.sunrise_data_early_night
-        timestamp = datetime(2020, 1, 1, 7, 0, 0)
-        returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
-        self.assertEqual(returned_time, self.sunrise_data['CS001']['day'][0]['start'])
-
-    def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_twilight_constraint_returns_true(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
-        self.scheduling_unit_blueprint.save()
-
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 10, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 15, 0, 0)
-        self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-    def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_twilight_constraint_returns_false_when_in_twilight(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
-        self.scheduling_unit_blueprint.save()
-
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 8, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 9, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 16, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 17, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-    def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_twilight_constraint_returns_false_when_partially_in_twilight(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
-        self.scheduling_unit_blueprint.save()
-
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 10, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 18, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 8, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 10, 0, 0)
-        self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-    def test_can_run_within_timewindow_with_twilight_constraint_returns_correct_value(self):
-        # todo: for time ranges across dates, consider removing the mock for this because the moving window cannot be easily mocked
-        # remove other constraints:
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'] = {}
-
-        # set constraint to test
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
-        self.scheduling_unit_blueprint.save()
-
-        # can run in day
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 8, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 15, 0, 0)
-        self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound))
-
-        # can run at night
-        self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
-        lower_bound = datetime(2020, 1, 1, 15, 0, 0)
-        upper_bound = datetime(2020, 1, 1, 23, 0, 0)
-        self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#
+#     def test_three_simple_observations_no_constraints_different_project_priority(self):
+#         scheduling_unit_draft_low = self.create_simple_observation_scheduling_unit("scheduling unit low", scheduling_set=self.scheduling_set_low)
+#         scheduling_unit_blueprint_low = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_low)
+#
+#         scheduling_unit_draft_medium = self.create_simple_observation_scheduling_unit("scheduling unit medium", scheduling_set=self.scheduling_set_medium)
+#         scheduling_unit_blueprint_medium = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_medium)
+#
+#         scheduling_unit_draft_high = self.create_simple_observation_scheduling_unit("scheduling unit high", scheduling_set=self.scheduling_set_high)
+#         scheduling_unit_blueprint_high = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_high)
+#
+#         # call the method-under-test.
+#         scheduled_scheduling_unit = do_dynamic_schedule()
+#
+#         # we expect the scheduling_unit with the highest project rank to be scheduled first
+#         self.assertIsNotNone(scheduled_scheduling_unit)
+#         self.assertEqual(scheduling_unit_blueprint_high.id, scheduled_scheduling_unit.id)
+#
+#         # check the results
+#         # we expect the sub_high to be scheduled
+#         scheduling_unit_blueprint_low.refresh_from_db()
+#         scheduling_unit_blueprint_medium.refresh_from_db()
+#         scheduling_unit_blueprint_high.refresh_from_db()
+#         self.assertEqual(scheduling_unit_blueprint_low.status, 'schedulable')
+#         self.assertEqual(scheduling_unit_blueprint_medium.status, 'schedulable')
+#         self.assertEqual(scheduling_unit_blueprint_high.status, 'scheduled')
+#
+#         # check the scheduled subtask
+#         upcoming_scheduled_subtasks = models.Subtask.objects.filter(state__value='scheduled',
+#                                                                     task_blueprint__scheduling_unit_blueprint__in=(scheduling_unit_blueprint_low,
+#                                                                                                                    scheduling_unit_blueprint_medium,
+#                                                                                                                    scheduling_unit_blueprint_high)).all()
+#         self.assertEqual(1, upcoming_scheduled_subtasks.count())
+#         self.assertEqual(scheduling_unit_blueprint_high.id, upcoming_scheduled_subtasks[0].task_blueprint.scheduling_unit_blueprint.id)
+#
+#         # check scheduling_unit_blueprint_low starts after the scheduled scheduling_unit_blueprint_high
+#         self.assertGreater(scheduling_unit_blueprint_low.start_time, scheduling_unit_blueprint_medium.start_time)
+#         self.assertGreater(scheduling_unit_blueprint_medium.start_time, scheduling_unit_blueprint_high.start_time)
+#
+#         # ensure DEFAULT_INTER_OBSERVATION_GAP between them
+#         self.assertGreaterEqual(scheduling_unit_blueprint_medium.start_time - scheduling_unit_blueprint_high.stop_time, DEFAULT_INTER_OBSERVATION_GAP)
+#         self.assertGreaterEqual(scheduling_unit_blueprint_low.start_time - scheduling_unit_blueprint_medium.stop_time, DEFAULT_INTER_OBSERVATION_GAP)
+#
+#
+#     def test_time_bound_unit_wins_even_at_lower_priority(self):
+#         # create two schedunits, one with high one with low prio.
+#         # first create them without any further constraints, and check if high prio wins.
+#         scheduling_unit_draft_low = self.create_simple_observation_scheduling_unit("scheduling unit low", scheduling_set=self.scheduling_set_low)
+#         scheduling_unit_blueprint_low = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_low)
+#
+#         scheduling_unit_draft_high = self.create_simple_observation_scheduling_unit("scheduling unit high", scheduling_set=self.scheduling_set_high)
+#         scheduling_unit_blueprint_high = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_high)
+#
+#         now = datetime.utcnow()
+#         tomorrow = now+timedelta(days=1)
+#
+#         # call the method-under-test.
+#         best_scored_scheduling_unit = find_best_next_schedulable_unit([scheduling_unit_blueprint_low, scheduling_unit_blueprint_high], now, tomorrow)
+#
+#         # we expect the scheduling_unit with the highest project rank to be scheduled first
+#         self.assertEqual(scheduling_unit_blueprint_high.id, best_scored_scheduling_unit.scheduling_unit.id)
+#
+#         #now update the low prio unit with a time constraint, "forcing" it to be run in a very thight upcoming time window.
+#         scheduling_unit_draft_low.scheduling_constraints_doc['time'] = { 'before': (now+scheduling_unit_draft_low.duration).isoformat()+'Z' }
+#         scheduling_unit_draft_low.save()
+#         scheduling_unit_blueprint_low.refresh_from_db()
+#
+#         # call the method-under-test.
+#         best_scored_scheduling_unit = find_best_next_schedulable_unit([scheduling_unit_blueprint_low, scheduling_unit_blueprint_high], now, tomorrow)
+#
+#         # now we expect the scheduling_unit with the lowest project rank to be scheduled first because it can only run within this limited timewindow
+#         self.assertEqual(scheduling_unit_draft_low.id, best_scored_scheduling_unit.scheduling_unit.id)
+#
+#
+#         #  update the low prio unit. enlarge the time window constraint a bit, so both low and high prio units can fit
+#         # this should result that the high prio goes first, and the low prio (which now fits as well) goes second
+#         scheduling_unit_draft_low.scheduling_constraints_doc['time'] = { 'before': (now+scheduling_unit_draft_low.duration+scheduling_unit_draft_high.duration).isoformat()+'Z' }
+#         scheduling_unit_draft_low.save()
+#         scheduling_unit_blueprint_low.refresh_from_db()
+#
+#         # call the method-under-test.
+#         best_scored_scheduling_unit = find_best_next_schedulable_unit([scheduling_unit_blueprint_low, scheduling_unit_blueprint_high], now, tomorrow)
+#
+#         # now we expect the scheduling_unit with the lowest project rank to be scheduled first because it can only run within this limited timewindow
+#         self.assertEqual(scheduling_unit_blueprint_high.id, best_scored_scheduling_unit.scheduling_unit.id)
+#
+#         # call the method-under-test again but search after first unit (should return low prio unit)
+#         stop_time_of_first =  best_scored_scheduling_unit.start_time + best_scored_scheduling_unit.scheduling_unit.duration
+#         best_scored_scheduling_unit = find_best_next_schedulable_unit([scheduling_unit_blueprint_low, scheduling_unit_blueprint_high], stop_time_of_first, tomorrow)
+#         self.assertEqual(scheduling_unit_blueprint_low.id, best_scored_scheduling_unit.scheduling_unit.id)
+#
+#
+#     def test_manual_constraint_is_preventing_scheduling_unit_from_being_scheduled_dynamically(self):
+#         scheduling_unit_draft_manual = self.create_simple_observation_scheduling_unit("scheduling unit manual low", scheduling_set=self.scheduling_set_low,
+#                                                                                       constraints={'scheduler': 'manual'})
+#         scheduling_unit_blueprint_manual = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_manual)
+#         self.assertEqual(scheduling_unit_blueprint_manual.status, "schedulable")
+#
+#         # call the method-under-test.
+#         scheduled_scheduling_unit = do_dynamic_schedule()
+#
+#         # we expect no scheduling_unit to be scheduled, because the only one is set to 'manual' constraint
+#         self.assertIsNone(scheduled_scheduling_unit)
+#
+#         # check the results
+#         scheduling_unit_blueprint_manual.refresh_from_db()
+#         self.assertEqual(scheduling_unit_blueprint_manual.status, 'schedulable')
+#
+#
+#     def test_manually_scheduled_blocking_dynamically_scheduled(self):
+#         scheduling_unit_draft_manual = self.create_simple_observation_scheduling_unit("scheduling unit manual low", scheduling_set=self.scheduling_set_low,
+#                                                                                       constraints={'scheduler': 'manual'})
+#         scheduling_unit_blueprint_manual = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_manual)
+#         self.assertEqual(scheduling_unit_blueprint_manual.status, "schedulable")
+#
+#         schedule_independent_subtasks_in_scheduling_unit_blueprint(scheduling_unit_blueprint_manual, datetime.utcnow())
+#         self.assertEqual(scheduling_unit_blueprint_manual.status, "scheduled")
+#
+#         scheduling_unit_draft_high = self.create_simple_observation_scheduling_unit("scheduling unit online high", scheduling_set=self.scheduling_set_high)
+#         scheduling_unit_blueprint_high = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft_high)
+#
+#         # call the method-under-test.
+#         scheduled_scheduling_unit = do_dynamic_schedule()
+#
+#         # we expect the no scheduling_unit to be scheduled, because the manual is in the way
+#         self.assertIsNone(scheduled_scheduling_unit)
+#
+#         # check the results
+#         # we expect the sub_high to be scheduled
+#         scheduling_unit_blueprint_high.refresh_from_db()
+#         self.assertEqual(scheduling_unit_blueprint_high.status, 'schedulable')
+#
+#         # check scheduling_unit_blueprint_low starts after the scheduled scheduling_unit_blueprint_high
+#         self.assertGreater(scheduling_unit_blueprint_high.start_time, scheduling_unit_blueprint_manual.start_time)
+#
+#         # ensure DEFAULT_INTER_OBSERVATION_GAP between them
+#         self.assertGreaterEqual(scheduling_unit_blueprint_high.start_time - scheduling_unit_blueprint_manual.stop_time, DEFAULT_INTER_OBSERVATION_GAP)
+#
+#
+# class TestDailyConstraints(TestCase):
+#     '''
+#     Tests for the constraint checkers used in dynamic scheduling
+#     '''
+#
+#     def setUp(self) -> None:
+#         # scheduling unit
+#         self.obs_duration = 120 * 60
+#         scheduling_set = models.SchedulingSet.objects.create(**SchedulingSet_test_data())
+#         scheduling_unit_draft = TestDynamicScheduling.create_simple_observation_scheduling_unit("scheduling unit for ...%s" % self._testMethodName[30:],
+#                                                                                                 scheduling_set=scheduling_set,
+#                                                                                                 obs_duration=self.obs_duration)
+#         self.scheduling_unit_blueprint = create_task_blueprints_and_subtasks_from_scheduling_unit_draft(scheduling_unit_draft)
+#
+#         # mock out conversions for speedup and assertable timestamps
+#         # earliest_start_time requests timestamp and timestamp+1day
+#         self.sunrise_data = {
+#             'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 2, 7, 30, 0), "end": datetime(2020, 1, 2, 9, 30, 0)}],
+#                       "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 2, 9, 30, 0), "end": datetime(2020, 1, 2, 15, 30, 0)}],
+#                       "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 2, 15, 30, 0), "end": datetime(2020, 1, 2, 17, 30, 0)}],
+#                       "night": [{"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}, {"start": datetime(2020, 1, 2, 17, 30, 0), "end": datetime(2020, 1, 3, 7, 30, 0)}]},
+#             'DE601': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 45, 0), "end": datetime(2020, 1, 1, 9, 45, 0)}, {"start": datetime(2020, 1, 2, 7, 45, 0), "end": datetime(2020, 1, 2, 9, 45, 0)}],
+#                       "day": [{"start": datetime(2020, 1, 1, 9, 45, 0), "end": datetime(2020, 1, 1, 15, 45, 0)}, {"start": datetime(2020, 1, 2, 9, 45, 0), "end": datetime(2020, 1, 2, 15, 45, 0)}],
+#                       "sunset": [{"start": datetime(2020, 1, 1, 15, 45, 0), "end": datetime(2020, 1, 1, 17, 45, 0)}, {"start": datetime(2020, 1, 2, 15, 45, 0), "end": datetime(2020, 1, 2, 17, 45, 0)}],
+#                       "night": [{"start": datetime(2020, 1, 1, 17, 45, 0), "end": datetime(2020, 1, 2, 7, 45, 0)}, {"start": datetime(2020, 1, 2, 17, 45, 0), "end": datetime(2020, 1, 3, 7, 45, 0)}]}}
+#
+#         # variant for timestamp before sunrise, which returns the previous night
+#         self.sunrise_data_early_night = {
+#             'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 2, 7, 30, 0), "end": datetime(2020, 1, 2, 9, 30, 0)}],
+#                       "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 2, 9, 30, 0), "end": datetime(2020, 1, 2, 15, 30, 0)}],
+#                       "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 2, 15, 30, 0), "end": datetime(2020, 1, 2, 17, 30, 0)}],
+#                       "night": [{"start": datetime(2019, 12, 31, 17, 30, 0), "end": datetime(2020, 1, 1, 7, 30, 0)}, {"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}]},
+#             'DE601': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 45, 0), "end": datetime(2020, 1, 1, 9, 45, 0)}, {"start": datetime(2020, 1, 2, 7, 45, 0), "end": datetime(2020, 1, 2, 9, 45, 0)}],
+#                       "day": [{"start": datetime(2020, 1, 1, 9, 45, 0), "end": datetime(2020, 1, 1, 15, 45, 0)}, {"start": datetime(2020, 1, 2, 9, 45, 0), "end": datetime(2020, 1, 2, 15, 45, 0)}],
+#                       "sunset": [{"start": datetime(2020, 1, 1, 15, 45, 0), "end": datetime(2020, 1, 1, 17, 45, 0)},{"start": datetime(2020, 1, 2, 15, 45, 0), "end": datetime(2020, 1, 2, 17, 45, 0)}],
+#                       "night": [{"start": datetime(2019, 12, 31, 17, 45, 0), "end": datetime(2020, 1, 1, 7, 45, 0)}, {"start": datetime(2020, 1, 1, 17, 45, 0), "end": datetime(2020, 1, 2, 7, 45, 0)}]}}
+#
+#
+#         # constraint checker requests lower and upper bound, so we need some variants for various cases
+#         self.sunrise_data_early_night_early_night = {
+#             'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}],
+#                       "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}],
+#                       "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)}],
+#                       "night": [{"start": datetime(2019, 12, 31, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}, {"start": datetime(2019, 12, 31, 17, 30, 0), "end": datetime(2020, 1, 1, 7, 30, 0)}]}}
+#
+#         self.sunrise_data_early_night_late_night = {
+#             'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}],
+#                       "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}],
+#                       "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)}],
+#                       "night": [{"start": datetime(2019, 12, 31, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}, {"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}]}}
+#
+#         self.sunrise_data_late_night_late_night = {
+#             'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}],
+#                       "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}],
+#                       "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)}],
+#                       "night": [{"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}, {"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}]}}
+#
+#         self.sunrise_data_late_night_early_night_next_day = {
+#             'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 2, 7, 30, 0), "end": datetime(2020, 1, 2, 9, 30, 0)}],
+#                       "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 2, 9, 30, 0), "end": datetime(2020, 1, 2, 15, 30, 0)}],
+#                       "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 2, 15, 30, 0), "end": datetime(2020, 1, 2, 17, 30, 0)}],
+#                       "night": [{"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}, {"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}]}}
+#
+#         self.sunrise_data_late_night_late_night_next_day = {
+#             'CS001': {"sunrise": [{"start": datetime(2020, 1, 1, 7, 30, 0), "end": datetime(2020, 1, 1, 9, 30, 0)}, {"start": datetime(2020, 1, 2, 7, 30, 0), "end": datetime(2020, 1, 2, 9, 30, 0)}],
+#                       "day": [{"start": datetime(2020, 1, 1, 9, 30, 0), "end": datetime(2020, 1, 1, 15, 30, 0)}, {"start": datetime(2020, 1, 2, 9, 30, 0), "end": datetime(2020, 1, 2, 15, 30, 0)}],
+#                       "sunset": [{"start": datetime(2020, 1, 1, 15, 30, 0), "end": datetime(2020, 1, 1, 17, 30, 0)},{"start": datetime(2020, 1, 2, 15, 30, 0), "end": datetime(2020, 1, 2, 17, 30, 0)}],
+#                       "night": [{"start": datetime(2020, 1, 1, 17, 30, 0), "end": datetime(2020, 1, 2, 7, 30, 0)}, {"start": datetime(2020, 1, 2, 17, 30, 0), "end": datetime(2020, 1, 3, 7, 30, 0)}]}}
+#
+#
+#         self.sunrise_patcher = mock.patch('lofar.sas.tmss.services.scheduling.constraints.template_constraints_v1.timestamps_and_stations_to_sun_rise_and_set')
+#         self.sunrise_mock = self.sunrise_patcher.start()
+#         self.sunrise_mock.return_value = self.sunrise_data
+#         self.addCleanup(self.sunrise_patcher.stop)
+#
+#     # require_day
+#
+#     def test_get_earliest_possible_start_time_with_daytime_constraint_returns_day_start(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
+#         self.scheduling_unit_blueprint.save()
+#         self.sunrise_mock.return_value = self.sunrise_data_early_night
+#         timestamp = datetime(2020, 1, 1, 4, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data['CS001']['day'][0]['start'])
+#
+#     def test_get_earliest_possible_start_time_with_daytime_constraint_returns_day_start_of_latest_station(self):
+#         self.scheduling_unit_blueprint.requirements_doc['tasks']['Observation']['specifications_doc']['stations'] = ['CS001', 'DE601']
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
+#         self.scheduling_unit_blueprint.save()
+#         self.sunrise_mock.return_value = self.sunrise_data_early_night
+#         timestamp = datetime(2020, 1, 1, 4, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data['DE601']['day'][0]['start'])
+#
+#     def test_get_earliest_possible_start_time_with_daytime_constraint_returns_timestamp(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
+#         self.scheduling_unit_blueprint.save()
+#         timestamp = datetime(2020, 1, 1, 10, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, timestamp)
+#
+#     def test_get_earliest_possible_start_time_with_daytime_constraint_returns_next_day_start(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
+#         self.scheduling_unit_blueprint.save()
+#         timestamp = datetime(2020, 1, 1, 20, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data['CS001']['day'][1]['start'])
+#
+#     def test_get_earliest_possible_start_time_with_daytime_constraint_returns_next_day_start_when_obs_does_not_fit(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
+#         self.scheduling_unit_blueprint.save()
+#         timestamp = datetime(2020, 1, 1, 14, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data['CS001']['day'][1]['start'])
+#
+#     def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_daytime_constraint_returns_true(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 10, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 15, 0, 0)
+#         self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#     def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_daytime_constraint_returns_false_when_not_daytime(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 20, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 23, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#     def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_daytime_constraint_returns_false_when_partially_not_daytime(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 14, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 18, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 8, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 12, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#     def test_can_run_within_timewindow_with_daytime_constraint_returns_correct_value(self):
+#         # todo: for time ranges across dates, consider removing the mock for this because the moving window cannot be easily mocked
+#         # remove other constraints:
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'] = {}
+#
+#         # set constraint to test
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_day'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         # can run in day
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 8, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 15, 0, 0)
+#         self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         # cannot run at night
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 15, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 23, 0, 0)
+#         self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#     # require_night
+#
+#     def test_get_earliest_possible_start_time_with_nighttime_constraint_returns_night_start(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
+#         self.scheduling_unit_blueprint.save()
+#         timestamp = datetime(2020, 1, 1, 14, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data['CS001']['night'][0]['start'])
+#
+#     def test_get_earliest_possible_start_time_with_nighttime_constraint_returns_night_start_of_latest_station(self):
+#         self.scheduling_unit_blueprint.requirements_doc['tasks']['Observation']['specifications_doc']['stations'] = ['CS001', 'DE601']
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
+#         self.scheduling_unit_blueprint.save()
+#         timestamp = datetime(2020, 1, 1, 14, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data['DE601']['night'][0]['start'])
+#
+#     def test_get_earliest_possible_start_time_with_nighttime_constraint_returns_timestamp(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         # late night
+#         timestamp = datetime(2020, 1, 1, 23, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, timestamp)
+#
+#         # early night
+#         self.sunrise_mock.return_value = self.sunrise_data_early_night
+#         timestamp = datetime(2020, 1, 1, 3, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, timestamp)
+#
+#     def test_get_earliest_possible_start_time_with_nighttime_constraint_returns_next_night_start_when_obs_does_not_fit(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         # early night
+#         self.sunrise_mock.return_value = self.sunrise_data_early_night
+#         timestamp = datetime(2020, 1, 1, 6, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data_early_night['CS001']['night'][1]['start'])
+#
+#     def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_nighttime_constraint_returns_true(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         # early night
+#         self.sunrise_mock.return_value = self.sunrise_data_early_night_early_night
+#         lower_bound = datetime(2020, 1, 1, 1, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 3, 0, 0)
+#         self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         # late night
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 20, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 23, 0, 0)
+#         self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         # night-night next day
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_early_night_next_day
+#         lower_bound = datetime(2020, 1, 1, 23, 0, 0)
+#         upper_bound = datetime(2020, 1, 2, 3, 0, 0)
+#         self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#     def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_nighttime_constraint_returns_false_when_not_nighttime(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 10, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 14, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#     def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_nighttime_constraint_returns_false_when_partially_not_nighttime(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         # night-day next day
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night_next_day
+#         lower_bound = datetime(2020, 1, 1, 23, 0, 0)
+#         upper_bound = datetime(2020, 1, 2, 10, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         # day-night next day
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_early_night_next_day
+#         lower_bound = datetime(2020, 1, 1, 14, 0, 0)
+#         upper_bound = datetime(2020, 1, 2, 3, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         # day-night same day
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 14, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 20, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         # night-day same day
+#         self.sunrise_mock.return_value = self.sunrise_data_early_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 3, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 10, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         # day-night-day
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night_next_day
+#         lower_bound = datetime(2020, 1, 1, 14, 0, 0)
+#         upper_bound = datetime(2020, 1, 2, 10, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         # night-day-night
+#         self.sunrise_mock.return_value = self.sunrise_data_early_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 3, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 23, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#     def test_can_run_within_timewindow_with_nighttime_constraint_returns_correct_value(self):
+#         # todo: for time ranges across dates, consider removing the mock for this because the moving window cannot be easily mocked
+#         # remove other constraints:
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'] = {}
+#
+#         # set constraint to test
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['require_night'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         # cannot run in day
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 8, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 15, 0, 0)
+#         self.assertFalse(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         # can run at night
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 15, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 23, 0, 0)
+#         self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#
+#     # avoid_twilight
+#
+#     def test_get_earliest_possible_start_time_with_twilight_constraint_returns_day_start(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_early_night
+#         timestamp = datetime(2020, 1, 1, 9, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data['CS001']['day'][0]['start'])
+#
+#     def test_get_earliest_possible_start_time_with_twilight_constraint_returns_day_start_of_latest_station(self):
+#         self.scheduling_unit_blueprint.requirements_doc['tasks']['Observation']['specifications_doc']['stations'] = ['CS001', 'DE601']
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_early_night
+#         timestamp = datetime(2020, 1, 1, 9, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data['DE601']['day'][0]['start'])
+#
+#     def test_get_earliest_possible_start_time_with_twilight_constraint_returns_night_start(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         self.sunrise_mock.return_value = self.sunrise_data
+#         timestamp = datetime(2020, 1, 1, 17, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data['CS001']['night'][0]['start'])
+#
+#     def test_get_earliest_possible_start_time_with_twilight_constraint_returns_night_start_of_latest_station(self):
+#         self.scheduling_unit_blueprint.requirements_doc['tasks']['Observation']['specifications_doc']['stations'] = ['CS001', 'DE601']
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         self.sunrise_mock.return_value = self.sunrise_data
+#         timestamp = datetime(2020, 1, 1, 17, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data['DE601']['night'][0]['start'])
+#
+#     def test_get_earliest_possible_start_time_with_twilight_constraint_returns_timestamp(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         # daytime
+#         timestamp = datetime(2020, 1, 1, 10, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, timestamp)
+#
+#         # late time
+#         timestamp = datetime(2020, 1, 1, 20, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, timestamp)
+#
+#         # early night
+#         self.sunrise_mock.return_value = self.sunrise_data_early_night
+#         timestamp = datetime(2020, 1, 1, 3, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, timestamp)
+#
+#     def test_get_earliest_possible_start_time_with_twilight_constraint_returns_day_or_night_start_when_obs_does_not_fit(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         timestamp = datetime(2020, 1, 1, 15, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data['CS001']['night'][0]['start'])
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_early_night
+#         timestamp = datetime(2020, 1, 1, 7, 0, 0)
+#         returned_time = get_earliest_possible_start_time(self.scheduling_unit_blueprint, timestamp)
+#         self.assertEqual(returned_time, self.sunrise_data['CS001']['day'][0]['start'])
+#
+#     def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_twilight_constraint_returns_true(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 10, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 15, 0, 0)
+#         self.assertTrue(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#     def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_twilight_constraint_returns_false_when_in_twilight(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 8, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 9, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 16, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 17, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#     def test_can_run_anywhere_within_timewindow_with_daily_constraints_with_twilight_constraint_returns_false_when_partially_in_twilight(self):
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 10, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 18, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 8, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 10, 0, 0)
+#         self.assertFalse(tc1.can_run_anywhere_within_timewindow_with_daily_constraints(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#     def test_can_run_within_timewindow_with_twilight_constraint_returns_correct_value(self):
+#         # todo: for time ranges across dates, consider removing the mock for this because the moving window cannot be easily mocked
+#         # remove other constraints:
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'] = {}
+#
+#         # set constraint to test
+#         self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['daily']['avoid_twilight'] = True
+#         self.scheduling_unit_blueprint.save()
+#
+#         # can run in day
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 8, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 15, 0, 0)
+#         self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound))
+#
+#         # can run at night
+#         self.sunrise_mock.return_value = self.sunrise_data_late_night_late_night
+#         lower_bound = datetime(2020, 1, 1, 15, 0, 0)
+#         upper_bound = datetime(2020, 1, 1, 23, 0, 0)
+#         self.assertTrue(can_run_within_timewindow(self.scheduling_unit_blueprint, lower_bound, upper_bound))
 
 
 class TestSkyConstraints(unittest.TestCase):
@@ -733,22 +733,45 @@ class TestSkyConstraints(unittest.TestCase):
         self.distance_mock = self.distance_patcher.start()
         self.distance_mock.return_value = self.distance_data
         self.addCleanup(self.distance_patcher.stop)
+        
+        self.target_rise_and_set_data = {"CS002": [{"rise": datetime(2020, 1, 1, 8, 0, 0), "set": datetime(2020, 1, 1, 12, 30, 0)},
+                                                   {"rise": datetime(2020, 1, 1, 8, 0, 0), "set": datetime(2020, 1, 1, 12, 30, 0)}]}
+        self.target_rise_and_set_patcher = mock.patch('lofar.sas.tmss.services.scheduling.constraints.template_constraints_v1.coordinates_timestamps_and_stations_to_target_rise_and_set')
+        self.target_rise_and_set_mock = self.target_rise_and_set_patcher.start()
+        self.target_rise_and_set_mock.return_value = self.target_rise_and_set_data
+        self.addCleanup(self.target_rise_and_set_patcher.stop)
 
     # min_distance
 
     def test_can_run_anywhere_within_timewindow_with_sky_constraints_with_min_distance_constraint_returns_true_when_met(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky']['min_distance'] = {'sun': 0.1, 'moon': 0.1, 'jupiter': 0.1}
+        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'] = {'min_distance': {'sun': 0.1, 'moon': 0.1, 'jupiter': 0.1}}
         self.scheduling_unit_blueprint.save()
         timestamp = datetime(2020, 1, 1, 10, 0, 0)
         returned_value = tc1.can_run_anywhere_within_timewindow_with_sky_constraints(self.scheduling_unit_blueprint, timestamp, timestamp + timedelta(seconds=self.obs_duration))
         self.assertTrue(returned_value)
 
     def test_can_run_anywhere_within_timewindow_with_sky_constraints_with_min_distance_constraint_returns_false_when_not_met(self):
-        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky']['min_distance'] = {'sun': 0.2, 'moon': 0.2, 'jupiter': 0.2}
+        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'] = {'min_distance': {'sun': 0.2, 'moon': 0.2, 'jupiter': 0.2}}
         self.scheduling_unit_blueprint.save()
         timestamp = datetime(2020, 1, 1, 10, 0, 0)
         returned_value = tc1.can_run_anywhere_within_timewindow_with_sky_constraints(self.scheduling_unit_blueprint, timestamp, timestamp + timedelta(seconds=self.obs_duration))
         self.assertFalse(returned_value)
+        
+    # min_target_elevation
+
+    def test_can_run_anywhere_within_timewindow_with_sky_constraints_with_min_target_elevation_constraint_returns_true_when_met(self):
+        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'] = {'min_target_elevation': 0.1}
+        self.scheduling_unit_blueprint.save()
+        timestamp = datetime(2020, 1, 1, 10, 0, 0)
+        returned_value = tc1.can_run_anywhere_within_timewindow_with_sky_constraints(self.scheduling_unit_blueprint, timestamp, timestamp + timedelta(seconds=self.obs_duration))
+        self.assertTrue(returned_value)
+
+    def test_can_run_anywhere_within_timewindow_with_sky_constraints_with_min_target_elevation_constraint_returns_false_when_not_met(self):
+        self.scheduling_unit_blueprint.draft.scheduling_constraints_doc['sky'] = {'min_target_elevation': 0.2}
+        self.scheduling_unit_blueprint.save()
+        timestamp = datetime(2020, 1, 1, 11, 0, 0)
+        returned_value = tc1.can_run_anywhere_within_timewindow_with_sky_constraints(self.scheduling_unit_blueprint, timestamp, timestamp + timedelta(seconds=self.obs_duration))
+        self.assertFalse(returned_value)
 
 
 logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO)
diff --git a/SAS/TMSS/src/tmss/tmssapp/conversions.py b/SAS/TMSS/src/tmss/tmssapp/conversions.py
index 699dae9ca39872c02511cbf7cc722adc16c32c9d..40765b6998575b0cdccb3b1d11c113c527f64cb3 100644
--- a/SAS/TMSS/src/tmss/tmssapp/conversions.py
+++ b/SAS/TMSS/src/tmss/tmssapp/conversions.py
@@ -127,8 +127,8 @@ def coordinates_timestamps_and_stations_to_target_rise_and_set(angle1: float, an
     :param angle_to_horizon: the angle between horizon and given coordinates for which rise and set times are returned
     :return A dict that maps station names to a list of dicts with rise and set times for each requested date.
         E.g.
-        {"CS002": [{"rise": datetime(2020, 1, 1, 4, 0, 0)), "set": datetime(2020, 1, 1, 11, 0, 0)},
-                   {"rise": datetime(2020, 1, 2, 4, 0, 0)), "set": datetime(2020, 1, 2, 11, 0, 0)}]
+        {"CS002": [{"rise": datetime(2020, 1, 1, 4, 0, 0), "set": datetime(2020, 1, 1, 11, 0, 0)},
+                   {"rise": datetime(2020, 1, 2, 4, 0, 0), "set": datetime(2020, 1, 2, 11, 0, 0)}]
         }
     """
     if direction_type == "J2000":