{DEDE_en2a}

Your favourite AmongUs Store!

createdBy(){

Álvaro

Rodríguez González

Andrés "Sitoo"

Martínez Rodríguez

Ángel

Iglesias Préstamo

Pablo

López Amado

Noelia

Iglesias Cuesta

TheApp{

// What is DeDe?

proyect(){

shop(){

GitHub{

// How did we organize our job?

templates(){

issues;

templates(){

issues;

templates(){

issues;

templates(){

templates(){

issues;

issues;

templates(){

pull_requests;

templates(){

pull_requests;

templates(){

kanban(){

minutes(){

reviews(){

Doc{

// How did we document the project?

runtimeView(){

deploymentView(){

domainModel(){

qualityTree(){

TheCode{

// How did we code?

basis(){

tools(){

structure(){

carrierAPI(){

const api: Router = express.Router();

api.get("/rates", getCarrierRates);
api.post("/rates/create", createCarrierRates);

export default api;
// const api: Router = express.Router();

// api.get("/rates", getCarrierRates);
// api.post("/rates/create", createCarrierRates);

// export default api;
// const api: Router = express.Router();

// api.get("/rates", getCarrierRates);

//Get the rates given a weight
export const getCarrierRates: RequestHandler = async (req, res) => {
  const { weight } = req.query;
  const { to } = req.query;
  if (!weight) {
    res.status(400).send("Missing weight");
    return;
  }
  const weightNumber = parseFloat(weight as string);
  if (isNaN(weightNumber)) {
    res.status(400).send("Invalid weight");
    return;
  }
  const rates = await ratesModel.findOne({ weight: weightNumber });

  if (!rates) {
    res.status(404).send("No rates found");
    return;
  }

  if (!to) {
    res.status(200).send(filerRatesByType(rates, "National"));
    return;
  }

  if ((to as String).substring(0, 2) == "07") {
    res.status(200).send(filerRatesByType(rates, "Baleares"));
  } else if (
    (to as String).substring(0, 2) == "38" ||
    (to as String).substring(0, 2) == "35"
  ) {
    res.status(200).send(filerRatesByType(rates, "Canarias"));
  } else {
    res.status(200).send(filerRatesByType(rates, "National"));
  }
};

// api.post("/rates/create", createCarrierRates);

// export default api;
// const api: Router = express.Router();

// api.get("/rates", getCarrierRates);
// api.post("/rates/create", createCarrierRates);

//Create a new rate
export const createCarrierRates: RequestHandler = async (req, res) => {
  const { weight } = req.body;
  if (!weight) {
    res.status(400).send("Missing weight or price");
    return;
  }
  const weightNumber = parseFloat(weight as string);
  if (isNaN(weightNumber)) {
    res.status(400).send("Invalid weight");
    return;
  }
  const newRate = new ratesModel(req.body);
  await newRate.save();
  res.status(201).json(newRate);
};

// export default api;
const api: Router = express.Router();

api.get("/rates", getCarrierRates);
api.post("/rates/create", createCarrierRates);

export default api;

solidHelper(){

// SOLID HELPER 
// SOLID HELPER

async function getProfile(webId: string): Promise<Thing> {
  // ...
}

export async function getEmailsFromPod(webId: string) {
  // ...
}

export async function getAddressesFromPod(webId: string): Promise<Address[]> {
  // ...
}

export async function addAddressToPod(webId: string, address: Address) {
  // ...
}
// SOLID HELPER

async function getProfile(webId: string): Promise<Thing> {
  // we remove the right hand side of the # for consistency
  let profileDocumentURI = webId.split("#")[0]; 
  // obtain the dataset from the URI
  let myDataset = await getSolidDataset(profileDocumentURI);
   // we obtain the thing we are looking for from the dataset
  return getThing(myDataset, webId) as Thing;
}

export async function getEmailsFromPod(webId: string) {
  // ...
}

export async function getAddressesFromPod(webId: string): Promise<Address[]> {
  // ...
}

export async function addAddressToPod(webId: string, address: Address) {
  // ...
}

// SOLID HELPER

async function getProfile(webId: string): Promise<Thing> {
  // ...
}

export async function getEmailsFromPod(webId: string) {
  let emailURLs = getUrlAll(await getProfile(webId), VCARD.hasEmail);
  let emails: string[] = [];

  for (let emailURL of emailURLs) {
    let email = getUrl(await getProfile(emailURL), VCARD.value);
    
    // we remove the mailto: part
    if (email) emails.push(email.toString().replace("mailto:", "")); 
  }

  return emails;
}

export async function getAddressesFromPod(webId: string): Promise<Address[]> {
  // ...
}

export async function addAddressToPod(webId: string, address: Address) {
  // ...
}

// SOLID HELPER

async function getProfile(webId: string): Promise<Thing> {
  // ...
}

export async function getEmailsFromPod(webId: string) {
  // ...
}

export async function getAddressesFromPod(webId: string): Promise<Address[]> {
  let addressURLs = getUrlAll(await getProfile(webId), VCARD.hasAddress);
  let addresses: Address[] = [];

  for (let addressURL of addressURLs) {
    let address = getStringNoLocale(
      await getProfile(addressURL),
      VCARD.street_address
    );
    let locality = getStringNoLocale(
      await getProfile(addressURL),
      VCARD.locality
    ) as string;
    let region = getStringNoLocale(
      await getProfile(addressURL),
      VCARD.region
    ) as string;
    let postal_code = getStringNoLocale(
      await getProfile(addressURL),
      VCARD.postal_code
    ) as string;

    if (address)
      addresses.push({
        street: address,
        postalCode: postal_code,
        locality: locality,
        region: region,
        url: addressURL,
      });
  }

  return addresses;
}

export async function addAddressToPod(webId: string, address: Address) {
  // ...
}

// SOLID HELPER

async function getProfile(webId: string): Promise<Thing> {
  // ...
}

export async function getEmailsFromPod(webId: string) {
  // ...
}

export async function getAddressesFromPod(webId: string): Promise<Address[]> {
  // ...
}

export async function addAddressToPod(webId: string, address: Address) {
  let profileDocumentURI = webId.split("#")[0]; // we remove the right hand side of the # for consistency
  let solidDataset = await getSolidDataset(profileDocumentURI); // obtain the dataset from the URI

  // We create the address
  const newAddressThing = buildThing(createThing())
    .addStringNoLocale(VCARD.street_address, address.street)
    .addStringNoLocale(VCARD.locality, address.locality)
    .addStringNoLocale(VCARD.region, address.region)
    .addStringNoLocale(VCARD.postal_code, address.postalCode)
    .addUrl(VCARD.Type, VCARD.street_address)
    .build();

  // We have to store also the hasAddress :)
  let hasAddress = getThing(solidDataset, VCARD.hasAddress) as Thing;
  if (hasAddress === null)
    // we create the thing as it has not been done before :(
    hasAddress = buildThing(await getProfile(webId))
      .addUrl(VCARD.hasAddress, newAddressThing.url)
      .build();
  else
    hasAddress = buildThing(hasAddress)
      .addUrl(VCARD.hasAddress, newAddressThing.url)
      .build();

  solidDataset = setThing(solidDataset, newAddressThing);
  solidDataset = setThing(solidDataset, hasAddress);

  return await saveSolidDatasetAt(webId, solidDataset, { fetch: fetch });
}

// SOLID HELPER

async function getProfile(webId: string): Promise<Thing> {
  // ...
}

export async function getEmailsFromPod(webId: string) {
  // ...
}

export async function getAddressesFromPod(webId: string): Promise<Address[]> {
  // ...
}

export async function addAddressToPod(webId: string, address: Address) {
  // ...
}

restAPI(){

// Product Schema 

const mongoose = require("mongoose");
const { model, Schema } = mongoose;

export const product = new Schema(
  {
    code: {
      type: String,
      required: true,
      trim: true,
      unique: true,
    },
    name: {
      type: String,
      required: true,
      trim: true,
    },
    description: {
      type: String,
      trim: true,
    },
    price: {
      type: Number,
      required: true,
      trim: true,
    },
    stock: {
      type: Number,
      required: true,
      trim: true,
    },
    image: {
      type: String,
      required: false,
    },
    category: {
      type: String,
      required: true,
      enum: ["Clothes", "Decoration", "Electronics", "Miscellaneous"],
    },
    weight: {
      type: Number,
      required: true,
    },
  },
  {
    versionKey: false,
    timestamps: true,
  }
);

export const productModel = model("Product", product);
// Order Controller

export const getOrder: RequestHandler = async (req, res) => {
  // ...
};

export const getOrdersForAdminOrModerator: RequestHandler = async (req, res) => {
  // ...
};

export const getOrdersForUser: RequestHandler = async (req, res) => {
  // ...
};

export const createOrder: RequestHandler = async (req, res) => {
  // ...
};
// Order Controller

export const getOrder: RequestHandler = async (req, res) => {
  const webId = req.headers.token + "";
  if (await verifyWebID(webId)) {
    const orderFound = await orderModel.findOne({
      code: req.params.code,
    });
    if (orderFound) {
      if (webId === orderFound.webId) {
        return res.json(orderFound);
      } else {
        return res.status(409).json();
      }
    } else {
      return res.status(412).json();
    }
  } else {
    return res.status(403).json();
  }
};

export const getOrdersForAdminOrModerator: RequestHandler = async (req, res) => {
  // ...
};

export const getOrdersForUser: RequestHandler = async (req, res) => {
  // ...
};

export const createOrder: RequestHandler = async (req, res) => {
  // ...
};
// Order Controller

export const getOrder: RequestHandler = async (req, res) => {
  // ...
};

export const getOrdersForAdminOrModerator: RequestHandler = async (req, res) => {
  const webId = req.headers.token + "";
  const user = await userModel.findOne({ webId: webId });
  const isVerified = await verifyWebID(webId);
  if (isVerified && (user.role === "admin" || user.role === "manager")) {
    const ordersFound = await orderModel.find({});
    return res.json(ordersFound);
  } else return res.status(403).json();
};

export const getOrdersForUser: RequestHandler = async (req, res) => {
  // ...
};

export const createOrder: RequestHandler = async (req, res) => {
  // ...
};
// Order Controller

export const getOrder: RequestHandler = async (req, res) => {
  // ...
};

export const getOrdersForAdminOrModerator: RequestHandler = async (req, res) => {
  // ...
};

export const getOrdersForUser: RequestHandler = async (req, res) => {
  const webId = req.headers.token + "";
  const isVerified = await verifyWebID(webId);
  if (isVerified) {
    const ordersFound = await orderModel.find({
      webId: webId,
    });
    return res.json(ordersFound);
  } else return res.status(403).json();
};

export const createOrder: RequestHandler = async (req, res) => {
  // ...
};
// Order Controller

export const getOrder: RequestHandler = async (req, res) => {
  // ...
};

export const getOrdersForAdminOrModerator: RequestHandler = async (req, res) => {
  // ...
};

export const getOrdersForUser: RequestHandler = async (req, res) => {
  // ...
};

export const createOrder: RequestHandler = async (req, res) => {
  const updateStock = async (products: any) => {
    for (var i = 0; i < products.length; i++) {
      let product = await productModel.findOne({ code: products[i].code });
      product.stock = product.stock - products[i].stock;
      product.save();
    }
  };

  if (await verifyWebID(req.headers.token + ""))
    try {
      const order = new orderModel(req.body);
      updateStock(order.products);
      const orderSaved = await order.save();
      res.json(orderSaved);
    } catch (error) {
      res.status(412).json();
    }
  else res.status(403).json();
};
// Order Controller

export const getOrder: RequestHandler = async (req, res) => {
  // ...
};

export const getOrdersForAdminOrModerator: RequestHandler = async (req, res) => {
  // ...
};

export const getOrdersForUser: RequestHandler = async (req, res) => {
  // ...
};

export const createOrder: RequestHandler = async (req, res) => {
  // ...
};

Test{

// How did we test the app?

restAPITesting(){

MAIN

MAIN

MAIN

TEST

MAIN

webappTesting(){

// Product Box tests

test("A product is rendered", async () => {
  // ...
});

test("A product is added to the cart", async () => {
  // ...
});

test("URL to product details works", async () => {
   // ...
});
// Product Box tests

test("A product is rendered", async () => {
  const product: Product = {
    code: "9999",
    name: "Producto Prueba 1",
    description: "Descripcion Prueba 1",
    price: 10,
    stock: 20,
    image: "9999.png",
    category: "Electronics",
    weight: 1,
  };

  const { getByText, container } = render(
    <Router>
      <ProductBox product={product} currentCartAmount={0} onAdd={() => {}} />
    </Router>
  );

  expect(getByText(product.name)).toBeInTheDocument();
  expect(getByText(product.price + "€")).toBeInTheDocument();
  expect(getByText(product.description)).toBeInTheDocument();

  //Check that the default image is rendered
  const image = container.querySelector("img") as HTMLImageElement;
  expect(image.src).toContain("http://localhost:5000/9999.png");

  //Check that the info about stock is rendered correctly
  expect(getByText("Stock available!")).toBeInTheDocument();
});

test("A product is added to the cart", async () => {
  // ...
});

test("URL to product details works", async () => {
  // ...
});
// Product Box tests

test("A product is rendered", async () => {
  // ...
});

test("A product is added to the cart", async () => {
  const product: Product = {
    code: "9999",
    name: "Producto Prueba 1",
    description: "Descripcion Prueba 1",
    price: 10,
    stock: 20,
    image: "",
    category: "Electronics",
    weight: 1,
  };
  const cart: CartItem[] = [];

  const { getByText } = render(
    <Router>
      <ProductBox
        product={product}
        currentCartAmount={0}
        onAdd={() => {
          cart.push({ product: product, amount: 1 });
        }}
      />
    </Router>
  );

  const addButton = getByText("Add product");
  fireEvent.click(addButton);
  expect(cart.length).toEqual(1);
});

test("URL to product details works", async () => {
  // ...
});
// Product Box tests

test("A product is rendered", async () => {
  // ...
});

test("A product is added to the cart", async () => {
  // ...
});

test("URL to product details works", async () => {
  const product: Product = {
    code: "9999",
    name: "Producto Prueba 1",
    description: "Descripcion Prueba 1",
    price: 10,
    stock: 20,
    image: "",
    category: "Electronics",
    weight: 1,
  };
  const cart: CartItem[] = [];

  const { container } = render(
    <Router>
      <ProductBox product={product} currentCartAmount={0} onAdd={() => {}} />
    </Router>
  );

  const hrefDetails = container.querySelector("img") as HTMLElement;

  fireEvent.click(hrefDetails);
  expect(window.location.pathname).toEqual("/product/" + product.code);
});
// Product Box tests

test("A product is rendered", async () => {
  // ...
});

test("A product is added to the cart", async () => {
  // ...
});

test("URL to product details works", async () => {
   // ...
});

integration(){

TEST

loadTesting(){

coverage(){

Deployment{

// How did we deploy the code?

tools(){

process(){

TheShop{

// Main features of the shop?

darkMode(){

signIn(){

shopping(){

review(){

checkout(){

Made with Slides.com