diff --git a/src/main/java/myblog/blog/article/controller/ArticleController.java b/src/main/java/myblog/blog/article/controller/ArticleController.java index 898660f..9d5b168 100644 --- a/src/main/java/myblog/blog/article/controller/ArticleController.java +++ b/src/main/java/myblog/blog/article/controller/ArticleController.java @@ -1,9 +1,40 @@ package myblog.blog.article.controller; +import lombok.RequiredArgsConstructor; +import myblog.blog.article.dto.NewArticleDto; +import myblog.blog.article.service.ArticleService; +import myblog.blog.member.auth.PrincipalDetails; +import org.springframework.security.core.Authentication; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; @Controller +@RequiredArgsConstructor public class ArticleController { + private final ArticleService articleService; + + @GetMapping("article/write") + public String writeArticleForm(NewArticleDto newArticleDto, Model model){ + + model.addAttribute(newArticleDto); + + return "articleWriteForm"; + } + + @PostMapping("article/write") + public String WriteArticle(@ModelAttribute NewArticleDto newArticleDto, Authentication authentication){ + + PrincipalDetails principal = (PrincipalDetails) authentication.getPrincipal(); + newArticleDto.setMemberId(principal.getMemberId()); + + Long articleId = articleService.writeArticle(newArticleDto); + + return "redirect:/"; + + } } diff --git a/src/main/java/myblog/blog/article/domain/Article.java b/src/main/java/myblog/blog/article/domain/Article.java index 4442226..dddc5ca 100644 --- a/src/main/java/myblog/blog/article/domain/Article.java +++ b/src/main/java/myblog/blog/article/domain/Article.java @@ -1,6 +1,8 @@ package myblog.blog.article.domain; +import lombok.Builder; import lombok.Getter; +import myblog.blog.base.domain.BasicEntity; import myblog.blog.member.doamin.Member; import javax.persistence.*; @@ -8,26 +10,37 @@ import javax.persistence.*; @Entity @Getter @SequenceGenerator( - name = "article_seq_generator", - sequenceName = "article_seq", + name = "ARTICLE_SEQ_GENERATOR", + sequenceName = "ARTICLE_SEQ", initialValue = 1, allocationSize = 50) -public class Article { +public class Article extends BasicEntity { @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "article_generator") + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ARTICLE_SEQ_GENERATOR") @Column(name = "article_id") private Long id; @Column(nullable = false) private String title; - @Column(nullable = false) + @Column(nullable = false, length = 10000) private String content; + @Column(columnDefinition = "bigint default 0",nullable = false) private Long hit; private String toc; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; + private String thumbnailUrl; + protected Article() { + } - + @Builder + public Article(String title, String content, String toc, Member member) { + this.title = title; + this.content = content; + this.toc = toc; + this.member = member; + this.hit = 0L; + } } diff --git a/src/main/java/myblog/blog/article/service/NewArticleDto.java b/src/main/java/myblog/blog/article/dto/NewArticleDto.java similarity index 64% rename from src/main/java/myblog/blog/article/service/NewArticleDto.java rename to src/main/java/myblog/blog/article/dto/NewArticleDto.java index 4b717ea..121e220 100644 --- a/src/main/java/myblog/blog/article/service/NewArticleDto.java +++ b/src/main/java/myblog/blog/article/dto/NewArticleDto.java @@ -1,10 +1,12 @@ -package myblog.blog.article.service; +package myblog.blog.article.dto; -import myblog.blog.member.doamin.Member; +import lombok.Getter; +import lombok.Setter; -import javax.persistence.*; import javax.validation.constraints.NotBlank; +@Setter +@Getter public class NewArticleDto { @NotBlank @@ -15,4 +17,7 @@ public class NewArticleDto { @NotBlank private Long memberId; + private String thumbnailUrl; + + } diff --git a/src/main/java/myblog/blog/article/service/ArticleService.java b/src/main/java/myblog/blog/article/service/ArticleService.java index 5370388..9b304d2 100644 --- a/src/main/java/myblog/blog/article/service/ArticleService.java +++ b/src/main/java/myblog/blog/article/service/ArticleService.java @@ -2,8 +2,10 @@ package myblog.blog.article.service; import lombok.RequiredArgsConstructor; import myblog.blog.article.domain.Article; +import myblog.blog.article.dto.NewArticleDto; import myblog.blog.article.repository.ArticleRepository; -import org.modelmapper.ModelMapper; +import myblog.blog.member.doamin.Member; +import myblog.blog.member.repository.MemberRepository; import org.springframework.stereotype.Service; @Service @@ -11,19 +13,27 @@ import org.springframework.stereotype.Service; public class ArticleService { private final ArticleRepository articleRepository; - private final ModelMapper modelMapper; + private final MemberRepository memberRepository; - public Long writeArticle(NewArticleDto newArticleDto){ + public Long writeArticle(NewArticleDto articleDto) { - Article article = modelMapper.map(newArticleDto, Article.class); - - articleRepository.save(article); - - return article.getId(); + Article newArticle = createNewArticleFrom(articleDto); + articleRepository.save(newArticle); + return newArticle.getId(); } + private Article createNewArticleFrom(NewArticleDto articleDto) { + Member member = + memberRepository.findById(articleDto.getMemberId()).orElseThrow(() -> { + throw new IllegalArgumentException("작성자를 확인할 수 없습니다"); + }); - - + return Article.builder() + .title(articleDto.getTitle()) + .content(articleDto.getContent()) + .toc(articleDto.getToc()) + .member(member) + .build(); + } } diff --git a/src/main/java/myblog/blog/base/config/SecurityConfig.java b/src/main/java/myblog/blog/base/config/SecurityConfig.java index a376ec5..38d2ef7 100644 --- a/src/main/java/myblog/blog/base/config/SecurityConfig.java +++ b/src/main/java/myblog/blog/base/config/SecurityConfig.java @@ -31,7 +31,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() - .antMatchers("/admin").hasRole(Role.ADMIN.name()) + .antMatchers("/article/write").hasRole(Role.ADMIN.name()) .anyRequest().permitAll() .and() diff --git a/src/main/java/myblog/blog/img/domain/UploadedImg.java b/src/main/java/myblog/blog/img/domain/UploadedImg.java new file mode 100644 index 0000000..5c6f431 --- /dev/null +++ b/src/main/java/myblog/blog/img/domain/UploadedImg.java @@ -0,0 +1,19 @@ +package myblog.blog.img.domain; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class UploadedImg { + + private String uploadFileName; + private String storeFileName; + private String uploadUrl; + + public UploadedImg(String uploadFileName, String storeFileName, String uploadUrl) { + this.uploadFileName = uploadFileName; + this.storeFileName = storeFileName; + this.uploadUrl = uploadUrl; + } +} diff --git a/src/main/java/myblog/blog/img/service/ImgService.java b/src/main/java/myblog/blog/img/service/ImgService.java new file mode 100644 index 0000000..d098cd1 --- /dev/null +++ b/src/main/java/myblog/blog/img/service/ImgService.java @@ -0,0 +1,59 @@ +package myblog.blog.img.service; + +import lombok.RequiredArgsConstructor; +import myblog.blog.img.domain.UploadedImg; +import org.kohsuke.github.GHRepository; +import org.kohsuke.github.GitHub; +import org.kohsuke.github.GitHubBuilder; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class ImgService { + + @Value("${git.gitToken}") + private String gitToken; + @Value("${git.imgRepo}") + + private String gitRepo; + @Value("${git.imgUrl}") + private String imgUrl; + + private final ModelMapper modelMapper; + + public UploadedImg storeImg(MultipartFile multipartFile) throws IOException { + if (multipartFile.isEmpty()) { + throw new IllegalArgumentException("이미지가 존재하지 않습니다."); + } + + GitHub gitHub = new GitHubBuilder().withOAuthToken(gitToken).build(); + GHRepository repository = gitHub.getRepository(gitRepo); + + String originalFilename = multipartFile.getOriginalFilename(); + String storeFileName = createStoreFileName(originalFilename); + + repository.createContent().path("img/"+storeFileName) + .content(multipartFile.getBytes()).message("test").branch("main").commit(); + + return new UploadedImg(originalFilename, storeFileName, imgUrl +storeFileName+"?raw=true"); + + } + + private String createStoreFileName(String originalFilename) { + String ext = extractExt(originalFilename); + String uuid = UUID.randomUUID().toString(); + return uuid + "." + ext; + } + + private String extractExt(String originalFilename) { + int pos = originalFilename.lastIndexOf("."); + return originalFilename.substring(pos + 1); + } + +} \ No newline at end of file diff --git a/src/main/java/myblog/blog/member/auth/PrincipalDetails.java b/src/main/java/myblog/blog/member/auth/PrincipalDetails.java index 81eda5d..75be195 100644 --- a/src/main/java/myblog/blog/member/auth/PrincipalDetails.java +++ b/src/main/java/myblog/blog/member/auth/PrincipalDetails.java @@ -23,6 +23,10 @@ public class PrincipalDetails implements OAuth2User { this.attributes = attributes; } + public Long getMemberId(){ + return member.getId(); + } + // Oauth2 @Override public Map getAttributes() { diff --git a/src/main/resources/static/css/login.css b/src/main/resources/static/css/login.css index fad7820..ee87b73 100644 --- a/src/main/resources/static/css/login.css +++ b/src/main/resources/static/css/login.css @@ -17,12 +17,15 @@ button img{ cursor: pointer; font-size: 0.9em; line-height: 1em; + font-family: 'Noto Sans C JK KR'; + font-weight: bold; padding: 0 2em 0 4em; text-decoration: none; transition: all 0.5s; height: 50px; width: 200px; margin-bottom: 5px; + } .btn-google { diff --git a/src/main/resources/static/js/editor.js b/src/main/resources/static/js/editor.js new file mode 100644 index 0000000..05ceb15 --- /dev/null +++ b/src/main/resources/static/js/editor.js @@ -0,0 +1,145 @@ + +const contents = document.getElementById("content"); + +toastui.Editor.setLanguage(['ko', 'ko-KR'], { + Markdown: '마크다운', + WYSIWYG: '일반', + Write: '편집하기', + Preview: '미리보기', + Headings: '제목크기', + Paragraph: '본문', + Bold: '굵게', + Italic: '기울임꼴', + Strike: '취소선', + Code: '인라인 코드', + Line: '문단나눔', + Blockquote: '인용구', + 'Unordered list': '글머리 기호', + 'Ordered list': '번호 매기기', + Task: '체크박스', + Indent: '들여쓰기', + Outdent: '내어쓰기', + 'Insert link': '링크 삽입', + 'Insert CodeBlock': '코드블럭 삽입', + 'Insert table': '표 삽입', + 'Insert image': '이미지 삽입', + Heading: '제목', + 'Image URL': '이미지 주소', + 'Select image file': '이미지 파일을 선택하세요.', + 'Choose a file': '파일 선택', + 'No file': '선택된 파일 없음', + Description: '설명', + OK: '확인', + More: '더 보기', + Cancel: '취소', + File: '파일', + URL: '주소', + 'Link text': '링크 텍스트', + 'Add row to up': '위에 행 추가', + 'Add row to down': '아래에 행 추가', + 'Add column to left': '왼쪽에 열 추가', + 'Add column to right': '오른쪽에 열 추가', + 'Remove row': '행 삭제', + 'Remove column': '열 삭제', + 'Align column to left': '열 왼쪽 정렬', + 'Align column to center': '열 가운데 정렬', + 'Align column to right': '열 오른쪽 정렬', + 'Remove table': '표 삭제', + 'Would you like to paste as table?': '표형태로 붙여 넣겠습니까?', + 'Text color': '글자 색상', + 'Auto scroll enabled': '자동 스크롤 켜짐', + 'Auto scroll disabled': '자동 스크롤 꺼짐', + 'Choose language': '언어 선택', +}) + +const editor = new toastui.Editor({ + el: document.querySelector('#editor'), + height: '500px', + initialEditType: 'markdown', + previewStyle: 'vertical', + language: 'ko', + toolbarItems: [ + ['heading', 'bold', 'italic', 'strike'], + ['hr'], + ['ul', 'ol'], + ['code'], + ['table', 'image', 'link'] + ], + hooks: { + addImageBlobHook: (blob, callback) => { + let imgurl = uploadImage(blob); + callback(imgurl, "첨부 이미지") + } + } +}); +const editorMobile = new toastui.Editor({ + el: document.querySelector('#editorMobile'), + height: 'auto', + language: 'ko', + initialEditType: 'wysiwyg', + previewStyle: 'tab', + toolbarItems: [ + ['heading', 'bold', 'italic', 'strike'], + ['hr'], + ['ul', 'ol'], + ['code'] + ] +}); + +editor.setMarkdown(contents.value); +editorMobile.setMarkdown(contents.value); + + +function uploadImage(blob) { + let token = getCsrfToken(); + let formData = new FormData(); + formData.append('img', blob); + + const xhr = new XMLHttpRequest(); + xhr.open("POST", "/board/uploadImg", false); + xhr.setRequestHeader("contentType", "multipart/form-data"); + xhr.setRequestHeader("X-XSRF-TOKEN", token); + xhr.send(formData); + + if (xhr.readyState === 4 && xhr.status === 200) { + return xhr.response; + } else { + alert("이미지가 정상적으로 업로드되지 못했습니다.") + } + +} + +function checkTitle() { + + let title = document.getElementById("title"); + + if (title.value === "") { + return false; + } + return true; +} + +function post() { + + if (!checkTitle()) { + alert("제목을 입력해주세요") + return; + } + + + contents.value = editor.getMarkdown(); + document.getElementById("writeArticleForm").submit(); + +} + +function postMobile() { + + if (!checkTitle()) { + alert("제목을 입력해주세요") + return; + } + + contents.value = editorMobile.getMarkdown(); + document.getElementById("writeArticleForm").submit(); + +} diff --git a/src/main/resources/static/package-lock.json b/src/main/resources/static/package-lock.json index 99fe35a..1cfc7fd 100644 --- a/src/main/resources/static/package-lock.json +++ b/src/main/resources/static/package-lock.json @@ -1,27 +1,121 @@ { "name": "static", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "bootstrap": "^5.1.3" + "dependencies": { + "@toast-ui/editor": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@toast-ui/editor/-/editor-3.1.1.tgz", + "integrity": "sha512-9Js9+qpg6rMlPZjJLf96sFd87Wm+rc3N+CqQ4RWuqNvpYQLE/YifXHlJkaLIZTpYx40L08gkv205xKq6Ifa9TQ==", + "requires": { + "dompurify": "^2.3.3", + "prosemirror-commands": "^1.1.9", + "prosemirror-history": "^1.1.3", + "prosemirror-inputrules": "^1.1.3", + "prosemirror-keymap": "^1.1.4", + "prosemirror-model": "^1.14.1", + "prosemirror-state": "^1.3.4", + "prosemirror-view": "^1.18.7" } }, - "node_modules/bootstrap": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz", - "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==" - } - }, - "dependencies": { "bootstrap": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz", "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==" + }, + "dompurify": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.3.tgz", + "integrity": "sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg==" + }, + "orderedmap": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-1.1.1.tgz", + "integrity": "sha512-3Ux8um0zXbVacKUkcytc0u3HgC0b0bBLT+I60r2J/En72cI0nZffqrA7Xtf2Hqs27j1g82llR5Mhbd0Z1XW4AQ==" + }, + "prosemirror-commands": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.1.12.tgz", + "integrity": "sha512-+CrMs3w/ZVPSkR+REg8KL/clyFLv/1+SgY/OMN+CB22Z24j9TZDje72vL36lOZ/E4NeRXuiCcmENcW/vAcG67A==", + "requires": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "prosemirror-history": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.2.0.tgz", + "integrity": "sha512-B9v9xtf4fYbKxQwIr+3wtTDNLDZcmMMmGiI3TAPShnUzvo+Rmv1GiUrsQChY1meetHl7rhML2cppF3FTs7f7UQ==", + "requires": { + "prosemirror-state": "^1.2.2", + "prosemirror-transform": "^1.0.0", + "rope-sequence": "^1.3.0" + } + }, + "prosemirror-inputrules": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.1.3.tgz", + "integrity": "sha512-ZaHCLyBtvbyIHv0f5p6boQTIJjlD6o2NPZiEaZWT2DA+j591zS29QQEMT4lBqwcLW3qRSf7ZvoKNbf05YrsStw==", + "requires": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "prosemirror-keymap": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.1.5.tgz", + "integrity": "sha512-8SZgPH3K+GLsHL2wKuwBD9rxhsbnVBTwpHCO4VUO5GmqUQlxd/2GtBVWTsyLq4Dp3N9nGgPd3+lZFKUDuVp+Vw==", + "requires": { + "prosemirror-state": "^1.0.0", + "w3c-keyname": "^2.2.0" + } + }, + "prosemirror-model": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.15.0.tgz", + "integrity": "sha512-hQJv7SnIhlAy9ga3lhPPgaufhvCbQB9tHwscJ9E1H1pPHmN8w5V/lURueoYv9Kc3/bpNWoyHa8r3g//m7N0ChQ==", + "requires": { + "orderedmap": "^1.1.0" + } + }, + "prosemirror-state": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.3.4.tgz", + "integrity": "sha512-Xkkrpd1y/TQ6HKzN3agsQIGRcLckUMA9u3j207L04mt8ToRgpGeyhbVv0HI7omDORIBHjR29b7AwlATFFf2GLA==", + "requires": { + "prosemirror-model": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "prosemirror-transform": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.3.3.tgz", + "integrity": "sha512-9NLVXy1Sfa2G6qPqhWMkEvwQQMTw7OyTqOZbJaGQWsCeH3hH5Cw+c5eNaLM1Uu75EyKLsEZhJ93XpHJBa6RX8A==", + "requires": { + "prosemirror-model": "^1.0.0" + } + }, + "prosemirror-view": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.21.0.tgz", + "integrity": "sha512-Pjh0vXw/l2Ifc3QcBVKJ/qHej33MX4sdq4/uAVqkSmHLf//bVWTYSZibihMya3lsIxTbDzNl/Z03KrhXWMHaoA==", + "requires": { + "prosemirror-model": "^1.14.3", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" + } + }, + "rope-sequence": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.2.tgz", + "integrity": "sha512-ku6MFrwEVSVmXLvy3dYph3LAMNS0890K7fabn+0YIRQ2T96T9F4gkFf0vf0WW0JUraNWwGRtInEpH7yO4tbQZg==" + }, + "w3c-keyname": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz", + "integrity": "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==" } } } diff --git a/src/main/resources/static/package.json b/src/main/resources/static/package.json index cf67cec..1815dd1 100644 --- a/src/main/resources/static/package.json +++ b/src/main/resources/static/package.json @@ -9,6 +9,7 @@ "author": "", "license": "ISC", "dependencies": { + "@toast-ui/editor": "^3.1.1", "bootstrap": "^5.1.3" } } diff --git a/src/main/resources/templates/articleWriteForm.html b/src/main/resources/templates/articleWriteForm.html new file mode 100644 index 0000000..0ebdbfd --- /dev/null +++ b/src/main/resources/templates/articleWriteForm.html @@ -0,0 +1,95 @@ + + + + + + + Jinia's Log - 글 작성 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + +
+ +
+
+
+
+
+
+
+ +
+ + + +
+
+ + + + + +
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/layout/layout.html b/src/main/resources/templates/layout/layout.html index 328a576..1392dc6 100644 --- a/src/main/resources/templates/layout/layout.html +++ b/src/main/resources/templates/layout/layout.html @@ -1,58 +1,21 @@ - - - - - Jinia's Log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
@@ -106,6 +70,7 @@
  • 카테고리1
  • 카테고리2
  • 카테고리3
  • +
  • @@ -118,6 +83,7 @@
  • 카테고리1
  • 카테고리2
  • 카테고리3
  • +
  • @@ -130,6 +96,7 @@
  • 카테고리1
  • 카테고리2
  • 카테고리3
  • +
  • @@ -206,6 +173,7 @@
  • 카테고리1
  • 카테고리2
  • 카테고리3
  • +
  • @@ -218,6 +186,7 @@
  • 카테고리1
  • 카테고리2
  • 카테고리3
  • +
  • @@ -230,6 +199,7 @@
  • 카테고리1
  • 카테고리2
  • 카테고리3
  • +
  • @@ -270,6 +240,14 @@
    + + + + + +
    @@ -277,18 +255,11 @@
    Copyright ©Jinia
    + - - - - - - diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index 917727c..ab187b7 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -1,22 +1,58 @@ - + + Jinia's Log - 로그인 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    -
    +
    -
    +

    로그인 오류

    + -

    로그인 오류

    -
    +
    -
    +
    diff --git a/src/main/resources/templates/main.html b/src/main/resources/templates/main.html index b500cea..6568d51 100644 --- a/src/main/resources/templates/main.html +++ b/src/main/resources/templates/main.html @@ -1,12 +1,48 @@ - + + Jinia's Log - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/src/test/java/myblog/blog/article/service/ArticleServiceTest.java b/src/test/java/myblog/blog/article/service/ArticleServiceTest.java new file mode 100644 index 0000000..ab1fb41 --- /dev/null +++ b/src/test/java/myblog/blog/article/service/ArticleServiceTest.java @@ -0,0 +1,47 @@ +package myblog.blog.article.service; + +import myblog.blog.article.dto.NewArticleDto; +import myblog.blog.article.repository.ArticleRepository; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.Rollback; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; + + +@SpringBootTest +@Transactional +@Rollback(value = false) +class ArticleServiceTest { + + @Autowired + ArticleService articleService; + @Autowired + ArticleRepository articleRepository; + @Autowired + EntityManager entityManager; + + @Test + public void 게시글테스트() throws Exception { + // given + NewArticleDto newArticleDto = new NewArticleDto(); + newArticleDto.setTitle("abs"); + newArticleDto.setMemberId(1L); + newArticleDto.setToc("df"); + newArticleDto.setContent("sdfsf"); + + // when + Long articleId = articleService.writeArticle(newArticleDto); + + // then + + + System.out.println(articleRepository.findById(articleId).get().getContent()); + + } + + +} \ No newline at end of file