All files / src/api imageUploadHelper.js

100% Statements 6/6
100% Branches 2/2
100% Functions 1/1
100% Lines 6/6

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44                                                          6x 8x       8x 3x   5x 5x          
import axios from "axios";
 
import { API_ENDPOINTS } from "@/api/endpoints";
 
/**
 * Upload an image for embedding in a question.
 *
 * Teacher-Student API only:
 *   POST /v1/teacher/question/image/upload   (multipart: `file`)
 *
 * The editor used to inline images as base64 `data:` URIs, which put the whole
 * image inside the saved question HTML — re-sent in full to every student on
 * every attempt, with no CDN caching. The bytes are stored once here and the
 * editor embeds a URL instead.
 *
 * Auth rides on the global axios interceptors (BFF httpOnly cookie + CSRF);
 * this deliberately uses the shared instance rather than a bare client.
 *
 * Note there is no role branch. This client only ever authenticates teachers
 * and students, and the staff image API belongs to a different service with a
 * different token — calling it from here would 401 and log the user out.
 *
 * Developer: Allan Ninal
 *
 * @param {FormData} formData Must contain `file`.
 * @returns {Promise<Object>} `{ url, id, path, original_filename, size, content_type, ... }`
 * @throws {Error} With the API's `detail` when present, so the dialog can show
 *   the real reason (415 wrong type, 413 too large) instead of something generic.
 */
export const uploadQuestionImage = async (formData) => {
    try {
        // Content-Type is deliberately NOT set. FormData needs a multipart
        // boundary, and the browser only generates one when it owns the header;
        // setting it by hand yields a boundary-less header the server cannot parse.
        const response = await axios.post(API_ENDPOINTS.teacher.question.imageUpload, formData);
        return response.data;
    } catch (error) {
        const detail = error.response?.data?.detail;
        throw new Error(detail || "Failed to upload image");
    }
};
 
export default uploadQuestionImage;