From 39438223b1d48ba83d87423e212f6386a62ede93 Mon Sep 17 00:00:00 2001 From: Alexandre Barrymore Date: Mon, 2 Jun 2025 14:42:25 +0100 Subject: [PATCH 1/4] Updated test from JUnit4 --> JUnit5 --- .../acebook/feature/SignUpTest.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/test/java/com/makersacademy/acebook/feature/SignUpTest.java b/src/test/java/com/makersacademy/acebook/feature/SignUpTest.java index dcb1416bb..bf36682f9 100644 --- a/src/test/java/com/makersacademy/acebook/feature/SignUpTest.java +++ b/src/test/java/com/makersacademy/acebook/feature/SignUpTest.java @@ -1,29 +1,30 @@ package com.makersacademy.acebook.feature; import com.github.javafaker.Faker; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +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.chrome.ChromeDriver; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class SignUpTest { WebDriver driver; Faker faker; - @Before + @BeforeEach public void setup() { System.setProperty("webdriver.chrome.driver", "/usr/local/bin/chromedriver"); driver = new ChromeDriver(); faker = new Faker(); } - @After + @AfterEach public void tearDown() { - driver.close(); + driver.quit(); // safer than close() } @Test @@ -37,6 +38,7 @@ public void successfulSignUpAlsoLogsInUser() { driver.findElement(By.name("action")).click(); driver.findElement(By.name("action")).click(); String greetingText = driver.findElement(By.id("greeting")).getText(); - Assert.assertEquals("Signed in as " + email, greetingText); + + assertEquals("Signed in as " + email, greetingText); } } From 97de2336c1ee087c12c7ef28f46e18de201aa89b Mon Sep 17 00:00:00 2001 From: Alexandre Barrymore <131294388+twiin0@users.noreply.github.com> Date: Mon, 2 Jun 2025 15:33:19 +0100 Subject: [PATCH 2/4] Update application.yml New placeholder for secret values --- src/main/resources/application.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 699e8575a..39af65fd8 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,5 +1,5 @@ okta: oauth2: - issuer: https://dev-edward-andress.uk.auth0.com/ - client-id: ${OKTA_CLIENT_ID} - client-secret: ${OKTA_CLIENT_SECRET} + issuer: ${ISSUER_ACEBOOK} + client-id: ${CLIENT_ID_ACEBOOK} + client-secret: ${CLIENT_SECRET_ACEBOOK} From 3bc9f18d7be667eb9953a76bd4c50bf6b91ab7ee Mon Sep 17 00:00:00 2001 From: Alexandre Barrymore <131294388+twiin0@users.noreply.github.com> Date: Mon, 2 Jun 2025 15:35:58 +0100 Subject: [PATCH 3/4] Update application-test.properties Fixing spring.jpa.database-platform updated to latest version --- src/main/resources/application-test.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties index 865b41e1c..926b9edf4 100644 --- a/src/main/resources/application-test.properties +++ b/src/main/resources/application-test.properties @@ -3,4 +3,4 @@ spring.datasource.username= spring.datasource.password= flyway.baseline-on-migrate=true spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false -spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect From bdd5b26d187dff3b09adc3632b912994c5bfbeed Mon Sep 17 00:00:00 2001 From: Karen Date: Tue, 3 Jun 2025 15:35:48 +0100 Subject: [PATCH 4/4] Created foundations for friends page. --- .DS_Store | Bin 0 -> 6148 bytes src/.DS_Store | Bin 0 -> 6148 bytes src/main/.DS_Store | Bin 0 -> 6148 bytes .../acebook/controller/UsersController.java | 24 ++++++++++++++++++ .../com/makersacademy/acebook/model/User.java | 14 ++++++++++ .../db/migration/V4__create_friends_table.sql | 10 ++++++++ src/main/resources/templates/friends.html | 13 ++++++++++ .../makersacademy/acebook/model/UserTest.java | 22 ++++++++++++++++ 8 files changed, 83 insertions(+) create mode 100644 .DS_Store create mode 100644 src/.DS_Store create mode 100644 src/main/.DS_Store create mode 100644 src/main/resources/db/migration/V4__create_friends_table.sql create mode 100644 src/main/resources/templates/friends.html create mode 100644 src/test/java/com/makersacademy/acebook/model/UserTest.java diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..f4cc0af8dfd25621e8c446da4aff90476971adbc GIT binary patch literal 6148 zcmeHKL2KJE6n<*5#9kTXut6^a!>%RE(orb8cxigrVV8Prhiznb9Xd1D3bwNhLcr(l z$Mo7?vj4JE`#nj8*x62nF@hdEeNWQ+Wb4C{EFu!4dHjN?M??;svHcLmAB_9iH*CkW zxIm%Cm{Rd3m1j{Zqm69aU=^?m{BH{I+U-z67ZlPt)z>d?3a{b)8)fR%Yq`;)n3=VH z9nI3DC{0e3gr!49j^j3iFR#dnaWY-Nj+_KAA2iy~oEgE5jt4 z=8BNSQ>1+QkYur3jO09v3&jm|hvPc#q_?+R4i5+W-ofx_weKyDhKOGt9IjTb^W@p{ zSErM2=|v_l)mxLm{-o@Y!8`bgpf;!PL7t^DJ4ZWnx-=sRb^7!JWxBSzu{u}qb#+`i zr4wj2rnkU87;&8;o;DaQDk!J3Mi#%-`nV=*OY}CgX(-*H65n91zQVGh$M1$7s9L+X z0%lD(yZ0W+4qz3q3T&GKygztwM&DqiQEeS4)D-~OMzb=+d@wS{Gw2(vG@=J4G!>|+ z!dx+grlZ|6dA`9)qo$KEmk(i{EX)l>sHbCmPo6_iPsh#%Nl9U;keY3MOlJ>3G-60~?pAKIWwTQ@vGS-@Cej_~2`bcWd;{g>v z<87udlT0V*^8-bmJ_EdV9$isPDdijMcY?8(4@S&HR&mL!7`t`;k&LsnC_9~dRjYej z+YP_r@AzM$Z+aG$aXBse@#GWt-fNvDOFK?Jq@&rOwRfuXGEVc+#3ZD{5kfwHO!J|h z_4PC#7A7~c1AfzQ4q6BEdH1N(4i3A$MLU@Hy0G6I9xWD4fB(g+<9CDa*;TG@EcFWi zrIB5SOSpxxn$LAK$upgQg^%MsDrrOol^cBAVeD5v&=nB|gaKjTSu)`EMt|p7e!YCO zFdz*4O$K;>2%wCi!^)!BI?$LB0La%!Be2cY9~iI$7&@#h!UIt@6=+kHD>0O-9F$GR zcohB=B6%SZ76)Cl|m8^F+EWf2~TTm%da(g*|p Gl!2dMuV9G) literal 0 HcmV?d00001 diff --git a/src/main/.DS_Store b/src/main/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..3d9e7c3dcf41dfdd930f62b5de7512ccc9907549 GIT binary patch literal 6148 zcmeHKO;6iE5SJ>o<2r25tO~awr8o{Ad!A_#q)b&PjLJm*-|Xy+?R{(Q?hujcOb2^J4I=WOj1?cvGs5GnPo&~JRiNT$ ze93e_$#jA~KTzc5Gr((Cr3;GblHy0}_X%S=w?@oFmT}3f7`b)6PDWW;Oq$IbRoSS% zd0X>pUfug1{nWE)5>KW@Cmw&}-m%tMa&O1UNjjYM8t*>qd=jVmaBLFN!4M&5r)fUW zvyPtTgTmxScEIyJzt`BB&s&Gh?O?yvUTg>Rb_@2w{^4Tbd+$H&e*D_|mHp23A4|Q$ ze`#dX;XPczSkC7%8t0kLf56A_K8a+cbnZJnoml<4Gkw##ft3NPc2QYM4T7(CpY%0*EDpz7C zS2-w~j`7gNmlkb0Df4DL$Gus(3PriXLj@+BRA^CJVL%vo$iRl}Hu(HM`hWfZFiCpC zfH3f?7*N%2)a_tO?reQBIX-Ix=sA>y<4TLm6d2|xMl2u2TTmnL2W$XChowb$AaW5f LG)N;1tdxN}h38_R literal 0 HcmV?d00001 diff --git a/src/main/java/com/makersacademy/acebook/controller/UsersController.java b/src/main/java/com/makersacademy/acebook/controller/UsersController.java index a7c9db1d8..8176c4f45 100644 --- a/src/main/java/com/makersacademy/acebook/controller/UsersController.java +++ b/src/main/java/com/makersacademy/acebook/controller/UsersController.java @@ -6,8 +6,11 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.view.RedirectView; +import java.util.Set; + @RestController public class UsersController { @Autowired @@ -27,4 +30,25 @@ public RedirectView afterLogin() { return new RedirectView("/posts"); } + + @GetMapping("/users/friends") + public ModelAndView viewFriends() { + DefaultOidcUser principal = (DefaultOidcUser) SecurityContextHolder + .getContext() + .getAuthentication() + .getPrincipal(); + String username = (String) principal.getAttributes().get("email"); + + // Find the user by username + User currentUser = userRepository.findUserByUsername(username) + .orElseThrow(() -> new RuntimeException("User not found")); + + // Get friends + Set friends = currentUser.getFriends(); + + // Pass friends to the view named "friends" + ModelAndView mav = new ModelAndView("friends"); + mav.addObject("friends", friends); + return mav; + } } diff --git a/src/main/java/com/makersacademy/acebook/model/User.java b/src/main/java/com/makersacademy/acebook/model/User.java index 6013fbe23..0741d5c0d 100644 --- a/src/main/java/com/makersacademy/acebook/model/User.java +++ b/src/main/java/com/makersacademy/acebook/model/User.java @@ -3,6 +3,9 @@ import jakarta.persistence.*; import lombok.Data; +import java.util.HashSet; +import java.util.Set; + import static java.lang.Boolean.TRUE; @Data @@ -19,6 +22,17 @@ public User() { this.enabled = TRUE; } + // Join table to link user ID with friend ID + @ManyToMany + @JoinTable( + name = "friends", + joinColumns = @JoinColumn(name = "user_id"), + inverseJoinColumns = @JoinColumn(name = "friend_id") + ) + + // Using hashset to store friends to prevent duplicates and lets us do faster access/search + private Set friends = new HashSet<>(); + public User(String username) { this.username = username; this.enabled = TRUE; diff --git a/src/main/resources/db/migration/V4__create_friends_table.sql b/src/main/resources/db/migration/V4__create_friends_table.sql new file mode 100644 index 000000000..c999c5fd8 --- /dev/null +++ b/src/main/resources/db/migration/V4__create_friends_table.sql @@ -0,0 +1,10 @@ +CREATE TABLE friends ( + user_id bigint NOT NULL, + friend_id bigint NOT NULL, + PRIMARY KEY (user_id, friend_id), + + -- These constraints force the tables to use only existing user ids. + -- On delete cascade deletes friendships if either user or friend deletes their account. + CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, + CONSTRAINT fk_friend FOREIGN KEY (friend_id) REFERENCES users(id) ON DELETE CASCADE +); diff --git a/src/main/resources/templates/friends.html b/src/main/resources/templates/friends.html new file mode 100644 index 000000000..82a7fa8ac --- /dev/null +++ b/src/main/resources/templates/friends.html @@ -0,0 +1,13 @@ + + + + + Friends + + +
    +
  • +
+ + + \ No newline at end of file diff --git a/src/test/java/com/makersacademy/acebook/model/UserTest.java b/src/test/java/com/makersacademy/acebook/model/UserTest.java new file mode 100644 index 000000000..f56539abb --- /dev/null +++ b/src/test/java/com/makersacademy/acebook/model/UserTest.java @@ -0,0 +1,22 @@ +package com.makersacademy.acebook.model; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItem; + +import org.junit.jupiter.api.Test; + +public class UserTest { + + private User karen = new User("Karen", true); + private User zehad = new User("Zehad", true); + + @Test + public void checkWhoIsFriends() { + // Hashset friends table is not bidirectional, + // Both friends must be added each other + karen.getFriends().add(zehad); + zehad.getFriends().add(karen); + assertThat(karen.getFriends(), hasItem(zehad)); + assertThat(zehad.getFriends(), hasItem(karen)); + } +}