PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/nym-vikbez000/nightsky/v1

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v1
Namespace
nym-vikbez000 / nightsky
Files
5 (gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/nym-vikbez000/nightsky/v1
gno
0.9

Files (5)

  • gnomod.tomltoml
  • feed.gnogno
  • nightsky.gnogno
  • render.gnogno
  • nightsky_test.gnogno
nightsky_test.gnogno
1package nightsky23import (4	"testing"5	"time"67	"gno.land/p/nt/avl/v0"8	"gno.land/p/nt/uassert/v0"9	"gno.land/p/nt/urequire/v0"10)1112const (13	owner = "g1owner"14	guest = "g1guest"15)1617func newTestRealm() *TelescopeRealm {18	cfg := NewTelescopeConfig("Test Scope", "Seestar S50", 49.0, 1.0, owner, "/r/test/telescope")19	return NewTelescopeRealm(&cfg)20}2122func TestNewTelescopeConfig(t *testing.T) {23	cfg := NewTelescopeConfig("Scope", "Model", 1.5, 2.5, owner, "/r/x/y")24	uassert.Equal(t, "Scope", cfg.Name)25	uassert.Equal(t, "offline", cfg.Status) // starts offline26	uassert.Equal(t, owner, cfg.Owner)2728	cfg.UpdateStatus("online")29	uassert.Equal(t, "online", cfg.Status)30}3132func TestValidateCommand(cur realm, t *testing.T) {33	cfg := NewTelescopeConfig("Scope", "Model", 0, 0, owner, "/r/x/y")3435	// Valid capture and stop should not panic.36	uassert.NotPanics(t, cur, func() {37		ValidateCommand(TelescopeCommand{CommandType: "capture", TargetRA: 5.5, TargetDec: 22.5, Exposure: 60}, cfg)38	})39	uassert.NotPanics(t, cur, func() {40		// stop ignores coordinates entirely.41		ValidateCommand(TelescopeCommand{CommandType: "stop", TargetRA: 999, TargetDec: 999, Exposure: 0}, cfg)42	})4344	cases := []struct {45		name string46		cmd  TelescopeCommand47		msg  string48	}{49		{"bad type", TelescopeCommand{CommandType: "explode"}, "invalid command type"},50		{"RA low", TelescopeCommand{CommandType: "capture", TargetRA: -1, Exposure: 10}, "invalid RA"},51		{"RA high", TelescopeCommand{CommandType: "capture", TargetRA: 24, Exposure: 10}, "invalid RA"},52		{"Dec low", TelescopeCommand{CommandType: "capture", TargetRA: 1, TargetDec: -91, Exposure: 10}, "invalid Dec"},53		{"Dec high", TelescopeCommand{CommandType: "capture", TargetRA: 1, TargetDec: 91, Exposure: 10}, "invalid Dec"},54		{"exp low", TelescopeCommand{CommandType: "capture", TargetRA: 1, Exposure: 0}, "invalid exposure"},55		{"exp high", TelescopeCommand{CommandType: "capture", TargetRA: 1, Exposure: 301}, "invalid exposure"},56	}57	for _, tc := range cases {58		cmd := tc.cmd59		uassert.PanicsContains(t, cur, tc.msg, func() { ValidateCommand(cmd, cfg) }, tc.name)60	}61}6263func TestIsAccessAllowed(t *testing.T) {64	rules := avl.NewTree()6566	// Unknown address: denied.67	uassert.False(t, IsAccessAllowed(guest, rules))6869	// Never-expires rule (zero time): allowed.70	rules.Set(guest, AccessRule{AllowedAddress: guest, ExpiresAt: time.Time{}})71	uassert.True(t, IsAccessAllowed(guest, rules))7273	// Future expiry: allowed.74	rules.Set(guest, AccessRule{AllowedAddress: guest, ExpiresAt: time.Now().Add(time.Hour)})75	uassert.True(t, IsAccessAllowed(guest, rules))7677	// Past expiry: denied.78	rules.Set(guest, AccessRule{AllowedAddress: guest, ExpiresAt: time.Now().Add(-time.Hour)})79	uassert.False(t, IsAccessAllowed(guest, rules))80}8182func TestAccessFlow(cur realm, t *testing.T) {83	r := newTestRealm()8485	// Owner can always submit.86	urequire.NotPanics(t, cur, func() {87		r.SubmitCommand(owner, "capture", 5, 10, 30)88	})8990	// Guest without a grant is denied.91	uassert.PanicsContains(t, cur, "access denied", func() {92		r.SubmitCommand(guest, "capture", 5, 10, 30)93	})9495	// Grant, then guest can submit.96	r.GrantAccess(owner, guest, 0) // 0 = never expires97	uassert.Equal(t, 1, r.GetAccessRuleCount())98	urequire.NotPanics(t, cur, func() {99		r.SubmitCommand(guest, "capture", 5, 10, 30)100	})101102	// Re-granting the same address does not duplicate the rule.103	r.GrantAccess(owner, guest, 5)104	uassert.Equal(t, 1, r.GetAccessRuleCount())105106	// Revoke, then guest is denied again.107	r.RevokeAccess(owner, guest)108	uassert.Equal(t, 0, r.GetAccessRuleCount())109	uassert.PanicsContains(t, cur, "access denied", func() {110		r.SubmitCommand(guest, "capture", 5, 10, 30)111	})112113	// Non-owner cannot grant access.114	uassert.PanicsContains(t, cur, "owner only", func() {115		r.GrantAccess(guest, "g1evil", 0)116	})117}118119func TestCommandQueueFIFO(cur realm, t *testing.T) {120	r := newTestRealm()121122	r.SubmitCommand(owner, "capture", 1, 1, 10)123	r.SubmitCommand(owner, "capture", 2, 2, 20)124	r.SubmitCommand(owner, "stop", 0, 0, 0)125	uassert.Equal(t, 3, r.GetCommandCount())126127	// FIFO order.128	c1 := r.GetNextCommand(owner)129	uassert.Equal(t, "capture", c1.CommandType)130	uassert.Equal(t, int64(10), int64(c1.Exposure))131132	c2 := r.GetNextCommand(owner)133	uassert.Equal(t, int64(20), int64(c2.Exposure))134135	c3 := r.GetNextCommand(owner)136	uassert.Equal(t, "stop", c3.CommandType)137138	uassert.Equal(t, 0, r.GetCommandCount())139140	// Draining an empty queue panics.141	uassert.PanicsContains(t, cur, "no commands", func() { r.GetNextCommand(owner) })142143	// Only the owner may pull commands.144	r.SubmitCommand(owner, "stop", 0, 0, 0)145	uassert.PanicsContains(t, cur, "owner only", func() { r.GetNextCommand(guest) })146147	// Emergency stop clears everything and sets status online.148	r.ClearCommandQueue(owner)149	uassert.Equal(t, 0, r.GetCommandCount())150	uassert.Equal(t, "online", r.Config.Status)151}152153func TestRecordCaptureUpdatesStatus(cur realm, t *testing.T) {154	r := newTestRealm()155156	// Submitting a command flips status to busy.157	r.SubmitCommand(owner, "capture", 5, 10, 30)158	uassert.Equal(t, "busy", r.Config.Status)159160	// Recording a capture flips it back to online and stores the capture.161	r.RecordCapture(owner, "https://img/1.png", 5, 10, 30, owner)162	uassert.Equal(t, "online", r.Config.Status)163	uassert.Equal(t, 1, r.GetCaptureCount())164165	// Empty image URL is rejected.166	uassert.PanicsContains(t, cur, "image URL", func() {167		r.RecordCapture(owner, "", 5, 10, 30, owner)168	})169170	// Non-owner cannot record.171	uassert.PanicsContains(t, cur, "owner only", func() {172		r.RecordCapture(guest, "https://img/2.png", 5, 10, 30, guest)173	})174}175176// --- CaptureFeed tests ------------------------------------------------------177178func mkCap(url string) CaptureResult {179	return CaptureResult{ImageURL: url}180}181182func TestCaptureFeedOrderAndLatest(t *testing.T) {183	f := NewCaptureFeed(10)184	uassert.Equal(t, 0, f.Len())185186	_, ok := f.Latest()187	uassert.False(t, ok)188189	f.Add(mkCap("a"))190	f.Add(mkCap("b"))191	f.Add(mkCap("c"))192	uassert.Equal(t, 3, f.Len())193194	latest, ok := f.Latest()195	urequire.True(t, ok)196	uassert.Equal(t, "c", latest.ImageURL)197198	// Newest-first iteration order.199	var got []string200	f.IterateNewest(func(c CaptureResult) bool {201		got = append(got, c.ImageURL)202		return false203	})204	urequire.Equal(t, 3, len(got))205	uassert.Equal(t, "c", got[0])206	uassert.Equal(t, "b", got[1])207	uassert.Equal(t, "a", got[2])208209	// Early stop.210	count := 0211	f.IterateNewest(func(c CaptureResult) bool {212		count++213		return true // stop after first214	})215	uassert.Equal(t, 1, count)216}217218func TestCaptureFeedTrim(t *testing.T) {219	f := NewCaptureFeed(3)220	f.Add(mkCap("1"))221	f.Add(mkCap("2"))222	f.Add(mkCap("3"))223	f.Add(mkCap("4")) // evicts "1"224	f.Add(mkCap("5")) // evicts "2"225226	uassert.Equal(t, 3, f.Len())227228	var got []string229	f.IterateNewest(func(c CaptureResult) bool {230		got = append(got, c.ImageURL)231		return false232	})233	// Newest-first: 5, 4, 3 — oldest two evicted.234	uassert.Equal(t, "5", got[0])235	uassert.Equal(t, "4", got[1])236	uassert.Equal(t, "3", got[2])237}238239func TestCaptureFeedRemoveAt(t *testing.T) {240	f := NewCaptureFeed(10)241	f.Add(mkCap("a"))242	f.Add(mkCap("b"))243	f.Add(mkCap("c")) // newest-first: c(0), b(1), a(2)244245	// Out-of-range is a no-op returning false.246	uassert.False(t, f.RemoveAt(-1))247	uassert.False(t, f.RemoveAt(3))248	uassert.Equal(t, 3, f.Len())249250	// Remove the middle (b).251	uassert.True(t, f.RemoveAt(1))252	uassert.Equal(t, 2, f.Len())253254	var got []string255	f.IterateNewest(func(c CaptureResult) bool {256		got = append(got, c.ImageURL)257		return false258	})259	uassert.Equal(t, "c", got[0])260	uassert.Equal(t, "a", got[1])261262	// Removing newest (c).263	uassert.True(t, f.RemoveAt(0))264	latest, ok := f.Latest()265	urequire.True(t, ok)266	uassert.Equal(t, "a", latest.ImageURL)267}268269func TestNewCaptureFeedRejectsNonPositive(cur realm, t *testing.T) {270	uassert.PanicsContains(t, cur, "must be positive", func() { NewCaptureFeed(0) })271}272

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.