diff --git a/.github/workflows/prettier.yml b/.github/workflows/prettier.yml
deleted file mode 100644
index 8003d23..0000000
--- a/.github/workflows/prettier.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-name: Prettier
-
-on:
- pull_request:
- branches:
- - main
-
- # Allows you to run this workflow manually from the Actions tab
- workflow_dispatch:
-
-jobs:
- # Single deploy job since we're just deploying
- test:
- runs-on: ubuntu-latest
- steps:
- - name: Install apt updates
- run: sudo apt -y update; sudo apt -y upgrade;
- - name: Install prerequisites
- uses: actions/setup-node@v3
- with:
- node-version: 18
- - name: Checkout
- uses: actions/checkout@v3
- - name: Install dependencies
- run: sudo npm install
- - name: Start local http server
- run: sudo npm run http-server &
- - name: Run tests
- run: sudo npm lint-prettier
\ No newline at end of file
diff --git a/admin/cipipeline/phase2.drawio.png b/admin/cipipeline/phase2.drawio.png
new file mode 100644
index 0000000..625f966
Binary files /dev/null and b/admin/cipipeline/phase2.drawio.png differ
diff --git a/admin/cipipeline/phase2.md b/admin/cipipeline/phase2.md
new file mode 100644
index 0000000..5075e7c
--- /dev/null
+++ b/admin/cipipeline/phase2.md
@@ -0,0 +1,47 @@
+# CI/CD Phase 2
+
+## Overall Pipeline Architecture
+
+Rather than create one large pipeline with many steps which increases complexity, we decided to create many small independent pipelines which work in parallel to conduct code quality checking. Using this strategy, if any one pipeline has issues, we can still continue development without delay, and the quality of code is likely to remain high.
+
+## Overview of Pipeline Features
+
+We've identified 5 major features which we definitely want to implement in the CI/CD pipeline.
+
+- Deployment
+- Unit Testing
+- Linting
+- End To End Validation
+- Manual Validation
+
+We also identified some features which are nice to have:
+- Automatic documentation publishing
+- Minification
+- HTML Validation and accessibility scoring
+
+We created this diagram to demonstrate our strategy of multiple simple pipelines.
+
+![Pipeline Diagram](phase2.drawio.png)
+
+## Finished Features and Implementation
+
+So far the features listed below have been completed to some degree:
+
+- Deployment
+ - Implemented: action triggered on any push to main, uses the github pages action to publish the app
+ - Implemented: uses JSDoc to generate documentation on the same site at [docs](https://cse110-fa22-group29.github.io/cse110-fa22-group29/docs/)
+ - ToDo: Add minification step between trigger and github pages action
+- Unit Testing
+ - Implemented: action triggers on PR to main, uses mocha to perform unit testing on core components
+- End to end testing
+ - Implemented: action triggers on PR to main, uses mocha and puppeteer to perform end to end testing
+- Linting (JS)
+ - Implemented: action triggers on PR to main, uses eslint to perform style enforcement on all JS components
+- Linting (HTML)
+ - Implemented: action triggers on PR to main, uses HTMLhint to perform style enforcement on all HTML components
+- Linting (CSS)
+ - Implemented: action triggers on PR to main, uses Stylelint to perform style enforcement on all CSS components
+- Linting (general)
+ - Implemented: action triggers on PR to main, uses Prettier to perform style checking on all file types
+
+## Planned Features and Timeline
diff --git a/admin/cipipeline/phase2.mp4 b/admin/cipipeline/phase2.mp4
new file mode 100644
index 0000000..2387d61
Binary files /dev/null and b/admin/cipipeline/phase2.mp4 differ
diff --git a/admin/meetings/112922-Sprint3Opener.md b/admin/meetings/112922-Sprint3Opener.md
new file mode 100644
index 0000000..dde1ac3
--- /dev/null
+++ b/admin/meetings/112922-Sprint3Opener.md
@@ -0,0 +1,35 @@
+# Meeting Minutes (11/29/2022)
+## Team 29: Hackers1995
+## Meeting Topic: Sprint 3 Debut Meeting
+
+## Attendance
+1. Rhea Bhutada
+2. George Dubinin
+3. Gavyn Ezell
+4. Henry Feng
+5. Kara Hoagland
+6. Marc Reta (remote)
+7. Sanjit Joseph
+8. Daniel Hernandez
+9. Arthur Lu (remote)
+
+## Meeting Details
+- When: 11/29/2022 at 5:00PM
+- Where: Design and Innovation Building
+
+## Agenda:
+- ### Old/Unresolved Business
+ - Resolve pretty print linting PR
+ - Resolve documentation not being merged to main PR
+- ### New Business
+ - Create ADR for image storage
+ - Review sorting defaults (recent or top rated)
+ - Adding lists of reviewIDs corresponding to reviews which share specific star ratings
+ - Create function for retrieving top 20 reviews organized by decreasing star ratings
+ - Implement search for for flitering tags
+ - Frontend checked out new branch for alternate home page designs
+- ### Next Meeting's Business
+ - Creation of team status video
+
+## End Time
+- 11/20/2022 at 3:00PM
\ No newline at end of file
diff --git a/admin/meetings/113022-Sprint3Cont.md b/admin/meetings/113022-Sprint3Cont.md
new file mode 100644
index 0000000..5689e85
--- /dev/null
+++ b/admin/meetings/113022-Sprint3Cont.md
@@ -0,0 +1,30 @@
+# Meeting Minutes (11/30/2022)
+## Team 29: Hackers1995
+## Meeting Topic: Sprint 3 Continued
+
+## Attendance
+1. Rhea Bhutada
+2. George Dubinin
+4. Henry Feng
+5. Kara Hoagland
+7. Sanjit Joseph
+9. Arthur Lu
+
+## Meeting Details
+- When: 11/30/2022 at 2:00PM
+- Where: Design and Innovation Building
+
+## Agenda:
+- ### Old/Unresolved Business
+ - Fix empty page for no-tag search
+ - Catch testing up with what we implemented yesterday
+- ### New Business
+ - Cache the site for local first (high priority)
+ - Implement editing form "in place" (optional for this sprint)
+ - Change icon for "add review" entry
+ - Overcoming UI test challenges
+- ### Next Meeting's Business
+ - Creation of team status video
+
+## End Time
+- 11/30/2022 at 2:00PM
\ No newline at end of file
diff --git a/admin/meetings/1212022-check10.md b/admin/meetings/1212022-check10.md
new file mode 100644
index 0000000..80a9937
--- /dev/null
+++ b/admin/meetings/1212022-check10.md
@@ -0,0 +1,22 @@
+# Meeting Minutes (12/1/2022)
+## Team 29: Hackers1995
+## Meeting Topic: Weekly TA Catchup with Gagan
+We are meeting with Gagan to discuss status video and general updates on project.
+
+## Attendance
+1. Rhea Bhutada
+2. George Dubinin
+3. Gagan Gopalaiah
+
+## Meeting Details
+- When: 12/1/2022 at 12:00PM
+- Where: Zoom
+
+## Discussion Points by Gagan
+- Don't code up anything after Sunday. Reserve the time for bug fixes
+- Final Interview is a 4-5 minute interview about general course specific topics
+- Live demo of the app for Gagan
+- Gagan asks us to evaluate instructional assistants
+
+## End Time
+- 12/1/2022 at 12:20PM
\ No newline at end of file
diff --git a/package.json b/package.json
index 66b994d..13fd016 100644
--- a/package.json
+++ b/package.json
@@ -24,4 +24,4 @@
"stylelint": "14.14.1",
"stylelint-config-standard": "^29.0.0"
}
-}
+}
\ No newline at end of file
diff --git a/source/ReviewDetails.html b/source/ReviewDetails.html
index d58bf69..ed1323e 100644
--- a/source/ReviewDetails.html
+++ b/source/ReviewDetails.html
@@ -7,7 +7,7 @@
Food Journal
-
+
diff --git a/source/assets/images/Grouppink.png b/source/assets/images/Grouppink.png
deleted file mode 100644
index d4f1d14..0000000
Binary files a/source/assets/images/Grouppink.png and /dev/null differ
diff --git a/source/assets/images/create_button.png b/source/assets/images/create_button.png
new file mode 100644
index 0000000..3a96529
Binary files /dev/null and b/source/assets/images/create_button.png differ
diff --git a/source/assets/images/plate_with_chopsticks.png b/source/assets/images/plate_with_chopsticks.png
deleted file mode 100644
index 023e43e..0000000
Binary files a/source/assets/images/plate_with_chopsticks.png and /dev/null differ
diff --git a/source/assets/images/plate_with_cutlery.png b/source/assets/images/plate_with_cutlery.png
deleted file mode 100644
index 6f7a938..0000000
Binary files a/source/assets/images/plate_with_cutlery.png and /dev/null differ
diff --git a/source/assets/images/search_button.png b/source/assets/images/search_button.png
new file mode 100644
index 0000000..66a1a85
Binary files /dev/null and b/source/assets/images/search_button.png differ
diff --git a/source/assets/scripts/CreatePage.js b/source/assets/scripts/CreatePage.js
index 526a766..83bb776 100644
--- a/source/assets/scripts/CreatePage.js
+++ b/source/assets/scripts/CreatePage.js
@@ -159,10 +159,10 @@ function initFormHandler() {
let tagLabel = document.createElement("label");
tagLabel.innerHTML = tagField.value;
tagLabel.setAttribute("class","tag");
- tagSet.add(tagField.value.toLowerCase());
+ tagSet.add(tagSetVal);
tagLabel.addEventListener("click",()=> {
tagContainer.removeChild(tagLabel);
- tagSet.delete(tagField.value.toLowerCase());
+ tagSet.delete(tagSetVal);
});
tagContainer.append(tagLabel);
diff --git a/source/assets/scripts/ReviewCard.js b/source/assets/scripts/ReviewCard.js
index ad339bc..91a7a70 100644
--- a/source/assets/scripts/ReviewCard.js
+++ b/source/assets/scripts/ReviewCard.js
@@ -17,6 +17,7 @@ class ReviewCard extends HTMLElement {
margin: 0;
padding: 0;
overflow-wrap: anywhere;
+ cursor: pointer;
}
a {
@@ -149,7 +150,7 @@ class ReviewCard extends HTMLElement {
// Image setup
let mealImg = document.createElement("img");
- mealImg.setAttribute("id", "a-mealImg");
+ mealImg.setAttribute("id", "a-meal-img");
mealImg.setAttribute("alt","Meal Photo Corrupted");
mealImg.setAttribute("src",data["mealImg"]);
mealImg.addEventListener("error", function(e) {
@@ -157,11 +158,11 @@ class ReviewCard extends HTMLElement {
e.onerror = null;
});
- //meal name setup
+ // Meal name setup
let meallabelDiv = document.createElement("div");
meallabelDiv.setAttribute("class", "meal-name-div");
let mealLabel = document.createElement("label");
- mealLabel.setAttribute("id", "a-mealName");
+ mealLabel.setAttribute("id", "a-meal-name");
mealLabel.setAttribute("class","meal-name");
mealLabel.innerHTML = data["mealName"];
meallabelDiv.append(mealLabel);
@@ -188,7 +189,7 @@ class ReviewCard extends HTMLElement {
starsImg.setAttribute("num", data["rating"]);
ratingDiv.append(starsImg);
- //added tags
+ // Tags setup
let tagContainerDiv = document.createElement("div");
tagContainerDiv.setAttribute("class", "tag-container-div");
let tagContainer = document.createElement("div");
@@ -244,12 +245,12 @@ class ReviewCard extends HTMLElement {
// Getting the article elements for the review card
dataContainer["reviewID"] = this.reviewID;
- // Get image
- let mealImg = this.shadowEl.getElementById("a-mealImg");
+ //get image
+ let mealImg = this.shadowEl.getElementById("a-meal-img");
dataContainer["mealImg"] = mealImg.getAttribute("src");
- // Get meal name
- let mealLabel = this.shadowEl.getElementById("a-mealName");
+ //get meal name
+ let mealLabel = this.shadowEl.getElementById("a-meal-name");
dataContainer["mealName"] = mealLabel.innerHTML;
// Get comment section
diff --git a/source/assets/scripts/ReviewDetails.js b/source/assets/scripts/ReviewDetails.js
index 5c056c1..ceaea94 100644
--- a/source/assets/scripts/ReviewDetails.js
+++ b/source/assets/scripts/ReviewDetails.js
@@ -58,7 +58,7 @@ function setupInfo(){
}
/**
- * Sets up delete button to delete review from storage and switch to homepage
+ * Sets up delete button to delete reveiw from storage and switch to homepage.
*/
function setupDelete(){
let deleteBtn = document.getElementById("delete-btn");
@@ -73,7 +73,7 @@ function setupDelete(){
}
/**
- * Sets up update button to reveal form and update info in storage and the current page
+ * Sets up update button to reveal form and update info in storage and the current page.
*/
function setupUpdate(){
let updateBtn = document.getElementById("update-btn");
@@ -102,8 +102,10 @@ function setupUpdate(){
while (tagContainer.firstChild) {
tagContainer.removeChild(tagContainer.firstChild);
}
+
+ let tagSetVal;
for (let i = 0; i < currReview["tags"].length; i++) {
- let tagSetVal = currReview["tags"][i].toLowerCase()
+ tagSetVal = currReview["tags"][i].toLowerCase();
tagSet.add(tagSetVal);
let newTag = document.createElement("label");
newTag.setAttribute("class","tag");
@@ -242,7 +244,7 @@ function setupUpdate(){
});
- //adding tag to form functionality
+ // Adding tag to form functionality
let tagAddBtn = document.getElementById("tag-add-btn");
tagAddBtn.addEventListener("click", ()=> {
let tagField = document.getElementById("tag-form");
diff --git a/source/assets/scripts/appTestHelpers.js b/source/assets/scripts/appTestHelpers.js
index 37e7cb4..aa4b1db 100644
--- a/source/assets/scripts/appTestHelpers.js
+++ b/source/assets/scripts/appTestHelpers.js
@@ -40,13 +40,13 @@ export async function setReviewForm(page, review) {
*/
export async function checkCorrectness(root, prefix, expected){
// Get the review image and check src
- let img = await root.$(`#${prefix}-mealImg`);
+ let img = await root.$(`#${prefix}-meal-img`);
let imgSrc = await img.getProperty("src");
// Check src
assert.strictEqual(await imgSrc.jsonValue(), expected.imgSrc);
// Get the title, comment, and restaurant
- let title = await root.$(`#${prefix}-mealName`);
+ let title = await root.$(`#${prefix}-meal-name`);
let title_text = await title.getProperty("innerText");
let comment = await root.$(`#${prefix}-comments`);
let comment_text = await comment.getProperty("innerText");
diff --git a/source/assets/scripts/localStorage.js b/source/assets/scripts/localStorage.js
index d0278e3..093e711 100644
--- a/source/assets/scripts/localStorage.js
+++ b/source/assets/scripts/localStorage.js
@@ -13,6 +13,14 @@ export function newReviewToStorage(review){
// adding to the tag keys
addTagsToStorage(nextReviewId, review["tags"]);
+
+ //adding to the star storage
+ let starArr = JSON.parse(localStorage.getItem(`star${review["rating"]}`));
+ if(!starArr){
+ starArr = [];
+ }
+ starArr.push(nextReviewId);
+ localStorage.setItem(`star${review["rating"]}`, JSON.stringify(starArr));
//updating our activeIDS list
let tempIdArr = JSON.parse(localStorage.getItem("activeIDS"));
@@ -41,6 +49,70 @@ export function getReviewFromStorage(ID){
*/
export function updateReviewToStorage(ID, review){
let oldReview = JSON.parse(localStorage.getItem(`review${ID}`));
+ let starArr = JSON.parse(localStorage.getItem(`star${review["rating"]}`));
+
+ //activeID update recency
+ let activeIDS = JSON.parse(localStorage.getItem("activeIDS"));
+ for (let i in activeIDS){
+ if(activeIDS[i] == ID){
+ activeIDS.splice(i,1);
+ activeIDS.push(ID);
+ break;
+ }
+ }
+ localStorage.setItem("activeIDS", JSON.stringify(activeIDS));
+
+ //star local storage update
+ if(oldReview["rating"] !== review["rating"]){
+ //first delete from previous rating array in storage
+ let oldStarArr = JSON.parse(localStorage.getItem(`star${oldReview["rating"]}`));
+ for (let i in oldStarArr) {
+ if (oldStarArr[i] == ID) {
+ //removing from corresponding rating array and updating local Storage
+ oldStarArr.splice(i,1);
+ break;
+ }
+ }
+ if(oldStarArr.length != 0){
+ localStorage.setItem(`star${oldReview["rating"]}`, JSON.stringify(oldStarArr));
+ } else {
+ localStorage.removeItem(`star${oldReview["rating"]}`);
+ }
+ //then add ID to array corresponding to new review rating
+ let newStarArr = starArr;
+ if(!newStarArr){
+ newStarArr = [];
+ }
+ newStarArr.push(ID);
+ localStorage.setItem(`star${review["rating"]}`, JSON.stringify(newStarArr));
+ } else if(starArr.length !== 1) {
+ //stars update recency if unchanged
+ for (let i in starArr){
+ if(starArr[i] == ID) {
+ starArr.splice(i,1);
+ starArr.push(ID);
+ break;
+ }
+ }
+ localStorage.setItem(`star${review["rating"]}`, JSON.stringify(starArr));
+ }
+
+ //specifically the unchanged tags update recency
+ let repeatedTags = review["tags"].filter(x => oldReview["tags"].includes(x));
+ let tagArr = [];
+ for (let i in repeatedTags){
+ tagArr = JSON.parse(localStorage.getItem(`!${repeatedTags[i]}`));
+ if(tagArr.length == 1){
+ for (let j in tagArr){
+ if(tagArr[j] == ID){
+ tagArr.splice(j,1);
+ tagArr.push(ID);
+ break;
+ }
+ }
+ localStorage.setItem(`!${repeatedTags[i]}`, JSON.stringify(tagArr));
+ }
+ }
//Get diff of tags and update storage
let deletedTags = oldReview["tags"].filter(x => !review["tags"].includes(x));
@@ -57,12 +129,29 @@ export function updateReviewToStorage(ID, review){
* @param {string} ID of the review to delete
*/
export function deleteReviewFromStorage(ID){
+ //removing id number from activeIDS and star{rating}
let activeIDS = JSON.parse(localStorage.getItem("activeIDS"));
-
+ let reviewRating = JSON.parse(localStorage.getItem(`review${ID}`))["rating"];
+ let starArr = JSON.parse(localStorage.getItem(`star${reviewRating}`));
+
+ for (let i in starArr) {
+ if (starArr[i] == ID) {
+ //removing from corresponding rating array and updating local Storage
+ starArr.splice(i,1);
+ break;
+ }
+ }
+ if(starArr.length != 0){
+ localStorage.setItem(`star${reviewRating}`, JSON.stringify(starArr));
+ } else {
+ localStorage.removeItem(`star${reviewRating}`);
+ }
+
for (let i in activeIDS) {
if (activeIDS[i] == ID) {
activeIDS.splice(i,1);
localStorage.setItem("activeIDS", JSON.stringify(activeIDS));
+
let currReview = JSON.parse(localStorage.getItem(`review${ID}`));
deleteTagsFromStorage(ID, currReview["tags"]);
localStorage.removeItem(`review${ID}`);
@@ -115,24 +204,9 @@ function addTagsToStorage(ID, addedTags) {
}
/**
- * Returns the top n reviews by ID. If there are less than n reviews, returns the most possible.
- * @param {number} n number of reviews to return
- * @returns {Object} list of n reviews that are the top rated
+ * Test Helper Function to get all reviews from local storage
+ * @returns {Object} all active reviews from local storage
*/
-export function getTopReviewsFromStorage(n) {
-
-}
-
-/**
- * Returns all reviews which contain the same tag specified.
- * @param {string} tag to filter by
- * @returns {Object} list of reviews that all contain the specified tag
- */
-export function getReviewsByTag(tag) {
-
-}
-
-// legacy function
export function getAllReviewsFromStorage() {
if (!(localStorage.getItem("activeIDS"))) {
// we wanna init the active ID array and start the nextID count
@@ -147,4 +221,47 @@ export function getAllReviewsFromStorage() {
reviews.push(currReview);
}
return reviews;
+}
+
+/**
+ * Get all IDs of active reviews (order: most recent)
+ * @returns {number[]} list of all active IDs by recency
+ */
+export function getIDsFromStorage() {
+ if (!(localStorage.getItem("activeIDS"))) {
+ // we wanna init the active ID array and start the nextID count
+ localStorage.setItem("activeIDS", JSON.stringify([]));
+ localStorage.setItem("nextID", JSON.stringify(0));
+ }
+ let activeIDS = JSON.parse(localStorage.getItem("activeIDS"));
+ return activeIDS.reverse();
+}
+
+/**
+ * Returns all review IDs which contain the same tag specified (order: most recent)
+ * @param {string} tag to filter by
+ * @returns {number[]} list of IDs of reviews that all contain the specified tag by recency
+ */
+export function getIDsByTag(tag) {
+ let tagArr = JSON.parse(localStorage.getItem("!" + tag.toLowerCase()));
+ if(!tagArr){
+ tagArr = [];
+ }
+ return tagArr.reverse();
+}
+
+/**
+ * Returns the top rated review IDs in order.
+ * @returns {number[]} list of IDs of reviews in order of top rating (most recent if equal rating)
+ */
+export function getTopIDsFromStorage() {
+ let resultArr = [];
+ for(let i = 5; i > 0; i--){
+ let starArr = JSON.parse(localStorage.getItem(`star${i}`));
+ if(!starArr){
+ continue;
+ }
+ resultArr = resultArr.concat(starArr.reverse());
+ }
+ return resultArr;
}
\ No newline at end of file
diff --git a/source/assets/scripts/localStorage.test.js b/source/assets/scripts/localStorage.test.js
index 3330ba0..a365c59 100644
--- a/source/assets/scripts/localStorage.test.js
+++ b/source/assets/scripts/localStorage.test.js
@@ -1,6 +1,6 @@
import {strict as assert} from "node:assert";
import {describe, it, before, after} from "mocha";
-import {newReviewToStorage, getReviewFromStorage, updateReviewToStorage, deleteReviewFromStorage, getAllReviewsFromStorage, getTopReviewsFromStorage, getReviewsByTag} from "./localStorage.js";
+import {newReviewToStorage, getReviewFromStorage, updateReviewToStorage, deleteReviewFromStorage, getAllReviewsFromStorage, getIDsByTag, getTopIDsFromStorage} from "./localStorage.js";
describe("test CRUD localStorage interaction", () => {
@@ -58,26 +58,27 @@ describe("test CRUD localStorage interaction", () => {
}).timeout(5000);
it("test localStorage state during updating 1000 reviews", () => {
- let reviews = getAllReviewsFromStorage();
- let ids = JSON.parse(localStorage.getItem("activeIDS"));
-
for(let i = 0; i < 1000; i++){
+ let old_review = getReviewFromStorage(i);
+ let id = old_review.reviewID;
+
let new_review = {
- "imgSrc": `updated sample src ${i}`,
- "mealName": `updated sample name ${i}`,
- "restaurant": `updated sample restaurant ${i}`,
- "rating": i*2+i,
- "tags": [`tag ${3*i}`, `tag ${3*i + 1}`, `tag ${3*i + 2}`]
+ "imgSrc": `updated sample src ${id}`,
+ "mealName": `updated sample name ${id}`,
+ "restaurant": `updated sample restaurant ${id}`,
+ "reviewID": id,
+ "rating": (id % 5) + 1,
+ "tags": [`tag ${3*id}`, `tag ${3*id + 1}`, `tag ${3*id + 2}`]
};
- new_review.reviewID = i;
- reviews[i] = new_review;
+ updateReviewToStorage(id, new_review);
- updateReviewToStorage(i, new_review);
+ let all_reviews = getAllReviewsFromStorage();
+ let active_ids = JSON.parse(localStorage.getItem("activeIDS"));
- assert.deepEqual(getAllReviewsFromStorage(), reviews);
+ assert.deepEqual(all_reviews[999], new_review);
+ assert.strictEqual(active_ids[999], id);
assert.deepEqual(getReviewFromStorage(i), new_review);
- assert.deepEqual(JSON.parse(localStorage.getItem("activeIDS")), ids);
assert.strictEqual(JSON.parse(localStorage.getItem("nextID")), 1000);
}
}).timeout(5000);
@@ -108,6 +109,7 @@ describe("test sort/filter localStorage interaction", () => {
before(() => {
localStorage.clear();
+ getAllReviewsFromStorage();
});
it("add sample data for sort and filter", () => {
@@ -116,7 +118,7 @@ describe("test sort/filter localStorage interaction", () => {
"imgSrc": `sample src ${i}`,
"mealName": `sample name ${i}`,
"restaurant": `sample restaurant ${i}`,
- "rating": i,
+ "rating": (i % 5) + 1,
"tags": [`tag ${i%3}`, `tag ${i < 50}`, "tag x"]
};
@@ -124,134 +126,145 @@ describe("test sort/filter localStorage interaction", () => {
}
});
- it("test getTopReviewsFromStorage end behavior after create", () =>{
- for(let i = 0; i <= 100; i++){
- let top_reviews = getTopReviewsFromStorage(i);
- for(let j = 0; j < i; j++){
- assert.strictEqual(top_reviews[j].rating, 99 - j);
- assert.strictEqual(top_reviews[j].reviewID, 99 - j);
- }
+ it("test getTopIDsFromStorage end behavior after create", () =>{
+ let top_reviews = getTopIDsFromStorage();
+ let prev = Infinity;
+ for(let i = 0; i < top_reviews.length; i++){
+ let review = getReviewFromStorage(top_reviews[i]);
+ assert.strictEqual(review.rating <= prev, true);
}
});
- it("test getReviewsByTag end behavior after create", () => {
+ it("test getIDsByTag end behavior after create", () => {
let specific_tagged_reviews = [];
- specific_tagged_reviews = getReviewsByTag("tag 0");
+ specific_tagged_reviews = getIDsByTag("tag 0");
assert.strictEqual(specific_tagged_reviews.length, 34);
for(let i = 0; i < specific_tagged_reviews.length; i++){
- assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 0"), true);
- assert.strictEqual(specific_tagged_reviews[i].reviewID % 3, 0);
+ let review = getReviewFromStorage(specific_tagged_reviews[i]);
+ assert.strictEqual(review.tags.includes("tag 0"), true);
+ assert.strictEqual(review.reviewID % 3, 0);
}
- specific_tagged_reviews = getReviewsByTag("tag 1");
+ specific_tagged_reviews = getIDsByTag("tag 1");
assert.strictEqual(specific_tagged_reviews.length, 33);
for(let i = 0; i < specific_tagged_reviews.length; i++){
- assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 1"), true);
- assert.strictEqual(specific_tagged_reviews[i].reviewID % 3, 1);
+ let review = getReviewFromStorage(specific_tagged_reviews[i]);
+ assert.strictEqual(review.tags.includes("tag 1"), true);
+ assert.strictEqual(review.reviewID % 3, 1);
}
- specific_tagged_reviews = getReviewsByTag("tag 2");
+ specific_tagged_reviews = getIDsByTag("tag 2");
assert.strictEqual(specific_tagged_reviews.length, 33);
for(let i = 0; i < specific_tagged_reviews.length; i++){
- assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 2"), true);
- assert.strictEqual(specific_tagged_reviews[i].reviewID % 3, 2);
+ let review = getReviewFromStorage(specific_tagged_reviews[i]);
+ assert.strictEqual(review.tags.includes("tag 2"), true);
+ assert.strictEqual(review.reviewID % 3, 2);
}
- specific_tagged_reviews = getReviewsByTag("tag true");
+ specific_tagged_reviews = getIDsByTag("tag true");
assert.strictEqual(specific_tagged_reviews.length, 50);
for(let i = 0; i < specific_tagged_reviews.length; i++){
- assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag true"), true);
- assert.strictEqual(specific_tagged_reviews[i].reviewID < 50, true);
+ let review = getReviewFromStorage(specific_tagged_reviews[i]);
+ assert.strictEqual(review.tags.includes("tag true"), true);
+ assert.strictEqual(review.reviewID < 50, true);
}
- specific_tagged_reviews = getReviewsByTag("tag false");
+ specific_tagged_reviews = getIDsByTag("tag false");
assert.strictEqual(specific_tagged_reviews.length, 50);
for(let i = 0; i < specific_tagged_reviews.length; i++){
- assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag false"), true);
- assert.strictEqual(specific_tagged_reviews[i].reviewID >= 50, true);
+ let review = getReviewFromStorage(specific_tagged_reviews[i]);
+ assert.strictEqual(review.tags.includes("tag false"), true);
+ assert.strictEqual(review.reviewID >= 50, true);
}
- specific_tagged_reviews = getReviewsByTag("tag x");
+ specific_tagged_reviews = getIDsByTag("tag x");
assert.strictEqual(specific_tagged_reviews.length, 100);
- specific_tagged_reviews = getReviewsByTag("tag y");
+ specific_tagged_reviews = getIDsByTag("tag y");
assert.deepEqual(specific_tagged_reviews, []);
});
it("update sample data for sort and filter", () => {
for(let i = 0; i < 100; i++){
+ let old_review = getReviewFromStorage(i);
let new_review = {
"imgSrc": `sample src ${i}`,
"mealName": `sample name ${i}`,
"restaurant": `sample restaurant ${i}`,
- "rating": 99-i,
- "tags": [`tag ${i%4}`, `tag ${i < 37}`, "tag y"]
+ "reviewID": old_review.reviewID,
+ "rating": (i % 5) + 1,
+ "tags": [`tag ${i % 4}`, `tag ${i < 37}`, "tag y"]
};
- updateReviewToStorage(i, new_review);
+ updateReviewToStorage(old_review.reviewID, new_review);
}
});
- it("test getTopReviewsFromStorage end behavior after create", () =>{
- for(let i = 0; i <= 100; i++){
- let top_reviews = getTopReviewsFromStorage(i);
- for(let j = 0; j < i; j++){
- assert.strictEqual(top_reviews[j].rating, 99 - j);
- assert.strictEqual(top_reviews[j].reviewID, j);
- }
+ it("test getTopIDsFromStorage end behavior after create", () =>{
+ let top_reviews = getTopIDsFromStorage();
+ let prev = Infinity;
+ for(let i = 0; i < top_reviews.length; i++){
+ let review = getReviewFromStorage(top_reviews[i]);
+ assert.strictEqual(review.rating <= prev, true);
}
});
- it("test getReviewsByTag end behavior after update", () => {
+ it("test getIDsByTag end behavior after update", () => {
let specific_tagged_reviews = [];
- specific_tagged_reviews = getReviewsByTag("tag 0");
+ specific_tagged_reviews = getIDsByTag("tag 0");
assert.strictEqual(specific_tagged_reviews.length, 25);
for(let i = 0; i < specific_tagged_reviews.length; i++){
- assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 0"), true);
- assert.strictEqual(specific_tagged_reviews[i].reviewID % 4, 0);
+ let review = getReviewFromStorage(specific_tagged_reviews[i]);
+ assert.strictEqual(review.tags.includes("tag 0"), true);
+ assert.strictEqual(review.reviewID % 4, 0);
}
- specific_tagged_reviews = getReviewsByTag("tag 1");
+ specific_tagged_reviews = getIDsByTag("tag 1");
assert.strictEqual(specific_tagged_reviews.length, 25);
for(let i = 0; i < specific_tagged_reviews.length; i++){
- assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 1"), true);
- assert.strictEqual(specific_tagged_reviews[i].reviewID % 4, 1);
+ let review = getReviewFromStorage(specific_tagged_reviews[i]);
+ assert.strictEqual(review.tags.includes("tag 1"), true);
+ assert.strictEqual(review.reviewID % 4, 1);
}
- specific_tagged_reviews = getReviewsByTag("tag 2");
+ specific_tagged_reviews = getIDsByTag("tag 2");
assert.strictEqual(specific_tagged_reviews.length, 25);
for(let i = 0; i < specific_tagged_reviews.length; i++){
- assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 2"), true);
- assert.strictEqual(specific_tagged_reviews[i].reviewID % 4, 2);
+ let review = getReviewFromStorage(specific_tagged_reviews[i]);
+ assert.strictEqual(review.tags.includes("tag 2"), true);
+ assert.strictEqual(review.reviewID % 4, 2);
}
- specific_tagged_reviews = getReviewsByTag("tag 3");
+ specific_tagged_reviews = getIDsByTag("tag 3");
assert.strictEqual(specific_tagged_reviews.length, 25);
for(let i = 0; i < specific_tagged_reviews.length; i++){
- assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag 3"), true);
- assert.strictEqual(specific_tagged_reviews[i].reviewID % 4, 3);
+ let review = getReviewFromStorage(specific_tagged_reviews[i]);
+ assert.strictEqual(review.tags.includes("tag 3"), true);
+ assert.strictEqual(review.reviewID % 4, 3);
}
- specific_tagged_reviews = getReviewsByTag("tag true");
+ specific_tagged_reviews = getIDsByTag("tag true");
assert.strictEqual(specific_tagged_reviews.length, 37);
for(let i = 0; i < specific_tagged_reviews.length; i++){
- assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag true"), true);
- assert.strictEqual(specific_tagged_reviews[i].reviewID < 37, true);
+ let review = getReviewFromStorage(specific_tagged_reviews[i]);
+ assert.strictEqual(review.tags.includes("tag true"), true);
+ assert.strictEqual(review.reviewID < 37, true);
}
- specific_tagged_reviews = getReviewsByTag("tag false");
+ specific_tagged_reviews = getIDsByTag("tag false");
assert.strictEqual(specific_tagged_reviews.length, 63);
for(let i = 0; i < specific_tagged_reviews.length; i++){
- assert.strictEqual(specific_tagged_reviews[i].tags.includes("tag false"), true);
- assert.strictEqual(specific_tagged_reviews[i].reviewID >= 37, true);
+ let review = getReviewFromStorage(specific_tagged_reviews[i]);
+ assert.strictEqual(review.tags.includes("tag false"), true);
+ assert.strictEqual(review.reviewID >= 37, true);
}
- specific_tagged_reviews = getReviewsByTag("tag x");
+ specific_tagged_reviews = getIDsByTag("tag x");
assert.deepEqual(specific_tagged_reviews, []);
- specific_tagged_reviews = getReviewsByTag("tag y");
+ specific_tagged_reviews = getIDsByTag("tag y");
assert.strictEqual(specific_tagged_reviews.length, 100);
});
@@ -261,38 +274,38 @@ describe("test sort/filter localStorage interaction", () => {
}
});
- it("test getTopReviewsFromStorage end behavior after delete", () =>{
+ it("test getTopIDsFromStorage end behavior after delete", () =>{
for(let i = 0; i <= 100; i++){
- let top_reviews = getTopReviewsFromStorage(i);
+ let top_reviews = getTopIDsFromStorage(i);
assert.deepEqual(top_reviews, []);
}
});
- it("test getReviewsByTag end behavior after delete", () => {
+ it("test getIDsByTag end behavior after delete", () => {
let specific_tagged_reviews = [];
- specific_tagged_reviews = getReviewsByTag("tag 0");
+ specific_tagged_reviews = getIDsByTag("tag 0");
assert.deepEqual(specific_tagged_reviews, []);
- specific_tagged_reviews = getReviewsByTag("tag 1");
+ specific_tagged_reviews = getIDsByTag("tag 1");
assert.deepEqual(specific_tagged_reviews, []);
- specific_tagged_reviews = getReviewsByTag("tag 2");
+ specific_tagged_reviews = getIDsByTag("tag 2");
assert.deepEqual(specific_tagged_reviews, []);
- specific_tagged_reviews = getReviewsByTag("tag 3");
+ specific_tagged_reviews = getIDsByTag("tag 3");
assert.deepEqual(specific_tagged_reviews, []);
- specific_tagged_reviews = getReviewsByTag("tag true");
+ specific_tagged_reviews = getIDsByTag("tag true");
assert.deepEqual(specific_tagged_reviews, []);
- specific_tagged_reviews = getReviewsByTag("tag false");
+ specific_tagged_reviews = getIDsByTag("tag false");
assert.deepEqual(specific_tagged_reviews, []);
- specific_tagged_reviews = getReviewsByTag("tag x");
+ specific_tagged_reviews = getIDsByTag("tag x");
assert.deepEqual(specific_tagged_reviews, []);
- specific_tagged_reviews = getReviewsByTag("tag y");
+ specific_tagged_reviews = getIDsByTag("tag y");
assert.deepEqual(specific_tagged_reviews, []);
});
diff --git a/source/assets/scripts/main.js b/source/assets/scripts/main.js
index f012cb9..7f57f1b 100644
--- a/source/assets/scripts/main.js
+++ b/source/assets/scripts/main.js
@@ -1,15 +1,13 @@
// main.js
-import {getAllReviewsFromStorage} from "./localStorage.js";
+import {getIDsByTag, getIDsFromStorage, getReviewFromStorage, getTopIDsFromStorage} from "./localStorage.js";
// Run the init() function when the page has loaded
window.addEventListener("DOMContentLoaded", init);
function init() {
- // Get the reviews from localStorage
- let reviews = getAllReviewsFromStorage();
- // Add each reviews to the element
- addReviewsToDocument(reviews);
- // Add the event listeners to the form elements
+ //initial population of review container
+ sortAndFilter(false, null);
+ //Add the event listeners to dropdown and search bar
initFormHandler();
}
@@ -22,21 +20,141 @@ function addReviewsToDocument(reviews) {
reviews.forEach(review => {
let newReview = document.createElement("review-card");
newReview.data = review;
- //TODO: want to append it to whatever the box is in layout
reviewBox.append(newReview);
});
}
/**
- * Adds the necessary event handlers to