Change repository
-
- Repository Location (Org/Repo)
-
-
-
- {{suggestion}}
-
-
-
+
diff --git a/src/app/shared/repo-change-form/repo-change-form.component.ts b/src/app/shared/repo-change-form/repo-change-form.component.ts
index 86580870e..14db27458 100644
--- a/src/app/shared/repo-change-form/repo-change-form.component.ts
+++ b/src/app/shared/repo-change-form/repo-change-form.component.ts
@@ -2,7 +2,7 @@ import { Component, Inject, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Observable } from 'rxjs';
-import { map, startWith } from 'rxjs/operators';
+import { RepoUrlCacheService } from '../../core/services/repo-url-cache.service';
@Component({
selector: 'app-repo-change-form',
@@ -11,11 +11,14 @@ import { map, startWith } from 'rxjs/operators';
})
export class RepoChangeFormComponent implements OnInit {
public repoName: String;
- suggestions: string[];
filteredSuggestions: Observable;
repoChangeForm = new FormControl();
- constructor(public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data) {
+ constructor(
+ public dialogRef: MatDialogRef,
+ private repoUrlCacheService: RepoUrlCacheService,
+ @Inject(MAT_DIALOG_DATA) public data
+ ) {
this.repoName = data.repoName;
}
@@ -24,14 +27,9 @@ export class RepoChangeFormComponent implements OnInit {
}
private initRepoChangeForm() {
- this.suggestions = JSON.parse(window.localStorage.getItem('suggestions')) || [];
- // Ref: https://v10.material.angular.io/components/autocomplete/overview
- this.filteredSuggestions = this.repoChangeForm.valueChanges
- .pipe(
- startWith(''),
- map(value => this.suggestions.filter(suggestion => suggestion.toLowerCase().includes(value.toLowerCase())))
- );
+ this.filteredSuggestions = this.repoUrlCacheService.getFilteredSuggestions(this.repoChangeForm);
}
+
onYesClick(): void {
this.dialogRef.close(this.repoName);
}
diff --git a/src/markdown.css b/src/markdown.css
deleted file mode 100644
index a4454ff01..000000000
--- a/src/markdown.css
+++ /dev/null
@@ -1,696 +0,0 @@
-@font-face {
- font-family: octicons-link;
- src: url(data:font/woff;charset=utf-8;base64,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)
- format('woff');
-}
-
-markdown {
- -ms-text-size-adjust: 100%;
- -webkit-text-size-adjust: 100%;
- line-height: 1.5;
- color: #24292e;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
- 'Segoe UI Symbol';
- font-size: 16px;
- word-wrap: break-word;
-}
-
-markdown .pl-c {
- color: #6a737d;
-}
-
-markdown .pl-c1,
-markdown .pl-s .pl-v {
- color: #005cc5;
-}
-
-markdown .pl-e,
-markdown .pl-en {
- color: #6f42c1;
-}
-
-markdown .pl-smi,
-markdown .pl-s .pl-s1 {
- color: #24292e;
-}
-
-markdown .pl-ent {
- color: #22863a;
-}
-
-markdown .pl-k {
- color: #d73a49;
-}
-
-markdown .pl-s,
-markdown .pl-pds,
-markdown .pl-s .pl-pse .pl-s1,
-markdown .pl-sr,
-markdown .pl-sr .pl-cce,
-markdown .pl-sr .pl-sre,
-markdown .pl-sr .pl-sra {
- color: #032f62;
-}
-
-markdown .pl-v,
-markdown .pl-smw {
- color: #e36209;
-}
-
-markdown .pl-bu {
- color: #b31d28;
-}
-
-markdown .pl-ii {
- color: #fafbfc;
- background-color: #b31d28;
-}
-
-markdown .pl-c2 {
- color: #fafbfc;
- background-color: #d73a49;
-}
-
-markdown .pl-c2::before {
- content: '^M';
-}
-
-markdown .pl-sr .pl-cce {
- font-weight: bold;
- color: #22863a;
-}
-
-markdown .pl-ml {
- color: #735c0f;
-}
-
-markdown .pl-mh,
-markdown .pl-mh .pl-en,
-markdown .pl-ms {
- font-weight: bold;
- color: #005cc5;
-}
-
-markdown .pl-mi {
- font-style: italic;
- color: #24292e;
-}
-
-markdown .pl-mb {
- font-weight: bold;
- color: #24292e;
-}
-
-markdown .pl-md {
- color: #b31d28;
- background-color: #ffeef0;
-}
-
-markdown .pl-mi1 {
- color: #22863a;
- background-color: #f0fff4;
-}
-
-markdown .pl-mc {
- color: #e36209;
- background-color: #ffebda;
-}
-
-markdown .pl-mi2 {
- color: #f6f8fa;
- background-color: #005cc5;
-}
-
-markdown .pl-mdr {
- font-weight: bold;
- color: #6f42c1;
-}
-
-markdown .pl-ba {
- color: #586069;
-}
-
-markdown .pl-sg {
- color: #959da5;
-}
-
-markdown .pl-corl {
- text-decoration: underline;
- color: #032f62;
-}
-
-markdown .octicon {
- display: inline-block;
- vertical-align: text-top;
- fill: currentColor;
-}
-
-markdown a {
- background-color: transparent;
-}
-
-markdown a:active,
-markdown a:hover {
- outline-width: 0;
-}
-
-markdown strong {
- font-weight: inherit;
-}
-
-markdown strong {
- font-weight: bolder;
-}
-
-markdown h1 {
- font-size: 2em;
- margin: 0.67em 0;
-}
-
-markdown img {
- border-style: none;
-}
-
-markdown code,
-markdown kbd,
-markdown pre {
- font-family: monospace, monospace;
- font-size: 1em;
-}
-
-markdown hr {
- box-sizing: content-box;
- height: 0;
- overflow: visible;
-}
-
-markdown input {
- font: inherit;
- margin: 0;
-}
-
-markdown input {
- overflow: visible;
-}
-
-markdown [type='checkbox'] {
- box-sizing: border-box;
- padding: 0;
-}
-
-markdown * {
- box-sizing: border-box;
-}
-
-markdown input {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
-}
-
-markdown a {
- color: #0366d6;
- text-decoration: none;
-}
-
-markdown a:hover {
- text-decoration: underline;
-}
-
-markdown strong {
- font-weight: 600;
-}
-
-markdown hr {
- height: 0;
- margin: 15px 0;
- overflow: hidden;
- background: transparent;
- border: 0;
- border-bottom: 1px solid #dfe2e5;
-}
-
-markdown hr::before {
- display: table;
- content: '';
-}
-
-markdown hr::after {
- display: table;
- clear: both;
- content: '';
-}
-
-markdown table {
- border-spacing: 0;
- border-collapse: collapse;
-}
-
-markdown td,
-markdown th {
- padding: 0;
-}
-
-markdown h1,
-markdown h2,
-markdown h3,
-markdown h4,
-markdown h5,
-markdown h6 {
- margin-top: 0;
- margin-bottom: 0;
-}
-
-markdown h1 {
- font-size: 32px;
- font-weight: 600;
-}
-
-markdown h2 {
- font-size: 24px;
- font-weight: 600;
-}
-
-markdown h3 {
- font-size: 20px;
- font-weight: 600;
-}
-
-markdown h4 {
- font-size: 16px;
- font-weight: 600;
-}
-
-markdown h5 {
- font-size: 14px;
- font-weight: 600;
-}
-
-markdown h6 {
- font-size: 12px;
- font-weight: 600;
-}
-
-markdown p {
- margin-top: 0;
- margin-bottom: 10px;
-}
-
-markdown blockquote {
- margin: 0;
-}
-
-markdown ul,
-markdown ol {
- padding-left: 0;
- margin-top: 0;
- margin-bottom: 0;
-}
-
-markdown ol ol,
-markdown ul ol {
- list-style-type: lower-roman;
-}
-
-markdown ul ul ol,
-markdown ul ol ol,
-markdown ol ul ol,
-markdown ol ol ol {
- list-style-type: lower-alpha;
-}
-
-markdown dd {
- margin-left: 0;
-}
-
-markdown code {
- font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
- font-size: 12px;
-}
-
-markdown pre {
- margin-top: 0;
- margin-bottom: 0;
- font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
- font-size: 12px;
-}
-
-markdown .octicon {
- vertical-align: text-bottom;
-}
-
-markdown .pl-0 {
- padding-left: 0 !important;
-}
-
-markdown .pl-1 {
- padding-left: 4px !important;
-}
-
-markdown .pl-2 {
- padding-left: 8px !important;
-}
-
-markdown .pl-3 {
- padding-left: 16px !important;
-}
-
-markdown .pl-4 {
- padding-left: 24px !important;
-}
-
-markdown .pl-5 {
- padding-left: 32px !important;
-}
-
-markdown .pl-6 {
- padding-left: 40px !important;
-}
-
-markdown::before {
- display: table;
- content: '';
-}
-
-markdown::after {
- display: table;
- clear: both;
- content: '';
-}
-
-markdown > *:first-child {
- margin-top: 0 !important;
-}
-
-markdown > *:last-child {
- margin-bottom: 0 !important;
-}
-
-markdown a:not([href]) {
- color: inherit;
- text-decoration: none;
-}
-
-markdown .anchor {
- float: left;
- padding-right: 4px;
- margin-left: -20px;
- line-height: 1;
-}
-
-markdown .anchor:focus {
- outline: none;
-}
-
-markdown p,
-markdown blockquote,
-markdown ul,
-markdown ol,
-markdown dl,
-markdown table,
-markdown pre {
- margin-top: 0;
- margin-bottom: 16px;
-}
-
-markdown hr {
- height: 0.25em;
- padding: 0;
- margin: 24px 0;
- background-color: #e1e4e8;
- border: 0;
-}
-
-markdown blockquote {
- padding: 0 1em;
- color: #6a737d;
- border-left: 0.25em solid #dfe2e5;
-}
-
-markdown blockquote > :first-child {
- margin-top: 0;
-}
-
-markdown blockquote > :last-child {
- margin-bottom: 0;
-}
-
-markdown kbd {
- display: inline-block;
- padding: 3px 5px;
- font-size: 11px;
- line-height: 10px;
- color: #444d56;
- vertical-align: middle;
- background-color: #fafbfc;
- border: solid 1px #c6cbd1;
- border-bottom-color: #959da5;
- border-radius: 3px;
- box-shadow: inset 0 -1px 0 #959da5;
-}
-
-markdown h1,
-markdown h2,
-markdown h3,
-markdown h4,
-markdown h5,
-markdown h6 {
- margin-top: 24px;
- margin-bottom: 16px;
- font-weight: 600;
- line-height: 1.25;
-}
-
-markdown h1 .octicon-link,
-markdown h2 .octicon-link,
-markdown h3 .octicon-link,
-markdown h4 .octicon-link,
-markdown h5 .octicon-link,
-markdown h6 .octicon-link {
- color: #1b1f23;
- vertical-align: middle;
- visibility: hidden;
-}
-
-markdown h1:hover .anchor,
-markdown h2:hover .anchor,
-markdown h3:hover .anchor,
-markdown h4:hover .anchor,
-markdown h5:hover .anchor,
-markdown h6:hover .anchor {
- text-decoration: none;
-}
-
-markdown h1:hover .anchor .octicon-link,
-markdown h2:hover .anchor .octicon-link,
-markdown h3:hover .anchor .octicon-link,
-markdown h4:hover .anchor .octicon-link,
-markdown h5:hover .anchor .octicon-link,
-markdown h6:hover .anchor .octicon-link {
- visibility: visible;
-}
-
-markdown h1 {
- padding-bottom: 0.3em;
- font-size: 2em;
- border-bottom: 1px solid #eaecef;
-}
-
-markdown h2 {
- padding-bottom: 0.3em;
- font-size: 1.5em;
- border-bottom: 1px solid #eaecef;
-}
-
-markdown h3 {
- font-size: 1.25em;
-}
-
-markdown h4 {
- font-size: 1em;
-}
-
-markdown h5 {
- font-size: 0.875em;
-}
-
-markdown h6 {
- font-size: 0.85em;
- color: #6a737d;
-}
-
-markdown ul,
-markdown ol {
- padding-left: 2em;
-}
-
-markdown ul ul,
-markdown ul ol,
-markdown ol ol,
-markdown ol ul {
- margin-top: 0;
- margin-bottom: 0;
-}
-
-markdown li {
- word-wrap: break-all;
-}
-
-markdown li > p {
- margin-top: 16px;
-}
-
-markdown li + li {
- margin-top: 0.25em;
-}
-
-markdown dl {
- padding: 0;
-}
-
-markdown dl dt {
- padding: 0;
- margin-top: 16px;
- font-size: 1em;
- font-style: italic;
- font-weight: 600;
-}
-
-markdown dl dd {
- padding: 0 16px;
- margin-bottom: 16px;
-}
-
-markdown table {
- display: block;
- width: 100%;
- overflow: auto;
-}
-
-markdown table th {
- font-weight: 600;
-}
-
-markdown table th,
-markdown table td {
- padding: 6px 13px;
- border: 1px solid #dfe2e5;
-}
-
-markdown table tr {
- background-color: #fff;
- border-top: 1px solid #c6cbd1;
-}
-
-markdown table tr:nth-child(2n) {
- background-color: #f6f8fa;
-}
-
-markdown img {
- max-width: 100%;
- box-sizing: content-box;
- background-color: #fff;
-}
-
-markdown img[align='right'] {
- padding-left: 20px;
-}
-
-markdown img[align='left'] {
- padding-right: 20px;
-}
-
-markdown code {
- padding: 0.2em 0.4em;
- margin: 0;
- font-size: 85%;
- background-color: rgba(27, 31, 35, 0.05);
- border-radius: 3px;
-}
-
-markdown pre {
- word-wrap: normal;
-}
-
-markdown pre > code {
- padding: 0;
- margin: 0;
- font-size: 100%;
- word-break: normal;
- white-space: pre;
- background: transparent;
- border: 0;
-}
-
-markdown .highlight {
- margin-bottom: 16px;
-}
-
-markdown .highlight pre {
- margin-bottom: 0;
- word-break: normal;
-}
-
-markdown .highlight pre,
-markdown pre {
- padding: 16px;
- overflow: auto;
- font-size: 85%;
- line-height: 1.45;
- background-color: #f6f8fa;
- border-radius: 3px;
-}
-
-markdown pre code {
- display: inline;
- max-width: auto;
- padding: 0;
- margin: 0;
- overflow: visible;
- line-height: inherit;
- word-wrap: normal;
- background-color: transparent;
- border: 0;
-}
-
-markdown .full-commit .btn-outline:not(:disabled):hover {
- color: #005cc5;
- border-color: #005cc5;
-}
-
-markdown kbd {
- display: inline-block;
- padding: 3px 5px;
- font: 11px 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
- line-height: 10px;
- color: #444d56;
- vertical-align: middle;
- background-color: #fafbfc;
- border: solid 1px #d1d5da;
- border-bottom-color: #c6cbd1;
- border-radius: 3px;
- box-shadow: inset 0 -1px 0 #c6cbd1;
-}
-
-markdown :checked + .radio-label {
- position: relative;
- z-index: 1;
- border-color: #0366d6;
-}
-
-markdown .task-list-item {
- list-style-type: none;
-}
-
-markdown .task-list-item + .task-list-item {
- margin-top: 3px;
-}
-
-markdown .task-list-item input {
- margin: 0 0.2em 0.25em -1.6em;
- vertical-align: middle;
-}
-
-markdown hr {
- border-bottom-color: #eee;
-}
diff --git a/src/typings.d.ts b/src/typings.d.ts
index 78708ff3e..6f504bd8c 100644
--- a/src/typings.d.ts
+++ b/src/typings.d.ts
@@ -4,7 +4,7 @@ interface NodeModule {
id: string;
}
-declare var window: Window;
+declare var window: Window & typeof globalThis;
interface Window {
process: any;
require: any;
diff --git a/tests/app/shared/lib/marked.spec.ts b/tests/app/shared/lib/marked.spec.ts
deleted file mode 100644
index 448bf32a3..000000000
--- a/tests/app/shared/lib/marked.spec.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { MarkedOptions, MarkedRenderer } from 'ngx-markdown';
-import { markedOptionsFactory } from '../../../../src/app/shared/lib/marked';
-
-describe('markedOptionsFactory', () => {
- const markedOptions: MarkedOptions = markedOptionsFactory();
- const renderer: MarkedRenderer = markedOptions.renderer;
-
- const CUSTOM_LINK = 'www.google.com';
- const CUSTOM_TITLE = 'google';
- const CUSTOM_TEXT = 'link here';
-
- it('should append all links with target=_blank', () => {
- const htmlOutput: string = renderer.link(CUSTOM_LINK, CUSTOM_TITLE, CUSTOM_TEXT);
- expect(htmlOutput).toContain('target="_blank"');
- });
-});
diff --git a/tests/model/checkbox.model.spec.ts b/tests/model/checkbox.model.spec.ts
deleted file mode 100644
index 1b8339394..000000000
--- a/tests/model/checkbox.model.spec.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Checkbox } from '../../src/app/core/models/checkbox.model';
-
-const EXPECTED_CHECKED_STRING = '- [x] todo';
-const EXPECTED_UNCHECKED_STRING = '- [ ] todo';
-
-describe('Checkbox', () => {
- it('.setChecked() sets the correct isChecked value', () => {
- const checkbox = new Checkbox('todo', false);
- checkbox.setChecked(true);
- expect(checkbox.isChecked).toBe(true);
- });
-
- it('formats the correct toString value', () => {
- const falseCheckbox = new Checkbox('todo', false);
- const trueCheckbox = new Checkbox('todo', true);
-
- expect(falseCheckbox.toString()).toBe(EXPECTED_UNCHECKED_STRING);
- expect(trueCheckbox.toString()).toBe(EXPECTED_CHECKED_STRING);
- });
-});
diff --git a/tests/model/templates/sections/issue-dispute-section-parser.model.spec.ts b/tests/model/templates/sections/issue-dispute-section-parser.model.spec.ts
deleted file mode 100644
index c137ab3aa..000000000
--- a/tests/model/templates/sections/issue-dispute-section-parser.model.spec.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { IssueDisputeSectionParser } from '../../../../src/app/core/models/templates/sections/issue-dispute-section-parser.model';
-
-const TYPE_DISPUTE =
- '## :question: Issue Type\n\n' +
- '### Team says:\n\n' +
- "{the team's action that is being disputed}\n\n" +
- '### Tester says:\n\n' +
- "{tester's objection}\n\n" +
- '-------------------';
-
-const EXPECTED_TITLE = 'Issue Type';
-const EXPECTED_DESCRIPTION =
- '### Team says:\n\n' + "{the team's action that is being disputed}\n\n" + '### Tester says:\n\n' + "{tester's objection}";
-
-describe('IssueDisputeSectionParser', () => {
- it('parses type dispute correctly', () => {
- const result = IssueDisputeSectionParser.run(TYPE_DISPUTE).result;
-
- expect(result.title).toBe(EXPECTED_TITLE);
- expect(result.description).toBe(EXPECTED_DESCRIPTION);
- });
-});
diff --git a/tests/model/templates/sections/moderation-section-parser.model.spec.ts b/tests/model/templates/sections/moderation-section-parser.model.spec.ts
deleted file mode 100644
index 1e03e2243..000000000
--- a/tests/model/templates/sections/moderation-section-parser.model.spec.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import {
- DoneCheckboxParser,
- ModerationSectionParser
-} from '../../../../src/app/core/models/templates/sections/moderation-section-parser.model';
-
-const TYPE_DISPUTE = '## :question: Issue Type\n\n' + '- [ ] Done\n\n' + '[replace this with your explanation]\n\n' + '-------------------';
-
-const EMPTY_DONE_CHECKBOX = '- [ ] Done';
-const FILLED_DONE_CHECKBOX = '- [x] Done';
-
-const EXPECTED_TITLE = 'Issue Type';
-const EXPECTED_DESCRIPTION = '- [ ] Done\n\n[replace this with your explanation]';
-const EXPECTED_TUTOR_RESPONSE = '[replace this with your explanation]';
-
-describe('DoneCheckboxParser', () => {
- it('parses empty checkbox correctly', () => {
- const result = DoneCheckboxParser.run(EMPTY_DONE_CHECKBOX).result;
-
- expect(result).toBe(false);
- });
- it('parses filled checkbox correctly', () => {
- const result = DoneCheckboxParser.run(FILLED_DONE_CHECKBOX).result;
-
- expect(result).toBe(true);
- });
-});
-
-describe('ModerationSectionParser', () => {
- it('parses type dispute correctly', () => {
- const result = ModerationSectionParser.run(TYPE_DISPUTE).result;
-
- expect(result.title).toBe(EXPECTED_TITLE);
- expect(result.description).toBe(EXPECTED_DESCRIPTION);
- expect(result.todo.isChecked).toBe(false);
- expect(result.tutorResponse).toBe(EXPECTED_TUTOR_RESPONSE);
- });
-});
diff --git a/tests/model/templates/sections/tester-response-section-parser.model.spec.ts b/tests/model/templates/sections/tester-response-section-parser.model.spec.ts
deleted file mode 100644
index a9e0e9a23..000000000
--- a/tests/model/templates/sections/tester-response-section-parser.model.spec.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import {
- DisagreeCheckboxParser,
- TesterResponseSectionParser
-} from '../../../../src/app/core/models/templates/sections/tester-response-section-parser.model';
-
-const EMPTY_DISAGREE_CHECKBOX = '- [ ] I disagree';
-const FILLED_DISAGREE_CHECKBOX = '- [x] I disagree';
-const DEFAULT_DISAGREEMENT_REASON = '[replace this with your reason]';
-const USER_DISAGREEMENT_REASON = 'I disagree!';
-
-const RESPONSE_TITLE = 'response';
-const RESPONSE_DESCRIPTION = 'Team chose [`response.Rejected`]';
-const RESPONSE_TEAM_CHOSE = 'Rejected';
-
-const SEVERITY_TITLE = 'severity';
-const SEVERITY_DESCRIPTION = 'Team chose [`severity.Low`]\nOriginally [`severity.High`]';
-const SEVERITY_TEAM_CHOSE = 'Low';
-const SEVERITY_TESTER_CHOSE = 'High';
-
-const TYPE_TITLE = 'type';
-const TYPE_DESCRIPTION = 'Team chose [`type.DocumentationBug`]\nOriginally [`type.FunctionalityBug`]';
-const TYPE_TEAM_CHOSE = 'DocumentationBug';
-const TYPE_TESTER_CHOSE = 'FunctionalityBug';
-
-const DUPLICATE_TITLE = 'duplicate status';
-const DUPLICATE_DESCRIPTION =
- "Team chose to mark this issue as a duplicate of another issue (as explained in the _**Team's response**_ above)";
-
-export const RESPONSE_DISAGREEMENT =
- '## :question: Issue response\n\n' +
- 'Team chose [`response.Rejected`]\n\n' +
- '- [ ] I disagree\n\n' +
- '**Reason for disagreement:** [replace this with your reason]\n\n' +
- '-------------------';
-
-export const SEVERITY_DISAGREEMENT =
- '## :question: Issue severity\n\n' +
- 'Team chose [`severity.Low`]\n' +
- 'Originally [`severity.High`]\n\n' +
- '- [x] I disagree\n\n' +
- '**Reason for disagreement:** I disagree!\n\n' +
- '-------------------';
-
-export const TYPE_DISAGREEMENT =
- '## :question: Issue type\n\n' +
- 'Team chose [`type.DocumentationBug`]\n' +
- 'Originally [`type.FunctionalityBug`]\n\n' +
- '- [ ] I disagree\n\n' +
- '**Reason for disagreement:** [replace this with your reason]\n\n' +
- '-------------------';
-
-export const DUPLICATE_DISAGREEMENT =
- '## :question: Issue duplicate status\n\n' +
- "Team chose to mark this issue as a duplicate of another issue (as explained in the _**Team's response**_ above)\n\n" +
- '- [ ] I disagree\n\n' +
- '**Reason for disagreement:** [replace this with your reason]\n\n' +
- '-------------------';
-
-describe('DisagreeCheckboxParser', () => {
- it('parses empty checkbox correctly', () => {
- const result = DisagreeCheckboxParser.run(EMPTY_DISAGREE_CHECKBOX).result;
-
- expect(result).toBe(false);
- });
- it('parses filled checkbox correctly', () => {
- const result = DisagreeCheckboxParser.run(FILLED_DISAGREE_CHECKBOX).result;
-
- expect(result).toBe(true);
- });
-});
-
-describe('TesterResponseSectionParser', () => {
- it('parses response disagreement correctly', () => {
- const result = TesterResponseSectionParser.run(RESPONSE_DISAGREEMENT).result;
-
- expect(result.title).toBe(RESPONSE_TITLE);
- expect(result.description).toBe(RESPONSE_DESCRIPTION);
- expect(result.teamChose).toBe(RESPONSE_TEAM_CHOSE);
- expect(result.testerChose).toBe(null);
- expect(result.disagreeCheckboxValue).toBe(false);
- expect(result.reasonForDisagreement).toBe(DEFAULT_DISAGREEMENT_REASON);
- });
- it('parses severity disagreement correctly', () => {
- const result = TesterResponseSectionParser.run(SEVERITY_DISAGREEMENT).result;
-
- expect(result.title).toBe(SEVERITY_TITLE);
- expect(result.description).toBe(SEVERITY_DESCRIPTION);
- expect(result.teamChose).toBe(SEVERITY_TEAM_CHOSE);
- expect(result.testerChose).toBe(SEVERITY_TESTER_CHOSE);
- expect(result.disagreeCheckboxValue).toBe(true);
- expect(result.reasonForDisagreement).toBe(USER_DISAGREEMENT_REASON);
- });
- it('parses type disagreement correctly', () => {
- const result = TesterResponseSectionParser.run(TYPE_DISAGREEMENT).result;
-
- expect(result.title).toBe(TYPE_TITLE);
- expect(result.description).toBe(TYPE_DESCRIPTION);
- expect(result.teamChose).toBe(TYPE_TEAM_CHOSE);
- expect(result.testerChose).toBe(TYPE_TESTER_CHOSE);
- expect(result.disagreeCheckboxValue).toBe(false);
- expect(result.reasonForDisagreement).toBe(DEFAULT_DISAGREEMENT_REASON);
- });
- it('parses duplicate status disagreement correctly', () => {
- const result = TesterResponseSectionParser.run(DUPLICATE_DISAGREEMENT).result;
-
- expect(result.title).toBe(DUPLICATE_TITLE);
- expect(result.description).toBe(DUPLICATE_DESCRIPTION);
- expect(result.teamChose).toBe(null);
- expect(result.testerChose).toBe(null);
- expect(result.disagreeCheckboxValue).toBe(false);
- expect(result.reasonForDisagreement).toBe(DEFAULT_DISAGREEMENT_REASON);
- });
-});
diff --git a/tests/model/templates/team-accepted-template.model.spec.ts b/tests/model/templates/team-accepted-template.model.spec.ts
deleted file mode 100644
index d87f08aad..000000000
--- a/tests/model/templates/team-accepted-template.model.spec.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { GithubComment } from '../../../src/app/core/models/github/github-comment.model';
-import { TeamAcceptedMessage, TeamAcceptedTemplate } from '../../../src/app/core/models/templates/team-accepted-template.model';
-
-import { TEAM_RESPONSE_MULTIPLE_DISAGREEMENT } from '../../constants/githubcomment.constants';
-
-const EMPTY_BODY_GITHUB_COMMENT = {
- body: ''
-} as GithubComment;
-
-const ACCEPTED_MESSAGE_GITHUB_COMMENT = {
- body: TeamAcceptedMessage
-} as GithubComment;
-
-const hasAcceptedComment = [EMPTY_BODY_GITHUB_COMMENT, ACCEPTED_MESSAGE_GITHUB_COMMENT];
-const noAcceptedComment = [EMPTY_BODY_GITHUB_COMMENT, TEAM_RESPONSE_MULTIPLE_DISAGREEMENT];
-
-describe('TeamAcceptedTemplate class', () => {
- it('parses team accepted message correctly', () => {
- const template = new TeamAcceptedTemplate([ACCEPTED_MESSAGE_GITHUB_COMMENT]);
-
- expect(template.teamAccepted).toBe(true);
- });
- it('finds team accepted comment correctly', () => {
- const template = new TeamAcceptedTemplate(hasAcceptedComment);
-
- expect(template.teamAccepted).toBe(true);
- });
- it('does not find team accepted comment', () => {
- const template = new TeamAcceptedTemplate(noAcceptedComment);
-
- expect(template.teamAccepted).not.toBe(true);
- });
-});
diff --git a/tests/model/templates/team-response-template.model.spec.ts b/tests/model/templates/team-response-template.model.spec.ts
deleted file mode 100644
index 430b64786..000000000
--- a/tests/model/templates/team-response-template.model.spec.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { GithubComment } from '../../../src/app/core/models/github/github-comment.model';
-import { TeamResponseParser, TeamResponseTemplate } from '../../../src/app/core/models/templates/team-response-template.model';
-
-const EMPTY_BODY_GITHUB_COMMENT = {
- body: ''
-} as GithubComment;
-const EXPECTED_TEAM_RESPONSE_HEADER = "# Team's Response";
-const EXPECTED_TEAM_RESPONSE_TEMPLATE_CONTENT = 'This is a simple response';
-const DUPLICATE_ISSUE_NUMBER = 100;
-
-const TEAM_RESPONSE_WITH_EXTRA_NEWLINES_AND_WHITESPACE =
- EXPECTED_TEAM_RESPONSE_HEADER + '\r\n \n ' + EXPECTED_TEAM_RESPONSE_TEMPLATE_CONTENT + '\r\n \n\n ' + '## Duplicate status (if any): --';
-const TEAM_RESPONSE_WITH_DUPLICATE =
- EXPECTED_TEAM_RESPONSE_HEADER +
- '\r\n' +
- EXPECTED_TEAM_RESPONSE_TEMPLATE_CONTENT +
- '\r\n' +
- '## Duplicate status (if any): Duplicate of #' +
- DUPLICATE_ISSUE_NUMBER;
-
-describe('TeamResponseParser', () => {
- it('parses the team response correctly', () => {
- const result = TeamResponseParser.run(TEAM_RESPONSE_WITH_EXTRA_NEWLINES_AND_WHITESPACE).result;
-
- expect(result.teamResponse).toBe(EXPECTED_TEAM_RESPONSE_TEMPLATE_CONTENT);
- expect(result.issueNumber).toBe(null);
- });
- it('parses the duplicate issue number correctly', () => {
- const result = TeamResponseParser.run(TEAM_RESPONSE_WITH_DUPLICATE).result;
-
- expect(result.issueNumber).toBe(DUPLICATE_ISSUE_NUMBER);
- });
-});
-
-describe('TeamResponseTemplate', () => {
- it('parses the teamResponse correctly', () => {
- EMPTY_BODY_GITHUB_COMMENT.body = TEAM_RESPONSE_WITH_EXTRA_NEWLINES_AND_WHITESPACE;
- const template = new TeamResponseTemplate([EMPTY_BODY_GITHUB_COMMENT]);
-
- expect(template.teamResponse.content).toBe(EXPECTED_TEAM_RESPONSE_TEMPLATE_CONTENT);
- expect(template.teamResponse.header.toString()).toBe(EXPECTED_TEAM_RESPONSE_HEADER);
- expect(template.duplicateOf.issueNumber).toEqual(null);
- });
- it('parses the duplicateOf value correctly', () => {
- EMPTY_BODY_GITHUB_COMMENT.body = TEAM_RESPONSE_WITH_DUPLICATE;
- const template = new TeamResponseTemplate([EMPTY_BODY_GITHUB_COMMENT]);
-
- expect(template.duplicateOf.issueNumber).toBe(DUPLICATE_ISSUE_NUMBER);
- });
-});
diff --git a/tests/model/templates/tester-response-template.model.spec.ts b/tests/model/templates/tester-response-template.model.spec.ts
deleted file mode 100644
index 3957746d7..000000000
--- a/tests/model/templates/tester-response-template.model.spec.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import { TesterResponseParser, TesterResponseTemplate } from '../../../src/app/core/models/templates/tester-response-template.model';
-
-import { TEAM_RESPONSE_MULTIPLE_DISAGREEMENT } from '../../constants/githubcomment.constants';
-
-const SEVERITY_LOW = 'Low';
-const TYPE_DOCUMENTATION_BUG = 'DocumentationBug';
-
-const EXPECTED_TEAM_RESPONSE_CONTENT = 'This is a dummy team response comment: Thanks for the feedback';
-const EXPECTED_TEAM_RESPONSE_HEADER = "# Team's Response";
-
-const ISSUE_SEVERITY_TITLE = 'Issue severity';
-const ISSUE_TYPE_TITLE = 'Issue type';
-const DISAGREE_CHECKBOX = '- [ ] I disagree';
-const DISAGREE_REASON = '[replace this with your reason]';
-
-const ISSUE_SEVERITY_DESCRIPTION = 'Team chose [`severity.Low`]\nOriginally [`severity.High`]';
-const ISSUE_TYPE_DESCRIPTION = 'Team chose [`type.DocumentationBug`]\nOriginally [`type.FunctionalityBug`]';
-
-describe('TesterResponseParser', () => {
- describe('testerDisagree, teamChosenSeverity and teamChosenType fields', () => {
- it('fields are parsed correctly from the body of the GithubComment', () => {
- const result = TesterResponseParser.run(TEAM_RESPONSE_MULTIPLE_DISAGREEMENT.body).result;
-
- expect(result.testerDisagree).toBe(false);
- expect(result.teamChosenSeverity).toBe(SEVERITY_LOW);
- expect(result.teamChosenType).toBe(TYPE_DOCUMENTATION_BUG);
- });
- });
- describe('testerResponse and teamResponse fields', () => {
- it('parses the fields correctly from the body of the GithubComment', () => {
- const result = TesterResponseParser.run(TEAM_RESPONSE_MULTIPLE_DISAGREEMENT.body).result;
-
- expect(result.teamResponse).toBe(EXPECTED_TEAM_RESPONSE_CONTENT);
-
- expect(result.testerResponses[0].title).toBe(ISSUE_SEVERITY_TITLE);
- expect(result.testerResponses[0].description).toBe(ISSUE_SEVERITY_DESCRIPTION);
- expect(result.testerResponses[0].disagreeCheckbox.toString()).toBe(DISAGREE_CHECKBOX);
- expect(result.testerResponses[0].reasonForDisagreement).toBe(DISAGREE_REASON);
-
- expect(result.testerResponses[1].title).toBe(ISSUE_TYPE_TITLE);
- expect(result.testerResponses[1].description).toBe(ISSUE_TYPE_DESCRIPTION);
- expect(result.testerResponses[1].disagreeCheckbox.toString()).toBe(DISAGREE_CHECKBOX);
- expect(result.testerResponses[1].reasonForDisagreement).toBe(DISAGREE_REASON);
- });
- });
-});
-
-describe('TesterResponseTemplate class', () => {
- describe('teamChosenType and teamChosenSeverity fields', () => {
- it('parses the teamChosenType and teamChosenSeverity values correctly from the GithubComment', () => {
- const template = new TesterResponseTemplate([TEAM_RESPONSE_MULTIPLE_DISAGREEMENT]);
-
- expect(template.teamChosenSeverity).toBe(SEVERITY_LOW);
- expect(template.teamChosenType).toBe(TYPE_DOCUMENTATION_BUG);
- });
- });
- describe('testerResponse and teamResponse fields', () => {
- it('parses the testerResponse and teamResponse fields correctly from the GithubComment', () => {
- const template = new TesterResponseTemplate([TEAM_RESPONSE_MULTIPLE_DISAGREEMENT]);
-
- expect(template.teamResponse.content).toBe(EXPECTED_TEAM_RESPONSE_CONTENT);
- expect(template.teamResponse.header.toString()).toBe(EXPECTED_TEAM_RESPONSE_HEADER);
-
- expect(template.testerResponse.testerResponses[0].title).toBe(ISSUE_SEVERITY_TITLE);
- expect(template.testerResponse.testerResponses[0].description).toBe(ISSUE_SEVERITY_DESCRIPTION);
- expect(template.testerResponse.testerResponses[0].disagreeCheckbox.toString()).toBe(DISAGREE_CHECKBOX);
- expect(template.testerResponse.testerResponses[0].reasonForDisagreement).toBe(DISAGREE_REASON);
-
- expect(template.testerResponse.testerResponses[1].title).toBe(ISSUE_TYPE_TITLE);
- expect(template.testerResponse.testerResponses[1].description).toBe(ISSUE_TYPE_DESCRIPTION);
- expect(template.testerResponse.testerResponses[1].disagreeCheckbox.toString()).toBe(DISAGREE_CHECKBOX);
- expect(template.testerResponse.testerResponses[1].reasonForDisagreement).toBe(DISAGREE_REASON);
- });
- });
-});
diff --git a/tests/model/templates/tutor-moderation-issue-template.model.spec.ts b/tests/model/templates/tutor-moderation-issue-template.model.spec.ts
deleted file mode 100644
index f450126a8..000000000
--- a/tests/model/templates/tutor-moderation-issue-template.model.spec.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import {
- TutorModerationIssueParser,
- TutorModerationIssueTemplate
-} from '../../../src/app/core/models/templates/tutor-moderation-issue-template.model';
-
-import { ISSUE_PENDING_MODERATION } from '../../constants/githubissue.constants';
-
-const EXPECTED_ISSUE_DESCRIPTION = '{original issue description}';
-const EXPECTED_TEAM_RESPONSE = "{team's response}";
-const EXPECTED_DISPUTE_DESCRIPTION =
- "### Team says:\r\n{the team's action that is being disputed}\r\n\r\n" + "### Tester says:\r\n{tester's objection}";
-const TYPE_TITLE = 'Issue Type';
-const SEVERITY_TITLE = 'Issue Severity';
-const NOT_RELATED_TITLE = 'Not Related Question';
-
-describe('TutorModerationIssueParser', () => {
- it('parses the issue description and team response correctly', () => {
- const result = TutorModerationIssueParser.run(ISSUE_PENDING_MODERATION.body).result;
-
- expect(result.description).toBe(EXPECTED_ISSUE_DESCRIPTION);
- expect(result.teamResponse).toBe(EXPECTED_TEAM_RESPONSE);
- });
- it('parses the issue disputes correctly', () => {
- const result = TutorModerationIssueParser.run(ISSUE_PENDING_MODERATION.body).result;
-
- expect(result.issueDisputes[0].title).toBe(TYPE_TITLE);
- expect(result.issueDisputes[0].description).toBe(EXPECTED_DISPUTE_DESCRIPTION);
-
- expect(result.issueDisputes[1].title).toBe(SEVERITY_TITLE);
- expect(result.issueDisputes[1].description).toBe(EXPECTED_DISPUTE_DESCRIPTION);
-
- expect(result.issueDisputes[2].title).toBe(NOT_RELATED_TITLE);
- expect(result.issueDisputes[2].description).toBe(EXPECTED_DISPUTE_DESCRIPTION);
- });
-});
-
-describe('TutorModerationIssueTemplate class', () => {
- it('parses a tutor moderation issue successfully', () => {
- const template = new TutorModerationIssueTemplate(ISSUE_PENDING_MODERATION);
-
- expect(template.description.content).toBe(EXPECTED_ISSUE_DESCRIPTION);
- expect(template.teamResponse.content).toBe(EXPECTED_TEAM_RESPONSE);
- });
-});
diff --git a/tests/model/templates/tutor-moderation-todo-template.model.spec.ts b/tests/model/templates/tutor-moderation-todo-template.model.spec.ts
deleted file mode 100644
index 67a4766c1..000000000
--- a/tests/model/templates/tutor-moderation-todo-template.model.spec.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import {
- TutorModerationTodoParser,
- TutorModerationTodoTemplate
-} from '../../../src/app/core/models/templates/tutor-moderation-todo-template.model';
-
-import { PENDING_TUTOR_MODERATION } from '../../constants/githubcomment.constants';
-
-const EMPTY_DONE_CHECKBOX = '- [ ] Done';
-const FILLED_DONE_CHECKBOX = '- [x] Done';
-const DEFAULT_TUTOR_RESPONSE = '[replace this with your explanation]';
-const TEST_TUTOR_RESPONSE = 'test';
-const DEFAULT_DESCRIPTION = EMPTY_DONE_CHECKBOX + '\n\n' + DEFAULT_TUTOR_RESPONSE;
-const TEST_DESCRIPTION = FILLED_DONE_CHECKBOX + '\n\n' + TEST_TUTOR_RESPONSE;
-
-const TYPE_TITLE = 'Issue Type';
-const SEVERITY_TITLE = 'Issue Severity';
-const NOT_RELATED_TITLE = 'Not Related Question';
-
-describe('TutorModerationTodoParser', () => {
- it('parses comment body correctly', () => {
- const result = TutorModerationTodoParser.run(PENDING_TUTOR_MODERATION.body).result;
-
- expect(result.disputesToResolve[0].title).toBe(TYPE_TITLE);
- expect(result.disputesToResolve[0].description).toBe(TEST_DESCRIPTION);
- expect(result.disputesToResolve[0].todo.isChecked).toBe(true);
- expect(result.disputesToResolve[0].tutorResponse).toBe(TEST_TUTOR_RESPONSE);
-
- expect(result.disputesToResolve[1].title).toBe(SEVERITY_TITLE);
- expect(result.disputesToResolve[1].description).toBe(DEFAULT_DESCRIPTION);
- expect(result.disputesToResolve[1].todo.isChecked).toBe(false);
- expect(result.disputesToResolve[1].tutorResponse).toBe(DEFAULT_TUTOR_RESPONSE);
-
- expect(result.disputesToResolve[2].title).toBe(NOT_RELATED_TITLE);
- expect(result.disputesToResolve[2].description).toBe(DEFAULT_DESCRIPTION);
- expect(result.disputesToResolve[2].todo.isChecked).toBe(false);
- expect(result.disputesToResolve[2].tutorResponse).toBe(DEFAULT_TUTOR_RESPONSE);
- });
-});
-
-describe('TutorModerationTodoTemplate', () => {
- it('parses the github comment successfully', () => {
- const template = new TutorModerationTodoTemplate([PENDING_TUTOR_MODERATION]);
-
- expect(template.parseFailure).not.toBe(true);
- });
-});
diff --git a/tests/services/repo-url-cache.service.spec.ts b/tests/services/repo-url-cache.service.spec.ts
new file mode 100644
index 000000000..e51a473eb
--- /dev/null
+++ b/tests/services/repo-url-cache.service.spec.ts
@@ -0,0 +1,79 @@
+import { FormControl } from '@angular/forms';
+import { Observable } from 'rxjs';
+import { RepoUrlCacheService } from '../../src/app/core/services/repo-url-cache.service';
+import { MockLocalStorage } from '../helper/mock.local.storage';
+
+let repoUrlCacheService: RepoUrlCacheService;
+
+const repoNameOne = 'mock/repo_one';
+const repoNameTwo = 'mock/repo_two';
+
+const mockLocalStorageFunctionCalls = (mockLocalStorage: MockLocalStorage) => {
+ spyOn(localStorage, 'getItem').and.callFake(mockLocalStorage.getItem.bind(mockLocalStorage));
+ spyOn(localStorage, 'setItem').and.callFake(mockLocalStorage.setItem.bind(mockLocalStorage));
+ spyOn(localStorage, 'removeItem').and.callFake(mockLocalStorage.removeItem.bind(mockLocalStorage));
+ spyOn(localStorage, 'clear').and.callFake(mockLocalStorage.clear.bind(mockLocalStorage));
+};
+
+describe('RepoUrlCacheService', () => {
+ beforeAll(() => {
+ const mockLocalStorage = new MockLocalStorage();
+ mockLocalStorageFunctionCalls(mockLocalStorage);
+ });
+
+ afterEach(() => {
+ localStorage.clear();
+ });
+
+ it('should load with no suggestions if localStorage is empty', () => {
+ repoUrlCacheService = new RepoUrlCacheService();
+
+ expect(repoUrlCacheService.suggestions).toEqual([]);
+ });
+
+ it('should load with suggestions if localStorage is not empty', () => {
+ localStorage.setItem(RepoUrlCacheService.KEY_NAME, JSON.stringify([repoNameOne, repoNameTwo]));
+
+ repoUrlCacheService = new RepoUrlCacheService();
+
+ expect(repoUrlCacheService.suggestions).toEqual([repoNameOne, repoNameTwo]);
+ });
+
+ describe('cache()', () => {
+ it('should update suggestions if it does not already include the repo', () => {
+ repoUrlCacheService = new RepoUrlCacheService();
+
+ repoUrlCacheService.cache(repoNameOne);
+
+ // suggestions in repoUrlCacheService should be updated
+ expect(repoUrlCacheService.suggestions).toEqual([repoNameOne]);
+ // suggestions in localStorage should be updated
+ expect(localStorage.getItem(RepoUrlCacheService.KEY_NAME)).toEqual(JSON.stringify([repoNameOne]));
+ });
+
+ it('should not update suggestions if it already includes the repo', () => {
+ localStorage.setItem(RepoUrlCacheService.KEY_NAME, JSON.stringify([repoNameOne]));
+
+ repoUrlCacheService = new RepoUrlCacheService();
+
+ repoUrlCacheService.cache(repoNameOne);
+
+ // suggestions in repoUrlCacheService should not be updated
+ expect(repoUrlCacheService.suggestions).toEqual([repoNameOne]);
+ // suggestions in localStorage should be not updated
+ expect(localStorage.getItem(RepoUrlCacheService.KEY_NAME)).toEqual(JSON.stringify([repoNameOne]));
+ });
+ });
+
+ describe('getFilteredSuggestions()', () => {
+ it('should return an Observable', () => {
+ const formControl = new FormControl();
+
+ repoUrlCacheService = new RepoUrlCacheService();
+
+ const filteredSuggestions = repoUrlCacheService.getFilteredSuggestions(formControl);
+
+ expect(filteredSuggestions).toBeInstanceOf(Observable);
+ });
+ });
+});