From cd3c2500039c482677709664f691eb0c4d97fa66 Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 24 Mar 2026 14:43:49 +0100 Subject: [PATCH 01/26] Added URLCharityScraper Added a web-scraper that will scrape relevant information for the charity about-us page. Currently supports scraping description String. --- .../team6/scraper/URLCharityScraper.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java new file mode 100644 index 0000000..4120dcc --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -0,0 +1,65 @@ +package ntnu.systemutvikling.team6.scraper; + +import java.time.Duration; +import java.util.List; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +public class URLCharityScraper { + ChromeOptions options; + WebDriver driver; + + public URLCharityScraper() { + this.options = new ChromeOptions(); + options.addArguments("--headless=new"); + options.addArguments("--window-size=1920,1080"); + options.addArguments("--disable-gpu"); + options.addArguments("--no-sandbox"); + options.addArguments("--disable-dev-shm-usage"); + + this.driver = new ChromeDriver(options); + } + + public boolean updateDescription() { + StringBuilder descriptionString = new StringBuilder(); + + try { + // URL for scraping approved organizations + driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); + wait.until( + ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); + + List description = driver.findElements(By.cssSelector(".information div")); + + for (WebElement element : description) { + descriptionString.append(element.getText()); + } + + // Check for if description is long and contains a "read more" link + List doesReadMoreExist = driver.findElements(By.cssSelector("a.read-more")); + + if (!doesReadMoreExist.isEmpty()) { + WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); + descReadMore.click(); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); + + List extraDescription = driver.findElements(By.cssSelector(".extra-info")); + + for (WebElement webElement : extraDescription) { + descriptionString.append(webElement.getText()); + } + } + + } finally { + driver.quit(); + } + return true; + } +} From 30a5f0e61b0f07d2898996442076a91611ad52c1 Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 24 Mar 2026 15:25:26 +0100 Subject: [PATCH 02/26] Updated URLCharityScraper Added method to get the URL of the logo. Converted WebDriverWait object to an object parameter, and initialize it in the constructor. --- .../team6/scraper/URLCharityScraper.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index 4120dcc..ba1dda9 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -13,6 +13,7 @@ public class URLCharityScraper { ChromeOptions options; WebDriver driver; + WebDriverWait wait; public URLCharityScraper() { this.options = new ChromeOptions(); @@ -23,6 +24,8 @@ public URLCharityScraper() { options.addArguments("--disable-dev-shm-usage"); this.driver = new ChromeDriver(options); + + this.wait = new WebDriverWait(driver, Duration.ofSeconds(30)); } public boolean updateDescription() { @@ -32,8 +35,7 @@ public boolean updateDescription() { // URL for scraping approved organizations driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); - wait.until( + this.wait.until( ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); List description = driver.findElements(By.cssSelector(".information div")); @@ -48,7 +50,7 @@ public boolean updateDescription() { if (!doesReadMoreExist.isEmpty()) { WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); descReadMore.click(); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); + this.wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); List extraDescription = driver.findElements(By.cssSelector(".extra-info")); @@ -62,4 +64,21 @@ public boolean updateDescription() { } return true; } + + public boolean updateLogo() { + String logoURL = ""; + + try { + driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + + this.wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); + + WebElement logo = driver.findElement(By.cssSelector(".logo > img")); + + logoURL = logo.getAttribute("src"); + } finally { + driver.close(); + } + return true; + } } From bc0cc72aac08448c0a8a1e1f9cc00cdf16cac586 Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 24 Mar 2026 15:55:30 +0100 Subject: [PATCH 03/26] Updated URLCharityScraper Changed driver and wait initialization to be for each method instead of constructor. Added a method for getting categories from charity URL. --- .../team6/scraper/URLCharityScraper.java | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index ba1dda9..173785d 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -1,6 +1,7 @@ package ntnu.systemutvikling.team6.scraper; import java.time.Duration; +import java.util.ArrayList; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; @@ -12,8 +13,6 @@ public class URLCharityScraper { ChromeOptions options; - WebDriver driver; - WebDriverWait wait; public URLCharityScraper() { this.options = new ChromeOptions(); @@ -22,20 +21,18 @@ public URLCharityScraper() { options.addArguments("--disable-gpu"); options.addArguments("--no-sandbox"); options.addArguments("--disable-dev-shm-usage"); - - this.driver = new ChromeDriver(options); - - this.wait = new WebDriverWait(driver, Duration.ofSeconds(30)); } public boolean updateDescription() { + WebDriver driver = new ChromeDriver(options); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); StringBuilder descriptionString = new StringBuilder(); try { // URL for scraping approved organizations driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); - this.wait.until( + wait.until( ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); List description = driver.findElements(By.cssSelector(".information div")); @@ -50,7 +47,7 @@ public boolean updateDescription() { if (!doesReadMoreExist.isEmpty()) { WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); descReadMore.click(); - this.wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); List extraDescription = driver.findElements(By.cssSelector(".extra-info")); @@ -66,19 +63,46 @@ public boolean updateDescription() { } public boolean updateLogo() { + WebDriver driver = new ChromeDriver(options); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); String logoURL = ""; try { driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); - this.wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); WebElement logo = driver.findElement(By.cssSelector(".logo > img")); logoURL = logo.getAttribute("src"); } finally { - driver.close(); + driver.quit(); } return true; } + + public boolean updateCategories() { + WebDriver driver = new ChromeDriver(options); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); + List categoriesList = new ArrayList<>(); + + try { + driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".tag-label"))); + + List categories = driver.findElements(By.cssSelector(".tag-label")); + + for (WebElement element : categories) { + categoriesList.add(element.getText()); + } + + } finally { + driver.quit(); + } + + System.out.println(categoriesList); + + return true; + } } From 3232a981e1825ca2e3dafe4bf7c6150dd4654ae8 Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 1 Apr 2026 13:53:57 +0200 Subject: [PATCH 04/26] Updated URLCharityScraper Added method updateKeyNumbers() that gets the value of the 3 key number values by IK for the given charity. --- .../team6/scraper/URLCharityScraper.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index 173785d..9b64342 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -105,4 +105,50 @@ public boolean updateCategories() { return true; } + + public boolean updateKeyNumbers() { + WebDriver driver = new ChromeDriver(options); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); + String percentage; + WebElement element; + + try { + driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + + wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( + "//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']"))); + + element = driver.findElement( + By.xpath("//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']") + ); + + percentage = element.getAttribute("data-percentage"); + System.out.println(percentage); + + wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( + "//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']"))); + + element = driver.findElement( + By.xpath("//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']") + ); + + percentage = element.getAttribute("data-percentage"); + System.out.println(percentage); + + wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( + "//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']"))); + + element = driver.findElement( + By.xpath("//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']") + ); + + percentage = element.getAttribute("data-percentage"); + System.out.println(percentage); + + } finally { + driver.quit(); + } + + return true; + } } From bfc92ab93cb6d52d8d31b658b4ad2ba04f59ba38 Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 1 Apr 2026 14:21:33 +0200 Subject: [PATCH 05/26] Updated URLCharityScraper Fixed updateDescription so it doesn't output some of the text twice, and it now returns the String. --- .../team6/scraper/URLCharityScraper.java | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index 9b64342..75709ec 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -23,43 +23,37 @@ public URLCharityScraper() { options.addArguments("--disable-dev-shm-usage"); } - public boolean updateDescription() { + public String updateDescription(String url) { WebDriver driver = new ChromeDriver(options); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); - StringBuilder descriptionString = new StringBuilder(); + StringBuilder descriptionString = new StringBuilder(); try { - // URL for scraping approved organizations - driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + driver.get(url); wait.until( ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); + // Check for if description is long and contains a "read more" link + List doesReadMoreExist = driver.findElements(By.cssSelector("a.read-more")); + + if (!doesReadMoreExist.isEmpty()) { + WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); + descReadMore.click(); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); + } + List description = driver.findElements(By.cssSelector(".information div")); for (WebElement element : description) { descriptionString.append(element.getText()); } - // Check for if description is long and contains a "read more" link - List doesReadMoreExist = driver.findElements(By.cssSelector("a.read-more")); - - if (!doesReadMoreExist.isEmpty()) { - WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); - descReadMore.click(); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); - - List extraDescription = driver.findElements(By.cssSelector(".extra-info")); - - for (WebElement webElement : extraDescription) { - descriptionString.append(webElement.getText()); - } - } - } finally { driver.quit(); } - return true; + + return descriptionString.toString(); } public boolean updateLogo() { From ee2aee62f879825d03c4082a4b2ddc2f574a10a9 Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 1 Apr 2026 14:40:14 +0200 Subject: [PATCH 06/26] Updated URLCharityScraper Changed methods to return their values, and made the url a object parameter. --- .../team6/scraper/URLCharityScraper.java | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index 75709ec..53aa2dc 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -13,23 +13,25 @@ public class URLCharityScraper { ChromeOptions options; + String url; - public URLCharityScraper() { + public URLCharityScraper(String url) { this.options = new ChromeOptions(); options.addArguments("--headless=new"); options.addArguments("--window-size=1920,1080"); options.addArguments("--disable-gpu"); options.addArguments("--no-sandbox"); options.addArguments("--disable-dev-shm-usage"); + this.url = url; } - public String updateDescription(String url) { + public String updateDescription() { WebDriver driver = new ChromeDriver(options); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); StringBuilder descriptionString = new StringBuilder(); try { - driver.get(url); + driver.get(this.url); wait.until( ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); @@ -56,13 +58,13 @@ public String updateDescription(String url) { return descriptionString.toString(); } - public boolean updateLogo() { + public String updateLogo() { WebDriver driver = new ChromeDriver(options); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); - String logoURL = ""; + String logoURL; try { - driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + driver.get(this.url); wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); @@ -72,16 +74,16 @@ public boolean updateLogo() { } finally { driver.quit(); } - return true; + return logoURL; } - public boolean updateCategories() { + public List updateCategories() { WebDriver driver = new ChromeDriver(options); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); List categoriesList = new ArrayList<>(); try { - driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + driver.get(this.url); wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".tag-label"))); @@ -95,19 +97,18 @@ public boolean updateCategories() { driver.quit(); } - System.out.println(categoriesList); - - return true; + return categoriesList; } - public boolean updateKeyNumbers() { + public List updateKeyNumbers() { WebDriver driver = new ChromeDriver(options); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); String percentage; WebElement element; + List keyNumbersList = new ArrayList<>(); try { - driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + driver.get(this.url); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( "//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']"))); @@ -117,7 +118,8 @@ public boolean updateKeyNumbers() { ); percentage = element.getAttribute("data-percentage"); - System.out.println(percentage); + + keyNumbersList.add(percentage); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( "//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']"))); @@ -127,7 +129,8 @@ public boolean updateKeyNumbers() { ); percentage = element.getAttribute("data-percentage"); - System.out.println(percentage); + + keyNumbersList.add(percentage); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( "//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']"))); @@ -137,12 +140,13 @@ public boolean updateKeyNumbers() { ); percentage = element.getAttribute("data-percentage"); - System.out.println(percentage); + + keyNumbersList.add(percentage); } finally { driver.quit(); } - return true; + return keyNumbersList; } } From 3cf79845bde0b5acc722321b288b9c01363bb549 Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 24 Mar 2026 14:43:49 +0100 Subject: [PATCH 07/26] Added URLCharityScraper Added a web-scraper that will scrape relevant information for the charity about-us page. Currently supports scraping description String. --- .../team6/scraper/URLCharityScraper.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java new file mode 100644 index 0000000..4120dcc --- /dev/null +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -0,0 +1,65 @@ +package ntnu.systemutvikling.team6.scraper; + +import java.time.Duration; +import java.util.List; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +public class URLCharityScraper { + ChromeOptions options; + WebDriver driver; + + public URLCharityScraper() { + this.options = new ChromeOptions(); + options.addArguments("--headless=new"); + options.addArguments("--window-size=1920,1080"); + options.addArguments("--disable-gpu"); + options.addArguments("--no-sandbox"); + options.addArguments("--disable-dev-shm-usage"); + + this.driver = new ChromeDriver(options); + } + + public boolean updateDescription() { + StringBuilder descriptionString = new StringBuilder(); + + try { + // URL for scraping approved organizations + driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); + wait.until( + ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); + + List description = driver.findElements(By.cssSelector(".information div")); + + for (WebElement element : description) { + descriptionString.append(element.getText()); + } + + // Check for if description is long and contains a "read more" link + List doesReadMoreExist = driver.findElements(By.cssSelector("a.read-more")); + + if (!doesReadMoreExist.isEmpty()) { + WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); + descReadMore.click(); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); + + List extraDescription = driver.findElements(By.cssSelector(".extra-info")); + + for (WebElement webElement : extraDescription) { + descriptionString.append(webElement.getText()); + } + } + + } finally { + driver.quit(); + } + return true; + } +} From d2f0a5489f9f28b50c9cf0adee82655212480942 Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 24 Mar 2026 15:25:26 +0100 Subject: [PATCH 08/26] Updated URLCharityScraper Added method to get the URL of the logo. Converted WebDriverWait object to an object parameter, and initialize it in the constructor. --- .../team6/scraper/URLCharityScraper.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index 4120dcc..ba1dda9 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -13,6 +13,7 @@ public class URLCharityScraper { ChromeOptions options; WebDriver driver; + WebDriverWait wait; public URLCharityScraper() { this.options = new ChromeOptions(); @@ -23,6 +24,8 @@ public URLCharityScraper() { options.addArguments("--disable-dev-shm-usage"); this.driver = new ChromeDriver(options); + + this.wait = new WebDriverWait(driver, Duration.ofSeconds(30)); } public boolean updateDescription() { @@ -32,8 +35,7 @@ public boolean updateDescription() { // URL for scraping approved organizations driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); - wait.until( + this.wait.until( ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); List description = driver.findElements(By.cssSelector(".information div")); @@ -48,7 +50,7 @@ public boolean updateDescription() { if (!doesReadMoreExist.isEmpty()) { WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); descReadMore.click(); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); + this.wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); List extraDescription = driver.findElements(By.cssSelector(".extra-info")); @@ -62,4 +64,21 @@ public boolean updateDescription() { } return true; } + + public boolean updateLogo() { + String logoURL = ""; + + try { + driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + + this.wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); + + WebElement logo = driver.findElement(By.cssSelector(".logo > img")); + + logoURL = logo.getAttribute("src"); + } finally { + driver.close(); + } + return true; + } } From 1671e1e5c3642699b4c4538618f06b727c499fe4 Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 24 Mar 2026 15:55:30 +0100 Subject: [PATCH 09/26] Updated URLCharityScraper Changed driver and wait initialization to be for each method instead of constructor. Added a method for getting categories from charity URL. --- .../team6/scraper/URLCharityScraper.java | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index ba1dda9..173785d 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -1,6 +1,7 @@ package ntnu.systemutvikling.team6.scraper; import java.time.Duration; +import java.util.ArrayList; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; @@ -12,8 +13,6 @@ public class URLCharityScraper { ChromeOptions options; - WebDriver driver; - WebDriverWait wait; public URLCharityScraper() { this.options = new ChromeOptions(); @@ -22,20 +21,18 @@ public URLCharityScraper() { options.addArguments("--disable-gpu"); options.addArguments("--no-sandbox"); options.addArguments("--disable-dev-shm-usage"); - - this.driver = new ChromeDriver(options); - - this.wait = new WebDriverWait(driver, Duration.ofSeconds(30)); } public boolean updateDescription() { + WebDriver driver = new ChromeDriver(options); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); StringBuilder descriptionString = new StringBuilder(); try { // URL for scraping approved organizations driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); - this.wait.until( + wait.until( ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); List description = driver.findElements(By.cssSelector(".information div")); @@ -50,7 +47,7 @@ public boolean updateDescription() { if (!doesReadMoreExist.isEmpty()) { WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); descReadMore.click(); - this.wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); List extraDescription = driver.findElements(By.cssSelector(".extra-info")); @@ -66,19 +63,46 @@ public boolean updateDescription() { } public boolean updateLogo() { + WebDriver driver = new ChromeDriver(options); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); String logoURL = ""; try { driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); - this.wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); WebElement logo = driver.findElement(By.cssSelector(".logo > img")); logoURL = logo.getAttribute("src"); } finally { - driver.close(); + driver.quit(); } return true; } + + public boolean updateCategories() { + WebDriver driver = new ChromeDriver(options); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); + List categoriesList = new ArrayList<>(); + + try { + driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".tag-label"))); + + List categories = driver.findElements(By.cssSelector(".tag-label")); + + for (WebElement element : categories) { + categoriesList.add(element.getText()); + } + + } finally { + driver.quit(); + } + + System.out.println(categoriesList); + + return true; + } } From 77dd08a9966266af4c029e530cc93426daed876d Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 1 Apr 2026 13:53:57 +0200 Subject: [PATCH 10/26] Updated URLCharityScraper Added method updateKeyNumbers() that gets the value of the 3 key number values by IK for the given charity. --- .../team6/scraper/URLCharityScraper.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index 173785d..9b64342 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -105,4 +105,50 @@ public boolean updateCategories() { return true; } + + public boolean updateKeyNumbers() { + WebDriver driver = new ChromeDriver(options); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); + String percentage; + WebElement element; + + try { + driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + + wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( + "//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']"))); + + element = driver.findElement( + By.xpath("//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']") + ); + + percentage = element.getAttribute("data-percentage"); + System.out.println(percentage); + + wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( + "//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']"))); + + element = driver.findElement( + By.xpath("//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']") + ); + + percentage = element.getAttribute("data-percentage"); + System.out.println(percentage); + + wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( + "//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']"))); + + element = driver.findElement( + By.xpath("//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']") + ); + + percentage = element.getAttribute("data-percentage"); + System.out.println(percentage); + + } finally { + driver.quit(); + } + + return true; + } } From 6cf3b0bba8932e1aca2bb8c9cec0bcfdc5719fbb Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 1 Apr 2026 14:21:33 +0200 Subject: [PATCH 11/26] Updated URLCharityScraper Fixed updateDescription so it doesn't output some of the text twice, and it now returns the String. --- .../team6/scraper/URLCharityScraper.java | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index 9b64342..75709ec 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -23,43 +23,37 @@ public URLCharityScraper() { options.addArguments("--disable-dev-shm-usage"); } - public boolean updateDescription() { + public String updateDescription(String url) { WebDriver driver = new ChromeDriver(options); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); - StringBuilder descriptionString = new StringBuilder(); + StringBuilder descriptionString = new StringBuilder(); try { - // URL for scraping approved organizations - driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + driver.get(url); wait.until( ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); + // Check for if description is long and contains a "read more" link + List doesReadMoreExist = driver.findElements(By.cssSelector("a.read-more")); + + if (!doesReadMoreExist.isEmpty()) { + WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); + descReadMore.click(); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); + } + List description = driver.findElements(By.cssSelector(".information div")); for (WebElement element : description) { descriptionString.append(element.getText()); } - // Check for if description is long and contains a "read more" link - List doesReadMoreExist = driver.findElements(By.cssSelector("a.read-more")); - - if (!doesReadMoreExist.isEmpty()) { - WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); - descReadMore.click(); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); - - List extraDescription = driver.findElements(By.cssSelector(".extra-info")); - - for (WebElement webElement : extraDescription) { - descriptionString.append(webElement.getText()); - } - } - } finally { driver.quit(); } - return true; + + return descriptionString.toString(); } public boolean updateLogo() { From e6efe6f71f6153a8a1337d647819c7bf84abc01b Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 1 Apr 2026 14:40:14 +0200 Subject: [PATCH 12/26] Updated URLCharityScraper Changed methods to return their values, and made the url a object parameter. --- .../team6/scraper/URLCharityScraper.java | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index 75709ec..53aa2dc 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -13,23 +13,25 @@ public class URLCharityScraper { ChromeOptions options; + String url; - public URLCharityScraper() { + public URLCharityScraper(String url) { this.options = new ChromeOptions(); options.addArguments("--headless=new"); options.addArguments("--window-size=1920,1080"); options.addArguments("--disable-gpu"); options.addArguments("--no-sandbox"); options.addArguments("--disable-dev-shm-usage"); + this.url = url; } - public String updateDescription(String url) { + public String updateDescription() { WebDriver driver = new ChromeDriver(options); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); StringBuilder descriptionString = new StringBuilder(); try { - driver.get(url); + driver.get(this.url); wait.until( ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); @@ -56,13 +58,13 @@ public String updateDescription(String url) { return descriptionString.toString(); } - public boolean updateLogo() { + public String updateLogo() { WebDriver driver = new ChromeDriver(options); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); - String logoURL = ""; + String logoURL; try { - driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + driver.get(this.url); wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); @@ -72,16 +74,16 @@ public boolean updateLogo() { } finally { driver.quit(); } - return true; + return logoURL; } - public boolean updateCategories() { + public List updateCategories() { WebDriver driver = new ChromeDriver(options); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); List categoriesList = new ArrayList<>(); try { - driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + driver.get(this.url); wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".tag-label"))); @@ -95,19 +97,18 @@ public boolean updateCategories() { driver.quit(); } - System.out.println(categoriesList); - - return true; + return categoriesList; } - public boolean updateKeyNumbers() { + public List updateKeyNumbers() { WebDriver driver = new ChromeDriver(options); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); String percentage; WebElement element; + List keyNumbersList = new ArrayList<>(); try { - driver.get("https://www.innsamlingskontrollen.no/organisasjoner/anna-ministries/"); + driver.get(this.url); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( "//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']"))); @@ -117,7 +118,8 @@ public boolean updateKeyNumbers() { ); percentage = element.getAttribute("data-percentage"); - System.out.println(percentage); + + keyNumbersList.add(percentage); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( "//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']"))); @@ -127,7 +129,8 @@ public boolean updateKeyNumbers() { ); percentage = element.getAttribute("data-percentage"); - System.out.println(percentage); + + keyNumbersList.add(percentage); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( "//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']"))); @@ -137,12 +140,13 @@ public boolean updateKeyNumbers() { ); percentage = element.getAttribute("data-percentage"); - System.out.println(percentage); + + keyNumbersList.add(percentage); } finally { driver.quit(); } - return true; + return keyNumbersList; } } From 017e820f4a5243aedbbe318b0931a2eea4886873 Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 1 Apr 2026 18:44:23 +0200 Subject: [PATCH 13/26] Updated URLCharityScraper Fixed method to get description to be more robust, and it now correctly spaces paragraphs. Made scraping methods private, and a public method to run them all. Restructured the class for easier testing with mockito. --- .../team6/scraper/URLCharityScraper.java | 202 +++++++++++------- 1 file changed, 120 insertions(+), 82 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index 53aa2dc..1aab6ae 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -2,6 +2,7 @@ import java.time.Duration; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; @@ -12,141 +13,178 @@ import org.openqa.selenium.support.ui.WebDriverWait; public class URLCharityScraper { - ChromeOptions options; - String url; + private final String url; + private final WebDriver driver; + private String description; + private String logoURL; + private final List categories; + private final List keyValues; + + // Used for production public URLCharityScraper(String url) { - this.options = new ChromeOptions(); + this.categories = new ArrayList<>(); + this.keyValues = new ArrayList<>(); + ChromeOptions options = new ChromeOptions(); options.addArguments("--headless=new"); options.addArguments("--window-size=1920,1080"); options.addArguments("--disable-gpu"); options.addArguments("--no-sandbox"); options.addArguments("--disable-dev-shm-usage"); this.url = url; + this.driver = new ChromeDriver(options); + } + + // Used for testing + public URLCharityScraper(String url, WebDriver driver) { + this.categories = new ArrayList<>(); + this.keyValues = new ArrayList<>(); + this.url = url; + this.driver = driver; + } + + private void quitDriver() { + if (driver instanceof ChromeDriver) { + driver.quit(); + } } - public String updateDescription() { - WebDriver driver = new ChromeDriver(options); - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); - StringBuilder descriptionString = new StringBuilder(); + private void updateDescription() { + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); + StringBuilder descriptionString = new StringBuilder(); - try { driver.get(this.url); wait.until( - ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); + ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); + + List firstDescription = driver.findElements(By.cssSelector(".information div p")); - // Check for if description is long and contains a "read more" link - List doesReadMoreExist = driver.findElements(By.cssSelector("a.read-more")); + for (WebElement element : firstDescription) { + if (element.getText().isBlank()) { + continue; + } + descriptionString.append(element.getText()).append("\n\n"); + } + // Check for if description is long and contains a "read more" link + List doesReadMoreExist = driver.findElements(By.cssSelector("a.read-more")); - if (!doesReadMoreExist.isEmpty()) { - WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); - descReadMore.click(); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); - } + if (!doesReadMoreExist.isEmpty()) { + WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); + descReadMore.click(); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); + } - List description = driver.findElements(By.cssSelector(".information div")); + List extraDescription = driver.findElements(By.cssSelector(".extra-info p")); - for (WebElement element : description) { - descriptionString.append(element.getText()); + for (WebElement element : extraDescription) { + if (element.getText().isBlank()) { + continue; + } + descriptionString.append(element.getText()).append("\n\n"); } - } finally { - driver.quit(); - } - return descriptionString.toString(); + this.description = descriptionString.toString(); } - public String updateLogo() { - WebDriver driver = new ChromeDriver(options); - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); - String logoURL; + private void updateLogo() { + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); - try { - driver.get(this.url); + driver.get(this.url); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); - WebElement logo = driver.findElement(By.cssSelector(".logo > img")); + WebElement logo = driver.findElement(By.cssSelector(".logo > img")); - logoURL = logo.getAttribute("src"); - } finally { - driver.quit(); - } - return logoURL; + this.logoURL = logo.getAttribute("src"); } - public List updateCategories() { - WebDriver driver = new ChromeDriver(options); + private void updateCategories() { WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); - List categoriesList = new ArrayList<>(); - - try { - driver.get(this.url); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".tag-label"))); + driver.get(this.url); - List categories = driver.findElements(By.cssSelector(".tag-label")); + wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".tag-label"))); - for (WebElement element : categories) { - categoriesList.add(element.getText()); - } + List categories = driver.findElements(By.cssSelector(".tag-label")); - } finally { - driver.quit(); + for (WebElement element : categories) { + this.categories.add(element.getText()); } - - return categoriesList; } - public List updateKeyNumbers() { - WebDriver driver = new ChromeDriver(options); - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); - String percentage; - WebElement element; - List keyNumbersList = new ArrayList<>(); + private void updateKeyNumbers() { + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); + String percentage; + WebElement element; - try { - driver.get(this.url); + driver.get(this.url); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( - "//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']"))); + wait.until( + ExpectedConditions.visibilityOfElementLocated( + By.xpath( + "//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']"))); - element = driver.findElement( - By.xpath("//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']") - ); + element = + driver.findElement( + By.xpath("//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']")); - percentage = element.getAttribute("data-percentage"); + percentage = element.getAttribute("data-percentage"); - keyNumbersList.add(percentage); + this.keyValues.add(percentage); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( - "//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']"))); + wait.until( + ExpectedConditions.visibilityOfElementLocated( + By.xpath( + "//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']"))); - element = driver.findElement( - By.xpath("//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']") - ); + element = + driver.findElement( + By.xpath( + "//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']")); - percentage = element.getAttribute("data-percentage"); + percentage = element.getAttribute("data-percentage"); - keyNumbersList.add(percentage); + this.keyValues.add(percentage); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath( - "//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']"))); + wait.until( + ExpectedConditions.visibilityOfElementLocated( + By.xpath("//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']"))); - element = driver.findElement( - By.xpath("//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']") - ); + element = + driver.findElement( + By.xpath("//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']")); - percentage = element.getAttribute("data-percentage"); + percentage = element.getAttribute("data-percentage"); - keyNumbersList.add(percentage); + this.keyValues.add(percentage); + } + public void scrapeCharityPage() { + try { + this.updateDescription(); + this.updateLogo(); + this.updateCategories(); + this.updateKeyNumbers(); } finally { - driver.quit(); + this.quitDriver(); } + } + + public String getDescription() { + return this.description; + } + + public String getLogoURL() { + return this.logoURL; + } + + public List getCategories() { + return Collections.unmodifiableList(this.categories); + } - return keyNumbersList; + public List getKeyValues() { + return Collections.unmodifiableList(this.keyValues); } } From 358aeb4c39e991c32d830a18373dae10a974d8ad Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 7 Apr 2026 08:36:25 +0200 Subject: [PATCH 14/26] Updated URLCharityScraper Edited methods to return strings instead for easier uploading to database. --- .../team6/scraper/URLCharityScraper.java | 349 +++++++++++------- 1 file changed, 219 insertions(+), 130 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index 1aab6ae..7c5f88a 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -12,6 +12,10 @@ import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; +/** + * Class for scraping the description, URL of the logo, string of categories, and key values of the charities + * registered in IK. + */ public class URLCharityScraper { private final String url; private final WebDriver driver; @@ -20,171 +24,256 @@ public class URLCharityScraper { private final List categories; private final List keyValues; - - // Used for production - public URLCharityScraper(String url) { - this.categories = new ArrayList<>(); - this.keyValues = new ArrayList<>(); - ChromeOptions options = new ChromeOptions(); - options.addArguments("--headless=new"); - options.addArguments("--window-size=1920,1080"); - options.addArguments("--disable-gpu"); - options.addArguments("--no-sandbox"); - options.addArguments("--disable-dev-shm-usage"); - this.url = url; - this.driver = new ChromeDriver(options); + /** + * Constructor used for production code. + * + *

It initializes the lists used for categories and keyValues, as well as defining the parameters used + * for the selenium Chromium-based browser that does the scraping.

+ * + * @param url the URL for the charity's webpage on IK + */ + public URLCharityScraper(String url) { + this.categories = new ArrayList<>(); + this.keyValues = new ArrayList<>(); + + ChromeOptions options = new ChromeOptions(); + options.addArguments("--headless=new"); + options.addArguments("--window-size=1920,1080"); + options.addArguments("--disable-gpu"); + options.addArguments("--no-sandbox"); + options.addArguments("--disable-dev-shm-usage"); + + this.url = url; + this.driver = new ChromeDriver(options); } - // Used for testing + /** + * Constructor used for testing. + * + *

It accepts both a url (in this case used as a dud) and a {@link WebDriver} as parameters. The WebDriver is + * passed to make testing easier.

+ * + * @param url the URL for the charity's webpage on IK (for this constructor it should not be a real URL) + * @param driver the {@code WebDriver} object used for scraping + */ public URLCharityScraper(String url, WebDriver driver) { - this.categories = new ArrayList<>(); - this.keyValues = new ArrayList<>(); - this.url = url; - this.driver = driver; + this.categories = new ArrayList<>(); + this.keyValues = new ArrayList<>(); + this.url = url; + this.driver = driver; } - private void quitDriver() { - if (driver instanceof ChromeDriver) { - driver.quit(); - } - } - - private void updateDescription() { - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); - StringBuilder descriptionString = new StringBuilder(); - - driver.get(this.url); - - wait.until( - ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".information div"), 0)); - - List firstDescription = driver.findElements(By.cssSelector(".information div p")); - - for (WebElement element : firstDescription) { - if (element.getText().isBlank()) { - continue; - } - descriptionString.append(element.getText()).append("\n\n"); - } - // Check for if description is long and contains a "read more" link - List doesReadMoreExist = driver.findElements(By.cssSelector("a.read-more")); - - if (!doesReadMoreExist.isEmpty()) { - WebElement descReadMore = driver.findElement(By.cssSelector("a.read-more")); - descReadMore.click(); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".extra-info"))); - } + /** + * Creates a {@link WebDriverWait} object for halting scraping until the correct pre-conditions are met. + * + * @return the {@code WebDriverWait} object to be used in the methods + */ + protected WebDriverWait createWait() { + return new WebDriverWait(driver, Duration.ofSeconds(30)); + } - List extraDescription = driver.findElements(By.cssSelector(".extra-info p")); + /** + * Calls the {@code findElements} method from the {@code WebDriver} object and returns a list of the returned + * {@link WebElement} objects. + * + * @param by a selector for {@code WebElement} objects + * @return a list of found {@code WebElement} objects matching the given selector + */ + protected List findElements(By by) { + return driver.findElements(by); + } - for (WebElement element : extraDescription) { - if (element.getText().isBlank()) { - continue; - } - descriptionString.append(element.getText()).append("\n\n"); - } + /** + * Calls the {@code findElement} method from the {@code WebDriver} object and returns a list of the returned + * {@code WebElement} objects. + * + * @param by a selector for {@code WebElement} objects + * @return a list of found {@code WebElement} objects matching the given selector + */ + protected WebElement findElement(By by) { + return driver.findElement(by); + } + /** + * Quits the driver instance, making it unusable. + */ + protected void closeDriver() { + driver.quit(); + } - this.description = descriptionString.toString(); - } + /** + * Scrapes the URL for the paragraphs containing the description of the charity. + */ + protected void updateDescription() { + WebDriverWait wait = createWait(); + StringBuilder descriptionString = new StringBuilder(); - private void updateLogo() { - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); + wait.until(ExpectedConditions.numberOfElementsToBeMoreThan( + By.cssSelector(".information div"), 0)); - driver.get(this.url); + List firstDescription = + findElements(By.cssSelector(".information div p")); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".logo > img"))); + for (WebElement element : firstDescription) { + if (!element.getText().isBlank()) { + descriptionString.append(element.getText()).append("\n\n"); + } + } - WebElement logo = driver.findElement(By.cssSelector(".logo > img")); + List readMoreLinks = + findElements(By.cssSelector("a.read-more")); - this.logoURL = logo.getAttribute("src"); - } + if (!readMoreLinks.isEmpty()) { + WebElement readMore = findElement(By.cssSelector("a.read-more")); + readMore.click(); - private void updateCategories() { - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); + wait.until(ExpectedConditions.visibilityOfElementLocated( + By.cssSelector(".extra-info"))); + } - driver.get(this.url); + List extraDescription = + findElements(By.cssSelector(".extra-info p")); - wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".tag-label"))); + for (WebElement element : extraDescription) { + if (!element.getText().isBlank()) { + descriptionString.append(element.getText()).append("\n\n"); + } + } - List categories = driver.findElements(By.cssSelector(".tag-label")); + this.description = descriptionString.toString(); + } - for (WebElement element : categories) { - this.categories.add(element.getText()); - } - } + /** + * Scrapes the URL for the image URL of the logo for the charity. + */ + void updateLogo() { + WebDriverWait wait = createWait(); - private void updateKeyNumbers() { - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); - String percentage; - WebElement element; + wait.until(ExpectedConditions.visibilityOfElementLocated( + By.cssSelector(".logo > img"))); - driver.get(this.url); + WebElement logo = findElement(By.cssSelector(".logo > img")); + this.logoURL = logo.getAttribute("src"); + } - wait.until( - ExpectedConditions.visibilityOfElementLocated( - By.xpath( - "//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']"))); + /** + * Scrapes the URL for the category labels containing the categories for the charity. + */ + void updateCategories() { + WebDriverWait wait = createWait(); - element = - driver.findElement( - By.xpath("//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']")); + wait.until(ExpectedConditions.visibilityOfElementLocated( + By.cssSelector(".tag-label"))); - percentage = element.getAttribute("data-percentage"); + List elements = + findElements(By.cssSelector(".tag-label")); - this.keyValues.add(percentage); + for (WebElement element : elements) { + this.categories.add(element.getText()); + } + } - wait.until( - ExpectedConditions.visibilityOfElementLocated( - By.xpath( - "//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']"))); + /** + * Scrapes the URL for the statistics of the charity; the percentage collected, the percentage that goes to the + * administration, and the percentage that is put towards the cause. + */ + void updateKeyValues() { + WebDriverWait wait = createWait(); - element = - driver.findElement( - By.xpath( - "//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']")); + String percentage; + WebElement element; - percentage = element.getAttribute("data-percentage"); + wait.until(ExpectedConditions.visibilityOfElementLocated( + By.xpath("//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']"))); - this.keyValues.add(percentage); + element = findElement(By.xpath( + "//li[.//h2[normalize-space()='Innsamlingsprosent']]//div[@class='graph']")); + percentage = element.getAttribute("data-percentage"); + this.keyValues.add(percentage); - wait.until( - ExpectedConditions.visibilityOfElementLocated( - By.xpath("//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']"))); + wait.until(ExpectedConditions.visibilityOfElementLocated( + By.xpath("//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']"))); - element = - driver.findElement( - By.xpath("//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']")); + element = findElement(By.xpath( + "//li[.//h2[normalize-space()='Administrasjonsprosent']]//div[@class='graph']")); + percentage = element.getAttribute("data-percentage"); + this.keyValues.add(percentage); - percentage = element.getAttribute("data-percentage"); + wait.until(ExpectedConditions.visibilityOfElementLocated( + By.xpath("//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']"))); - this.keyValues.add(percentage); - } + element = findElement(By.xpath( + "//li[.//h2[normalize-space()='Formålsprosent']]//div[@class='graph']")); + percentage = element.getAttribute("data-percentage"); + this.keyValues.add(percentage); + } - public void scrapeCharityPage() { - try { - this.updateDescription(); - this.updateLogo(); - this.updateCategories(); - this.updateKeyNumbers(); - } finally { - this.quitDriver(); - } - } + /** + * Runs all the scraper methods at once, updating the object parameters. + */ + public void scrapeCharityPage() { + try { + driver.get(this.url); + + updateDescription(); + updateLogo(); + updateCategories(); + updateKeyValues(); + + } finally { + closeDriver(); + } + } - public String getDescription() { - return this.description; - } + /** + * Returns the description of the charity. + * + * @return a String containing the description of the charity. + */ + public String getDescription() { + return description; + } - public String getLogoURL() { - return this.logoURL; - } + /** + * Returns the URL of the logo for the charity. + * + * @return a String containing the URL for the logo of the charity. + */ + public String getLogoURL() { + return logoURL; + } - public List getCategories() { - return Collections.unmodifiableList(this.categories); - } + /** + * Returns a String of the categories for the charity with ',' as a delimiter. + * + * @return a String of strings containing the categories for the charity + */ + public String getCategories() { + StringBuilder categoriesString = new StringBuilder(); + + for (int i = 0; i < this.categories.size(); i++) { + categoriesString.append(this.categories.get(i)); + if (i < this.categories.size() - 1) { + categoriesString.append(","); + } + } + return categoriesString.toString(); + } - public List getKeyValues() { - return Collections.unmodifiableList(this.keyValues); - } -} + /** + * Returns a String of the key value percentages for the charity with ':' as a delimiter, verified by IK. + * + * @return a String of the key values for the charity- + */ + public String getKeyValues() { + StringBuilder keyValuesString = new StringBuilder(); + + for (int i = 0; i < this.keyValues.size(); i++) { + keyValuesString.append(this.keyValues.get(i)); + if (i < this.keyValues.size() - 1) { + keyValuesString.append(":"); + } + } + return keyValuesString.toString(); + } +} \ No newline at end of file From 2d81972144173aebc855829099e637fd9bec32df Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 7 Apr 2026 08:38:10 +0200 Subject: [PATCH 15/26] Updated URLCharityScraper Removed unused collections import statement. --- .../ntnu/systemutvikling/team6/scraper/URLCharityScraper.java | 1 - 1 file changed, 1 deletion(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java index 7c5f88a..1122919 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/scraper/URLCharityScraper.java @@ -2,7 +2,6 @@ import java.time.Duration; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; From 36628157cf2e271f960fb755617ae7ca00579f8e Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 7 Apr 2026 08:39:35 +0200 Subject: [PATCH 16/26] Updated Charity Changed description parameter to only contain URL to pass to the URLCharityScraper --- .../ntnu/systemutvikling/team6/models/Charity.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java index d97d996..2addc07 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java @@ -20,8 +20,8 @@ public class Charity { /* Name of the charity */ private String name; - /* Description of the charity's mission and activities */ - private String description; + /* URL of the charity */ + private String url; /* Is the charity verified? */ private String status; @@ -34,6 +34,7 @@ public class Charity { /* List that contains the charity's Feedbacks */ private List feedbacks; + /** * Contructor for creating a new charity. Taylored to match data given from Api. Other attributes * will just be initialized as empty @@ -48,7 +49,7 @@ public Charity( this.UUID = java.util.UUID.randomUUID(); this.org_number = org_number.replaceAll("\\s", ""); this.name = name; - this.description = "Les mer her: " + link; + this.url = link; this.is_pre_approved = is_pre_approved; this.status = status; this.feedbacks = new ArrayList<>(); @@ -74,7 +75,7 @@ public Charity( this.UUID = UUID.fromString(uuid); this.org_number = org_number.replaceAll("\\s", ""); this.name = name; - this.description = link; + this.url = link; this.is_pre_approved = is_pre_approved; this.status = status; this.feedbacks = new ArrayList<>(); @@ -110,8 +111,8 @@ public String getName() { return name; } - public String getDescription() { - return description; + public String getURL() { + return this.url; } /** Setter for verification status. This one sets the charity as verified. */ From 1a48b29023f6174ba6ccdad8f7b8023965012fe9 Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 7 Apr 2026 08:42:21 +0200 Subject: [PATCH 17/26] Updated DatabaseManager Added 4 new columns: description, logoURL, categories, and key_values to the create table method. Creates and calls a URLCharityScraper object on updating API values that populates these new columns using the URL for the charity given from the API. --- .../team6/database/DatabaseManager.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java index a4007a0..1095ef5 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java @@ -8,6 +8,7 @@ import ntnu.systemutvikling.team6.models.Donation; import ntnu.systemutvikling.team6.models.DonationRegistry; import ntnu.systemutvikling.team6.scraper.APICharityData; +import ntnu.systemutvikling.team6.scraper.URLCharityScraper; /** * Manages the Database with MySQL tables and JDBC. @@ -74,6 +75,10 @@ charity_name VARCHAR(255) NOT NULL, charity_link VARCHAR(255) NOT NULL, pre_approved TINYINT NOT NULL, status VARCHAR(255) NOT NULL, + description TEXT, + logoURL TEXT, + categories TEXT, + key_values TEXT, UNIQUE KEY unique_org_number (org_number) ) ENGINE=InnoDB; @@ -127,13 +132,17 @@ public void addAPIDataToTable(List charities) { conn.setAutoCommit(false); String sql_query = """ - INSERT INTO Charities (UUID_charities, org_number, charity_name, charity_link, pre_approved, status) - VALUES (?, ?, ?, ?, ?, ?) + INSERT INTO Charities (UUID_charities, org_number, charity_name, charity_link, pre_approved, status, description, logoURL, categories, key_values) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE charity_name = VALUES(charity_name), charity_link = VALUES(charity_link), pre_approved = VALUES(pre_approved), - status = VALUES(status) + status = VALUES(status), + description = VALUES(description), + logoURL = VALUES(logoURL), + categories = VALUES(categories), + key_values = VALUES(key_values) """; try (PreparedStatement ps = conn.prepareStatement(sql_query)) { @@ -143,12 +152,19 @@ INSERT INTO Charities (UUID_charities, org_number, charity_name, charity_link, p } else { ps.setString(1, charity.getUUID().toString()); } + // Scrapes description, logo, categories, and key values from IK + URLCharityScraper urlScraper = new URLCharityScraper(charity.getURL()); + urlScraper.scrapeCharityPage(); ps.setString(2, charity.getOrg_number().replaceAll("\\s", "")); ps.setString(3, charity.getName()); - ps.setString(4, charity.getDescription()); + ps.setString(4, charity.getURL()); ps.setBoolean(5, charity.getPreApproved()); // Description is the link ps.setString(6, charity.getStatus()); + ps.setString(7, urlScraper.getDescription()); + ps.setString(8, urlScraper.getLogoURL()); + ps.setString(9, urlScraper.getCategories()); + ps.setString(10, urlScraper.getKeyValues()); ps.addBatch(); } From b9b372b3a19b2add127fdf968798edb49c768c46 Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 7 Apr 2026 08:44:44 +0200 Subject: [PATCH 18/26] Updated DatabaseManagerTest Changed getDescription test to use getURL instead. --- .../team6/database/DatabaseManagerTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/database/DatabaseManagerTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/database/DatabaseManagerTest.java index 086ed69..f930aba 100644 --- a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/database/DatabaseManagerTest.java +++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/database/DatabaseManagerTest.java @@ -18,6 +18,20 @@ public void setUp() throws SQLException { this.dbManager = new DatabaseManager(); } + @Test + public void test() { + dbManager.createTables(); + + String org_number = "12345"; + String name = "Test Charity"; + String status = "approved"; + String url = "https://www.innsamlingskontrollen.no/organisasjoner/adra-norge-adventist-development-and-relief-agency-norway/"; + boolean is_pre_approved = false; + + Charity charity = new Charity(org_number, url, name, is_pre_approved, status); + dbManager.addAPIDataToTable(List.of(charity)); + } + // Make sure you're connected to the NTNU network for this to work @Test public void testConnectionShouldReturnTrue() { From 39aedbad12d8796d1c2f7a8ab3553ee227724590 Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 7 Apr 2026 08:47:51 +0200 Subject: [PATCH 19/26] Updated DatabaseManagerTest Changed getDescription test to use getURL instead. --- .../java/ntnu/systemutvikling/team6/models/CharityTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/CharityTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/CharityTest.java index e382fe5..8bcc674 100644 --- a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/CharityTest.java +++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/CharityTest.java @@ -37,7 +37,7 @@ public void testGettingNameShouldWork() { @Test public void testGettingDescriptionShouldWork() { - assertEquals("Les mer her: www.aaaa.com", charity.getDescription()); + assertEquals("www.aaaa.com", charity.getURL()); } /** Getter and setter for IsVerified should be able to switch between true and false */ From 0ec340b88012447d6b46bac30b7dfd7c0ff18ea5 Mon Sep 17 00:00:00 2001 From: Roar Date: Tue, 7 Apr 2026 08:51:45 +0200 Subject: [PATCH 20/26] Added URLCharityScraperTest Test file for URLCharityScraper with as much coverage as possible. --- .../team6/scraper/URLCharityScraperTest.java | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/scraper/URLCharityScraperTest.java diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/scraper/URLCharityScraperTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/scraper/URLCharityScraperTest.java new file mode 100644 index 0000000..d437891 --- /dev/null +++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/scraper/URLCharityScraperTest.java @@ -0,0 +1,171 @@ +package ntnu.systemutvikling.team6.scraper; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.WebDriverWait; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class URLCharityScraperTest { + + private WebDriver driver; + private URLCharityScraper scraper; + + @BeforeEach + void setup() { + driver = mock(WebDriver.class); + + scraper = new URLCharityScraper("http://test", driver) { + @Override + protected WebDriverWait createWait() { + return mock(WebDriverWait.class); + } + + @Override + protected void closeDriver() { + } + }; + } + + @Test + void updateDescriptionShouldReturnCorrectDescriptionWithoutReadMore() { + WebElement p1 = mock(WebElement.class); + WebElement p2 = mock(WebElement.class); + + when(p1.getText()).thenReturn("Short description"); + when(p2.getText()).thenReturn(""); + + when(scraper.findElements(By.cssSelector(".information div p"))) + .thenReturn(List.of(p1, p2)); + + when(scraper.findElements(By.cssSelector("a.read-more"))) + .thenReturn(List.of()); + + when(scraper.findElements(By.cssSelector(".extra-info p"))) + .thenReturn(List.of()); + + scraper.updateDescription(); + + String result = scraper.getDescription(); + + assertTrue(result.contains("Short description"), + "First paragraph should be 'Short description'"); + assertFalse(result.isBlank(), + "Second paragraph should be blank."); + } + + @Test + void updateDescriptionShouldReturnCorrectDescriptionWithReadMore() { + WebElement p1 = mock(WebElement.class); + WebElement extra = mock(WebElement.class); + WebElement readMore = mock(WebElement.class); + + when(p1.getText()).thenReturn("Intro"); + when(extra.getText()).thenReturn("Extra info"); + + when(scraper.findElements(By.cssSelector(".information div p"))) + .thenReturn(List.of(p1)); + + when(scraper.findElements(By.cssSelector("a.read-more"))) + .thenReturn(List.of(readMore)); + + when(scraper.findElement(By.cssSelector("a.read-more"))) + .thenReturn(readMore); + + when(scraper.findElements(By.cssSelector(".extra-info p"))) + .thenReturn(List.of(extra)); + + scraper.updateDescription(); + + String result = scraper.getDescription(); + + verify(readMore).click(); + assertTrue(result.contains("Intro"), + "First paragraph should be 'Intro'"); + assertTrue(result.contains("Extra info"), + "Second paragraph should be 'Extra info'"); + } + + @Test + void updateLogoShouldReturnCorrectLogoURL() { + WebElement logo = mock(WebElement.class); + + when(scraper.findElement(By.cssSelector(".logo > img"))) + .thenReturn(logo); + + when(logo.getAttribute("src")).thenReturn("logo.png"); + + scraper.updateLogo(); + + assertEquals("logo.png", scraper.getLogoURL()); + } + + @Test + void updateCategoriesShouldReturnCorrectCategories() { + WebElement c1 = mock(WebElement.class); + WebElement c2 = mock(WebElement.class); + + when(c1.getText()).thenReturn("Health"); + when(c2.getText()).thenReturn("Education"); + + when(scraper.findElements(By.cssSelector(".tag-label"))) + .thenReturn(List.of(c1, c2)); + + scraper.updateCategories(); + + assertEquals("Health,Education", scraper.getCategories(), + "Should return a string that lists categories with ',' as a delimiter."); + } + + @Test + void updateKeyNumbersShouldReturnCorrectNumbers() { + WebElement e1 = mock(WebElement.class); + WebElement e2 = mock(WebElement.class); + WebElement e3 = mock(WebElement.class); + + when(e1.getAttribute("data-percentage")).thenReturn("80"); + when(e2.getAttribute("data-percentage")).thenReturn("10"); + when(e3.getAttribute("data-percentage")).thenReturn("90"); + + when(scraper.findElement(any(By.class))) + .thenReturn(e1, e2, e3); + + scraper.updateKeyValues(); + + System.out.println(scraper.getKeyValues()); + + assertEquals("80:10:90", scraper.getKeyValues(), + "Should return a string that lists key values with ':' as a delimiter."); + } + + @Test + void scrapeCharityPageShouldCallAllRelevantMethods() { + URLCharityScraper spyScraper = spy(scraper); + + doNothing().when(spyScraper).updateDescription(); + doNothing().when(spyScraper).updateLogo(); + doNothing().when(spyScraper).updateCategories(); + doNothing().when(spyScraper).updateKeyValues(); + + spyScraper.scrapeCharityPage(); + + // Url should be correct + verify(driver).get("http://test"); + // UpdateDescription should run + verify(spyScraper).updateDescription(); + // UpdateLogo should run + verify(spyScraper).updateLogo(); + // UpdateCategories should run + verify(spyScraper).updateCategories(); + // UpdateKeyValues should run + verify(spyScraper).updateKeyValues(); + } + + +} \ No newline at end of file From 5638e8fdd5c00599072ca2376d6ea8da3636b32c Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 8 Apr 2026 18:18:20 +0200 Subject: [PATCH 21/26] Updated Charity Added parameters for the new SQL entries to the Charity object. --- .../systemutvikling/team6/models/Charity.java | 49 +++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java index 2addc07..4643d87 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/models/Charity.java @@ -31,10 +31,18 @@ public class Charity { /* Category for the charity */ private String category; + /* Description for the charity */ + private String description; + + /* URL for the logo of the charity */ + private String logoURL; + + /* Key values for the charity */ + private String keyValues; + /* List that contains the charity's Feedbacks */ private List feedbacks; - /** * Contructor for creating a new charity. Taylored to match data given from Api. Other attributes * will just be initialized as empty @@ -78,8 +86,11 @@ public Charity( this.url = link; this.is_pre_approved = is_pre_approved; this.status = status; - this.feedbacks = new ArrayList<>(); this.category = ""; + this.description = ""; + this.logoURL = ""; + this.keyValues = ""; + this.feedbacks = new ArrayList<>(); } /** Getters for the charity's attributes. */ @@ -112,7 +123,19 @@ public String getName() { } public String getURL() { - return this.url; + return this.url; + } + + public String getDescription() { + return this.description; + } + + public String getLogoURL() { + return this.logoURL; + } + + public String getKeyValues() { + return this.keyValues; } /** Setter for verification status. This one sets the charity as verified. */ @@ -124,4 +147,24 @@ public void setVerified() { public void setUnverified() { this.status = "Veto"; } + + /** Setter for categories. */ + public void setCategory(String category) { + this.category = category; + } + + /** Setter for description. */ + public void setDescription(String description) { + this.description = description; + } + + /** Setter for the URL of the charity's logo. */ + public void setLogoURL(String url) { + this.logoURL = url; + } + + /** Setter for the charity's key values. */ + public void setKeyValues(String values) { + this.keyValues = values; + } } From 40dec7763fb0595c401dca177a5e6555839514ab Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 8 Apr 2026 18:19:45 +0200 Subject: [PATCH 22/26] Updated DatabaseManager Adds the scraped parameters directly to the charity object. --- .../team6/database/DatabaseManager.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java index 1095ef5..e411642 100644 --- a/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java +++ b/helpmehelpapplication/src/main/java/ntnu/systemutvikling/team6/database/DatabaseManager.java @@ -153,18 +153,23 @@ INSERT INTO Charities (UUID_charities, org_number, charity_name, charity_link, p ps.setString(1, charity.getUUID().toString()); } // Scrapes description, logo, categories, and key values from IK - URLCharityScraper urlScraper = new URLCharityScraper(charity.getURL()); + URLCharityScraper urlScraper = new URLCharityScraper(charity.getURL()); urlScraper.scrapeCharityPage(); + charity.setDescription(urlScraper.getDescription()); + charity.setCategory(urlScraper.getCategories()); + charity.setLogoURL(urlScraper.getLogoURL()); + charity.setKeyValues(urlScraper.getKeyValues()); + ps.setString(2, charity.getOrg_number().replaceAll("\\s", "")); ps.setString(3, charity.getName()); ps.setString(4, charity.getURL()); - ps.setBoolean(5, charity.getPreApproved()); // Description is the link + ps.setBoolean(5, charity.getPreApproved()); ps.setString(6, charity.getStatus()); - ps.setString(7, urlScraper.getDescription()); - ps.setString(8, urlScraper.getLogoURL()); - ps.setString(9, urlScraper.getCategories()); - ps.setString(10, urlScraper.getKeyValues()); + ps.setString(7, charity.getDescription()); + ps.setString(8, charity.getLogoURL()); + ps.setString(9, charity.getCategory()); + ps.setString(10, charity.getKeyValues()); ps.addBatch(); } From e167e510d7897bf359385f774619cbb78c4f33ee Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 8 Apr 2026 18:20:33 +0200 Subject: [PATCH 23/26] Updated APICHarityScraperTest Fixed getDescription test. --- .../systemutvikling/team6/scraper/APICharityScraperTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/scraper/APICharityScraperTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/scraper/APICharityScraperTest.java index 40c3ce4..1ab7413 100644 --- a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/scraper/APICharityScraperTest.java +++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/scraper/APICharityScraperTest.java @@ -86,8 +86,8 @@ void parsedJSONShouldHaveCorrectValues() throws URISyntaxException { assertEquals("Misjonsalliansen", d.getName(), "Name parameter should be correct."); assertEquals("approved", d.getStatus(), "Status parameter should be correct."); assertEquals( - "Les mer her: https://www.innsamlingskontrollen.no/organisasjoner/misjonsalliansen/", - d.getDescription(), + "https://www.innsamlingskontrollen.no/organisasjoner/misjonsalliansen/", + d.getURL(), "Url parameter should be correct."); assertFalse(d.getPreApproved(), "Is_pre_approved parameter should be correct."); } From d2174e43c7cf72957d86b598f81a1d0c28a0b5fc Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 8 Apr 2026 18:21:09 +0200 Subject: [PATCH 24/26] Updated DonationDAOTest Temp fix to make tests work by using a valid charity URL. --- .../ntnu/systemutvikling/team6/DAO/DonationDAOTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/DAO/DonationDAOTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/DAO/DonationDAOTest.java index d3522ed..c90a297 100644 --- a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/DAO/DonationDAOTest.java +++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/DAO/DonationDAOTest.java @@ -20,7 +20,13 @@ void setUp() { DatabaseManager manager = new DatabaseManager(); manager.createTables(); - charity = new Charity("123456", "https://test.org", "Test Charity", true, "approved"); + charity = + new Charity( + "123456", + "https://www.innsamlingskontrollen.no/organisasjoner/adra-norge-adventist-development-and-relief-agency-norway/", + "Test Charity", + true, + "approved"); manager.addAPIDataToTable(java.util.List.of(charity)); } From aaf62f9a9a93cfcab31477635c43494481bca1c0 Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 8 Apr 2026 18:21:45 +0200 Subject: [PATCH 25/26] Updated DonationDAOTest Temp fix to make tests work. --- .../team6/scraper/URLCharityScraperTest.java | 226 +++++++++--------- 1 file changed, 107 insertions(+), 119 deletions(-) diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/scraper/URLCharityScraperTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/scraper/URLCharityScraperTest.java index d437891..82c28cb 100644 --- a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/scraper/URLCharityScraperTest.java +++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/scraper/URLCharityScraperTest.java @@ -1,5 +1,9 @@ package ntnu.systemutvikling.team6.scraper; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; @@ -7,165 +11,149 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.WebDriverWait; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; - class URLCharityScraperTest { - private WebDriver driver; - private URLCharityScraper scraper; + private WebDriver driver; + private URLCharityScraper scraper; - @BeforeEach - void setup() { - driver = mock(WebDriver.class); + @BeforeEach + void setup() { + driver = mock(WebDriver.class); - scraper = new URLCharityScraper("http://test", driver) { - @Override - protected WebDriverWait createWait() { - return mock(WebDriverWait.class); - } + scraper = + new URLCharityScraper("http://test", driver) { + @Override + protected WebDriverWait createWait() { + return mock(WebDriverWait.class); + } - @Override - protected void closeDriver() { - } + @Override + protected void closeDriver() {} }; - } - - @Test - void updateDescriptionShouldReturnCorrectDescriptionWithoutReadMore() { - WebElement p1 = mock(WebElement.class); - WebElement p2 = mock(WebElement.class); - - when(p1.getText()).thenReturn("Short description"); - when(p2.getText()).thenReturn(""); + } - when(scraper.findElements(By.cssSelector(".information div p"))) - .thenReturn(List.of(p1, p2)); + @Test + void updateDescriptionShouldReturnCorrectDescriptionWithoutReadMore() { + WebElement p1 = mock(WebElement.class); + WebElement p2 = mock(WebElement.class); - when(scraper.findElements(By.cssSelector("a.read-more"))) - .thenReturn(List.of()); + when(p1.getText()).thenReturn("Short description"); + when(p2.getText()).thenReturn(""); - when(scraper.findElements(By.cssSelector(".extra-info p"))) - .thenReturn(List.of()); + when(scraper.findElements(By.cssSelector(".information div p"))).thenReturn(List.of(p1, p2)); - scraper.updateDescription(); + when(scraper.findElements(By.cssSelector("a.read-more"))).thenReturn(List.of()); - String result = scraper.getDescription(); + when(scraper.findElements(By.cssSelector(".extra-info p"))).thenReturn(List.of()); - assertTrue(result.contains("Short description"), - "First paragraph should be 'Short description'"); - assertFalse(result.isBlank(), - "Second paragraph should be blank."); - } + scraper.updateDescription(); - @Test - void updateDescriptionShouldReturnCorrectDescriptionWithReadMore() { - WebElement p1 = mock(WebElement.class); - WebElement extra = mock(WebElement.class); - WebElement readMore = mock(WebElement.class); + String result = scraper.getDescription(); - when(p1.getText()).thenReturn("Intro"); - when(extra.getText()).thenReturn("Extra info"); + assertTrue( + result.contains("Short description"), "First paragraph should be 'Short description'"); + assertFalse(result.isBlank(), "Second paragraph should be blank."); + } - when(scraper.findElements(By.cssSelector(".information div p"))) - .thenReturn(List.of(p1)); + @Test + void updateDescriptionShouldReturnCorrectDescriptionWithReadMore() { + WebElement p1 = mock(WebElement.class); + WebElement extra = mock(WebElement.class); + WebElement readMore = mock(WebElement.class); - when(scraper.findElements(By.cssSelector("a.read-more"))) - .thenReturn(List.of(readMore)); + when(p1.getText()).thenReturn("Intro"); + when(extra.getText()).thenReturn("Extra info"); - when(scraper.findElement(By.cssSelector("a.read-more"))) - .thenReturn(readMore); + when(scraper.findElements(By.cssSelector(".information div p"))).thenReturn(List.of(p1)); - when(scraper.findElements(By.cssSelector(".extra-info p"))) - .thenReturn(List.of(extra)); + when(scraper.findElements(By.cssSelector("a.read-more"))).thenReturn(List.of(readMore)); - scraper.updateDescription(); + when(scraper.findElement(By.cssSelector("a.read-more"))).thenReturn(readMore); - String result = scraper.getDescription(); + when(scraper.findElements(By.cssSelector(".extra-info p"))).thenReturn(List.of(extra)); - verify(readMore).click(); - assertTrue(result.contains("Intro"), - "First paragraph should be 'Intro'"); - assertTrue(result.contains("Extra info"), - "Second paragraph should be 'Extra info'"); - } + scraper.updateDescription(); - @Test - void updateLogoShouldReturnCorrectLogoURL() { - WebElement logo = mock(WebElement.class); + String result = scraper.getDescription(); - when(scraper.findElement(By.cssSelector(".logo > img"))) - .thenReturn(logo); + verify(readMore).click(); + assertTrue(result.contains("Intro"), "First paragraph should be 'Intro'"); + assertTrue(result.contains("Extra info"), "Second paragraph should be 'Extra info'"); + } - when(logo.getAttribute("src")).thenReturn("logo.png"); + @Test + void updateLogoShouldReturnCorrectLogoURL() { + WebElement logo = mock(WebElement.class); - scraper.updateLogo(); + when(scraper.findElement(By.cssSelector(".logo > img"))).thenReturn(logo); - assertEquals("logo.png", scraper.getLogoURL()); - } + when(logo.getAttribute("src")).thenReturn("logo.png"); - @Test - void updateCategoriesShouldReturnCorrectCategories() { - WebElement c1 = mock(WebElement.class); - WebElement c2 = mock(WebElement.class); + scraper.updateLogo(); - when(c1.getText()).thenReturn("Health"); - when(c2.getText()).thenReturn("Education"); + assertEquals("logo.png", scraper.getLogoURL()); + } - when(scraper.findElements(By.cssSelector(".tag-label"))) - .thenReturn(List.of(c1, c2)); + @Test + void updateCategoriesShouldReturnCorrectCategories() { + WebElement c1 = mock(WebElement.class); + WebElement c2 = mock(WebElement.class); - scraper.updateCategories(); + when(c1.getText()).thenReturn("Health"); + when(c2.getText()).thenReturn("Education"); - assertEquals("Health,Education", scraper.getCategories(), - "Should return a string that lists categories with ',' as a delimiter."); - } + when(scraper.findElements(By.cssSelector(".tag-label"))).thenReturn(List.of(c1, c2)); - @Test - void updateKeyNumbersShouldReturnCorrectNumbers() { - WebElement e1 = mock(WebElement.class); - WebElement e2 = mock(WebElement.class); - WebElement e3 = mock(WebElement.class); + scraper.updateCategories(); - when(e1.getAttribute("data-percentage")).thenReturn("80"); - when(e2.getAttribute("data-percentage")).thenReturn("10"); - when(e3.getAttribute("data-percentage")).thenReturn("90"); + assertEquals( + "Health,Education", + scraper.getCategories(), + "Should return a string that lists categories with ',' as a delimiter."); + } - when(scraper.findElement(any(By.class))) - .thenReturn(e1, e2, e3); + @Test + void updateKeyNumbersShouldReturnCorrectNumbers() { + WebElement e1 = mock(WebElement.class); + WebElement e2 = mock(WebElement.class); + WebElement e3 = mock(WebElement.class); - scraper.updateKeyValues(); + when(e1.getAttribute("data-percentage")).thenReturn("80"); + when(e2.getAttribute("data-percentage")).thenReturn("10"); + when(e3.getAttribute("data-percentage")).thenReturn("90"); - System.out.println(scraper.getKeyValues()); + when(scraper.findElement(any(By.class))).thenReturn(e1, e2, e3); - assertEquals("80:10:90", scraper.getKeyValues(), - "Should return a string that lists key values with ':' as a delimiter."); - } + scraper.updateKeyValues(); - @Test - void scrapeCharityPageShouldCallAllRelevantMethods() { - URLCharityScraper spyScraper = spy(scraper); + System.out.println(scraper.getKeyValues()); - doNothing().when(spyScraper).updateDescription(); - doNothing().when(spyScraper).updateLogo(); - doNothing().when(spyScraper).updateCategories(); - doNothing().when(spyScraper).updateKeyValues(); + assertEquals( + "80:10:90", + scraper.getKeyValues(), + "Should return a string that lists key values with ':' as a delimiter."); + } - spyScraper.scrapeCharityPage(); + @Test + void scrapeCharityPageShouldCallAllRelevantMethods() { + URLCharityScraper spyScraper = spy(scraper); - // Url should be correct - verify(driver).get("http://test"); - // UpdateDescription should run - verify(spyScraper).updateDescription(); - // UpdateLogo should run - verify(spyScraper).updateLogo(); - // UpdateCategories should run - verify(spyScraper).updateCategories(); - // UpdateKeyValues should run - verify(spyScraper).updateKeyValues(); - } + doNothing().when(spyScraper).updateDescription(); + doNothing().when(spyScraper).updateLogo(); + doNothing().when(spyScraper).updateCategories(); + doNothing().when(spyScraper).updateKeyValues(); + spyScraper.scrapeCharityPage(); -} \ No newline at end of file + // Url should be correct + verify(driver).get("http://test"); + // UpdateDescription should run + verify(spyScraper).updateDescription(); + // UpdateLogo should run + verify(spyScraper).updateLogo(); + // UpdateCategories should run + verify(spyScraper).updateCategories(); + // UpdateKeyValues should run + verify(spyScraper).updateKeyValues(); + } +} From 72c77e33de6d8031a68cf100b9c7d6cde093d3bd Mon Sep 17 00:00:00 2001 From: Roar Date: Wed, 8 Apr 2026 18:22:01 +0200 Subject: [PATCH 26/26] Updated DatabaseManagerTest Temp fix to make tests work. --- .../team6/database/DatabaseManagerTest.java | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/database/DatabaseManagerTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/database/DatabaseManagerTest.java index f930aba..78be78a 100644 --- a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/database/DatabaseManagerTest.java +++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/database/DatabaseManagerTest.java @@ -20,16 +20,17 @@ public void setUp() throws SQLException { @Test public void test() { - dbManager.createTables(); + dbManager.createTables(); - String org_number = "12345"; - String name = "Test Charity"; - String status = "approved"; - String url = "https://www.innsamlingskontrollen.no/organisasjoner/adra-norge-adventist-development-and-relief-agency-norway/"; - boolean is_pre_approved = false; + String org_number = "12345"; + String name = "Test Charity"; + String status = "approved"; + String url = + "https://www.innsamlingskontrollen.no/organisasjoner/adra-norge-adventist-development-and-relief-agency-norway/"; + boolean is_pre_approved = false; - Charity charity = new Charity(org_number, url, name, is_pre_approved, status); - dbManager.addAPIDataToTable(List.of(charity)); + Charity charity = new Charity(org_number, url, name, is_pre_approved, status); + dbManager.addAPIDataToTable(List.of(charity)); } // Make sure you're connected to the NTNU network for this to work @@ -56,7 +57,8 @@ void updateCharitiesShouldInsertCorrectData() throws SQLException { String org_number = "12345"; String name = "Test Charity"; String status = "approved"; - String url = "https://www.svindel.no"; + String url = + "https://www.innsamlingskontrollen.no/organisasjoner/adra-norge-adventist-development-and-relief-agency-norway/"; boolean is_pre_approved = false; Charity charity = new Charity(org_number, url, name, is_pre_approved, status); @@ -77,7 +79,8 @@ void updateCharitiesShouldRemoveDataNotInList() throws SQLException { String org_number = "12345"; String name = "Svindelorg"; String status = "approved"; - String url = "https://www.svindel.no"; + String url = + "https://www.innsamlingskontrollen.no/organisasjoner/adra-norge-adventist-development-and-relief-agency-norway/"; boolean is_pre_approved = false; var charity1 = new Charity(org_number, url, name, is_pre_approved, status); @@ -85,7 +88,8 @@ void updateCharitiesShouldRemoveDataNotInList() throws SQLException { org_number = "23456"; name = "SvindelKoin"; status = "approved"; - url = "https://www.svindel.net"; + url = + "https://www.innsamlingskontrollen.no/organisasjoner/adra-norge-adventist-development-and-relief-agency-norway/"; is_pre_approved = true; var charity2 = new Charity(org_number, url, name, is_pre_approved, status); @@ -93,7 +97,8 @@ void updateCharitiesShouldRemoveDataNotInList() throws SQLException { org_number = "345672"; name = "Arme Svindlere"; status = "approved"; - url = "https://www.armesvindlere.com"; + url = + "https://www.innsamlingskontrollen.no/organisasjoner/adra-norge-adventist-development-and-relief-agency-norway/"; is_pre_approved = false; var charity3 = new Charity(org_number, url, name, is_pre_approved, status); @@ -127,7 +132,13 @@ void updateCharitiesShouldRemoveDataNotInList() throws SQLException { @Test void tempTableShouldNotExistAfterUpdating() throws SQLException { - Charity charity = new Charity("99999", "https://temp.no", "Temp Charity", false, "approved"); + Charity charity = + new Charity( + "99999", + "https://www.innsamlingskontrollen.no/organisasjoner/adra-norge-adventist-development-and-relief-agency-norway/", + "Temp Charity", + false, + "approved"); dbManager.addAPIDataToTable(List.of(charity));