|
16 | 16 | test_science_path = "imap/swe/l1/2010/01/" + test_science_filename |
17 | 17 |
|
18 | 18 |
|
| 19 | +@pytest.fixture |
| 20 | +def api_key(monkeypatch): |
| 21 | + """Set a dummy API key so release() doesn't raise on missing key.""" |
| 22 | + monkeypatch.setitem(imap_data_access.config, "API_KEY", "test-api-key") |
| 23 | + |
| 24 | + |
19 | 25 | @pytest.mark.parametrize( |
20 | 26 | ("url", "api_key", "access_token", "expected"), |
21 | 27 | [ |
@@ -794,3 +800,162 @@ def test_reprocess_bad_instrument(mock_send_request): |
794 | 800 | ) |
795 | 801 | # Should not have made any calls to urlopen |
796 | 802 | assert mock_send_request.call_count == 0 |
| 803 | + |
| 804 | + |
| 805 | +@pytest.mark.parametrize( |
| 806 | + "release_params", |
| 807 | + [ |
| 808 | + { |
| 809 | + "instrument": "hit", |
| 810 | + "release_type": "release", |
| 811 | + "start_date": "20260401", |
| 812 | + "end_date": "20260430", |
| 813 | + "release_number": 1, |
| 814 | + }, |
| 815 | + { |
| 816 | + "instrument": "mag", |
| 817 | + "release_type": "release", |
| 818 | + "start_date": "20260101", |
| 819 | + "end_date": "20260131", |
| 820 | + "release_number": 0, |
| 821 | + }, |
| 822 | + ], |
| 823 | +) |
| 824 | +def test_release(mock_send_request, api_key, release_params): |
| 825 | + """Test a successful call to the release API with release type. |
| 826 | +
|
| 827 | + Parameters |
| 828 | + ---------- |
| 829 | + mock_send_request : unittest.mock.MagicMock |
| 830 | + Mock object for requests.Session |
| 831 | + api_key : fixture |
| 832 | + Sets a dummy API key in the config. |
| 833 | + release_params : dict |
| 834 | + Parameters passed to release(). |
| 835 | + """ |
| 836 | + mock_response = MagicMock() |
| 837 | + mock_response.json.return_value = {} |
| 838 | + mock_send_request.return_value = mock_response |
| 839 | + |
| 840 | + imap_data_access.release(**release_params) |
| 841 | + |
| 842 | + mock_send_request.assert_called_once() |
| 843 | + sent_request = mock_send_request.call_args[0][0] |
| 844 | + assert "/release" in sent_request.url |
| 845 | + assert sent_request.method == "GET" |
| 846 | + for key, value in release_params.items(): |
| 847 | + assert f"{key}={value}" in sent_request.url |
| 848 | + |
| 849 | + |
| 850 | +def test_release_no_api_key(mock_send_request): |
| 851 | + """Test that release() raises when no API key is set.""" |
| 852 | + with pytest.raises(ValueError, match="API key is required"): |
| 853 | + imap_data_access.release( |
| 854 | + instrument="hit", |
| 855 | + release_type="release", |
| 856 | + start_date="20260401", |
| 857 | + end_date="20260430", |
| 858 | + release_number=1, |
| 859 | + ) |
| 860 | + assert mock_send_request.call_count == 0 |
| 861 | + |
| 862 | + |
| 863 | +def test_release_invalid_release_type(mock_send_request, api_key): |
| 864 | + """Test that release() raises on an unrecognised release_type.""" |
| 865 | + with pytest.raises(ValueError, match="Not a valid release type"): |
| 866 | + imap_data_access.release( |
| 867 | + instrument="hit", |
| 868 | + release_type="bad-type", |
| 869 | + start_date="20260401", |
| 870 | + end_date="20260430", |
| 871 | + ) |
| 872 | + assert mock_send_request.call_count == 0 |
| 873 | + |
| 874 | + |
| 875 | +def test_release_invalid_instrument(mock_send_request, api_key): |
| 876 | + """Test that release() raises on an invalid instrument for release type.""" |
| 877 | + with pytest.raises(ValueError, match="Not a valid instrument"): |
| 878 | + imap_data_access.release( |
| 879 | + instrument="bad_instrument", |
| 880 | + release_type="release", |
| 881 | + start_date="20260401", |
| 882 | + end_date="20260430", |
| 883 | + release_number=1, |
| 884 | + ) |
| 885 | + assert mock_send_request.call_count == 0 |
| 886 | + |
| 887 | + |
| 888 | +def test_release_missing_release_number(mock_send_request, api_key): |
| 889 | + """Test that release() raises when release_number is missing for release type.""" |
| 890 | + with pytest.raises(ValueError, match=r"release_number.*required"): |
| 891 | + imap_data_access.release( |
| 892 | + instrument="hit", |
| 893 | + release_type="release", |
| 894 | + start_date="20260401", |
| 895 | + end_date="20260430", |
| 896 | + ) |
| 897 | + assert mock_send_request.call_count == 0 |
| 898 | + |
| 899 | + |
| 900 | +def test_release_invalid_start_date(mock_send_request, api_key): |
| 901 | + """Test that release() raises on a bad start_date.""" |
| 902 | + with pytest.raises(ValueError, match="Not a valid start date"): |
| 903 | + imap_data_access.release( |
| 904 | + instrument="hit", |
| 905 | + release_type="release", |
| 906 | + start_date="bad-date", |
| 907 | + end_date="20260430", |
| 908 | + release_number=1, |
| 909 | + ) |
| 910 | + assert mock_send_request.call_count == 0 |
| 911 | + |
| 912 | + |
| 913 | +def test_release_invalid_end_date(mock_send_request, api_key): |
| 914 | + """Test that release() raises on a bad end_date.""" |
| 915 | + with pytest.raises(ValueError, match="Not a valid end date"): |
| 916 | + imap_data_access.release( |
| 917 | + instrument="hit", |
| 918 | + release_type="release", |
| 919 | + start_date="20260401", |
| 920 | + end_date="bad-date", |
| 921 | + release_number=1, |
| 922 | + ) |
| 923 | + assert mock_send_request.call_count == 0 |
| 924 | + |
| 925 | + |
| 926 | +@pytest.mark.parametrize("release_type", ["early-release", "unrelease"]) |
| 927 | +def test_release_missing_manifest_file(mock_send_request, api_key, release_type): |
| 928 | + """Test that early-release and unrelease require a manifest_file.""" |
| 929 | + with pytest.raises(ValueError, match=r"manifest_file.*required"): |
| 930 | + imap_data_access.release(release_type=release_type) |
| 931 | + assert mock_send_request.call_count == 0 |
| 932 | + |
| 933 | + |
| 934 | +def test_release_reprocess_missing_release_number(mock_send_request, api_key): |
| 935 | + """Test that reprocess release type requires release_number.""" |
| 936 | + with pytest.raises(ValueError, match=r"release_number.*required"): |
| 937 | + imap_data_access.release(release_type="reprocess") |
| 938 | + assert mock_send_request.call_count == 0 |
| 939 | + |
| 940 | + |
| 941 | +def test_release_early_release_with_manifest(mock_send_request, api_key, tmp_path): |
| 942 | + """Test early-release type uploads manifest and calls the release endpoint.""" |
| 943 | + manifest = tmp_path / "imap_hit_unrelease_20260101_20260131_v001.txt" |
| 944 | + manifest.write_text("imap_hit_l2_standard-intensity_20260101_v001.cdf\n") |
| 945 | + |
| 946 | + # upload() makes two requests: first returns an S3 presigned URL string, |
| 947 | + # second (PUT to S3) and the final release GET each return an empty dict. |
| 948 | + s3_response = MagicMock() |
| 949 | + s3_response.json.return_value = "https://s3-test-bucket.com/manifest" |
| 950 | + put_response = MagicMock() |
| 951 | + put_response.json.return_value = {} |
| 952 | + release_response = MagicMock() |
| 953 | + release_response.json.return_value = {} |
| 954 | + mock_send_request.side_effect = [s3_response, put_response, release_response] |
| 955 | + |
| 956 | + imap_data_access.release(release_type="early-release", manifest_file=manifest) |
| 957 | + |
| 958 | + assert mock_send_request.call_count == 3 |
| 959 | + last_request = mock_send_request.call_args[0][0] |
| 960 | + assert "/release" in last_request.url |
| 961 | + assert "manifest_file=" in last_request.url |
0 commit comments