All files / daos photos.ts

93.75% Statements 30/32
80% Branches 8/10
100% Functions 12/12
92.31% Lines 24/26

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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98      1x 1x   3x           1x 1x             2x 2x       2x   1x         1x                 3x 3x       3x   2x         2x 1x 1x                   2x 2x 2x                 1x 1x     1x           1x                      
import { MyModels } from "../models";
import { PhotoAttributes } from "../models/Photos";
import Photo, { PostPhoto } from "../types/Photo";
import { InvalidKeyError, NotFoundError } from "../types/errors";
import { ForeignKeyConstraintError } from "sequelize";
 
const modelToPhoto = ({ photoID, url, dateAdded }: PhotoAttributes): Photo => ({
    photoID,
    url,
    dateAdded,
});
 
export default function({ Photos, DumpsterPositions, sequelize }: MyModels) {
    return {
        /**
         * Get photos for a given dumpster
         *
         * @param dumpsterID
         */
        getAll: (dumpsterID: number) =>
            sequelize.transaction(async t => {
                const dumpster = await DumpsterPositions.findOne({
                    where: { dumpsterID },
                    transaction: t,
                });
                if (!dumpster) throw new NotFoundError("No such dumpster");
 
                return await Photos.findAll({
                    where: { dumpsterID },
                    limit: 100,
                    order: [["dateAdded", "DESC"]],
                    transaction: t,
                }).then(ps => ps.map(modelToPhoto));
            }),
 
        /**
         * Get most recent photo for a given dumpster
         *
         * @param dumpsterID
         */
        getOne: (dumpsterID: number) =>
            sequelize.transaction(async t => {
                const dumpster = await DumpsterPositions.findOne({
                    where: { dumpsterID },
                    transaction: t,
                });
                if (!dumpster) throw new NotFoundError("No such dumpster");
 
                const photo = await Photos.findOne({
                    where: { dumpsterID },
                    order: [["dateAdded", "DESC"]],
                    transaction: t,
                });
                if (!photo)
                    throw new NotFoundError("No photos for this dumpster");
                return photo;
            }),
 
        /**
         * Add a photo to a dumpster
         *
         * @param dumpsterID
         * @param photo
         */
        addOne: (dumpsterID: number, photo: PostPhoto) =>
            sequelize.transaction(async t => {
                try {
                    await Photos.create(
                        {
                            dumpsterID,
                            ...photo,
                        },
                        { transaction: t },
                    );
                } catch (e) {
                    // Throw a more precise error if possible
                    Eif (e instanceof ForeignKeyConstraintError) {
                        Eif (
                            e.message.includes("REFERENCES `DumpsterPositions`")
                        )
                            throw new NotFoundError("No such dumpster");
                        else throw new InvalidKeyError("No such user ID");
                    }
                    throw e;
                }
                // Get dateAdded back
                return await Photos.findOne({
                    where: {
                        dumpsterID,
                        ...photo,
                    },
                    order: [["dateAdded", "DESC"]],
                    transaction: t,
                });
            }),
    };
}