Skip to content

Merge feat/organisation into release/v1.0.0 #40

Merged
merged 18 commits into from
Mar 3, 2026
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/main/java/edu/group5/app/model/Repository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package edu.group5.app.model;

import java.util.Map;

/**
* Represents a repository
*/
public abstract class Repository<K, V> {
protected final Map<K, V> content;

public Repository(Map<K, V> content) {
this.content = content;
}

/**
* Gets the content of the repo
* @return content of the repo
*/
public Map<K, V> getContent() {
return content;
}
}
55 changes: 53 additions & 2 deletions src/main/java/edu/group5/app/model/organization/Organization.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,56 @@
package edu.group5.app.model.organization;

public class Organization {

import java.util.Objects;

/**
* Represents an organization.
*
* <p>An organization is identified by an organization number, a name,
* trust status, website URL, pre-approval status, and a textual description.
*
* <p>Instances are validated on creation:
* <ul>
* <li>orgNumber must be non-negative</li>
* <li>name and websiteURL must not be null or blank</li>
* <li>description must not be null</li>
* </ul>
*/
public record Organization(
int orgNumber,
String name,
boolean trusted,
String websiteURL,
boolean isPreApproved,
String description
) {
/**
* Creates a new organization.
*
* @param orgNumber the organization number; must be non-negative
* @param name the organization name; must not be null or blank
* @param trusted whether the organization is trusted
* @param websiteURL the organization's website URL; must not be null or blank
* @param isPreApproved whether the organization is pre-approved
* @param description a textual description of the organization; must not be null
* @throws NullPointerException if name, websiteURL or description is null
* @throws IllegalArgumentException if orgNumber is negative, or if name or websiteURL is blank
*/
public Organization(int orgNumber, String name, boolean trusted, String websiteURL, boolean isPreApproved, String description) {
if (orgNumber < 0) {
throw new IllegalArgumentException("orgNumber cannot be negative");
}
this.orgNumber = orgNumber;
this.name = Objects.requireNonNull(name, "name cannot be null");
this.trusted = trusted;
this.websiteURL = Objects.requireNonNull(websiteURL, "websiteURL cannot be null");
this.isPreApproved = isPreApproved;
this.description = Objects.requireNonNull(description, "description cannot be null");

if (name.isBlank()) {
throw new IllegalArgumentException("name cannot be blank");
}
if (websiteURL.isBlank()) {
throw new IllegalArgumentException("websiteURL cannot be blank");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package edu.group5.app.model.organization;

import edu.group5.app.model.Repository;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
* Handles the business logic associated with organizations
*/
public class OrganizationRepository extends Repository<Integer, Organization> {
/**
* Creates a new Organization Repository
*
* @param content holds all current organizations in the repository; must not be null
* @throws NullPointerException if content is null
*/
public OrganizationRepository(Map<Integer, Organization> content) {
super(Objects.requireNonNull(content, "content cannot be null"));
}

/**
* Gets all trusted organizations in the repository
* @return all organizations with trusted = true
*/
public Map<Integer, Organization> getTrustedOrganizations() {
Map<Integer, Organization> trustedOrganizations = new HashMap<>();

content.forEach((orgNr, org) -> {
if (org.trusted()) {
trustedOrganizations.put(orgNr, org);
}
});

return trustedOrganizations;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package edu.group5.app.model.organization;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.HashMap;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.*;

class OrganizationRepositoryTest {

private OrganizationRepository repository;

@BeforeEach
void setUp() {
Map<Integer, Organization> content = new HashMap<>();

Organization trustedOrganization1 = new Organization(1, "Trusted Org1", true, "org.com", true, "description");
Organization trustedOrganization2 = new Organization(2, "Trusted Org2", true, "org.com", true, "description");
Organization untrustedOrganization1 = new Organization(3, "Untrusted Org1", false, "org.com", true, "description");
Organization untrustedOrganization2 = new Organization(4, "Untrusted Org2", false, "org.com", true, "description");

content.put(1, trustedOrganization1);
content.put(2, trustedOrganization2);
content.put(3, untrustedOrganization1);
content.put(4, untrustedOrganization2);

repository = new OrganizationRepository(content);
}

@Test
void constructor_ThrowsWhenContentIsNull() {
assertThrows(NullPointerException.class, () -> new OrganizationRepository(null));
}

@Test
void getTrustedOrganizations_OnlyReturnsTrustedOrganizations() {
Map<Integer, Organization> trusted = repository.getTrustedOrganizations();

assertEquals(2, trusted.size());
assertTrue(trusted.containsKey(1));
assertTrue(trusted.containsKey(2));
assertFalse(trusted.containsKey(3));
assertFalse(trusted.containsKey(4));
assertTrue(trusted.values().stream().allMatch(Organization::trusted));
}
}
102 changes: 99 additions & 3 deletions src/test/java/edu/group5/app/model/organization/OrganizationTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,101 @@
package edu.group5.app.model.organization;

public class OrganizationTest {

}
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class OrganizationTest {

@Test
void constructor_CreatesAnOrganizationWhenInputIsValid() {
Organization org = new Organization(
1,
"Org",
true,
"org.com",
true,
"Org description"
);

assertAll(
() -> assertEquals(1, org.orgNumber()),
() -> assertEquals("Org", org.name()),
() -> assertTrue(org.trusted()),
() -> assertEquals("org.com", org.websiteURL()),
() -> assertTrue(org.isPreApproved()),
() -> assertEquals("Org description", org.description())
);
}

@Test
void constructor_ThrowsWhenOrgNumberIsNegative() {
assertThrows(IllegalArgumentException.class, () -> new Organization(
-1,
"Org",
true,
"org.com",
true,
"Org description"
));
}

@Test
void constructor_ThrowsWhenNameIsNull() {
assertThrows(NullPointerException.class, () -> new Organization(
1,
null,
true,
"org.com",
true,
"Org description"
));
}

@Test
void constructor_ThrowsWhenNameIsBlank() {
assertThrows(IllegalArgumentException.class, () -> new Organization(
1,
"",
true,
"org.com",
true,
"Org description"
));
}

@Test
void constructor_ThrowsWhenWebsiteURLIsNull() {
assertThrows(NullPointerException.class, () -> new Organization(
1,
"Org",
true,
null,
true,
"Org description"
));
}

@Test
void constructor_ThrowsWhenWebsiteURLIsBlank() {
assertThrows(IllegalArgumentException.class, () -> new Organization(
1,
"Org",
true,
"",
true,
"Org description"
));
}

@Test
void constructor_ThrowsWhenDescriptionIsNull() {
assertThrows(NullPointerException.class, () -> new Organization(
1,
"Org",
true,
"org.com",
true,
null
));
}
}