Compare commits
2 commits
51283c1a4f
...
6db35b2f99
Author | SHA1 | Date | |
---|---|---|---|
6db35b2f99 | |||
e5ae167550 |
10 changed files with 257 additions and 17 deletions
|
@ -7,7 +7,7 @@
|
||||||
<h3 class="release-title">
|
<h3 class="release-title">
|
||||||
<a href="/admin/release/{{.ID}}">{{.Title}}</a>
|
<a href="/admin/release/{{.ID}}">{{.Title}}</a>
|
||||||
<small>
|
<small>
|
||||||
<span title="{{.PrintReleaseDate}}">{{.GetReleaseYear}}</span>
|
<span title="{{.PrintReleaseDate}}">{{.ReleaseDate.Year}}</span>
|
||||||
{{if not .Visible}}(hidden){{end}}
|
{{if not .Visible}}(hidden){{end}}
|
||||||
</small>
|
</small>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
|
@ -9,10 +9,6 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (artist Artist) GetWebsite() string {
|
|
||||||
return artist.Website
|
|
||||||
}
|
|
||||||
|
|
||||||
func (artist Artist) GetAvatar() string {
|
func (artist Artist) GetAvatar() string {
|
||||||
if artist.Avatar == "" {
|
if artist.Avatar == "" {
|
||||||
return "/img/default-avatar.png"
|
return "/img/default-avatar.png"
|
||||||
|
|
23
model/artist_test.go
Normal file
23
model/artist_test.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_Artist_GetAvatar(t *testing.T) {
|
||||||
|
want := "testavatar.png"
|
||||||
|
artist := Artist{ Avatar: want }
|
||||||
|
|
||||||
|
got := artist.GetAvatar()
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`correct value not returned when avatar is populated (want "%s", got "%s")`, want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
artist = Artist{}
|
||||||
|
|
||||||
|
want = "/img/default-avatar.png"
|
||||||
|
got = artist.GetAvatar()
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`default value not returned when avatar is empty (want "%s", got "%s")`, want, got)
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,6 @@ type Link struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (link Link) NormaliseName() string {
|
func (link Link) NormaliseName() string {
|
||||||
rgx := regexp.MustCompile(`[^a-z0-9]`)
|
rgx := regexp.MustCompile(`[^a-z0-9\-]`)
|
||||||
return strings.ToLower(rgx.ReplaceAllString(link.Name, ""))
|
return rgx.ReplaceAllString(strings.ToLower(link.Name), "")
|
||||||
}
|
}
|
||||||
|
|
23
model/link_test.go
Normal file
23
model/link_test.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_Link_NormaliseName(t *testing.T) {
|
||||||
|
link := Link{
|
||||||
|
Name: "!c@o#o$l%-^a&w*e(s)o_m=e+-[l{i]n}k-0123456789ABCDEF",
|
||||||
|
}
|
||||||
|
|
||||||
|
want := "cool-awesome-link-0123456789abcdef"
|
||||||
|
got := link.NormaliseName()
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`name with invalid characters not properly formatted (want "%s", got "%s")`, want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
link.Name = want
|
||||||
|
got = link.NormaliseName()
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`valid name mangled by formatter (want "%s", got "%s")`, want, got)
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,10 +50,6 @@ func (release Release) PrintReleaseDate() string {
|
||||||
return release.ReleaseDate.Format("02 January 2006")
|
return release.ReleaseDate.Format("02 January 2006")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (release Release) GetReleaseYear() int {
|
|
||||||
return release.ReleaseDate.Year()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (release Release) GetArtwork() string {
|
func (release Release) GetArtwork() string {
|
||||||
if release.Artwork == "" {
|
if release.Artwork == "" {
|
||||||
return "/img/default-cover-art.png"
|
return "/img/default-cover-art.png"
|
||||||
|
|
157
model/release_test.go
Normal file
157
model/release_test.go
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_Release_DescriptionHTML(t *testing.T) {
|
||||||
|
release := Release{
|
||||||
|
Description: "this is\na test\n<strong>description!</strong>",
|
||||||
|
}
|
||||||
|
|
||||||
|
// descriptions are set by privileged users,
|
||||||
|
// so we'll allow HTML injection here
|
||||||
|
want := "this is<br>a test<br><strong>description!</strong>"
|
||||||
|
got := release.GetDescriptionHTML()
|
||||||
|
if want != string(got) {
|
||||||
|
t.Errorf(`release description incorrectly formatted (want "%s", got "%s")`, want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Release_ReleaseDate(t *testing.T) {
|
||||||
|
release := Release{
|
||||||
|
ReleaseDate: time.Date(2025, time.July, 26, 16, 0, 0, 0, time.UTC),
|
||||||
|
}
|
||||||
|
|
||||||
|
want := "2025-07-26T16:00"
|
||||||
|
got := release.TextReleaseDate()
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`release date incorrectly formatted (want "%s", got "%s")`, want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
want = "26 July 2025"
|
||||||
|
got = release.PrintReleaseDate()
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`release date (print) incorrectly formatted (want "%s", got "%s")`, want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Release_Artwork(t *testing.T) {
|
||||||
|
want := "testartwork.png"
|
||||||
|
release := Release{ Artwork: want }
|
||||||
|
|
||||||
|
got := release.GetArtwork()
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`correct value not returned when artwork is populated (want "%s", got "%s")`, want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
release = Release{}
|
||||||
|
|
||||||
|
want = "/img/default-cover-art.png"
|
||||||
|
got = release.GetArtwork()
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`default value not returned when artwork is empty (want "%s", got "%s")`, want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Release_IsSingle(t *testing.T) {
|
||||||
|
release := Release{
|
||||||
|
Tracks: []*Track{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if release.IsSingle() {
|
||||||
|
t.Errorf("IsSingle() == true when no tracks are present")
|
||||||
|
}
|
||||||
|
|
||||||
|
release.Tracks = append(release.Tracks, &Track{})
|
||||||
|
if !release.IsSingle() {
|
||||||
|
t.Errorf("IsSingle() == false when one track is present")
|
||||||
|
}
|
||||||
|
|
||||||
|
release.Tracks = append(release.Tracks, &Track{})
|
||||||
|
if release.IsSingle() {
|
||||||
|
t.Errorf("IsSingle() == true when >1 tracks are present")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Release_IsReleased(t *testing.T) {
|
||||||
|
release := Release {
|
||||||
|
ReleaseDate: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if !release.IsReleased() {
|
||||||
|
t.Errorf("IsRelease() == false when release date in the past")
|
||||||
|
}
|
||||||
|
|
||||||
|
release.ReleaseDate = time.Now().Add(time.Hour)
|
||||||
|
if release.IsReleased() {
|
||||||
|
t.Errorf("IsRelease() == true when release date in the future")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Release_PrintArtists(t *testing.T) {
|
||||||
|
artist1 := "ari melody"
|
||||||
|
artist2 := "aridoodle"
|
||||||
|
artist3 := "idk"
|
||||||
|
artist4 := "guest"
|
||||||
|
|
||||||
|
release := Release {
|
||||||
|
Credits: []*Credit{
|
||||||
|
{ Artist: Artist{ Name: artist1 }, Primary: true },
|
||||||
|
{ Artist: Artist{ Name: artist2 }, Primary: true },
|
||||||
|
{ Artist: Artist{ Name: artist3 }, Primary: false },
|
||||||
|
{ Artist: Artist{ Name: artist4 }, Primary: true },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
want := []string{ artist1, artist2, artist4 }
|
||||||
|
got := release.GetUniqueArtistNames(true)
|
||||||
|
if len(want) != len(got) {
|
||||||
|
t.Errorf(`len(GetUniqueArtistNames) (primary only) == %d, want %d`, len(got), len(want))
|
||||||
|
}
|
||||||
|
for i := range got {
|
||||||
|
if want[i] != got[i] {
|
||||||
|
t.Errorf(`GetUniqueArtistNames[%d] (primary only) == %s, want %s`, i, got[i], want[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
want = []string{ artist1, artist2, artist3, artist4 }
|
||||||
|
got = release.GetUniqueArtistNames(false)
|
||||||
|
if len(want) != len(got) {
|
||||||
|
t.Errorf(`len(GetUniqueArtistNames) == %d, want %d`, len(got), len(want))
|
||||||
|
}
|
||||||
|
for i := range got {
|
||||||
|
if want[i] != got[i] {
|
||||||
|
t.Errorf(`GetUniqueArtistNames[%d] == %s, want %s`, i, got[i], want[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
want := "ari melody, aridoodle & guest"
|
||||||
|
got := release.PrintArtists(true, true)
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`PrintArtists (primary only, ampersand) == "%s", want "%s"`, want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
want = "ari melody, aridoodle, guest"
|
||||||
|
got = release.PrintArtists(true, false)
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`PrintArtists (primary only) == "%s", want "%s"`, want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
want = "ari melody, aridoodle, idk & guest"
|
||||||
|
got = release.PrintArtists(false, true)
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`PrintArtists (all, ampersand) == "%s", want "%s"`, want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
want = "ari melody, aridoodle, idk, guest"
|
||||||
|
got = release.PrintArtists(false, false)
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`PrintArtists (all) == "%s", want "%s"`, want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
model/track_test.go
Normal file
43
model/track_test.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_Track_DescriptionHTML(t *testing.T) {
|
||||||
|
track := Track{
|
||||||
|
Description: "this is\na test\n<strong>description!</strong>",
|
||||||
|
}
|
||||||
|
|
||||||
|
// descriptions are set by privileged users,
|
||||||
|
// so we'll allow HTML injection here
|
||||||
|
want := "this is<br>a test<br><strong>description!</strong>"
|
||||||
|
got := track.GetDescriptionHTML()
|
||||||
|
if want != string(got) {
|
||||||
|
t.Errorf(`track description incorrectly formatted (want "%s", got "%s")`, want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Track_LyricsHTML(t *testing.T) {
|
||||||
|
track := Track{
|
||||||
|
Lyrics: "these are\ntest\n<strong>lyrics!</strong>",
|
||||||
|
}
|
||||||
|
|
||||||
|
// lyrics are set by privileged users,
|
||||||
|
// so we'll allow HTML injection here
|
||||||
|
want := "these are<br>test<br><strong>lyrics!</strong>"
|
||||||
|
got := track.GetLyricsHTML()
|
||||||
|
if want != string(got) {
|
||||||
|
t.Errorf(`track lyrics incorrectly formatted (want "%s", got "%s")`, want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Track_Add(t *testing.T) {
|
||||||
|
track := Track{}
|
||||||
|
|
||||||
|
want := 4
|
||||||
|
got := track.Add(2, 2)
|
||||||
|
if want != got {
|
||||||
|
t.Errorf(`somehow, we screwed up addition. (want %d, got %d)`, want, got)
|
||||||
|
}
|
||||||
|
}
|
|
@ -197,7 +197,9 @@
|
||||||
<img src="/img/buttons/misc/sprunk.gif" alt="sprunk" width="88" height="31">
|
<img src="/img/buttons/misc/sprunk.gif" alt="sprunk" width="88" height="31">
|
||||||
<img src="/img/buttons/misc/tohell.gif" alt="go straight to hell" width="88" height="31">
|
<img src="/img/buttons/misc/tohell.gif" alt="go straight to hell" width="88" height="31">
|
||||||
<img src="/img/buttons/misc/virusalert.gif" alt="virus alert! click here" onclick="alert('meow :3')" width="88" height="31">
|
<img src="/img/buttons/misc/virusalert.gif" alt="virus alert! click here" onclick="alert('meow :3')" width="88" height="31">
|
||||||
|
<a href="http://wiishopchannel.net/" target="_blank">
|
||||||
<img src="/img/buttons/misc/wii.gif" alt="wii" width="88" height="31">
|
<img src="/img/buttons/misc/wii.gif" alt="wii" width="88" height="31">
|
||||||
|
</a>
|
||||||
<img src="/img/buttons/misc/www2.gif" alt="www" width="88" height="31">
|
<img src="/img/buttons/misc/www2.gif" alt="www" width="88" height="31">
|
||||||
<img src="/img/buttons/misc/iemandatory.gif" alt="get mandatory internet explorer" width="88" height="31">
|
<img src="/img/buttons/misc/iemandatory.gif" alt="get mandatory internet explorer" width="88" height="31">
|
||||||
<img src="/img/buttons/misc/learn_html.gif" alt="HTML - learn it today!" width="88" height="31">
|
<img src="/img/buttons/misc/learn_html.gif" alt="HTML - learn it today!" width="88" height="31">
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<meta name="description" content="Stream "{{.Title}}" by {{.PrintArtists true true}} on all platforms!">
|
<meta name="description" content="Stream "{{.Title}}" by {{.PrintArtists true true}} on all platforms!">
|
||||||
<meta name="author" content="{{.PrintArtists true true}}">
|
<meta name="author" content="{{.PrintArtists true true}}">
|
||||||
<meta name="keywords" content="{{.PrintArtists true false}}, music, {{.Title}}, {{.ID}}, {{.GetReleaseYear}}">
|
<meta name="keywords" content="{{.PrintArtists true false}}, music, {{.Title}}, {{.ID}}, {{.ReleaseDate.Year}}">
|
||||||
|
|
||||||
<meta property="og:url" content="https://arimelody.me/music/{{.ID}}">
|
<meta property="og:url" content="https://arimelody.me/music/{{.ID}}">
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
<div id="overview">
|
<div id="overview">
|
||||||
<div id="title-container">
|
<div id="title-container">
|
||||||
<h1 id="title">{{.Title}}</h1>
|
<h1 id="title">{{.Title}}</h1>
|
||||||
<span id="year" title="{{.PrintReleaseDate}}">{{.GetReleaseYear}}</span>
|
<span id="year" title="{{.PrintReleaseDate}}">{{.ReleaseDate.Year}}</span>
|
||||||
</div>
|
</div>
|
||||||
<p id="artist">{{.PrintArtists true true}}</p>
|
<p id="artist">{{.PrintArtists true true}}</p>
|
||||||
{{if .IsReleased}}
|
{{if .IsReleased}}
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if and .Copyright .CopyrightURL}}
|
{{if and .Copyright .CopyrightURL}}
|
||||||
<p id="copyright">{{.Title}} © {{.GetReleaseYear}} by {{.PrintArtists true true}} is licensed under <a href="{{.CopyrightURL}}" target="_blank">{{.Copyright}}</a></p>
|
<p id="copyright">{{.Title}} © {{.ReleaseDate.Year}} by {{.PrintArtists true true}} is licensed under <a href="{{.CopyrightURL}}" target="_blank">{{.Copyright}}</a></p>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<button id="share">share</button>
|
<button id="share">share</button>
|
||||||
|
@ -105,8 +105,8 @@
|
||||||
<ul>
|
<ul>
|
||||||
{{range .Credits}}
|
{{range .Credits}}
|
||||||
{{$Artist := .Artist}}
|
{{$Artist := .Artist}}
|
||||||
{{if $Artist.GetWebsite}}
|
{{if $Artist.Website}}
|
||||||
<li><strong><a href="{{$Artist.GetWebsite}}">{{$Artist.Name}}</a></strong>: {{.Role}}</li>
|
<li><strong><a href="{{$Artist.Website}}">{{$Artist.Name}}</a></strong>: {{.Role}}</li>
|
||||||
{{else}}
|
{{else}}
|
||||||
<li><strong>{{$Artist.Name}}</strong>: {{.Role}}</li>
|
<li><strong>{{$Artist.Name}}</strong>: {{.Role}}</li>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue