Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
348 changes: 178 additions & 170 deletions docs/src/openapi.yaml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/src/source/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ For an interactive "Try it out" experience, see the
.. openapi:: ../../openapi.yaml
:group:
:examples:
:format: markdown
8 changes: 5 additions & 3 deletions src/Event/EventsStateManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,14 @@ private function __construct(array $events_state)

/**
* Creates a new EventsStateManager from events_state
* @param array $events_state, events state posted from frontend
* @param ?array $events_state, events state posted from frontend. When
* null (e.g. the optional eventsState param was omitted), it is
* treated as an empty events state.
* @return EventsStateManager
*/
public static function buildFromEventsState(array $events_state) : EventsStateManager
public static function buildFromEventsState(?array $events_state = null) : EventsStateManager
{
return new self($events_state);
return new self($events_state ?? []);
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/Image/JPEG2000/HelioviewerJPXImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,11 @@ private function _queryJPXImageFramesMidPoint() {

$imgIndex = new Database_ImgIndex();

// Parse List of dates and convert them to Unix Timestaps
$startTimesArray = explode(',', $this->_startTime);
$endTimesArray = explode(',', $this->_endTime);
// List of start/end dates as arrays of Unix timestamps
$startTimesArray = $this->_startTime;
$endTimesArray = $this->_endTime;

if(count($startTimesArray) < 1 || count($endTimesArray) < 1){
if(!is_array($startTimesArray) || !is_array($endTimesArray) || count($startTimesArray) < 1 || count($endTimesArray) < 1){
throw new Exception('At least one Start and End date need to be specified. Please use timestamps separated with commas.', 61);
}

Expand Down
12 changes: 5 additions & 7 deletions src/Module/JHelioviewer.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,8 @@ public function getJPXClosestToMidPoint() {
//Build Statistic
include_once HV_ROOT_DIR.'/../src/Database/Statistics.php';
$statistics = new Database_Statistics();
$startArray = explode(",", $this->_params['startTimes']);
$endArray = explode(",", $this->_params['endTimes']);
$startTime = $startArray[0];
$endTime = array_pop($endArray);
$startTime = $this->_params['startTimes'][0];
$endTime = end($this->_params['endTimes']);

$statistics->logJPX(date('Y-m-d H:i:s', $startTime), date('Y-m-d H:i:s', $endTime), $this->_params['sourceId']);

Expand Down Expand Up @@ -309,8 +307,8 @@ private function _getJPXFilename($cadence, $linked) {
* @return string Filename to use for generated JPX image
*/
private function _getJPXMidPointFilename($cadence, $linked) {
$startTimesArray = explode(',', $this->_params['startTimes']);
$endTimesArray = explode(',', $this->_params['endTimes']);
$startTimesArray = $this->_params['startTimes'];
$endTimesArray = $this->_params['endTimes'];
$endArrayValues = array_values($endTimesArray);

$from = str_replace(':', '.', date("Y-m-d\TH:i:s\Z", current($startTimesArray)) );
Expand All @@ -335,7 +333,7 @@ private function _getJPXMidPointFilename($cadence, $linked) {
$filename .= 'L';
}

$hash_of_midpoints = md5($this->_params['startTimes'].">>".$this->_params['endTimes']);
$hash_of_midpoints = md5(implode(',', $this->_params['startTimes']).">>".implode(',', $this->_params['endTimes']));

$result_filename = str_replace(' ', '-', $filename);

Expand Down
23 changes: 23 additions & 0 deletions tests/unit_tests/events/EventsStateManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -498,5 +498,28 @@ public function testItShouldReturnEmptySourcesWhenStateIsEmpty()
$manager = EventsStateManager::buildFromEventsState($state);
$this->assertEquals([], $manager->getSources());
}

// Regression: postScreenshot/postMovie pass the optional eventsState param
// straight through, so an omitted eventsState arrives here as null. It must
// be treated as an empty events state rather than throwing a TypeError.
public function testItShouldBuildFromNullEventsStateAsEmpty()
{
$manager = EventsStateManager::buildFromEventsState(null);
$this->assertInstanceOf(EventsStateManager::class, $manager);
$this->assertFalse($manager->hasEvents());
$this->assertEquals([], $manager->getStateTree());
$this->assertEquals([], $manager->getStateTreeLabelVisibility());
$this->assertEquals([], $manager->getSources());
}

// The eventsState argument is optional; calling with no argument must
// behave identically to passing an empty events state.
public function testItShouldBuildFromOmittedEventsStateAsEmpty()
{
$manager = EventsStateManager::buildFromEventsState();
$this->assertInstanceOf(EventsStateManager::class, $manager);
$this->assertFalse($manager->hasEvents());
$this->assertEquals([], $manager->getSources());
}
}

40 changes: 40 additions & 0 deletions tests/unit_tests/jhelioviewer/HelioviewerJPXImageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,46 @@ public function testCacheConditions_NewFrames() {
$this->_cleanupTestFiles();
}

/**
* Regression test for getJPXClosestToMidPoint.
*
* The 'array_ints' validation rule converts the startTimes/endTimes
* request parameters into PHP arrays before they reach this class. This
* test verifies that the midpoint code path accepts those arrays directly
* instead of throwing a TypeError from explode() (the arguments used to be
* comma-separated strings). See Module_JHelioviewer::getJPXClosestToMidPoint.
*/
public function testMidPointAcceptsArrayInput() {
$output_name = "test_midpoint_SOHO_LASCO_C2.jpx";
$output_json = "test_midpoint_SOHO_LASCO_C2.json";

// Known LASCO C2 time range present in the test database, expressed as
// arrays of Unix timestamps (the shape produced by the array_ints
// validator for the startTimes/endTimes parameters).
$startTimes = [strtotime("2023-12-01 00:00:00 UTC")];
$endTimes = [strtotime("2023-12-01 01:00:00 UTC")];

// Constructing with array inputs and middleFrames = true exercises the
// midpoint query. Before the fix this threw:
// explode(): Argument #2 ($string) must be of type string, array given
$jpx = new Image_JPEG2000_HelioviewerJPXImage(
4, // LASCO C2 source
$startTimes,
$endTimes,
false,
false,
$output_name,
true); // middleFrames = true -> midpoint path

// If the array input was handled correctly, a JPX file was generated
// for the frame closest to the interval midpoint.
$this->assertFileExists(self::MOVIE_DIR . $output_name, "Expected a JPX file to be generated from array midpoint input.");

// Remove generated files.
@unlink(self::MOVIE_DIR . $output_name);
@unlink(self::MOVIE_DIR . $output_json);
}

private function _setupTestFiles() {
if (!is_dir(self::MOVIE_DIR)) {
mkdir(self::MOVIE_DIR);
Expand Down
Loading